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,...@@ -46,7 +46,9 @@ phdr_load_zerofill_index: ?u16 = null,
46/// The index into the program headers of the PT_TLS program header.46/// The index into the program headers of the PT_TLS program header.
47phdr_tls_index: ?u16 = null,47phdr_tls_index: ?u16 = null,
48/// The index into the program headers of a PT_LOAD program header with TLS data.48/// 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
51entry_addr: ?u64 = null,53entry_addr: ?u64 = null,
52page_size: u32,54page_size: u32,
...@@ -499,7 +501,7 @@ pub fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{Ou...@@ -499,7 +501,7 @@ pub fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{Ou
499 .sh_flags = opts.flags,501 .sh_flags = opts.flags,
500 .sh_addr = phdr.p_vaddr,502 .sh_addr = phdr.p_vaddr,
501 .sh_offset = phdr.p_offset,503 .sh_offset = phdr.p_offset,
502 .sh_size = phdr.p_filesz,504 .sh_size = phdr.p_memsz,
503 .sh_link = 0,505 .sh_link = 0,
504 .sh_info = 0,506 .sh_info = 0,
505 .sh_addralign = opts.alignment,507 .sh_addralign = opts.alignment,
...@@ -631,24 +633,37 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -631,24 +633,37 @@ pub fn populateMissingMetadata(self: *Elf) !void {
631 }633 }
632634
633 if (!self.base.options.single_threaded) {635 if (!self.base.options.single_threaded) {
634 if (self.phdr_load_tls_index == null) {636 if (self.phdr_load_tls_data_index == null) {
635 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);637 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(.{
637 .size = 1024,639 .size = 1024,
638 .alignment = alignment,640 .alignment = alignment,
639 .flags = elf.PF_R | elf.PF_W,641 .flags = elf.PF_R | elf.PF_W,
640 });642 });
641 }643 }
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
643 if (self.phdr_tls_index == null) {657 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.?];
645 try self.phdrs.append(gpa, .{660 try self.phdrs.append(gpa, .{
646 .p_type = elf.PT_TLS,661 .p_type = elf.PT_TLS,
647 .p_offset = phdr.p_offset,662 .p_offset = phdr_tdata.p_offset,
648 .p_vaddr = phdr.p_vaddr,663 .p_vaddr = phdr_tdata.p_vaddr,
649 .p_paddr = phdr.p_paddr,664 .p_paddr = phdr_tdata.p_paddr,
650 .p_filesz = phdr.p_filesz,665 .p_filesz = phdr_tdata.p_filesz,
651 .p_memsz = phdr.p_memsz,666 .p_memsz = phdr_tbss.p_vaddr + phdr_tbss.p_memsz - phdr_tdata.p_vaddr,
652 .p_align = ptr_size,667 .p_align = ptr_size,
653 .p_flags = elf.PF_R,668 .p_flags = elf.PF_R,
654 });669 });
...@@ -724,6 +739,31 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -724,6 +739,31 @@ pub fn populateMissingMetadata(self: *Elf) !void {
724 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.bss_section_index.?, .{});739 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.bss_section_index.?, .{});
725 }740 }
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
727 if (self.symtab_section_index == null) {767 if (self.symtab_section_index == null) {
728 const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym);768 const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym);
729 const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym);769 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...@@ -1295,6 +1335,12 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1295 self.phdrs.items[bss_phndx].p_offset = self.phdrs.items[data_phndx].p_offset;1335 self.phdrs.items[bss_phndx].p_offset = self.phdrs.items[data_phndx].p_offset;
1296 }1336 }
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
1298 // Dump the state for easy debugging.1344 // Dump the state for easy debugging.
1299 // State can be dumped via `--debug-log link_state`.1345 // State can be dumped via `--debug-log link_state`.
1300 if (build_options.enable_logging) {1346 if (build_options.enable_logging) {