History

Support GOT32 and PLT32 reloc for same symbol

Some symbol (such as __gmon_start__ but this one does not matter to tcc) can have both a R_386_GOT32 and R_386_PLT32 relocation. It is thus not enough to test if a GOT reloc was already done when deciding whether to return early from put_got_entry.

Thomas Preud'homme committed 12 years ago

Commit dc8ea931 parent 078ba241 file · +31 −11Browse files

Unified · Split

tccelf.c+31−11
@@ -1008,7 +1008,7 @@ static void put_got_entry(TCCState *s1, · 1007 unmodified lines
10081008 int reloc_type, unsigned long size, int info,
10091009 int sym_index)
10101010 {
1011− int index;
1011+ int index, need_plt_entry, got_entry_present = 0;
10121012 const char *name;
10131013 ElfW(Sym) *sym;
10141014 unsigned long offset;
@@ -1017,25 +1017,38 @@ static void put_got_entry(TCCState *s1, · 2 unmodified lines
10171017 if (!s1->got)
10181018 build_got(s1);
10191019
1020+ need_plt_entry = s1->dynsym &&
1021+#ifdef TCC_TARGET_X86_64
1022+ (reloc_type == R_X86_64_JUMP_SLOT);
1023+#elif defined(TCC_TARGET_I386)
1024+ (reloc_type == R_386_JMP_SLOT);
1025+#elif defined(TCC_TARGET_ARM)
1026+ (reloc_type == R_ARM_JUMP_SLOT);
1027+#else
1028+ 0;
1029+#endif
1030+
10201031 /* if a got entry already exists for that symbol, no need to add one */
10211032 if (sym_index < s1->nb_sym_attrs &&
1022− s1->sym_attrs[sym_index].got_offset)
1023− return;
1033+ s1->sym_attrs[sym_index].got_offset) {
1034+ if (!need_plt_entry)
1035+ return;
1036+ else
1037+ got_entry_present = 1;
1038+ }
10241039
10251040 alloc_sym_attr(s1, sym_index)->got_offset = s1->got->data_offset;
10261041
10271042 if (s1->dynsym) {
10281043 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
10291044 name = (char *) symtab_section->link->data + sym->st_name;
1045+ if (!find_elf_sym(s1->dynsym, name))
1046+ need_plt_entry = 1;
1047+ else
1048+ return;
10301049 offset = sym->st_value;
10311050 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1032− if (reloc_type ==
1033−#ifdef TCC_TARGET_X86_64
1034− R_X86_64_JUMP_SLOT
1035−#else
1036− R_386_JMP_SLOT
1037−#endif
1038− ) {
1051+ if (need_plt_entry) {
10391052 Section *plt;
10401053 uint8_t *p;
10411054 int modrm;
@@ -1080,7 +1093,7 @@ static void put_got_entry(TCCState *s1, · 38 unmodified lines
10801093 offset = plt->data_offset - 16;
10811094 }
10821095 #elif defined(TCC_TARGET_ARM)
1083− if (reloc_type == R_ARM_JUMP_SLOT) {
1096+ if (need_plt_entry) {
10841097 Section *plt;
10851098 uint8_t *p;
10861099
@@ -1123,6 +1136,13 @@ static void put_got_entry(TCCState *s1, · 36 unmodified lines
11231136 #endif
11241137 index = put_elf_sym(s1->dynsym, offset,
11251138 size, info, 0, sym->st_shndx, name);
1139+ if (got_entry_present) {
1140+ put_elf_reloc(s1->dynsym, s1->got,
1141+ s1->sym_attrs[sym_index].got_offset,
1142+ reloc_type, index);
1143+ return;
1144+ }
1145+
11261146 /* put a got entry */
11271147 put_elf_reloc(s1->dynsym, s1->got,
11281148 s1->got->data_offset,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t