authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-03 18:30:48+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-03 18:30:55+02:00
logc0e9b849974cdbc93053919f54f0cf3830243572
tree60ee1c5646280243901d7440719fef34b5b944b5
parent5900dc05804a4089eb7d1ccd8a36b4ade16c02e4

elf: preallocate offsets for PT_PHDR and PT_LOAD (empty) segment

Otherwise, we will be using `undefined` as the offset to allocate remaining phdrs and shdrs.

1 files changed, 17 insertions(+), 12 deletions(-)

src/link/Elf.zig+17-12
...@@ -110,7 +110,7 @@ program_headers: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{},...@@ -110,7 +110,7 @@ program_headers: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{},
110phdr_table_index: ?u16 = null,110phdr_table_index: ?u16 = null,
111/// The index into the program headers of the PT_LOAD program header containing the phdr111/// The index into the program headers of the PT_LOAD program header containing the phdr
112/// Most linkers would merge this with phdr_load_ro_index,112/// Most linkers would merge this with phdr_load_ro_index,
113/// but hot swap means we can't ensure they are consecutive.113/// but incremental linking means we can't ensure they are consecutive.
114phdr_table_load_index: ?u16 = null,114phdr_table_load_index: ?u16 = null,
115/// The index into the program headers of a PT_LOAD program header with Read and Execute flags115/// The index into the program headers of a PT_LOAD program header with Read and Execute flags
116phdr_load_re_index: ?u16 = null,116phdr_load_re_index: ?u16 = null,
...@@ -473,18 +473,19 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -473,18 +473,19 @@ pub fn populateMissingMetadata(self: *Elf) !void {
473 var new_phdr_table_index: ?u16 = null;473 var new_phdr_table_index: ?u16 = null;
474 if (self.phdr_table_index == null) {474 if (self.phdr_table_index == null) {
475 new_phdr_table_index = @intCast(u16, self.program_headers.items.len);475 new_phdr_table_index = @intCast(u16, self.program_headers.items.len);
476 const phalign: u16 = switch (self.ptr_width) {476 const p_align: u16 = switch (self.ptr_width) {
477 .p32 => @alignOf(elf.Elf32_Phdr),477 .p32 => @alignOf(elf.Elf32_Phdr),
478 .p64 => @alignOf(elf.Elf64_Phdr),478 .p64 => @alignOf(elf.Elf64_Phdr),
479 };479 };
480 const off = self.findFreeSpace(1, p_align);
480 try self.program_headers.append(gpa, .{481 try self.program_headers.append(gpa, .{
481 .p_type = elf.PT_PHDR,482 .p_type = elf.PT_PHDR,
482 .p_offset = undefined,483 .p_offset = off,
483 .p_filesz = undefined,484 .p_filesz = 1,
484 .p_vaddr = undefined,485 .p_vaddr = 0,
485 .p_paddr = undefined,486 .p_paddr = 0,
486 .p_memsz = undefined,487 .p_memsz = 0,
487 .p_align = phalign,488 .p_align = p_align,
488 .p_flags = elf.PF_R,489 .p_flags = elf.PF_R,
489 });490 });
490 self.phdr_table_dirty = true;491 self.phdr_table_dirty = true;
...@@ -494,14 +495,18 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -494,14 +495,18 @@ pub fn populateMissingMetadata(self: *Elf) !void {
494 self.phdr_table_load_index = @intCast(u16, self.program_headers.items.len);495 self.phdr_table_load_index = @intCast(u16, self.program_headers.items.len);
495 // TODO Same as for GOT496 // TODO Same as for GOT
496 const phdr_addr: u64 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x1000000 else 0x1000;497 const phdr_addr: u64 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x1000000 else 0x1000;
498 const p_align = self.page_size;
499 const off = self.findFreeSpace(1, p_align);
500 const file_size: u32 = 1;
501 log.debug("found PT_LOAD free space 0x{x} to 0x{x}", .{ off, off + file_size });
497 try self.program_headers.append(gpa, .{502 try self.program_headers.append(gpa, .{
498 .p_type = elf.PT_LOAD,503 .p_type = elf.PT_LOAD,
499 .p_offset = undefined,504 .p_offset = off,
500 .p_filesz = undefined,505 .p_filesz = file_size,
501 .p_vaddr = phdr_addr,506 .p_vaddr = phdr_addr,
502 .p_paddr = phdr_addr,507 .p_paddr = phdr_addr,
503 .p_memsz = undefined,508 .p_memsz = file_size,
504 .p_align = self.page_size,509 .p_align = p_align,
505 .p_flags = elf.PF_R,510 .p_flags = elf.PF_R,
506 });511 });
507 self.phdr_table_dirty = true;512 self.phdr_table_dirty = true;