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}