authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-02 17:36:56+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-30 13:44:50+01:00
log1397b95143a799d836f549448485d87a70de391c
tree6243ef5d507e7dd9f64af59aaaf835307d1fb589
parentb762cd30fd3695e6c54b81d71f9adaf7bac1e5be
signaturelock-open Commit is signed but in an unrecognized format.

std.debug.Dwarf: eliminate host pointer size dependency


3 files changed, 75 insertions(+), 75 deletions(-)

lib/std/debug/Dwarf.zig+75-71
......@@ -1,14 +1,13 @@
11//! Implements parsing, decoding, and caching of DWARF information.
22//!
3//! This API does not assume the current executable is itself the thing being
4//! debugged, however, it does assume the debug info has the same CPU
5//! architecture and OS as the current executable. It is planned to remove this
6//! limitation.
3//! This API makes no assumptions about the relationship between the host and
4//! the target being debugged. In other words, any DWARF information can be used
5//! from any host via this API. Note, however, that the limits of 32-bit
6//! addressing can cause very large 64-bit binaries to be impossible to open on
7//! 32-bit hosts.
78//!
89//! For unopinionated types and bits, see `std.dwarf`.
910
10const builtin = @import("builtin");
11
1211const std = @import("../std.zig");
1312const Allocator = std.mem.Allocator;
1413const mem = std.mem;
......@@ -57,9 +56,6 @@ pub const Range = struct {
5756
5857pub const Section = struct {
5958 data: []const u8,
60 // Module-relative virtual address.
61 // Only set if the section data was loaded from disk.
62 virtual_address: ?usize = null,
6359 // If `data` is owned by this Dwarf.
6460 owned: bool,
6561
......@@ -120,6 +116,7 @@ pub const Abbrev = struct {
120116pub const CompileUnit = struct {
121117 version: u16,
122118 format: Format,
119 addr_size_bytes: u8,
123120 die: Die,
124121 pc_range: ?PcRange,
125122
......@@ -170,7 +167,7 @@ pub const CompileUnit = struct {
170167
171168pub const FormValue = union(enum) {
172169 addr: u64,
173 addrx: usize,
170 addrx: u64,
174171 block: []const u8,
175172 udata: u64,
176173 data16: *const [16]u8,
......@@ -182,7 +179,7 @@ pub const FormValue = union(enum) {
182179 ref_addr: u64,
183180 string: [:0]const u8,
184181 strp: u64,
185 strx: usize,
182 strx: u64,
186183 line_strp: u64,
187184 loclistx: u64,
188185 rnglistx: u64,
......@@ -392,12 +389,11 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
392389 const unit_type = try fr.takeByte();
393390 if (unit_type != DW.UT.compile) return bad();
394391 address_size = try fr.takeByte();
395 debug_abbrev_offset = try readAddress(&fr, unit_header.format, endian);
392 debug_abbrev_offset = try readFormatSizedInt(&fr, unit_header.format, endian);
396393 } else {
397 debug_abbrev_offset = try readAddress(&fr, unit_header.format, endian);
394 debug_abbrev_offset = try readFormatSizedInt(&fr, unit_header.format, endian);
398395 address_size = try fr.takeByte();
399396 }
400 if (address_size != @sizeOf(usize)) return bad();
401397
402398 const abbrev_table = try di.getAbbrevTable(allocator, debug_abbrev_offset);
403399
......@@ -424,6 +420,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
424420 var compile_unit: CompileUnit = .{
425421 .version = version,
426422 .format = unit_header.format,
423 .addr_size_bytes = address_size,
427424 .die = undefined,
428425 .pc_range = null,
429426
......@@ -446,6 +443,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
446443 abbrev_table,
447444 unit_header.format,
448445 endian,
446 address_size,
449447 )) orelse continue;
450448
451449 switch (die_obj.tag_id) {
......@@ -480,6 +478,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
480478 abbrev_table, // wrong abbrev table for different cu
481479 unit_header.format,
482480 endian,
481 address_size,
483482 )) orelse return bad();
484483 } else if (this_die_obj.getAttr(AT.specification)) |_| {
485484 const after_die_offset = fr.seek;
......@@ -494,6 +493,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
494493 abbrev_table, // wrong abbrev table for different cu
495494 unit_header.format,
496495 endian,
496 address_size,
497497 )) orelse return bad();
498498 } else {
499499 break :x null;
......@@ -584,12 +584,11 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator, endian: Endian) ScanErr
584584 const unit_type = try fr.takeByte();
585585 if (unit_type != UT.compile) return bad();
586586 address_size = try fr.takeByte();
587 debug_abbrev_offset = try readAddress(&fr, unit_header.format, endian);
587 debug_abbrev_offset = try readFormatSizedInt(&fr, unit_header.format, endian);
588588 } else {
589 debug_abbrev_offset = try readAddress(&fr, unit_header.format, endian);
589 debug_abbrev_offset = try readFormatSizedInt(&fr, unit_header.format, endian);
590590 address_size = try fr.takeByte();
591591 }
592 if (address_size != @sizeOf(usize)) return bad();
593592
594593 const abbrev_table = try di.getAbbrevTable(allocator, debug_abbrev_offset);
595594
......@@ -605,6 +604,7 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator, endian: Endian) ScanErr
605604 abbrev_table,
606605 unit_header.format,
607606 endian,
607 address_size,
608608 )) orelse return bad();
609609
610610 if (compile_unit_die.tag_id != DW.TAG.compile_unit) return bad();
......@@ -614,6 +614,7 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator, endian: Endian) ScanErr
614614 var compile_unit: CompileUnit = .{
615615 .version = version,
616616 .format = unit_header.format,
617 .addr_size_bytes = address_size,
617618 .pc_range = null,
618619 .die = compile_unit_die,
619620 .str_offsets_base = if (compile_unit_die.getAttr(AT.str_offsets_base)) |fv| try fv.getUInt(usize) else 0,
......@@ -702,15 +703,15 @@ const DebugRangeIterator = struct {
702703 .rnglistx => |idx| off: {
703704 switch (compile_unit.format) {
704705 .@"32" => {
705 const offset_loc = @as(usize, @intCast(compile_unit.rnglists_base + 4 * idx));
706 const offset_loc = compile_unit.rnglists_base + 4 * idx;
706707 if (offset_loc + 4 > debug_ranges.len) return bad();
707 const offset = mem.readInt(u32, debug_ranges[offset_loc..][0..4], endian);
708 const offset = mem.readInt(u32, debug_ranges[@intCast(offset_loc)..][0..4], endian);
708709 break :off compile_unit.rnglists_base + offset;
709710 },
710711 .@"64" => {
711 const offset_loc = @as(usize, @intCast(compile_unit.rnglists_base + 8 * idx));
712 const offset_loc = compile_unit.rnglists_base + 8 * idx;
712713 if (offset_loc + 8 > debug_ranges.len) return bad();
713 const offset = mem.readInt(u64, debug_ranges[offset_loc..][0..8], endian);
714 const offset = mem.readInt(u64, debug_ranges[@intCast(offset_loc)..][0..8], endian);
714715 break :off compile_unit.rnglists_base + offset;
715716 },
716717 }
......@@ -743,21 +744,22 @@ const DebugRangeIterator = struct {
743744 // Returns the next range in the list, or null if the end was reached.
744745 pub fn next(self: *@This()) !?PcRange {
745746 const endian = self.endian;
747 const addr_size_bytes = self.compile_unit.addr_size_bytes;
746748 switch (self.section_type) {
747749 .debug_rnglists => {
748750 const kind = try self.fr.takeByte();
749751 switch (kind) {
750752 RLE.end_of_list => return null,
751753 RLE.base_addressx => {
752 const index = try self.fr.takeLeb128(usize);
754 const index = try self.fr.takeLeb128(u64);
753755 self.base_address = try self.di.readDebugAddr(endian, self.compile_unit, index);
754756 return try self.next();
755757 },
756758 RLE.startx_endx => {
757 const start_index = try self.fr.takeLeb128(usize);
759 const start_index = try self.fr.takeLeb128(u64);
758760 const start_addr = try self.di.readDebugAddr(endian, self.compile_unit, start_index);
759761
760 const end_index = try self.fr.takeLeb128(usize);
762 const end_index = try self.fr.takeLeb128(u64);
761763 const end_addr = try self.di.readDebugAddr(endian, self.compile_unit, end_index);
762764
763765 return .{
......@@ -766,10 +768,10 @@ const DebugRangeIterator = struct {
766768 };
767769 },
768770 RLE.startx_length => {
769 const start_index = try self.fr.takeLeb128(usize);
771 const start_index = try self.fr.takeLeb128(u64);
770772 const start_addr = try self.di.readDebugAddr(endian, self.compile_unit, start_index);
771773
772 const len = try self.fr.takeLeb128(usize);
774 const len = try self.fr.takeLeb128(u64);
773775 const end_addr = start_addr + len;
774776
775777 return .{
......@@ -778,8 +780,8 @@ const DebugRangeIterator = struct {
778780 };
779781 },
780782 RLE.offset_pair => {
781 const start_addr = try self.fr.takeLeb128(usize);
782 const end_addr = try self.fr.takeLeb128(usize);
783 const start_addr = try self.fr.takeLeb128(u64);
784 const end_addr = try self.fr.takeLeb128(u64);
783785
784786 // This is the only kind that uses the base address
785787 return .{
......@@ -788,12 +790,12 @@ const DebugRangeIterator = struct {
788790 };
789791 },
790792 RLE.base_address => {
791 self.base_address = try self.fr.takeInt(usize, endian);
793 self.base_address = try readAddress(&self.fr, endian, addr_size_bytes);
792794 return try self.next();
793795 },
794796 RLE.start_end => {
795 const start_addr = try self.fr.takeInt(usize, endian);
796 const end_addr = try self.fr.takeInt(usize, endian);
797 const start_addr = try readAddress(&self.fr, endian, addr_size_bytes);
798 const end_addr = try readAddress(&self.fr, endian, addr_size_bytes);
797799
798800 return .{
799801 .start = start_addr,
......@@ -801,8 +803,8 @@ const DebugRangeIterator = struct {
801803 };
802804 },
803805 RLE.start_length => {
804 const start_addr = try self.fr.takeInt(usize, endian);
805 const len = try self.fr.takeLeb128(usize);
806 const start_addr = try readAddress(&self.fr, endian, addr_size_bytes);
807 const len = try self.fr.takeLeb128(u64);
806808 const end_addr = start_addr + len;
807809
808810 return .{
......@@ -814,12 +816,13 @@ const DebugRangeIterator = struct {
814816 }
815817 },
816818 .debug_ranges => {
817 const start_addr = try self.fr.takeInt(usize, endian);
818 const end_addr = try self.fr.takeInt(usize, endian);
819 const start_addr = try readAddress(&self.fr, endian, addr_size_bytes);
820 const end_addr = try readAddress(&self.fr, endian, addr_size_bytes);
819821 if (start_addr == 0 and end_addr == 0) return null;
820822
821 // This entry selects a new value for the base address
822 if (start_addr == maxInt(usize)) {
823 // The entry with start_addr = max_representable_address selects a new value for the base address
824 const max_representable_address = ~@as(u64, 0) >> @intCast(64 - addr_size_bytes);
825 if (start_addr == max_representable_address) {
823826 self.base_address = end_addr;
824827 return try self.next();
825828 }
......@@ -921,6 +924,7 @@ fn parseDie(
921924 abbrev_table: *const Abbrev.Table,
922925 format: Format,
923926 endian: Endian,
927 addr_size_bytes: u8,
924928) ScanError!?Die {
925929 const abbrev_code = try fr.takeLeb128(u64);
926930 if (abbrev_code == 0) return null;
......@@ -929,7 +933,7 @@ fn parseDie(
929933 const attrs = attrs_buf[0..table_entry.attrs.len];
930934 for (attrs, table_entry.attrs) |*result_attr, attr| result_attr.* = .{
931935 .id = attr.id,
932 .value = try parseFormValue(fr, attr.form_id, format, endian, attr.payload),
936 .value = try parseFormValue(fr, attr.form_id, format, endian, addr_size_bytes, attr.payload),
933937 };
934938 return .{
935939 .tag_id = table_entry.tag_id,
......@@ -954,20 +958,16 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
954958 const version = try fr.takeInt(u16, endian);
955959 if (version < 2) return bad();
956960
957 const addr_size: u8, const seg_size: u8 = if (version >= 5) .{
961 const addr_size_bytes: u8, const seg_size: u8 = if (version >= 5) .{
958962 try fr.takeByte(),
959963 try fr.takeByte(),
960964 } else .{
961 switch (unit_header.format) {
962 .@"32" => 4,
963 .@"64" => 8,
964 },
965 compile_unit.addr_size_bytes,
965966 0,
966967 };
967968 if (seg_size != 0) return bad(); // unsupported
968 _ = addr_size; // TODO: ignoring this is incorrect, we should use it to decide address lengths
969969
970 const prologue_length = try readAddress(&fr, unit_header.format, endian);
970 const prologue_length = try readFormatSizedInt(&fr, unit_header.format, endian);
971971 const prog_start_offset = fr.seek + prologue_length;
972972
973973 const minimum_instruction_length = try fr.takeByte();
......@@ -1036,7 +1036,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
10361036 for (try directories.addManyAsSlice(gpa, directories_count)) |*e| {
10371037 e.* = .{ .path = &.{} };
10381038 for (dir_ent_fmt_buf[0..directory_entry_format_count]) |ent_fmt| {
1039 const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, null);
1039 const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null);
10401040 switch (ent_fmt.content_type_code) {
10411041 DW.LNCT.path => e.path = try form_value.getString(d.*),
10421042 DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32),
......@@ -1068,7 +1068,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
10681068 for (try file_entries.addManyAsSlice(gpa, file_names_count)) |*e| {
10691069 e.* = .{ .path = &.{} };
10701070 for (file_ent_fmt_buf[0..file_name_entry_format_count]) |ent_fmt| {
1071 const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, null);
1071 const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null);
10721072 switch (ent_fmt.content_type_code) {
10731073 DW.LNCT.path => e.path = try form_value.getString(d.*),
10741074 DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32),
......@@ -1117,8 +1117,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
11171117 prog.reset();
11181118 },
11191119 DW.LNE.set_address => {
1120 const addr = try fr.takeInt(usize, endian);
1121 prog.address = addr;
1120 prog.address = try readAddress(&fr, endian, addr_size_bytes);
11221121 },
11231122 DW.LNE.define_file => {
11241123 const path = try fr.takeSentinel(0);
......@@ -1150,7 +1149,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
11501149 prog.basic_block = false;
11511150 },
11521151 DW.LNS.advance_pc => {
1153 const arg = try fr.takeLeb128(usize);
1152 const arg = try fr.takeLeb128(u64);
11541153 prog.address += arg * minimum_instruction_length;
11551154 },
11561155 DW.LNS.advance_line => {
......@@ -1258,13 +1257,13 @@ fn readDebugAddr(di: Dwarf, endian: Endian, compile_unit: *const CompileUnit, in
12581257 const addr_size = debug_addr[compile_unit.addr_base - 2];
12591258 const seg_size = debug_addr[compile_unit.addr_base - 1];
12601259
1261 const byte_offset = @as(usize, @intCast(compile_unit.addr_base + (addr_size + seg_size) * index));
1260 const byte_offset = compile_unit.addr_base + (addr_size + seg_size) * index;
12621261 if (byte_offset + addr_size > debug_addr.len) return bad();
12631262 return switch (addr_size) {
1264 1 => debug_addr[byte_offset],
1265 2 => mem.readInt(u16, debug_addr[byte_offset..][0..2], endian),
1266 4 => mem.readInt(u32, debug_addr[byte_offset..][0..4], endian),
1267 8 => mem.readInt(u64, debug_addr[byte_offset..][0..8], endian),
1263 1 => debug_addr[@intCast(byte_offset)],
1264 2 => mem.readInt(u16, debug_addr[@intCast(byte_offset)..][0..2], endian),
1265 4 => mem.readInt(u32, debug_addr[@intCast(byte_offset)..][0..4], endian),
1266 8 => mem.readInt(u64, debug_addr[@intCast(byte_offset)..][0..8], endian),
12681267 else => bad(),
12691268 };
12701269}
......@@ -1274,17 +1273,18 @@ fn parseFormValue(
12741273 form_id: u64,
12751274 format: Format,
12761275 endian: Endian,
1276 addr_size_bytes: u8,
12771277 implicit_const: ?i64,
12781278) ScanError!FormValue {
12791279 return switch (form_id) {
12801280 // DWARF5.pdf page 213: the size of this value is encoded in the
12811281 // compilation unit header as address size.
1282 FORM.addr => .{ .addr = try readAddress(r, nativeFormat(), endian) },
1282 FORM.addr => .{ .addr = try readAddress(r, endian, addr_size_bytes) },
12831283 FORM.addrx1 => .{ .addrx = try r.takeByte() },
12841284 FORM.addrx2 => .{ .addrx = try r.takeInt(u16, endian) },
12851285 FORM.addrx3 => .{ .addrx = try r.takeInt(u24, endian) },
12861286 FORM.addrx4 => .{ .addrx = try r.takeInt(u32, endian) },
1287 FORM.addrx => .{ .addrx = try r.takeLeb128(usize) },
1287 FORM.addrx => .{ .addrx = try r.takeLeb128(u64) },
12881288
12891289 FORM.block1 => .{ .block = try r.take(try r.takeByte()) },
12901290 FORM.block2 => .{ .block = try r.take(try r.takeInt(u16, endian)) },
......@@ -1301,7 +1301,7 @@ fn parseFormValue(
13011301 FORM.exprloc => .{ .exprloc = try r.take(try r.takeLeb128(usize)) },
13021302 FORM.flag => .{ .flag = (try r.takeByte()) != 0 },
13031303 FORM.flag_present => .{ .flag = true },
1304 FORM.sec_offset => .{ .sec_offset = try readAddress(r, format, endian) },
1304 FORM.sec_offset => .{ .sec_offset = try readFormatSizedInt(r, format, endian) },
13051305
13061306 FORM.ref1 => .{ .ref = try r.takeByte() },
13071307 FORM.ref2 => .{ .ref = try r.takeInt(u16, endian) },
......@@ -1309,18 +1309,18 @@ fn parseFormValue(
13091309 FORM.ref8 => .{ .ref = try r.takeInt(u64, endian) },
13101310 FORM.ref_udata => .{ .ref = try r.takeLeb128(u64) },
13111311
1312 FORM.ref_addr => .{ .ref_addr = try readAddress(r, format, endian) },
1312 FORM.ref_addr => .{ .ref_addr = try readFormatSizedInt(r, format, endian) },
13131313 FORM.ref_sig8 => .{ .ref = try r.takeInt(u64, endian) },
13141314
13151315 FORM.string => .{ .string = try r.takeSentinel(0) },
1316 FORM.strp => .{ .strp = try readAddress(r, format, endian) },
1316 FORM.strp => .{ .strp = try readFormatSizedInt(r, format, endian) },
13171317 FORM.strx1 => .{ .strx = try r.takeByte() },
13181318 FORM.strx2 => .{ .strx = try r.takeInt(u16, endian) },
13191319 FORM.strx3 => .{ .strx = try r.takeInt(u24, endian) },
13201320 FORM.strx4 => .{ .strx = try r.takeInt(u32, endian) },
13211321 FORM.strx => .{ .strx = try r.takeLeb128(usize) },
1322 FORM.line_strp => .{ .line_strp = try readAddress(r, format, endian) },
1323 FORM.indirect => parseFormValue(r, try r.takeLeb128(u64), format, endian, implicit_const),
1322 FORM.line_strp => .{ .line_strp = try readFormatSizedInt(r, format, endian) },
1323 FORM.indirect => parseFormValue(r, try r.takeLeb128(u64), format, endian, addr_size_bytes, implicit_const),
13241324 FORM.implicit_const => .{ .sdata = implicit_const orelse return bad() },
13251325 FORM.loclistx => .{ .loclistx = try r.takeLeb128(u64) },
13261326 FORM.rnglistx => .{ .rnglistx = try r.takeLeb128(u64) },
......@@ -1464,20 +1464,24 @@ pub fn getSymbol(di: *Dwarf, allocator: Allocator, endian: Endian, address: u64)
14641464 };
14651465}
14661466
1467fn readAddress(r: *Reader, format: std.dwarf.Format, endian: Endian) !u64 {
1468 // MLUGG TODO FIX BEFORE MERGE: this function is slightly bogus. addresses have a byte width which is independent of the `dwarf.Format`!
1467/// DWARF5 7.4: "In the 32-bit DWARF format, all values that represent lengths of DWARF sections and
1468/// offsets relative to the beginning of DWARF sections are represented using four bytes. In the
1469/// 64-bit DWARF format, all values that represent lengths of DWARF sections and offsets relative to
1470/// the beginning of DWARF sections are represented using eight bytes".
1471///
1472/// This function is for reading such values.
1473fn readFormatSizedInt(r: *Reader, format: std.dwarf.Format, endian: Endian) !u64 {
14691474 return switch (format) {
14701475 .@"32" => try r.takeInt(u32, endian),
14711476 .@"64" => try r.takeInt(u64, endian),
14721477 };
14731478}
14741479
1475fn nativeFormat() std.dwarf.Format {
1476 // MLUGG TODO FIX BEFORE MERGE: this is nonsensical. this is neither what `dwarf.Format` is for, nor does it make sense to check the NATIVE FUCKING FORMAT
1477 // when parsing ARBITRARY DWARF.
1478 return switch (@sizeOf(usize)) {
1479 4 => .@"32",
1480 8 => .@"64",
1481 else => @compileError("unsupported @sizeOf(usize)"),
1480fn readAddress(r: *Reader, endian: Endian, addr_size_bytes: u8) !u64 {
1481 return switch (addr_size_bytes) {
1482 2 => try r.takeInt(u16, endian),
1483 4 => try r.takeInt(u32, endian),
1484 8 => try r.takeInt(u64, endian),
1485 else => return bad(),
14821486 };
14831487}
lib/std/debug/Dwarf/ElfModule.zig-2
......@@ -155,12 +155,10 @@ pub fn load(
155155 }
156156 break :blk .{
157157 .data = try decompressed_section.toOwnedSlice(gpa),
158 .virtual_address = shdr.sh_addr,
159158 .owned = true,
160159 };
161160 } else .{
162161 .data = section_bytes,
163 .virtual_address = shdr.sh_addr,
164162 .owned = false,
165163 };
166164 }
lib/std/debug/SelfInfo.zig-2
......@@ -465,7 +465,6 @@ const Module = switch (native_os) {
465465 const section_bytes = mapped_mem[sect.offset..][0..sect.size];
466466 sections[section_index] = .{
467467 .data = section_bytes,
468 .virtual_address = @intCast(sect.addr),
469468 .owned = false,
470469 };
471470 }
......@@ -751,7 +750,6 @@ const Module = switch (native_os) {
751750 di.dwarf.?.sections[i] = if (coff_obj.getSectionByName("." ++ section.name)) |section_header| blk: {
752751 break :blk .{
753752 .data = try coff_obj.getSectionDataAlloc(section_header, gpa),
754 .virtual_address = section_header.virtual_address,
755753 .owned = true,
756754 };
757755 } else null;