authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-28 13:29:04+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-28 13:29:04+02:00
loga63ce5a37c9655f4f453d848285b85fb91625390
treeed549d7f314b6283ec909e1c7d3f5be402438aa8
parent22127a879234459dad65c73ffae4d5ec9da548c1

elf: allocate .tdata and .tbss sections


1 files changed, 56 insertions(+), 10 deletions(-)

src/link/Elf.zig+56-10
......@@ -46,7 +46,9 @@ phdr_load_zerofill_index: ?u16 = null,
4646/// The index into the program headers of the PT_TLS program header.
4747phdr_tls_index: ?u16 = null,
4848/// The index into the program headers of a PT_LOAD program header with TLS data.
49phdr_load_tls_index: ?u16 = null,
49phdr_load_tls_data_index: ?u16 = null,
50/// The index into the program headers of a PT_LOAD program header with TLS zerofill data.
51phdr_load_tls_zerofill_index: ?u16 = null,
5052
5153entry_addr: ?u64 = null,
5254page_size: u32,
......@@ -499,7 +501,7 @@ pub fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{Ou
499501 .sh_flags = opts.flags,
500502 .sh_addr = phdr.p_vaddr,
501503 .sh_offset = phdr.p_offset,
502 .sh_size = phdr.p_filesz,
504 .sh_size = phdr.p_memsz,
503505 .sh_link = 0,
504506 .sh_info = 0,
505507 .sh_addralign = opts.alignment,
......@@ -631,24 +633,37 @@ pub fn populateMissingMetadata(self: *Elf) !void {
631633 }
632634
633635 if (!self.base.options.single_threaded) {
634 if (self.phdr_load_tls_index == null) {
636 if (self.phdr_load_tls_data_index == null) {
635637 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
636 self.phdr_load_tls_index = try self.allocateSegment(.{
638 self.phdr_load_tls_data_index = try self.allocateSegment(.{
637639 .size = 1024,
638640 .alignment = alignment,
639641 .flags = elf.PF_R | elf.PF_W,
640642 });
641643 }
642644
645 if (self.phdr_load_tls_zerofill_index == null) {
646 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
647 self.phdr_load_tls_zerofill_index = try self.allocateSegment(.{
648 .size = 0,
649 .alignment = alignment,
650 .flags = elf.PF_R | elf.PF_W,
651 });
652 const phdr = &self.phdrs.items[self.phdr_load_tls_zerofill_index.?];
653 phdr.p_offset = self.phdrs.items[self.phdr_load_tls_data_index.?].p_offset; // .tbss overlaps .tdata
654 phdr.p_memsz = 1024;
655 }
656
643657 if (self.phdr_tls_index == null) {
644 const phdr = &self.phdrs.items[self.phdr_load_tls_index.?];
658 const phdr_tdata = &self.phdrs.items[self.phdr_load_tls_data_index.?];
659 const phdr_tbss = &self.phdrs.items[self.phdr_load_tls_zerofill_index.?];
645660 try self.phdrs.append(gpa, .{
646661 .p_type = elf.PT_TLS,
647 .p_offset = phdr.p_offset,
648 .p_vaddr = phdr.p_vaddr,
649 .p_paddr = phdr.p_paddr,
650 .p_filesz = phdr.p_filesz,
651 .p_memsz = phdr.p_memsz,
662 .p_offset = phdr_tdata.p_offset,
663 .p_vaddr = phdr_tdata.p_vaddr,
664 .p_paddr = phdr_tdata.p_paddr,
665 .p_filesz = phdr_tdata.p_filesz,
666 .p_memsz = phdr_tbss.p_vaddr + phdr_tbss.p_memsz - phdr_tdata.p_vaddr,
652667 .p_align = ptr_size,
653668 .p_flags = elf.PF_R,
654669 });
......@@ -724,6 +739,31 @@ pub fn populateMissingMetadata(self: *Elf) !void {
724739 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.bss_section_index.?, .{});
725740 }
726741
742 if (self.phdr_load_tls_data_index) |phdr_index| {
743 if (self.tdata_section_index == null) {
744 self.tdata_section_index = try self.allocateAllocSection(.{
745 .name = ".tdata",
746 .phdr_index = phdr_index,
747 .alignment = ptr_size,
748 .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS,
749 });
750 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.tdata_section_index.?, .{});
751 }
752 }
753
754 if (self.phdr_load_tls_zerofill_index) |phdr_index| {
755 if (self.tbss_section_index == null) {
756 self.tbss_section_index = try self.allocateAllocSection(.{
757 .name = ".tbss",
758 .phdr_index = phdr_index,
759 .alignment = ptr_size,
760 .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS,
761 .type = elf.SHT_NOBITS,
762 });
763 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.tbss_section_index.?, .{});
764 }
765 }
766
727767 if (self.symtab_section_index == null) {
728768 const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym);
729769 const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym);
......@@ -1295,6 +1335,12 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
12951335 self.phdrs.items[bss_phndx].p_offset = self.phdrs.items[data_phndx].p_offset;
12961336 }
12971337
1338 // Same treatment for .tbss section.
1339 if (self.tdata_section_index) |tdata_shndx| blk: {
1340 const tbss_shndx = self.tbss_section_index orelse break :blk;
1341 self.shdrs.items[tbss_shndx].sh_offset = self.shdrs.items[tdata_shndx].sh_offset;
1342 }
1343
12981344 // Dump the state for easy debugging.
12991345 // State can be dumped via `--debug-log link_state`.
13001346 if (build_options.enable_logging) {