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
145145
146146 if (p < p_end) {
147147 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);
149149 p += 20;
150150 while (p < p_end) {
151151 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
157157 p += 12;
158158 }
159159 }
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+ }
160172 }
161173 #endif
162174
arm64-link.c+14−1
@@ -113,7 +113,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 112 unmodified lines
113113
114114 if (p < p_end) {
115115 uint64_t plt = s1->plt->sh_addr;
116− uint64_t got = s1->got->sh_addr;
116+ uint64_t got = s1->got->sh_addr + 16;
117117 uint64_t off = (got >> 12) - (plt >> 12);
118118 if ((off + ((uint32_t)1 << 20)) >> 21)
119119 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
129129 write32le(p + 24, 0xd503201f); // nop
130130 write32le(p + 28, 0xd503201f); // nop
131131 p += 32;
132+ got = s1->got->sh_addr;
132133 while (p < p_end) {
133134 uint64_t pc = plt + (p - s1->plt->data);
134135 uint64_t addr = got + read64le(p);
@@ -145,6 +146,18 @@ ST_FUNC void relocate_plt(TCCState *s1) · 10 unmodified lines
145146 p += 16;
146147 }
147148 }
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+ }
148161 }
149162
150163 void 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
1616 #define ELF_PAGE_SIZE 0x1000
1717
1818 #define PCRELATIVE_DLLPLT 0
19−#define RELOCATE_DLLPLT 0
19+#define RELOCATE_DLLPLT 1
2020
2121 #else /* !TARGET_DEFS_ONLY */
2222
@@ -121,7 +121,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 98 unmodified lines
121121 /* The PLT slot refers to the relocation entry it needs via offset.
122122 The reloc entry is created below, so its offset is the current
123123 data_offset */
124− relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
124+ relofs = s1->got->relocplt ? s1->got->relocplt->data_offset : 0;
125125
126126 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
127127 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
129129 p[1] = modrm;
130130 write32le(p + 2, got_offset);
131131 p[6] = 0x68; /* push $xxx */
132− write32le(p + 7, relofs);
132+ write32le(p + 7, relofs - sizeof (ElfW_Rel));
133133 p[11] = 0xe9; /* jmp plt_start */
134134 write32le(p + 12, -(plt->data_offset));
135135 return plt_offset;
@@ -147,7 +147,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 11 unmodified lines
147147 p = s1->plt->data;
148148 p_end = p + s1->plt->data_offset;
149149
150− if (p < p_end) {
150+ if (s1->output_type != TCC_OUTPUT_DLL && p < p_end) {
151151 add32le(p + 2, s1->got->sh_addr);
152152 add32le(p + 8, s1->got->sh_addr);
153153 p += 16;
@@ -156,6 +156,20 @@ ST_FUNC void relocate_plt(TCCState *s1) · 2 unmodified lines
156156 p += 16;
157157 }
158158 }
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+ }
159173 }
160174 #endif
161175
lib/bcheck.c+2−1
@@ -1153,7 +1153,8 @@ void __attribute__((destructor)) __bound_exit(void) · 1152 unmodified lines
11531153 dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__);
11541154
11551155 if (inited) {
1156−#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__) && !defined TCC_MUSL
1156+#if !defined(_WIN32) && !defined(__APPLE__) && !defined TCC_MUSL && \
1157+ !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
11571158 if (print_heap) {
11581159 extern void __libc_freeres (void);
11591160 __libc_freeres ();
riscv64-link.c+12−0
@@ -153,6 +153,18 @@ ST_FUNC void relocate_plt(TCCState *s1) · 152 unmodified lines
153153 p += 16;
154154 }
155155 }
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+ }
156168 }
157169
158170 void 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
397397 # define ElfW_Rel ElfW(Rela)
398398 # define SHT_RELX SHT_RELA
399399 # define REL_SECTION_FMT ".rela%s"
400+# define RELPLT_SECTION_FMT ".rel.plt"
400401 #else
401402 # define ELFCLASSW ELFCLASS32
402403 # define ElfW(type) Elf##32##_##type
@@ -404,6 +405,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 1 unmodified line
404405 # define ElfW_Rel ElfW(Rel)
405406 # define SHT_RELX SHT_REL
406407 # define REL_SECTION_FMT ".rel%s"
408+# define RELPLT_SECTION_FMT ".rel.plt"
407409 #endif
408410 /* target address type */
409411 #define addr_t ElfW(Addr)
@@ -565,6 +567,7 @@ typedef struct Section { · 155 unmodified lines
565567 struct Section *reloc; /* corresponding section for relocation, if any */
566568 struct Section *hash; /* hash table for symbols */
567569 struct Section *prev; /* previous section on section stack */
570+ struct Section *relocplt;/* reloc with JMP_SLOTs */
568571 char name[1]; /* section name */
569572 } Section;
570573
tccelf.c+77−30
@@ -735,18 +735,25 @@ ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, · 734 unmodified lines
735735 char buf[256];
736736 Section *sr;
737737 ElfW_Rel *rel;
738+ int jmp_slot = type == R_JMP_SLOT;
738739
739− sr = s->reloc;
740+ sr = jmp_slot ? s->relocplt : s->reloc;
740741 if (!sr) {
741742 /* 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);
743747 /* if the symtab is allocated, then we consider the relocation
744748 are also */
745749 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
746750 sr->sh_entsize = sizeof(ElfW_Rel);
747751 sr->link = symtab;
748752 sr->sh_info = s->sh_num;
749− s->reloc = sr;
753+ if (jmp_slot)
754+ s->relocplt = sr;
755+ else
756+ s->reloc = sr;
750757 }
751758 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
752759 rel->r_offset = offset;
@@ -1164,7 +1171,7 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type, · 411 unmodified lines
11641171 }
11651172
11661173 /* build GOT and PLT entries */
1167−ST_FUNC void build_got_entries(TCCState *s1)
1174+static void build_got_entries_pass(TCCState *s1, int pass)
11681175 {
11691176 Section *s;
11701177 ElfW_Rel *rel;
@@ -1235,6 +1242,8 @@ ST_FUNC void build_got_entries(TCCState *s1) · 64 unmodified lines
12351242 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
12361243 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
12371244 s1->output_type == TCC_OUTPUT_EXE)) {
1245+ if (pass == 0)
1246+ continue;
12381247 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
12391248 continue;
12401249 }
@@ -1248,6 +1257,11 @@ ST_FUNC void build_got_entries(TCCState *s1) · 7 unmodified lines
12481257 } else
12491258 reloc_type = R_GLOB_DAT;
12501259
1260+
1261+ if ((pass == 0 && reloc_type == R_GLOB_DAT) ||
1262+ (pass == 1 && reloc_type == R_JMP_SLOT))
1263+ continue;
1264+
12511265 if (!s1->got)
12521266 build_got(s1);
12531267
@@ -1261,6 +1275,16 @@ ST_FUNC void build_got_entries(TCCState *s1) · 7 unmodified lines
12611275 }
12621276 }
12631277 }
1278+
1279+ST_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+}
12641288 #endif
12651289
12661290 ST_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
18011825 unsigned long data_offset;
18021826 addr_t rel_addr;
18031827 addr_t rel_size;
1804−#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
1828+#if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
18051829 addr_t bss_addr;
18061830 addr_t bss_size;
18071831 #endif
@@ -1861,11 +1885,13 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 53 unmodified lines
18611885
18621886 /* dynamic relocation table information, for .dynamic section */
18631887 dyninf->rel_addr = dyninf->rel_size = 0;
1864−#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
1888+#if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
18651889 dyninf->bss_addr = dyninf->bss_size = 0;
18661890 #endif
18671891
18681892 for(j = 0; j < (phnum == 6 ? 3 : 2); j++) {
1893+ Section *relocplt = s1->got ? s1->got->relocplt : NULL;
1894+
18691895 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
18701896 if (j == 0)
18711897 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
18781904 info about the layout. We do the following ordering: interp,
18791905 symbol tables, relocations, progbits, nobits */
18801906 /* XXX: do faster and simpler sorting */
1881− for(k = 0; k < 5; k++) {
1907+ for(k = 0; k < 6; k++) {
18821908 for(i = 1; i < s1->nb_sections; i++) {
18831909 s = s1->sections[i];
18841910 /* compute if section should be included */
@@ -1905,13 +1931,15 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 20 unmodified lines
19051931 if (k != 1)
19061932 continue;
19071933 } 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)
19091937 continue;
19101938 } else if (s->sh_type == SHT_NOBITS) {
1911− if (k != 4)
1939+ if (k != 5)
19121940 continue;
19131941 } else {
1914− if (k != 3)
1942+ if (k != 4)
19151943 continue;
19161944 }
19171945 sec_order[sh_order_index++] = i;
@@ -1931,8 +1959,8 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 13 unmodified lines
19311959 ph->p_paddr = ph->p_vaddr;
19321960 }
19331961 /* update dynamic relocation infos */
1934− if (s->sh_type == SHT_RELX) {
1935−#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
1962+ if (s->sh_type == SHT_RELX && s != relocplt) {
1963+#if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
19361964 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
19371965 dyninf->rel_addr = addr;
19381966 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
20792107 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
20802108 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
20812109 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2082−#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2083− put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2084− put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2085− put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2086− put_dt(dynamic, DT_PLTREL, DT_RELA);
2087− put_dt(dynamic, DT_BIND_NOW, 1); /* Dirty hack */
2088−#endif
2110+ if (s1->got && s1->got->relocplt) {
2111+ put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2112+ put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2113+ put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2114+ put_dt(dynamic, DT_PLTREL, DT_RELA);
2115+ }
2116+ put_dt(dynamic, DT_RELACOUNT, 0);
20892117 #else
2090−#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2091− put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2118+#if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
2119+ if (s1->got)
2120+ put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
20922121 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
20932122 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
20942123 put_dt(dynamic, DT_PLTREL, DT_REL);
@@ -2098,11 +2127,18 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) · 3 unmodified lines
20982127 put_dt(dynamic, DT_REL, dyninf->rel_addr);
20992128 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
21002129 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);
21012137 #endif
21022138 #endif
2103− if (versym_section)
2139+ if (versym_section && verneed_section) {
2140+ /* The dynamic linker can not handle VERSYM without VERNEED */
21042141 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2105− if (verneed_section) {
21062142 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
21072143 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
21082144 }
@@ -2406,10 +2442,12 @@ static void create_arm_attribute_section(TCCState *s1) · 297 unmodified lines
24062442 }
24072443 #endif
24082444
2409−#if TARGETOS_OpenBSD
2410−static Section *create_openbsd_note_section(TCCState *s1)
2445+#if TARGETOS_OpenBSD || TARGETOS_NetBSD
2446+static Section *create_bsd_note_section(TCCState *s1,
2447+ const char *name,
2448+ const char *value)
24112449 {
2412− Section *s = find_section (s1, ".note.openbsd.ident");
2450+ Section *s = find_section (s1, name);
24132451
24142452 if (s->data_offset == 0) {
24152453 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
24192457 note->n_namesz = 8;
24202458 note->n_descsz = 4;
24212459 note->n_type = ELF_NOTE_OS_GNU;
2422− strcpy (ptr + sizeof(ElfW(Nhdr)), "OpenBSD");
2460+ strcpy (ptr + sizeof(ElfW(Nhdr)), value);
24232461 }
24242462 return s;
24252463 }
@@ -2441,7 +2479,11 @@ static int elf_output_file(TCCState *s1, const char *filename) · 15 unmodified lines
24412479 #endif
24422480 #if TARGETOS_OpenBSD
24432481 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");
24452487 #endif
24462488
24472489 s1->nb_errors = 0;
@@ -2814,8 +2856,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 366 unmodified lines
28142856 sm_table[i].new_section = 1;
28152857 found:
28162858 if (sh->sh_type != s->sh_type) {
2817− tcc_error_noabort("invalid section type");
2818− goto fail;
2859+#if TARGETOS_OpenBSD
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+ }
28192866 }
28202867 /* align start of section */
28212868 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
tests/Makefile+3−0
@@ -61,6 +61,9 @@ endif · 60 unmodified lines
6161 ifeq ($(CC_NAME),msvc)
6262 test.ref abitest : CC = gcc
6363 endif
64+ifeq ($(TARGETOS),OpenBSD)
65+dlltest: CFLAGS+=-fno-stack-protector
66+endif
6467
6568 RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)
6669 DISAS = objdump -d
tests/tests2/Makefile+4−0
@@ -48,6 +48,10 @@ ifeq (-$(CONFIG_WIN32)-,-yes-) · 47 unmodified lines
4848 SKIP += 106_pthread.test # No pthread support
4949 SKIP += 114_bound_signal.test # No pthread support
5050 endif
51+ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS)))
52+ SKIP += 106_pthread.test # no pthread_condattr_setpshared
53+ SKIP += 114_bound_signal.test # libc problem signal/fork
54+endif
5155
5256 # Some tests might need arguments
5357 ARGS =
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
131131 /* The PLT slot refers to the relocation entry it needs via offset.
132132 The reloc entry is created below, so its offset is the current
133133 data_offset */
134− relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
134+ relofs = s1->got->relocplt ? s1->got->relocplt->data_offset : 0;
135135
136136 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
137137 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
140140 write32le(p + 2, got_offset);
141141 p[6] = 0x68; /* push $xxx */
142142 /* 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);
144144 p[11] = 0xe9; /* jmp plt_start */
145145 write32le(p + 12, -(plt->data_offset));
146146 return plt_offset;
@@ -168,6 +168,20 @@ ST_FUNC void relocate_plt(TCCState *s1) · 21 unmodified lines
168168 p += 16;
169169 }
170170 }
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+ }
171185 }
172186 #endif
173187 #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