History

review generic tls support

*-link.c: remove stupid loops tccelf.c: ...also tccgen.c: create .tdata/.tbss sections only when needed

grischka committed 4 months ago

Commit 56730551 parent 7f7845c9 files · +86 −213Browse files

Unified · Split

9 files
  1. arm-link.c +4 −21
  2. arm64-link.c +1 −10
  3. i386-link.c +4 −23
  4. riscv64-link.c +1 −11
  5. tcc.h +2 −3
  6. tccelf.c +55 −84
  7. tccgen.c +3 −4
  8. tests/tests2/Makefile +2 −2
  9. x86_64-link.c +14 −55
arm-link.c+4−21
@@ -434,29 +434,12 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 433 unmodified lines
434 return;434 return;
435 case R_ARM_TLS_LE32:435 case R_ARM_TLS_LE32:
436 {436 {
437 ElfW(Sym) *sym;
438 Section *sec;
439 int32_t x;437 int32_t x;
440 addr_t tls_start = 0, tls_end = 0, tls_align = 1;438 if (s1->tls_end) {
441 int i;439 x = val - s1->tls_start + 8;
442
443 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
444 sec = s1->sections[sym->st_shndx];
445
446 for (i = 1; i < s1->nb_sections; i++) {
447 Section *s = s1->sections[i];
448 if (s->sh_flags & SHF_TLS && s->sh_size) {
449 if (!tls_start || s->sh_addr < tls_start)
450 tls_start = s->sh_addr;
451 if (s->sh_addr + s->sh_size > tls_end)
452 tls_end = s->sh_addr + s->sh_size;
453 if (s->sh_addralign > tls_align)
454 tls_align = s->sh_addralign;
455 }
456 }
457 if (tls_end > tls_start) {
458 x = val - tls_start + 8;
459 } else {440 } else {
441 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
442 Section *sec = s1->sections[sym->st_shndx];
460 x = val - sec->sh_addr - sec->data_offset + 8;443 x = val - sec->sh_addr - sec->data_offset + 8;
461 }444 }
462 add32le(ptr, x);445 add32le(ptr, x);
arm64-link.c+1−10
@@ -371,17 +371,8 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 370 unmodified lines
371 return;371 return;
372 case R_AARCH64_TLSLE_ADD_TPREL_HI12:372 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
373 case R_AARCH64_TLSLE_ADD_TPREL_LO12: {373 case R_AARCH64_TLSLE_ADD_TPREL_LO12: {
374 addr_t tls_start = 0;
375 int i;
376 for (i = 1; i < s1->nb_sections; i++) {
377 Section *s = s1->sections[i];
378 if (s->sh_flags & SHF_TLS && s->sh_size) {
379 if (!tls_start || s->sh_addr < tls_start)
380 tls_start = s->sh_addr;
381 }
382 }
383 /* glibc arm64: tp points to tcbhead_t (DTV), TLS data starts after it */374 /* glibc arm64: tp points to tcbhead_t (DTV), TLS data starts after it */
384 int64_t tp_offset = val - tls_start + 16;375 int64_t tp_offset = val - s1->tls_start + 16;
385 int64_t imm;376 int64_t imm;
386 if (type == R_AARCH64_TLSLE_ADD_TPREL_HI12)377 if (type == R_AARCH64_TLSLE_ADD_TPREL_HI12)
387 imm = (tp_offset >> 12) & 0xfff;378 imm = (tp_offset >> 12) & 0xfff;
i386-link.c+4−23
@@ -318,31 +318,12 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 317 unmodified lines
318 return;318 return;
319 case R_386_TLS_LE:319 case R_386_TLS_LE:
320 {320 {
321 ElfW(Sym) *sym;
322 Section *sec;
323 int32_t x;321 int32_t x;
324 addr_t tls_start = 0, tls_end = 0, tls_align = 1;322 if (s1->tls_end) {
325 int i;323 x = val - s1->tls_end;
326
327 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
328 sec = s1->sections[sym->st_shndx];
329
330 for (i = 1; i < s1->nb_sections; i++) {
331 Section *s = s1->sections[i];
332 if (s->sh_flags & SHF_TLS && s->sh_size) {
333 if (!tls_start || s->sh_addr < tls_start)
334 tls_start = s->sh_addr;
335 if (s->sh_addr + s->sh_size > tls_end)
336 tls_end = s->sh_addr + s->sh_size;
337 if (s->sh_addralign > tls_align)
338 tls_align = s->sh_addralign;
339 }
340 }
341 if (tls_end > tls_start) {
342 addr_t tls_size = tls_end - tls_start;
343 addr_t aligned_size = (tls_size + tls_align - 1) & ~(tls_align - 1);
344 x = val - (tls_start + aligned_size);
345 } else {324 } else {
325 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
326 Section *sec = s1->sections[sym->st_shndx];
346 x = val - sec->sh_addr - sec->data_offset;327 x = val - sec->sh_addr - sec->data_offset;
347 }328 }
348 add32le(ptr, x);329 add32le(ptr, x);
riscv64-link.c+1−11
@@ -407,17 +407,7 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 406 unmodified lines
407 407
408 case R_RISCV_TPREL_HI20:408 case R_RISCV_TPREL_HI20:
409 case R_RISCV_TPREL_LO12_I: {409 case R_RISCV_TPREL_LO12_I: {
410 addr_t tls_start = 0;410 int64_t tp_offset = val - s1->tls_start;
411 int64_t tp_offset;
412 int i;
413 for (i = 1; i < s1->nb_sections; i++) {
414 Section *s = s1->sections[i];
415 if (s->sh_flags & SHF_TLS && s->sh_size) {
416 if (!tls_start || s->sh_addr < tls_start)
417 tls_start = s->sh_addr;
418 }
419 }
420 tp_offset = val - tls_start;
421 if (type == R_RISCV_TPREL_HI20) {411 if (type == R_RISCV_TPREL_HI20) {
422 off64 = (int64_t)(tp_offset + 0x800) >> 12;412 off64 = (int64_t)(tp_offset + 0x800) >> 12;
423 if ((off64 + ((uint64_t)1 << 20)) >> 21)413 if ((off64 + ((uint64_t)1 << 20)) >> 21)
tcc.h+2−3
@@ -889,7 +889,6 @@ struct TCCState { · 888 unmodified lines
889 889
890 /* predefined sections */890 /* predefined sections */
891 Section *text_section, *data_section, *rodata_section, *bss_section;891 Section *text_section, *data_section, *rodata_section, *bss_section;
892 Section *tdata_section, *tbss_section;
893 Section *common_section;892 Section *common_section;
894 Section *cur_text_section; /* current section where function code is generated */893 Section *cur_text_section; /* current section where function code is generated */
895#ifdef CONFIG_TCC_BCHECK894#ifdef CONFIG_TCC_BCHECK
@@ -930,6 +929,8 @@ struct TCCState { · 34 unmodified lines
930 ElfW_Rel *qrel;929 ElfW_Rel *qrel;
931 #define qrel s1->qrel930 #define qrel s1->qrel
932 931
932 addr_t tls_start, tls_end;
933
933#ifdef TCC_TARGET_RISCV64934#ifdef TCC_TARGET_RISCV64
934 struct pcrel_hi { addr_t addr, val; } **pcrel_hi_entries;935 struct pcrel_hi { addr_t addr, val; } **pcrel_hi_entries;
935 int nb_pcrel_hi_entries;936 int nb_pcrel_hi_entries;
@@ -1979,8 +1980,6 @@ static inline void post_sem(TCCSem *p) { · 1043 unmodified lines
1979#define data_section TCC_STATE_VAR(data_section)1980#define data_section TCC_STATE_VAR(data_section)
1980#define rodata_section TCC_STATE_VAR(rodata_section)1981#define rodata_section TCC_STATE_VAR(rodata_section)
1981#define bss_section TCC_STATE_VAR(bss_section)1982#define bss_section TCC_STATE_VAR(bss_section)
1982#define tdata_section TCC_STATE_VAR(tdata_section)
1983#define tbss_section TCC_STATE_VAR(tbss_section)
1984#define common_section TCC_STATE_VAR(common_section)1983#define common_section TCC_STATE_VAR(common_section)
1985#define cur_text_section TCC_STATE_VAR(cur_text_section)1984#define cur_text_section TCC_STATE_VAR(cur_text_section)
1986#define bounds_section TCC_STATE_VAR(bounds_section)1985#define bounds_section TCC_STATE_VAR(bounds_section)
tccelf.c+55−84
@@ -70,8 +70,6 @@ ST_FUNC void tccelf_new(TCCState *s) · 69 unmodified lines
70 /* create ro data section (make ro after relocation done with GNU_RELRO) */70 /* create ro data section (make ro after relocation done with GNU_RELRO) */
71 rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);71 rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);
72 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);72 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
73 tdata_section = new_section(s, ".tdata", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE | SHF_TLS);
74 tbss_section = new_section(s, ".tbss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE | SHF_TLS);
75 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);73 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
76 common_section->sh_num = SHN_COMMON;74 common_section->sh_num = SHN_COMMON;
77 75
@@ -2198,12 +2196,11 @@ struct dyn_inf { · 2120 unmodified lines
2198 ElfW(Phdr) *phdr;2196 ElfW(Phdr) *phdr;
2199 int phnum;2197 int phnum;
2200 int shnum;2198 int shnum;
2199 int tls;
2200 int relro;
2201 Section *interp;2201 Section *interp;
2202 Section *note;2202 Section *note;
2203 Section *gnu_hash;2203 Section *gnu_hash;
2204
2205 /* read only segment mapping for GNU_RELRO */
2206 Section _roinf, *roinf;
2207};2204};
2208 2205
2209/* Decide the layout of sections loaded in memory. This must be done before2206/* Decide the layout of sections loaded in memory. This must be done before
@@ -2226,7 +2223,7 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 16 unmodified lines
2226 if (s->sh_flags & SHF_WRITE)2223 if (s->sh_flags & SHF_WRITE)
2227 j = 0x200;2224 j = 0x200;
2228 if (s->sh_flags & SHF_TLS)2225 if (s->sh_flags & SHF_TLS)
2229 j += 0x200;2226 j = 0x300;
2230 } else {2227 } else {
2231 j = 0x700;2228 j = 0x700;
2232 }2229 }
@@ -2287,6 +2284,9 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 54 unmodified lines
2287 sec_order[0] = 0;2284 sec_order[0] = 0;
2288 d->shnum = 1;2285 d->shnum = 1;
2289 2286
2287#define SHFX_NEWPH (1 << 4)
2288#define SHFX_RELRO (1 << 5)
2289
2290 /* count PT_LOAD headers needed */2290 /* count PT_LOAD headers needed */
2291 n = f0 = 0;2291 n = f0 = 0;
2292 for (i = 1; i < nb_sections; i++) {2292 for (i = 1; i < nb_sections; i++) {
@@ -2297,18 +2297,21 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 4 unmodified lines
2297 ++d->shnum;2297 ++d->shnum;
2298 if (k < 0x700) {2298 if (k < 0x700) {
2299 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR);2299 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR);
2300#if TARGETOS_NetBSD2300#if TARGETOS_NetBSD || TARGETOS_FreeBSD
2301 /* NetBSD only supports 2 PT_LOAD sections.2301 /* NetBSD only supports 2 PT_LOAD sections.
2302 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */2302 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2303 if ((f & SHF_WRITE) == 0)2303 if ((f & SHF_WRITE) == 0)
2304 f |= SHF_EXECINSTR;2304 f |= SHF_EXECINSTR;
2305#else2305#else
2306 if ((k & 0xfff0) == 0x240) /* RELRO sections */2306 if ((k & 0xfff0) == 0x240) /* RELRO sections */
2307 f |= 1<<4;2307 d->relro = 1, f |= SHFX_RELRO;
2308#endif2308#endif
2309 /* start new header when flags changed or relro, but avoid zero memsz */2309 /* start new header when flags changed or relro, but avoid zero memsz */
2310 if (f != f0 && s->sh_size)2310 if (f != f0 && s->sh_size)
2311 f0 = f, ++n, f |= 1<<8;2311 f0 = f, ++n, f |= SHFX_NEWPH;
2312
2313 if ((s->sh_flags & SHF_TLS) && s->sh_size)
2314 d->tls = 1, f |= SHF_TLS;
2312 }2315 }
2313 sec_cls[i] = f;2316 sec_cls[i] = f;
2314 //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", (f>0) * n, i, f, k, s->sh_type, (int)s->sh_size, s->name);2317 //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", (f>0) * n, i, f, k, s->sh_type, (int)s->sh_size, s->name);
@@ -2331,13 +2334,24 @@ static ElfW(Phdr) *fill_phdr(ElfW(Phdr) *ph, int type, Section *s) · 16 unmodified lines
2331 return ph;2334 return ph;
2332}2335}
2333 2336
2337static ElfW(Phdr) *update_phdr(ElfW(Phdr) *ph, int type, Section *s, addr_t addr, int file_offset)
2338{
2339 if (ph->p_type == 0) {
2340 fill_phdr(ph, type, s);
2341 ph->p_flags |= PF_W;
2342 }
2343 ph->p_filesz = file_offset - ph->p_offset;
2344 ph->p_memsz = addr - ph->p_vaddr;
2345 return ph;
2346}
2347
2334/* Assign sections to segments and decide how are sections laid out when loaded2348/* Assign sections to segments and decide how are sections laid out when loaded
2335 in memory. This function also fills corresponding program headers. */2349 in memory. This function also fills corresponding program headers. */
2336static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)2350static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
2337{2351{
2338 Section *s;2352 Section *s;
2339 addr_t addr, tmp, align, s_align, base;2353 addr_t addr, tmp, align, s_align, base;
2340 ElfW(Phdr) *ph = NULL;2354 ElfW(Phdr) *ph = NULL, *ph2;
2341 int i, f, n, phnum, phfill;2355 int i, f, n, phnum, phfill;
2342 int file_offset;2356 int file_offset;
2343 2357
@@ -2347,26 +2361,16 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 3 unmodified lines
2347 if (d->interp)2361 if (d->interp)
2348 phfill = 2;2362 phfill = 2;
2349 phnum += phfill;2363 phnum += phfill;
2364 if (d->tls)
2365 d->tls = phnum, ++phnum;
2366 if (d->relro)
2367 d->relro = phnum, ++phnum;
2350 if (d->note)2368 if (d->note)
2351 ++phnum;2369 ++phnum;
2352 if (d->dynamic)2370 if (d->dynamic)
2353 ++phnum;2371 ++phnum;
2354 if (eh_frame_hdr_section)2372 if (eh_frame_hdr_section)
2355 ++phnum;2373 ++phnum;
2356 if (d->roinf)
2357 ++phnum;
2358 {
2359 int has_tls = 0;
2360 for (i = 1; i < s1->nb_sections; i++) {
2361 s = s1->sections[i];
2362 if (s->sh_flags & SHF_TLS) {
2363 has_tls = 1;
2364 break;
2365 }
2366 }
2367 if (has_tls)
2368 ++phnum;
2369 }
2370 d->phnum = phnum;2374 d->phnum = phnum;
2371 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));2375 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2372 2376
@@ -2415,7 +2419,7 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 42 unmodified lines
2415 continue;2419 continue;
2416 }2420 }
2417 2421
2418 if ((f & 1<<8) && n) {2422 if ((f & SHFX_NEWPH) && n) {
2419 /* different rwx section flags */2423 /* different rwx section flags */
2420 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {2424 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2421 /* if in the middle of a page, w e duplicate the page in2425 /* if in the middle of a page, w e duplicate the page in
@@ -2433,51 +2437,53 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 11 unmodified lines
2433 s->sh_offset = file_offset;2437 s->sh_offset = file_offset;
2434 s->sh_addr = addr;2438 s->sh_addr = addr;
2435 2439
2436 if (f & 1<<8) {2440 addr += s->sh_size;
2441 if (s->sh_type != SHT_NOBITS)
2442 file_offset += s->sh_size;
2443
2444 if (f & SHFX_NEWPH) {
2437 /* set new program header */2445 /* set new program header */
2438 ph = &d->phdr[phfill + n];2446 ph = &d->phdr[phfill + n];
2439 ph->p_type = PT_LOAD;2447 fill_phdr(ph, PT_LOAD, s);
2440 ph->p_align = s_align;2448 ph->p_align = s_align;
2441 ph->p_flags = PF_R;
2442 if (f & SHF_WRITE)2449 if (f & SHF_WRITE)
2443 ph->p_flags |= PF_W;2450 ph->p_flags |= PF_W;
2444 if (f & SHF_EXECINSTR)2451 if (f & SHF_EXECINSTR)
2445 ph->p_flags |= PF_X;2452 ph->p_flags |= PF_X;
2446
2447 ph->p_offset = file_offset;
2448 ph->p_vaddr = addr;
2449 if (n == 0) {2453 if (n == 0) {
2450 /* Make the first PT_LOAD segment include the program2454 /* Make the first PT_LOAD segment include the program
2451 headers itself (and the ELF header as well), it'll2455 headers itself (and the ELF header as well), it'll
2452 come out with same memory use but will make various2456 come out with same memory use but will make various
2453 tools like binutils strip work better. */2457 tools like binutils strip work better. */
2454 ph->p_offset = 0;2458 ph->p_offset = 0;
2455 ph->p_vaddr = base;2459 ph->p_paddr = ph->p_vaddr = base;
2456 }2460 }
2457 ph->p_paddr = ph->p_vaddr;
2458 ++n;2461 ++n;
2459 }2462 }
2460 2463
2461 if (f & 1<<4) {2464 if (ph)
2462 Section *roinf = &d->_roinf;2465 update_phdr(ph, 0, 0, addr, file_offset);
2463 if (roinf->sh_size == 0) {
2464 roinf->sh_offset = s->sh_offset;
2465 roinf->sh_addr = s->sh_addr;
2466 roinf->sh_addralign = 1;
2467 }
2468 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2469 }
2470 2466
2471 addr += s->sh_size;2467 if (f & SHFX_RELRO) {
2472 if (s->sh_type != SHT_NOBITS)2468 ph2 = update_phdr(&d->phdr[d->relro], PT_GNU_RELRO, s, addr, file_offset);
2473 file_offset += s->sh_size;2469 ph2->p_align = 1;
2470 }
2474 2471
2475 if (ph) {2472 if (f & SHF_TLS) {
2476 ph->p_filesz = file_offset - ph->p_offset;2473 ph2 = update_phdr(&d->phdr[d->tls], PT_TLS, s, addr, file_offset);
2477 ph->p_memsz = addr - ph->p_vaddr;2474 if (s->sh_addralign > ph2->p_align)
2475 ph2->p_align = s->sh_addralign;
2478 }2476 }
2479 }2477 }
2480 2478
2479 if (d->tls) {
2480 ++ph;
2481 /* for xxx-link.c:relocate() */
2482 s1->tls_start = ph->p_vaddr;
2483 s1->tls_end = s1->tls_start + ph->p_memsz + (-ph->p_memsz & (ph->p_align - 1));
2484 }
2485 if (d->relro)
2486 ++ph;
2481 /* Fill other headers */2487 /* Fill other headers */
2482 if (d->note)2488 if (d->note)
2483 fill_phdr(++ph, PT_NOTE, d->note);2489 fill_phdr(++ph, PT_NOTE, d->note);
@@ -2485,36 +2491,6 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 1 unmodified line
2485 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;2491 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
2486 if (eh_frame_hdr_section)2492 if (eh_frame_hdr_section)
2487 fill_phdr(++ph, PT_GNU_EH_FRAME, eh_frame_hdr_section);2493 fill_phdr(++ph, PT_GNU_EH_FRAME, eh_frame_hdr_section);
2488 if (d->roinf)
2489 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
2490 {
2491 /* Create PT_TLS segment covering all TLS sections */
2492 Section *tls_start_sec = NULL;
2493 addr_t tls_start = 0, tls_end = 0;
2494 for (i = 1; i < s1->nb_sections; i++) {
2495 s = s1->sections[i];
2496 if (s->sh_flags & SHF_TLS && s->sh_size) {
2497 if (!tls_start_sec) {
2498 tls_start_sec = s;
2499 tls_start = s->sh_addr;
2500 tls_end = s->sh_addr + s->sh_size;
2501 } else {
2502 if (s->sh_addr < tls_start)
2503 tls_start = s->sh_addr;
2504 if (s->sh_addr + s->sh_size > tls_end)
2505 tls_end = s->sh_addr + s->sh_size;
2506 }
2507 }
2508 }
2509 if (tls_start_sec) {
2510 ph = fill_phdr(++ph, PT_TLS, tls_start_sec);
2511 ph->p_vaddr = tls_start;
2512 ph->p_paddr = tls_start;
2513 ph->p_filesz = tls_end - tls_start;
2514 ph->p_memsz = ph->p_filesz;
2515 ph->p_align = tls_start_sec->sh_addralign;
2516 }
2517 }
2518 if (d->interp)2494 if (d->interp)
2519 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);2495 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);
2520 if (phfill) {2496 if (phfill) {
@@ -2823,7 +2799,7 @@ static void reorder_sections(TCCState *s1, int *sec_order) · 302 unmodified lines
2823 2799
2824 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));2800 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2825 for (i = 0, nnew = 0, snew = NULL; i < s1->nb_sections; i++) {2801 for (i = 0, nnew = 0, snew = NULL; i < s1->nb_sections; i++) {
2826 k = sec_order[i];2802 k = sec_order ? sec_order[i] : i;
2827 s = s1->sections[k];2803 s = s1->sections[k];
2828 if (!i || s->sh_name) {2804 if (!i || s->sh_name) {
2829 backmap[k] = nnew;2805 backmap[k] = nnew;
@@ -2986,7 +2962,6 @@ static int elf_output_file(TCCState *s1, const char *filename) · 156 unmodified lines
2986 ret = -1;2962 ret = -1;
2987 interp = dynstr = dynamic = NULL;2963 interp = dynstr = dynamic = NULL;
2988 sec_order = NULL;2964 sec_order = NULL;
2989 dyninf.roinf = &dyninf._roinf;
2990 2965
2991#ifdef TCC_TARGET_ARM2966#ifdef TCC_TARGET_ARM
2992 create_arm_attribute_section (s1);2967 create_arm_attribute_section (s1);
@@ -3008,10 +2983,6 @@ static int elf_output_file(TCCState *s1, const char *filename) · 15 unmodified lines
3008 dyninf.note = create_bsd_note_section (s1, ".note.tag", "FreeBSD");2983 dyninf.note = create_bsd_note_section (s1, ".note.tag", "FreeBSD");
3009#endif2984#endif
3010 2985
3011#if TARGETOS_FreeBSD || TARGETOS_NetBSD
3012 dyninf.roinf = NULL;
3013#endif
3014
3015 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */2986 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
3016 tcc_add_runtime(s1);2987 tcc_add_runtime(s1);
3017 resolve_common_syms(s1);2988 resolve_common_syms(s1);
tccgen.c+3−4
@@ -8400,10 +8400,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 8399 unmodified lines
8400 while ((tp->t & (VT_BTYPE|VT_ARRAY)) == (VT_PTR|VT_ARRAY))8400 while ((tp->t & (VT_BTYPE|VT_ARRAY)) == (VT_PTR|VT_ARRAY))
8401 tp = &tp->ref->type;8401 tp = &tp->ref->type;
8402 if (type->t & VT_TLS) {8402 if (type->t & VT_TLS) {
8403 if (has_init)8403 sec = find_section(tcc_state, has_init ? ".tdata" : ".tbss");
8404 sec = tdata_section;8404 sec->sh_flags = SHF_ALLOC | SHF_WRITE | SHF_TLS;
8405 else8405 sec->sh_type = has_init ? SHT_PROGBITS : SHT_NOBITS;
8406 sec = tbss_section;
8407 } else if (tp->t & VT_CONSTANT) {8406 } else if (tp->t & VT_CONSTANT) {
8408 sec = rodata_section;8407 sec = rodata_section;
8409 } else if (has_init) {8408 } else if (has_init) {
tests/tests2/Makefile+2−2
@@ -57,8 +57,8 @@ endif · 56 unmodified lines
57ifeq ($(CONFIG_OSX),yes)57ifeq ($(CONFIG_OSX),yes)
58 SKIP += 144_tls.test # TLS runtime not supported on Mach-O58 SKIP += 144_tls.test # TLS runtime not supported on Mach-O
59endif59endif
60ifeq (,$(filter i386 x86_64 riscv64 arm64,$(ARCH)))60ifeq (-$(ARCH)-,-arm-)
61 SKIP += 144_tls.test # TLS only implemented on these architectures so far61 SKIP += 144_tls.test # doesn't work currently
62endif62endif
63ifneq (-$(ARCH)-,-arm64-)63ifneq (-$(ARCH)-,-arm64-)
64 SKIP += 138_arm64_encoding.test64 SKIP += 138_arm64_encoding.test
x86_64-link.c+14−55
@@ -368,70 +368,29 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 367 unmodified lines
368 tcc_error_noabort("unexpected R_X86_64_TLSLD pattern");368 tcc_error_noabort("unexpected R_X86_64_TLSLD pattern");
369 }369 }
370 break;370 break;
371
371 case R_X86_64_DTPOFF32:372 case R_X86_64_DTPOFF32:
372 case R_X86_64_TPOFF32:373 case R_X86_64_TPOFF32:
373 {
374 ElfW(Sym) *sym;
375 Section *sec;
376 int32_t x;
377 addr_t tls_start = 0, tls_end = 0, tls_align = 1;
378 int i;
379
380 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
381 sec = s1->sections[sym->st_shndx];
382
383 for (i = 1; i < s1->nb_sections; i++) {
384 Section *s = s1->sections[i];
385 if (s->sh_flags & SHF_TLS && s->sh_size) {
386 if (!tls_start || s->sh_addr < tls_start)
387 tls_start = s->sh_addr;
388 if (s->sh_addr + s->sh_size > tls_end)
389 tls_end = s->sh_addr + s->sh_size;
390 if (s->sh_addralign > tls_align)
391 tls_align = s->sh_addralign;
392 }
393 }
394 if (tls_end > tls_start) {
395 addr_t tls_size = tls_end - tls_start;
396 addr_t aligned_size = (tls_size + tls_align - 1) & ~(tls_align - 1);
397 x = val - (tls_start + aligned_size);
398 } else {
399 x = val - sec->sh_addr - sec->data_offset;
400 }
401 add32le(ptr, x);
402 }
403 break;
404 case R_X86_64_DTPOFF64:374 case R_X86_64_DTPOFF64:
405 case R_X86_64_TPOFF64:375 case R_X86_64_TPOFF64:
406 {376 {
407 ElfW(Sym) *sym;
408 Section *sec;
409 int32_t x;377 int32_t x;
410 addr_t tls_start = 0, tls_end = 0, tls_align = 1;378 if (s1->tls_end) {
411 int i;379 x = val - s1->tls_end;
412
413 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
414 sec = s1->sections[sym->st_shndx];
415
416 for (i = 1; i < s1->nb_sections; i++) {
417 Section *s = s1->sections[i];
418 if (s->sh_flags & SHF_TLS && s->sh_size) {
419 if (!tls_start || s->sh_addr < tls_start)
420 tls_start = s->sh_addr;
421 if (s->sh_addr + s->sh_size > tls_end)
422 tls_end = s->sh_addr + s->sh_size;
423 if (s->sh_addralign > tls_align)
424 tls_align = s->sh_addralign;
425 }
426 }
427 if (tls_end > tls_start) {
428 addr_t tls_size = tls_end - tls_start;
429 addr_t aligned_size = (tls_size + tls_align - 1) & ~(tls_align - 1);
430 x = val - (tls_start + aligned_size);
431 } else {380 } else {
381 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
382 Section *sec = s1->sections[sym->st_shndx];
432 x = val - sec->sh_addr - sec->data_offset;383 x = val - sec->sh_addr - sec->data_offset;
433 }384 }
434 add64le(ptr, x);385 switch (type) {
386 case R_X86_64_DTPOFF64:
387 case R_X86_64_TPOFF64:
388 add64le(ptr, x);
389 break;
390 default:
391 add32le(ptr, x);
392 break;
393 }
435 }394 }
436 break;395 break;
437 case R_X86_64_NONE:396 case R_X86_64_NONE:

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