1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #define ELF_TARGET_SPARC 27 28 #include <stdio.h> 29 #include <string.h> 30 #include <alloca.h> 31 #include <sys/types.h> 32 #include <debug.h> 33 #include "msg.h" 34 #include "_libld.h" 35 #include "machsym.sparc.h" 36 37 /* 38 * Matrix of legal combinations of usage of a given register: 39 * 40 * Obj1 \ Obj2 Scratch Named 41 * Scratch OK NO 42 * Named NO * 43 * 44 * (*) OK if the symbols are identical, NO if they are not. Two symbols 45 * are identical if and only if one of the following is true: 46 * A. They are both global and have the same name. 47 * B. They are both local, have the same name, and are defined in the same 48 * object. (Note that a local symbol in one object is never identical to 49 * a local symbol in another object, even if the name is the same.) 50 * 51 * Matrix of legal combinations of st_shndx for the same register symbol: 52 * 53 * Obj1 \ Obj2 UNDEF ABS 54 * UNDEF OK OK 55 * ABS OK NO 56 * 57 */ 58 int 59 ld_reg_check_sparc(Sym_desc *sdp, Sym *nsym, const char *nname, Ifl_desc *ifl, 60 Ofl_desc *ofl) 61 { 62 Sym *osym = sdp->sd_sym; 63 const char *oname = sdp->sd_name; 64 Conv_inv_buf_t inv_buf1, inv_buf2; 65 66 /* 67 * Scratch register definitions are compatible. 68 */ 69 if ((osym->st_name == 0) && (nsym->st_name == 0)) 70 return (0); 71 72 /* 73 * A local and a global, or another local is incompatible. 74 */ 75 if ((ELF_ST_BIND(osym->st_info) == STB_LOCAL) || 76 (ELF_ST_BIND(nsym->st_info) == STB_LOCAL)) { 77 if (osym->st_value == nsym->st_value) { 78 79 eprintf(ofl->ofl_lml, ERR_FATAL, 80 MSG_INTL(MSG_SYM_INCOMPREG3), 81 conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1), 82 sdp->sd_file->ifl_name, demangle(oname), 83 ifl->ifl_name, demangle(nname)); 84 ofl->ofl_flags |= FLG_OF_FATAL; 85 return (1); 86 } 87 return (0); 88 } 89 90 if (osym->st_value == nsym->st_value) { 91 /* 92 * A scratch register and a named register are incompatible. 93 * So are two different named registers. 94 */ 95 if (((osym->st_name == 0) || (nsym->st_name == 0)) || 96 (strcmp(oname, nname) != 0)) { 97 eprintf(ofl->ofl_lml, ERR_FATAL, 98 MSG_INTL(MSG_SYM_INCOMPREG1), 99 conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1), 100 sdp->sd_file->ifl_name, demangle(oname), 101 ifl->ifl_name, demangle(nname)); 102 ofl->ofl_flags |= FLG_OF_FATAL; 103 return (1); 104 } 105 106 /* 107 * A multiply initialized symbol is also illegal. 108 */ 109 if ((osym->st_shndx == SHN_ABS) && 110 (nsym->st_shndx == SHN_ABS)) { 111 eprintf(ofl->ofl_lml, ERR_FATAL, 112 MSG_INTL(MSG_SYM_MULTINIREG), 113 conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1), 114 demangle(nname), sdp->sd_file->ifl_name, 115 ifl->ifl_name); 116 ofl->ofl_flags |= FLG_OF_FATAL; 117 return (1); 118 } 119 120 } else if (strcmp(oname, nname) == 0) { 121 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_INCOMPREG2), 122 demangle(sdp->sd_name), sdp->sd_file->ifl_name, 123 conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1), 124 ifl->ifl_name, 125 conv_sym_SPARC_value(nsym->st_value, 0, &inv_buf2)); 126 ofl->ofl_flags |= FLG_OF_FATAL; 127 return (1); 128 } 129 return (0); 130 } 131 132 int 133 ld_mach_sym_typecheck_sparc(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, 134 Ofl_desc *ofl) 135 { 136 Conv_inv_buf_t inv_buf1, inv_buf2; 137 Sym *osym = sdp->sd_sym; 138 Byte otype = ELF_ST_TYPE(osym->st_info); 139 Byte ntype = ELF_ST_TYPE(nsym->st_info); 140 141 if (otype != ntype) { 142 if ((otype == STT_SPARC_REGISTER) || 143 (ntype == STT_SPARC_REGISTER)) { 144 eprintf(ofl->ofl_lml, ERR_FATAL, 145 MSG_INTL(MSG_SYM_DIFFTYPE), demangle(sdp->sd_name)); 146 eprintf(ofl->ofl_lml, ERR_NONE, 147 MSG_INTL(MSG_SYM_FILETYPES), 148 sdp->sd_file->ifl_name, conv_sym_info_type( 149 sdp->sd_file->ifl_ehdr->e_machine, otype, 150 0, &inv_buf1), ifl->ifl_name, 151 conv_sym_info_type(ifl->ifl_ehdr->e_machine, 152 ntype, 0, &inv_buf2)); 153 ofl->ofl_flags |= FLG_OF_FATAL; 154 return (1); 155 } 156 } else if (otype == STT_SPARC_REGISTER) 157 return (ld_reg_check_sparc(sdp, nsym, sdp->sd_name, ifl, ofl)); 158 159 return (0); 160 } 161 162 static const char *registers[] = { 0, 163 MSG_ORIG(MSG_STO_REGISTERG1), MSG_ORIG(MSG_STO_REGISTERG2), 164 MSG_ORIG(MSG_STO_REGISTERG3), MSG_ORIG(MSG_STO_REGISTERG4), 165 MSG_ORIG(MSG_STO_REGISTERG5), MSG_ORIG(MSG_STO_REGISTERG6), 166 MSG_ORIG(MSG_STO_REGISTERG7) 167 }; 168 169 const char * 170 ld_is_regsym_sparc(Ofl_desc *ofl, Ifl_desc *ifl, Sym *sym, const char *strs, 171 int symndx, Word shndx, const char *symsecname, sd_flag_t *flags) 172 { 173 const char *name; 174 175 /* 176 * Only do something if this is a register symbol. 177 */ 178 if (ELF_ST_TYPE(sym->st_info) != STT_SPARC_REGISTER) 179 return (0); 180 181 /* 182 * Check for bogus register number. 183 */ 184 if ((sym->st_value < STO_SPARC_REGISTER_G1) || 185 (sym->st_value > STO_SPARC_REGISTER_G7)) { 186 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_BADREG), 187 ifl->ifl_name, symsecname, symndx, EC_XWORD(sym->st_value)); 188 return ((const char *)S_ERROR); 189 } 190 191 /* 192 * A register symbol can only be undefined or defined (absolute). 193 */ 194 if ((shndx != SHN_ABS) && (shndx != SHN_UNDEF)) { 195 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_BADREG), 196 ifl->ifl_name, symsecname, symndx, EC_XWORD(sym->st_value)); 197 return ((const char *)S_ERROR); 198 } 199 200 /* 201 * Determine whether this is a scratch (unnamed) definition. 202 */ 203 if (sym->st_name == 0) { 204 /* 205 * Check for bogus scratch register definitions. 206 */ 207 if ((ELF_ST_BIND(sym->st_info) != STB_GLOBAL) || 208 (shndx != SHN_UNDEF)) { 209 Conv_inv_buf_t inv_buf; 210 211 eprintf(ofl->ofl_lml, ERR_FATAL, 212 MSG_INTL(MSG_SYM_BADSCRATCH), 213 ifl->ifl_name, symsecname, symndx, 214 conv_sym_SPARC_value(sym->st_value, 0, &inv_buf)); 215 return ((const char *)S_ERROR); 216 } 217 218 /* 219 * Fabricate a name for this register so that this definition 220 * can be processed through the symbol resolution engine. 221 */ 222 name = registers[sym->st_value]; 223 } else 224 name = strs + sym->st_name; 225 226 /* 227 * Indicate we're dealing with a register and return its name. 228 */ 229 *flags |= FLG_SY_REGSYM; 230 return (name); 231 } 232 233 Sym_desc * 234 ld_reg_find_sparc(Sym *sym, Ofl_desc *ofl) 235 { 236 if (ofl->ofl_regsyms == NULL) 237 return (NULL); 238 239 return (ofl->ofl_regsyms[sym->st_value]); 240 } 241 242 int 243 ld_reg_enter_sparc(Sym_desc *sdp, Ofl_desc *ofl) 244 { 245 if (ofl->ofl_regsyms == NULL) { 246 247 ofl->ofl_regsymsno = STO_SPARC_REGISTER_G7 + 1; 248 249 if ((ofl->ofl_regsyms = libld_calloc(sizeof (Sym_desc *), 250 ofl->ofl_regsymsno)) == NULL) { 251 ofl->ofl_flags |= FLG_OF_FATAL; 252 return (0); 253 } 254 } 255 256 ofl->ofl_regsyms[sdp->sd_sym->st_value] = sdp; 257 return (1); 258 } 259