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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2000-2003 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 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(ERR_FATAL, MSG_INTL(MSG_SYM_INCOMPREG3), 77 conv_sym_SPARC_value_str((Lword)osym->st_value), 78 sdp->sd_file->ifl_name, demangle(oname), 79 ifl->ifl_name, demangle(nname)); 80 ofl->ofl_flags |= FLG_OF_FATAL; 81 return (1); 82 } 83 return (0); 84 } 85 86 if (osym->st_value == nsym->st_value) { 87 /* 88 * A scratch register and a named register are incompatible. 89 * So are two different named registers. 90 */ 91 if (((osym->st_name == 0) || (nsym->st_name == 0)) || 92 (strcmp(oname, nname) != 0)) { 93 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_INCOMPREG1), 94 conv_sym_SPARC_value_str((Lword)osym->st_value), 95 sdp->sd_file->ifl_name, demangle(oname), 96 ifl->ifl_name, demangle(nname)); 97 ofl->ofl_flags |= FLG_OF_FATAL; 98 return (1); 99 } 100 101 /* 102 * A multiply initialized symbol is also illegal. 103 */ 104 if ((osym->st_shndx == SHN_ABS) && 105 (nsym->st_shndx == SHN_ABS)) { 106 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_MULTINIREG), 107 conv_sym_SPARC_value_str((Lword)osym->st_value), 108 demangle(nname), sdp->sd_file->ifl_name, 109 ifl->ifl_name); 110 ofl->ofl_flags |= FLG_OF_FATAL; 111 return (1); 112 } 113 114 } else if (strcmp(oname, nname) == 0) { 115 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_INCOMPREG2), 116 demangle(sdp->sd_name), sdp->sd_file->ifl_name, 117 conv_sym_SPARC_value_str((Lword)osym->st_value), 118 ifl->ifl_name, 119 conv_sym_SPARC_value_str((Lword)nsym->st_value)); 120 ofl->ofl_flags |= FLG_OF_FATAL; 121 return (1); 122 } 123 return (0); 124 } 125 126 int 127 mach_sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl) 128 { 129 Sym *osym = sdp->sd_sym; 130 Byte otype = ELF_ST_TYPE(osym->st_info); 131 Byte ntype = ELF_ST_TYPE(nsym->st_info); 132 133 if (otype != ntype) { 134 if ((otype == STT_SPARC_REGISTER) || 135 (ntype == STT_SPARC_REGISTER)) { 136 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_DIFFTYPE), 137 demangle(sdp->sd_name)); 138 eprintf(ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 139 sdp->sd_file->ifl_name, 140 conv_info_type_str(ofl->ofl_e_machine, otype), 141 ifl->ifl_name, 142 conv_info_type_str(ofl->ofl_e_machine, ntype)); 143 ofl->ofl_flags |= FLG_OF_FATAL; 144 return (1); 145 } 146 } else if (otype == STT_SPARC_REGISTER) 147 return (reg_check(sdp, nsym, sdp->sd_name, ifl, ofl)); 148 149 return (0); 150 } 151 152 static const char *registers[] = { 0, 153 MSG_ORIG(MSG_STO_REGISTERG1), MSG_ORIG(MSG_STO_REGISTERG2), 154 MSG_ORIG(MSG_STO_REGISTERG3), MSG_ORIG(MSG_STO_REGISTERG4), 155 MSG_ORIG(MSG_STO_REGISTERG5), MSG_ORIG(MSG_STO_REGISTERG6), 156 MSG_ORIG(MSG_STO_REGISTERG7) 157 }; 158 159 const char * 160 is_regsym(Ifl_desc *ifl, Sym *sym, const char *strs, int symndx, Word shndx, 161 const char *symsecname, Word * flags) 162 { 163 const char *name; 164 165 /* 166 * Only do something if this is a register symbol. 167 */ 168 if (ELF_ST_TYPE(sym->st_info) != STT_SPARC_REGISTER) 169 return (0); 170 171 /* 172 * Check for bogus register number. 173 */ 174 if ((sym->st_value < STO_SPARC_REGISTER_G1) || 175 (sym->st_value > STO_SPARC_REGISTER_G7)) { 176 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_BADREG), ifl->ifl_name, 177 symsecname, symndx, EC_XWORD(sym->st_value)); 178 return ((const char *)S_ERROR); 179 } 180 181 /* 182 * A register symbol can only be undefined or defined (absolute). 183 */ 184 if ((shndx != SHN_ABS) && (shndx != SHN_UNDEF)) { 185 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_BADREG), ifl->ifl_name, 186 symsecname, symndx, EC_XWORD(sym->st_value)); 187 return ((const char *)S_ERROR); 188 } 189 190 /* 191 * Determine whether this is a scratch (unnamed) definition. 192 */ 193 if (sym->st_name == 0) { 194 /* 195 * Check for bogus scratch register definitions. 196 */ 197 if ((ELF_ST_BIND(sym->st_info) != STB_GLOBAL) || 198 (shndx != SHN_UNDEF)) { 199 eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_BADSCRATCH), 200 ifl->ifl_name, symsecname, symndx, 201 conv_sym_SPARC_value_str((Lword)sym->st_value)); 202 return ((const char *)S_ERROR); 203 } 204 205 /* 206 * Fabricate a name for this register so that this definition 207 * can be processed through the symbol resolution engine. 208 */ 209 name = registers[sym->st_value]; 210 } else 211 name = strs + sym->st_name; 212 213 /* 214 * Indicate we're dealing with a register and return its name. 215 */ 216 *flags |= FLG_SY_REGSYM; 217 return (name); 218 } 219 220 Sym_desc * 221 reg_find(Sym * sym, Ofl_desc * ofl) 222 { 223 if (ofl->ofl_regsyms == 0) 224 return (0); 225 226 return (ofl->ofl_regsyms[sym->st_value]); 227 } 228 229 int 230 reg_enter(Sym_desc * sdp, Ofl_desc * ofl) 231 { 232 if (ofl->ofl_regsyms == 0) { 233 ofl->ofl_regsymsno = STO_SPARC_REGISTER_G7 + 1; 234 if ((ofl->ofl_regsyms = libld_calloc(sizeof (Sym_desc *), 235 ofl->ofl_regsymsno)) == 0) { 236 ofl->ofl_flags |= FLG_OF_FATAL; 237 return (0); 238 } 239 } 240 241 ofl->ofl_regsyms[sdp->sd_sym->st_value] = sdp; 242 return (1); 243 } 244