authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-28 11:46:40+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-28 11:46:40+02:00
log42011a82498655ab3471aa92642878de7c7f024a
treedc4e85f93b2e044f05fb6dc291655d5500bf5eeb
parentdf285949f78661732031972599f720771a725241

elf: remove explicit load segment alloc - we can replicate programmatically now


1 files changed, 7 insertions(+), 31 deletions(-)

src/link/Elf.zig+7-31
......@@ -429,15 +429,15 @@ pub fn allocateSegment(self: *Elf, opts: AllocateSegmentOpts) error{OutOfMemory}
429429 const addr = opts.addr orelse blk: {
430430 const reserved_capacity = self.calcImageBase() * 4;
431431 // Calculate largest VM address
432 const count = self.phdrs.items.len;
433432 var addresses = std.ArrayList(u64).init(gpa);
434433 defer addresses.deinit();
435 try addresses.ensureTotalCapacityPrecise(count);
434 try addresses.ensureTotalCapacityPrecise(self.phdrs.items.len);
436435 for (self.phdrs.items) |phdr| {
436 if (phdr.p_type != elf.PT_LOAD) continue;
437437 addresses.appendAssumeCapacity(phdr.p_vaddr + reserved_capacity);
438438 }
439439 mem.sort(u64, addresses.items, {}, std.sort.asc(u64));
440 break :blk mem.alignForward(u64, addresses.items[count - 1], opts.alignment);
440 break :blk mem.alignForward(u64, addresses.pop(), opts.alignment);
441441 };
442442 log.debug("allocating phdr({d})({c}{c}{c}) from 0x{x} to 0x{x} (0x{x} - 0x{x})", .{
443443 index,
......@@ -543,7 +543,6 @@ pub fn populateMissingMetadata(self: *Elf) !void {
543543 };
544544 const ptr_size: u8 = self.ptrWidthBytes();
545545 const is_linux = self.base.options.target.os.tag == .linux;
546 const large_addrspace = self.base.options.target.ptrBitWidth() >= 32;
547546 const image_base = self.calcImageBase();
548547
549548 if (self.phdr_table_index == null) {
......@@ -566,23 +565,16 @@ pub fn populateMissingMetadata(self: *Elf) !void {
566565 }
567566
568567 if (self.phdr_table_load_index == null) {
569 self.phdr_table_load_index = @intCast(self.phdrs.items.len);
570 try self.phdrs.append(gpa, .{
571 .p_type = elf.PT_LOAD,
572 .p_offset = 0,
573 .p_filesz = 0,
574 .p_vaddr = image_base,
575 .p_paddr = image_base,
576 .p_memsz = 0,
577 .p_align = self.page_size,
578 .p_flags = elf.PF_R,
568 self.phdr_table_load_index = try self.allocateSegment(.{
569 .addr = image_base,
570 .size = 0,
571 .alignment = self.page_size,
579572 });
580573 self.phdr_table_dirty = true;
581574 }
582575
583576 if (self.phdr_load_re_index == null) {
584577 self.phdr_load_re_index = try self.allocateSegment(.{
585 .addr = self.defaultEntryAddress(),
586578 .size = self.base.options.program_code_size_hint,
587579 .alignment = self.page_size,
588580 .flags = elf.PF_X | elf.PF_R | elf.PF_W,
......@@ -591,12 +583,10 @@ pub fn populateMissingMetadata(self: *Elf) !void {
591583 }
592584
593585 if (self.phdr_got_index == null) {
594 const addr: u64 = if (large_addrspace) 0x4000000 else 0x8000;
595586 // We really only need ptr alignment but since we are using PROGBITS, linux requires
596587 // page align.
597588 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
598589 self.phdr_got_index = try self.allocateSegment(.{
599 .addr = addr,
600590 .size = @as(u64, ptr_size) * self.base.options.symbol_count_hint,
601591 .alignment = alignment,
602592 .flags = elf.PF_R | elf.PF_W,
......@@ -604,10 +594,8 @@ pub fn populateMissingMetadata(self: *Elf) !void {
604594 }
605595
606596 if (self.phdr_load_ro_index == null) {
607 const addr: u64 = if (large_addrspace) 0xc000000 else 0xa000;
608597 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
609598 self.phdr_load_ro_index = try self.allocateSegment(.{
610 .addr = addr,
611599 .size = 1024,
612600 .alignment = alignment,
613601 .flags = elf.PF_R | elf.PF_W,
......@@ -615,10 +603,8 @@ pub fn populateMissingMetadata(self: *Elf) !void {
615603 }
616604
617605 if (self.phdr_load_rw_index == null) {
618 const addr: u64 = if (large_addrspace) 0x10000000 else 0xc000;
619606 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
620607 self.phdr_load_rw_index = try self.allocateSegment(.{
621 .addr = addr,
622608 .size = 1024,
623609 .alignment = alignment,
624610 .flags = elf.PF_R | elf.PF_W,
......@@ -626,10 +612,8 @@ pub fn populateMissingMetadata(self: *Elf) !void {
626612 }
627613
628614 if (self.phdr_load_zerofill_index == null) {
629 const addr: u64 = if (large_addrspace) 0x14000000 else 0xf000;
630615 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
631616 self.phdr_load_zerofill_index = try self.allocateSegment(.{
632 .addr = addr,
633617 .size = 0,
634618 .alignment = alignment,
635619 .flags = elf.PF_R | elf.PF_W,
......@@ -3820,14 +3804,6 @@ pub fn calcImageBase(self: Elf) u64 {
38203804 };
38213805}
38223806
3823pub fn defaultEntryAddress(self: Elf) u64 {
3824 if (self.entry_addr) |addr| return addr;
3825 return switch (self.base.options.target.cpu.arch) {
3826 .spu_2 => 0,
3827 else => default_entry_addr,
3828 };
3829}
3830
38313807pub fn isDynLib(self: Elf) bool {
38323808 return self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic;
38333809}