authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-08 13:49:23+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-09 09:24:25+01:00
logd7e42014caadeb726d19243995365a573b6a9d06
treed9cda0dca6a6ad51cba2d482f6e9c7982b0a9c80
parentaa2f48f013c9a1f4847d49d85be82ece138190ea

elf: add growAllocSection and growNonAllocSection

Update `Dwarf.zig` to use `growNonAllocSection` for ELF and implement routine to make space for `.debug_line` header.

2 files changed, 137 insertions(+), 151 deletions(-)

src/link/Dwarf.zig+44-79
...@@ -1150,29 +1150,9 @@ pub fn commitDeclState(...@@ -1150,29 +1150,9 @@ pub fn commitDeclState(
1150 switch (self.bin_file.tag) {1150 switch (self.bin_file.tag) {
1151 .elf => {1151 .elf => {
1152 const elf_file = self.bin_file.cast(File.Elf).?;1152 const elf_file = self.bin_file.cast(File.Elf).?;
1153 const debug_line_sect = &elf_file.sections.items[elf_file.debug_line_section_index.?];1153 const shdr_index = elf_file.debug_line_section_index.?;
1154 if (needed_size != debug_line_sect.sh_size) {1154 try elf_file.growNonAllocSection(shdr_index, needed_size, 1);
1155 if (needed_size > elf_file.allocatedSize(debug_line_sect.sh_offset)) {1155 const debug_line_sect = elf_file.sections.items[shdr_index];
1156 const new_offset = elf_file.findFreeSpace(needed_size, 1);
1157 const existing_size = last_src_fn.off;
1158 log.debug("moving .debug_line section: {d} bytes from 0x{x} to 0x{x}", .{
1159 existing_size,
1160 debug_line_sect.sh_offset,
1161 new_offset,
1162 });
1163 const amt = try elf_file.base.file.?.copyRangeAll(
1164 debug_line_sect.sh_offset,
1165 elf_file.base.file.?,
1166 new_offset,
1167 existing_size,
1168 );
1169 if (amt != existing_size) return error.InputOutput;
1170 debug_line_sect.sh_offset = new_offset;
1171 }
1172 debug_line_sect.sh_size = needed_size;
1173 elf_file.shdr_table_dirty = true; // TODO look into making only the one section dirty
1174 elf_file.debug_line_header_dirty = true;
1175 }
1176 const file_pos = debug_line_sect.sh_offset + src_fn.off;1156 const file_pos = debug_line_sect.sh_offset + src_fn.off;
1177 try pwriteDbgLineNops(1157 try pwriteDbgLineNops(
1178 elf_file.base.file.?,1158 elf_file.base.file.?,
...@@ -1417,29 +1397,9 @@ fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void...@@ -1417,29 +1397,9 @@ fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void
1417 switch (self.bin_file.tag) {1397 switch (self.bin_file.tag) {
1418 .elf => {1398 .elf => {
1419 const elf_file = self.bin_file.cast(File.Elf).?;1399 const elf_file = self.bin_file.cast(File.Elf).?;
1420 const debug_info_sect = &elf_file.sections.items[elf_file.debug_info_section_index.?];1400 const shdr_index = elf_file.debug_info_section_index.?;
1421 if (needed_size != debug_info_sect.sh_size) {1401 try elf_file.growNonAllocSection(shdr_index, needed_size, 1);
1422 if (needed_size > elf_file.allocatedSize(debug_info_sect.sh_offset)) {1402 const debug_info_sect = elf_file.sections.items[shdr_index];
1423 const new_offset = elf_file.findFreeSpace(needed_size, 1);
1424 const existing_size = last_decl.off;
1425 log.debug("moving .debug_info section: {d} bytes from 0x{x} to 0x{x}", .{
1426 existing_size,
1427 debug_info_sect.sh_offset,
1428 new_offset,
1429 });
1430 const amt = try elf_file.base.file.?.copyRangeAll(
1431 debug_info_sect.sh_offset,
1432 elf_file.base.file.?,
1433 new_offset,
1434 existing_size,
1435 );
1436 if (amt != existing_size) return error.InputOutput;
1437 debug_info_sect.sh_offset = new_offset;
1438 }
1439 debug_info_sect.sh_size = needed_size;
1440 elf_file.shdr_table_dirty = true; // TODO look into making only the one section dirty
1441 elf_file.debug_info_header_dirty = true;
1442 }
1443 const file_pos = debug_info_sect.sh_offset + atom.off;1403 const file_pos = debug_info_sect.sh_offset + atom.off;
1444 try pwriteDbgInfoNops(1404 try pwriteDbgInfoNops(
1445 elf_file.base.file.?,1405 elf_file.base.file.?,
...@@ -1728,18 +1688,9 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void {...@@ -1728,18 +1688,9 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void {
1728 switch (self.bin_file.tag) {1688 switch (self.bin_file.tag) {
1729 .elf => {1689 .elf => {
1730 const elf_file = self.bin_file.cast(File.Elf).?;1690 const elf_file = self.bin_file.cast(File.Elf).?;
1731 const debug_abbrev_sect = &elf_file.sections.items[elf_file.debug_abbrev_section_index.?];1691 const shdr_index = elf_file.debug_abbrev_section_index.?;
1732 const allocated_size = elf_file.allocatedSize(debug_abbrev_sect.sh_offset);1692 try elf_file.growNonAllocSection(shdr_index, needed_size, 1);
1733 if (needed_size > allocated_size) {1693 const debug_abbrev_sect = elf_file.sections.items[shdr_index];
1734 debug_abbrev_sect.sh_size = 0; // free the space
1735 debug_abbrev_sect.sh_offset = elf_file.findFreeSpace(needed_size, 1);
1736 }
1737 debug_abbrev_sect.sh_size = needed_size;
1738 log.debug(".debug_abbrev start=0x{x} end=0x{x}", .{
1739 debug_abbrev_sect.sh_offset,
1740 debug_abbrev_sect.sh_offset + needed_size,
1741 });
1742
1743 const file_pos = debug_abbrev_sect.sh_offset + abbrev_offset;1694 const file_pos = debug_abbrev_sect.sh_offset + abbrev_offset;
1744 try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);1695 try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
1745 },1696 },
...@@ -2174,17 +2125,9 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {...@@ -2174,17 +2125,9 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
2174 switch (self.bin_file.tag) {2125 switch (self.bin_file.tag) {
2175 .elf => {2126 .elf => {
2176 const elf_file = self.bin_file.cast(File.Elf).?;2127 const elf_file = self.bin_file.cast(File.Elf).?;
2177 const debug_aranges_sect = &elf_file.sections.items[elf_file.debug_aranges_section_index.?];2128 const shdr_index = elf_file.debug_aranges_section_index.?;
2178 const allocated_size = elf_file.allocatedSize(debug_aranges_sect.sh_offset);2129 try elf_file.growNonAllocSection(shdr_index, needed_size, 16);
2179 if (needed_size > allocated_size) {2130 const debug_aranges_sect = elf_file.sections.items[shdr_index];
2180 debug_aranges_sect.sh_size = 0; // free the space
2181 debug_aranges_sect.sh_offset = elf_file.findFreeSpace(needed_size, 16);
2182 }
2183 debug_aranges_sect.sh_size = needed_size;
2184 log.debug(".debug_aranges start=0x{x} end=0x{x}", .{
2185 debug_aranges_sect.sh_offset,
2186 debug_aranges_sect.sh_offset + needed_size,
2187 });
2188 const file_pos = debug_aranges_sect.sh_offset;2131 const file_pos = debug_aranges_sect.sh_offset;
2189 try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);2132 try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);
2190 },2133 },
...@@ -2335,21 +2278,40 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {...@@ -2335,21 +2278,40 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {
2335 const needed_with_padding = padToIdeal(needed_bytes);2278 const needed_with_padding = padToIdeal(needed_bytes);
2336 const delta = needed_with_padding - dbg_line_prg_off;2279 const delta = needed_with_padding - dbg_line_prg_off;
23372280
2338 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
2339 const sect_index = d_sym.debug_line_section_index.?;
2340 const needed_size = @intCast(u32, d_sym.getSection(sect_index).size + delta);
2341 try d_sym.growSection(sect_index, needed_size);
2342
2343 var src_fn = self.dbg_line_fn_first.?;2281 var src_fn = self.dbg_line_fn_first.?;
2344 const last_fn = self.dbg_line_fn_last.?;2282 const last_fn = self.dbg_line_fn_last.?;
2345 const file_pos = d_sym.getSection(sect_index).offset + src_fn.off;
23462283
2347 var buffer = try gpa.alloc(u8, last_fn.off + last_fn.len - src_fn.off);2284 var buffer = try gpa.alloc(u8, last_fn.off + last_fn.len - src_fn.off);
2348 defer gpa.free(buffer);2285 defer gpa.free(buffer);
2349 const amt = try d_sym.file.preadAll(buffer, file_pos);
2350 if (amt != buffer.len) return error.InputOutput;
23512286
2352 try d_sym.file.pwriteAll(buffer, file_pos + delta);2287 switch (self.bin_file.tag) {
2288 .elf => {
2289 const elf_file = self.bin_file.cast(File.Elf).?;
2290 const shdr_index = elf_file.debug_line_section_index.?;
2291 const needed_size = elf_file.sections.items[shdr_index].sh_size + delta;
2292 try elf_file.growNonAllocSection(shdr_index, needed_size, 1);
2293 const file_pos = elf_file.sections.items[shdr_index].sh_offset + src_fn.off;
2294
2295 const amt = try elf_file.base.file.?.preadAll(buffer, file_pos);
2296 if (amt != buffer.len) return error.InputOutput;
2297
2298 try elf_file.base.file.?.pwriteAll(buffer, file_pos + delta);
2299 },
2300 .macho => {
2301 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
2302 const sect_index = d_sym.debug_line_section_index.?;
2303 const needed_size = @intCast(u32, d_sym.getSection(sect_index).size + delta);
2304 try d_sym.growSection(sect_index, needed_size);
2305 const file_pos = d_sym.getSection(sect_index).offset + src_fn.off;
2306
2307 const amt = try d_sym.file.preadAll(buffer, file_pos);
2308 if (amt != buffer.len) return error.InputOutput;
2309
2310 try d_sym.file.pwriteAll(buffer, file_pos + delta);
2311 },
2312 .wasm => @panic("TODO grow section"),
2313 else => unreachable,
2314 }
23532315
2354 while (true) {2316 while (true) {
2355 src_fn.off += delta;2317 src_fn.off += delta;
...@@ -2568,7 +2530,10 @@ fn addDIFile(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 {...@@ -2568,7 +2530,10 @@ fn addDIFile(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 {
2568 const gop = try self.di_files.getOrPut(self.allocator, file_scope);2530 const gop = try self.di_files.getOrPut(self.allocator, file_scope);
2569 if (!gop.found_existing) {2531 if (!gop.found_existing) {
2570 switch (self.bin_file.tag) {2532 switch (self.bin_file.tag) {
2571 .elf => self.bin_file.cast(File.Elf).?.debug_line_header_dirty = true,2533 .elf => {
2534 const elf_file = self.bin_file.cast(File.Elf).?;
2535 elf_file.markDirty(elf_file.debug_line_section_index.?, null);
2536 },
2572 .macho => {2537 .macho => {
2573 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;2538 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
2574 d_sym.markDirty(d_sym.debug_line_section_index.?);2539 d_sym.markDirty(d_sym.debug_line_section_index.?);
src/link/Elf.zig+93-72
...@@ -931,6 +931,94 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -931,6 +931,94 @@ pub fn populateMissingMetadata(self: *Elf) !void {
931 }931 }
932}932}
933933
934fn growAllocSection(self: *Elf, shdr_index: u16, phdr_index: u16, needed_size: u64) !void {
935 // TODO Also detect virtual address collisions.
936 const shdr = &self.sections.items[shdr_index];
937 const phdr = &self.program_headers.items[phdr_index];
938
939 if (needed_size > self.allocatedSize(shdr.sh_offset)) {
940 // Must move the entire section.
941 const new_offset = self.findFreeSpace(needed_size, self.page_size);
942 const existing_size = if (self.atoms.get(phdr_index)) |last| blk: {
943 const sym = self.local_symbols.items[last.local_sym_index];
944 break :blk (sym.st_value + sym.st_size) - phdr.p_vaddr;
945 } else if (shdr_index == self.got_section_index.?) blk: {
946 break :blk shdr.sh_size;
947 } else 0;
948 shdr.sh_size = 0;
949
950 log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{
951 self.getString(shdr.sh_name),
952 new_offset,
953 new_offset + existing_size,
954 });
955
956 const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, existing_size);
957 if (amt != existing_size) return error.InputOutput;
958
959 shdr.sh_offset = new_offset;
960 phdr.p_offset = new_offset;
961 }
962
963 shdr.sh_size = needed_size;
964 phdr.p_memsz = needed_size;
965 phdr.p_filesz = needed_size;
966
967 self.markDirty(shdr_index, phdr_index);
968}
969
970pub fn growNonAllocSection(self: *Elf, shdr_index: u16, needed_size: u64, min_alignment: u32) !void {
971 const shdr = &self.sections.items[shdr_index];
972
973 if (needed_size > self.allocatedSize(shdr.sh_offset)) {
974 const existing_size = if (self.symtab_section_index.? == shdr_index) blk: {
975 const sym_size: u64 = switch (self.ptr_width) {
976 .p32 => @sizeOf(elf.Elf32_Sym),
977 .p64 => @sizeOf(elf.Elf64_Sym),
978 };
979 break :blk @as(u64, shdr.sh_info) * sym_size;
980 } else shdr.sh_size;
981 shdr.sh_size = 0;
982 // Move all the symbols to a new file location.
983 const new_offset = self.findFreeSpace(needed_size, min_alignment);
984 log.debug("moving '{s}' from 0x{x} to 0x{x}", .{ self.getString(shdr.sh_name), shdr.sh_offset, new_offset });
985 const amt = try self.base.file.?.copyRangeAll(
986 shdr.sh_offset,
987 self.base.file.?,
988 new_offset,
989 existing_size,
990 );
991 if (amt != existing_size) return error.InputOutput;
992 shdr.sh_offset = new_offset;
993 }
994
995 shdr.sh_size = needed_size; // anticipating adding the global symbols later
996
997 self.markDirty(shdr_index, null);
998}
999
1000pub fn markDirty(self: *Elf, shdr_index: u16, phdr_index: ?u16) void {
1001 self.shdr_table_dirty = true; // TODO look into only writing one section
1002
1003 if (phdr_index) |_| {
1004 self.phdr_table_dirty = true; // TODO look into making only the one program header dirty
1005 }
1006
1007 if (self.dwarf) |_| {
1008 if (self.debug_info_section_index.? == shdr_index) {
1009 self.debug_info_header_dirty = true;
1010 } else if (self.debug_line_section_index.? == shdr_index) {
1011 self.debug_line_header_dirty = true;
1012 } else if (self.debug_abbrev_section_index.? == shdr_index) {
1013 self.debug_abbrev_section_dirty = true;
1014 } else if (self.debug_str_section_index.? == shdr_index) {
1015 self.debug_strtab_dirty = true;
1016 } else if (self.debug_aranges_section_index.? == shdr_index) {
1017 self.debug_aranges_section_dirty = true;
1018 }
1019 }
1020}
1021
934pub fn flush(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {1022pub fn flush(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
935 if (self.base.options.emit == null) {1023 if (self.base.options.emit == null) {
936 if (build_options.have_llvm) {1024 if (build_options.have_llvm) {
...@@ -2134,27 +2222,10 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al...@@ -2134,27 +2222,10 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al
21342222
2135 const expand_text_section = block_placement == null or block_placement.?.next == null;2223 const expand_text_section = block_placement == null or block_placement.?.next == null;
2136 if (expand_text_section) {2224 if (expand_text_section) {
2137 const text_capacity = self.allocatedSize(shdr.sh_offset);
2138 const needed_size = (vaddr + new_block_size) - phdr.p_vaddr;2225 const needed_size = (vaddr + new_block_size) - phdr.p_vaddr;
2139 if (needed_size > text_capacity) {2226 try self.growAllocSection(shdr_index, phdr_index, needed_size);
2140 // Must move the entire section.
2141 const new_offset = self.findFreeSpace(needed_size, self.page_size);
2142 const text_size = if (self.atoms.get(phdr_index)) |last| blk: {
2143 const sym = self.local_symbols.items[last.local_sym_index];
2144 break :blk (sym.st_value + sym.st_size) - phdr.p_vaddr;
2145 } else 0;
2146 log.debug("new PT_LOAD file offset 0x{x} to 0x{x}", .{ new_offset, new_offset + text_size });
2147 const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, text_size);
2148 if (amt != text_size) return error.InputOutput;
2149 shdr.sh_offset = new_offset;
2150 phdr.p_offset = new_offset;
2151 }
2152 _ = try self.atoms.put(self.base.allocator, phdr_index, text_block);2227 _ = try self.atoms.put(self.base.allocator, phdr_index, text_block);
21532228
2154 shdr.sh_size = needed_size;
2155 phdr.p_memsz = needed_size;
2156 phdr.p_filesz = needed_size;
2157
2158 if (self.dwarf) |_| {2229 if (self.dwarf) |_| {
2159 // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address2230 // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address
2160 // range of the compilation unit. When we expand the text section, this range changes,2231 // range of the compilation unit. When we expand the text section, this range changes,
...@@ -2165,9 +2236,6 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al...@@ -2165,9 +2236,6 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al
2165 // model each package as a different compilation unit.2236 // model each package as a different compilation unit.
2166 self.debug_aranges_section_dirty = true;2237 self.debug_aranges_section_dirty = true;
2167 }2238 }
2168
2169 self.phdr_table_dirty = true; // TODO look into making only the one program header dirty
2170 self.shdr_table_dirty = true; // TODO look into making only the one section dirty
2171 }2239 }
2172 shdr.sh_addralign = math.max(shdr.sh_addralign, alignment);2240 shdr.sh_addralign = math.max(shdr.sh_addralign, alignment);
21732241
...@@ -2747,31 +2815,14 @@ fn writeSectHeader(self: *Elf, index: usize) !void {...@@ -2747,31 +2815,14 @@ fn writeSectHeader(self: *Elf, index: usize) !void {
2747}2815}
27482816
2749fn writeOffsetTableEntry(self: *Elf, index: usize) !void {2817fn writeOffsetTableEntry(self: *Elf, index: usize) !void {
2750 const shdr = &self.sections.items[self.got_section_index.?];
2751 const phdr = &self.program_headers.items[self.phdr_got_index.?];
2752 const entry_size: u16 = self.archPtrWidthBytes();2818 const entry_size: u16 = self.archPtrWidthBytes();
2753 if (self.offset_table_count_dirty) {2819 if (self.offset_table_count_dirty) {
2754 // TODO Also detect virtual address collisions.
2755 const allocated_size = self.allocatedSize(shdr.sh_offset);
2756 const needed_size = self.offset_table.items.len * entry_size;2820 const needed_size = self.offset_table.items.len * entry_size;
2757 if (needed_size > allocated_size) {2821 try self.growAllocSection(self.got_section_index.?, self.phdr_got_index.?, needed_size);
2758 // Must move the entire got section.
2759 const new_offset = self.findFreeSpace(needed_size, self.page_size);
2760 const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, shdr.sh_size);
2761 if (amt != shdr.sh_size) return error.InputOutput;
2762 shdr.sh_offset = new_offset;
2763 phdr.p_offset = new_offset;
2764 }
2765 shdr.sh_size = needed_size;
2766 phdr.p_memsz = needed_size;
2767 phdr.p_filesz = needed_size;
2768
2769 self.shdr_table_dirty = true; // TODO look into making only the one section dirty
2770 self.phdr_table_dirty = true; // TODO look into making only the one program header dirty
2771
2772 self.offset_table_count_dirty = false;2822 self.offset_table_count_dirty = false;
2773 }2823 }
2774 const endian = self.base.options.target.cpu.arch.endian();2824 const endian = self.base.options.target.cpu.arch.endian();
2825 const shdr = &self.sections.items[self.got_section_index.?];
2775 const off = shdr.sh_offset + @as(u64, entry_size) * index;2826 const off = shdr.sh_offset + @as(u64, entry_size) * index;
2776 switch (entry_size) {2827 switch (entry_size) {
2777 2 => {2828 2 => {
...@@ -2810,23 +2861,8 @@ fn writeSymbol(self: *Elf, index: usize) !void {...@@ -2810,23 +2861,8 @@ fn writeSymbol(self: *Elf, index: usize) !void {
2810 .p64 => @alignOf(elf.Elf64_Sym),2861 .p64 => @alignOf(elf.Elf64_Sym),
2811 };2862 };
2812 const needed_size = (self.local_symbols.items.len + self.global_symbols.items.len) * sym_size;2863 const needed_size = (self.local_symbols.items.len + self.global_symbols.items.len) * sym_size;
2813 if (needed_size > self.allocatedSize(syms_sect.sh_offset)) {2864 try self.growNonAllocSection(self.symtab_section_index.?, needed_size, sym_align);
2814 // Move all the symbols to a new file location.
2815 const new_offset = self.findFreeSpace(needed_size, sym_align);
2816 log.debug("moving '.symtab' from 0x{x} to 0x{x}", .{ syms_sect.sh_offset, new_offset });
2817 const existing_size = @as(u64, syms_sect.sh_info) * sym_size;
2818 const amt = try self.base.file.?.copyRangeAll(
2819 syms_sect.sh_offset,
2820 self.base.file.?,
2821 new_offset,
2822 existing_size,
2823 );
2824 if (amt != existing_size) return error.InputOutput;
2825 syms_sect.sh_offset = new_offset;
2826 }
2827 syms_sect.sh_info = @intCast(u32, self.local_symbols.items.len);2865 syms_sect.sh_info = @intCast(u32, self.local_symbols.items.len);
2828 syms_sect.sh_size = needed_size; // anticipating adding the global symbols later
2829 self.shdr_table_dirty = true; // TODO look into only writing one section
2830 }2866 }
2831 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();2867 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
2832 const off = switch (self.ptr_width) {2868 const off = switch (self.ptr_width) {
...@@ -2874,22 +2910,7 @@ fn writeAllGlobalSymbols(self: *Elf) !void {...@@ -2874,22 +2910,7 @@ fn writeAllGlobalSymbols(self: *Elf) !void {
2874 .p64 => @alignOf(elf.Elf64_Sym),2910 .p64 => @alignOf(elf.Elf64_Sym),
2875 };2911 };
2876 const needed_size = (self.local_symbols.items.len + self.global_symbols.items.len) * sym_size;2912 const needed_size = (self.local_symbols.items.len + self.global_symbols.items.len) * sym_size;
2877 if (needed_size > self.allocatedSize(syms_sect.sh_offset)) {2913 try self.growNonAllocSection(self.symtab_section_index.?, needed_size, sym_align);
2878 // Move all the symbols to a new file location.
2879 const new_offset = self.findFreeSpace(needed_size, sym_align);
2880 log.debug("moving '.symtab' from 0x{x} to 0x{x}", .{ syms_sect.sh_offset, new_offset });
2881 const existing_size = @as(u64, syms_sect.sh_info) * sym_size;
2882 const amt = try self.base.file.?.copyRangeAll(
2883 syms_sect.sh_offset,
2884 self.base.file.?,
2885 new_offset,
2886 existing_size,
2887 );
2888 if (amt != existing_size) return error.InputOutput;
2889 syms_sect.sh_offset = new_offset;
2890 }
2891 syms_sect.sh_size = needed_size; // anticipating adding the global symbols later
2892 self.shdr_table_dirty = true; // TODO look into only writing one section
28932914
2894 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();2915 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
2895 const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size;2916 const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size;