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 2007 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 Conv_inv_buf_t inv_buf1, inv_buf2; 64 65 /* 66 * Scratch register definitions are compatible. 67 */ 68 if ((osym->st_name == 0) && (nsym->st_name == 0)) 69 return (0); 70 71 /* 72 * A local and a global, or another local is incompatible. 73 */ 74 if ((ELF_ST_BIND(osym->st_info) == STB_LOCAL) || 75 (ELF_ST_BIND(nsym->st_info) == STB_LOCAL)) { 76 if (osym->st_value == nsym->st_value) { 77 78 eprintf(ofl->ofl_lml, ERR_FATAL, 79 MSG_INTL(MSG_SYM_INCOMPREG3), 80 conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1), 81 sdp->sd_file->ifl_name, demangle(oname), 82 ifl->ifl_name, demangle(nname)); 83 ofl->ofl_flags |= FLG_OF_FATAL; 84 return (1); 85 } 86 return (0); 87 } 88 89 if (osym->st_value == nsym->st_value) { 90 /* 91 * A scratch register and a named register are incompatible. 92 * So are two different named registers. 93 */ 94 if (((osym->st_name == 0) || (nsym->st_name == 0)) || 95 (strcmp(oname, nname) != 0)) { 96 eprintf(ofl->ofl_lml, ERR_FATAL, 97 MSG_INTL(MSG_SYM_INCOMPREG1), 98 conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1), 99 sdp->sd_file->ifl_name, demangle(oname), 100 ifl->ifl_name, demangle(nname)); 101 ofl->ofl_flags |= FLG_OF_FATAL; 102 return (1); 103 } 104 105 /* 106 * A multiply initialized symbol is also illegal. 107 */ 108 if ((osym->st_shndx == SHN_ABS) && 109 (nsym->st_shndx == SHN_ABS)) { 110 eprintf(ofl->ofl_lml, ERR_FATAL, 111 MSG_INTL(MSG_SYM_MULTINIREG), 112 conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1), 113 demangle(nname), sdp->sd_file->ifl_name, 114 ifl->ifl_name); 115 ofl->ofl_flags |= FLG_OF_FATAL; 116 return (1); 117 } 118 119 } else if (strcmp(oname, nname) == 0) { 120 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_INCOMPREG2), 121 demangle(sdp->sd_name), sdp->sd_file->ifl_name, 122 conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1), 123 ifl->ifl_name, 124 conv_sym_SPARC_value(nsym->st_value, 0, &inv_buf2)); 125 ofl->ofl_flags |= FLG_OF_FATAL; 126 return (1); 127 } 128 return (0); 129 } 130 131 int 132 ld_mach_sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl) 133 { 134 Conv_inv_buf_t inv_buf1, inv_buf2; 135 Sym *osym = sdp->sd_sym; 136 Byte otype = ELF_ST_TYPE(osym->st_info); 137 Byte ntype = ELF_ST_TYPE(nsym->st_info); 138 139 if (otype != ntype) { 140 if ((otype == STT_SPARC_REGISTER) || 141 (ntype == STT_SPARC_REGISTER)) { 142 eprintf(ofl->ofl_lml, ERR_FATAL, 143 MSG_INTL(MSG_SYM_DIFFTYPE), demangle(sdp->sd_name)); 144 eprintf(ofl->ofl_lml, ERR_NONE, 145 MSG_INTL(MSG_SYM_FILETYPES), 146 sdp->sd_file->ifl_name, conv_sym_info_type( 147 sdp->sd_file->ifl_ehdr->e_machine, otype, 148 0, &inv_buf1), ifl->ifl_name, 149 conv_sym_info_type(ifl->ifl_ehdr->e_machine, 150 ntype, 0, &inv_buf2)); 151 ofl->ofl_flags |= FLG_OF_FATAL; 152 return (1); 153 } 154 } else if (otype == STT_SPARC_REGISTER) 155 return (ld_reg_check(sdp, nsym, sdp->sd_name, ifl, ofl)); 156 157 return (0); 158 } 159 160 static const char *registers[] = { 0, 161 MSG_ORIG(MSG_STO_REGISTERG1), MSG_ORIG(MSG_STO_REGISTERG2), 162 MSG_ORIG(MSG_STO_REGISTERG3), MSG_ORIG(MSG_STO_REGISTERG4), 163 MSG_ORIG(MSG_STO_REGISTERG5), MSG_ORIG(MSG_STO_REGISTERG6), 164 MSG_ORIG(MSG_STO_REGISTERG7) 165 }; 166 167 const char * 168 ld_is_regsym(Ofl_desc *ofl, Ifl_desc *ifl, Sym *sym, const char *strs, 169 int symndx, Word shndx, const char *symsecname, Word * flags) 170 { 171 const char *name; 172 173 /* 174 * Only do something if this is a register symbol. 175 */ 176 if (ELF_ST_TYPE(sym->st_info) != STT_SPARC_REGISTER) 177 return (0); 178 179 /* 180 * Check for bogus register number. 181 */ 182 if ((sym->st_value < STO_SPARC_REGISTER_G1) || 183 (sym->st_value > STO_SPARC_REGISTER_G7)) { 184 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_BADREG), 185 ifl->ifl_name, symsecname, symndx, EC_XWORD(sym->st_value)); 186 return ((const char *)S_ERROR); 187 } 188 189 /* 190 * A register symbol can only be undefined or defined (absolute). 191 */ 192 if ((shndx != SHN_ABS) && (shndx != SHN_UNDEF)) { 193 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_BADREG), 194 ifl->ifl_name, symsecname, symndx, EC_XWORD(sym->st_value)); 195 return ((const char *)S_ERROR); 196 } 197 198 /* 199 * Determine whether this is a scratch (unnamed) definition. 200 */ 201 if (sym->st_name == 0) { 202 /* 203 * Check for bogus scratch register definitions. 204 */ 205 if ((ELF_ST_BIND(sym->st_info) != STB_GLOBAL) || 206 (shndx != SHN_UNDEF)) { 207 Conv_inv_buf_t inv_buf; 208 209 eprintf(ofl->ofl_lml, ERR_FATAL, 210 MSG_INTL(MSG_SYM_BADSCRATCH), 211 ifl->ifl_name, symsecname, symndx, 212 conv_sym_SPARC_value(sym->st_value, 0, &inv_buf)); 213 return ((const char *)S_ERROR); 214 } 215 216 /* 217 * Fabricate a name for this register so that this definition 218 * can be processed through the symbol resolution engine. 219 */ 220 name = registers[sym->st_value]; 221 } else 222 name = strs + sym->st_name; 223 224 /* 225 * Indicate we're dealing with a register and return its name. 226 */ 227 *flags |= FLG_SY_REGSYM; 228 return (name); 229 } 230 231 Sym_desc * 232 ld_reg_find(Sym * sym, Ofl_desc * ofl) 233 { 234 if (ofl->ofl_regsyms == 0) 235 return (0); 236 237 return (ofl->ofl_regsyms[sym->st_value]); 238 } 239 240 int 241 ld_reg_enter(Sym_desc * sdp, Ofl_desc * ofl) 242 { 243 if (ofl->ofl_regsyms == 0) { 244 ofl->ofl_regsymsno = STO_SPARC_REGISTER_G7 + 1; 245 if ((ofl->ofl_regsyms = libld_calloc(sizeof (Sym_desc *), 246 ofl->ofl_regsymsno)) == 0) { 247 ofl->ofl_flags |= FLG_OF_FATAL; 248 return (0); 249 } 250 } 251 252 ofl->ofl_regsyms[sdp->sd_sym->st_value] = sdp; 253 return (1); 254 } 255