History

lazy binding

Currently tcc does not use lazy binding. It puts all relocations in the RELX section and solve them all at startup. This was not working on bsd. tcc.h: - New RELPLT_SECTION_FMT for plt relocations - New entry relocplt in struct Section tccelf.c: - put_elf_reloca: put R_JMP_SLOT in relocplt section - build_got_entries*: Use two passes because R_JMP_SLOT and R_GLOB_DAT can not be intermixed on some targets (arm, arm64) - layout_sections: Calculate correct size relocplt section for DT_ values. Make sure relocplt is last - fill_dynamic: Add DT_ values when got is filled move DT_VERSYM because dynamic linker cannot handle it standone - Add note section for NetBSD arm-link.c/arm64-link.c/i386-link.c/riscv64-link.c/x86_64-link.c: - fill got table with pointer to plt section or symbol value in case of TCC_OUTPUT_MEMORY arm-link.c/arm64-link.c: - fix offset first plt entry i386-link.c/x86_64-link.c: - use correct reloc entry - use relofs - sizeof (ElfW_Rel) because the reloc is already done lib/bcheck.c: - no __libc_freeres on FreeBSD and NetBSD tests/Makefile: - Add -fno-stack-protector for OpenBSD tests/tests2/Makefile: - disable 106_pthread/114_bound_signal

herman ten brugge committed 5 years ago

Commit 50b4f321 parent e2e62fc10 files · +162 −39Browse files

Unified · Split

10 files
  1. arm-link.c +13 −1
  2. arm64-link.c +14 −1
  3. i386-link.c +18 −4
  4. lib/bcheck.c +2 −1
  5. riscv64-link.c +12 −0
  6. tcc.h +3 −0
  7. tccelf.c +77 −30
  8. tests/Makefile +3 −0
  9. tests/tests2/Makefile +4 −0
  10. x86_64-link.c +16 −2
