link_elf.c (8420105927433fa5327d76871e927d2c295aa976) | link_elf.c (d297ad160e39eb30b95e90432e98732ba2e464ea) |
---|---|
1/*- 2 * Copyright (c) 1998-2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 890 unchanged lines hidden (view full) --- 899 const Elf_Rela *rela; 900 const char *symname; 901 902 /* Perform relocations without addend if there are any: */ 903 rel = ef->rel; 904 if (rel) { 905 rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize); 906 while (rel < rellim) { | 1/*- 2 * Copyright (c) 1998-2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 890 unchanged lines hidden (view full) --- 899 const Elf_Rela *rela; 900 const char *symname; 901 902 /* Perform relocations without addend if there are any: */ 903 rel = ef->rel; 904 if (rel) { 905 rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize); 906 while (rel < rellim) { |
907 symname = symbol_name(ef, rel->r_info); 908 if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) { | 907 if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { 908 symname = symbol_name(ef, rel->r_info); |
909 printf("link_elf: symbol %s undefined\n", symname); 910 return ENOENT; 911 } 912 rel++; 913 } 914 } 915 916 /* Perform relocations with addend if there are any: */ 917 rela = ef->rela; 918 if (rela) { 919 relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize); 920 while (rela < relalim) { | 909 printf("link_elf: symbol %s undefined\n", symname); 910 return ENOENT; 911 } 912 rel++; 913 } 914 } 915 916 /* Perform relocations with addend if there are any: */ 917 rela = ef->rela; 918 if (rela) { 919 relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize); 920 while (rela < relalim) { |
921 symname = symbol_name(ef, rela->r_info); 922 if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) { | 921 if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { 922 symname = symbol_name(ef, rela->r_info); |
923 printf("link_elf: symbol %s undefined\n", symname); 924 return ENOENT; 925 } 926 rela++; 927 } 928 } 929 930 /* Perform PLT relocations without addend if there are any: */ 931 rel = ef->pltrel; 932 if (rel) { 933 rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize); 934 while (rel < rellim) { | 923 printf("link_elf: symbol %s undefined\n", symname); 924 return ENOENT; 925 } 926 rela++; 927 } 928 } 929 930 /* Perform PLT relocations without addend if there are any: */ 931 rel = ef->pltrel; 932 if (rel) { 933 rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize); 934 while (rel < rellim) { |
935 symname = symbol_name(ef, rel->r_info); 936 if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) { | 935 if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { 936 symname = symbol_name(ef, rel->r_info); |
937 printf("link_elf: symbol %s undefined\n", symname); 938 return ENOENT; 939 } 940 rel++; 941 } 942 } 943 944 /* Perform relocations with addend if there are any: */ 945 rela = ef->pltrela; 946 if (rela) { 947 relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize); 948 while (rela < relalim) { | 937 printf("link_elf: symbol %s undefined\n", symname); 938 return ENOENT; 939 } 940 rel++; 941 } 942 } 943 944 /* Perform relocations with addend if there are any: */ 945 rela = ef->pltrela; 946 if (rela) { 947 relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize); 948 while (rela < relalim) { |
949 symname = symbol_name(ef, rela->r_info); 950 if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) { | 949 if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { 950 symname = symbol_name(ef, rela->r_info); |
951 printf("link_elf: symbol %s undefined\n", symname); 952 return ENOENT; 953 } 954 rela++; 955 } 956 } 957 958 return 0; --- 226 unchanged lines hidden (view full) --- 1185 */ 1186Elf_Addr 1187link_elf_get_gp(linker_file_t lf) 1188{ 1189 elf_file_t ef = (elf_file_t)lf; 1190 return (Elf_Addr)ef->got; 1191} 1192#endif | 951 printf("link_elf: symbol %s undefined\n", symname); 952 return ENOENT; 953 } 954 rela++; 955 } 956 } 957 958 return 0; --- 226 unchanged lines hidden (view full) --- 1185 */ 1186Elf_Addr 1187link_elf_get_gp(linker_file_t lf) 1188{ 1189 elf_file_t ef = (elf_file_t)lf; 1190 return (Elf_Addr)ef->got; 1191} 1192#endif |
1193 1194/* 1195 * Symbol lookup function that can be used when the symbol index is known (ie 1196 * in relocations). It uses the symbol index instead of doing a fully fledged 1197 * hash table based lookup when such is valid. For example for local symbols. 1198 * This is not only more efficient, it's also more correct. It's not always 1199 * the case that the symbol can be found through the hash table. 1200 */ 1201Elf_Addr 1202elf_lookup(linker_file_t lf, Elf_Word symidx, int deps) 1203{ 1204 elf_file_t ef = (elf_file_t)lf; 1205 const Elf_Sym *sym; 1206 const char *symbol; 1207 1208 /* Don't even try to lookup the symbol if the index is bogus. */ 1209 if (symidx >= ef->nchains) 1210 return (0); 1211 1212 sym = ef->symtab + symidx; 1213 1214 /* 1215 * Don't do a full lookup when the symbol is local. It may even 1216 * fail because it may not be found through the hash table. 1217 */ 1218 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) { 1219 /* Force lookup failure when we have an insanity. */ 1220 if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) 1221 return (0); 1222 return ((Elf_Addr)ef->address + sym->st_value); 1223 } 1224 1225 /* 1226 * XXX we can avoid doing a hash table based lookup for global 1227 * symbols as well. This however is not always valid, so we'll 1228 * just do it the hard way for now. Performance tweaks can 1229 * always be added. 1230 */ 1231 1232 symbol = ef->strtab + sym->st_name; 1233 1234 /* Force a lookup failure if the symbol name is bogus. */ 1235 if (*symbol == 0) 1236 return (0); 1237 1238 return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); 1239} |
|