authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-18 23:14:23+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-19 21:56:47+02:00
log400faec10beed6c146bc562efab146be258471d7
tree19490d9fd5a0b66de4cb79974fc805d6c465314f
parent4f66efdc7f2158330b73f40a44b1f16b43c5318a

dwarf: introduce Dwarf.Format to be able to select 32/64bit format at whim


4 files changed, 115 insertions(+), 169 deletions(-)

src/link/Dwarf.zig+112-166
......@@ -1,32 +1,7 @@
1const Dwarf = @This();
2
3const std = @import("std");
4const builtin = @import("builtin");
5const assert = std.debug.assert;
6const fs = std.fs;
7const leb128 = std.leb;
8const log = std.log.scoped(.dwarf);
9const mem = std.mem;
10
11const link = @import("../link.zig");
12const trace = @import("../tracy.zig").trace;
13
14const Allocator = mem.Allocator;
15const DW = std.dwarf;
16const File = link.File;
17const LinkBlock = File.LinkBlock;
18const LinkFn = File.LinkFn;
19const LinkerLoad = @import("../codegen.zig").LinkerLoad;
20const Module = @import("../Module.zig");
21const InternPool = @import("../InternPool.zig");
22const StringTable = @import("strtab.zig").StringTable;
23const Type = @import("../type.zig").Type;
24const Value = @import("../value.zig").Value;
25
261allocator: Allocator,
272bin_file: *File,
3format: Format,
284ptr_width: PtrWidth,
29target: std.Target,
305
316/// A list of `Atom`s whose Line Number Programs have surplus capacity.
327/// This is the same concept as `Section.free_list` in Elf; see those doc comments.
......@@ -983,17 +958,17 @@ const min_nop_size = 2;
983958/// actual_capacity + (actual_capacity / ideal_factor)
984959const ideal_factor = 3;
985960
986pub fn init(allocator: Allocator, bin_file: *File, target: std.Target) Dwarf {
987 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
961pub fn init(allocator: Allocator, bin_file: *File, format: Format) Dwarf {
962 const ptr_width: PtrWidth = switch (bin_file.options.target.ptrBitWidth()) {
988963 0...32 => .p32,
989964 33...64 => .p64,
990965 else => unreachable,
991966 };
992 return Dwarf{
967 return .{
993968 .allocator = allocator,
994969 .bin_file = bin_file,
970 .format = format,
995971 .ptr_width = ptr_width,
996 .target = target,
997972 };
998973}
999974
......@@ -1129,7 +1104,7 @@ pub fn commitDeclState(
11291104 const decl = mod.declPtr(decl_index);
11301105 const ip = &mod.intern_pool;
11311106
1132 const target_endian = self.target.cpu.arch.endian();
1107 const target_endian = self.bin_file.options.target.cpu.arch.endian();
11331108
11341109 assert(decl.has_tv);
11351110 switch (decl.ty.zigTypeTag(mod)) {
......@@ -1837,12 +1812,10 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
18371812 var di_buf = try std.ArrayList(u8).initCapacity(self.allocator, needed_bytes);
18381813 defer di_buf.deinit();
18391814
1840 const target_endian = self.target.cpu.arch.endian();
1841 const init_len_size: usize = if (self.bin_file.tag == .macho)
1842 4
1843 else switch (self.ptr_width) {
1844 .p32 => @as(usize, 4),
1845 .p64 => 12,
1815 const target_endian = self.bin_file.options.target.cpu.arch.endian();
1816 const init_len_size: usize = switch (self.format) {
1817 .dwarf32 => 4,
1818 .dwarf64 => 12,
18461819 };
18471820
18481821 // initial length - length of the .debug_info contribution for this compilation unit,
......@@ -1851,32 +1824,16 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
18511824 const after_init_len = di_buf.items.len + init_len_size;
18521825 const dbg_info_end = self.getDebugInfoEnd().?;
18531826 const init_len = dbg_info_end - after_init_len;
1854 if (self.bin_file.tag == .macho) {
1855 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(init_len)));
1856 } else switch (self.ptr_width) {
1857 .p32 => {
1858 mem.writeInt(u32, di_buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(init_len)), target_endian);
1859 },
1860 .p64 => {
1861 di_buf.appendNTimesAssumeCapacity(0xff, 4);
1862 mem.writeInt(u64, di_buf.addManyAsArrayAssumeCapacity(8), init_len, target_endian);
1863 },
1864 }
1827
1828 if (self.format == .dwarf64) di_buf.appendNTimesAssumeCapacity(0xff, 4);
1829 self.writeOffsetAssumeCapacity(&di_buf, init_len);
1830
18651831 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 4, target_endian); // DWARF version
18661832 const abbrev_offset = self.abbrev_table_offset.?;
1867 if (self.bin_file.tag == .macho) {
1868 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(abbrev_offset)));
1869 di_buf.appendAssumeCapacity(8); // address size
1870 } else switch (self.ptr_width) {
1871 .p32 => {
1872 mem.writeInt(u32, di_buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(abbrev_offset)), target_endian);
1873 di_buf.appendAssumeCapacity(4); // address size
1874 },
1875 .p64 => {
1876 mem.writeInt(u64, di_buf.addManyAsArrayAssumeCapacity(8), abbrev_offset, target_endian);
1877 di_buf.appendAssumeCapacity(8); // address size
1878 },
1879 }
1833
1834 self.writeOffsetAssumeCapacity(&di_buf, abbrev_offset);
1835 di_buf.appendAssumeCapacity(self.ptrWidthBytes()); // address size
1836
18801837 // Write the form for the compile unit, which must match the abbrev table above.
18811838 const name_strp = try self.strtab.insert(self.allocator, module.root_mod.root_src_path);
18821839 var compile_unit_dir_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
......@@ -1885,21 +1842,13 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
18851842 const producer_strp = try self.strtab.insert(self.allocator, link.producer_string);
18861843
18871844 di_buf.appendAssumeCapacity(@intFromEnum(AbbrevKind.compile_unit));
1888 if (self.bin_file.tag == .macho) {
1889 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT.stmt_list, DW.FORM.sec_offset
1890 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc);
1891 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), high_pc);
1892 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(name_strp)));
1893 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(comp_dir_strp)));
1894 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(producer_strp)));
1895 } else {
1896 self.writeAddrAssumeCapacity(&di_buf, 0); // DW.AT.stmt_list, DW.FORM.sec_offset
1897 self.writeAddrAssumeCapacity(&di_buf, low_pc);
1898 self.writeAddrAssumeCapacity(&di_buf, high_pc);
1899 self.writeAddrAssumeCapacity(&di_buf, name_strp);
1900 self.writeAddrAssumeCapacity(&di_buf, comp_dir_strp);
1901 self.writeAddrAssumeCapacity(&di_buf, producer_strp);
1902 }
1845 self.writeOffsetAssumeCapacity(&di_buf, 0); // DW.AT.stmt_list, DW.FORM.sec_offset
1846 self.writeAddrAssumeCapacity(&di_buf, low_pc);
1847 self.writeAddrAssumeCapacity(&di_buf, high_pc);
1848 self.writeOffsetAssumeCapacity(&di_buf, name_strp);
1849 self.writeOffsetAssumeCapacity(&di_buf, comp_dir_strp);
1850 self.writeOffsetAssumeCapacity(&di_buf, producer_strp);
1851
19031852 // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number:
19041853 // http://dwarfstd.org/ShowIssue.php?issue=171115.1
19051854 // Until then we say it is C99.
......@@ -1952,13 +1901,26 @@ fn resolveCompilationDir(module: *Module, buffer: *[std.fs.MAX_PATH_BYTES]u8) []
19521901}
19531902
19541903fn writeAddrAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), addr: u64) void {
1955 const target_endian = self.target.cpu.arch.endian();
1904 const target_endian = self.bin_file.options.target.cpu.arch.endian();
19561905 switch (self.ptr_width) {
19571906 .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(addr)), target_endian),
19581907 .p64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), addr, target_endian),
19591908 }
19601909}
19611910
1911fn writeOffsetAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), off: u64) void {
1912 const target_endian = self.bin_file.options.target.cpu.arch.endian();
1913 switch (self.format) {
1914 .dwarf32 => mem.writeInt(
1915 u32,
1916 buf.addManyAsArrayAssumeCapacity(4),
1917 @as(u32, @intCast(off)),
1918 target_endian,
1919 ),
1920 .dwarf64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), off, target_endian),
1921 }
1922}
1923
19621924/// Writes to the file a buffer, prefixed and suffixed by the specified number of
19631925/// bytes of NOPs. Asserts each padding size is at least `min_nop_size` and total padding bytes
19641926/// are less than 1044480 bytes (if this limit is ever reached, this function can be
......@@ -2174,13 +2136,7 @@ fn writeDbgInfoNopsToArrayList(
21742136}
21752137
21762138pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
2177 const target_endian = self.target.cpu.arch.endian();
2178 const init_len_size: usize = if (self.bin_file.tag == .macho)
2179 4
2180 else switch (self.ptr_width) {
2181 .p32 => @as(usize, 4),
2182 .p64 => 12,
2183 };
2139 const target_endian = self.bin_file.options.target.cpu.arch.endian();
21842140 const ptr_width_bytes = self.ptrWidthBytes();
21852141
21862142 // Enough for all the data without resizing. When support for more compilation units
......@@ -2191,17 +2147,15 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
21912147 // initial length - length of the .debug_aranges contribution for this compilation unit,
21922148 // not including the initial length itself.
21932149 // We have to come back and write it later after we know the size.
2150 if (self.format == .dwarf64) di_buf.appendNTimesAssumeCapacity(0xff, 4);
21942151 const init_len_index = di_buf.items.len;
2195 di_buf.items.len += init_len_size;
2152 self.writeOffsetAssumeCapacity(&di_buf, 0);
21962153 const after_init_len = di_buf.items.len;
21972154 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 2, target_endian); // version
2155
21982156 // When more than one compilation unit is supported, this will be the offset to it.
21992157 // For now it is always at offset 0 in .debug_info.
2200 if (self.bin_file.tag == .macho) {
2201 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // __debug_info offset
2202 } else {
2203 self.writeAddrAssumeCapacity(&di_buf, 0); // .debug_info offset
2204 }
2158 self.writeOffsetAssumeCapacity(&di_buf, 0); // .debug_info offset
22052159 di_buf.appendAssumeCapacity(ptr_width_bytes); // address_size
22062160 di_buf.appendAssumeCapacity(0); // segment_selector_size
22072161
......@@ -2220,18 +2174,14 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
22202174
22212175 // Go back and populate the initial length.
22222176 const init_len = di_buf.items.len - after_init_len;
2223 if (self.bin_file.tag == .macho) {
2224 mem.writeIntLittle(u32, di_buf.items[init_len_index..][0..4], @as(u32, @intCast(init_len)));
2225 } else switch (self.ptr_width) {
2226 .p32 => {
2227 mem.writeInt(u32, di_buf.items[init_len_index..][0..4], @as(u32, @intCast(init_len)), target_endian);
2228 },
2229 .p64 => {
2230 // initial length - length of the .debug_aranges contribution for this compilation unit,
2231 // not including the initial length itself.
2232 di_buf.items[init_len_index..][0..4].* = [_]u8{ 0xff, 0xff, 0xff, 0xff };
2233 mem.writeInt(u64, di_buf.items[init_len_index + 4 ..][0..8], init_len, target_endian);
2234 },
2177 switch (self.format) {
2178 .dwarf32 => mem.writeInt(
2179 u32,
2180 di_buf.items[init_len_index..][0..4],
2181 @as(u32, @intCast(init_len)),
2182 target_endian,
2183 ),
2184 .dwarf64 => mem.writeInt(u64, di_buf.items[init_len_index..][0..8], init_len, target_endian),
22352185 }
22362186
22372187 const needed_size = @as(u32, @intCast(di_buf.items.len));
......@@ -2265,12 +2215,10 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
22652215pub fn writeDbgLineHeader(self: *Dwarf) !void {
22662216 const gpa = self.allocator;
22672217
2268 const target_endian = self.target.cpu.arch.endian();
2269 const init_len_size: usize = if (self.bin_file.tag == .macho)
2270 4
2271 else switch (self.ptr_width) {
2272 .p32 => @as(usize, 4),
2273 .p64 => 12,
2218 const target_endian = self.bin_file.options.target.cpu.arch.endian();
2219 const init_len_size: usize = switch (self.format) {
2220 .dwarf32 => 4,
2221 .dwarf64 => 12,
22742222 };
22752223
22762224 const dbg_line_prg_off = self.getDebugLineProgramOff() orelse return;
......@@ -2288,20 +2236,8 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
22882236 var di_buf = try std.ArrayList(u8).initCapacity(gpa, needed_bytes);
22892237 defer di_buf.deinit();
22902238
2291 switch (self.bin_file.tag) {
2292 .macho => {
2293 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @as(u32, 0));
2294 },
2295 else => switch (self.ptr_width) {
2296 .p32 => {
2297 mem.writeInt(u32, di_buf.addManyAsArrayAssumeCapacity(4), @as(u32, 0), target_endian);
2298 },
2299 .p64 => {
2300 di_buf.appendNTimesAssumeCapacity(0xff, 4);
2301 mem.writeInt(u64, di_buf.addManyAsArrayAssumeCapacity(8), @as(u64, 0), target_endian);
2302 },
2303 },
2304 }
2239 if (self.format == .dwarf64) di_buf.appendNTimesAssumeCapacity(0xff, 4);
2240 self.writeOffsetAssumeCapacity(&di_buf, 0);
23052241
23062242 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 4, target_endian); // version
23072243
......@@ -2310,16 +2246,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
23102246 // Therefore we rely on the NOP jump at the beginning of the Line Number Program for
23112247 // padding rather than this field.
23122248 const before_header_len = di_buf.items.len;
2313
2314 // We will come back and write this.
2315 switch (self.bin_file.tag) {
2316 .macho => di_buf.appendNTimesAssumeCapacity(0, 4),
2317 else => switch (self.ptr_width) {
2318 .p32 => di_buf.appendNTimesAssumeCapacity(0, 4),
2319 .p64 => di_buf.appendNTimesAssumeCapacity(0, 8),
2320 },
2321 }
2322
2249 self.writeOffsetAssumeCapacity(&di_buf, 0); // We will come back and write this.
23232250 const after_header_len = di_buf.items.len;
23242251
23252252 const opcode_base = DW.LNS.set_isa + 1;
......@@ -2372,19 +2299,14 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
23722299 di_buf.appendAssumeCapacity(0); // file names sentinel
23732300
23742301 const header_len = di_buf.items.len - after_header_len;
2375
2376 switch (self.bin_file.tag) {
2377 .macho => {
2378 mem.writeIntLittle(u32, di_buf.items[before_header_len..][0..4], @as(u32, @intCast(header_len)));
2379 },
2380 else => switch (self.ptr_width) {
2381 .p32 => {
2382 mem.writeInt(u32, di_buf.items[before_header_len..][0..4], @as(u32, @intCast(header_len)), target_endian);
2383 },
2384 .p64 => {
2385 mem.writeInt(u64, di_buf.items[before_header_len..][0..8], header_len, target_endian);
2386 },
2387 },
2302 switch (self.format) {
2303 .dwarf32 => mem.writeInt(
2304 u32,
2305 di_buf.items[before_header_len..][0..4],
2306 @as(u32, @intCast(header_len)),
2307 target_endian,
2308 ),
2309 .dwarf64 => mem.writeInt(u64, di_buf.items[before_header_len..][0..8], header_len, target_endian),
23882310 }
23892311
23902312 assert(needed_bytes == di_buf.items.len);
......@@ -2453,17 +2375,12 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
24532375
24542376 // Backpatch actual length of the debug line program
24552377 const init_len = self.getDebugLineProgramEnd().? - init_len_size;
2456 switch (self.bin_file.tag) {
2457 .macho => {
2458 mem.writeIntLittle(u32, di_buf.items[0..4], @as(u32, @intCast(init_len)));
2378 switch (self.format) {
2379 .dwarf32 => {
2380 mem.writeInt(u32, di_buf.items[0..4], @as(u32, @intCast(init_len)), target_endian);
24592381 },
2460 else => switch (self.ptr_width) {
2461 .p32 => {
2462 mem.writeInt(u32, di_buf.items[0..4], @as(u32, @intCast(init_len)), target_endian);
2463 },
2464 .p64 => {
2465 mem.writeInt(u64, di_buf.items[4..][0..8], init_len, target_endian);
2466 },
2382 .dwarf64 => {
2383 mem.writeInt(u64, di_buf.items[4..][0..8], init_len, target_endian);
24672384 },
24682385 }
24692386
......@@ -2524,17 +2441,14 @@ fn ptrWidthBytes(self: Dwarf) u8 {
25242441}
25252442
25262443fn dbgLineNeededHeaderBytes(self: Dwarf, dirs: []const []const u8, files: []const []const u8) u32 {
2527 var size = switch (self.bin_file.tag) { // length field
2528 .macho => @sizeOf(u32),
2529 else => switch (self.ptr_width) {
2530 .p32 => @as(usize, @sizeOf(u32)),
2531 .p64 => @sizeOf(u32) + @sizeOf(u64),
2532 },
2444 var size: usize = switch (self.format) { // length field
2445 .dwarf32 => @as(usize, 4),
2446 .dwarf64 => 12,
25332447 };
25342448 size += @sizeOf(u16); // version field
2535 size += switch (self.bin_file.tag) { // offset to end-of-header
2536 .macho => @sizeOf(u32),
2537 else => self.ptrWidthBytes(),
2449 size += switch (self.format) { // offset to end-of-header
2450 .dwarf32 => @as(usize, 4),
2451 .dwarf64 => 8,
25382452 };
25392453 size += 18; // opcodes
25402454
......@@ -2570,6 +2484,8 @@ fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
25702484}
25712485
25722486pub fn flushModule(self: *Dwarf, module: *Module) !void {
2487 const target = self.bin_file.options.target;
2488
25732489 if (self.global_abbrev_relocs.items.len > 0) {
25742490 const gpa = self.allocator;
25752491 var arena_alloc = std.heap.ArenaAllocator.init(gpa);
......@@ -2581,7 +2497,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
25812497 module,
25822498 Type.anyerror,
25832499 module.global_error_set.keys(),
2584 self.target,
2500 target,
25852501 &dbg_info_buffer,
25862502 );
25872503
......@@ -2610,7 +2526,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
26102526 };
26112527
26122528 var buf: [@sizeOf(u32)]u8 = undefined;
2613 mem.writeInt(u32, &buf, self.getAtom(.di_atom, di_atom_index).off, self.target.cpu.arch.endian());
2529 mem.writeInt(u32, &buf, self.getAtom(.di_atom, di_atom_index).off, target.cpu.arch.endian());
26142530
26152531 while (self.global_abbrev_relocs.popOrNull()) |reloc| {
26162532 const atom = self.getAtom(.di_atom, reloc.atom_index);
......@@ -2805,3 +2721,33 @@ fn getAtomPtr(self: *Dwarf, comptime kind: Kind, index: Atom.Index) *Atom {
28052721 .di_atom => &self.di_atoms.items[index],
28062722 };
28072723}
2724
2725pub const Format = enum {
2726 dwarf32,
2727 dwarf64,
2728};
2729
2730const Dwarf = @This();
2731
2732const std = @import("std");
2733const builtin = @import("builtin");
2734const assert = std.debug.assert;
2735const fs = std.fs;
2736const leb128 = std.leb;
2737const log = std.log.scoped(.dwarf);
2738const mem = std.mem;
2739
2740const link = @import("../link.zig");
2741const trace = @import("../tracy.zig").trace;
2742
2743const Allocator = mem.Allocator;
2744const DW = std.dwarf;
2745const File = link.File;
2746const LinkBlock = File.LinkBlock;
2747const LinkFn = File.LinkFn;
2748const LinkerLoad = @import("../codegen.zig").LinkerLoad;
2749const Module = @import("../Module.zig");
2750const InternPool = @import("../InternPool.zig");
2751const StringTable = @import("strtab.zig").StringTable;
2752const Type = @import("../type.zig").Type;
2753const Value = @import("../value.zig").Value;
src/link/Elf.zig+1-1
......@@ -310,7 +310,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
310310
311311 if (options.module != null and !options.use_llvm) {
312312 if (!options.strip) {
313 self.dwarf = Dwarf.init(allocator, &self.base, options.target);
313 self.dwarf = Dwarf.init(allocator, &self.base, .dwarf32);
314314 }
315315
316316 const index = @as(File.Index, @intCast(try self.files.addOne(allocator)));
src/link/MachO.zig+1-1
......@@ -206,7 +206,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
206206
207207 self.d_sym = .{
208208 .allocator = allocator,
209 .dwarf = link.File.Dwarf.init(allocator, &self.base, options.target),
209 .dwarf = link.File.Dwarf.init(allocator, &self.base, .dwarf32),
210210 .file = d_sym_file,
211211 };
212212 }
src/link/Wasm.zig+1-1
......@@ -507,7 +507,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
507507 }
508508
509509 // if (!options.strip and options.module != null) {
510 // wasm_bin.dwarf = Dwarf.init(allocator, &wasm_bin.base, options.target);
510 // wasm_bin.dwarf = Dwarf.init(allocator, &wasm_bin.base, .dwarf32);
511511 // try wasm_bin.initDebugSections();
512512 // }
513513