| ... | ... | @@ -570,8 +570,6 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_align |
| 570 | 570 | const slice = self.sections.slice(); |
| 571 | 571 | const shdr = &slice.items(.shdr)[shdr_index]; |
| 572 | 572 | assert(shdr.sh_flags & elf.SHF_ALLOC != 0); |
| 573 | | const phndx = slice.items(.phndx)[shdr_index]; |
| 574 | | const maybe_phdr = if (phndx) |ndx| &self.phdrs.items[ndx] else null; |
| 575 | 573 | |
| 576 | 574 | log.debug("allocated size {x} of {s}, needed size {x}", .{ |
| 577 | 575 | self.allocatedSize(shdr.sh_offset), |
| ... | ... | @@ -598,11 +596,9 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_align |
| 598 | 596 | if (amt != existing_size) return error.InputOutput; |
| 599 | 597 | |
| 600 | 598 | shdr.sh_offset = new_offset; |
| 601 | | if (maybe_phdr) |phdr| phdr.p_offset = new_offset; |
| 602 | 599 | } else if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) { |
| 603 | 600 | try self.base.file.?.setEndPos(shdr.sh_offset + needed_size); |
| 604 | 601 | } |
| 605 | | if (maybe_phdr) |phdr| phdr.p_filesz = needed_size; |
| 606 | 602 | } |
| 607 | 603 | shdr.sh_size = needed_size; |
| 608 | 604 | self.markDirty(shdr_index); |
| ... | ... | @@ -3890,57 +3886,70 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3890 | 3886 | } |
| 3891 | 3887 | |
| 3892 | 3888 | const first = slice.items(.shdr)[cover.items[0]]; |
| 3893 | | var new_offset = try self.findFreeSpace(filesz, @"align"); |
| 3894 | 3889 | const phndx = self.getPhdr(.{ .type = elf.PT_LOAD, .flags = shdrToPhdrFlags(first.sh_flags) }).?; |
| 3895 | 3890 | const phdr = &self.phdrs.items[phndx]; |
| 3896 | | phdr.p_offset = new_offset; |
| 3897 | | phdr.p_vaddr = first.sh_addr; |
| 3898 | | phdr.p_paddr = first.sh_addr; |
| 3899 | | phdr.p_memsz = memsz; |
| 3900 | | phdr.p_filesz = filesz; |
| 3901 | | phdr.p_align = @"align"; |
| 3902 | | |
| 3903 | | for (cover.items) |shndx| { |
| 3904 | | const shdr = &slice.items(.shdr)[shndx]; |
| 3905 | | slice.items(.phndx)[shndx] = phndx; |
| 3906 | | if (shdr.sh_type == elf.SHT_NOBITS) { |
| 3907 | | shdr.sh_offset = 0; |
| 3908 | | continue; |
| 3909 | | } |
| 3910 | | new_offset = alignment.@"align"(shndx, shdr.sh_addralign, new_offset); |
| 3891 | const allocated_size = self.allocatedSize(phdr.p_offset); |
| 3892 | if (filesz > allocated_size) { |
| 3893 | const old_offset = phdr.p_offset; |
| 3894 | phdr.p_offset = 0; |
| 3895 | var new_offset = try self.findFreeSpace(filesz, @"align"); |
| 3896 | phdr.p_offset = new_offset; |
| 3897 | |
| 3898 | log.debug("moving phdr({d}) from 0x{x} to 0x{x}", .{ phndx, old_offset, new_offset }); |
| 3899 | |
| 3900 | for (cover.items) |shndx| { |
| 3901 | const shdr = &slice.items(.shdr)[shndx]; |
| 3902 | slice.items(.phndx)[shndx] = phndx; |
| 3903 | if (shdr.sh_type == elf.SHT_NOBITS) { |
| 3904 | shdr.sh_offset = 0; |
| 3905 | continue; |
| 3906 | } |
| 3907 | new_offset = alignment.@"align"(shndx, shdr.sh_addralign, new_offset); |
| 3911 | 3908 | |
| 3912 | | if (self.zigObjectPtr()) |zo| blk: { |
| 3913 | | const existing_size = for ([_]?Symbol.Index{ |
| 3914 | | zo.text_index, |
| 3915 | | zo.rodata_index, |
| 3916 | | zo.data_relro_index, |
| 3917 | | zo.data_index, |
| 3918 | | zo.tdata_index, |
| 3919 | | zo.eh_frame_index, |
| 3920 | | }) |maybe_sym_index| { |
| 3921 | | const sect_sym_index = maybe_sym_index orelse continue; |
| 3922 | | const sect_atom_ptr = zo.symbol(sect_sym_index).atom(self).?; |
| 3923 | | if (sect_atom_ptr.output_section_index != shndx) continue; |
| 3924 | | break sect_atom_ptr.size; |
| 3925 | | } else break :blk; |
| 3926 | 3909 | log.debug("moving {s} from 0x{x} to 0x{x}", .{ |
| 3927 | 3910 | self.getShString(shdr.sh_name), |
| 3928 | 3911 | shdr.sh_offset, |
| 3929 | 3912 | new_offset, |
| 3930 | 3913 | }); |
| 3931 | | const amt = try self.base.file.?.copyRangeAll( |
| 3932 | | shdr.sh_offset, |
| 3933 | | self.base.file.?, |
| 3934 | | new_offset, |
| 3935 | | existing_size, |
| 3936 | | ); |
| 3937 | | if (amt != existing_size) return error.InputOutput; |
| 3938 | | } |
| 3939 | 3914 | |
| 3940 | | shdr.sh_offset = new_offset; |
| 3941 | | new_offset += shdr.sh_size; |
| 3915 | if (shdr.sh_offset > 0) { |
| 3916 | // Get size actually commited to the output file. |
| 3917 | const existing_size = if (self.zigObjectPtr()) |zo| for ([_]?Symbol.Index{ |
| 3918 | zo.text_index, |
| 3919 | zo.rodata_index, |
| 3920 | zo.data_relro_index, |
| 3921 | zo.data_index, |
| 3922 | zo.tdata_index, |
| 3923 | zo.eh_frame_index, |
| 3924 | }) |maybe_sym_index| { |
| 3925 | const sect_sym_index = maybe_sym_index orelse continue; |
| 3926 | const sect_atom_ptr = zo.symbol(sect_sym_index).atom(self).?; |
| 3927 | if (sect_atom_ptr.output_section_index != shndx) continue; |
| 3928 | break sect_atom_ptr.size; |
| 3929 | } else 0 else 0 + if (!slice.items(.atom_list_2)[shndx].dirty) |
| 3930 | slice.items(.atom_list_2)[shndx].size |
| 3931 | else |
| 3932 | 0; |
| 3933 | const amt = try self.base.file.?.copyRangeAll( |
| 3934 | shdr.sh_offset, |
| 3935 | self.base.file.?, |
| 3936 | new_offset, |
| 3937 | existing_size, |
| 3938 | ); |
| 3939 | if (amt != existing_size) return error.InputOutput; |
| 3940 | } |
| 3941 | |
| 3942 | shdr.sh_offset = new_offset; |
| 3943 | new_offset += shdr.sh_size; |
| 3944 | } |
| 3942 | 3945 | } |
| 3943 | 3946 | |
| 3947 | phdr.p_vaddr = first.sh_addr; |
| 3948 | phdr.p_paddr = first.sh_addr; |
| 3949 | phdr.p_memsz = memsz; |
| 3950 | phdr.p_filesz = filesz; |
| 3951 | phdr.p_align = @"align"; |
| 3952 | |
| 3944 | 3953 | addr = mem.alignForward(u64, addr, self.page_size); |
| 3945 | 3954 | } |
| 3946 | 3955 | } |