History

x86-64: Add basic shared lib support

Initial support for shared libraries on x86-64.

Michael Matz committed 12 years ago

Commit 080ad7e1 parent 5a5fee82 files · +41 −37Browse files

Unified · Split

2 files
  1. tccelf.c +40 −36
  2. x86_64-gen.c +1 −1
tccelf.c+40−36
@@ -802,9 +802,18 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 801 unmodified lines
802802 #elif defined(TCC_TARGET_X86_64)
803803 case R_X86_64_64:
804804 if (s1->output_type == TCC_OUTPUT_DLL) {
805− qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
806− qrel->r_addend = *(long long *)ptr + val;
807− qrel++;
805+ esym_index = s1->symtab_to_dynsym[sym_index];
806+ qrel->r_offset = rel->r_offset;
807+ if (esym_index) {
808+ qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
809+ qrel->r_addend = rel->r_addend;
810+ qrel++;
811+ break;
812+ } else {
813+ qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
814+ qrel->r_addend = *(long long *)ptr + val;
815+ qrel++;
816+ }
808817 }
809818 *(long long *)ptr += val;
810819 break;
@@ -1013,6 +1022,7 @@ static void put_got_entry(TCCState *s1, · 202 unmodified lines
10131022 ElfW(Sym) *sym;
10141023 unsigned long offset;
10151024 int *ptr;
1025+ struct sym_attr *symattr;
10161026
10171027 if (!s1->got)
10181028 build_got(s1);
@@ -1037,7 +1047,10 @@ static void put_got_entry(TCCState *s1, · 18 unmodified lines
10371047 got_entry_present = 1;
10381048 }
10391049
1040− alloc_sym_attr(s1, sym_index)->got_offset = s1->got->data_offset;
1050+ symattr = alloc_sym_attr(s1, sym_index);
1051+ /* Only store the GOT offset if it's not generated for the PLT entry. */
1052+ if (!need_plt_entry)
1053+ symattr->got_offset = s1->got->data_offset;
10411054
10421055 if (s1->dynsym) {
10431056 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
@@ -1048,6 +1061,7 @@ static void put_got_entry(TCCState *s1, · 4 unmodified lines
10481061 Section *plt;
10491062 uint8_t *p;
10501063 int modrm;
1064+ unsigned long relofs;
10511065
10521066 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
10531067 modrm = 0x25;
@@ -1072,12 +1086,21 @@ static void put_got_entry(TCCState *s1, · 18 unmodified lines
10721086 put32(p + 8, PTR_SIZE * 2);
10731087 }
10741088
1089+ /* The PLT slot refers to the relocation entry it needs
1090+ via offset. The reloc entry is created below, so its
1091+ offset is the current data_offset. */
1092+ relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
10751093 p = section_ptr_add(plt, 16);
10761094 p[0] = 0xff; /* jmp *(got + x) */
10771095 p[1] = modrm;
10781096 put32(p + 2, s1->got->data_offset);
10791097 p[6] = 0x68; /* push $xxx */
1080− put32(p + 7, (plt->data_offset - 32) >> 1);
1098+#ifdef TCC_TARGET_X86_64
1099+ /* On x86-64, the relocation is referred to by _index_. */
1100+ put32(p + 7, relofs / sizeof (ElfW_Rel));
1101+#else
1102+ put32(p + 7, relofs);
1103+#endif
10811104 p[11] = 0xe9; /* jmp plt_start */
10821105 put32(p + 12, -(plt->data_offset));
10831106
@@ -1087,7 +1110,7 @@ static void put_got_entry(TCCState *s1, · 3 unmodified lines
10871110 if (s1->output_type == TCC_OUTPUT_EXE)
10881111 #endif
10891112 offset = plt->data_offset - 16;
1090− s1->sym_attrs[sym_index].has_plt_entry = 1;
1113+ symattr->has_plt_entry = 1;
10911114 }
10921115 #elif defined(TCC_TARGET_ARM)
10931116 if (need_plt_entry) {
@@ -1109,7 +1132,7 @@ static void put_got_entry(TCCState *s1, · 15 unmodified lines
11091132 put32(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
11101133 }
11111134
1112− if (s1->sym_attrs[sym_index].plt_thumb_stub) {
1135+ if (symattr->plt_thumb_stub) {
11131136 p = section_ptr_add(plt, 20);
11141137 put32(p, 0x4778); /* bx pc */
11151138 put32(p+2, 0x46c0); /* nop */
@@ -1125,27 +1148,23 @@ static void put_got_entry(TCCState *s1, · 9 unmodified lines
11251148 the PLT */
11261149 if (s1->output_type == TCC_OUTPUT_EXE)
11271150 offset = plt->data_offset - 16;
1128− s1->sym_attrs[sym_index].has_plt_entry = 1;
1151+ symattr->has_plt_entry = 1;
11291152 }
11301153 #elif defined(TCC_TARGET_C67)
11311154 tcc_error("C67 got not implemented");
11321155 #else
11331156 #error unsupported CPU
11341157 #endif
1158+ /* XXX This might generate multiple syms for name. */
11351159 index = put_elf_sym(s1->dynsym, offset,
11361160 size, info, 0, sym->st_shndx, name);
1137− if (got_entry_present) {
1138− put_elf_reloc(s1->dynsym, s1->got,
1139− s1->sym_attrs[sym_index].got_offset,
1140− reloc_type, index);
1141− return;
1142− }
1143−
1144− /* put a got entry */
1161+ /* Create the relocation (it's against the GOT for PLT
1162+ and GOT relocs). */
11451163 put_elf_reloc(s1->dynsym, s1->got,
11461164 s1->got->data_offset,
11471165 reloc_type, index);
11481166 }
1167+ /* And now create the GOT slot itself. */
11491168 ptr = section_ptr_add(s1->got, PTR_SIZE);
11501169 *ptr = 0;
11511170 }
@@ -1697,26 +1716,11 @@ static void export_global_syms(TCCState *s1) · 545 unmodified lines
16971716 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
16981717 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
16991718 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1700−#if defined(TCC_OUTPUT_DLL_WITH_PLT)
1701− int type = ELFW(ST_TYPE)(sym->st_info);
1702− if ((type == STT_FUNC || type == STT_GNU_IFUNC)
1703− && sym->st_shndx == SHN_UNDEF) {
1704− int visibility = ELFW(ST_BIND)(sym->st_info);
1705− put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1706− ELFW(ST_INFO)(visibility, STT_FUNC),
1707− sym - (ElfW(Sym) *) symtab_section->data);
1708− } else if (type == STT_OBJECT) {
1709− put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size, sym->st_info,
1710− sym - (ElfW(Sym) *) symtab_section->data);
1711− } else
1712−#endif
1713− {
1714− name = (char *) symtab_section->link->data + sym->st_name;
1715− dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1716− sym->st_info, 0, sym->st_shndx, name);
1717− index = sym - (ElfW(Sym) *) symtab_section->data;
1718− s1->symtab_to_dynsym[index] = dynindex;
1719− }
1719+ name = (char *) symtab_section->link->data + sym->st_name;
1720+ dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1721+ sym->st_info, 0, sym->st_shndx, name);
1722+ index = sym - (ElfW(Sym) *) symtab_section->data;
1723+ s1->symtab_to_dynsym[index] = dynindex;
17201724 }
17211725 }
17221726 }
x86_64-gen.c+1−1
@@ -604,7 +604,7 @@ static void gcall_or_jmp(int is_jmp) · 603 unmodified lines
604604 if (vtop->r & VT_SYM) {
605605 /* relocation case */
606606 greloc(cur_text_section, vtop->sym,
607− ind + 1, R_X86_64_PC32);
607+ ind + 1, R_X86_64_PLT32);
608608 } else {
609609 /* put an empty PC32 relocation */
610610 put_elf_reloc(symtab_section, cur_text_section,

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