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
434434 return;
435435 case R_ARM_TLS_LE32:
436436 {
437− ElfW(Sym) *sym;
438− Section *sec;
439437 int32_t x;
440− addr_t tls_start = 0, tls_end = 0, tls_align = 1;
441− int i;
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;
438+ if (s1->tls_end) {
439+ x = val - s1->tls_start + 8;
459440 } else {
441+ ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
442+ Section *sec = s1->sections[sym->st_shndx];
460443 x = val - sec->sh_addr - sec->data_offset + 8;
461444 }
462445 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
371371 return;
372372 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
373373 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− }
383374 /* 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;
385376 int64_t imm;
386377 if (type == R_AARCH64_TLSLE_ADD_TPREL_HI12)
387378 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
318318 return;
319319 case R_386_TLS_LE:
320320 {
321− ElfW(Sym) *sym;
322− Section *sec;
323321 int32_t x;
324− addr_t tls_start = 0, tls_end = 0, tls_align = 1;
325− int i;
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);
322+ if (s1->tls_end) {
323+ x = val - s1->tls_end;
345324 } else {
325+ ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
326+ Section *sec = s1->sections[sym->st_shndx];
346327 x = val - sec->sh_addr - sec->data_offset;
347328 }
348329 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
407407
408408 case R_RISCV_TPREL_HI20:
409409 case R_RISCV_TPREL_LO12_I: {
410− addr_t tls_start = 0;
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;
410+ int64_t tp_offset = val - s1->tls_start;
421411 if (type == R_RISCV_TPREL_HI20) {
422412 off64 = (int64_t)(tp_offset + 0x800) >> 12;
423413 if ((off64 + ((uint64_t)1 << 20)) >> 21)
tcc.h+2−3
@@ -889,7 +889,6 @@ struct TCCState { · 888 unmodified lines
889889
890890 /* predefined sections */
891891 Section *text_section, *data_section, *rodata_section, *bss_section;
892− Section *tdata_section, *tbss_section;
893892 Section *common_section;
894893 Section *cur_text_section; /* current section where function code is generated */
895894 #ifdef CONFIG_TCC_BCHECK
@@ -930,6 +929,8 @@ struct TCCState { · 34 unmodified lines
930929 ElfW_Rel *qrel;
931930 #define qrel s1->qrel
932931
932+ addr_t tls_start, tls_end;
933+
933934 #ifdef TCC_TARGET_RISCV64
934935 struct pcrel_hi { addr_t addr, val; } **pcrel_hi_entries;
935936 int nb_pcrel_hi_entries;
@@ -1979,8 +1980,6 @@ static inline void post_sem(TCCSem *p) { · 1043 unmodified lines
19791980 #define data_section TCC_STATE_VAR(data_section)
19801981 #define rodata_section TCC_STATE_VAR(rodata_section)
19811982 #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)
19841983 #define common_section TCC_STATE_VAR(common_section)
19851984 #define cur_text_section TCC_STATE_VAR(cur_text_section)
19861985 #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
7070 /* create ro data section (make ro after relocation done with GNU_RELRO) */
7171 rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);
7272 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);
7573 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
7674 common_section->sh_num = SHN_COMMON;
7775
@@ -2198,12 +2196,11 @@ struct dyn_inf { · 2120 unmodified lines
21982196 ElfW(Phdr) *phdr;
21992197 int phnum;
22002198 int shnum;
2199+ int tls;
2200+ int relro;
22012201 Section *interp;
22022202 Section *note;
22032203 Section *gnu_hash;
2204−
2205− /* read only segment mapping for GNU_RELRO */
2206− Section _roinf, *roinf;
22072204 };
22082205
22092206 /* 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
22262223 if (s->sh_flags & SHF_WRITE)
22272224 j = 0x200;
22282225 if (s->sh_flags & SHF_TLS)
2229− j += 0x200;
2226+ j = 0x300;
22302227 } else {
22312228 j = 0x700;
22322229 }
@@ -2287,6 +2284,9 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 54 unmodified lines
22872284 sec_order[0] = 0;
22882285 d->shnum = 1;
22892286
2287+#define SHFX_NEWPH (1 << 4)
2288+#define SHFX_RELRO (1 << 5)
2289+
22902290 /* count PT_LOAD headers needed */
22912291 n = f0 = 0;
22922292 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
22972297 ++d->shnum;
22982298 if (k < 0x700) {
22992299 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR);
2300−#if TARGETOS_NetBSD
2300+#if TARGETOS_NetBSD || TARGETOS_FreeBSD
23012301 /* NetBSD only supports 2 PT_LOAD sections.
23022302 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
23032303 if ((f & SHF_WRITE) == 0)
23042304 f |= SHF_EXECINSTR;
23052305 #else
23062306 if ((k & 0xfff0) == 0x240) /* RELRO sections */
2307− f |= 1<<4;
2307+ d->relro = 1, f |= SHFX_RELRO;
23082308 #endif
23092309 /* start new header when flags changed or relro, but avoid zero memsz */
23102310 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;
23122315 }
23132316 sec_cls[i] = f;
23142317 //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
23312334 return ph;
23322335 }
23332336
2337+static 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+
23342348 /* Assign sections to segments and decide how are sections laid out when loaded
23352349 in memory. This function also fills corresponding program headers. */
23362350 static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
23372351 {
23382352 Section *s;
23392353 addr_t addr, tmp, align, s_align, base;
2340− ElfW(Phdr) *ph = NULL;
2354+ ElfW(Phdr) *ph = NULL, *ph2;
23412355 int i, f, n, phnum, phfill;
23422356 int file_offset;
23432357
@@ -2347,26 +2361,16 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 3 unmodified lines
23472361 if (d->interp)
23482362 phfill = 2;
23492363 phnum += phfill;
2364+ if (d->tls)
2365+ d->tls = phnum, ++phnum;
2366+ if (d->relro)
2367+ d->relro = phnum, ++phnum;
23502368 if (d->note)
23512369 ++phnum;
23522370 if (d->dynamic)
23532371 ++phnum;
23542372 if (eh_frame_hdr_section)
23552373 ++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− }
23702374 d->phnum = phnum;
23712375 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
23722376
@@ -2415,7 +2419,7 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 42 unmodified lines
24152419 continue;
24162420 }
24172421
2418− if ((f & 1<<8) && n) {
2422+ if ((f & SHFX_NEWPH) && n) {
24192423 /* different rwx section flags */
24202424 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
24212425 /* 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
24332437 s->sh_offset = file_offset;
24342438 s->sh_addr = addr;
24352439
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) {
24372445 /* set new program header */
24382446 ph = &d->phdr[phfill + n];
2439− ph->p_type = PT_LOAD;
2447+ fill_phdr(ph, PT_LOAD, s);
24402448 ph->p_align = s_align;
2441− ph->p_flags = PF_R;
24422449 if (f & SHF_WRITE)
24432450 ph->p_flags |= PF_W;
24442451 if (f & SHF_EXECINSTR)
24452452 ph->p_flags |= PF_X;
2446−
2447− ph->p_offset = file_offset;
2448− ph->p_vaddr = addr;
24492453 if (n == 0) {
24502454 /* Make the first PT_LOAD segment include the program
24512455 headers itself (and the ELF header as well), it'll
24522456 come out with same memory use but will make various
24532457 tools like binutils strip work better. */
24542458 ph->p_offset = 0;
2455− ph->p_vaddr = base;
2459+ ph->p_paddr = ph->p_vaddr = base;
24562460 }
2457− ph->p_paddr = ph->p_vaddr;
24582461 ++n;
24592462 }
24602463
2461− if (f & 1<<4) {
2462− Section *roinf = &d->_roinf;
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− }
2464+ if (ph)
2465+ update_phdr(ph, 0, 0, addr, file_offset);
24702466
2471− addr += s->sh_size;
2472− if (s->sh_type != SHT_NOBITS)
2473− file_offset += s->sh_size;
2467+ if (f & SHFX_RELRO) {
2468+ ph2 = update_phdr(&d->phdr[d->relro], PT_GNU_RELRO, s, addr, file_offset);
2469+ ph2->p_align = 1;
2470+ }
24742471
2475− if (ph) {
2476− ph->p_filesz = file_offset - ph->p_offset;
2477− ph->p_memsz = addr - ph->p_vaddr;
2472+ if (f & SHF_TLS) {
2473+ ph2 = update_phdr(&d->phdr[d->tls], PT_TLS, s, addr, file_offset);
2474+ if (s->sh_addralign > ph2->p_align)
2475+ ph2->p_align = s->sh_addralign;
24782476 }
24792477 }
24802478
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;
24812487 /* Fill other headers */
24822488 if (d->note)
24832489 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
24852491 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
24862492 if (eh_frame_hdr_section)
24872493 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− }
25182494 if (d->interp)
25192495 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);
25202496 if (phfill) {
@@ -2823,7 +2799,7 @@ static void reorder_sections(TCCState *s1, int *sec_order) · 302 unmodified lines
28232799
28242800 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
28252801 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;
28272803 s = s1->sections[k];
28282804 if (!i || s->sh_name) {
28292805 backmap[k] = nnew;
@@ -2986,7 +2962,6 @@ static int elf_output_file(TCCState *s1, const char *filename) · 156 unmodified lines
29862962 ret = -1;
29872963 interp = dynstr = dynamic = NULL;
29882964 sec_order = NULL;
2989− dyninf.roinf = &dyninf._roinf;
29902965
29912966 #ifdef TCC_TARGET_ARM
29922967 create_arm_attribute_section (s1);
@@ -3008,10 +2983,6 @@ static int elf_output_file(TCCState *s1, const char *filename) · 15 unmodified lines
30082983 dyninf.note = create_bsd_note_section (s1, ".note.tag", "FreeBSD");
30092984 #endif
30102985
3011−#if TARGETOS_FreeBSD || TARGETOS_NetBSD
3012− dyninf.roinf = NULL;
3013−#endif
3014−
30152986 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
30162987 tcc_add_runtime(s1);
30172988 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
84008400 while ((tp->t & (VT_BTYPE|VT_ARRAY)) == (VT_PTR|VT_ARRAY))
84018401 tp = &tp->ref->type;
84028402 if (type->t & VT_TLS) {
8403− if (has_init)
8404− sec = tdata_section;
8405− else
8406− sec = tbss_section;
8403+ sec = find_section(tcc_state, has_init ? ".tdata" : ".tbss");
8404+ sec->sh_flags = SHF_ALLOC | SHF_WRITE | SHF_TLS;
8405+ sec->sh_type = has_init ? SHT_PROGBITS : SHT_NOBITS;
84078406 } else if (tp->t & VT_CONSTANT) {
84088407 sec = rodata_section;
84098408 } else if (has_init) {
tests/tests2/Makefile+2−2
@@ -57,8 +57,8 @@ endif · 56 unmodified lines
5757 ifeq ($(CONFIG_OSX),yes)
5858 SKIP += 144_tls.test # TLS runtime not supported on Mach-O
5959 endif
60−ifeq (,$(filter i386 x86_64 riscv64 arm64,$(ARCH)))
61− SKIP += 144_tls.test # TLS only implemented on these architectures so far
60+ifeq (-$(ARCH)-,-arm-)
61+ SKIP += 144_tls.test # doesn't work currently
6262 endif
6363 ifneq (-$(ARCH)-,-arm64-)
6464 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
368368 tcc_error_noabort("unexpected R_X86_64_TLSLD pattern");
369369 }
370370 break;
371+
371372 case R_X86_64_DTPOFF32:
372373 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;
404374 case R_X86_64_DTPOFF64:
405375 case R_X86_64_TPOFF64:
406376 {
407− ElfW(Sym) *sym;
408− Section *sec;
409377 int32_t x;
410− addr_t tls_start = 0, tls_end = 0, tls_align = 1;
411− int i;
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);
378+ if (s1->tls_end) {
379+ x = val - s1->tls_end;
431380 } else {
381+ ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
382+ Section *sec = s1->sections[sym->st_shndx];
432383 x = val - sec->sh_addr - sec->data_offset;
433384 }
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+ }
435394 }
436395 break;
437396 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