| ... | @@ -4433,8 +4433,9 @@ fn resetPhdrs(self: *Elf) !void { | ... | @@ -4433,8 +4433,9 @@ fn resetPhdrs(self: *Elf) !void { |
| 4433 | | 4433 | |
| 4434 | fn initSegments(self: *Elf) !void { | 4434 | fn initSegments(self: *Elf) !void { |
| 4435 | // Add LOAD phdrs | 4435 | // 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; |
| 4456 | | 4458 | |
| 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 | } |
| 4625 | | 4627 | |
| | 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`). |
| 4626 | fn initAndAllocateSegments(self: *Elf) !void { | 4633 | fn 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), |