authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-22 17:18:51+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-23 17:11:20+02:00
logd9c5a26cfb992b0951c80b80298dba2d690c7639
tree439846edbd2bf8517e2c344e2264dbf6e2b161a8
parentce919ccf45951856a762ffdb8ef850301cd8c588

elf: add helper for calculating available VM size for phdr


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

src/link/Elf.zig+18-7
...@@ -373,9 +373,8 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 {...@@ -373,9 +373,8 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 {
373 return null;373 return null;
374}374}
375375
376pub fn allocatedSize(self: *Elf, start: u64) u64 {376fn allocatedSize(self: *Elf, start: u64) u64 {
377 if (start == 0)377 if (start == 0) return 0;
378 return 0;
379 var min_pos: u64 = std.math.maxInt(u64);378 var min_pos: u64 = std.math.maxInt(u64);
380 if (self.shdr_table_offset) |off| {379 if (self.shdr_table_offset) |off| {
381 if (off > start and off < min_pos) min_pos = off;380 if (off > start and off < min_pos) min_pos = off;
...@@ -391,7 +390,17 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 {...@@ -391,7 +390,17 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 {
391 return min_pos - start;390 return min_pos - start;
392}391}
393392
394pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u32) u64 {393fn allocatedVirtualSize(self: *Elf, start: u64) u64 {
394 if (start == 0) return 0;
395 var min_pos: u64 = std.math.maxInt(u64);
396 for (self.phdrs.items) |phdr| {
397 if (phdr.p_vaddr <= start) continue;
398 if (phdr.p_vaddr < min_pos) min_pos = phdr.p_vaddr;
399 }
400 return min_pos - start;
401}
402
403fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u32) u64 {
395 var start: u64 = 0;404 var start: u64 = 0;
396 while (self.detectAllocCollision(start, object_size)) |item_end| {405 while (self.detectAllocCollision(start, object_size)) |item_end| {
397 start = mem.alignForward(u64, item_end, min_alignment);406 start = mem.alignForward(u64, item_end, min_alignment);
...@@ -907,7 +916,6 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -907,7 +916,6 @@ pub fn populateMissingMetadata(self: *Elf) !void {
907}916}
908917
909pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {918pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
910 // TODO Also detect virtual address collisions.
911 const shdr = &self.shdrs.items[shdr_index];919 const shdr = &self.shdrs.items[shdr_index];
912 const phdr_index = self.phdr_to_shdr_table.get(shdr_index).?;920 const phdr_index = self.phdr_to_shdr_table.get(shdr_index).?;
913 const phdr = &self.phdrs.items[phdr_index];921 const phdr = &self.phdrs.items[phdr_index];
...@@ -922,8 +930,8 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {...@@ -922,8 +930,8 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
922 } else shdr.sh_size;930 } else shdr.sh_size;
923 shdr.sh_size = 0;931 shdr.sh_size = 0;
924932
925 log.debug("new '{?s}' file offset 0x{x} to 0x{x}", .{933 log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{
926 self.shstrtab.get(shdr.sh_name),934 self.shstrtab.getAssumeExists(shdr.sh_name),
927 new_offset,935 new_offset,
928 new_offset + existing_size,936 new_offset + existing_size,
929 });937 });
...@@ -935,6 +943,9 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {...@@ -935,6 +943,9 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
935 phdr.p_offset = new_offset;943 phdr.p_offset = new_offset;
936 }944 }
937945
946 const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr);
947 assert(needed_size <= mem_capacity); // TODO grow section in virtual memory
948
938 shdr.sh_size = needed_size;949 shdr.sh_size = needed_size;
939 phdr.p_memsz = needed_size;950 phdr.p_memsz = needed_size;
940951