| author | |
| committer | |
| log | 0ee2ab413fd0370a8ced8d433c71d1d951dab41c |
| tree | ae75278dcaa46cc1413e300e3f373c60a36fbf08 |
| parent | 74f12d0691292e9730327971bbf6c27a78095ae8 |
2 files changed, 37 insertions(+), 29 deletions(-)
src/link/Elf.zig+27-15| ... | ... | @@ -768,15 +768,15 @@ pub fn initMetadata(self: *Elf) !void { |
| 768 | 768 | |
| 769 | 769 | pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { |
| 770 | 770 | const shdr = &self.shdrs.items[shdr_index]; |
| 771 | const phdr_index = self.phdr_to_shdr_table.get(shdr_index).?; | |
| 772 | const phdr = &self.phdrs.items[phdr_index]; | |
| 771 | const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null; | |
| 773 | 772 | const is_zerofill = shdr.sh_type == elf.SHT_NOBITS; |
| 774 | 773 | |
| 775 | 774 | if (needed_size > self.allocatedSize(shdr.sh_offset) and !is_zerofill) { |
| 776 | 775 | const existing_size = shdr.sh_size; |
| 777 | 776 | shdr.sh_size = 0; |
| 778 | 777 | // Must move the entire section. |
| 779 | const new_offset = self.findFreeSpace(needed_size, self.page_size); | |
| 778 | const alignment = if (maybe_phdr) |phdr| phdr.p_align else shdr.sh_addralign; | |
| 779 | const new_offset = self.findFreeSpace(needed_size, alignment); | |
| 780 | 780 | |
| 781 | 781 | log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{ |
| 782 | 782 | self.getShString(shdr.sh_name), |
| ... | ... | @@ -789,25 +789,27 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { |
| 789 | 789 | if (amt != existing_size) return error.InputOutput; |
| 790 | 790 | |
| 791 | 791 | shdr.sh_offset = new_offset; |
| 792 | phdr.p_offset = new_offset; | |
| 792 | if (maybe_phdr) |phdr| phdr.p_offset = new_offset; | |
| 793 | 793 | } |
| 794 | 794 | |
| 795 | 795 | shdr.sh_size = needed_size; |
| 796 | 796 | if (!is_zerofill) { |
| 797 | phdr.p_filesz = needed_size; | |
| 797 | if (maybe_phdr) |phdr| phdr.p_filesz = needed_size; | |
| 798 | 798 | } |
| 799 | 799 | |
| 800 | const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr); | |
| 801 | if (needed_size > mem_capacity) { | |
| 802 | var err = try self.addErrorWithNotes(2); | |
| 803 | try err.addMsg(self, "fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{ | |
| 804 | phdr_index, | |
| 805 | }); | |
| 806 | try err.addNote(self, "TODO: emit relocations to memory locations in self-hosted backends", .{}); | |
| 807 | try err.addNote(self, "as a workaround, try increasing pre-allocated virtual memory of each segment", .{}); | |
| 808 | } | |
| 800 | if (maybe_phdr) |phdr| { | |
| 801 | const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr); | |
| 802 | if (needed_size > mem_capacity) { | |
| 803 | var err = try self.addErrorWithNotes(2); | |
| 804 | try err.addMsg(self, "fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{ | |
| 805 | self.phdr_to_shdr_table.get(shdr_index).?, | |
| 806 | }); | |
| 807 | try err.addNote(self, "TODO: emit relocations to memory locations in self-hosted backends", .{}); | |
| 808 | try err.addNote(self, "as a workaround, try increasing pre-allocated virtual memory of each segment", .{}); | |
| 809 | } | |
| 809 | 810 | |
| 810 | phdr.p_memsz = needed_size; | |
| 811 | phdr.p_memsz = needed_size; | |
| 812 | } | |
| 811 | 813 | |
| 812 | 814 | self.markDirty(shdr_index); |
| 813 | 815 | } |
| ... | ... | @@ -1499,7 +1501,17 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1499 | 1501 | pub fn flushObject(self: *Elf, comp: *Compilation) link.File.FlushError!void { |
| 1500 | 1502 | _ = comp; |
| 1501 | 1503 | try self.initSections(); |
| 1504 | try self.sortShdrs(); | |
| 1505 | try self.updateSectionSizes(); | |
| 1506 | ||
| 1507 | try self.allocateNonAllocSections(); | |
| 1508 | ||
| 1509 | if (build_options.enable_logging) { | |
| 1510 | state_log.debug("{}", .{self.dumpState()}); | |
| 1511 | } | |
| 1512 | ||
| 1502 | 1513 | try self.writeShdrTable(); |
| 1514 | try self.writeSyntheticSections(); | |
| 1503 | 1515 | try self.writeHeader(); |
| 1504 | 1516 | } |
| 1505 | 1517 |
src/link/Elf/ZigObject.zig+10-14| ... | ... | @@ -180,16 +180,16 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | 182 | if (self.debug_info_header_dirty) { |
| 183 | const text_phdr = &elf_file.phdrs.items[elf_file.phdr_zig_load_re_index.?]; | |
| 184 | const low_pc = text_phdr.p_vaddr; | |
| 185 | const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; | |
| 183 | const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?]; | |
| 184 | const low_pc = text_shdr.sh_addr; | |
| 185 | const high_pc = text_shdr.sh_addr + text_shdr.sh_size; | |
| 186 | 186 | try dw.writeDbgInfoHeader(elf_file.base.options.module.?, low_pc, high_pc); |
| 187 | 187 | self.debug_info_header_dirty = false; |
| 188 | 188 | } |
| 189 | 189 | |
| 190 | 190 | if (self.debug_aranges_section_dirty) { |
| 191 | const text_phdr = &elf_file.phdrs.items[elf_file.phdr_zig_load_re_index.?]; | |
| 192 | try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz); | |
| 191 | const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?]; | |
| 192 | try dw.writeDbgAranges(text_shdr.sh_addr, text_shdr.sh_size); | |
| 193 | 193 | self.debug_aranges_section_dirty = false; |
| 194 | 194 | } |
| 195 | 195 | |
| ... | ... | @@ -731,9 +731,7 @@ fn updateDeclCode( |
| 731 | 731 | |
| 732 | 732 | const shdr = elf_file.shdrs.items[shdr_index]; |
| 733 | 733 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 734 | const phdr_index = elf_file.phdr_to_shdr_table.get(shdr_index).?; | |
| 735 | const section_offset = sym.value - elf_file.phdrs.items[phdr_index].p_vaddr; | |
| 736 | const file_offset = shdr.sh_offset + section_offset; | |
| 734 | const file_offset = shdr.sh_offset + sym.value - shdr.sh_addr; | |
| 737 | 735 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 738 | 736 | } |
| 739 | 737 | } |
| ... | ... | @@ -940,7 +938,6 @@ fn updateLazySymbol( |
| 940 | 938 | .const_data => elf_file.zig_data_rel_ro_section_index.?, |
| 941 | 939 | }; |
| 942 | 940 | const local_sym = elf_file.symbol(symbol_index); |
| 943 | const phdr_index = elf_file.phdr_to_shdr_table.get(output_section_index).?; | |
| 944 | 941 | local_sym.name_offset = name_str_index; |
| 945 | 942 | local_sym.output_section_index = output_section_index; |
| 946 | 943 | const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index]; |
| ... | ... | @@ -963,8 +960,8 @@ fn updateLazySymbol( |
| 963 | 960 | const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file); |
| 964 | 961 | try elf_file.zig_got.writeOne(elf_file, gop.index); |
| 965 | 962 | |
| 966 | const section_offset = atom_ptr.value - elf_file.phdrs.items[phdr_index].p_vaddr; | |
| 967 | const file_offset = elf_file.shdrs.items[output_section_index].sh_offset + section_offset; | |
| 963 | const shdr = elf_file.shdrs.items[output_section_index]; | |
| 964 | const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr; | |
| 968 | 965 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 969 | 966 | } |
| 970 | 967 | |
| ... | ... | @@ -1038,7 +1035,6 @@ fn lowerConst( |
| 1038 | 1035 | .fail => |em| return .{ .fail = em }, |
| 1039 | 1036 | }; |
| 1040 | 1037 | |
| 1041 | const phdr_index = elf_file.phdr_to_shdr_table.get(output_section_index).?; | |
| 1042 | 1038 | const local_sym = elf_file.symbol(sym_index); |
| 1043 | 1039 | const name_str_index = try self.insertString(gpa, name); |
| 1044 | 1040 | local_sym.name_offset = name_str_index; |
| ... | ... | @@ -1061,8 +1057,8 @@ fn lowerConst( |
| 1061 | 1057 | local_sym.value = atom_ptr.value; |
| 1062 | 1058 | local_esym.st_value = atom_ptr.value; |
| 1063 | 1059 | |
| 1064 | const section_offset = atom_ptr.value - elf_file.phdrs.items[phdr_index].p_vaddr; | |
| 1065 | const file_offset = elf_file.shdrs.items[output_section_index].sh_offset + section_offset; | |
| 1060 | const shdr = elf_file.shdrs.items[output_section_index]; | |
| 1061 | const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr; | |
| 1066 | 1062 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1067 | 1063 | |
| 1068 | 1064 | return .{ .ok = sym_index }; |