| ... | @@ -558,43 +558,47 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 { | ... | @@ -558,43 +558,47 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 { |
| 558 | | 558 | |
| 559 | pub fn growSection(self: *Elf, shdr_index: u32, needed_size: u64, min_alignment: u64) !void { | 559 | pub fn growSection(self: *Elf, shdr_index: u32, needed_size: u64, min_alignment: u64) !void { |
| 560 | const shdr = &self.sections.items(.shdr)[shdr_index]; | 560 | const shdr = &self.sections.items(.shdr)[shdr_index]; |
| 561 | assert(shdr.sh_type != elf.SHT_NOBITS); | | |
| 562 | | 561 | |
| 563 | const allocated_size = self.allocatedSize(shdr.sh_offset); | 562 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 564 | log.debug("allocated size {x} of '{s}', needed size {x}", .{ | 563 | const allocated_size = self.allocatedSize(shdr.sh_offset); |
| 565 | allocated_size, | 564 | log.debug("allocated size {x} of '{s}', needed size {x}", .{ |
| 566 | self.getShString(shdr.sh_name), | 565 | allocated_size, |
| 567 | needed_size, | | |
| 568 | }); | | |
| 569 | | | |
| 570 | if (needed_size > allocated_size) { | | |
| 571 | const existing_size = shdr.sh_size; | | |
| 572 | shdr.sh_size = 0; | | |
| 573 | // Must move the entire section. | | |
| 574 | const new_offset = try self.findFreeSpace(needed_size, min_alignment); | | |
| 575 | | | |
| 576 | log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{ | | |
| 577 | self.getShString(shdr.sh_name), | 566 | self.getShString(shdr.sh_name), |
| 578 | new_offset, | 567 | needed_size, |
| 579 | new_offset + existing_size, | | |
| 580 | }); | 568 | }); |
| 581 | | 569 | |
| 582 | const amt = try self.base.file.?.copyRangeAll( | 570 | if (needed_size > allocated_size) { |
| 583 | shdr.sh_offset, | 571 | const existing_size = shdr.sh_size; |
| 584 | self.base.file.?, | 572 | shdr.sh_size = 0; |
| 585 | new_offset, | 573 | // Must move the entire section. |
| 586 | existing_size, | 574 | const new_offset = try self.findFreeSpace(needed_size, min_alignment); |
| 587 | ); | 575 | |
| 588 | // TODO figure out what to about this error condition - how to communicate it up. | 576 | log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{ |
| 589 | if (amt != existing_size) return error.InputOutput; | 577 | self.getShString(shdr.sh_name), |
| | 578 | new_offset, |
| | 579 | new_offset + existing_size, |
| | 580 | }); |
| | 581 | |
| | 582 | const amt = try self.base.file.?.copyRangeAll( |
| | 583 | shdr.sh_offset, |
| | 584 | self.base.file.?, |
| | 585 | new_offset, |
| | 586 | existing_size, |
| | 587 | ); |
| | 588 | // TODO figure out what to about this error condition - how to communicate it up. |
| | 589 | if (amt != existing_size) return error.InputOutput; |
| 590 | | 590 | |
| 591 | shdr.sh_offset = new_offset; | 591 | shdr.sh_offset = new_offset; |
| 592 | } else if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) { | 592 | } else if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) { |
| 593 | try self.base.file.?.setEndPos(shdr.sh_offset + needed_size); | 593 | try self.base.file.?.setEndPos(shdr.sh_offset + needed_size); |
| | 594 | } |
| 594 | } | 595 | } |
| | 596 | |
| | 597 | shdr.sh_size = needed_size; |
| | 598 | self.markDirty(shdr_index); |
| 595 | } | 599 | } |
| 596 | | 600 | |
| 597 | pub fn markDirty(self: *Elf, shdr_index: u32) void { | 601 | fn markDirty(self: *Elf, shdr_index: u32) void { |
| 598 | if (self.zigObjectPtr()) |zo| { | 602 | if (self.zigObjectPtr()) |zo| { |
| 599 | for ([_]?Symbol.Index{ | 603 | for ([_]?Symbol.Index{ |
| 600 | zo.debug_info_index, | 604 | zo.debug_info_index, |
| ... | @@ -700,11 +704,7 @@ pub fn allocateChunk(self: *Elf, args: struct { | ... | @@ -700,11 +704,7 @@ pub fn allocateChunk(self: *Elf, args: struct { |
| 700 | true; | 704 | true; |
| 701 | if (expand_section) { | 705 | if (expand_section) { |
| 702 | const needed_size = res.value + args.size; | 706 | const needed_size = res.value + args.size; |
| 703 | if (shdr.sh_type != elf.SHT_NOBITS) { | 707 | try self.growSection(args.shndx, needed_size, args.alignment.toByteUnits().?); |
| 704 | try self.growSection(args.shndx, needed_size, args.alignment.toByteUnits().?); | | |
| 705 | } | | |
| 706 | shdr.sh_size = needed_size; | | |
| 707 | self.markDirty(args.shndx); | | |
| 708 | } | 708 | } |
| 709 | | 709 | |
| 710 | return res; | 710 | return res; |