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