arm-link.c+13−1
@@ -145,7 +145,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 144 unmodified lines
145 145
146 if (p < p_end) {146 if (p < p_end) {
147 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;147 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
148 write32le(s1->plt->data + 16, x - 16);148 write32le(s1->plt->data + 16, x - 4);
149 p += 20;149 p += 20;
150 while (p < p_end) {150 while (p < p_end) {
151 unsigned off = x + read32le(p + 4) + (s1->plt->data - p) + 4;151 unsigned off = x + read32le(p + 4) + (s1->plt->data - p) + 4;
@@ -157,6 +157,18 @@ ST_FUNC void relocate_plt(TCCState *s1) · 5 unmodified lines
157 p += 12;157 p += 12;
158 }158 }
159 }159 }
160
161 if (s1->got->relocplt) {
162 int mem = s1->output_type == TCC_OUTPUT_MEMORY;
163 ElfW_Rel *rel;
164
165 p = s1->got->data;
166 for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
167 int sym_index = ELFW(R_SYM)(rel->r_info);
168 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
169 write32le(p + rel->r_offset, mem ? sym->st_value : s1->plt->sh_addr);
170 }
171 }
160}172}
161#endif173#endif
162 174
arm64-link.c+14−1
@@ -113,7 +113,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 112 unmodified lines
113 113
114 if (p < p_end) {114 if (p < p_end) {
115 uint64_t plt = s1->plt->sh_addr;115 uint64_t plt = s1->plt->sh_addr;
116 uint64_t got = s1->got->sh_addr;116 uint64_t got = s1->got->sh_addr + 16;
117 uint64_t off = (got >> 12) - (plt >> 12);117 uint64_t off = (got >> 12) - (plt >> 12);
118 if ((off + ((uint32_t)1 << 20)) >> 21)118 if ((off + ((uint32_t)1 << 20)) >> 21)
119 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);119 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
@@ -129,6 +129,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 9 unmodified lines
129 write32le(p + 24, 0xd503201f); // nop129 write32le(p + 24, 0xd503201f); // nop
130 write32le(p + 28, 0xd503201f); // nop130 write32le(p + 28, 0xd503201f); // nop
131 p += 32;131 p += 32;
132 got = s1->got->sh_addr;
132 while (p < p_end) {133 while (p < p_end) {
133 uint64_t pc = plt + (p - s1->plt->data);134 uint64_t pc = plt + (p - s1->plt->data);
134 uint64_t addr = got + read64le(p);135 uint64_t addr = got + read64le(p);
@@ -145,6 +146,18 @@ ST_FUNC void relocate_plt(TCCState *s1) · 10 unmodified lines
145 p += 16;146 p += 16;
146 }147 }
147 }148 }
149
150 if (s1->got->relocplt) {
151 int mem = s1->output_type == TCC_OUTPUT_MEMORY;
152 ElfW_Rel *rel;
153
154 p = s1->got->data;
155 for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
156 int sym_index = ELFW(R_SYM)(rel->r_info);
157 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
158 write64le(p + rel->r_offset, mem ? sym->st_value : s1->plt->sh_addr);
159 }
160 }
148}161}
149 162
150void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)163void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
i386-link.c+18−4
@@ -16,7 +16,7 @@ · 15 unmodified lines
16#define ELF_PAGE_SIZE 0x100016#define ELF_PAGE_SIZE 0x1000
17 17
18#define PCRELATIVE_DLLPLT 018#define PCRELATIVE_DLLPLT 0
19#define RELOCATE_DLLPLT 019#define RELOCATE_DLLPLT 1
20 20
21#else /* !TARGET_DEFS_ONLY */21#else /* !TARGET_DEFS_ONLY */
22 22
@@ -121,7 +121,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 98 unmodified lines
121 /* The PLT slot refers to the relocation entry it needs via offset.121 /* The PLT slot refers to the relocation entry it needs via offset.
122 The reloc entry is created below, so its offset is the current122 The reloc entry is created below, so its offset is the current
123 data_offset */123 data_offset */
124 relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;124 relofs = s1->got->relocplt ? s1->got->relocplt->data_offset : 0;
125 125
126 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */126 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
127 p = section_ptr_add(plt, 16);127 p = section_ptr_add(plt, 16);
@@ -129,7 +129,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 1 unmodified line
129 p[1] = modrm;129 p[1] = modrm;
130 write32le(p + 2, got_offset);130 write32le(p + 2, got_offset);
131 p[6] = 0x68; /* push $xxx */131 p[6] = 0x68; /* push $xxx */
132 write32le(p + 7, relofs);132 write32le(p + 7, relofs - sizeof (ElfW_Rel));
133 p[11] = 0xe9; /* jmp plt_start */133 p[11] = 0xe9; /* jmp plt_start */
134 write32le(p + 12, -(plt->data_offset));134 write32le(p + 12, -(plt->data_offset));
135 return plt_offset;135 return plt_offset;
@@ -147,7 +147,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 11 unmodified lines
147 p = s1->plt->data;147 p = s1->plt->data;
148 p_end = p + s1->plt->data_offset;148 p_end = p + s1->plt->data_offset;
149 149
150 if (p < p_end) {150 if (s1->output_type != TCC_OUTPUT_DLL && p < p_end) {
151 add32le(p + 2, s1->got->sh_addr);151 add32le(p + 2, s1->got->sh_addr);
152 add32le(p + 8, s1->got->sh_addr);152 add32le(p + 8, s1->got->sh_addr);
153 p += 16;153 p += 16;
@@ -156,6 +156,20 @@ ST_FUNC void relocate_plt(TCCState *s1) · 2 unmodified lines
156 p += 16;156 p += 16;
157 }157 }
158 }158 }
159
160 if (s1->got->relocplt) {
161 int mem = s1->output_type == TCC_OUTPUT_MEMORY;
162 ElfW_Rel *rel;
163 int x = s1->plt->sh_addr + 16 + 6;
164
165 p = s1->got->data;
166 for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
167 int sym_index = ELFW(R_SYM)(rel->r_info);
168 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
169 write32le(p + rel->r_offset, mem ? sym->st_value : x);
170 x += 16;
171 }
172 }
159}173}
160#endif174#endif
161 175
lib/bcheck.c+2−1
@@ -1153,7 +1153,8 @@ void __attribute__((destructor)) __bound_exit(void) · 1152 unmodified lines
1153 dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__);1153 dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__);
1154 1154
1155 if (inited) {1155 if (inited) {
1156#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__) && !defined TCC_MUSL1156#if !defined(_WIN32) && !defined(__APPLE__) && !defined TCC_MUSL && \
1157 !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
1157 if (print_heap) {1158 if (print_heap) {
1158 extern void __libc_freeres (void);1159 extern void __libc_freeres (void);
1159 __libc_freeres ();1160 __libc_freeres ();
riscv64-link.c+12−0
@@ -153,6 +153,18 @@ ST_FUNC void relocate_plt(TCCState *s1) · 152 unmodified lines
153 p += 16;153 p += 16;
154 }154 }
155 }155 }
156
157 if (s1->got->relocplt) {
158 int mem = s1->output_type == TCC_OUTPUT_MEMORY;
159 ElfW_Rel *rel;
160
161 p = s1->got->data;
162 for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
163 int sym_index = ELFW(R_SYM)(rel->r_info);
164 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
165 write64le(p + rel->r_offset, mem ? sym->st_value + rel->r_addend : s1->plt->sh_addr);
166 }
167 }
156}168}
157 169
158void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,170void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
tcc.h+3−0
@@ -397,6 +397,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 396 unmodified lines
397# define ElfW_Rel ElfW(Rela)397# define ElfW_Rel ElfW(Rela)
398# define SHT_RELX SHT_RELA398# define SHT_RELX SHT_RELA
399# define REL_SECTION_FMT ".rela%s"399# define REL_SECTION_FMT ".rela%s"
400# define RELPLT_SECTION_FMT ".rel.plt"
400#else401#else
401# define ELFCLASSW ELFCLASS32402# define ELFCLASSW ELFCLASS32
402# define ElfW(type) Elf##32##_##type403# define ElfW(type) Elf##32##_##type
@@ -404,6 +405,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 1 unmodified line
404# define ElfW_Rel ElfW(Rel)405# define ElfW_Rel ElfW(Rel)
405# define SHT_RELX SHT_REL406# define SHT_RELX SHT_REL
406# define REL_SECTION_FMT ".rel%s"407# define REL_SECTION_FMT ".rel%s"
408# define RELPLT_SECTION_FMT ".rel.plt"
407#endif409#endif
408/* target address type */410/* target address type */
409#define addr_t ElfW(Addr)411#define addr_t ElfW(Addr)
@@ -565,6 +567,7 @@ typedef struct Section { · 155 unmodified lines
565 struct Section *reloc; /* corresponding section for relocation, if any */567 struct Section *reloc; /* corresponding section for relocation, if any */
566 struct Section *hash; /* hash table for symbols */568 struct Section *hash; /* hash table for symbols */
567 struct Section *prev; /* previous section on section stack */569 struct Section *prev; /* previous section on section stack */
570 struct Section *relocplt;/* reloc with JMP_SLOTs */
568 char name[1]; /* section name */571 char name[1]; /* section name */
569} Section;572} Section;
570 573
tccelf.c+77−30
@@ -735,18 +735,25 @@ ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, · 734 unmodified lines
735 char buf[256];735 char buf[256];
736 Section *sr;736 Section *sr;
737 ElfW_Rel *rel;737 ElfW_Rel *rel;
738 int jmp_slot = type == R_JMP_SLOT;
738 739
739 sr = s->reloc;740 sr = jmp_slot ? s->relocplt : s->reloc;
740 if (!sr) {741 if (!sr) {
741 /* if no relocation section, create it */742 /* if no relocation section, create it */
742 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);743 if (jmp_slot)
744 snprintf(buf, sizeof(buf), RELPLT_SECTION_FMT);
745 else
746 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
743 /* if the symtab is allocated, then we consider the relocation747 /* if the symtab is allocated, then we consider the relocation
744 are also */748 are also */
745 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);749 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
746 sr->sh_entsize = sizeof(ElfW_Rel);750 sr->sh_entsize = sizeof(ElfW_Rel);
747 sr->link = symtab;751 sr->link = symtab;
748 sr->sh_info = s->sh_num;752 sr->sh_info = s->sh_num;
749 s->reloc = sr;753 if (jmp_slot)
754 s->relocplt = sr;
755 else
756 s->reloc = sr;
750 }757 }
751 rel = section_ptr_add(sr, sizeof(ElfW_Rel));758 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
752 rel->r_offset = offset;759 rel->r_offset = offset;
@@ -1164,7 +1171,7 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type, · 411 unmodified lines
1164}1171}
1165 1172
1166/* build GOT and PLT entries */1173/* build GOT and PLT entries */
1167ST_FUNC void build_got_entries(TCCState *s1)1174static void build_got_entries_pass(TCCState *s1, int pass)
1168{1175{
1169 Section *s;1176 Section *s;
1170 ElfW_Rel *rel;1177 ElfW_Rel *rel;
@@ -1235,6 +1242,8 @@ ST_FUNC void build_got_entries(TCCState *s1) · 64 unmodified lines
1235 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||1242 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1236 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||1243 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1237 s1->output_type == TCC_OUTPUT_EXE)) {1244 s1->output_type == TCC_OUTPUT_EXE)) {
1245 if (pass == 0)
1246 continue;
1238 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);1247 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1239 continue;1248 continue;
1240 }1249 }
@@ -1248,6 +1257,11 @@ ST_FUNC void build_got_entries(TCCState *s1) · 7 unmodified lines
1248 } else1257 } else
1249 reloc_type = R_GLOB_DAT;1258 reloc_type = R_GLOB_DAT;
1250 1259
1260
1261 if ((pass == 0 && reloc_type == R_GLOB_DAT) ||
1262 (pass == 1 && reloc_type == R_JMP_SLOT))
1263 continue;
1264
1251 if (!s1->got)1265 if (!s1->got)
1252 build_got(s1);1266 build_got(s1);
1253 1267
@@ -1261,6 +1275,16 @@ ST_FUNC void build_got_entries(TCCState *s1) · 7 unmodified lines
1261 }1275 }
1262 }1276 }
1263}1277}
1278
1279ST_FUNC void build_got_entries(TCCState *s1)
1280{
1281 int i;
1282
1283 /* Two passes because R_JMP_SLOT should become first.
1284 Some targets (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1285 for (i = 0; i < 2; i++)
1286 build_got_entries_pass(s1, i);
1287}
1264#endif1288#endif
1265 1289
1266ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)1290ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
@@ -1801,7 +1825,7 @@ struct dyn_inf { · 534 unmodified lines
1801 unsigned long data_offset;1825 unsigned long data_offset;
1802 addr_t rel_addr;1826 addr_t rel_addr;
1803 addr_t rel_size;1827 addr_t rel_size;
1804#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel1828#if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
1805 addr_t bss_addr;1829 addr_t bss_addr;
1806 addr_t bss_size;1830 addr_t bss_size;
1807#endif1831#endif
@@ -1861,11 +1885,13 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 53 unmodified lines
1861 1885
1862 /* dynamic relocation table information, for .dynamic section */1886 /* dynamic relocation table information, for .dynamic section */
1863 dyninf->rel_addr = dyninf->rel_size = 0;1887 dyninf->rel_addr = dyninf->rel_size = 0;
1864#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel1888#if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
1865 dyninf->bss_addr = dyninf->bss_size = 0;1889 dyninf->bss_addr = dyninf->bss_size = 0;
1866#endif1890#endif
1867 1891
1868 for(j = 0; j < (phnum == 6 ? 3 : 2); j++) {1892 for(j = 0; j < (phnum == 6 ? 3 : 2); j++) {
1893 Section *relocplt = s1->got ? s1->got->relocplt : NULL;
1894
1869 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;1895 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1870 if (j == 0)1896 if (j == 0)
1871 ph->p_flags = PF_R | PF_X;1897 ph->p_flags = PF_R | PF_X;
@@ -1878,7 +1904,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 6 unmodified lines
1878 info about the layout. We do the following ordering: interp,1904 info about the layout. We do the following ordering: interp,
1879 symbol tables, relocations, progbits, nobits */1905 symbol tables, relocations, progbits, nobits */
1880 /* XXX: do faster and simpler sorting */1906 /* XXX: do faster and simpler sorting */
1881 for(k = 0; k < 5; k++) {1907 for(k = 0; k < 6; k++) {
1882 for(i = 1; i < s1->nb_sections; i++) {1908 for(i = 1; i < s1->nb_sections; i++) {
1883 s = s1->sections[i];1909 s = s1->sections[i];
1884 /* compute if section should be included */1910 /* compute if section should be included */
@@ -1905,13 +1931,15 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 20 unmodified lines
1905 if (k != 1)1931 if (k != 1)
1906 continue;1932 continue;
1907 } else if (s->sh_type == SHT_RELX) {1933 } else if (s->sh_type == SHT_RELX) {
1908 if (k != 2)1934 if (k != 2 && s != relocplt)
1935 continue;
1936 else if (k != 3 && s == relocplt)
1909 continue;1937 continue;
1910 } else if (s->sh_type == SHT_NOBITS) {1938 } else if (s->sh_type == SHT_NOBITS) {
1911 if (k != 4)1939 if (k != 5)
1912 continue;1940 continue;
1913 } else {1941 } else {
1914 if (k != 3)1942 if (k != 4)
1915 continue;1943 continue;
1916 }1944 }
1917 sec_order[sh_order_index++] = i;1945 sec_order[sh_order_index++] = i;
@@ -1931,8 +1959,8 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 13 unmodified lines
1931 ph->p_paddr = ph->p_vaddr;1959 ph->p_paddr = ph->p_vaddr;
1932 }1960 }
1933 /* update dynamic relocation infos */1961 /* update dynamic relocation infos */
1934 if (s->sh_type == SHT_RELX) {1962 if (s->sh_type == SHT_RELX && s != relocplt) {
1935#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel1963#if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
1936 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {1964 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1937 dyninf->rel_addr = addr;1965 dyninf->rel_addr = addr;
1938 dyninf->rel_size += s->sh_size; /* XXX only first rel. */1966 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
@@ -2079,16 +2107,17 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) · 140 unmodified lines
2079 put_dt(dynamic, DT_RELA, dyninf->rel_addr);2107 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2080 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);2108 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2081 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));2109 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2082#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD2110 if (s1->got && s1->got->relocplt) {
2083 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);2111 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2084 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);2112 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2085 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);2113 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2086 put_dt(dynamic, DT_PLTREL, DT_RELA);2114 put_dt(dynamic, DT_PLTREL, DT_RELA);
2087 put_dt(dynamic, DT_BIND_NOW, 1); /* Dirty hack */2115 }
2088#endif2116 put_dt(dynamic, DT_RELACOUNT, 0);
2089#else2117#else
2090#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel2118#if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
2091 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);2119 if (s1->got)
2120 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2092 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);2121 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2093 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);2122 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2094 put_dt(dynamic, DT_PLTREL, DT_REL);2123 put_dt(dynamic, DT_PLTREL, DT_REL);
@@ -2098,11 +2127,18 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) · 3 unmodified lines
2098 put_dt(dynamic, DT_REL, dyninf->rel_addr);2127 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2099 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);2128 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2100 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));2129 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2130 if (s1->got && s1->got->relocplt) {
2131 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2132 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2133 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2134 put_dt(dynamic, DT_PLTREL, DT_REL);
2135 }
2136 put_dt(dynamic, DT_RELCOUNT, 0);
2101#endif2137#endif
2102#endif2138#endif
2103 if (versym_section)2139 if (versym_section && verneed_section) {
2140 /* The dynamic linker can not handle VERSYM without VERNEED */
2104 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);2141 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2105 if (verneed_section) {
2106 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);2142 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2107 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);2143 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2108 }2144 }
@@ -2406,10 +2442,12 @@ static void create_arm_attribute_section(TCCState *s1) · 297 unmodified lines
2406}2442}
2407#endif2443#endif
2408 2444
2409#if TARGETOS_OpenBSD2445#if TARGETOS_OpenBSD || TARGETOS_NetBSD
2410static Section *create_openbsd_note_section(TCCState *s1)2446static Section *create_bsd_note_section(TCCState *s1,
2447 const char *name,
2448 const char *value)
2411{2449{
2412 Section *s = find_section (s1, ".note.openbsd.ident");2450 Section *s = find_section (s1, name);
2413 2451
2414 if (s->data_offset == 0) {2452 if (s->data_offset == 0) {
2415 unsigned char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);2453 unsigned char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
@@ -2419,7 +2457,7 @@ static Section *create_openbsd_note_section(TCCState *s1) · 3 unmodified lines
2419 note->n_namesz = 8;2457 note->n_namesz = 8;
2420 note->n_descsz = 4;2458 note->n_descsz = 4;
2421 note->n_type = ELF_NOTE_OS_GNU;2459 note->n_type = ELF_NOTE_OS_GNU;
2422 strcpy (ptr + sizeof(ElfW(Nhdr)), "OpenBSD");2460 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2423 }2461 }
2424 return s;2462 return s;
2425}2463}
@@ -2441,7 +2479,11 @@ static int elf_output_file(TCCState *s1, const char *filename) · 15 unmodified lines
2441#endif2479#endif
2442#if TARGETOS_OpenBSD2480#if TARGETOS_OpenBSD
2443 if (file_type != TCC_OUTPUT_OBJ)2481 if (file_type != TCC_OUTPUT_OBJ)
2444 note = create_openbsd_note_section (s1);2482 note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2483#endif
2484#if TARGETOS_NetBSD
2485 if (file_type != TCC_OUTPUT_OBJ)
2486 note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2445#endif2487#endif
2446 2488
2447 s1->nb_errors = 0;2489 s1->nb_errors = 0;
@@ -2814,8 +2856,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 366 unmodified lines
2814 sm_table[i].new_section = 1;2856 sm_table[i].new_section = 1;
2815 found:2857 found:
2816 if (sh->sh_type != s->sh_type) {2858 if (sh->sh_type != s->sh_type) {
2817 tcc_error_noabort("invalid section type");2859#if TARGETOS_OpenBSD
2818 goto fail;2860 if (strcmp (s->name, ".eh_frame") || sh->sh_type != SHT_PROGBITS)
2861#endif
2862 {
2863 tcc_error_noabort("invalid section type");
2864 goto fail;
2865 }
2819 }2866 }
2820 /* align start of section */2867 /* align start of section */
2821 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);2868 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
tests/Makefile+3−0
@@ -61,6 +61,9 @@ endif · 60 unmodified lines
61ifeq ($(CC_NAME),msvc)61ifeq ($(CC_NAME),msvc)
62test.ref abitest : CC = gcc62test.ref abitest : CC = gcc
63endif63endif
64ifeq ($(TARGETOS),OpenBSD)
65dlltest: CFLAGS+=-fno-stack-protector
66endif
64 67
65RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)68RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)
66DISAS = objdump -d69DISAS = objdump -d
tests/tests2/Makefile+4−0
@@ -48,6 +48,10 @@ ifeq (-$(CONFIG_WIN32)-,-yes-) · 47 unmodified lines
48 SKIP += 106_pthread.test # No pthread support48 SKIP += 106_pthread.test # No pthread support
49 SKIP += 114_bound_signal.test # No pthread support49 SKIP += 114_bound_signal.test # No pthread support
50endif50endif
51ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS)))
52 SKIP += 106_pthread.test # no pthread_condattr_setpshared
53 SKIP += 114_bound_signal.test # libc problem signal/fork
54endif
51 55
52# Some tests might need arguments56# Some tests might need arguments
53ARGS =57ARGS =
x86_64-link.c+16−2
@@ -131,7 +131,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 130 unmodified lines
131 /* The PLT slot refers to the relocation entry it needs via offset.131 /* The PLT slot refers to the relocation entry it needs via offset.
132 The reloc entry is created below, so its offset is the current132 The reloc entry is created below, so its offset is the current
133 data_offset */133 data_offset */
134 relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;134 relofs = s1->got->relocplt ? s1->got->relocplt->data_offset : 0;
135 135
136 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */136 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
137 p = section_ptr_add(plt, 16);137 p = section_ptr_add(plt, 16);
@@ -140,7 +140,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 2 unmodified lines
140 write32le(p + 2, got_offset);140 write32le(p + 2, got_offset);
141 p[6] = 0x68; /* push $xxx */141 p[6] = 0x68; /* push $xxx */
142 /* On x86-64, the relocation is referred to by _index_ */142 /* On x86-64, the relocation is referred to by _index_ */
143 write32le(p + 7, relofs / sizeof (ElfW_Rel));143 write32le(p + 7, relofs / sizeof (ElfW_Rel) - 1);
144 p[11] = 0xe9; /* jmp plt_start */144 p[11] = 0xe9; /* jmp plt_start */
145 write32le(p + 12, -(plt->data_offset));145 write32le(p + 12, -(plt->data_offset));
146 return plt_offset;146 return plt_offset;
@@ -168,6 +168,20 @@ ST_FUNC void relocate_plt(TCCState *s1) · 21 unmodified lines
168 p += 16;168 p += 16;
169 }169 }
170 }170 }
171
172 if (s1->got->relocplt) {
173 int mem = s1->output_type == TCC_OUTPUT_MEMORY;
174 ElfW_Rel *rel;
175 int x = s1->plt->sh_addr + 16 + 6;
176
177 p = s1->got->data;
178 for_each_elem(s1->got->relocplt, 0, rel, ElfW_Rel) {
179 int sym_index = ELFW(R_SYM)(rel->r_info);
180 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
181 write64le(p + rel->r_offset, mem ? sym->st_value : x);
182 x += 16;
183 }
184 }
171}185}
172#endif186#endif
173#endif187#endif

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