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