| author | |
| committer | |
| log | 8530e997ea6673ebdeb2c90d6d2eb2d777a99fcb |
| tree | b412bc2a28b5a0d64194fcc4fb9be75b55d01170 |
| parent | b9b1174d069fcf201df79cb2fbaecdfc1fc74206 |
6 files changed, 638 insertions(+), 513 deletions(-)
src/Zcu/PerThread.zig+2-1| ... | ... | @@ -861,6 +861,7 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void { |
| 861 | 861 | log.debug("tracking failed for %{d}", .{old_inst}); |
| 862 | 862 | tracked_inst.inst = .lost; |
| 863 | 863 | try zcu.markDependeeOutdated(.not_marked_po, .{ .src_hash = tracked_inst_index }); |
| 864 | try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .lost_tracking = tracked_inst_index }); | |
| 864 | 865 | continue; |
| 865 | 866 | }; |
| 866 | 867 | tracked_inst.inst = InternPool.TrackedInst.MaybeLost.ZirIndex.wrap(new_inst); |
| ... | ... | @@ -981,7 +982,7 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void { |
| 981 | 982 | /// Ensures that `zcu.fileRootType` on this `file_index` is populated (not `.none`). This implies |
| 982 | 983 | /// that the file's namespace is scanned, discovering declarations. |
| 983 | 984 | /// |
| 984 | /// Typical Zig compilations begin by claling this function on the root source file of the standard | |
| 985 | /// Typical Zig compilations begin by calling this function on the root source file of the standard | |
| 985 | 986 | /// library, `lib/std/std.zig`. The resulting namespace scan discovers a `comptime` declaration in |
| 986 | 987 | /// that file, which is queued for analysis, and everything goes from there. |
| 987 | 988 | pub fn ensureFilePopulated(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Allocator.Error || Io.Cancelable)!void { |
src/link.zig+29-3| ... | ... | @@ -878,12 +878,11 @@ pub const File = struct { |
| 878 | 878 | const inst = file.zir.?.instructions.get(@backingInt(ti.inst)); |
| 879 | 879 | assert(inst.tag == .declaration); |
| 880 | 880 | } |
| 881 | ||
| 882 | 881 | switch (base.tag) { |
| 883 | 882 | .lld => unreachable, |
| 884 | .spirv => {}, | |
| 885 | 883 | .plan9 => unreachable, |
| 886 | .elf2, .coff2 => {}, | |
| 884 | .spirv => {}, | |
| 885 | .coff2 => {}, | |
| 887 | 886 | inline else => |tag| { |
| 888 | 887 | dev.check(tag.devFeature()); |
| 889 | 888 | return @as(*tag.Type(), @fieldParentPtr("base", base)).updateLineNumber(pt, ti_id); |
| ... | ... | @@ -891,6 +890,19 @@ pub const File = struct { |
| 891 | 890 | } |
| 892 | 891 | } |
| 893 | 892 | |
| 893 | fn lostTracking(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) Error!void { | |
| 894 | assert(base.comp.zcu.?.llvm_object == null); | |
| 895 | switch (base.tag) { | |
| 896 | .lld => unreachable, | |
| 897 | .plan9 => unreachable, | |
| 898 | else => {}, | |
| 899 | inline .elf2 => |tag| { | |
| 900 | dev.check(tag.devFeature()); | |
| 901 | return @as(*tag.Type(), @fieldParentPtr("base", base)).lostTracking(pt, ti_id); | |
| 902 | }, | |
| 903 | } | |
| 904 | } | |
| 905 | ||
| 894 | 906 | pub fn releaseLock(base: *File) void { |
| 895 | 907 | const comp = base.comp; |
| 896 | 908 | const io = comp.io; |
| ... | ... | @@ -1441,6 +1453,7 @@ pub const ZcuTask = union(enum) { |
| 1441 | 1453 | success: bool, |
| 1442 | 1454 | }, |
| 1443 | 1455 | debug_update_line_number: InternPool.TrackedInst.Index, |
| 1456 | lost_tracking: InternPool.TrackedInst.Index, | |
| 1444 | 1457 | }; |
| 1445 | 1458 | |
| 1446 | 1459 | pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| ... | ... | @@ -1713,6 +1726,19 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1713 | 1726 | } |
| 1714 | 1727 | break :nav null; |
| 1715 | 1728 | }, |
| 1729 | .lost_tracking => |ti| nav: { | |
| 1730 | const nav_prog_node = comp.link_prog_node.start("Lost tracking", 0); | |
| 1731 | defer nav_prog_node.end(); | |
| 1732 | if (pt.zcu.llvm_object == null) { | |
| 1733 | if (comp.bin_file) |lf| { | |
| 1734 | lf.lostTracking(pt, ti) catch |err| switch (err) { | |
| 1735 | error.OutOfMemory => diags.setAllocFailure(), | |
| 1736 | else => |e| log.err("lost tracking failed: {s}", .{@errorName(e)}), | |
| 1737 | }; | |
| 1738 | } | |
| 1739 | } | |
| 1740 | break :nav null; | |
| 1741 | }, | |
| 1716 | 1742 | }; |
| 1717 | 1743 | |
| 1718 | 1744 | if (timer.finish(io)) |ns_link| report_time: { |
src/link/Coff.zig+71-70| ... | ... | @@ -536,7 +536,7 @@ pub const Member = struct { |
| 536 | 536 | const new_size = Alignment.@"4".forward(old_size + name.len + 1); |
| 537 | 537 | assert(new_size < comptime try std.math.powi(u64, 10, max_name_len - 1)); |
| 538 | 538 | |
| 539 | try Node.known.longnames_member.resizeLeaf(&coff.mf, gpa, new_size); | |
| 539 | try Node.known.longnames_member.resizeLeaf(gpa, &coff.mf, new_size); | |
| 540 | 540 | const name_table_slice = Node.known.longnames_member.slice(&coff.mf); |
| 541 | 541 | const name_slice = name_table_slice[@intCast(old_size)..][0 .. name.len + 1]; |
| 542 | 542 | @memcpy(name_slice[0..name.len], name); |
| ... | ... | @@ -1840,13 +1840,13 @@ fn initHeaders( |
| 1840 | 1840 | coff.nodes.appendAssumeCapacity(.file); |
| 1841 | 1841 | |
| 1842 | 1842 | const header_ni = Node.known.header; |
| 1843 | assert(header_ni == try Node.known.file.addOnlyHeaderChild(&coff.mf, gpa, .{ | |
| 1843 | assert(header_ni == try Node.known.file.addOnlyHeaderChild(gpa, &coff.mf, .{ | |
| 1844 | 1844 | .alignment = coff.mf.flags.block_size, |
| 1845 | 1845 | })); |
| 1846 | 1846 | coff.nodes.appendAssumeCapacity(.header); |
| 1847 | 1847 | |
| 1848 | 1848 | const coff_parent_ni: MappedFile.Node.Index = if (is_archive) parent: { |
| 1849 | assert(try Node.known.file.addHeaderChildAfter(&coff.mf, gpa, .wrap(header_ni), .{ | |
| 1849 | assert(try Node.known.file.addHeaderChildAfter(gpa, &coff.mf, .wrap(header_ni), .{ | |
| 1850 | 1850 | .size = std.coff.archive_signature.len, |
| 1851 | 1851 | .alignment = .@"4", |
| 1852 | 1852 | }) == Node.known.signature); |
| ... | ... | @@ -1879,7 +1879,7 @@ fn initHeaders( |
| 1879 | 1879 | const zcu_member = zcu_mi.get(coff); |
| 1880 | 1880 | try zcu_member.initHeader(coff, zcu.main_mod.fully_qualified_name, timestamp); |
| 1881 | 1881 | |
| 1882 | assert(try zcu_member.content_ni.addOnlyHeaderChild(&coff.mf, gpa, .{ | |
| 1882 | assert(try zcu_member.content_ni.addOnlyHeaderChild(gpa, &coff.mf, .{ | |
| 1883 | 1883 | .size = @sizeOf(std.coff.Header), |
| 1884 | 1884 | .alignment = .@"4", |
| 1885 | 1885 | }) == Node.known.coff_header); |
| ... | ... | @@ -1894,13 +1894,13 @@ fn initHeaders( |
| 1894 | 1894 | // no other members then the last linker member (longnames) needs to expand |
| 1895 | 1895 | // to fill the padding at the end of the file. |
| 1896 | 1896 | while (coff.nodes.len < Node.known_count) { |
| 1897 | _ = try Node.known.header.addHeaderChildAfter(&coff.mf, gpa, .none, .{}); | |
| 1897 | _ = try Node.known.header.addHeaderChildAfter(gpa, &coff.mf, .none, .{}); | |
| 1898 | 1898 | coff.nodes.appendAssumeCapacity(.placeholder); |
| 1899 | 1899 | } |
| 1900 | 1900 | |
| 1901 | 1901 | return; |
| 1902 | 1902 | } else parent: { |
| 1903 | assert(try header_ni.addOnlyHeaderChild(&coff.mf, gpa, .{ | |
| 1903 | assert(try header_ni.addOnlyHeaderChild(gpa, &coff.mf, .{ | |
| 1904 | 1904 | .size = if (is_image) msdos_stub.len + std.coff.pe_signature.len else 0, |
| 1905 | 1905 | .alignment = .@"4", |
| 1906 | 1906 | }) == Node.known.signature); |
| ... | ... | @@ -1913,12 +1913,12 @@ fn initHeaders( |
| 1913 | 1913 | |
| 1914 | 1914 | // TODO: Not ideal to have this many placeholder nodes - use two distinct `Node.known` types? |
| 1915 | 1915 | while (true) { |
| 1916 | const placeholder_ni = try Node.known.file.addHeaderChildAfter(&coff.mf, gpa, .none, .{}); | |
| 1916 | const placeholder_ni = try Node.known.file.addHeaderChildAfter(gpa, &coff.mf, .none, .{}); | |
| 1917 | 1917 | coff.nodes.appendAssumeCapacity(.placeholder); |
| 1918 | 1918 | if (placeholder_ni == Node.known.zcu_member) break; |
| 1919 | 1919 | } |
| 1920 | 1920 | |
| 1921 | assert(try header_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(Node.known.signature), .{ | |
| 1921 | assert(try header_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(Node.known.signature), .{ | |
| 1922 | 1922 | .size = @sizeOf(std.coff.Header), |
| 1923 | 1923 | .alignment = .@"4", |
| 1924 | 1924 | }) == Node.known.coff_header); |
| ... | ... | @@ -1949,7 +1949,7 @@ fn initHeaders( |
| 1949 | 1949 | } |
| 1950 | 1950 | |
| 1951 | 1951 | const optional_header_ni = Node.known.optional_header; |
| 1952 | assert(optional_header_ni == try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(Node.known.coff_header), .{ | |
| 1952 | assert(optional_header_ni == try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(Node.known.coff_header), .{ | |
| 1953 | 1953 | .size = optional_header_size, |
| 1954 | 1954 | .alignment = .@"4", |
| 1955 | 1955 | })); |
| ... | ... | @@ -2060,7 +2060,7 @@ fn initHeaders( |
| 2060 | 2060 | } |
| 2061 | 2061 | |
| 2062 | 2062 | const data_directories_ni = Node.known.data_directories; |
| 2063 | assert(data_directories_ni == try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(optional_header_ni), .{ | |
| 2063 | assert(data_directories_ni == try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(optional_header_ni), .{ | |
| 2064 | 2064 | .size = data_directories_size, |
| 2065 | 2065 | .alignment = .@"4", |
| 2066 | 2066 | })); |
| ... | ... | @@ -2075,7 +2075,7 @@ fn initHeaders( |
| 2075 | 2075 | } |
| 2076 | 2076 | |
| 2077 | 2077 | const section_table_ni = Node.known.section_table; |
| 2078 | assert(section_table_ni == try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(data_directories_ni), .{ | |
| 2078 | assert(section_table_ni == try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(data_directories_ni), .{ | |
| 2079 | 2079 | .alignment = .@"4", |
| 2080 | 2080 | })); |
| 2081 | 2081 | coff.nodes.appendAssumeCapacity(.section_table); |
| ... | ... | @@ -2084,13 +2084,13 @@ fn initHeaders( |
| 2084 | 2084 | |
| 2085 | 2085 | if (!is_image) { |
| 2086 | 2086 | // TODO: These two nodes could be inside one movable node? |
| 2087 | coff.symbol_table.ni = try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(section_table_ni), .{ | |
| 2087 | coff.symbol_table.ni = try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(section_table_ni), .{ | |
| 2088 | 2088 | .alignment = .@"2", |
| 2089 | 2089 | .moved = true, |
| 2090 | 2090 | }); |
| 2091 | 2091 | coff.nodes.appendAssumeCapacity(.symbol_table); |
| 2092 | 2092 | |
| 2093 | coff.symbol_table.strings_ni = try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(coff.symbol_table.ni), .{ | |
| 2093 | coff.symbol_table.strings_ni = try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(coff.symbol_table.ni), .{ | |
| 2094 | 2094 | .size = @sizeOf(u32), |
| 2095 | 2095 | .resized = true, |
| 2096 | 2096 | }); |
| ... | ... | @@ -2143,7 +2143,7 @@ fn initHeaders( |
| 2143 | 2143 | coff.mf.flags.block_size, |
| 2144 | 2144 | .{ .read = true, .initialized = true }, |
| 2145 | 2145 | )).symbol(coff).node(coff); |
| 2146 | coff.import_table.ni = try import_table_parent_ni.addFloatingChild(&coff.mf, gpa, .{ | |
| 2146 | coff.import_table.ni = try import_table_parent_ni.addFloatingChild(gpa, &coff.mf, .{ | |
| 2147 | 2147 | .alignment = .@"4", |
| 2148 | 2148 | }); |
| 2149 | 2149 | coff.nodes.appendAssumeCapacity(.import_directory_table); |
| ... | ... | @@ -2154,7 +2154,7 @@ fn initHeaders( |
| 2154 | 2154 | .{ .read = true, .initialized = true }, |
| 2155 | 2155 | )).symbol(coff).node(coff); |
| 2156 | 2156 | |
| 2157 | coff.export_table.export_directory_table_ni = try coff.export_table.ni.addHeaderChildAfter(&coff.mf, gpa, coff.export_table.ni.last(&coff.mf), .{ | |
| 2157 | coff.export_table.export_directory_table_ni = try coff.export_table.ni.addHeaderChildAfter(gpa, &coff.mf, coff.export_table.ni.last(&coff.mf), .{ | |
| 2158 | 2158 | .size = @sizeOf(std.coff.ExportDirectoryTable) + file_name.len + 1, |
| 2159 | 2159 | .moved = true, |
| 2160 | 2160 | }); |
| ... | ... | @@ -2165,7 +2165,7 @@ fn initHeaders( |
| 2165 | 2165 | @memcpy(table_slice[name_index..][0..file_name.len], file_name[0..file_name.len]); |
| 2166 | 2166 | @memset(table_slice[name_index + file_name.len ..], 0); |
| 2167 | 2167 | |
| 2168 | const export_address_table_ni = try coff.export_table.ni.addFloatingChild(&coff.mf, gpa, .{ | |
| 2168 | const export_address_table_ni = try coff.export_table.ni.addFloatingChild(gpa, &coff.mf, .{ | |
| 2169 | 2169 | .alignment = .of(std.coff.ExportAddressTableEntry), |
| 2170 | 2170 | .moved = true, |
| 2171 | 2171 | }); |
| ... | ... | @@ -2181,19 +2181,19 @@ fn initHeaders( |
| 2181 | 2181 | export_address_table_sym.section_number = |
| 2182 | 2182 | coff.getNode(coff.export_table.ni).pseudo_section.symbol(coff).get(coff).section_number; |
| 2183 | 2183 | |
| 2184 | coff.export_table.name_pointer_table_ni = try coff.export_table.ni.addFloatingChild(&coff.mf, gpa, .{ | |
| 2184 | coff.export_table.name_pointer_table_ni = try coff.export_table.ni.addFloatingChild(gpa, &coff.mf, .{ | |
| 2185 | 2185 | .alignment = .of(std.coff.ExportNamePointerTableEntry), |
| 2186 | 2186 | .moved = true, |
| 2187 | 2187 | }); |
| 2188 | 2188 | coff.nodes.appendAssumeCapacity(.export_name_pointer_table); |
| 2189 | 2189 | |
| 2190 | coff.export_table.ordinal_table_ni = try coff.export_table.ni.addFloatingChild(&coff.mf, gpa, .{ | |
| 2190 | coff.export_table.ordinal_table_ni = try coff.export_table.ni.addFloatingChild(gpa, &coff.mf, .{ | |
| 2191 | 2191 | .alignment = .of(std.coff.ExportOrdinalTableEntry), |
| 2192 | 2192 | .moved = true, |
| 2193 | 2193 | }); |
| 2194 | 2194 | coff.nodes.appendAssumeCapacity(.export_ordinal_table); |
| 2195 | 2195 | |
| 2196 | coff.export_table.name_table_ni = try coff.export_table.ni.addFloatingChild(&coff.mf, gpa, .{ | |
| 2196 | coff.export_table.name_table_ni = try coff.export_table.ni.addFloatingChild(gpa, &coff.mf, .{ | |
| 2197 | 2197 | .alignment = .of(u8), |
| 2198 | 2198 | .moved = true, |
| 2199 | 2199 | }); |
| ... | ... | @@ -2286,7 +2286,7 @@ pub fn initBuiltins(coff: *Coff) !void { |
| 2286 | 2286 | const list_len_si = try coff.globalSymbol(.{ .name = list.global, .type = .data }); |
| 2287 | 2287 | const list_len_sym = list_len_si.get(coff); |
| 2288 | 2288 | list_len_sym.setExtra(.{ .size = addr_info.size }); |
| 2289 | list_len_sym.ni = .wrap(try start_sym.ni.unwrap().?.addHeaderChildAfter(&coff.mf, gpa, .none, .{ | |
| 2289 | list_len_sym.ni = .wrap(try start_sym.ni.unwrap().?.addHeaderChildAfter(gpa, &coff.mf, .none, .{ | |
| 2290 | 2290 | .size = addr_info.size, |
| 2291 | 2291 | })); |
| 2292 | 2292 | coff.nodes.appendAssumeCapacity(.{ .builtin = list_len_si }); |
| ... | ... | @@ -2307,7 +2307,7 @@ pub fn initBuiltins(coff: *Coff) !void { |
| 2307 | 2307 | const list_end_si = coff.addSymbolAssumeCapacity(); |
| 2308 | 2308 | const list_end_sym = list_end_si.get(coff); |
| 2309 | 2309 | list_end_sym.setExtra(.{ .size = addr_info.size }); |
| 2310 | list_end_sym.ni = .wrap(try end_sym.ni.unwrap().?.addHeaderChildAfter(&coff.mf, gpa, .none, .{ | |
| 2310 | list_end_sym.ni = .wrap(try end_sym.ni.unwrap().?.addHeaderChildAfter(gpa, &coff.mf, .none, .{ | |
| 2311 | 2311 | .size = addr_info.size, |
| 2312 | 2312 | })); |
| 2313 | 2313 | coff.nodes.appendAssumeCapacity(.{ .builtin = list_end_si }); |
| ... | ... | @@ -2723,7 +2723,7 @@ fn getOrPutSymbolName(coff: *Coff, name: []const u8, opt_string: ?String) !Symbo |
| 2723 | 2723 | const string_index = coff.symbol_table.strings_ni.location(&coff.mf).resolve(&coff.mf)[1]; |
| 2724 | 2724 | string_gop.value_ptr.* = @fromBackingInt(@intCast(string_index)); |
| 2725 | 2725 | |
| 2726 | try coff.symbol_table.strings_ni.resizeLeaf(&coff.mf, gpa, string_index + name.len + 1); | |
| 2726 | try coff.symbol_table.strings_ni.resizeLeaf(gpa, &coff.mf, string_index + name.len + 1); | |
| 2727 | 2727 | const slice = coff.symbol_table.strings_ni.slice(&coff.mf); |
| 2728 | 2728 | @memcpy(slice[@intCast(string_index)..][0..name.len], name); |
| 2729 | 2729 | slice[@intCast(string_index + name.len)] = 0; |
| ... | ... | @@ -2948,7 +2948,7 @@ fn addMemberAssumeCapacity(coff: *Coff, kind: std.coff.ArchiveMemberHeader.Kind, |
| 2948 | 2948 | const comp = coff.base.comp; |
| 2949 | 2949 | const gpa = comp.gpa; |
| 2950 | 2950 | |
| 2951 | const header_ni = try Node.known.file.addHeaderChildAfter(&coff.mf, gpa, Node.known.file.last(&coff.mf), .{ | |
| 2951 | const header_ni = try Node.known.file.addHeaderChildAfter(gpa, &coff.mf, Node.known.file.last(&coff.mf), .{ | |
| 2952 | 2952 | .size = @sizeOf(std.coff.ArchiveMemberHeader), |
| 2953 | 2953 | .alignment = .@"2", |
| 2954 | 2954 | .moved = true, |
| ... | ... | @@ -2960,7 +2960,7 @@ fn addMemberAssumeCapacity(coff: *Coff, kind: std.coff.ArchiveMemberHeader.Kind, |
| 2960 | 2960 | .first_linker, .second_linker, .longnames, .coff => .@"4", |
| 2961 | 2961 | else => .@"2", |
| 2962 | 2962 | }; |
| 2963 | const content_ni = try Node.known.file.addHeaderChildAfter(&coff.mf, gpa, .wrap(header_ni), .{ | |
| 2963 | const content_ni = try Node.known.file.addHeaderChildAfter(gpa, &coff.mf, .wrap(header_ni), .{ | |
| 2964 | 2964 | .alignment = content_align, |
| 2965 | 2965 | .size = content_align.forward(size), |
| 2966 | 2966 | .resized = size > 0, |
| ... | ... | @@ -2989,7 +2989,7 @@ fn addMemberAssumeCapacity(coff: *Coff, kind: std.coff.ArchiveMemberHeader.Kind, |
| 2989 | 2989 | const old_size = Node.known.second_linker_member.location(&coff.mf).resolve(&coff.mf)[1]; |
| 2990 | 2990 | const old_header_size = new_num_members * @sizeOf(u32); |
| 2991 | 2991 | const trailing_size: usize = @intCast(old_size - old_header_size); |
| 2992 | try Node.known.second_linker_member.resizeLeaf(&coff.mf, gpa, old_size + @sizeOf(u32)); | |
| 2992 | try Node.known.second_linker_member.resizeLeaf(gpa, &coff.mf, old_size + @sizeOf(u32)); | |
| 2993 | 2993 | |
| 2994 | 2994 | const slice = Node.known.second_linker_member.slice(&coff.mf); |
| 2995 | 2995 | @memmove( |
| ... | ... | @@ -3060,7 +3060,7 @@ fn ensureMemberSymbol(coff: *Coff, mi: Member.Index, name: String) !void { |
| 3060 | 3060 | { |
| 3061 | 3061 | const old_header_size: usize = @intCast(@sizeOf(u32) + @backingInt(mfli) * @sizeOf(u32)); |
| 3062 | 3062 | const new_header_size: usize = @intCast(old_header_size + @sizeOf(u32)); |
| 3063 | try Node.known.first_linker_member.resizeLeaf(&coff.mf, gpa, Alignment.@"4".forward(new_header_size + new_string_table_size)); | |
| 3063 | try Node.known.first_linker_member.resizeLeaf(gpa, &coff.mf, Alignment.@"4".forward(new_header_size + new_string_table_size)); | |
| 3064 | 3064 | |
| 3065 | 3065 | const slice = Node.known.first_linker_member.slice(&coff.mf); |
| 3066 | 3066 | @memmove(slice[new_header_size..][0..coff.lib_string_len], slice[old_header_size..][0..coff.lib_string_len]); |
| ... | ... | @@ -3074,7 +3074,7 @@ fn ensureMemberSymbol(coff: *Coff, mi: Member.Index, name: String) !void { |
| 3074 | 3074 | const num_members = coff.targetLoad(coff.secondLinkerMemberNumMembersPtr()); |
| 3075 | 3075 | const old_header_size = 2 * @sizeOf(u32) + num_members * @sizeOf(u32) + @backingInt(mfli) * @sizeOf(u16); |
| 3076 | 3076 | const new_header_size = old_header_size + @sizeOf(u16); |
| 3077 | try Node.known.second_linker_member.resizeLeaf(&coff.mf, gpa, Alignment.@"4".forward(new_header_size + new_string_table_size)); | |
| 3077 | try Node.known.second_linker_member.resizeLeaf(gpa, &coff.mf, Alignment.@"4".forward(new_header_size + new_string_table_size)); | |
| 3078 | 3078 | |
| 3079 | 3079 | const old_needs_sort = coff.pending_members.get(Member.Index.second) != null; |
| 3080 | 3080 | const needs_sort = old_needs_sort or (if (coff.lib_string_table.items.len > 0) |
| ... | ... | @@ -3181,7 +3181,7 @@ fn flushSymbolTableEntry(coff: *Coff, index: u32) !void { |
| 3181 | 3181 | const new_num_symbols = old_num_symbols + 1 + num_aux_symbols; |
| 3182 | 3182 | coff.targetStore(&coff.headerPtr().number_of_symbols, new_num_symbols); |
| 3183 | 3183 | |
| 3184 | try coff.symbol_table.ni.resizeLeaf(&coff.mf, gpa, new_num_symbols * std.coff.Symbol.sizeOf()); | |
| 3184 | try coff.symbol_table.ni.resizeLeaf(gpa, &coff.mf, new_num_symbols * std.coff.Symbol.sizeOf()); | |
| 3185 | 3185 | |
| 3186 | 3186 | sti.* = .wrap(old_num_symbols); |
| 3187 | 3187 | si.flushSymbolTableIndex(coff); |
| ... | ... | @@ -3317,7 +3317,7 @@ fn flushInputSection(coff: *Coff, isi: Node.InputSection.Index) !void { |
| 3317 | 3317 | try fr.seekTo(file_loc.offset); |
| 3318 | 3318 | var nw: MappedFile.Node.Writer = undefined; |
| 3319 | 3319 | const si = isi.symbol(coff); |
| 3320 | si.node(coff).writer(&coff.mf, gpa, &nw); | |
| 3320 | si.node(coff).writer(gpa, &coff.mf, &nw); | |
| 3321 | 3321 | defer nw.deinit(); |
| 3322 | 3322 | log.debug("flushInputSection({f}{f}, {s}, {d}, n{d})", .{ |
| 3323 | 3323 | path, |
| ... | ... | @@ -3345,12 +3345,12 @@ fn addSection(coff: *Coff, name: String, flags: std.coff.SectionHeader.Flags) !S |
| 3345 | 3345 | const section_table_len = section_index + 1; |
| 3346 | 3346 | coff.targetStore(&coff_header.number_of_sections, section_table_len); |
| 3347 | 3347 | try Node.known.section_table.resizeLeaf( |
| 3348 | &coff.mf, | |
| 3349 | 3348 | gpa, |
| 3349 | &coff.mf, | |
| 3350 | 3350 | @sizeOf(std.coff.SectionHeader) * section_table_len, |
| 3351 | 3351 | ); |
| 3352 | 3352 | |
| 3353 | const ni = try coff.sectionParent().addFloatingChild(&coff.mf, gpa, .{ | |
| 3353 | const ni = try coff.sectionParent().addFloatingChild(gpa, &coff.mf, .{ | |
| 3354 | 3354 | .alignment = coff.mf.flags.block_size, |
| 3355 | 3355 | .moved = true, |
| 3356 | 3356 | .bubbles_moved = false, |
| ... | ... | @@ -3486,7 +3486,7 @@ fn pseudoSectionMapIndex( |
| 3486 | 3486 | |
| 3487 | 3487 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 3488 | 3488 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 3489 | const ni = try parent.node(coff).addFloatingChild(&coff.mf, gpa, .{ .alignment = alignment }); | |
| 3489 | const ni = try parent.node(coff).addFloatingChild(gpa, &coff.mf, .{ .alignment = alignment }); | |
| 3490 | 3490 | const si = coff.addSymbolAssumeCapacity(); |
| 3491 | 3491 | pseudo_section_gop.value_ptr.* = si; |
| 3492 | 3492 | const sym = si.get(coff); |
| ... | ... | @@ -3560,7 +3560,7 @@ fn objectSectionMapIndex( |
| 3560 | 3560 | } |
| 3561 | 3561 | } |
| 3562 | 3562 | } |
| 3563 | const ni = try parent_ni.addHeaderChildAfter(&coff.mf, gpa, prev_oni, .{ | |
| 3563 | const ni = try parent_ni.addHeaderChildAfter(gpa, &coff.mf, prev_oni, .{ | |
| 3564 | 3564 | .alignment = alignment, |
| 3565 | 3565 | }); |
| 3566 | 3566 | const si = coff.addSymbolAssumeCapacity(); |
| ... | ... | @@ -3579,13 +3579,13 @@ fn objectSectionMapIndex( |
| 3579 | 3579 | const parent_alignment = parent_ni.alignment(&coff.mf); |
| 3580 | 3580 | if (alignment.compare(.gt, parent_alignment)) { |
| 3581 | 3581 | log.debug("realignParent({s}, {d}) {d}->{d}", .{ name.toSlice(coff), parent_ni, parent_alignment, alignment }); |
| 3582 | try parent_ni.realign(&coff.mf, gpa, alignment); | |
| 3582 | try parent_ni.realign(gpa, &coff.mf, alignment); | |
| 3583 | 3583 | } |
| 3584 | 3584 | |
| 3585 | 3585 | const old_alignment = sym.ni.unwrap().?.alignment(&coff.mf); |
| 3586 | 3586 | if (alignment.compare(.gt, old_alignment)) { |
| 3587 | 3587 | log.debug("realignObject({s}) {d}->{d}", .{ name.toSlice(coff), old_alignment, alignment }); |
| 3588 | try sym.ni.unwrap().?.realign(&coff.mf, gpa, alignment); | |
| 3588 | try sym.ni.unwrap().?.realign(gpa, &coff.mf, alignment); | |
| 3589 | 3589 | } |
| 3590 | 3590 | |
| 3591 | 3591 | try coff.verifyParentSectionAttributes( |
| ... | ... | @@ -3742,9 +3742,9 @@ fn addRelocAssumeCapacity( |
| 3742 | 3742 | coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations); |
| 3743 | 3743 | |
| 3744 | 3744 | if (section.relocation_table_ni.unwrap()) |relocation_table_ni| { |
| 3745 | try relocation_table_ni.resizeLeaf(&coff.mf, gpa, new_size); | |
| 3745 | try relocation_table_ni.resizeLeaf(gpa, &coff.mf, new_size); | |
| 3746 | 3746 | } else { |
| 3747 | section.relocation_table_ni = .wrap(try coff.sectionParent().addFloatingChild(&coff.mf, gpa, .{ | |
| 3747 | section.relocation_table_ni = .wrap(try coff.sectionParent().addFloatingChild(gpa, &coff.mf, .{ | |
| 3748 | 3748 | .size = new_size, |
| 3749 | 3749 | .alignment = .@"2", |
| 3750 | 3750 | .moved = true, |
| ... | ... | @@ -4094,7 +4094,7 @@ fn loadObject( |
| 4094 | 4094 | { |
| 4095 | 4095 | // TODO: This should be deferred to an idle task (but resize it here!) |
| 4096 | 4096 | var nw: MappedFile.Node.Writer = undefined; |
| 4097 | member.content_ni.writer(&coff.mf, gpa, &nw); | |
| 4097 | member.content_ni.writer(gpa, &coff.mf, &nw); | |
| 4098 | 4098 | defer nw.deinit(); |
| 4099 | 4099 | |
| 4100 | 4100 | try fr.seekTo(fl.offset); |
| ... | ... | @@ -4653,7 +4653,7 @@ fn loadObject( |
| 4653 | 4653 | if (section.parent_si == .null) continue; |
| 4654 | 4654 | |
| 4655 | 4655 | const alignment: Alignment = .fromByteUnits(section.header.flags.ALIGN.toByteUnits() orelse 1); |
| 4656 | const ni = try section.parent_si.node(coff).addFloatingChild(&coff.mf, gpa, .{ | |
| 4656 | const ni = try section.parent_si.node(coff).addFloatingChild(gpa, &coff.mf, .{ | |
| 4657 | 4657 | .size = alignment.forward(section.header.size_of_raw_data), |
| 4658 | 4658 | .alignment = alignment, |
| 4659 | 4659 | .moved = true, |
| ... | ... | @@ -5447,7 +5447,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 5447 | 5447 | const sec_si = try coff.navSection(zcu, nav.resolved.?); |
| 5448 | 5448 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 5449 | 5449 | if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1); |
| 5450 | const ni = try sec_si.node(coff).addFloatingChild(&coff.mf, gpa, .{ | |
| 5450 | const ni = try sec_si.node(coff).addFloatingChild(gpa, &coff.mf, .{ | |
| 5451 | 5451 | .alignment = .fromIp(zcu.navAlignment(nav_index)), |
| 5452 | 5452 | .moved = true, |
| 5453 | 5453 | }); |
| ... | ... | @@ -5469,7 +5469,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 5469 | 5469 | |
| 5470 | 5470 | { |
| 5471 | 5471 | var nw: MappedFile.Node.Writer = undefined; |
| 5472 | ni.writer(&coff.mf, gpa, &nw); | |
| 5472 | ni.writer(gpa, &coff.mf, &nw); | |
| 5473 | 5473 | defer nw.deinit(); |
| 5474 | 5474 | codegen.generateSymbol( |
| 5475 | 5475 | &coff.base, |
| ... | ... | @@ -5486,7 +5486,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 5486 | 5486 | } |
| 5487 | 5487 | |
| 5488 | 5488 | if (nav.resolved.?.@"linksection".unwrap()) |_| { |
| 5489 | try ni.resizeLeaf(&coff.mf, gpa, si.get(coff).extra.size); | |
| 5489 | try ni.resizeLeaf(gpa, &coff.mf, si.get(coff).extra.size); | |
| 5490 | 5490 | } |
| 5491 | 5491 | |
| 5492 | 5492 | // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs. |
| ... | ... | @@ -5596,7 +5596,7 @@ fn updateFuncInner( |
| 5596 | 5596 | if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1); |
| 5597 | 5597 | const mod = zcu.navFileScope(func.owner_nav).mod.?; |
| 5598 | 5598 | const target = &mod.resolved_target.result; |
| 5599 | const ni = try sec_si.node(coff).addFloatingChild(&coff.mf, gpa, .{ | |
| 5599 | const ni = try sec_si.node(coff).addFloatingChild(gpa, &coff.mf, .{ | |
| 5600 | 5600 | .alignment = switch (nav.resolved.?.@"align") { |
| 5601 | 5601 | .none => switch (mod.optimize_mode) { |
| 5602 | 5602 | .debug, |
| ... | ... | @@ -5625,7 +5625,7 @@ fn updateFuncInner( |
| 5625 | 5625 | }; |
| 5626 | 5626 | |
| 5627 | 5627 | var nw: MappedFile.Node.Writer = undefined; |
| 5628 | ni.writer(&coff.mf, gpa, &nw); | |
| 5628 | ni.writer(gpa, &coff.mf, &nw); | |
| 5629 | 5629 | defer nw.deinit(); |
| 5630 | 5630 | codegen.emitFunction( |
| 5631 | 5631 | &coff.base, |
| ... | ... | @@ -5904,8 +5904,8 @@ pub fn flush( |
| 5904 | 5904 | |
| 5905 | 5905 | const number_of_symbols = coff.targetLoad(&coff.headerPtr().number_of_symbols); |
| 5906 | 5906 | coff.symbol_table.ni.resizeLeaf( |
| 5907 | &coff.mf, | |
| 5908 | 5907 | comp.gpa, |
| 5908 | &coff.mf, | |
| 5909 | 5909 | number_of_symbols * std.coff.Symbol.sizeOf(), |
| 5910 | 5910 | ) catch |err| switch (err) { |
| 5911 | 5911 | else => |e| return e, |
| ... | ... | @@ -6072,17 +6072,18 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 6072 | 6072 | }; |
| 6073 | 6073 | break :task; |
| 6074 | 6074 | } |
| 6075 | while (coff.mf.updates.pop()) |ni| { | |
| 6075 | while (coff.mf.updates.pop()) |ni| : (coff.mf.update_prog_node.completeOne()) { | |
| 6076 | if (ni.pendingDelete(&coff.mf)) continue; | |
| 6076 | 6077 | const clean_moved = ni.cleanMoved(&coff.mf); |
| 6077 | 6078 | const clean_resized = ni.cleanResized(&coff.mf); |
| 6078 | if (clean_moved or clean_resized) { | |
| 6079 | const sub_prog_node = | |
| 6080 | coff.idleProgNode(tid, coff.mf.update_prog_node, coff.getNode(ni)); | |
| 6081 | defer sub_prog_node.end(); | |
| 6082 | if (clean_moved) try coff.flushMoved(ni); | |
| 6083 | if (clean_resized) try coff.flushResized(ni); | |
| 6084 | break :task; | |
| 6085 | } else coff.mf.update_prog_node.completeOne(); | |
| 6079 | const clean_next_moved = ni.cleanNextMoved(&coff.mf); | |
| 6080 | if (!clean_moved and !clean_resized and !clean_next_moved) continue; | |
| 6081 | const sub_prog_node = | |
| 6082 | coff.idleProgNode(tid, coff.mf.update_prog_node, coff.getNode(ni)); | |
| 6083 | defer sub_prog_node.end(); | |
| 6084 | if (clean_moved) try coff.flushMoved(ni); | |
| 6085 | if (clean_resized) try coff.flushResized(ni); | |
| 6086 | break :task; | |
| 6086 | 6087 | } |
| 6087 | 6088 | while (coff.pending_members.pop()) |pending_mi| { |
| 6088 | 6089 | const sub_prog_node = coff.idleProgNode( |
| ... | ... | @@ -6210,7 +6211,7 @@ fn genUav( |
| 6210 | 6211 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 6211 | 6212 | if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1); |
| 6212 | 6213 | const sym = si.get(coff); |
| 6213 | const ni = try sec_si.node(coff).addFloatingChild(&coff.mf, gpa, .{ | |
| 6214 | const ni = try sec_si.node(coff).addFloatingChild(gpa, &coff.mf, .{ | |
| 6214 | 6215 | .alignment = .fromIp(uav_align), |
| 6215 | 6216 | .moved = true, |
| 6216 | 6217 | }); |
| ... | ... | @@ -6239,7 +6240,7 @@ fn genUav( |
| 6239 | 6240 | }; |
| 6240 | 6241 | |
| 6241 | 6242 | var nw: MappedFile.Node.Writer = undefined; |
| 6242 | ni.writer(&coff.mf, gpa, &nw); | |
| 6243 | ni.writer(gpa, &coff.mf, &nw); | |
| 6243 | 6244 | defer nw.deinit(); |
| 6244 | 6245 | codegen.generateSymbol( |
| 6245 | 6246 | &coff.base, |
| ... | ... | @@ -6503,19 +6504,19 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6503 | 6504 | if (!gop.found_existing) { |
| 6504 | 6505 | errdefer _ = coff.import_table.entries.pop(); |
| 6505 | 6506 | try coff.import_table.ni.resizeLeaf( |
| 6506 | &coff.mf, | |
| 6507 | 6507 | gpa, |
| 6508 | &coff.mf, | |
| 6508 | 6509 | @sizeOf(std.coff.ImportDirectoryEntry) * (gop.index + 2), |
| 6509 | 6510 | ); |
| 6510 | 6511 | const import_hint_name_table_len = |
| 6511 | 6512 | import_hint_name_align.forward(lib_name.len + ".dll".len + 1); |
| 6512 | 6513 | const idata_section_ni = coff.import_table.ni.parent(&coff.mf).unwrap().?; |
| 6513 | const import_lookup_table_ni = try idata_section_ni.addFloatingChild(&coff.mf, gpa, .{ | |
| 6514 | const import_lookup_table_ni = try idata_section_ni.addFloatingChild(gpa, &coff.mf, .{ | |
| 6514 | 6515 | .size = addr_info.size * 2, |
| 6515 | 6516 | .alignment = addr_info.alignment, |
| 6516 | 6517 | .moved = true, |
| 6517 | 6518 | }); |
| 6518 | const import_address_table_ni = try idata_section_ni.addFloatingChild(&coff.mf, gpa, .{ | |
| 6519 | const import_address_table_ni = try idata_section_ni.addFloatingChild(gpa, &coff.mf, .{ | |
| 6519 | 6520 | .size = addr_info.size * 2, |
| 6520 | 6521 | .alignment = addr_info.alignment, |
| 6521 | 6522 | .moved = true, |
| ... | ... | @@ -6529,7 +6530,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6529 | 6530 | import_address_table_sym.section_number = |
| 6530 | 6531 | coff.getNode(idata_section_ni).object_section.symbol(coff).get(coff).section_number; |
| 6531 | 6532 | } |
| 6532 | const import_hint_name_table_ni = try idata_section_ni.addFloatingChild(&coff.mf, gpa, .{ | |
| 6533 | const import_hint_name_table_ni = try idata_section_ni.addFloatingChild(gpa, &coff.mf, .{ | |
| 6533 | 6534 | .size = import_hint_name_table_len, |
| 6534 | 6535 | .alignment = import_hint_name_align, |
| 6535 | 6536 | .moved = true, |
| ... | ... | @@ -6585,9 +6586,9 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6585 | 6586 | gop.value_ptr.len = import_symbol_index + 1; |
| 6586 | 6587 | const new_symbol_table_size = addr_info.size * (import_symbol_index + 2); |
| 6587 | 6588 | |
| 6588 | try gop.value_ptr.import_lookup_table_ni.resizeLeaf(&coff.mf, gpa, new_symbol_table_size); | |
| 6589 | try gop.value_ptr.import_lookup_table_ni.resizeLeaf(gpa, &coff.mf, new_symbol_table_size); | |
| 6589 | 6590 | const import_address_table_ni = gop.value_ptr.import_address_table_si.node(coff); |
| 6590 | try import_address_table_ni.resizeLeaf(&coff.mf, gpa, new_symbol_table_size); | |
| 6591 | try import_address_table_ni.resizeLeaf(gpa, &coff.mf, new_symbol_table_size); | |
| 6591 | 6592 | |
| 6592 | 6593 | const opt_imp_name = import.name.toSlice(coff); |
| 6593 | 6594 | const opt_import_hint_name_index = if (opt_imp_name) |imp_name| blk: { |
| ... | ... | @@ -6595,7 +6596,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6595 | 6596 | gop.value_ptr.hint_name_len = @intCast( |
| 6596 | 6597 | import_hint_name_align.forward(import_hint_name_index + 2 + imp_name.len + 1), |
| 6597 | 6598 | ); |
| 6598 | try gop.value_ptr.import_hint_name_table_ni.resizeLeaf(&coff.mf, gpa, gop.value_ptr.hint_name_len); | |
| 6599 | try gop.value_ptr.import_hint_name_table_ni.resizeLeaf(gpa, &coff.mf, gop.value_ptr.hint_name_len); | |
| 6599 | 6600 | break :blk import_hint_name_index; |
| 6600 | 6601 | } else null; |
| 6601 | 6602 | |
| ... | ... | @@ -6670,7 +6671,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6670 | 6671 | else => |tag| @panic(@tagName(tag)), |
| 6671 | 6672 | .AMD64 => { |
| 6672 | 6673 | const init = [_]u8{ 0xff, 0x25, 0x00, 0x00, 0x00, 0x00 }; |
| 6673 | const ni = try parent_sym.ni.unwrap().?.addFloatingChild(&coff.mf, gpa, .{ | |
| 6674 | const ni = try parent_sym.ni.unwrap().?.addFloatingChild(gpa, &coff.mf, .{ | |
| 6674 | 6675 | .alignment = alignment, |
| 6675 | 6676 | .size = alignment.forward(init.len), |
| 6676 | 6677 | }); |
| ... | ... | @@ -6823,7 +6824,7 @@ fn genLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 6823 | 6824 | .code => .text, |
| 6824 | 6825 | .const_data => .rdata, |
| 6825 | 6826 | }; |
| 6826 | const ni = try sec_si.node(coff).addFloatingChild(&coff.mf, gpa, .{ .moved = true }); | |
| 6827 | const ni = try sec_si.node(coff).addFloatingChild(gpa, &coff.mf, .{ .moved = true }); | |
| 6827 | 6828 | coff.nodes.appendAssumeCapacity(switch (lazy.kind) { |
| 6828 | 6829 | .code => .{ .lazy_code = @fromBackingInt(@intCast(lmr.index)) }, |
| 6829 | 6830 | .const_data => .{ .lazy_const_data = @fromBackingInt(@intCast(lmr.index)) }, |
| ... | ... | @@ -6843,7 +6844,7 @@ fn genLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 6843 | 6844 | |
| 6844 | 6845 | var required_alignment: InternPool.Alignment = .none; |
| 6845 | 6846 | var nw: MappedFile.Node.Writer = undefined; |
| 6846 | ni.writer(&coff.mf, gpa, &nw); | |
| 6847 | ni.writer(gpa, &coff.mf, &nw); | |
| 6847 | 6848 | defer nw.deinit(); |
| 6848 | 6849 | codegen.generateLazySymbol( |
| 6849 | 6850 | &coff.base, |
| ... | ... | @@ -7479,7 +7480,7 @@ fn updateExportInner( |
| 7479 | 7480 | if (new_name_table_size > std.math.maxInt(@FieldType(ExportTable.Entry, "name_index"))) |
| 7480 | 7481 | return coff.base.comp.link_diags.fail("exports name table limit reached", .{}); |
| 7481 | 7482 | |
| 7482 | try coff.export_table.name_table_ni.resizeLeaf(&coff.mf, gpa, new_name_table_size); | |
| 7483 | try coff.export_table.name_table_ni.resizeLeaf(gpa, &coff.mf, new_name_table_size); | |
| 7483 | 7484 | |
| 7484 | 7485 | const name_table_slice = coff.export_table.name_table_ni.slice(&coff.mf); |
| 7485 | 7486 | @memcpy(name_table_slice[name_index..][0 .. name.len + 1], name[0 .. name.len + 1]); |
| ... | ... | @@ -7503,20 +7504,20 @@ fn updateExportInner( |
| 7503 | 7504 | // TODO: These should all be resized ahead of time to fit all exports |
| 7504 | 7505 | // after https://github.com/ziglang/zig/issues/23616 |
| 7505 | 7506 | try coff.export_table.export_address_table_si.node(coff).resizeLeaf( |
| 7506 | &coff.mf, | |
| 7507 | 7507 | gpa, |
| 7508 | &coff.mf, | |
| 7508 | 7509 | export_count * @sizeOf(std.coff.ExportAddressTableEntry), |
| 7509 | 7510 | ); |
| 7510 | 7511 | |
| 7511 | 7512 | try coff.export_table.name_pointer_table_ni.resizeLeaf( |
| 7512 | &coff.mf, | |
| 7513 | 7513 | gpa, |
| 7514 | &coff.mf, | |
| 7514 | 7515 | export_count * @sizeOf(std.coff.ExportNamePointerTableEntry), |
| 7515 | 7516 | ); |
| 7516 | 7517 | |
| 7517 | 7518 | try coff.export_table.ordinal_table_ni.resizeLeaf( |
| 7518 | &coff.mf, | |
| 7519 | 7519 | gpa, |
| 7520 | &coff.mf, | |
| 7520 | 7521 | export_count * @sizeOf(std.coff.ExportOrdinalTableEntry), |
| 7521 | 7522 | ); |
| 7522 | 7523 |
src/link/Dwarf2.zig+73-43| ... | ... | @@ -8,7 +8,7 @@ units: std.array_hash_map.Auto(*Module, Unit), |
| 8 | 8 | /// Indices are `link.ConstPool.Index`. |
| 9 | 9 | values: std.ArrayList(Value), |
| 10 | 10 | globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global), |
| 11 | funcs: std.array_hash_map.Auto(InternPool.Nav.Index, Func), | |
| 11 | funcs: std.array_hash_map.Auto(InternPool.TrackedInst.Index, Func), | |
| 12 | 12 | |
| 13 | 13 | debug_abbrev: Abbrev, |
| 14 | 14 | frame: Frame, |
| ... | ... | @@ -123,6 +123,7 @@ pub const Global = struct { |
| 123 | 123 | }; |
| 124 | 124 | |
| 125 | 125 | pub const Func = struct { |
| 126 | owner_nav: InternPool.Nav.Index, | |
| 126 | 127 | fde_ni: MappedFile.Node.Index.Optional, |
| 127 | 128 | debug_info_ni: MappedFile.Node.Index.Optional, |
| 128 | 129 | debug_line_ni: MappedFile.Node.Index.Optional, |
| ... | ... | @@ -130,7 +131,7 @@ pub const Func = struct { |
| 130 | 131 | pub const Index = enum(u32) { |
| 131 | 132 | _, |
| 132 | 133 | |
| 133 | pub fn nav(fi: Func.Index, dwarf: *Dwarf) InternPool.Nav.Index { | |
| 134 | pub fn srcInst(fi: Func.Index, dwarf: *Dwarf) InternPool.TrackedInst.Index { | |
| 134 | 135 | return dwarf.funcs.keys()[@backingInt(fi)]; |
| 135 | 136 | } |
| 136 | 137 | |
| ... | ... | @@ -195,7 +196,7 @@ pub const Str = struct { |
| 195 | 196 | ); |
| 196 | 197 | if (!gop.found_existing) { |
| 197 | 198 | gop.key_ptr.* = s.offset; |
| 198 | try ni.ensureMinimumSize(mf, gpa, s.offset + str.len + 1); | |
| 199 | try ni.ensureMinimumSize(gpa, mf, s.offset + str.len + 1); | |
| 199 | 200 | const slice_mut = ni.slice(mf); |
| 200 | 201 | @memcpy(slice_mut[s.offset..][0..str.len], str); |
| 201 | 202 | s.offset += str.len; |
| ... | ... | @@ -635,9 +636,15 @@ pub const WipNav = struct { |
| 635 | 636 | const dwarf = debug.wip_nav.dwarf; |
| 636 | 637 | const zcu = debug.pt.zcu; |
| 637 | 638 | const ip = &zcu.intern_pool; |
| 638 | const nav = ip.getNav(zcu.funcInfo(debug.wip_nav.func).owner_nav); | |
| 639 | const func = zcu.funcInfo(debug.wip_nav.func); | |
| 640 | const inst_info = ip.getNav(func.owner_nav).srcInst(ip).resolveFull(ip).?; | |
| 641 | const decl = zcu.fileByIndex(inst_info.file).zir.?.getDeclaration(inst_info.inst); | |
| 642 | const nav = ip.getNav(func.owner_nav); | |
| 639 | 643 | const diw = &debug.info_writer.interface; |
| 640 | 644 | try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func)); |
| 645 | try diw.writeInt(u32, decl.src_line + 1, dwarf.endian); | |
| 646 | try diw.writeUleb128(decl.src_column + 1); | |
| 647 | try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private); | |
| 641 | 648 | try debug.strp(nav.name.toSlice(ip)); |
| 642 | 649 | try debug.strp(nav.fqn.toSlice(ip)); |
| 643 | 650 | try dwarf.symbolAddress(&debug.info_writer, debug.wip_nav.func_si, 0); |
| ... | ... | @@ -657,9 +664,8 @@ pub const WipNav = struct { |
| 657 | 664 | const zcu = debug.pt.zcu; |
| 658 | 665 | const ip = &zcu.intern_pool; |
| 659 | 666 | const func = zcu.funcInfo(debug.wip_nav.func); |
| 660 | const zfi = zcu.navFileScopeIndex(func.owner_nav); | |
| 661 | const zf = zcu.fileByIndex(zfi); | |
| 662 | 667 | const inst_info = ip.getNav(func.owner_nav).srcInst(ip).resolveFull(ip).?; |
| 668 | const zf = zcu.fileByIndex(inst_info.file); | |
| 663 | 669 | const decl = zf.zir.?.getDeclaration(inst_info.inst); |
| 664 | 670 | const dlw = &debug.line_writer.interface; |
| 665 | 671 | try dlw.writeByte(DW.LNS.extended_op); |
| ... | ... | @@ -678,7 +684,7 @@ pub const WipNav = struct { |
| 678 | 684 | try dwarf.symbolAddress(&debug.line_writer, debug.wip_nav.func_si, 0); |
| 679 | 685 | |
| 680 | 686 | const unit = dwarf.getUnit(zf.mod.?); |
| 681 | _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, zfi); | |
| 687 | _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, inst_info.file); | |
| 682 | 688 | try dlw.writeByte(DW.LNS.set_file); |
| 683 | 689 | try dlw.writeUleb128(@backingInt(fi)); |
| 684 | 690 | |
| ... | ... | @@ -928,7 +934,7 @@ pub const WipNav = struct { |
| 928 | 934 | } |
| 929 | 935 | fn leaveBlockInner(debug: *Debug, code_off: usize) link.EmitError!void { |
| 930 | 936 | const dwarf = debug.wip_nav.dwarf; |
| 931 | const block_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.block)); | |
| 937 | const block_bytes = comptime uleb128Size(@backingInt(AbbrevCode.block)); | |
| 932 | 938 | const block = debug.blocks.pop().?; |
| 933 | 939 | if (debug.any_children) |
| 934 | 940 | try debug.info_writer.interface.writeUleb128(@backingInt(AbbrevCode.null)) |
| ... | ... | @@ -1000,7 +1006,7 @@ pub const WipNav = struct { |
| 1000 | 1006 | code_off: usize, |
| 1001 | 1007 | ) link.EmitError!void { |
| 1002 | 1008 | const dwarf = debug.wip_nav.dwarf; |
| 1003 | const inlined_func_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.inlined_func)); | |
| 1009 | const inlined_func_bytes = comptime uleb128Size(@backingInt(AbbrevCode.inlined_func)); | |
| 1004 | 1010 | const block = debug.blocks.pop().?; |
| 1005 | 1011 | const diw = &debug.info_writer.interface; |
| 1006 | 1012 | if (debug.any_children) |
| ... | ... | @@ -1029,14 +1035,14 @@ pub const WipNav = struct { |
| 1029 | 1035 | } |
| 1030 | 1036 | fn setInlineFuncInner(debug: *Debug, func: InternPool.Index) link.EmitError!void { |
| 1031 | 1037 | const zcu = debug.pt.zcu; |
| 1038 | const ip = &zcu.intern_pool; | |
| 1032 | 1039 | const dwarf = debug.wip_nav.dwarf; |
| 1033 | 1040 | if (debug.wip_nav.func == func) return; |
| 1034 | 1041 | |
| 1035 | const new_func_info = zcu.funcInfo(func); | |
| 1036 | ||
| 1042 | const new_owner_nav = zcu.funcInfo(func).owner_nav; | |
| 1037 | 1043 | const dlw = &debug.line_writer.interface; |
| 1038 | 1044 | if (zcu.comp.config.incremental) { |
| 1039 | const new_func = try dwarf.getFunc(new_func_info.owner_nav); | |
| 1045 | const new_func = try dwarf.getFunc(new_owner_nav); | |
| 1040 | 1046 | try dlw.writeByte(DW.LNS.extended_op); |
| 1041 | 1047 | try dlw.writeUleb128(1 + dwarf.sectionOffsetSize()); |
| 1042 | 1048 | try dlw.writeByte(DW.LNE.ZIG_set_decl); |
| ... | ... | @@ -1048,19 +1054,22 @@ pub const WipNav = struct { |
| 1048 | 1054 | return; |
| 1049 | 1055 | } |
| 1050 | 1056 | |
| 1051 | const old_func_info = zcu.funcInfo(debug.wip_nav.func); | |
| 1052 | const old_zfi = zcu.navFileScopeIndex(old_func_info.owner_nav); | |
| 1053 | const new_zfi = zcu.navFileScopeIndex(new_func_info.owner_nav); | |
| 1054 | if (old_zfi != new_zfi) { | |
| 1055 | const new_ui = dwarf.getUnit(zcu.fileByIndex(new_zfi).mod.?); | |
| 1056 | _, const new_fi = try debug.wip_nav.unit.get(dwarf).getFile(zcu.gpa, new_ui, new_zfi); | |
| 1057 | const old_owner_nav = zcu.funcInfo(debug.wip_nav.func).owner_nav; | |
| 1058 | const old_inst_info = ip.getNav(old_owner_nav).srcInst(ip).resolveFull(ip).?; | |
| 1059 | const old_file = zcu.fileByIndex(old_inst_info.file); | |
| 1060 | const new_inst_info = ip.getNav(new_owner_nav).srcInst(ip).resolveFull(ip).?; | |
| 1061 | const new_file = zcu.fileByIndex(new_inst_info.file); | |
| 1062 | if (old_inst_info.file != new_inst_info.file) { | |
| 1063 | const new_ui = dwarf.getUnit(new_file.mod.?); | |
| 1064 | _, const new_fi = | |
| 1065 | try debug.wip_nav.unit.get(dwarf).getFile(zcu.gpa, new_ui, new_inst_info.file); | |
| 1057 | 1066 | |
| 1058 | 1067 | try dlw.writeByte(DW.LNS.set_file); |
| 1059 | 1068 | try dlw.writeUleb128(@backingInt(new_fi)); |
| 1060 | 1069 | } |
| 1061 | 1070 | |
| 1062 | const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav); | |
| 1063 | const new_src_line: i33 = zcu.navSrcLine(new_func_info.owner_nav); | |
| 1071 | const old_src_line: i33 = old_file.zir.?.getDeclaration(old_inst_info.inst).src_line; | |
| 1072 | const new_src_line: i33 = new_file.zir.?.getDeclaration(new_inst_info.inst).src_line; | |
| 1064 | 1073 | if (new_src_line != old_src_line) { |
| 1065 | 1074 | try dlw.writeByte(DW.LNS.advance_line); |
| 1066 | 1075 | try dlw.writeSleb128(new_src_line - old_src_line); |
| ... | ... | @@ -1435,10 +1444,12 @@ pub fn deinit(dwarf: *Dwarf) void { |
| 1435 | 1444 | } |
| 1436 | 1445 | |
| 1437 | 1446 | pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void { |
| 1438 | try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count()); | |
| 1447 | try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count() - dwarf.units.count()); | |
| 1439 | 1448 | for (zcu.module_roots.keys(), zcu.module_roots.values()) |mod, root| if (root.unwrap()) |root_zfi| { |
| 1449 | if (!zcu.alive_files.contains(root_zfi)) continue; | |
| 1450 | assert(zcu.fileByIndex(root_zfi).mod != null); | |
| 1440 | 1451 | const unit_gop = dwarf.units.getOrPutAssumeCapacity(mod); |
| 1441 | assert(!unit_gop.found_existing); | |
| 1452 | if (unit_gop.found_existing) continue; | |
| 1442 | 1453 | unit_gop.value_ptr.* = .{ |
| 1443 | 1454 | .dirs = .empty, |
| 1444 | 1455 | .files = .empty, |
| ... | ... | @@ -1468,8 +1479,12 @@ pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index { |
| 1468 | 1479 | pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.Index { |
| 1469 | 1480 | const comp = dwarf.lf.comp; |
| 1470 | 1481 | const gpa = comp.gpa; |
| 1471 | const func_gop = try dwarf.funcs.getOrPut(gpa, owner_nav); | |
| 1482 | const zcu = comp.zcu.?; | |
| 1483 | const ip = &zcu.intern_pool; | |
| 1484 | const src_inst = ip.getNav(owner_nav).srcInst(ip); | |
| 1485 | const func_gop = try dwarf.funcs.getOrPut(gpa, src_inst); | |
| 1472 | 1486 | if (!func_gop.found_existing) func_gop.value_ptr.* = .{ |
| 1487 | .owner_nav = owner_nav, | |
| 1473 | 1488 | .fde_ni = .none, |
| 1474 | 1489 | .debug_info_ni = .none, |
| 1475 | 1490 | .debug_line_ni = .none, |
| ... | ... | @@ -1479,17 +1494,18 @@ pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.I |
| 1479 | 1494 | const elf = dwarf.lf.cast(.elf2).?; |
| 1480 | 1495 | try elf.nodes.ensureUnusedCapacity(gpa, 1); |
| 1481 | 1496 | try elf.dwarf_funcs.ensureUnusedCapacity(gpa, 1); |
| 1482 | const unit = dwarf.getUnit(comp.zcu.?.navFileScope(owner_nav).mod.?).get(dwarf); | |
| 1483 | func_gop.value_ptr.debug_info_ni = | |
| 1484 | .wrap(unit.debug_info_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{ | |
| 1497 | const unit = dwarf.getUnit(zcu.fileByIndex(src_inst.resolveFile(ip)).mod.?).get(dwarf); | |
| 1498 | func_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity( | |
| 1499 | unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{ | |
| 1485 | 1500 | .enable_next_moved = true, |
| 1486 | 1501 | }) catch |err| switch (err) { |
| 1487 | 1502 | else => |e| return e, |
| 1488 | 1503 | error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{ |
| 1489 | 1504 | elf.mf.io_err.?, |
| 1490 | 1505 | }), |
| 1491 | }); | |
| 1492 | elf.nodes.appendAssumeCapacity(.{ .func_debug_info = fi }); | |
| 1506 | }, | |
| 1507 | .{ .func_debug_info = fi }, | |
| 1508 | )); | |
| 1493 | 1509 | elf.dwarf_funcs.addOneAssumeCapacity().* = .{ |
| 1494 | 1510 | .frame_fde_first_symbol_reloc = .none, |
| 1495 | 1511 | .frame_fde_first_node_reloc = .none, |
| ... | ... | @@ -1503,7 +1519,9 @@ pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.I |
| 1503 | 1519 | return fi; |
| 1504 | 1520 | } |
| 1505 | 1521 | pub fn getFuncIfExists(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) ?Func.Index { |
| 1506 | return @fromBackingInt(@intCast(dwarf.funcs.getIndex(owner_nav) orelse return null)); | |
| 1522 | const ip = &dwarf.lf.comp.zcu.?.intern_pool; | |
| 1523 | return @fromBackingInt(@intCast(dwarf.funcs.getIndex(ip.getNav(owner_nav).srcInst(ip)) orelse | |
| 1524 | return null)); | |
| 1507 | 1525 | } |
| 1508 | 1526 | |
| 1509 | 1527 | pub fn unitLengthSize(dwarf: *Dwarf) usize { |
| ... | ... | @@ -1797,20 +1815,20 @@ pub fn genDebugLineHeader( |
| 1797 | 1815 | try dlhw.writeUleb128(DW.FORM.line_strp); |
| 1798 | 1816 | try dlhw.writeUleb128(unit.files.count()); |
| 1799 | 1817 | for (unit.files.keys()) |zfi| { |
| 1800 | const zcu_file = zcu.fileByIndex(zfi); | |
| 1801 | try dwarf.strp(&dwarf.debug_line_str, dlh_nw, zcu_file.sub_file_path); | |
| 1818 | const zf = zcu.fileByIndex(zfi); | |
| 1819 | try dwarf.strp(&dwarf.debug_line_str, dlh_nw, zf.sub_file_path); | |
| 1802 | 1820 | switch (directory_index_form) { |
| 1803 | 1821 | else => unreachable, |
| 1804 | 1822 | .data1 => try dlhw.writeByte(0), |
| 1805 | 1823 | .data2 => try dlhw.writeInt(u16, 0, dwarf.endian), |
| 1806 | 1824 | .udata => try dlhw.writeUleb128(0), |
| 1807 | 1825 | } |
| 1808 | try dlhw.writeInt(i64, @truncate(zcu_file.stat.mtime.nanoseconds), dwarf.endian); | |
| 1809 | try dlhw.writeInt(u64, zcu_file.stat.size, dwarf.endian); | |
| 1826 | try dlhw.writeInt(i64, @truncate(zf.stat.mtime.nanoseconds), dwarf.endian); | |
| 1827 | try dlhw.writeInt(u64, zf.stat.size, dwarf.endian); | |
| 1810 | 1828 | try dwarf.strp( |
| 1811 | 1829 | &dwarf.debug_line_str, |
| 1812 | 1830 | dlh_nw, |
| 1813 | if (zcu_file.is_builtin) zcu_file.source.? else "", | |
| 1831 | if (zf.is_builtin) zf.source.? else "", | |
| 1814 | 1832 | ); |
| 1815 | 1833 | } |
| 1816 | 1834 | switch (dwarf.format) { |
| ... | ... | @@ -1892,6 +1910,18 @@ pub fn genDebugRnglists( |
| 1892 | 1910 | try drw.writeByte(DW.RLE.end_of_list); |
| 1893 | 1911 | } |
| 1894 | 1912 | |
| 1913 | pub fn updateLineNumber( | |
| 1914 | dwarf: *Dwarf, | |
| 1915 | zcu: *Zcu, | |
| 1916 | src_inst: InternPool.TrackedInst.Index, | |
| 1917 | debug_info: []u8, | |
| 1918 | ) void { | |
| 1919 | const inst_info = src_inst.resolveFull(&zcu.intern_pool).?; | |
| 1920 | assert(inst_info.inst != .main_struct_inst); | |
| 1921 | const src_line = zcu.fileByIndex(inst_info.file).zir.?.getDeclaration(inst_info.inst).src_line; | |
| 1922 | std.mem.writeInt(u32, debug_info[AbbrevCode.decl_bytes..][0..4], src_line + 1, dwarf.endian); | |
| 1923 | } | |
| 1924 | ||
| 1895 | 1925 | fn refAbbrevCodeIfExists( |
| 1896 | 1926 | dwarf: *Dwarf, |
| 1897 | 1927 | abbrev_code: AbbrevCode, |
| ... | ... | @@ -1911,7 +1941,7 @@ fn refAbbrevCode( |
| 1911 | 1941 | const elf = dwarf.lf.cast(.elf2).?; |
| 1912 | 1942 | const comp = elf.base.comp; |
| 1913 | 1943 | var nw: MappedFile.Node.Writer = undefined; |
| 1914 | dwarf.debug_abbrev.ni.unwrap().?.writer(&elf.mf, comp.gpa, &nw); | |
| 1944 | dwarf.debug_abbrev.ni.unwrap().?.writer(comp.gpa, &elf.mf, &nw); | |
| 1915 | 1945 | defer nw.deinit(); |
| 1916 | 1946 | const abbrev = AbbrevCode.abbrevs.get(abbrev_code); |
| 1917 | 1947 | const daw = &nw.interface; |
| ... | ... | @@ -2133,11 +2163,11 @@ pub const AbbrevCode = enum { |
| 2133 | 2163 | comptime_value_elem_runtime_bits, |
| 2134 | 2164 | comptime_value_elem_comptime_state, |
| 2135 | 2165 | |
| 2136 | const decl_bytes = uleb128Bytes(@backingInt(AbbrevCode.decl_instance_extern_func)); | |
| 2166 | const decl_bytes = uleb128Size(@backingInt(AbbrevCode.decl_instance_extern_func)); | |
| 2137 | 2167 | comptime { |
| 2138 | assert(uleb128Bytes(@backingInt(AbbrevCode.pad_1)) == 1); | |
| 2139 | assert(uleb128Bytes(@backingInt(AbbrevCode.pad_n)) == 1); | |
| 2140 | assert(uleb128Bytes(@backingInt(AbbrevCode.decl_alias)) == decl_bytes); | |
| 2168 | assert(uleb128Size(@backingInt(AbbrevCode.pad_1)) == 1); | |
| 2169 | assert(uleb128Size(@backingInt(AbbrevCode.pad_n)) == 1); | |
| 2170 | assert(uleb128Size(@backingInt(AbbrevCode.decl_alias)) == decl_bytes); | |
| 2141 | 2171 | } |
| 2142 | 2172 | |
| 2143 | 2173 | const Attr = struct { |
| ... | ... | @@ -2145,7 +2175,7 @@ pub const AbbrevCode = enum { |
| 2145 | 2175 | DeclValEnum(DW.FORM), |
| 2146 | 2176 | }; |
| 2147 | 2177 | const decl_abbrev_common_attrs = &[_]Attr{ |
| 2148 | .{ .ZIG_parent, .ref_addr }, | |
| 2178 | //.{ .ZIG_parent, .ref_addr }, | |
| 2149 | 2179 | .{ .decl_line, .data4 }, |
| 2150 | 2180 | .{ .decl_column, .udata }, |
| 2151 | 2181 | .{ .accessibility, .data1 }, |
| ... | ... | @@ -2292,7 +2322,7 @@ pub const AbbrevCode = enum { |
| 2292 | 2322 | .decl_func = .{ |
| 2293 | 2323 | .tag = .subprogram, |
| 2294 | 2324 | .children = true, |
| 2295 | .attrs = decl_abbrev_common_attrs[4..] ++ .{ | |
| 2325 | .attrs = decl_abbrev_common_attrs ++ .{ | |
| 2296 | 2326 | .{ .linkage_name, .strp }, |
| 2297 | 2327 | //.{ .type, .ref_addr }, |
| 2298 | 2328 | .{ .low_pc, .addr }, |
| ... | ... | @@ -3197,14 +3227,14 @@ pub const AbbrevCode = enum { |
| 3197 | 3227 | }); |
| 3198 | 3228 | }; |
| 3199 | 3229 | |
| 3200 | pub fn uleb128Bytes(value: anytype) u32 { | |
| 3230 | pub fn uleb128Size(value: anytype) u32 { | |
| 3201 | 3231 | var buf: [64]u8 = undefined; |
| 3202 | 3232 | var dw: Writer.Discarding = .init(&buf); |
| 3203 | 3233 | dw.writer.writeUleb128(value) catch unreachable; |
| 3204 | 3234 | return @intCast(dw.fullCount()); |
| 3205 | 3235 | } |
| 3206 | 3236 | |
| 3207 | pub fn sleb128Bytes(value: anytype) u32 { | |
| 3237 | pub fn sleb128Size(value: anytype) u32 { | |
| 3208 | 3238 | var buf: [64]u8 = undefined; |
| 3209 | 3239 | var dw: Writer.Discarding = .init(&buf); |
| 3210 | 3240 | dw.writer.writeSleb128(value) catch unreachable; |
src/link/Elf2.zig+394-340| ... | ... | @@ -253,6 +253,8 @@ input_prog_node: std.Progress.Node, |
| 253 | 253 | const Error = link.Error || error{MappedFileIo}; |
| 254 | 254 | |
| 255 | 255 | const Node = union(enum) { |
| 256 | deleted, | |
| 257 | ||
| 256 | 258 | /// Only used when emitting a static library. |
| 257 | 259 | /// |
| 258 | 260 | /// Contains a header node which is an `.archive_header`. |
| ... | ... | @@ -642,7 +644,7 @@ const Section = struct { |
| 642 | 644 | } |
| 643 | 645 | const ni = shndx.get(elf).ni; |
| 644 | 646 | if (min_align.compare(.gt, ni.alignment(&elf.mf))) { |
| 645 | try ni.realign(&elf.mf, elf.base.comp.gpa, min_align); | |
| 647 | try ni.realign(elf.base.comp.gpa, &elf.mf, min_align); | |
| 646 | 648 | } |
| 647 | 649 | switch (elf.getNode(ni.parent(&elf.mf).unwrap().?)) { |
| 648 | 650 | .elf => {}, |
| ... | ... | @@ -675,7 +677,7 @@ const Section = struct { |
| 675 | 677 | break :need_size cur_size + need_additional * ent_size; |
| 676 | 678 | }, |
| 677 | 679 | }; |
| 678 | try node.ensureMinimumSize(&elf.mf, elf.base.comp.gpa, need_size); | |
| 680 | try node.ensureMinimumSize(elf.base.comp.gpa, &elf.mf, need_size); | |
| 679 | 681 | } |
| 680 | 682 | |
| 681 | 683 | /// Asserts that `rela_shndx` is a `SHT_RELA` section and deletes the `ElfN.Rela` entry at |
| ... | ... | @@ -2094,7 +2096,7 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe |
| 2094 | 2096 | const need_node_size: u64 = switch (elf.shdrPtr(.symtab)) { |
| 2095 | 2097 | inline else => |shdr, class| elf.targetLoad(&shdr.size) + len * @sizeOf(class.ElfN().Sym), |
| 2096 | 2098 | }; |
| 2097 | try Section.Index.symtab.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_node_size); | |
| 2099 | try Section.Index.symtab.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_node_size); | |
| 2098 | 2100 | } |
| 2099 | 2101 | |
| 2100 | 2102 | switch (kind) { |
| ... | ... | @@ -2117,7 +2119,7 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe |
| 2117 | 2119 | const dynsym_cur_len: u32 = @intCast(@divExact(dynsym_cur_size, dynsym_ent_size)); |
| 2118 | 2120 | |
| 2119 | 2121 | const dynsym_need_size: u64 = (dynsym_cur_len + len) * dynsym_ent_size; |
| 2120 | try elf.shndx.dynsym.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, dynsym_need_size); | |
| 2122 | try elf.shndx.dynsym.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, dynsym_need_size); | |
| 2121 | 2123 | |
| 2122 | 2124 | try elf.ensureDynsymHashCapacity(dynsym_cur_len + len); |
| 2123 | 2125 | |
| ... | ... | @@ -2150,7 +2152,7 @@ fn ensureDynsymHashCapacity(elf: *Elf, max_dynsym_count: u32) Error!void { |
| 2150 | 2152 | // We don't need to add any buckets, but we still need to make sure the section is large |
| 2151 | 2153 | // enough to fit `max_dynsym_count` chains. |
| 2152 | 2154 | const need_size = @sizeOf(info.Header()) + (nbucket + max_dynsym_count) * 4; |
| 2153 | try elf.shndx.hash.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size); | |
| 2155 | try elf.shndx.hash.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size); | |
| 2154 | 2156 | return; |
| 2155 | 2157 | } |
| 2156 | 2158 | // We need more buckets, so we'll have to rebuild the hash table. |
| ... | ... | @@ -2162,7 +2164,7 @@ fn ensureDynsymHashCapacity(elf: *Elf, max_dynsym_count: u32) Error!void { |
| 2162 | 2164 | |
| 2163 | 2165 | { |
| 2164 | 2166 | const need_size = @sizeOf(info.Header()) + (new_nbucket + max_dynsym_count) * 4; |
| 2165 | try elf.shndx.hash.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size); | |
| 2167 | try elf.shndx.hash.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size); | |
| 2166 | 2168 | } |
| 2167 | 2169 | |
| 2168 | 2170 | elf.mf.nodes_lock.lock(); |
| ... | ... | @@ -2306,19 +2308,19 @@ fn ensureUnusedPltCapacity(elf: *Elf, len: u32) Error!void { |
| 2306 | 2308 | // Ensure the `.plt` section's node is big enough: |
| 2307 | 2309 | { |
| 2308 | 2310 | const need_size: usize = plt.entry_size * (1 + need_plt_count); |
| 2309 | try elf.shndx.plt.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size); | |
| 2311 | try elf.shndx.plt.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size); | |
| 2310 | 2312 | } |
| 2311 | 2313 | |
| 2312 | 2314 | // If there is a `.got.plt` section, ensure its node is big enough |
| 2313 | 2315 | if (plt.got_plt) |got_plt| { |
| 2314 | 2316 | const need_size: usize = elf.targetPtrSize() * (got_plt.header_entries + need_plt_count); |
| 2315 | try elf.shndx.got_plt.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size); | |
| 2317 | try elf.shndx.got_plt.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size); | |
| 2316 | 2318 | } |
| 2317 | 2319 | |
| 2318 | 2320 | // If there is a `.plt.sec` section, ensure its node is big enough |
| 2319 | 2321 | if (plt.plt_sec) |plt_sec| { |
| 2320 | 2322 | const need_size: usize = plt_sec.entry_size * need_plt_count; |
| 2321 | try elf.shndx.plt_sec.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size); | |
| 2323 | try elf.shndx.plt_sec.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size); | |
| 2322 | 2324 | } |
| 2323 | 2325 | } |
| 2324 | 2326 | /// Given an index into the PLT, returns whether that PLT entry is dead, meaning it may be reused at |
| ... | ... | @@ -3244,6 +3246,7 @@ fn classifySymbolValue(elf: *Elf, sym: Symbol.Id) enum { |
| 3244 | 3246 | |
| 3245 | 3247 | pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { |
| 3246 | 3248 | const lsi: Symbol.LocalIndex = switch (elf.getNode(Node.fromAtom(atom))) { |
| 3249 | .deleted, | |
| 3247 | 3250 | .archive, |
| 3248 | 3251 | .archive_header, |
| 3249 | 3252 | .archive_input_member, |
| ... | ... | @@ -3305,7 +3308,13 @@ fn lazySymbolInner(elf: *Elf, pt: Zcu.PerThread, lazy: link.File.LazySymbol) Err |
| 3305 | 3308 | .code => .{ .text, .FUNC }, |
| 3306 | 3309 | .const_data => .{ .rodata, .OBJECT }, |
| 3307 | 3310 | }; |
| 3308 | const node = try shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{}); | |
| 3311 | const node = elf.addNodeAssumeCapacity( | |
| 3312 | try shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), | |
| 3313 | switch (lazy.kind) { | |
| 3314 | .code => .{ .lazy_code = @fromBackingInt(@intCast(gop.index)) }, | |
| 3315 | .const_data => .{ .lazy_const_data = @fromBackingInt(@intCast(gop.index)) }, | |
| 3316 | }, | |
| 3317 | ); | |
| 3309 | 3318 | var name_buf: [std.fmt.count("__lazy_const_data_{d}", .{std.math.maxInt(u32)})]u8 = undefined; |
| 3310 | 3319 | const name = std.mem.print(&name_buf, "__lazy_{t}_{d}", .{ lazy.kind, gop.index }) catch |
| 3311 | 3320 | unreachable; |
| ... | ... | @@ -3321,10 +3330,6 @@ fn lazySymbolInner(elf: *Elf, pt: Zcu.PerThread, lazy: link.File.LazySymbol) Err |
| 3321 | 3330 | .first_symbol_reloc = .none, |
| 3322 | 3331 | .first_got_reloc = .none, |
| 3323 | 3332 | }; |
| 3324 | elf.nodes.appendAssumeCapacity(switch (lazy.kind) { | |
| 3325 | .code => .{ .lazy_code = @fromBackingInt(@intCast(gop.index)) }, | |
| 3326 | .const_data => .{ .lazy_const_data = @fromBackingInt(@intCast(gop.index)) }, | |
| 3327 | }); | |
| 3328 | 3333 | elf.base.comp.link_prog_node.increaseEstimatedTotalItems(1); |
| 3329 | 3334 | } |
| 3330 | 3335 | const s: Symbol.Id = .local(gop.value_ptr.lsi); |
| ... | ... | @@ -3583,7 +3588,7 @@ const StringTable = struct { |
| 3583 | 3588 | break :size .{ old_size, new_size }; |
| 3584 | 3589 | }, |
| 3585 | 3590 | }; |
| 3586 | try ni.ensureMinimumSize(&elf.mf, gpa, new_size); | |
| 3591 | try ni.ensureMinimumSize(gpa, &elf.mf, new_size); | |
| 3587 | 3592 | const slice = ni.slice(&elf.mf)[old_size..]; |
| 3588 | 3593 | @memcpy(slice[0..key.len], key); |
| 3589 | 3594 | slice[key.len] = 0; |
| ... | ... | @@ -4014,21 +4019,21 @@ fn initHeaders( |
| 4014 | 4019 | try elf.symtab.ensureTotalCapacity(gpa, 1); |
| 4015 | 4020 | |
| 4016 | 4021 | if (is_archive) { |
| 4017 | elf.nodes.appendAssumeCapacity(.archive); | |
| 4018 | ||
| 4019 | const archive_ni: MappedFile.Node.Index = .root; | |
| 4020 | ||
| 4021 | const archive_header_ni = try archive_ni.addOnlyHeaderChild(&elf.mf, gpa, .{ | |
| 4022 | // We intentionally do not set `.alignment = .@"2"` here, because the string table data | |
| 4023 | // in this node does not need to have an aligned length. (This node's offset is aligned | |
| 4024 | // regardless by virtue of it being a header.) | |
| 4025 | .size = std.elf.ARMAG.len + @sizeOf(std.elf.ar_hdr), | |
| 4026 | // The archive header uses 'next_moved' events to resize the "//" member, so that it | |
| 4027 | // absorbs all padding between `archive_header_ni` and the actual object file members. | |
| 4028 | .enable_next_moved = true, | |
| 4029 | .next_moved = true, | |
| 4030 | }); | |
| 4031 | elf.nodes.appendAssumeCapacity(.archive_header); | |
| 4022 | const archive_ni = elf.addNodeAssumeCapacity(.root, .archive); | |
| 4023 | ||
| 4024 | const archive_header_ni = elf.addNodeAssumeCapacity( | |
| 4025 | try archive_ni.addOnlyHeaderChild(gpa, &elf.mf, .{ | |
| 4026 | // We intentionally do not set `.alignment = .@"2"` here, because the string table data | |
| 4027 | // in this node does not need to have an aligned length. (This node's offset is aligned | |
| 4028 | // regardless by virtue of it being a header.) | |
| 4029 | .size = std.elf.ARMAG.len + @sizeOf(std.elf.ar_hdr), | |
| 4030 | // The archive header uses 'next_moved' events to resize the "//" member, so that it | |
| 4031 | // absorbs all padding between `archive_header_ni` and the actual object file members. | |
| 4032 | .enable_next_moved = true, | |
| 4033 | .next_moved = true, | |
| 4034 | }), | |
| 4035 | .archive_header, | |
| 4036 | ); | |
| 4032 | 4037 | const archive_header_slice = archive_header_ni.slice(&elf.mf); |
| 4033 | 4038 | @memcpy(archive_header_slice[0..std.elf.ARMAG.len], std.elf.ARMAG); |
| 4034 | 4039 | const strtab_ar_hdr: *std.elf.ar_hdr = @ptrCast(archive_header_slice[std.elf.ARMAG.len..]); |
| ... | ... | @@ -4042,18 +4047,19 @@ fn initHeaders( |
| 4042 | 4047 | .ar_fmag = std.elf.ARFMAG.*, |
| 4043 | 4048 | }; |
| 4044 | 4049 | |
| 4045 | elf.ni.elf = try archive_ni.addOnlyFooterChild(&elf.mf, gpa, .{ | |
| 4050 | elf.ni.elf = elf.addNodeAssumeCapacity(try archive_ni.addOnlyFooterChild(gpa, &elf.mf, .{ | |
| 4046 | 4051 | .alignment = node_block_align.max(.@"2"), |
| 4047 | 4052 | .bubbles_moved = false, |
| 4048 | 4053 | .resized = true, // ensure that this node's `ar_hdr.ar_size` is updated at least once |
| 4049 | }); | |
| 4050 | elf.nodes.appendAssumeCapacity(.elf); | |
| 4054 | }), .elf); | |
| 4051 | 4055 | |
| 4052 | const elf_ar_hdr_ni = try archive_ni.addFooterChildBefore(&elf.mf, gpa, .wrap(elf.ni.elf), .{ | |
| 4053 | .alignment = .@"2", | |
| 4054 | .size = @sizeOf(std.elf.ar_hdr), | |
| 4055 | }); | |
| 4056 | elf.nodes.appendAssumeCapacity(.archive_elf_member_header); | |
| 4056 | const elf_ar_hdr_ni = elf.addNodeAssumeCapacity( | |
| 4057 | try archive_ni.addFooterChildBefore(gpa, &elf.mf, .wrap(elf.ni.elf), .{ | |
| 4058 | .alignment = .@"2", | |
| 4059 | .size = @sizeOf(std.elf.ar_hdr), | |
| 4060 | }), | |
| 4061 | .archive_elf_member_header, | |
| 4062 | ); | |
| 4057 | 4063 | |
| 4058 | 4064 | // Must be populated before we call `populateArchiveMemberName` below. |
| 4059 | 4065 | elf.archive = .{ |
| ... | ... | @@ -4079,10 +4085,7 @@ fn initHeaders( |
| 4079 | 4085 | defer gpa.free(zcu_member_name); |
| 4080 | 4086 | // After this call returns, `elf_ar_hdr` is invalidated. |
| 4081 | 4087 | try elf.populateArchiveMemberName(elf_ar_hdr, zcu_member_name); |
| 4082 | } else { | |
| 4083 | elf.ni.elf = .root; | |
| 4084 | elf.nodes.appendAssumeCapacity(.elf); | |
| 4085 | } | |
| 4088 | } else elf.ni.elf = elf.addNodeAssumeCapacity(.root, .elf); | |
| 4086 | 4089 | |
| 4087 | 4090 | const entsize: struct { ph: u32, sh: u32 } = switch (class) { |
| 4088 | 4091 | .NONE, _ => unreachable, |
| ... | ... | @@ -4098,69 +4101,65 @@ fn initHeaders( |
| 4098 | 4101 | if (@"type" != .REL) { |
| 4099 | 4102 | // This node will contain the ehdr, which must be at the start of the ELF file, so this |
| 4100 | 4103 | // node must itself be a header of the `.elf` node. |
| 4101 | elf.ni.rodata = try elf.ni.elf.addOnlyHeaderChild(&elf.mf, gpa, .{ | |
| 4104 | elf.ni.rodata = elf.addNodeAssumeCapacity(try elf.ni.elf.addOnlyHeaderChild(gpa, &elf.mf, .{ | |
| 4102 | 4105 | // Must be at least `addr_align` for `elf.ni.phdr` to be placed inside this node |
| 4103 | 4106 | .alignment = node_block_align.max(addr_align), |
| 4104 | 4107 | .moved = true, |
| 4105 | 4108 | .bubbles_moved = false, |
| 4106 | }); | |
| 4107 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.rodata }); | |
| 4109 | }), .{ .segment = phndx.rodata }); | |
| 4108 | 4110 | elf.phdrs.items[phndx.rodata] = .wrap(elf.ni.rodata); |
| 4109 | 4111 | |
| 4110 | elf.ni.phdr = try elf.ni.rodata.addFloatingChild(&elf.mf, gpa, .{ | |
| 4112 | elf.ni.phdr = elf.addNodeAssumeCapacity(try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{ | |
| 4111 | 4113 | .size = @as(u64, phnum) * entsize.ph, |
| 4112 | 4114 | .alignment = addr_align, // keep in sync with `elf.ni.rodata` alignment above |
| 4113 | 4115 | .moved = true, |
| 4114 | 4116 | .resized = true, |
| 4115 | 4117 | .bubbles_moved = false, |
| 4116 | }); | |
| 4117 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.phdr }); | |
| 4118 | }), .{ .segment = phndx.phdr }); | |
| 4118 | 4119 | elf.phdrs.items[phndx.phdr] = .wrap(elf.ni.phdr); |
| 4119 | 4120 | |
| 4120 | elf.ni.text = try elf.ni.elf.addFloatingChild(&elf.mf, gpa, .{ | |
| 4121 | elf.ni.text = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{ | |
| 4121 | 4122 | .alignment = node_block_align, |
| 4122 | 4123 | .moved = true, |
| 4123 | 4124 | .bubbles_moved = false, |
| 4124 | }); | |
| 4125 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.text }); | |
| 4125 | }), .{ .segment = phndx.text }); | |
| 4126 | 4126 | elf.phdrs.items[phndx.text] = .wrap(elf.ni.text); |
| 4127 | 4127 | |
| 4128 | elf.ni.data = try elf.ni.elf.addFloatingChild(&elf.mf, gpa, .{ | |
| 4128 | elf.ni.data = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{ | |
| 4129 | 4129 | // Must be at least `addr_align` for `elf.ni.data_rel_ro` to be placed inside this node |
| 4130 | 4130 | .alignment = node_block_align.max(addr_align), |
| 4131 | 4131 | .moved = true, |
| 4132 | 4132 | .bubbles_moved = false, |
| 4133 | }); | |
| 4134 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.data }); | |
| 4133 | }), .{ .segment = phndx.data }); | |
| 4135 | 4134 | elf.phdrs.items[phndx.data] = .wrap(elf.ni.data); |
| 4136 | 4135 | |
| 4137 | if (plt.got_plt == null) { | |
| 4138 | const plt_ni = try elf.ni.elf.addFloatingChild(&elf.mf, gpa, .{ | |
| 4136 | if (plt.got_plt == null) elf.phdrs.items[phndx.plt] = .wrap(elf.addNodeAssumeCapacity( | |
| 4137 | try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{ | |
| 4139 | 4138 | .alignment = node_block_align, |
| 4140 | 4139 | .moved = true, |
| 4141 | 4140 | .bubbles_moved = false, |
| 4142 | }); | |
| 4143 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.plt }); | |
| 4144 | elf.phdrs.items[phndx.plt] = .wrap(plt_ni); | |
| 4145 | } | |
| 4141 | }), | |
| 4142 | .{ .segment = phndx.plt }, | |
| 4143 | )); | |
| 4146 | 4144 | |
| 4147 | elf.ni.data_rel_ro = try elf.ni.data.addFloatingChild(&elf.mf, gpa, .{ | |
| 4145 | elf.ni.data_rel_ro = elf.addNodeAssumeCapacity(try elf.ni.data.addFloatingChild(gpa, &elf.mf, .{ | |
| 4148 | 4146 | // Must be at least `addr_align` for the `PT_DYNAMIC` node to be placed inside this one |
| 4149 | 4147 | // later (if `have_dynamic_section`). Keep in sync with `elf.ni.data` alignment above. |
| 4150 | 4148 | .alignment = node_block_align.max(addr_align), |
| 4151 | 4149 | .moved = true, |
| 4152 | 4150 | .bubbles_moved = false, |
| 4153 | }); | |
| 4154 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.relro }); | |
| 4151 | }), .{ .segment = phndx.relro }); | |
| 4155 | 4152 | elf.phdrs.items[phndx.relro] = .wrap(elf.ni.data_rel_ro); |
| 4156 | 4153 | |
| 4157 | 4154 | if (comp.config.any_non_single_threaded) { |
| 4158 | elf.ni.tls = .wrap(try elf.ni.rodata.addFloatingChild(&elf.mf, gpa, .{ | |
| 4159 | .alignment = node_block_align, | |
| 4160 | .moved = true, | |
| 4161 | .bubbles_moved = false, | |
| 4162 | })); | |
| 4163 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.tls }); | |
| 4155 | elf.ni.tls = .wrap(elf.addNodeAssumeCapacity( | |
| 4156 | try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{ | |
| 4157 | .alignment = node_block_align, | |
| 4158 | .moved = true, | |
| 4159 | .bubbles_moved = false, | |
| 4160 | }), | |
| 4161 | .{ .segment = phndx.tls }, | |
| 4162 | )); | |
| 4164 | 4163 | elf.phdrs.items[phndx.tls] = elf.ni.tls; |
| 4165 | 4164 | } |
| 4166 | 4165 | |
| ... | ... | @@ -4184,11 +4183,10 @@ fn initHeaders( |
| 4184 | 4183 | .REL => elf.ni.elf, |
| 4185 | 4184 | .DYN, .EXEC => elf.ni.rodata, |
| 4186 | 4185 | }; |
| 4187 | elf.ni.ehdr = try parent_ni.addOnlyHeaderChild(&elf.mf, gpa, .{ | |
| 4186 | elf.ni.ehdr = elf.addNodeAssumeCapacity(try parent_ni.addOnlyHeaderChild(gpa, &elf.mf, .{ | |
| 4188 | 4187 | .size = @sizeOf(ElfN.Ehdr), |
| 4189 | 4188 | .alignment = addr_align, |
| 4190 | }); | |
| 4191 | elf.nodes.appendAssumeCapacity(.ehdr); | |
| 4189 | }), .ehdr); | |
| 4192 | 4190 | |
| 4193 | 4191 | const ehdr: *ElfN.Ehdr = @ptrCast(@alignCast(elf.ni.ehdr.slice(&elf.mf))); |
| 4194 | 4192 | ehdr.ident = .{ |
| ... | ... | @@ -4238,13 +4236,12 @@ fn initHeaders( |
| 4238 | 4236 | }, |
| 4239 | 4237 | } |
| 4240 | 4238 | |
| 4241 | elf.ni.shdr = try elf.ni.elf.addFloatingChild(&elf.mf, gpa, .{ | |
| 4239 | elf.ni.shdr = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{ | |
| 4242 | 4240 | .size = node_block_align.forward(1 * entsize.sh), // as above, only the SHN_UNDEF initially |
| 4243 | 4241 | .alignment = addr_align.max(node_block_align), |
| 4244 | 4242 | .moved = true, |
| 4245 | 4243 | .resized = true, |
| 4246 | }); | |
| 4247 | elf.nodes.appendAssumeCapacity(.shdr); | |
| 4244 | }), .shdr); | |
| 4248 | 4245 | |
| 4249 | 4246 | switch (class) { |
| 4250 | 4247 | .NONE, _ => unreachable, |
| ... | ... | @@ -4298,18 +4295,16 @@ fn initHeaders( |
| 4298 | 4295 | .@"align" = @intCast(elf.ni.phdr.alignment(&elf.mf).toByteUnits()), |
| 4299 | 4296 | }; |
| 4300 | 4297 | |
| 4301 | if (maybe_interp) |_| { | |
| 4302 | phdr[phndx.interp] = .{ | |
| 4303 | .type = .INTERP, | |
| 4304 | .offset = 0, | |
| 4305 | .vaddr = 0, | |
| 4306 | .paddr = 0, | |
| 4307 | .filesz = 0, | |
| 4308 | .memsz = 0, | |
| 4309 | .flags = .{ .R = true }, | |
| 4310 | .@"align" = 1, | |
| 4311 | }; | |
| 4312 | } | |
| 4298 | if (maybe_interp) |_| phdr[phndx.interp] = .{ | |
| 4299 | .type = .INTERP, | |
| 4300 | .offset = 0, | |
| 4301 | .vaddr = 0, | |
| 4302 | .paddr = 0, | |
| 4303 | .filesz = 0, | |
| 4304 | .memsz = 0, | |
| 4305 | .flags = .{ .R = true }, | |
| 4306 | .@"align" = 1, | |
| 4307 | }; | |
| 4313 | 4308 | |
| 4314 | 4309 | phdr[phndx.rodata] = .{ |
| 4315 | 4310 | .type = .NULL, |
| ... | ... | @@ -4567,13 +4562,15 @@ fn initHeaders( |
| 4567 | 4562 | .node_align = node_block_align, |
| 4568 | 4563 | }); |
| 4569 | 4564 | if (maybe_interp) |interp| { |
| 4570 | const interp_ni = try elf.ni.rodata.addFloatingChild(&elf.mf, gpa, .{ | |
| 4571 | .size = interp.len + 1, | |
| 4572 | .moved = true, | |
| 4573 | .resized = true, | |
| 4574 | .bubbles_moved = false, | |
| 4575 | }); | |
| 4576 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.interp }); | |
| 4565 | const interp_ni = elf.addNodeAssumeCapacity( | |
| 4566 | try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{ | |
| 4567 | .size = interp.len + 1, | |
| 4568 | .moved = true, | |
| 4569 | .resized = true, | |
| 4570 | .bubbles_moved = false, | |
| 4571 | }), | |
| 4572 | .{ .segment = phndx.interp }, | |
| 4573 | ); | |
| 4577 | 4574 | elf.phdrs.items[phndx.interp] = .wrap(interp_ni); |
| 4578 | 4575 | |
| 4579 | 4576 | const sec_interp_shndx = try elf.addSection(interp_ni, .{ |
| ... | ... | @@ -4588,12 +4585,14 @@ fn initHeaders( |
| 4588 | 4585 | } |
| 4589 | 4586 | if (have_dynamic) { |
| 4590 | 4587 | assert(elf.ni.data_rel_ro.alignment(&elf.mf).compare(.gte, addr_align)); |
| 4591 | const dynamic_ni = try elf.ni.data_rel_ro.addFloatingChild(&elf.mf, gpa, .{ | |
| 4592 | .alignment = addr_align, | |
| 4593 | .moved = true, | |
| 4594 | .bubbles_moved = false, | |
| 4595 | }); | |
| 4596 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.dynamic }); | |
| 4588 | const dynamic_ni = elf.addNodeAssumeCapacity( | |
| 4589 | try elf.ni.data_rel_ro.addFloatingChild(gpa, &elf.mf, .{ | |
| 4590 | .alignment = addr_align, | |
| 4591 | .moved = true, | |
| 4592 | .bubbles_moved = false, | |
| 4593 | }), | |
| 4594 | .{ .segment = phndx.dynamic }, | |
| 4595 | ); | |
| 4597 | 4596 | elf.phdrs.items[phndx.dynamic] = .wrap(dynamic_ni); |
| 4598 | 4597 | |
| 4599 | 4598 | const dynstr_shndx = try elf.addSection(elf.ni.rodata, .{ |
| ... | ... | @@ -4778,13 +4777,15 @@ fn initHeaders( |
| 4778 | 4777 | } |
| 4779 | 4778 | } |
| 4780 | 4779 | if (have_eh_frame) { |
| 4781 | elf.ni.gnu_eh_frame = .wrap(try elf.ni.rodata.addFloatingChild(&elf.mf, gpa, .{ | |
| 4782 | .size = @sizeOf(Dwarf.EhFrameHdr), | |
| 4783 | .alignment = .@"4", | |
| 4784 | .moved = true, | |
| 4785 | .bubbles_moved = false, | |
| 4786 | })); | |
| 4787 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.gnu_eh_frame }); | |
| 4780 | elf.ni.gnu_eh_frame = .wrap(elf.addNodeAssumeCapacity( | |
| 4781 | try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{ | |
| 4782 | .size = @sizeOf(Dwarf.EhFrameHdr), | |
| 4783 | .alignment = .@"4", | |
| 4784 | .moved = true, | |
| 4785 | .bubbles_moved = false, | |
| 4786 | }), | |
| 4787 | .{ .segment = phndx.gnu_eh_frame }, | |
| 4788 | )); | |
| 4788 | 4789 | elf.phdrs.items[phndx.gnu_eh_frame] = elf.ni.gnu_eh_frame; |
| 4789 | 4790 | |
| 4790 | 4791 | elf.shndx.eh_frame_hdr = try elf.addSection(elf.ni.gnu_eh_frame.unwrap().?, .{ |
| ... | ... | @@ -5106,6 +5107,7 @@ fn getNode(elf: *const Elf, ni: MappedFile.Node.Index) Node { |
| 5106 | 5107 | /// Asserts that `ni` is a section, input section, copied global, NAV, UAV, or lazy code/data. |
| 5107 | 5108 | fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index { |
| 5108 | 5109 | return switch (elf.getNode(ni)) { |
| 5110 | .deleted, | |
| 5109 | 5111 | .archive, |
| 5110 | 5112 | .archive_header, |
| 5111 | 5113 | .archive_input_member, |
| ... | ... | @@ -5142,6 +5144,7 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index { |
| 5142 | 5144 | } |
| 5143 | 5145 | fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 5144 | 5146 | return switch (elf.getNode(ni)) { |
| 5147 | .deleted, | |
| 5145 | 5148 | .archive, |
| 5146 | 5149 | .archive_header, |
| 5147 | 5150 | .archive_input_member, |
| ... | ... | @@ -5179,7 +5182,12 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 5179 | 5182 | fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 5180 | 5183 | const parent_ni = ni.parent(&elf.mf).unwrap().?; |
| 5181 | 5184 | const parent_vaddr = parent_vaddr: switch (elf.getNode(parent_ni)) { |
| 5182 | .archive, .archive_header, .archive_input_member, .archive_elf_member_header => unreachable, | |
| 5185 | .deleted, | |
| 5186 | .archive, | |
| 5187 | .archive_header, | |
| 5188 | .archive_input_member, | |
| 5189 | .archive_elf_member_header, | |
| 5190 | => unreachable, | |
| 5183 | 5191 | .elf => return 0, |
| 5184 | 5192 | .ehdr, .shdr => unreachable, |
| 5185 | 5193 | .segment => |phndx| switch (elf.phdrSlice()) { |
| ... | ... | @@ -5229,6 +5237,7 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { |
| 5229 | 5237 | skip_node_relocs: MappedFile.Node.Index.Optional = .none, |
| 5230 | 5238 | first_got_reloc: ?*GotReloc.Index = null, |
| 5231 | 5239 | } = switch (elf.getNode(ni)) { |
| 5240 | .deleted, | |
| 5232 | 5241 | .archive, |
| 5233 | 5242 | .archive_header, |
| 5234 | 5243 | .archive_input_member, |
| ... | ... | @@ -5284,8 +5293,8 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { |
| 5284 | 5293 | }, |
| 5285 | 5294 | .func_debug_info => |fi| .{ |
| 5286 | 5295 | .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc, |
| 5287 | .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav| | |
| 5288 | nav.lsi.index().ptr(elf).node | |
| 5296 | .skip_symbol_relocs = if (elf.navs.getPtr(fi.get(&elf.dwarf).owner_nav)) |owner_nav| | |
| 5297 | owner_nav.lsi.index().ptr(elf).node | |
| 5289 | 5298 | else |
| 5290 | 5299 | .none, |
| 5291 | 5300 | .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc, |
| ... | ... | @@ -5875,9 +5884,9 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node |
| 5875 | 5884 | }, |
| 5876 | 5885 | }; |
| 5877 | 5886 | try shndx.ensureAligned(elf, alignment); |
| 5878 | const node = try shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 5887 | const node = elf.addNodeAssumeCapacity(try shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 5879 | 5888 | .alignment = alignment, |
| 5880 | }); | |
| 5889 | }), .{ .nav = nmi }); | |
| 5881 | 5890 | nav_gop.value_ptr.* = .{ |
| 5882 | 5891 | .lsi = elf.addLocalSymbolAssumeCapacity(.{ |
| 5883 | 5892 | .node = .wrap(node), |
| ... | ... | @@ -5890,7 +5899,6 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node |
| 5890 | 5899 | .first_symbol_reloc = .none, |
| 5891 | 5900 | .first_got_reloc = .none, |
| 5892 | 5901 | }; |
| 5893 | elf.nodes.appendAssumeCapacity(.{ .nav = nmi }); | |
| 5894 | 5902 | } |
| 5895 | 5903 | return nmi; |
| 5896 | 5904 | } |
| ... | ... | @@ -5919,10 +5927,10 @@ fn uavMapIndex( |
| 5919 | 5927 | if (!uav_gop.found_existing) { |
| 5920 | 5928 | const shndx: Section.Index = .data_rel_ro; // TODO: it would be better to use `.rodata` if the UAV value doesn't have relocs |
| 5921 | 5929 | try shndx.ensureAligned(elf, resolved_align); |
| 5922 | const node = try shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 5930 | const node = elf.addNodeAssumeCapacity(try shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 5923 | 5931 | .moved = true, // see assert at end of `genUav` |
| 5924 | 5932 | .alignment = resolved_align, |
| 5925 | }); | |
| 5933 | }), .{ .uav = umi }); | |
| 5926 | 5934 | var name_buf: [std.fmt.count("__anon_{d}", .{std.math.maxInt(u32)})]u8 = undefined; |
| 5927 | 5935 | const name = std.mem.print(&name_buf, "__anon_{d}", .{umi}) catch unreachable; |
| 5928 | 5936 | uav_gop.value_ptr.* = .{ |
| ... | ... | @@ -5936,7 +5944,6 @@ fn uavMapIndex( |
| 5936 | 5944 | }), |
| 5937 | 5945 | .first_symbol_reloc = .none, |
| 5938 | 5946 | }; |
| 5939 | elf.nodes.appendAssumeCapacity(.{ .uav = umi }); | |
| 5940 | 5947 | elf.const_prog_node.increaseEstimatedTotalItems(1); |
| 5941 | 5948 | elf.pending_uavs.appendAssumeCapacity(umi); |
| 5942 | 5949 | } else { |
| ... | ... | @@ -5944,7 +5951,7 @@ fn uavMapIndex( |
| 5944 | 5951 | const shndx = elf.getNode(node.parent(&elf.mf).unwrap().?).section; |
| 5945 | 5952 | try shndx.ensureAligned(elf, resolved_align); |
| 5946 | 5953 | if (resolved_align.order(node.alignment(&elf.mf)).compare(.gt)) { |
| 5947 | try node.realign(&elf.mf, gpa, resolved_align); | |
| 5954 | try node.realign(gpa, &elf.mf, resolved_align); | |
| 5948 | 5955 | } |
| 5949 | 5956 | } |
| 5950 | 5957 | return umi; |
| ... | ... | @@ -6173,11 +6180,13 @@ fn loadObject( |
| 6173 | 6180 | }; |
| 6174 | 6181 | |
| 6175 | 6182 | try elf.nodes.ensureUnusedCapacity(gpa, 1); |
| 6176 | const new_member_ni = try archive.ni.addFooterChildBefore(&elf.mf, gpa, first_member_oni, .{ | |
| 6177 | .size = Alignment.@"2".forward(@sizeOf(std.elf.ar_hdr) + fl.size), | |
| 6178 | .alignment = .@"2", | |
| 6179 | }); | |
| 6180 | elf.nodes.appendAssumeCapacity(.{ .archive_input_member = input_index }); | |
| 6183 | const new_member_ni = elf.addNodeAssumeCapacity( | |
| 6184 | try archive.ni.addFooterChildBefore(gpa, &elf.mf, first_member_oni, .{ | |
| 6185 | .size = Alignment.@"2".forward(@sizeOf(std.elf.ar_hdr) + fl.size), | |
| 6186 | .alignment = .@"2", | |
| 6187 | }), | |
| 6188 | .{ .archive_input_member = input_index }, | |
| 6189 | ); | |
| 6181 | 6190 | input.extra = .{ .node = new_member_ni }; |
| 6182 | 6191 | elf.input_prog_node.increaseEstimatedTotalItems(1); |
| 6183 | 6192 | |
| ... | ... | @@ -6391,22 +6400,20 @@ fn loadObject( |
| 6391 | 6400 | .alignment = need_align, |
| 6392 | 6401 | .moved = true, // see assert at end of `flushInputSection` |
| 6393 | 6402 | }; |
| 6394 | const ni = if (opts.node_fixed) ni: { | |
| 6395 | const shndx_ni = opts.shndx.get(elf).ni; | |
| 6396 | const after_oni: MappedFile.Node.Index.Optional = after: { | |
| 6397 | const last_ni = shndx_ni.last(&elf.mf).unwrap() orelse break :after .none; | |
| 6398 | break :after switch (last_ni.position(&elf.mf)) { | |
| 6399 | .header => .wrap(last_ni), | |
| 6400 | .footer, .floating => .none, | |
| 6403 | const ni = elf.addNodeAssumeCapacity( | |
| 6404 | if (opts.node_fixed) ni: { | |
| 6405 | const shndx_ni = opts.shndx.get(elf).ni; | |
| 6406 | const after_oni: MappedFile.Node.Index.Optional = after: { | |
| 6407 | const last_ni = shndx_ni.last(&elf.mf).unwrap() orelse break :after .none; | |
| 6408 | break :after switch (last_ni.position(&elf.mf)) { | |
| 6409 | .header => .wrap(last_ni), | |
| 6410 | .footer, .floating => .none, | |
| 6411 | }; | |
| 6401 | 6412 | }; |
| 6402 | }; | |
| 6403 | break :ni try shndx_ni.addHeaderChildAfter(&elf.mf, gpa, after_oni, add_node_opts); | |
| 6404 | } else ni: { | |
| 6405 | break :ni try opts.shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, add_node_opts); | |
| 6406 | }; | |
| 6407 | elf.nodes.appendAssumeCapacity(.{ | |
| 6408 | .input_section = @fromBackingInt(@intCast(elf.input_sections.items.len)), | |
| 6409 | }); | |
| 6413 | break :ni try shndx_ni.addHeaderChildAfter(gpa, &elf.mf, after_oni, add_node_opts); | |
| 6414 | } else try opts.shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, add_node_opts), | |
| 6415 | .{ .input_section = @fromBackingInt(@intCast(elf.input_sections.items.len)) }, | |
| 6416 | ); | |
| 6410 | 6417 | section.isi = @fromBackingInt(@intCast(elf.input_sections.items.len)); |
| 6411 | 6418 | elf.input_sections.addOneAssumeCapacity().* = .{ |
| 6412 | 6419 | .input = input_index, |
| ... | ... | @@ -6659,7 +6666,7 @@ fn populateArchiveMemberName(elf: *Elf, member_ar_hdr: *std.elf.ar_hdr, member_n |
| 6659 | 6666 | // We set the size of the archive header node exactly, because we want padding bytes to go into |
| 6660 | 6667 | // the root `.archive` node. That way, those bytes could still be used to grow the string table |
| 6661 | 6668 | // if necessary, but they could also be used for new archive members. |
| 6662 | try archive_header_ni.resizeLeaf(&elf.mf, gpa, old_archive_header_size + member_name.len + 2); | |
| 6669 | try archive_header_ni.resizeLeaf(gpa, &elf.mf, old_archive_header_size + member_name.len + 2); | |
| 6663 | 6670 | |
| 6664 | 6671 | const dest_slice = archive_header_ni.slice(&elf.mf)[@intCast(old_archive_header_size)..]; |
| 6665 | 6672 | @memcpy(dest_slice[0 .. dest_slice.len - 2], member_name); |
| ... | ... | @@ -6811,8 +6818,12 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (LoadPars |
| 6811 | 6818 | // We have a copy relocation for this global, but the amount of space we |
| 6812 | 6819 | // reserved for it could be too small or underaligned! |
| 6813 | 6820 | try Section.Index.data.ensureAligned(elf, gop.value_ptr.alignment); |
| 6814 | try copied_global.node.resizeLeaf(&elf.mf, gpa, gop.value_ptr.alignment.forward(gop.value_ptr.size)); | |
| 6815 | try copied_global.node.realign(&elf.mf, gpa, gop.value_ptr.alignment); | |
| 6821 | try copied_global.node.resizeLeaf( | |
| 6822 | gpa, | |
| 6823 | &elf.mf, | |
| 6824 | gop.value_ptr.alignment.forward(gop.value_ptr.size), | |
| 6825 | ); | |
| 6826 | try copied_global.node.realign(gpa, &elf.mf, gop.value_ptr.alignment); | |
| 6816 | 6827 | const global_ptr = elf.globalByName(name).?; |
| 6817 | 6828 | switch (elf.symPtr(global_ptr.symtab_index)) { |
| 6818 | 6829 | inline else => |sym_ptr| elf.targetStore(&sym_ptr.size, @intCast(gop.value_ptr.size)), |
| ... | ... | @@ -7034,49 +7045,25 @@ fn prelinkInner(elf: *Elf) Error!void { |
| 7034 | 7045 | .extra = .{ .file_symbol = zcu_file_symbol }, |
| 7035 | 7046 | }; |
| 7036 | 7047 | elf.input_pending_index += 1; |
| 7037 | } | |
| 7038 | } | |
| 7039 | ||
| 7040 | pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void { | |
| 7041 | elf.zcuFilesReadyInner(zcu) catch |err| switch (err) { | |
| 7042 | else => |e| return e, | |
| 7043 | error.MappedFileIo => return elf.base.comp.link_diags.fail( | |
| 7044 | "failed to write output file: {t}", | |
| 7045 | .{elf.mf.io_err.?}, | |
| 7046 | ), | |
| 7047 | }; | |
| 7048 | } | |
| 7049 | fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void { | |
| 7050 | const gpa = zcu.gpa; | |
| 7051 | 7048 | |
| 7052 | if (elf.dwarf.units.count() == 0) { | |
| 7053 | try elf.dwarf.initUnits(zcu); | |
| 7054 | try elf.nodes.ensureUnusedCapacity(gpa, 4 + 5 + 5 * elf.dwarf.units.count()); | |
| 7055 | try elf.dwarf_units.appendNTimes(gpa, .{ | |
| 7056 | .frame_cie_first_target_reloc = .none, | |
| 7057 | .debug_info_header_first_target_reloc = .none, | |
| 7058 | .debug_info_header_first_node_reloc = .none, | |
| 7059 | .debug_line_header_first_target_reloc = .none, | |
| 7060 | .debug_line_header_first_node_reloc = .none, | |
| 7061 | .debug_rnglists_first_target_reloc = .none, | |
| 7062 | .debug_rnglists_symbol_relocs = .empty, | |
| 7063 | }, elf.dwarf.units.count()); | |
| 7064 | ||
| 7065 | elf.dwarf.debug_abbrev.ni = | |
| 7066 | .wrap(try elf.shndx.debug_abbrev.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{})); | |
| 7067 | elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_abbrev }); | |
| 7068 | ||
| 7069 | elf.dwarf.debug_line_str.ni = | |
| 7070 | .wrap(try elf.shndx.debug_line_str.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{})); | |
| 7071 | elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_line_str }); | |
| 7072 | ||
| 7073 | elf.dwarf.debug_str.ni = | |
| 7074 | .wrap(try elf.shndx.debug_str.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{})); | |
| 7075 | elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_str }); | |
| 7076 | ||
| 7077 | elf.dwarf.debug_str_offsets.ni = | |
| 7078 | .wrap(try elf.shndx.debug_str_offsets.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{})); | |
| 7079 | elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_str_offsets }); | |
| 7049 | try elf.nodes.ensureUnusedCapacity(gpa, 4 + 5); | |
| 7050 | ||
| 7051 | elf.dwarf.debug_abbrev.ni = .wrap(elf.addNodeAssumeCapacity( | |
| 7052 | try elf.shndx.debug_abbrev.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), | |
| 7053 | .{ .debug_shared = .debug_abbrev }, | |
| 7054 | )); | |
| 7055 | elf.dwarf.debug_line_str.ni = .wrap(elf.addNodeAssumeCapacity( | |
| 7056 | try elf.shndx.debug_line_str.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), | |
| 7057 | .{ .debug_shared = .debug_line_str }, | |
| 7058 | )); | |
| 7059 | elf.dwarf.debug_str.ni = .wrap(elf.addNodeAssumeCapacity( | |
| 7060 | try elf.shndx.debug_str.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), | |
| 7061 | .{ .debug_shared = .debug_str }, | |
| 7062 | )); | |
| 7063 | elf.dwarf.debug_str_offsets.ni = .wrap(elf.addNodeAssumeCapacity( | |
| 7064 | try elf.shndx.debug_str_offsets.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), | |
| 7065 | .{ .debug_shared = .debug_str_offsets }, | |
| 7066 | )); | |
| 7080 | 7067 | |
| 7081 | 7068 | for ([5]Section.Index{ |
| 7082 | 7069 | elf.shndx.eh_frame, |
| ... | ... | @@ -7089,18 +7076,20 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void { |
| 7089 | 7076 | const debug_ni = debug_shndx.get(elf).ni; |
| 7090 | 7077 | _ = debug_ni.last(&elf.mf).unwrap() orelse continue; |
| 7091 | 7078 | const frame_format = debug_shndx.debugFrameFormat(elf); |
| 7092 | const unit_padding_ni = try debug_ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 7093 | .alignment = if (frame_format) |_| switch (elf.identClass()) { | |
| 7094 | .NONE, _ => unreachable, | |
| 7095 | .@"32" => .@"4", | |
| 7096 | .@"64" => .@"8", | |
| 7097 | } else .@"1", | |
| 7098 | .next_moved = true, | |
| 7099 | .enable_next_moved = true, | |
| 7100 | }); | |
| 7101 | elf.nodes.appendAssumeCapacity(.unit_padding); | |
| 7079 | const unit_padding_ni = elf.addNodeAssumeCapacity( | |
| 7080 | try debug_ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 7081 | .alignment = if (frame_format) |_| switch (elf.identClass()) { | |
| 7082 | .NONE, _ => unreachable, | |
| 7083 | .@"32" => .@"4", | |
| 7084 | .@"64" => .@"8", | |
| 7085 | } else .@"1", | |
| 7086 | .next_moved = true, | |
| 7087 | .enable_next_moved = true, | |
| 7088 | }), | |
| 7089 | .unit_padding, | |
| 7090 | ); | |
| 7102 | 7091 | var debug_nw: MappedFile.Node.Writer = undefined; |
| 7103 | unit_padding_ni.writer(&elf.mf, gpa, &debug_nw); | |
| 7092 | unit_padding_ni.writer(gpa, &elf.mf, &debug_nw); | |
| 7104 | 7093 | defer debug_nw.deinit(); |
| 7105 | 7094 | (if (frame_format) |format| |
| 7106 | 7095 | elf.dwarf.genDebugFrameCie(&debug_nw.interface, null, format) |
| ... | ... | @@ -7109,88 +7098,121 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void { |
| 7109 | 7098 | error.WriteFailed => return debug_nw.err.?, |
| 7110 | 7099 | }; |
| 7111 | 7100 | } |
| 7101 | } | |
| 7102 | } | |
| 7112 | 7103 | |
| 7113 | for (0.., elf.dwarf.units.values()) |unit_index, *unit| { | |
| 7114 | const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index)); | |
| 7115 | switch (elf.shndx.debug_info) { | |
| 7116 | .UNDEF => {}, | |
| 7117 | else => |debug_info_shndx| { | |
| 7118 | const debug_info_ni = | |
| 7119 | try debug_info_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 7120 | .alignment = elf.mf.flags.block_size, | |
| 7121 | .enable_next_moved = true, | |
| 7122 | }); | |
| 7123 | unit.debug_info_ni = .wrap(debug_info_ni); | |
| 7124 | elf.nodes.appendAssumeCapacity(.{ .unit_debug_info = ui }); | |
| 7125 | ||
| 7126 | unit.debug_info_header_ni = | |
| 7127 | .wrap(try debug_info_ni.addOnlyHeaderChild(&elf.mf, gpa, .{ | |
| 7128 | .next_moved = true, | |
| 7129 | .enable_next_moved = true, | |
| 7130 | })); | |
| 7131 | elf.nodes.appendAssumeCapacity(.{ .unit_debug_info_header = ui }); | |
| 7132 | }, | |
| 7133 | } | |
| 7134 | switch (elf.shndx.debug_line) { | |
| 7135 | .UNDEF => {}, | |
| 7136 | else => |debug_line_shndx| { | |
| 7137 | const debug_line_ni = | |
| 7138 | try debug_line_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 7139 | .alignment = elf.mf.flags.block_size, | |
| 7140 | .enable_next_moved = true, | |
| 7141 | }); | |
| 7142 | unit.debug_line_ni = .wrap(debug_line_ni); | |
| 7143 | elf.nodes.appendAssumeCapacity(.{ .unit_debug_line = ui }); | |
| 7144 | ||
| 7145 | unit.debug_line_header_ni = | |
| 7146 | .wrap(try debug_line_ni.addOnlyHeaderChild(&elf.mf, gpa, .{ | |
| 7147 | // Idle tasks are going to try to keep this up to date before we are able to | |
| 7148 | // write out the full header, so just reserve space for them to do so. | |
| 7149 | .size = elf.dwarf.unitLengthSize(), | |
| 7150 | .enable_next_moved = true, | |
| 7151 | })); | |
| 7152 | elf.nodes.appendAssumeCapacity(.{ .unit_debug_line_header = ui }); | |
| 7153 | }, | |
| 7154 | } | |
| 7155 | switch (elf.shndx.debug_rnglists) { | |
| 7156 | .UNDEF => {}, | |
| 7157 | else => |debug_rnglists_shndx| { | |
| 7158 | unit.debug_rnglists_ni = | |
| 7159 | .wrap(try debug_rnglists_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 7160 | .next_moved = true, | |
| 7161 | .enable_next_moved = true, | |
| 7162 | })); | |
| 7163 | elf.nodes.appendAssumeCapacity(.{ .unit_debug_rnglists = ui }); | |
| 7164 | }, | |
| 7165 | } | |
| 7104 | pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void { | |
| 7105 | elf.zcuFilesReadyInner(zcu) catch |err| switch (err) { | |
| 7106 | else => |e| return e, | |
| 7107 | error.MappedFileIo => return elf.base.comp.link_diags.fail( | |
| 7108 | "failed to write output file: {t}", | |
| 7109 | .{elf.mf.io_err.?}, | |
| 7110 | ), | |
| 7111 | }; | |
| 7112 | } | |
| 7113 | fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void { | |
| 7114 | const gpa = zcu.gpa; | |
| 7115 | ||
| 7116 | try elf.dwarf.initUnits(zcu); | |
| 7117 | const old_units_len = elf.dwarf_units.items.len; | |
| 7118 | const new_units_len = elf.dwarf.units.count(); | |
| 7119 | try elf.dwarf_units.appendNTimes(gpa, .{ | |
| 7120 | .frame_cie_first_target_reloc = .none, | |
| 7121 | .debug_info_header_first_target_reloc = .none, | |
| 7122 | .debug_info_header_first_node_reloc = .none, | |
| 7123 | .debug_line_header_first_target_reloc = .none, | |
| 7124 | .debug_line_header_first_node_reloc = .none, | |
| 7125 | .debug_rnglists_first_target_reloc = .none, | |
| 7126 | .debug_rnglists_symbol_relocs = .empty, | |
| 7127 | }, new_units_len - old_units_len); | |
| 7128 | try elf.nodes.ensureUnusedCapacity(gpa, 5 * (new_units_len - old_units_len)); | |
| 7129 | ||
| 7130 | for (old_units_len.., elf.dwarf.units.values()[old_units_len..]) |unit_index, *unit| { | |
| 7131 | const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index)); | |
| 7132 | switch (elf.shndx.debug_info) { | |
| 7133 | .UNDEF => {}, | |
| 7134 | else => |debug_info_shndx| { | |
| 7135 | const debug_info_ni = elf.addNodeAssumeCapacity( | |
| 7136 | try debug_info_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 7137 | .alignment = elf.mf.flags.block_size, | |
| 7138 | .enable_next_moved = true, | |
| 7139 | }), | |
| 7140 | .{ .unit_debug_info = ui }, | |
| 7141 | ); | |
| 7142 | unit.debug_info_ni = .wrap(debug_info_ni); | |
| 7143 | ||
| 7144 | unit.debug_info_header_ni = .wrap(elf.addNodeAssumeCapacity( | |
| 7145 | try debug_info_ni.addOnlyHeaderChild(gpa, &elf.mf, .{ | |
| 7146 | .next_moved = true, | |
| 7147 | .enable_next_moved = true, | |
| 7148 | }), | |
| 7149 | .{ .unit_debug_info_header = ui }, | |
| 7150 | )); | |
| 7151 | }, | |
| 7166 | 7152 | } |
| 7153 | switch (elf.shndx.debug_line) { | |
| 7154 | .UNDEF => {}, | |
| 7155 | else => |debug_line_shndx| { | |
| 7156 | const debug_line_ni = elf.addNodeAssumeCapacity( | |
| 7157 | try debug_line_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 7158 | .alignment = elf.mf.flags.block_size, | |
| 7159 | .enable_next_moved = true, | |
| 7160 | }), | |
| 7161 | .{ .unit_debug_line = ui }, | |
| 7162 | ); | |
| 7163 | unit.debug_line_ni = .wrap(debug_line_ni); | |
| 7167 | 7164 | |
| 7168 | for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| { | |
| 7169 | var drh_nw: MappedFile.Node.Writer = undefined; | |
| 7170 | unit.debug_rnglists_ni.unwrap().?.writer(&elf.mf, gpa, &drh_nw); | |
| 7171 | defer drh_nw.deinit(); | |
| 7172 | const debug_rnglists_offsets_table_offset = | |
| 7173 | elf.dwarf.genDebugRnglistsHeader(unit, &drh_nw) catch |err| switch (err) { | |
| 7174 | else => |e| return e, | |
| 7175 | error.WriteFailed => return drh_nw.err.?, | |
| 7176 | }; | |
| 7165 | unit.debug_line_header_ni = .wrap(elf.addNodeAssumeCapacity( | |
| 7166 | try debug_line_ni.addOnlyHeaderChild(gpa, &elf.mf, .{ | |
| 7167 | // Idle tasks are going to try to keep this up to date before we are able to | |
| 7168 | // write out the full header, so just reserve space for them to do so. | |
| 7169 | .size = elf.dwarf.unitLengthSize(), | |
| 7170 | .enable_next_moved = true, | |
| 7171 | }), | |
| 7172 | .{ .unit_debug_line_header = ui }, | |
| 7173 | )); | |
| 7174 | }, | |
| 7175 | } | |
| 7176 | switch (elf.shndx.debug_rnglists) { | |
| 7177 | .UNDEF => {}, | |
| 7178 | else => |debug_rnglists_shndx| unit.debug_rnglists_ni = .wrap(elf.addNodeAssumeCapacity( | |
| 7179 | try debug_rnglists_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 7180 | .next_moved = true, | |
| 7181 | .enable_next_moved = true, | |
| 7182 | }), | |
| 7183 | .{ .unit_debug_rnglists = ui }, | |
| 7184 | )), | |
| 7185 | } | |
| 7186 | } | |
| 7177 | 7187 | |
| 7178 | var dih_nw: MappedFile.Node.Writer = undefined; | |
| 7179 | const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?; | |
| 7180 | debug_info_header_ni.writer(&elf.mf, gpa, &dih_nw); | |
| 7181 | defer dih_nw.deinit(); | |
| 7182 | elf.resetNodeRelocs(debug_info_header_ni); | |
| 7183 | elf.dwarf.genDebugInfoHeader( | |
| 7184 | mod, | |
| 7185 | unit, | |
| 7186 | &dih_nw, | |
| 7187 | debug_rnglists_offsets_table_offset, | |
| 7188 | zcu, | |
| 7189 | ) catch |err| switch (err) { | |
| 7188 | for ( | |
| 7189 | elf.dwarf.units.keys()[old_units_len..], | |
| 7190 | elf.dwarf.units.values()[old_units_len..], | |
| 7191 | ) |mod, *unit| { | |
| 7192 | var drh_nw: MappedFile.Node.Writer = undefined; | |
| 7193 | unit.debug_rnglists_ni.unwrap().?.writer(gpa, &elf.mf, &drh_nw); | |
| 7194 | defer drh_nw.deinit(); | |
| 7195 | const debug_rnglists_offsets_table_offset = | |
| 7196 | elf.dwarf.genDebugRnglistsHeader(unit, &drh_nw) catch |err| switch (err) { | |
| 7190 | 7197 | else => |e| return e, |
| 7191 | error.WriteFailed => return dih_nw.err.?, | |
| 7198 | error.WriteFailed => return drh_nw.err.?, | |
| 7192 | 7199 | }; |
| 7193 | } | |
| 7200 | ||
| 7201 | var dih_nw: MappedFile.Node.Writer = undefined; | |
| 7202 | const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?; | |
| 7203 | debug_info_header_ni.writer(gpa, &elf.mf, &dih_nw); | |
| 7204 | defer dih_nw.deinit(); | |
| 7205 | elf.resetNodeRelocs(debug_info_header_ni); | |
| 7206 | elf.dwarf.genDebugInfoHeader( | |
| 7207 | mod, | |
| 7208 | unit, | |
| 7209 | &dih_nw, | |
| 7210 | debug_rnglists_offsets_table_offset, | |
| 7211 | zcu, | |
| 7212 | ) catch |err| switch (err) { | |
| 7213 | else => |e| return e, | |
| 7214 | error.WriteFailed => return dih_nw.err.?, | |
| 7215 | }; | |
| 7194 | 7216 | } |
| 7195 | 7217 | } |
| 7196 | 7218 | |
| ... | ... | @@ -7203,7 +7225,7 @@ fn flushFiles(elf: *Elf) Error!void { |
| 7203 | 7225 | try debug_line_header_ni.moved(gpa, &elf.mf); |
| 7204 | 7226 | try debug_line_header_ni.nextMoved(gpa, &elf.mf); |
| 7205 | 7227 | var dlh_nw: MappedFile.Node.Writer = undefined; |
| 7206 | debug_line_header_ni.writer(&elf.mf, gpa, &dlh_nw); | |
| 7228 | debug_line_header_ni.writer(gpa, &elf.mf, &dlh_nw); | |
| 7207 | 7229 | defer dlh_nw.deinit(); |
| 7208 | 7230 | elf.resetNodeRelocs(debug_line_header_ni); |
| 7209 | 7231 | elf.dwarf.genDebugLineHeader(mod, unit, &dlh_nw, elf.base.comp.zcu.?) catch |err| switch (err) { |
| ... | ... | @@ -7235,7 +7257,7 @@ fn prepareDynamic(elf: *Elf) Error!void { |
| 7235 | 7257 | |
| 7236 | 7258 | const dynamic_size = dynamic_len * 2 * elf.targetPtrSize(); |
| 7237 | 7259 | |
| 7238 | try elf.shndx.dynamic.get(elf).ni.resizeLeaf(&elf.mf, comp.gpa, dynamic_size); | |
| 7260 | try elf.shndx.dynamic.get(elf).ni.resizeLeaf(comp.gpa, &elf.mf, dynamic_size); | |
| 7239 | 7261 | switch (elf.shdrPtr(elf.shndx.dynamic)) { |
| 7240 | 7262 | inline else => |shdr| elf.targetStore(&shdr.size, @intCast(dynamic_size)), |
| 7241 | 7263 | } |
| ... | ... | @@ -7405,17 +7427,20 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 7405 | 7427 | break :shndx .{ @fromBackingInt(shndx), @as(u64, elf.targetLoad(&ehdr.shentsize)) * @as(u64, shnum) }; |
| 7406 | 7428 | }, |
| 7407 | 7429 | }; |
| 7408 | try elf.ni.shdr.ensureMinimumSize(&elf.mf, gpa, new_shdr_size); | |
| 7430 | try elf.ni.shdr.ensureMinimumSize(gpa, &elf.mf, new_shdr_size); | |
| 7409 | 7431 | const parent_ni = switch (elf.ehdrType()) { |
| 7410 | 7432 | .REL => elf.ni.elf, |
| 7411 | 7433 | .EXEC, .DYN => segment_ni, |
| 7412 | 7434 | }; |
| 7413 | 7435 | assert(opts.addralign.check(opts.size)); |
| 7414 | const ni = try parent_ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 7436 | const ni = elf.addNodeAssumeCapacity(try parent_ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 7415 | 7437 | .size = opts.node_align.forward(opts.size), |
| 7416 | 7438 | .alignment = opts.addralign.max(opts.node_align), |
| 7417 | 7439 | .resized = opts.size > 0, |
| 7418 | 7440 | .bubbles_moved = opts.flags.ALLOC, |
| 7441 | }), switch (opts.manual_size) { | |
| 7442 | false => .{ .section = shndx }, | |
| 7443 | true => .{ .section_manual_size = shndx }, | |
| 7419 | 7444 | }); |
| 7420 | 7445 | const addr = elf.computeNodeVAddr(ni); |
| 7421 | 7446 | const lsi: Symbol.LocalIndex = if (opts.flags.ALLOC) elf.addLocalSymbolAssumeCapacity(.{ |
| ... | ... | @@ -7431,10 +7456,6 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 7431 | 7456 | .RELA => .{ .free_head = .none }, |
| 7432 | 7457 | else => .{ .shndx = .UNDEF }, |
| 7433 | 7458 | } }); |
| 7434 | elf.nodes.appendAssumeCapacity(switch (opts.manual_size) { | |
| 7435 | false => .{ .section = shndx }, | |
| 7436 | true => .{ .section_manual_size = shndx }, | |
| 7437 | }); | |
| 7438 | 7459 | switch (elf.shdrPtr(shndx)) { |
| 7439 | 7460 | inline else => |shdr, class| { |
| 7440 | 7461 | shdr.* = .{ |
| ... | ... | @@ -7505,7 +7526,7 @@ fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize) |
| 7505 | 7526 | .NONE, _ => unreachable, |
| 7506 | 7527 | inline else => |ct_class| (elf.got.count() + new_got_entries) * @sizeOf(ct_class.ElfN().Addr), |
| 7507 | 7528 | }; |
| 7508 | try elf.shndx.got.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_got_size); | |
| 7529 | try elf.shndx.got.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_got_size); | |
| 7509 | 7530 | |
| 7510 | 7531 | if (elf.shndx.dynamic != .UNDEF) { |
| 7511 | 7532 | try elf.shndx.rela_dyn.relaEnsureAdditionalCapacity(elf, new_got_entries); |
| ... | ... | @@ -8100,6 +8121,7 @@ fn addGotRelocAssumeCapacity( |
| 8100 | 8121 | ) void { |
| 8101 | 8122 | assert(elf.ehdrType() != .REL); |
| 8102 | 8123 | switch (elf.getNode(node)) { |
| 8124 | .deleted, | |
| 8103 | 8125 | .archive, |
| 8104 | 8126 | .archive_header, |
| 8105 | 8127 | .archive_input_member, |
| ... | ... | @@ -8361,14 +8383,13 @@ fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) Error!bool { |
| 8361 | 8383 | try Section.Index.data.ensureAligned(elf, dso_global.alignment); |
| 8362 | 8384 | |
| 8363 | 8385 | try elf.nodes.ensureUnusedCapacity(gpa, 1); |
| 8364 | const node = try Section.Index.data.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 8386 | const node = try Section.Index.data.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 8365 | 8387 | .size = dso_global.alignment.forward(dso_global.size), |
| 8366 | 8388 | .alignment = dso_global.alignment, |
| 8367 | 8389 | }); |
| 8368 | 8390 | errdefer comptime unreachable; |
| 8369 | 8391 | |
| 8370 | 8392 | const vaddr = elf.computeNodeVAddr(node); |
| 8371 | elf.nodes.appendAssumeCapacity(.{ .copied_global = global_name }); | |
| 8372 | 8393 | const rela_index = elf.shndx.rela_dyn.relaAddOneAssumeCapacity(elf, .{ |
| 8373 | 8394 | .type = .copy(elf), |
| 8374 | 8395 | .offset = vaddr, |
| ... | ... | @@ -8423,7 +8444,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) |
| 8423 | 8444 | |
| 8424 | 8445 | { |
| 8425 | 8446 | var nw: MappedFile.Node.Writer = undefined; |
| 8426 | ni.writer(&elf.mf, gpa, &nw); | |
| 8447 | ni.writer(gpa, &elf.mf, &nw); | |
| 8427 | 8448 | defer nw.deinit(); |
| 8428 | 8449 | elf.resetNodeRelocs(ni); |
| 8429 | 8450 | codegen.generateSymbol( |
| ... | ... | @@ -8549,16 +8570,16 @@ fn updateFuncInner( |
| 8549 | 8570 | |
| 8550 | 8571 | { |
| 8551 | 8572 | var nw: MappedFile.Node.Writer = undefined; |
| 8552 | ni.writer(&elf.mf, gpa, &nw); | |
| 8573 | ni.writer(gpa, &elf.mf, &nw); | |
| 8553 | 8574 | defer nw.deinit(); |
| 8554 | 8575 | var debug_output_buf: Dwarf.WipNav.Debug = undefined; |
| 8555 | 8576 | const debug_output: link.File.DebugInfoOutput, const dwarf_func = debug_output: { |
| 8556 | 8577 | if (elf.ehdrMachine() != .X86_64) break :debug_output .{ .none, undefined }; |
| 8557 | 8578 | const dwarf = &elf.dwarf; |
| 8558 | const mod = zcu.navFileScope(func.owner_nav).mod.?; | |
| 8579 | const mod = zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?; | |
| 8559 | 8580 | if (mod.strip and mod.unwind_tables == .none) break :debug_output .{ .none, undefined }; |
| 8560 | 8581 | |
| 8561 | try elf.nodes.ensureUnusedCapacity(gpa, 5); | |
| 8582 | try elf.nodes.ensureUnusedCapacity(gpa, 4); | |
| 8562 | 8583 | const dwarf_fi = try dwarf.getFunc(func.owner_nav); |
| 8563 | 8584 | |
| 8564 | 8585 | const wip_nav = &debug_output_buf.wip_nav; |
| ... | ... | @@ -8586,27 +8607,28 @@ fn updateFuncInner( |
| 8586 | 8607 | .@"64" => .@"8", |
| 8587 | 8608 | }; |
| 8588 | 8609 | const frame_ni = unit.frame_ni.unwrap() orelse frame_ni: { |
| 8589 | const frame_ni = try switch (wip_nav.frame_format) { | |
| 8610 | const frame_ni = elf.addNodeAssumeCapacity(try switch (wip_nav.frame_format) { | |
| 8590 | 8611 | .debug_frame => elf.shndx.debug_frame, |
| 8591 | 8612 | .eh_frame => elf.shndx.eh_frame, |
| 8592 | }.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 8613 | }.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 8593 | 8614 | .alignment = frame_align.max(elf.mf.flags.block_size), |
| 8594 | 8615 | .enable_next_moved = true, |
| 8595 | }); | |
| 8616 | }), .{ .unit_frame = wip_nav.unit }); | |
| 8596 | 8617 | unit.frame_ni = .wrap(frame_ni); |
| 8597 | elf.nodes.appendAssumeCapacity(.{ .unit_frame = wip_nav.unit }); | |
| 8598 | 8618 | break :frame_ni frame_ni; |
| 8599 | 8619 | }; |
| 8600 | 8620 | _ = unit.cie_ni.unwrap() orelse { |
| 8601 | const cie_ni = try frame_ni.addOnlyHeaderChild(&elf.mf, gpa, .{ | |
| 8602 | .alignment = frame_align, | |
| 8603 | .next_moved = true, | |
| 8604 | .enable_next_moved = true, | |
| 8605 | }); | |
| 8621 | const cie_ni = elf.addNodeAssumeCapacity( | |
| 8622 | try frame_ni.addOnlyHeaderChild(gpa, &elf.mf, .{ | |
| 8623 | .alignment = frame_align, | |
| 8624 | .next_moved = true, | |
| 8625 | .enable_next_moved = true, | |
| 8626 | }), | |
| 8627 | .{ .unit_frame_cie = wip_nav.unit }, | |
| 8628 | ); | |
| 8606 | 8629 | unit.cie_ni = .wrap(cie_ni); |
| 8607 | elf.nodes.appendAssumeCapacity(.{ .unit_frame_cie = wip_nav.unit }); | |
| 8608 | 8630 | var cie_nw: MappedFile.Node.Writer = undefined; |
| 8609 | cie_ni.writer(&elf.mf, gpa, &cie_nw); | |
| 8631 | cie_ni.writer(gpa, &elf.mf, &cie_nw); | |
| 8610 | 8632 | defer cie_nw.deinit(); |
| 8611 | 8633 | dwarf.genDebugFrameCie(&cie_nw.interface, switch (elf.ehdrMachine()) { |
| 8612 | 8634 | else => unreachable, |
| ... | ... | @@ -8621,7 +8643,7 @@ fn updateFuncInner( |
| 8621 | 8643 | try fde_ni.nextMoved(gpa, &elf.mf); |
| 8622 | 8644 | break :fde_ni fde_ni; |
| 8623 | 8645 | } else fde_ni: { |
| 8624 | const fde_ni = try frame_ni.addFloatingChild(&elf.mf, gpa, .{ | |
| 8646 | const fde_ni = try frame_ni.addFloatingChild(gpa, &elf.mf, .{ | |
| 8625 | 8647 | .alignment = frame_align, |
| 8626 | 8648 | .moved = true, |
| 8627 | 8649 | .next_moved = true, |
| ... | ... | @@ -8630,7 +8652,7 @@ fn updateFuncInner( |
| 8630 | 8652 | dwarf_func.fde_ni = .wrap(fde_ni); |
| 8631 | 8653 | break :fde_ni fde_ni; |
| 8632 | 8654 | }; |
| 8633 | fde_ni.writer(&elf.mf, gpa, &wip_nav.fde_writer); | |
| 8655 | fde_ni.writer(gpa, &elf.mf, &wip_nav.fde_writer); | |
| 8634 | 8656 | |
| 8635 | 8657 | if (mod.strip) break :debug_output .{ .{ .eh_frame = wip_nav }, dwarf_func }; |
| 8636 | 8658 | |
| ... | ... | @@ -8642,20 +8664,21 @@ fn updateFuncInner( |
| 8642 | 8664 | const debug_info_ni = dwarf_func.debug_info_ni.unwrap().?; |
| 8643 | 8665 | try debug_info_ni.moved(gpa, &elf.mf); |
| 8644 | 8666 | try debug_info_ni.nextMoved(gpa, &elf.mf); |
| 8645 | debug_info_ni.writer(&elf.mf, gpa, &debug.info_writer); | |
| 8667 | debug_info_ni.writer(gpa, &elf.mf, &debug.info_writer); | |
| 8646 | 8668 | |
| 8647 | 8669 | const debug_line_ni = dwarf_func.debug_line_ni.unwrap() orelse debug_line_ni: { |
| 8648 | const debug_line_ni = | |
| 8649 | try unit.debug_line_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{ | |
| 8670 | const debug_line_ni = elf.addNodeAssumeCapacity( | |
| 8671 | try unit.debug_line_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{ | |
| 8650 | 8672 | .moved = true, |
| 8651 | 8673 | .next_moved = true, |
| 8652 | 8674 | .enable_next_moved = true, |
| 8653 | }); | |
| 8675 | }), | |
| 8676 | .{ .func_debug_line = dwarf_fi }, | |
| 8677 | ); | |
| 8654 | 8678 | dwarf_func.debug_line_ni = .wrap(debug_line_ni); |
| 8655 | elf.nodes.appendAssumeCapacity(.{ .func_debug_line = dwarf_fi }); | |
| 8656 | 8679 | break :debug_line_ni debug_line_ni; |
| 8657 | 8680 | }; |
| 8658 | debug_line_ni.writer(&elf.mf, gpa, &debug.line_writer); | |
| 8681 | debug_line_ni.writer(gpa, &elf.mf, &debug.line_writer); | |
| 8659 | 8682 | |
| 8660 | 8683 | break :debug_output .{ .{ .dwarf2 = debug }, dwarf_func }; |
| 8661 | 8684 | }; |
| ... | ... | @@ -8705,13 +8728,13 @@ fn updateFuncInner( |
| 8705 | 8728 | .debug_frame => elf.shndx.debug_frame, |
| 8706 | 8729 | .eh_frame => elf.shndx.eh_frame, |
| 8707 | 8730 | }.get(elf).ni; |
| 8708 | try frame_ni.trimStart(&elf.mf, gpa); | |
| 8731 | try frame_ni.trimStart(gpa, &elf.mf); | |
| 8709 | 8732 | switch (wip_nav.frame_format) { |
| 8710 | 8733 | .debug_frame => {}, |
| 8711 | 8734 | .eh_frame => { |
| 8712 | 8735 | const last_offset, const last_size = |
| 8713 | 8736 | frame_ni.last(&elf.mf).unwrap().?.location(&elf.mf).resolve(&elf.mf); |
| 8714 | try frame_ni.ensureMinimumSize(&elf.mf, gpa, last_offset + last_size + 4); | |
| 8737 | try frame_ni.ensureMinimumSize(gpa, &elf.mf, last_offset + last_size + 4); | |
| 8715 | 8738 | }, |
| 8716 | 8739 | } |
| 8717 | 8740 | }, |
| ... | ... | @@ -8721,18 +8744,18 @@ fn updateFuncInner( |
| 8721 | 8744 | elf.shndx.debug_info, |
| 8722 | 8745 | elf.shndx.debug_line, |
| 8723 | 8746 | elf.shndx.debug_rnglists, |
| 8724 | }) |debug_shndx| try debug_shndx.get(elf).ni.trimStart(&elf.mf, gpa); | |
| 8747 | }) |debug_shndx| try debug_shndx.get(elf).ni.trimStart(gpa, &elf.mf); | |
| 8725 | 8748 | const unit = debug.wip_nav.unit.get(debug.wip_nav.dwarf); |
| 8726 | 8749 | { |
| 8727 | 8750 | const debug_info_ni = unit.debug_info_ni.unwrap().?; |
| 8728 | 8751 | const last_offset, const last_size = |
| 8729 | 8752 | debug_info_ni.last(&elf.mf).unwrap().?.location(&elf.mf).resolve(&elf.mf); |
| 8730 | try debug_info_ni.ensureMinimumSize(&elf.mf, gpa, last_offset + last_size + | |
| 8731 | comptime Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) * 2); | |
| 8753 | try debug_info_ni.ensureMinimumSize(gpa, &elf.mf, last_offset + last_size + | |
| 8754 | comptime Dwarf.uleb128Size(@backingInt(Dwarf.AbbrevCode.null)) * 2); | |
| 8732 | 8755 | } |
| 8733 | 8756 | { |
| 8734 | 8757 | var dr_nw: MappedFile.Node.Writer = undefined; |
| 8735 | unit.debug_rnglists_ni.unwrap().?.writer(&elf.mf, gpa, &dr_nw); | |
| 8758 | unit.debug_rnglists_ni.unwrap().?.writer(gpa, &elf.mf, &dr_nw); | |
| 8736 | 8759 | defer dr_nw.deinit(); |
| 8737 | 8760 | const first_symbol_reloc = elf.symbol_relocs.items.len; |
| 8738 | 8761 | debug.wip_nav.dwarf.genDebugRnglists( |
| ... | ... | @@ -8764,6 +8787,25 @@ fn updateFuncInner( |
| 8764 | 8787 | try elf.genPending(pt); |
| 8765 | 8788 | } |
| 8766 | 8789 | |
| 8790 | pub fn updateLineNumber(elf: *Elf, pt: Zcu.PerThread, src_inst: InternPool.TrackedInst.Index) void { | |
| 8791 | const func = elf.dwarf.funcs.getPtr(src_inst) orelse return; | |
| 8792 | elf.dwarf.updateLineNumber(pt.zcu, src_inst, func.debug_info_ni.unwrap().?.slice(&elf.mf)); | |
| 8793 | } | |
| 8794 | ||
| 8795 | pub fn lostTracking( | |
| 8796 | elf: *Elf, | |
| 8797 | _: Zcu.PerThread, | |
| 8798 | src_inst: InternPool.TrackedInst.Index, | |
| 8799 | ) std.mem.Allocator.Error!void { | |
| 8800 | const func = elf.dwarf.funcs.getPtr(src_inst) orelse return; | |
| 8801 | elf.resetNodeRelocs(func.fde_ni.unwrap().?); | |
| 8802 | elf.resetNodeRelocs(func.debug_info_ni.unwrap().?); | |
| 8803 | elf.resetNodeRelocs(func.debug_line_ni.unwrap().?); | |
| 8804 | try elf.deleteNode(&func.fde_ni); | |
| 8805 | try elf.deleteNode(&func.debug_info_ni); | |
| 8806 | try elf.deleteNode(&func.debug_line_ni); | |
| 8807 | } | |
| 8808 | ||
| 8767 | 8809 | pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void { |
| 8768 | 8810 | try elf.updateConstInner( |
| 8769 | 8811 | pt, |
| ... | ... | @@ -8996,18 +9038,18 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { |
| 8996 | 9038 | |
| 8997 | 9039 | break :task; |
| 8998 | 9040 | } |
| 8999 | while (elf.mf.updates.pop()) |ni| { | |
| 9041 | while (elf.mf.updates.pop()) |ni| : (elf.mf.update_prog_node.completeOne()) { | |
| 9042 | if (ni.pendingDelete(&elf.mf)) continue; | |
| 9000 | 9043 | const clean_moved = ni.cleanMoved(&elf.mf); |
| 9001 | 9044 | const clean_resized = ni.cleanResized(&elf.mf); |
| 9002 | 9045 | const clean_next_moved = ni.cleanNextMoved(&elf.mf); |
| 9003 | if (clean_moved or clean_resized or clean_next_moved) { | |
| 9004 | const sub_prog_node = elf.idleProgNode(tid, elf.mf.update_prog_node, elf.getNode(ni)); | |
| 9005 | defer sub_prog_node.end(); | |
| 9006 | if (clean_moved) try elf.flushMoved(ni); | |
| 9007 | if (clean_resized) try elf.flushResized(ni); | |
| 9008 | if (clean_next_moved) try elf.flushNextMoved(ni); | |
| 9009 | break :task; | |
| 9010 | } else elf.mf.update_prog_node.completeOne(); | |
| 9046 | if (!clean_moved and !clean_resized and !clean_next_moved) continue; | |
| 9047 | const sub_prog_node = elf.idleProgNode(tid, elf.mf.update_prog_node, elf.getNode(ni)); | |
| 9048 | defer sub_prog_node.end(); | |
| 9049 | if (clean_moved) try elf.flushMoved(ni); | |
| 9050 | if (clean_resized) try elf.flushResized(ni); | |
| 9051 | if (clean_next_moved) try elf.flushNextMoved(ni); | |
| 9052 | break :task; | |
| 9011 | 9053 | } |
| 9012 | 9054 | } |
| 9013 | 9055 | if (elf.input_sections.items.len > elf.input_section_pending_index) return true; |
| ... | ... | @@ -9085,7 +9127,7 @@ fn idleProgNode( |
| 9085 | 9127 | .func_debug_info => "debug", |
| 9086 | 9128 | .func_debug_line => "line", |
| 9087 | 9129 | }, |
| 9088 | ip.getNav(fi.nav(&elf.dwarf)).fqn.fmt(ip), | |
| 9130 | ip.getNav(fi.get(&elf.dwarf).owner_nav).fqn.fmt(ip), | |
| 9089 | 9131 | }) catch &name; |
| 9090 | 9132 | }, |
| 9091 | 9133 | }, 0); |
| ... | ... | @@ -9109,14 +9151,13 @@ fn genUav( |
| 9109 | 9151 | pt: Zcu.PerThread, |
| 9110 | 9152 | umi: Node.UavMapIndex, |
| 9111 | 9153 | ) Error!void { |
| 9112 | const comp = elf.base.comp; | |
| 9113 | const gpa = comp.gpa; | |
| 9154 | const gpa = elf.base.comp.gpa; | |
| 9114 | 9155 | |
| 9115 | 9156 | const uav_val = umi.uavValue(elf); |
| 9116 | 9157 | const ni = umi.symbol(elf).index().ptr(elf).node.unwrap().?; |
| 9117 | 9158 | |
| 9118 | 9159 | var nw: MappedFile.Node.Writer = undefined; |
| 9119 | ni.writer(&elf.mf, gpa, &nw); | |
| 9160 | ni.writer(gpa, &elf.mf, &nw); | |
| 9120 | 9161 | defer nw.deinit(); |
| 9121 | 9162 | elf.resetNodeRelocs(ni); |
| 9122 | 9163 | codegen.generateSymbol( |
| ... | ... | @@ -9150,7 +9191,7 @@ fn genLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void { |
| 9150 | 9191 | |
| 9151 | 9192 | var required_alignment: InternPool.Alignment = .none; |
| 9152 | 9193 | var nw: MappedFile.Node.Writer = undefined; |
| 9153 | ni.writer(&elf.mf, gpa, &nw); | |
| 9194 | ni.writer(gpa, &elf.mf, &nw); | |
| 9154 | 9195 | defer nw.deinit(); |
| 9155 | 9196 | elf.resetNodeRelocs(ni); |
| 9156 | 9197 | codegen.generateLazySymbol( |
| ... | ... | @@ -9241,7 +9282,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void { |
| 9241 | 9282 | }), |
| 9242 | 9283 | }; |
| 9243 | 9284 | var nw: MappedFile.Node.Writer = undefined; |
| 9244 | isi.node(elf).writer(&elf.mf, gpa, &nw); | |
| 9285 | isi.node(elf).writer(gpa, &elf.mf, &nw); | |
| 9245 | 9286 | defer nw.deinit(); |
| 9246 | 9287 | const n_bytes = nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) catch |err| switch (err) { |
| 9247 | 9288 | error.ReadFailed => return diags.fail("failed to read input section '{s}' from \"{f}{f}\": {t}", .{ |
| ... | ... | @@ -9296,17 +9337,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9296 | 9337 | defer trace.end(); |
| 9297 | 9338 | |
| 9298 | 9339 | switch (elf.getNode(ni)) { |
| 9299 | .archive => unreachable, | |
| 9300 | .archive_header => unreachable, | |
| 9301 | ||
| 9302 | .archive_input_member, | |
| 9303 | .archive_elf_member_header, | |
| 9304 | .elf, | |
| 9305 | => { | |
| 9340 | .deleted => unreachable, | |
| 9341 | .archive, .archive_header => unreachable, | |
| 9342 | .archive_input_member, .archive_elf_member_header, .elf => { | |
| 9306 | 9343 | assert(elf.archive != null); |
| 9307 | 9344 | return; |
| 9308 | 9345 | }, |
| 9309 | ||
| 9310 | 9346 | .ehdr, .shdr => elf.flushElfOffset(ni), |
| 9311 | 9347 | .segment => |phndx| { |
| 9312 | 9348 | elf.flushElfOffset(ni); |
| ... | ... | @@ -9570,7 +9606,8 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9570 | 9606 | }, |
| 9571 | 9607 | .func_frame_fde => |fi| { |
| 9572 | 9608 | const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)]; |
| 9573 | const mod = elf.base.comp.zcu.?.navFileScope(fi.nav(&elf.dwarf)).mod.?; | |
| 9609 | const zcu = elf.base.comp.zcu.?; | |
| 9610 | const mod = zcu.fileByIndex(fi.srcInst(&elf.dwarf).resolveFile(&zcu.intern_pool)).mod.?; | |
| 9574 | 9611 | switch (mod.unwind_tables) { |
| 9575 | 9612 | .none => {}, |
| 9576 | 9613 | .sync, .async => { |
| ... | ... | @@ -9594,8 +9631,8 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9594 | 9631 | } |
| 9595 | 9632 | elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{ |
| 9596 | 9633 | .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc, |
| 9597 | .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav| | |
| 9598 | nav.lsi.index().ptr(elf).node | |
| 9634 | .skip_symbol_relocs = if (elf.navs.getPtr(fi.get(&elf.dwarf).owner_nav)) |owner_nav| | |
| 9635 | owner_nav.lsi.index().ptr(elf).node | |
| 9599 | 9636 | else |
| 9600 | 9637 | .none, |
| 9601 | 9638 | .first_node_reloc = dwarf_func.debug_info_first_node_reloc, |
| ... | ... | @@ -9770,6 +9807,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo |
| 9770 | 9807 | |
| 9771 | 9808 | _, const size = ni.location(&elf.mf).resolve(&elf.mf); |
| 9772 | 9809 | switch (elf.getNode(ni)) { |
| 9810 | .deleted => unreachable, | |
| 9773 | 9811 | .archive, .archive_header => {}, |
| 9774 | 9812 | .archive_input_member => unreachable, |
| 9775 | 9813 | .archive_elf_member_header => unreachable, |
| ... | ... | @@ -9869,6 +9907,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! |
| 9869 | 9907 | defer trace.end(); |
| 9870 | 9908 | |
| 9871 | 9909 | switch (elf.getNode(ni)) { |
| 9910 | .deleted, | |
| 9872 | 9911 | .archive, |
| 9873 | 9912 | .archive_input_member, |
| 9874 | 9913 | .archive_elf_member_header, |
| ... | ... | @@ -10002,7 +10041,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! |
| 10002 | 10041 | switch (tag) { |
| 10003 | 10042 | else => unreachable, |
| 10004 | 10043 | .unit_debug_info_header, .value_debug_info, .global_debug_info, .func_debug_info => { |
| 10005 | comptime assert(Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) == 1); | |
| 10044 | comptime assert(Dwarf.uleb128Size(@backingInt(Dwarf.AbbrevCode.null)) == 1); | |
| 10006 | 10045 | @memset(fw.unusedCapacitySlice(), @backingInt(Dwarf.AbbrevCode.null)); |
| 10007 | 10046 | }, |
| 10008 | 10047 | .unit_debug_line_header, .func_debug_line => Dwarf.genDebugLinePadding(&fw, fw.unusedCapacityLen()) catch |
| ... | ... | @@ -10591,10 +10630,10 @@ pub fn printNode( |
| 10591 | 10630 | .func_frame_fde, .func_debug_info, .func_debug_line => |fi| { |
| 10592 | 10631 | const zcu = elf.base.comp.zcu.?; |
| 10593 | 10632 | const ip = &zcu.intern_pool; |
| 10594 | const nav = ip.getNav(fi.nav(&elf.dwarf)); | |
| 10633 | const owner_nav = ip.getNav(fi.get(&elf.dwarf).owner_nav); | |
| 10595 | 10634 | try w.print("({f}, {f})", .{ |
| 10596 | Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }), | |
| 10597 | nav.fqn.fmt(ip), | |
| 10635 | Type.fromInterned(owner_nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }), | |
| 10636 | owner_nav.fqn.fmt(ip), | |
| 10598 | 10637 | }); |
| 10599 | 10638 | }, |
| 10600 | 10639 | } |
| ... | ... | @@ -10655,7 +10694,7 @@ fn ensureSegmentAligned(elf: *Elf, start_phndx: u32, min_align: Alignment) Error |
| 10655 | 10694 | // Align the actual node |
| 10656 | 10695 | const seg_ni = elf.phdrs.items[phndx].unwrap().?; |
| 10657 | 10696 | if (min_align.compare(.gt, seg_ni.alignment(&elf.mf))) { |
| 10658 | try seg_ni.realign(&elf.mf, gpa, min_align); | |
| 10697 | try seg_ni.realign(gpa, &elf.mf, min_align); | |
| 10659 | 10698 | } |
| 10660 | 10699 | // Update the phdr `@"align"` field if necessary |
| 10661 | 10700 | switch (elf.phdrSlice()) { |
| ... | ... | @@ -10686,6 +10725,21 @@ fn ensureSegmentAligned(elf: *Elf, start_phndx: u32, min_align: Alignment) Error |
| 10686 | 10725 | } |
| 10687 | 10726 | } |
| 10688 | 10727 | |
| 10728 | pub fn addNodeAssumeCapacity(elf: *Elf, ni: MappedFile.Node.Index, node: Node) MappedFile.Node.Index { | |
| 10729 | if (elf.nodes.len - @backingInt(ni) > 0) { | |
| 10730 | assert(elf.getNode(ni) == .deleted); | |
| 10731 | elf.nodes.set(@backingInt(ni), node); | |
| 10732 | } else elf.nodes.appendAssumeCapacity(node); | |
| 10733 | return ni; | |
| 10734 | } | |
| 10735 | ||
| 10736 | fn deleteNode(elf: *Elf, node: *MappedFile.Node.Index.Optional) std.mem.Allocator.Error!void { | |
| 10737 | const ni = node.unwrap().?; | |
| 10738 | try ni.delete(elf.base.comp.gpa, &elf.mf); | |
| 10739 | elf.nodes.set(@backingInt(ni), .deleted); | |
| 10740 | node.* = .none; | |
| 10741 | } | |
| 10742 | ||
| 10689 | 10743 | /// If `sym` has a PLT entry, returns the address of that entry (specifically, the address which a |
| 10690 | 10744 | /// branch to the PLT should target). If `sym` does not have a PLT entry, returns `null`. |
| 10691 | 10745 | fn pltEntryTargetAddr(elf: *Elf, sym: Symbol.Id) ?u64 { |
src/link/MappedFile.zig+69-56| ... | ... | @@ -362,7 +362,7 @@ pub const Node = extern struct { |
| 362 | 362 | } |
| 363 | 363 | |
| 364 | 364 | /// Adds a floating child node to `parent_ni`. Returns the index of the new child. |
| 365 | pub fn addFloatingChild(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, opts: AddOptions) Error!Node.Index { | |
| 365 | pub fn addFloatingChild(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, opts: AddOptions) Error!Node.Index { | |
| 366 | 366 | return mf.addNode(gpa, .{ |
| 367 | 367 | .add_options = opts, |
| 368 | 368 | .position = .floating, |
| ... | ... | @@ -373,11 +373,11 @@ pub const Node = extern struct { |
| 373 | 373 | /// Adds a header child node to `parent_ni`. Returns the index of the new child. |
| 374 | 374 | /// |
| 375 | 375 | /// Asserts that `parent_ni` has no existing header children. |
| 376 | pub fn addOnlyHeaderChild(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, opts: AddOptions) Error!Node.Index { | |
| 376 | pub fn addOnlyHeaderChild(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, opts: AddOptions) Error!Node.Index { | |
| 377 | 377 | if (parent_ni.first(mf).unwrap()) |first_ni| { |
| 378 | 378 | assert(first_ni.position(mf) != .header); // `parent_ni` already has a header child |
| 379 | 379 | } |
| 380 | return parent_ni.addHeaderChildAfter(mf, gpa, .none, opts); | |
| 380 | return parent_ni.addHeaderChildAfter(gpa, mf, .none, opts); | |
| 381 | 381 | } |
| 382 | 382 | /// Adds a header child node to `parent_ni`. Returns the index of the new child. |
| 383 | 383 | /// |
| ... | ... | @@ -386,7 +386,7 @@ pub const Node = extern struct { |
| 386 | 386 | /// |
| 387 | 387 | /// Otherwise, asserts that `prev_oni` is a header node and a child of `parent_ni`, and |
| 388 | 388 | /// places the new child node immediately after `prev_oni`. |
| 389 | pub fn addHeaderChildAfter(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, prev_oni: Node.Index.Optional, opts: AddOptions) Error!Node.Index { | |
| 389 | pub fn addHeaderChildAfter(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, prev_oni: Node.Index.Optional, opts: AddOptions) Error!Node.Index { | |
| 390 | 390 | return mf.addNode(gpa, .{ |
| 391 | 391 | .add_options = opts, |
| 392 | 392 | .position = .header, |
| ... | ... | @@ -397,11 +397,11 @@ pub const Node = extern struct { |
| 397 | 397 | /// Adds a footer child node to `parent_ni`. Returns the index of the new child. |
| 398 | 398 | /// |
| 399 | 399 | /// Asserts that `parent_ni` has no existing footer children. |
| 400 | pub fn addOnlyFooterChild(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, opts: AddOptions) Error!Node.Index { | |
| 400 | pub fn addOnlyFooterChild(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, opts: AddOptions) Error!Node.Index { | |
| 401 | 401 | if (parent_ni.last(mf).unwrap()) |last_ni| { |
| 402 | 402 | assert(last_ni.position(mf) != .footer); // `parent_ni` already has a footer child |
| 403 | 403 | } |
| 404 | return parent_ni.addFooterChildBefore(mf, gpa, .none, opts); | |
| 404 | return parent_ni.addFooterChildBefore(gpa, mf, .none, opts); | |
| 405 | 405 | } |
| 406 | 406 | /// Adds a footer child node to `parent_ni`. Returns the index of the new child. |
| 407 | 407 | /// |
| ... | ... | @@ -410,7 +410,7 @@ pub const Node = extern struct { |
| 410 | 410 | /// |
| 411 | 411 | /// Otherwise, asserts that `next_oni` is a footer node and a child of `parent_ni`, and |
| 412 | 412 | /// places the new child node immediately before `next_oni`. |
| 413 | pub fn addFooterChildBefore(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, next_oni: Node.Index.Optional, opts: AddOptions) Error!Node.Index { | |
| 413 | pub fn addFooterChildBefore(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, next_oni: Node.Index.Optional, opts: AddOptions) Error!Node.Index { | |
| 414 | 414 | const prev_oni: Node.Index.Optional = prev: { |
| 415 | 415 | const next_ni = next_oni.unwrap() orelse { |
| 416 | 416 | break :prev parent_ni.last(mf); |
| ... | ... | @@ -473,8 +473,8 @@ pub const Node = extern struct { |
| 473 | 473 | fn setNext( |
| 474 | 474 | ni: Node.Index, |
| 475 | 475 | gpa: Allocator, |
| 476 | next_ni: Node.Index.Optional, | |
| 477 | 476 | mf: *MappedFile, |
| 477 | next_ni: Node.Index.Optional, | |
| 478 | 478 | ) Allocator.Error!void { |
| 479 | 479 | const next_ptr = &ni.get(mf).next; |
| 480 | 480 | if (next_ptr.* == next_ni) return; |
| ... | ... | @@ -571,7 +571,7 @@ pub const Node = extern struct { |
| 571 | 571 | return ni.get(mf).flags.alignment; |
| 572 | 572 | } |
| 573 | 573 | |
| 574 | fn setLocation(ni: Node.Index, mf: *MappedFile, gpa: Allocator, offset: u64, size: u64) Allocator.Error!void { | |
| 574 | fn setLocation(ni: Node.Index, gpa: Allocator, mf: *MappedFile, offset: u64, size: u64) Allocator.Error!void { | |
| 575 | 575 | try mf.large.ensureUnusedCapacity(gpa, 2); |
| 576 | 576 | try mf.updates.ensureUnusedCapacity(gpa, 2); |
| 577 | 577 | const node = ni.get(mf); |
| ... | ... | @@ -646,19 +646,37 @@ pub const Node = extern struct { |
| 646 | 646 | return mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)]; |
| 647 | 647 | } |
| 648 | 648 | |
| 649 | pub fn trimStart(ni: Node.Index, mf: *MappedFile, gpa: Allocator) Allocator.Error!void { | |
| 649 | pub fn delete(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void { | |
| 650 | const node = ni.get(mf); | |
| 651 | assert(node.first == .none and node.last == .none); // has children | |
| 652 | mf.removeNodesFromChildList(gpa, ni, ni); | |
| 653 | const updated = node.flags.moved or node.flags.resized or node.flags.next_moved; | |
| 654 | node.* = undefined; | |
| 655 | node.next = ni.toOptional(); | |
| 656 | if (!updated) assert(ni.pendingDelete(mf)); | |
| 657 | } | |
| 658 | ||
| 659 | pub fn pendingDelete(ni: Node.Index, mf: *MappedFile) bool { | |
| 660 | const node = ni.get(mf); | |
| 661 | if (node.next != ni.toOptional()) return false; | |
| 662 | node.next = mf.free_ni; | |
| 663 | mf.free_ni = ni.toOptional(); | |
| 664 | return true; | |
| 665 | } | |
| 666 | ||
| 667 | pub fn trimStart(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void { | |
| 650 | 668 | mf.nodes_lock.assertUnlocked(); |
| 651 | 669 | const node = ni.get(mf); |
| 652 | 670 | const first_ni = node.first.unwrap() orelse return; |
| 653 | 671 | const shift, _ = first_ni.location(mf).resolve(mf); |
| 654 | 672 | if (shift == 0) return; |
| 655 | 673 | const offset, const size = node.location().resolve(mf); |
| 656 | try ni.setLocation(mf, gpa, offset + shift, size - shift); | |
| 674 | try ni.setLocation(gpa, mf, offset + shift, size - shift); | |
| 657 | 675 | var child_oni = node.first; |
| 658 | 676 | while (child_oni.unwrap()) |child_ni| { |
| 659 | 677 | const child_node = child_ni.get(mf); |
| 660 | 678 | const child_offset, const child_size = child_node.location().resolve(mf); |
| 661 | try child_ni.setLocation(mf, gpa, child_offset - shift, child_size); | |
| 679 | try child_ni.setLocation(gpa, mf, child_offset - shift, child_size); | |
| 662 | 680 | child_oni = child_node.next; |
| 663 | 681 | } |
| 664 | 682 | } |
| ... | ... | @@ -666,7 +684,7 @@ pub const Node = extern struct { |
| 666 | 684 | /// Ensures that the size of `ni` is at least `min_size`. Valid for any node. |
| 667 | 685 | /// |
| 668 | 686 | /// Applies `growth_factor` if necessary (so the caller should *not* apply `growth_factor`). |
| 669 | pub fn ensureMinimumSize(ni: Node.Index, mf: *MappedFile, gpa: Allocator, min_size: u64) Error!void { | |
| 687 | pub fn ensureMinimumSize(ni: Node.Index, gpa: Allocator, mf: *MappedFile, min_size: u64) Error!void { | |
| 670 | 688 | _, const current_size = ni.location(mf).resolve(mf); |
| 671 | 689 | if (current_size >= min_size) return; |
| 672 | 690 | const new_size = ni.alignment(mf).forward(min_size +| min_size / growth_factor); |
| ... | ... | @@ -682,7 +700,7 @@ pub const Node = extern struct { |
| 682 | 700 | /// Asserts that `ni` is a leaf node, i.e. has no children. |
| 683 | 701 | /// |
| 684 | 702 | /// Asserts that `size` is aligned to `ni.alignment(mf)`. |
| 685 | pub fn resizeLeaf(ni: Node.Index, mf: *MappedFile, gpa: Allocator, size: u64) Error!void { | |
| 703 | pub fn resizeLeaf(ni: Node.Index, gpa: Allocator, mf: *MappedFile, size: u64) Error!void { | |
| 686 | 704 | assert(ni.first(mf) == .none); |
| 687 | 705 | // The alignment of `size` is asserted by `shrinkLeafNode` and `growNode`. |
| 688 | 706 | _, const old_size = ni.location(mf).resolve(mf); |
| ... | ... | @@ -702,17 +720,12 @@ pub const Node = extern struct { |
| 702 | 720 | /// If the node's current offset or size is not sufficiently aligned, it will be moved |
| 703 | 721 | /// and/or resized to match the new alignment. The node's size may be increased by any |
| 704 | 722 | /// amount, as if `ensureMinimumSize` were used. |
| 705 | pub fn realign( | |
| 706 | ni: Node.Index, | |
| 707 | mf: *MappedFile, | |
| 708 | gpa: Allocator, | |
| 709 | new_alignment: Alignment, | |
| 710 | ) Error!void { | |
| 723 | pub fn realign(ni: Node.Index, gpa: Allocator, mf: *MappedFile, new_alignment: Alignment) Error!void { | |
| 711 | 724 | try mf.realignNode(gpa, ni, new_alignment); |
| 712 | 725 | mf.updateWriters(); |
| 713 | 726 | } |
| 714 | 727 | |
| 715 | pub fn writer(ni: Node.Index, mf: *MappedFile, gpa: Allocator, w: *Writer) void { | |
| 728 | pub fn writer(ni: Node.Index, gpa: Allocator, mf: *MappedFile, w: *Writer) void { | |
| 716 | 729 | w.* = .{ |
| 717 | 730 | .gpa = gpa, |
| 718 | 731 | .mf = mf, |
| ... | ... | @@ -842,7 +855,7 @@ pub const Node = extern struct { |
| 842 | 855 | ) Io.Writer.Error!void { |
| 843 | 856 | _ = preserve; |
| 844 | 857 | const w: *Writer = @fieldParentPtr("interface", interface); |
| 845 | w.ni.ensureMinimumSize(w.mf, w.gpa, interface.end + unused_capacity) catch |err| { | |
| 858 | w.ni.ensureMinimumSize(w.gpa, w.mf, interface.end + unused_capacity) catch |err| { | |
| 846 | 859 | w.err = err; |
| 847 | 860 | return error.WriteFailed; |
| 848 | 861 | }; |
| ... | ... | @@ -1014,7 +1027,7 @@ fn shrinkLeafNode( |
| 1014 | 1027 | }, |
| 1015 | 1028 | }; |
| 1016 | 1029 | try mf.ensureTotalCapacityPrecise(@intCast(new_size)); |
| 1017 | try ni.setLocation(mf, gpa, old_offset, new_size); | |
| 1030 | try ni.setLocation(gpa, mf, old_offset, new_size); | |
| 1018 | 1031 | return; |
| 1019 | 1032 | }; |
| 1020 | 1033 | |
| ... | ... | @@ -1022,7 +1035,7 @@ fn shrinkLeafNode( |
| 1022 | 1035 | .header => { |
| 1023 | 1036 | const shift = old_size - new_size; |
| 1024 | 1037 | |
| 1025 | try ni.setLocation(mf, gpa, old_offset, new_size); | |
| 1038 | try ni.setLocation(gpa, mf, old_offset, new_size); | |
| 1026 | 1039 | |
| 1027 | 1040 | // We need to shift backwards all header nodes following us. |
| 1028 | 1041 | const next_header_ni = ni.next(mf).unwrap() orelse return; |
| ... | ... | @@ -1031,7 +1044,7 @@ fn shrinkLeafNode( |
| 1031 | 1044 | var header_ni = next_header_ni; |
| 1032 | 1045 | while (true) { |
| 1033 | 1046 | const old_header_off, const old_header_size = header_ni.location(mf).resolve(mf); |
| 1034 | try header_ni.setLocation(mf, gpa, old_header_off - shift, old_header_size); | |
| 1047 | try header_ni.setLocation(gpa, mf, old_header_off - shift, old_header_size); | |
| 1035 | 1048 | |
| 1036 | 1049 | const next_ni = header_ni.next(mf).unwrap() orelse break; |
| 1037 | 1050 | if (next_ni.position(mf) != .header) break; |
| ... | ... | @@ -1056,13 +1069,13 @@ fn shrinkLeafNode( |
| 1056 | 1069 | ); |
| 1057 | 1070 | }, |
| 1058 | 1071 | .floating => { |
| 1059 | try ni.setLocation(mf, gpa, old_offset, new_size); | |
| 1072 | try ni.setLocation(gpa, mf, old_offset, new_size); | |
| 1060 | 1073 | }, |
| 1061 | 1074 | .footer => { |
| 1062 | 1075 | const shift = old_size - new_size; |
| 1063 | 1076 | |
| 1064 | 1077 | const new_offset = old_offset + shift; |
| 1065 | try ni.setLocation(mf, gpa, new_offset, new_size); | |
| 1078 | try ni.setLocation(gpa, mf, new_offset, new_size); | |
| 1066 | 1079 | |
| 1067 | 1080 | const prev_footers_size = prev_footers_size: { |
| 1068 | 1081 | // We need to shift forwards all footer nodes preceding us. |
| ... | ... | @@ -1076,7 +1089,7 @@ fn shrinkLeafNode( |
| 1076 | 1089 | var footer_ni = prev_footer_ni; |
| 1077 | 1090 | while (true) { |
| 1078 | 1091 | const old_footer_off, const old_footer_size = footer_ni.location(mf).resolve(mf); |
| 1079 | try footer_ni.setLocation(mf, gpa, old_footer_off + shift, old_footer_size); | |
| 1092 | try footer_ni.setLocation(gpa, mf, old_footer_off + shift, old_footer_size); | |
| 1080 | 1093 | |
| 1081 | 1094 | const prev_ni = footer_ni.prev(mf).unwrap() orelse break; |
| 1082 | 1095 | if (prev_ni.position(mf) != .footer) break; |
| ... | ... | @@ -1159,7 +1172,7 @@ fn growNode( |
| 1159 | 1172 | }, |
| 1160 | 1173 | }; |
| 1161 | 1174 | try mf.ensureTotalCapacityPrecise(@intCast(new_size)); |
| 1162 | try ni.setLocation(mf, gpa, old_offset, new_size); | |
| 1175 | try ni.setLocation(gpa, mf, old_offset, new_size); | |
| 1163 | 1176 | if (grow_options.move_footers) { |
| 1164 | 1177 | // We need to move any footers to be at the *new* end of the file. |
| 1165 | 1178 | if (ni.firstFooter(mf).unwrap()) |first_footer_ni| { |
| ... | ... | @@ -1174,7 +1187,7 @@ fn growNode( |
| 1174 | 1187 | var cur_ni = first_footer_ni; |
| 1175 | 1188 | while (true) { |
| 1176 | 1189 | const old_footer_offset, const footer_size = cur_ni.location(mf).resolve(mf); |
| 1177 | try cur_ni.setLocation(mf, gpa, old_footer_offset + (new_size - old_size), footer_size); | |
| 1190 | try cur_ni.setLocation(gpa, mf, old_footer_offset + (new_size - old_size), footer_size); | |
| 1178 | 1191 | cur_ni = cur_ni.next(mf).unwrap() orelse break; |
| 1179 | 1192 | } |
| 1180 | 1193 | } |
| ... | ... | @@ -1233,8 +1246,8 @@ fn growNode( |
| 1233 | 1246 | while (true) { |
| 1234 | 1247 | const old_sub_footer_offset, const sub_footer_size = cur_ni.location(mf).resolve(mf); |
| 1235 | 1248 | try cur_ni.setLocation( |
| 1236 | mf, | |
| 1237 | 1249 | gpa, |
| 1250 | mf, | |
| 1238 | 1251 | old_sub_footer_offset + (new_size - old_size), |
| 1239 | 1252 | sub_footer_size, |
| 1240 | 1253 | ); |
| ... | ... | @@ -1249,8 +1262,8 @@ fn growNode( |
| 1249 | 1262 | assert(moved_header_ni.position(mf) == .header); |
| 1250 | 1263 | const moved_header_offset, const moved_header_size = moved_header_ni.location(mf).resolve(mf); |
| 1251 | 1264 | try moved_header_ni.setLocation( |
| 1252 | mf, | |
| 1253 | 1265 | gpa, |
| 1266 | mf, | |
| 1254 | 1267 | moved_header_offset - old_size + new_size, |
| 1255 | 1268 | moved_header_size, |
| 1256 | 1269 | ); |
| ... | ... | @@ -1259,7 +1272,7 @@ fn growNode( |
| 1259 | 1272 | } |
| 1260 | 1273 | |
| 1261 | 1274 | // Finally, update our own size: |
| 1262 | try ni.setLocation(mf, gpa, old_offset, new_size); | |
| 1275 | try ni.setLocation(gpa, mf, old_offset, new_size); | |
| 1263 | 1276 | return; |
| 1264 | 1277 | }, |
| 1265 | 1278 | .floating => { |
| ... | ... | @@ -1387,8 +1400,8 @@ fn growNode( |
| 1387 | 1400 | |
| 1388 | 1401 | // Update our own offset and size: |
| 1389 | 1402 | try ni.setLocation( |
| 1390 | mf, | |
| 1391 | 1403 | gpa, |
| 1404 | mf, | |
| 1392 | 1405 | node.location().resolve(mf)[0] - shift, |
| 1393 | 1406 | new_size, |
| 1394 | 1407 | ); |
| ... | ... | @@ -1399,7 +1412,7 @@ fn growNode( |
| 1399 | 1412 | var footer_oni = first_sub_footer_oni; |
| 1400 | 1413 | while (footer_oni.unwrap()) |footer_ni| : (footer_oni = footer_ni.next(mf)) { |
| 1401 | 1414 | const old_footer_offset, const footer_size = footer_ni.location(mf).resolve(mf); |
| 1402 | try footer_ni.setLocation(mf, gpa, old_footer_offset + shift, footer_size); | |
| 1415 | try footer_ni.setLocation(gpa, mf, old_footer_offset + shift, footer_size); | |
| 1403 | 1416 | } |
| 1404 | 1417 | } |
| 1405 | 1418 | |
| ... | ... | @@ -1414,7 +1427,7 @@ fn growNode( |
| 1414 | 1427 | while (footer_ni != ni) : (footer_ni = footer_ni.next(mf).unwrap().?) { |
| 1415 | 1428 | moved_has_content = moved_has_content or footer_ni.get(mf).flags.has_content; |
| 1416 | 1429 | const old_footer_offset, const footer_size = footer_ni.location(mf).resolve(mf); |
| 1417 | try footer_ni.setLocation(mf, gpa, old_footer_offset - shift, footer_size); | |
| 1430 | try footer_ni.setLocation(gpa, mf, old_footer_offset - shift, footer_size); | |
| 1418 | 1431 | } |
| 1419 | 1432 | } |
| 1420 | 1433 | |
| ... | ... | @@ -1466,8 +1479,8 @@ fn growNode( |
| 1466 | 1479 | } |
| 1467 | 1480 | |
| 1468 | 1481 | try ni.setLocation( |
| 1469 | mf, | |
| 1470 | 1482 | gpa, |
| 1483 | mf, | |
| 1471 | 1484 | node.location().resolve(mf)[0], |
| 1472 | 1485 | actual_new_size, |
| 1473 | 1486 | ); |
| ... | ... | @@ -1483,7 +1496,7 @@ fn growNode( |
| 1483 | 1496 | assert(footer_ni.position(mf) == .footer); |
| 1484 | 1497 | moved_has_content = moved_has_content or footer_ni.get(mf).flags.has_content; |
| 1485 | 1498 | const footer_old_offset: u64, const footer_size: u64 = footer_ni.location(mf).resolve(mf); |
| 1486 | try footer_ni.setLocation(mf, gpa, footer_old_offset + shift, footer_size); | |
| 1499 | try footer_ni.setLocation(gpa, mf, footer_old_offset + shift, footer_size); | |
| 1487 | 1500 | } |
| 1488 | 1501 | } |
| 1489 | 1502 | |
| ... | ... | @@ -1494,7 +1507,7 @@ fn growNode( |
| 1494 | 1507 | assert(footer_ni.position(mf) == .footer); |
| 1495 | 1508 | moved_has_content = moved_has_content or footer_ni.get(mf).flags.has_content; |
| 1496 | 1509 | const footer_old_offset: u64, const footer_size: u64 = footer_ni.location(mf).resolve(mf); |
| 1497 | try footer_ni.setLocation(mf, gpa, footer_old_offset + shift, footer_size); | |
| 1510 | try footer_ni.setLocation(gpa, mf, footer_old_offset + shift, footer_size); | |
| 1498 | 1511 | } |
| 1499 | 1512 | } |
| 1500 | 1513 | |
| ... | ... | @@ -1566,7 +1579,7 @@ fn growFloatingNodeWithAlignment( |
| 1566 | 1579 | break :grow_in_place; // the parent is not big enough |
| 1567 | 1580 | } |
| 1568 | 1581 | // Great, we can grow this node without changing its offset or moving any siblings. |
| 1569 | try ni.setLocation(mf, gpa, old_offset, new_size); | |
| 1582 | try ni.setLocation(gpa, mf, old_offset, new_size); | |
| 1570 | 1583 | if (grow_options.move_footers) { |
| 1571 | 1584 | // If we have any footers, we need to move them to the end of our new size, and update |
| 1572 | 1585 | // their offsets accordingly. |
| ... | ... | @@ -1576,7 +1589,7 @@ fn growFloatingNodeWithAlignment( |
| 1576 | 1589 | while (true) { |
| 1577 | 1590 | footers_have_content = footers_have_content or cur_ni.get(mf).flags.has_content; |
| 1578 | 1591 | const old_footer_offset, const footer_size = cur_ni.location(mf).resolve(mf); |
| 1579 | try cur_ni.setLocation(mf, gpa, old_footer_offset + (new_size - old_size), footer_size); | |
| 1592 | try cur_ni.setLocation(gpa, mf, old_footer_offset + (new_size - old_size), footer_size); | |
| 1580 | 1593 | cur_ni = cur_ni.next(mf).unwrap() orelse break; |
| 1581 | 1594 | } |
| 1582 | 1595 | if (footers_have_content) { |
| ... | ... | @@ -1713,7 +1726,7 @@ fn growFloatingNodeWithAlignment( |
| 1713 | 1726 | footers_have_content = footers_have_content or cur_ni.get(mf).flags.has_content; |
| 1714 | 1727 | const old_footer_offset, const footer_size = cur_ni.location(mf).resolve(mf); |
| 1715 | 1728 | // Our footers' offsets must change to be at the end of our new size. |
| 1716 | try cur_ni.setLocation(mf, gpa, old_footer_offset + (new_size - old_size), footer_size); | |
| 1729 | try cur_ni.setLocation(gpa, mf, old_footer_offset + (new_size - old_size), footer_size); | |
| 1717 | 1730 | cur_ni = cur_ni.next(mf).unwrap() orelse break; |
| 1718 | 1731 | } |
| 1719 | 1732 | |
| ... | ... | @@ -1740,7 +1753,7 @@ fn growFloatingNodeWithAlignment( |
| 1740 | 1753 | assert(!footers_have_content); |
| 1741 | 1754 | } |
| 1742 | 1755 | |
| 1743 | try ni.setLocation(mf, gpa, new_loc.offset, new_size); | |
| 1756 | try ni.setLocation(gpa, mf, new_loc.offset, new_size); | |
| 1744 | 1757 | |
| 1745 | 1758 | if (new_loc.prev != ni.toOptional()) { |
| 1746 | 1759 | // We're potentially in a different place in `parent_ni`'s child list, so remove and re-add ourselves. |
| ... | ... | @@ -1940,11 +1953,11 @@ fn growNodeViaInsertRange( |
| 1940 | 1953 | if (cur_ni == .root) { |
| 1941 | 1954 | try mf.ensureTotalCapacityPrecise(@intCast(this_old_size + range_size)); |
| 1942 | 1955 | } |
| 1943 | try cur_ni.setLocation(mf, gpa, this_offset, this_old_size + range_size); | |
| 1956 | try cur_ni.setLocation(gpa, mf, this_offset, this_old_size + range_size); | |
| 1944 | 1957 | |
| 1945 | 1958 | while (cur_ni.next(mf).unwrap()) |next_ni| { |
| 1946 | 1959 | const next_old_offset, const next_size = next_ni.location(mf).resolve(mf); |
| 1947 | try next_ni.setLocation(mf, gpa, next_old_offset + range_size, next_size); | |
| 1960 | try next_ni.setLocation(gpa, mf, next_old_offset + range_size, next_size); | |
| 1948 | 1961 | cur_ni = next_ni; |
| 1949 | 1962 | } |
| 1950 | 1963 | |
| ... | ... | @@ -1957,7 +1970,7 @@ fn growNodeViaInsertRange( |
| 1957 | 1970 | var footer_ni = first_footer_ni; |
| 1958 | 1971 | while (true) { |
| 1959 | 1972 | const old_footer_offset, const footer_size = footer_ni.location(mf).resolve(mf); |
| 1960 | try footer_ni.setLocation(mf, gpa, old_footer_offset + range_size, footer_size); | |
| 1973 | try footer_ni.setLocation(gpa, mf, old_footer_offset + range_size, footer_size); | |
| 1961 | 1974 | footer_ni = footer_ni.next(mf).unwrap() orelse break; |
| 1962 | 1975 | } |
| 1963 | 1976 | } |
| ... | ... | @@ -2125,7 +2138,7 @@ fn ensureAdditionalHeaderCapacity( |
| 2125 | 2138 | const old_offset, const old_size = cur_ni.location(mf).resolve(mf); |
| 2126 | 2139 | const new_offset = old_offset - moving_offset + dest_offset; |
| 2127 | 2140 | assert(cur_ni.alignment(mf).check(new_offset)); |
| 2128 | try cur_ni.setLocation(mf, gpa, new_offset, old_size); | |
| 2141 | try cur_ni.setLocation(gpa, mf, new_offset, old_size); | |
| 2129 | 2142 | if (cur_ni == last_moving_ni) break; |
| 2130 | 2143 | cur_ni = cur_ni.next(mf).unwrap().?; |
| 2131 | 2144 | } |
| ... | ... | @@ -2168,7 +2181,7 @@ fn removeNodesFromChildList( |
| 2168 | 2181 | |
| 2169 | 2182 | if (prev_oni.unwrap()) |prev_ni| { |
| 2170 | 2183 | assert(prev_ni.next(mf).unwrap().? == first_remove_ni); |
| 2171 | try prev_ni.setNext(gpa, next_oni, mf); | |
| 2184 | try prev_ni.setNext(gpa, mf, next_oni); | |
| 2172 | 2185 | } else { |
| 2173 | 2186 | assert(parent_ni.first(mf).unwrap().? == first_remove_ni); |
| 2174 | 2187 | parent_ni.get(mf).first = next_oni; |
| ... | ... | @@ -2207,11 +2220,11 @@ fn addNodesToChildListBefore( |
| 2207 | 2220 | }; |
| 2208 | 2221 | |
| 2209 | 2222 | first_add_ni.get(mf).prev = prev_oni; |
| 2210 | try last_add_ni.setNext(gpa, next_oni, mf); | |
| 2223 | try last_add_ni.setNext(gpa, mf, next_oni); | |
| 2211 | 2224 | |
| 2212 | 2225 | if (prev_oni.unwrap()) |prev_ni| { |
| 2213 | 2226 | assert(prev_ni.next(mf) == next_oni); |
| 2214 | try prev_ni.setNext(gpa, .wrap(first_add_ni), mf); | |
| 2227 | try prev_ni.setNext(gpa, mf, .wrap(first_add_ni)); | |
| 2215 | 2228 | } else { |
| 2216 | 2229 | assert(parent_ni.first(mf) == next_oni); |
| 2217 | 2230 | parent_ni.get(mf).first = .wrap(first_add_ni); |
| ... | ... | @@ -2652,7 +2665,7 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void { |
| 2652 | 2665 | for (1..n) |_| cur_ni = cur_ni.next(&mf).unwrap().?; |
| 2653 | 2666 | break :prev_oni .wrap(cur_ni); |
| 2654 | 2667 | }; |
| 2655 | const new_ni = try parent_ni.addHeaderChildAfter(&mf, gpa, prev_oni, .{ | |
| 2668 | const new_ni = try parent_ni.addHeaderChildAfter(gpa, &mf, prev_oni, .{ | |
| 2656 | 2669 | .size = size, |
| 2657 | 2670 | .alignment = alignment, |
| 2658 | 2671 | }); |
| ... | ... | @@ -2660,7 +2673,7 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void { |
| 2660 | 2673 | break :new_ni new_ni; |
| 2661 | 2674 | }, |
| 2662 | 2675 | |
| 2663 | .floating => try parent_ni.addFloatingChild(&mf, gpa, .{ | |
| 2676 | .floating => try parent_ni.addFloatingChild(gpa, &mf, .{ | |
| 2664 | 2677 | .size = size, |
| 2665 | 2678 | .alignment = alignment, |
| 2666 | 2679 | }), |
| ... | ... | @@ -2674,7 +2687,7 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void { |
| 2674 | 2687 | for (1..n) |_| cur_ni = cur_ni.prev(&mf).unwrap().?; |
| 2675 | 2688 | break :next_oni .wrap(cur_ni); |
| 2676 | 2689 | }; |
| 2677 | const new_ni = try parent_ni.addFooterChildBefore(&mf, gpa, next_oni, .{ | |
| 2690 | const new_ni = try parent_ni.addFooterChildBefore(gpa, &mf, next_oni, .{ | |
| 2678 | 2691 | .size = size, |
| 2679 | 2692 | .alignment = alignment, |
| 2680 | 2693 | }); |
| ... | ... | @@ -2708,13 +2721,13 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void { |
| 2708 | 2721 | if (ni.first(&mf) == .none and smith.value(bool)) { |
| 2709 | 2722 | // Since this is a leaf node, we can use `resizeLeaf`. |
| 2710 | 2723 | const new_size = alignment.forward(smith.valueWeighted(u64, initial_size_weights)); |
| 2711 | try ni.resizeLeaf(&mf, gpa, new_size); | |
| 2724 | try ni.resizeLeaf(gpa, &mf, new_size); | |
| 2712 | 2725 | if (new_size == 0) { |
| 2713 | 2726 | node_info.initialized = false; |
| 2714 | 2727 | } |
| 2715 | 2728 | } else { |
| 2716 | 2729 | const min_size = alignment.forward(smith.valueWeighted(u64, initial_size_weights)); |
| 2717 | try ni.ensureMinimumSize(&mf, gpa, min_size); | |
| 2730 | try ni.ensureMinimumSize(gpa, &mf, min_size); | |
| 2718 | 2731 | } |
| 2719 | 2732 | |
| 2720 | 2733 | if (ni.first(&mf) == .none) { |
| ... | ... | @@ -2740,7 +2753,7 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void { |
| 2740 | 2753 | const new_alignment = smith.valueWeighted(Alignment, alignment_weights); |
| 2741 | 2754 | if (new_alignment.compare(.gt, ni.alignment(&mf))) { |
| 2742 | 2755 | _, const old_size = ni.location(&mf).resolve(&mf); |
| 2743 | try ni.realign(&mf, gpa, new_alignment); | |
| 2756 | try ni.realign(gpa, &mf, new_alignment); | |
| 2744 | 2757 | if (ni.first(&mf) == .none and nodes.get(ni).?.initialized) { |
| 2745 | 2758 | const slice = ni.slice(&mf); |
| 2746 | 2759 | @memmove(slice[slice.len - 4 ..][0..4], slice[old_size - 4 ..][0..4]); |