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