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}...@@ -429,15 +429,15 @@ pub fn allocateSegment(self: *Elf, opts: AllocateSegmentOpts) error{OutOfMemory}
429 const addr = opts.addr orelse blk: {429 const addr = opts.addr orelse blk: {
430 const reserved_capacity = self.calcImageBase() * 4;430 const reserved_capacity = self.calcImageBase() * 4;
431 // Calculate largest VM address431 // Calculate largest VM address
432 const count = self.phdrs.items.len;
433 var addresses = std.ArrayList(u64).init(gpa);432 var addresses = std.ArrayList(u64).init(gpa);
434 defer addresses.deinit();433 defer addresses.deinit();
435 try addresses.ensureTotalCapacityPrecise(count);434 try addresses.ensureTotalCapacityPrecise(self.phdrs.items.len);
436 for (self.phdrs.items) |phdr| {435 for (self.phdrs.items) |phdr| {
436 if (phdr.p_type != elf.PT_LOAD) continue;
437 addresses.appendAssumeCapacity(phdr.p_vaddr + reserved_capacity);437 addresses.appendAssumeCapacity(phdr.p_vaddr + reserved_capacity);
438 }438 }
439 mem.sort(u64, addresses.items, {}, std.sort.asc(u64));439 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);
441 };441 };
442 log.debug("allocating phdr({d})({c}{c}{c}) from 0x{x} to 0x{x} (0x{x} - 0x{x})", .{442 log.debug("allocating phdr({d})({c}{c}{c}) from 0x{x} to 0x{x} (0x{x} - 0x{x})", .{
443 index,443 index,
...@@ -543,7 +543,6 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -543,7 +543,6 @@ pub fn populateMissingMetadata(self: *Elf) !void {
543 };543 };
544 const ptr_size: u8 = self.ptrWidthBytes();544 const ptr_size: u8 = self.ptrWidthBytes();
545 const is_linux = self.base.options.target.os.tag == .linux;545 const is_linux = self.base.options.target.os.tag == .linux;
546 const large_addrspace = self.base.options.target.ptrBitWidth() >= 32;
547 const image_base = self.calcImageBase();546 const image_base = self.calcImageBase();
548547
549 if (self.phdr_table_index == null) {548 if (self.phdr_table_index == null) {
...@@ -566,23 +565,16 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -566,23 +565,16 @@ pub fn populateMissingMetadata(self: *Elf) !void {
566 }565 }
567566
568 if (self.phdr_table_load_index == null) {567 if (self.phdr_table_load_index == null) {
569 self.phdr_table_load_index = @intCast(self.phdrs.items.len);568 self.phdr_table_load_index = try self.allocateSegment(.{
570 try self.phdrs.append(gpa, .{569 .addr = image_base,
571 .p_type = elf.PT_LOAD,570 .size = 0,
572 .p_offset = 0,571 .alignment = self.page_size,
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,
579 });572 });
580 self.phdr_table_dirty = true;573 self.phdr_table_dirty = true;
581 }574 }
582575
583 if (self.phdr_load_re_index == null) {576 if (self.phdr_load_re_index == null) {
584 self.phdr_load_re_index = try self.allocateSegment(.{577 self.phdr_load_re_index = try self.allocateSegment(.{
585 .addr = self.defaultEntryAddress(),
586 .size = self.base.options.program_code_size_hint,578 .size = self.base.options.program_code_size_hint,
587 .alignment = self.page_size,579 .alignment = self.page_size,
588 .flags = elf.PF_X | elf.PF_R | elf.PF_W,580 .flags = elf.PF_X | elf.PF_R | elf.PF_W,
...@@ -591,12 +583,10 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -591,12 +583,10 @@ pub fn populateMissingMetadata(self: *Elf) !void {
591 }583 }
592584
593 if (self.phdr_got_index == null) {585 if (self.phdr_got_index == null) {
594 const addr: u64 = if (large_addrspace) 0x4000000 else 0x8000;
595 // We really only need ptr alignment but since we are using PROGBITS, linux requires586 // We really only need ptr alignment but since we are using PROGBITS, linux requires
596 // page align.587 // page align.
597 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);588 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
598 self.phdr_got_index = try self.allocateSegment(.{589 self.phdr_got_index = try self.allocateSegment(.{
599 .addr = addr,
600 .size = @as(u64, ptr_size) * self.base.options.symbol_count_hint,590 .size = @as(u64, ptr_size) * self.base.options.symbol_count_hint,
601 .alignment = alignment,591 .alignment = alignment,
602 .flags = elf.PF_R | elf.PF_W,592 .flags = elf.PF_R | elf.PF_W,
...@@ -604,10 +594,8 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -604,10 +594,8 @@ pub fn populateMissingMetadata(self: *Elf) !void {
604 }594 }
605595
606 if (self.phdr_load_ro_index == null) {596 if (self.phdr_load_ro_index == null) {
607 const addr: u64 = if (large_addrspace) 0xc000000 else 0xa000;
608 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);597 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
609 self.phdr_load_ro_index = try self.allocateSegment(.{598 self.phdr_load_ro_index = try self.allocateSegment(.{
610 .addr = addr,
611 .size = 1024,599 .size = 1024,
612 .alignment = alignment,600 .alignment = alignment,
613 .flags = elf.PF_R | elf.PF_W,601 .flags = elf.PF_R | elf.PF_W,
...@@ -615,10 +603,8 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -615,10 +603,8 @@ pub fn populateMissingMetadata(self: *Elf) !void {
615 }603 }
616604
617 if (self.phdr_load_rw_index == null) {605 if (self.phdr_load_rw_index == null) {
618 const addr: u64 = if (large_addrspace) 0x10000000 else 0xc000;
619 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);606 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
620 self.phdr_load_rw_index = try self.allocateSegment(.{607 self.phdr_load_rw_index = try self.allocateSegment(.{
621 .addr = addr,
622 .size = 1024,608 .size = 1024,
623 .alignment = alignment,609 .alignment = alignment,
624 .flags = elf.PF_R | elf.PF_W,610 .flags = elf.PF_R | elf.PF_W,
...@@ -626,10 +612,8 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -626,10 +612,8 @@ pub fn populateMissingMetadata(self: *Elf) !void {
626 }612 }
627613
628 if (self.phdr_load_zerofill_index == null) {614 if (self.phdr_load_zerofill_index == null) {
629 const addr: u64 = if (large_addrspace) 0x14000000 else 0xf000;
630 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);615 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
631 self.phdr_load_zerofill_index = try self.allocateSegment(.{616 self.phdr_load_zerofill_index = try self.allocateSegment(.{
632 .addr = addr,
633 .size = 0,617 .size = 0,
634 .alignment = alignment,618 .alignment = alignment,
635 .flags = elf.PF_R | elf.PF_W,619 .flags = elf.PF_R | elf.PF_W,
...@@ -3820,14 +3804,6 @@ pub fn calcImageBase(self: Elf) u64 {...@@ -3820,14 +3804,6 @@ pub fn calcImageBase(self: Elf) u64 {
3820 };3804 };
3821}3805}
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
3831pub fn isDynLib(self: Elf) bool {3807pub fn isDynLib(self: Elf) bool {
3832 return self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic;3808 return self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic;
3833}3809}