authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-11 18:30:11+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-16 19:33:05+02:00
log1939c7d182e55d09b7968052b0cda652dab18b74
tree41bbdfa547c91831aadc48d7cff49c460930aea7
parentc87e73b19f8aca4a5bcea1548924b44377a5eec6

elf: clean up logic for allocating TLS segment


1 files changed, 16 insertions(+), 9 deletions(-)

src/link/Elf.zig+16-9
...@@ -4433,8 +4433,9 @@ fn resetPhdrs(self: *Elf) !void {...@@ -4433,8 +4433,9 @@ fn resetPhdrs(self: *Elf) !void {
44334433
4434fn initSegments(self: *Elf) !void {4434fn initSegments(self: *Elf) !void {
4435 // Add LOAD phdrs4435 // Add LOAD phdrs
4436 const gpa = self.base.allocator;
4436 const slice = self.shdrs.items;4437 const slice = self.shdrs.items;
4437 var last_phdr: ?u16 = null;4438 var is_first = true;
4438 var shndx: u16 = 0;4439 var shndx: u16 = 0;
4439 while (shndx < slice.len) {4440 while (shndx < slice.len) {
4440 const shdr = &slice[shndx];4441 const shdr = &slice[shndx];
...@@ -4442,16 +4443,17 @@ fn initSegments(self: *Elf) !void {...@@ -4442,16 +4443,17 @@ fn initSegments(self: *Elf) !void {
4442 shndx += 1;4443 shndx += 1;
4443 continue;4444 continue;
4444 }4445 }
4445 last_phdr = try self.addPhdr(.{4446 const phndx = try self.addPhdr(.{
4446 .type = elf.PT_LOAD,4447 .type = elf.PT_LOAD,
4447 .flags = shdrToPhdrFlags(shdr.sh_flags),4448 .flags = shdrToPhdrFlags(shdr.sh_flags),
4448 .@"align" = @max(self.page_size, shdr.sh_addralign),4449 .@"align" = @max(self.page_size, shdr.sh_addralign),
4449 .offset = if (last_phdr == null) 0 else shdr.sh_offset,4450 .offset = if (is_first) 0 else shdr.sh_offset,
4450 .addr = if (last_phdr == null) self.calcImageBase() else shdr.sh_addr,4451 .addr = if (is_first) self.calcImageBase() else shdr.sh_addr,
4451 });4452 });
4452 const p_flags = self.phdrs.items[last_phdr.?].p_flags;4453 is_first = false;
4453 self.addShdrToPhdr(shndx, last_phdr.?);4454 const p_flags = self.phdrs.items[phndx].p_flags;
4454 try self.phdr_to_shdr_table.putNoClobber(self.base.allocator, shndx, last_phdr.?);4455 self.addShdrToPhdr(shndx, phndx);
4456 try self.phdr_to_shdr_table.putNoClobber(gpa, shndx, phndx);
4455 shndx += 1;4457 shndx += 1;
44564458
4457 while (shndx < slice.len) : (shndx += 1) {4459 while (shndx < slice.len) : (shndx += 1) {
...@@ -4459,8 +4461,8 @@ fn initSegments(self: *Elf) !void {...@@ -4459,8 +4461,8 @@ fn initSegments(self: *Elf) !void {
4459 if (shdrIsTbss(next)) continue;4461 if (shdrIsTbss(next)) continue;
4460 if (p_flags == shdrToPhdrFlags(next.sh_flags)) {4462 if (p_flags == shdrToPhdrFlags(next.sh_flags)) {
4461 if (shdrIsBss(next) or next.sh_offset - shdr.sh_offset == next.sh_addr - shdr.sh_addr) {4463 if (shdrIsBss(next) or next.sh_offset - shdr.sh_offset == next.sh_addr - shdr.sh_addr) {
4462 self.addShdrToPhdr(shndx, last_phdr.?);4464 self.addShdrToPhdr(shndx, phndx);
4463 try self.phdr_to_shdr_table.putNoClobber(self.base.allocator, shndx, last_phdr.?);4465 try self.phdr_to_shdr_table.putNoClobber(self.base.allocator, shndx, phndx);
4464 continue;4466 continue;
4465 }4467 }
4466 }4468 }
...@@ -4623,6 +4625,11 @@ fn allocateAllocSectionsInFile(self: *Elf, base_offset: u64) void {...@@ -4623,6 +4625,11 @@ fn allocateAllocSectionsInFile(self: *Elf, base_offset: u64) void {
4623 }4625 }
4624}4626}
46254627
4628/// This function is really only responsible for allocating alloc sections,
4629/// and creating load segments as-if incremental linking mode didn't exist.
4630/// As a base address we take space immediately after the PHDR table, and
4631/// aim for fitting between it and where the first incremental segment is
4632/// allocated (see `initMetadata`).
4626fn initAndAllocateSegments(self: *Elf) !void {4633fn initAndAllocateSegments(self: *Elf) !void {
4627 const ehsize: u64 = switch (self.ptr_width) {4634 const ehsize: u64 = switch (self.ptr_width) {
4628 .p32 => @sizeOf(elf.Elf32_Ehdr),4635 .p32 => @sizeOf(elf.Elf32_Ehdr),