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
802#elif defined(TCC_TARGET_X86_64)802#elif defined(TCC_TARGET_X86_64)
803 case R_X86_64_64:803 case R_X86_64_64:
804 if (s1->output_type == TCC_OUTPUT_DLL) {804 if (s1->output_type == TCC_OUTPUT_DLL) {
805 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);805 esym_index = s1->symtab_to_dynsym[sym_index];
806 qrel->r_addend = *(long long *)ptr + val;806 qrel->r_offset = rel->r_offset;
807 qrel++;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 }
808 }817 }
809 *(long long *)ptr += val;818 *(long long *)ptr += val;
810 break;819 break;
@@ -1013,6 +1022,7 @@ static void put_got_entry(TCCState *s1, · 202 unmodified lines
1013 ElfW(Sym) *sym;1022 ElfW(Sym) *sym;
1014 unsigned long offset;1023 unsigned long offset;
1015 int *ptr;1024 int *ptr;
1025 struct sym_attr *symattr;
1016 1026
1017 if (!s1->got)1027 if (!s1->got)
1018 build_got(s1);1028 build_got(s1);
@@ -1037,7 +1047,10 @@ static void put_got_entry(TCCState *s1, · 18 unmodified lines
1037 got_entry_present = 1;1047 got_entry_present = 1;
1038 }1048 }
1039 1049
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;
1041 1054
1042 if (s1->dynsym) {1055 if (s1->dynsym) {
1043 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];1056 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
@@ -1048,6 +1061,7 @@ static void put_got_entry(TCCState *s1, · 4 unmodified lines
1048 Section *plt;1061 Section *plt;
1049 uint8_t *p;1062 uint8_t *p;
1050 int modrm;1063 int modrm;
1064 unsigned long relofs;
1051 1065
1052#if defined(TCC_OUTPUT_DLL_WITH_PLT)1066#if defined(TCC_OUTPUT_DLL_WITH_PLT)
1053 modrm = 0x25;1067 modrm = 0x25;
@@ -1072,12 +1086,21 @@ static void put_got_entry(TCCState *s1, · 18 unmodified lines
1072 put32(p + 8, PTR_SIZE * 2);1086 put32(p + 8, PTR_SIZE * 2);
1073 }1087 }
1074 1088
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;
1075 p = section_ptr_add(plt, 16);1093 p = section_ptr_add(plt, 16);
1076 p[0] = 0xff; /* jmp *(got + x) */1094 p[0] = 0xff; /* jmp *(got + x) */
1077 p[1] = modrm;1095 p[1] = modrm;
1078 put32(p + 2, s1->got->data_offset);1096 put32(p + 2, s1->got->data_offset);
1079 p[6] = 0x68; /* push $xxx */1097 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
1081 p[11] = 0xe9; /* jmp plt_start */1104 p[11] = 0xe9; /* jmp plt_start */
1082 put32(p + 12, -(plt->data_offset));1105 put32(p + 12, -(plt->data_offset));
1083 1106
@@ -1087,7 +1110,7 @@ static void put_got_entry(TCCState *s1, · 3 unmodified lines
1087 if (s1->output_type == TCC_OUTPUT_EXE)1110 if (s1->output_type == TCC_OUTPUT_EXE)
1088#endif1111#endif
1089 offset = plt->data_offset - 16;1112 offset = plt->data_offset - 16;
1090 s1->sym_attrs[sym_index].has_plt_entry = 1;1113 symattr->has_plt_entry = 1;
1091 }1114 }
1092#elif defined(TCC_TARGET_ARM)1115#elif defined(TCC_TARGET_ARM)
1093 if (need_plt_entry) {1116 if (need_plt_entry) {
@@ -1109,7 +1132,7 @@ static void put_got_entry(TCCState *s1, · 15 unmodified lines
1109 put32(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */1132 put32(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
1110 }1133 }
1111 1134
1112 if (s1->sym_attrs[sym_index].plt_thumb_stub) {1135 if (symattr->plt_thumb_stub) {
1113 p = section_ptr_add(plt, 20);1136 p = section_ptr_add(plt, 20);
1114 put32(p, 0x4778); /* bx pc */1137 put32(p, 0x4778); /* bx pc */
1115 put32(p+2, 0x46c0); /* nop */1138 put32(p+2, 0x46c0); /* nop */
@@ -1125,27 +1148,23 @@ static void put_got_entry(TCCState *s1, · 9 unmodified lines
1125 the PLT */1148 the PLT */
1126 if (s1->output_type == TCC_OUTPUT_EXE)1149 if (s1->output_type == TCC_OUTPUT_EXE)
1127 offset = plt->data_offset - 16;1150 offset = plt->data_offset - 16;
1128 s1->sym_attrs[sym_index].has_plt_entry = 1;1151 symattr->has_plt_entry = 1;
1129 }1152 }
1130#elif defined(TCC_TARGET_C67)1153#elif defined(TCC_TARGET_C67)
1131 tcc_error("C67 got not implemented");1154 tcc_error("C67 got not implemented");
1132#else1155#else
1133#error unsupported CPU1156#error unsupported CPU
1134#endif1157#endif
1158 /* XXX This might generate multiple syms for name. */
1135 index = put_elf_sym(s1->dynsym, offset,1159 index = put_elf_sym(s1->dynsym, offset,
1136 size, info, 0, sym->st_shndx, name);1160 size, info, 0, sym->st_shndx, name);
1137 if (got_entry_present) {1161 /* Create the relocation (it's against the GOT for PLT
1138 put_elf_reloc(s1->dynsym, s1->got,1162 and GOT relocs). */
1139 s1->sym_attrs[sym_index].got_offset,
1140 reloc_type, index);
1141 return;
1142 }
1143
1144 /* put a got entry */
1145 put_elf_reloc(s1->dynsym, s1->got,1163 put_elf_reloc(s1->dynsym, s1->got,
1146 s1->got->data_offset,1164 s1->got->data_offset,
1147 reloc_type, index);1165 reloc_type, index);
1148 }1166 }
1167 /* And now create the GOT slot itself. */
1149 ptr = section_ptr_add(s1->got, PTR_SIZE);1168 ptr = section_ptr_add(s1->got, PTR_SIZE);
1150 *ptr = 0;1169 *ptr = 0;
1151}1170}
@@ -1697,26 +1716,11 @@ static void export_global_syms(TCCState *s1) · 545 unmodified lines
1697 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);1716 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1698 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {1717 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1699 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {1718 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1700#if defined(TCC_OUTPUT_DLL_WITH_PLT)1719 name = (char *) symtab_section->link->data + sym->st_name;
1701 int type = ELFW(ST_TYPE)(sym->st_info);1720 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1702 if ((type == STT_FUNC || type == STT_GNU_IFUNC)1721 sym->st_info, 0, sym->st_shndx, name);
1703 && sym->st_shndx == SHN_UNDEF) {1722 index = sym - (ElfW(Sym) *) symtab_section->data;
1704 int visibility = ELFW(ST_BIND)(sym->st_info);1723 s1->symtab_to_dynsym[index] = dynindex;
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 }
1720 }1724 }
1721 }1725 }
1722}1726}
x86_64-gen.c+1−1
@@ -604,7 +604,7 @@ static void gcall_or_jmp(int is_jmp) · 603 unmodified lines
604 if (vtop->r & VT_SYM) {604 if (vtop->r & VT_SYM) {
605 /* relocation case */605 /* relocation case */
606 greloc(cur_text_section, vtop->sym,606 greloc(cur_text_section, vtop->sym,
607 ind + 1, R_X86_64_PC32);607 ind + 1, R_X86_64_PLT32);
608 } else {608 } else {
609 /* put an empty PC32 relocation */609 /* put an empty PC32 relocation */
610 put_elf_reloc(symtab_section, cur_text_section,610 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