authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-28 08:47:58+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-28 08:47:58+02:00
logdf285949f78661732031972599f720771a725241
treefd9a6c28dee90133a43f45c307669f4227b571a3
parent8f90dbba557b33db4f84729925bf9773f9c5c168

elf: do not assume segments laid out in increasing order in VM space


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

src/link/Elf.zig+17-8
......@@ -418,17 +418,26 @@ const AllocateSegmentOpts = struct {
418418};
419419
420420pub fn allocateSegment(self: *Elf, opts: AllocateSegmentOpts) error{OutOfMemory}!u16 {
421 const gpa = self.base.allocator;
421422 const index = @as(u16, @intCast(self.phdrs.items.len));
422 try self.phdrs.ensureUnusedCapacity(self.base.allocator, 1);
423 try self.phdrs.ensureUnusedCapacity(gpa, 1);
423424 const off = self.findFreeSpace(opts.size, opts.alignment);
424 // Memory is always allocated in sequence.
425 // TODO is this correct? Or should we implement something similar to `findFreeSpace`?
426 // How would that impact HCS?
425 // Currently, we automatically allocate memory in sequence by finding the largest
426 // allocated virtual address and going from there.
427 // TODO we want to keep machine code segment in the furthest memory range among all
428 // segments as it is most likely to grow.
427429 const addr = opts.addr orelse blk: {
428 assert(index >= 1);
429 const phdr = &self.phdrs.items[index - 1];
430 const increased_size = padToIdeal(phdr.p_vaddr + phdr.p_memsz);
431 break :blk mem.alignForward(u64, increased_size, opts.alignment);
430 const reserved_capacity = self.calcImageBase() * 4;
431 // Calculate largest VM address
432 const count = self.phdrs.items.len;
433 var addresses = std.ArrayList(u64).init(gpa);
434 defer addresses.deinit();
435 try addresses.ensureTotalCapacityPrecise(count);
436 for (self.phdrs.items) |phdr| {
437 addresses.appendAssumeCapacity(phdr.p_vaddr + reserved_capacity);
438 }
439 mem.sort(u64, addresses.items, {}, std.sort.asc(u64));
440 break :blk mem.alignForward(u64, addresses.items[count - 1], opts.alignment);
432441 };
433442 log.debug("allocating phdr({d})({c}{c}{c}) from 0x{x} to 0x{x} (0x{x} - 0x{x})", .{
434443 index,