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 @@...@@ -1,14 +1,13 @@
1//! Implements parsing, decoding, and caching of DWARF information.1//! Implements parsing, decoding, and caching of DWARF information.
2//!2//!
3//! This API does not assume the current executable is itself the thing being3//! This API makes no assumptions about the relationship between the host and
4//! debugged, however, it does assume the debug info has the same CPU4//! the target being debugged. In other words, any DWARF information can be used
5//! architecture and OS as the current executable. It is planned to remove this5//! from any host via this API. Note, however, that the limits of 32-bit
6//! limitation.6//! addressing can cause very large 64-bit binaries to be impossible to open on
7//! 32-bit hosts.
7//!8//!
8//! For unopinionated types and bits, see `std.dwarf`.9//! For unopinionated types and bits, see `std.dwarf`.
910
10const builtin = @import("builtin");
11
12const std = @import("../std.zig");11const std = @import("../std.zig");
13const Allocator = std.mem.Allocator;12const Allocator = std.mem.Allocator;
14const mem = std.mem;13const mem = std.mem;
...@@ -57,9 +56,6 @@ pub const Range = struct {...@@ -57,9 +56,6 @@ pub const Range = struct {
5756
58pub const Section = struct {57pub const Section = struct {
59 data: []const u8,58 data: []const u8,
60 // Module-relative virtual address.
61 // Only set if the section data was loaded from disk.
62 virtual_address: ?usize = null,
63 // If `data` is owned by this Dwarf.59 // If `data` is owned by this Dwarf.
64 owned: bool,60 owned: bool,
6561
...@@ -120,6 +116,7 @@ pub const Abbrev = struct {...@@ -120,6 +116,7 @@ pub const Abbrev = struct {
120pub const CompileUnit = struct {116pub const CompileUnit = struct {
121 version: u16,117 version: u16,
122 format: Format,118 format: Format,
119 addr_size_bytes: u8,
123 die: Die,120 die: Die,
124 pc_range: ?PcRange,121 pc_range: ?PcRange,
125122
...@@ -170,7 +167,7 @@ pub const CompileUnit = struct {...@@ -170,7 +167,7 @@ pub const CompileUnit = struct {
170167
171pub const FormValue = union(enum) {168pub const FormValue = union(enum) {
172 addr: u64,169 addr: u64,
173 addrx: usize,170 addrx: u64,
174 block: []const u8,171 block: []const u8,
175 udata: u64,172 udata: u64,
176 data16: *const [16]u8,173 data16: *const [16]u8,
...@@ -182,7 +179,7 @@ pub const FormValue = union(enum) {...@@ -182,7 +179,7 @@ pub const FormValue = union(enum) {
182 ref_addr: u64,179 ref_addr: u64,
183 string: [:0]const u8,180 string: [:0]const u8,
184 strp: u64,181 strp: u64,
185 strx: usize,182 strx: u64,
186 line_strp: u64,183 line_strp: u64,
187 loclistx: u64,184 loclistx: u64,
188 rnglistx: u64,185 rnglistx: u64,
...@@ -392,12 +389,11 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!...@@ -392,12 +389,11 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
392 const unit_type = try fr.takeByte();389 const unit_type = try fr.takeByte();
393 if (unit_type != DW.UT.compile) return bad();390 if (unit_type != DW.UT.compile) return bad();
394 address_size = try fr.takeByte();391 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);
396 } else {393 } else {
397 debug_abbrev_offset = try readAddress(&fr, unit_header.format, endian);394 debug_abbrev_offset = try readFormatSizedInt(&fr, unit_header.format, endian);
398 address_size = try fr.takeByte();395 address_size = try fr.takeByte();
399 }396 }
400 if (address_size != @sizeOf(usize)) return bad();
401397
402 const abbrev_table = try di.getAbbrevTable(allocator, debug_abbrev_offset);398 const abbrev_table = try di.getAbbrevTable(allocator, debug_abbrev_offset);
403399
...@@ -424,6 +420,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!...@@ -424,6 +420,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
424 var compile_unit: CompileUnit = .{420 var compile_unit: CompileUnit = .{
425 .version = version,421 .version = version,
426 .format = unit_header.format,422 .format = unit_header.format,
423 .addr_size_bytes = address_size,
427 .die = undefined,424 .die = undefined,
428 .pc_range = null,425 .pc_range = null,
429426
...@@ -446,6 +443,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!...@@ -446,6 +443,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
446 abbrev_table,443 abbrev_table,
447 unit_header.format,444 unit_header.format,
448 endian,445 endian,
446 address_size,
449 )) orelse continue;447 )) orelse continue;
450448
451 switch (die_obj.tag_id) {449 switch (die_obj.tag_id) {
...@@ -480,6 +478,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!...@@ -480,6 +478,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
480 abbrev_table, // wrong abbrev table for different cu478 abbrev_table, // wrong abbrev table for different cu
481 unit_header.format,479 unit_header.format,
482 endian,480 endian,
481 address_size,
483 )) orelse return bad();482 )) orelse return bad();
484 } else if (this_die_obj.getAttr(AT.specification)) |_| {483 } else if (this_die_obj.getAttr(AT.specification)) |_| {
485 const after_die_offset = fr.seek;484 const after_die_offset = fr.seek;
...@@ -494,6 +493,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!...@@ -494,6 +493,7 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator, endian: Endian) ScanError!
494 abbrev_table, // wrong abbrev table for different cu493 abbrev_table, // wrong abbrev table for different cu
495 unit_header.format,494 unit_header.format,
496 endian,495 endian,
496 address_size,
497 )) orelse return bad();497 )) orelse return bad();
498 } else {498 } else {
499 break :x null;499 break :x null;
...@@ -584,12 +584,11 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator, endian: Endian) ScanErr...@@ -584,12 +584,11 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator, endian: Endian) ScanErr
584 const unit_type = try fr.takeByte();584 const unit_type = try fr.takeByte();
585 if (unit_type != UT.compile) return bad();585 if (unit_type != UT.compile) return bad();
586 address_size = try fr.takeByte();586 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);
588 } else {588 } else {
589 debug_abbrev_offset = try readAddress(&fr, unit_header.format, endian);589 debug_abbrev_offset = try readFormatSizedInt(&fr, unit_header.format, endian);
590 address_size = try fr.takeByte();590 address_size = try fr.takeByte();
591 }591 }
592 if (address_size != @sizeOf(usize)) return bad();
593592
594 const abbrev_table = try di.getAbbrevTable(allocator, debug_abbrev_offset);593 const abbrev_table = try di.getAbbrevTable(allocator, debug_abbrev_offset);
595594
...@@ -605,6 +604,7 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator, endian: Endian) ScanErr...@@ -605,6 +604,7 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator, endian: Endian) ScanErr
605 abbrev_table,604 abbrev_table,
606 unit_header.format,605 unit_header.format,
607 endian,606 endian,
607 address_size,
608 )) orelse return bad();608 )) orelse return bad();
609609
610 if (compile_unit_die.tag_id != DW.TAG.compile_unit) return bad();610 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...@@ -614,6 +614,7 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator, endian: Endian) ScanErr
614 var compile_unit: CompileUnit = .{614 var compile_unit: CompileUnit = .{
615 .version = version,615 .version = version,
616 .format = unit_header.format,616 .format = unit_header.format,
617 .addr_size_bytes = address_size,
617 .pc_range = null,618 .pc_range = null,
618 .die = compile_unit_die,619 .die = compile_unit_die,
619 .str_offsets_base = if (compile_unit_die.getAttr(AT.str_offsets_base)) |fv| try fv.getUInt(usize) else 0,620 .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 {...@@ -702,15 +703,15 @@ const DebugRangeIterator = struct {
702 .rnglistx => |idx| off: {703 .rnglistx => |idx| off: {
703 switch (compile_unit.format) {704 switch (compile_unit.format) {
704 .@"32" => {705 .@"32" => {
705 const offset_loc = @as(usize, @intCast(compile_unit.rnglists_base + 4 * idx));706 const offset_loc = compile_unit.rnglists_base + 4 * idx;
706 if (offset_loc + 4 > debug_ranges.len) return bad();707 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);
708 break :off compile_unit.rnglists_base + offset;709 break :off compile_unit.rnglists_base + offset;
709 },710 },
710 .@"64" => {711 .@"64" => {
711 const offset_loc = @as(usize, @intCast(compile_unit.rnglists_base + 8 * idx));712 const offset_loc = compile_unit.rnglists_base + 8 * idx;
712 if (offset_loc + 8 > debug_ranges.len) return bad();713 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);
714 break :off compile_unit.rnglists_base + offset;715 break :off compile_unit.rnglists_base + offset;
715 },716 },
716 }717 }
...@@ -743,21 +744,22 @@ const DebugRangeIterator = struct {...@@ -743,21 +744,22 @@ const DebugRangeIterator = struct {
743 // Returns the next range in the list, or null if the end was reached.744 // Returns the next range in the list, or null if the end was reached.
744 pub fn next(self: *@This()) !?PcRange {745 pub fn next(self: *@This()) !?PcRange {
745 const endian = self.endian;746 const endian = self.endian;
747 const addr_size_bytes = self.compile_unit.addr_size_bytes;
746 switch (self.section_type) {748 switch (self.section_type) {
747 .debug_rnglists => {749 .debug_rnglists => {
748 const kind = try self.fr.takeByte();750 const kind = try self.fr.takeByte();
749 switch (kind) {751 switch (kind) {
750 RLE.end_of_list => return null,752 RLE.end_of_list => return null,
751 RLE.base_addressx => {753 RLE.base_addressx => {
752 const index = try self.fr.takeLeb128(usize);754 const index = try self.fr.takeLeb128(u64);
753 self.base_address = try self.di.readDebugAddr(endian, self.compile_unit, index);755 self.base_address = try self.di.readDebugAddr(endian, self.compile_unit, index);
754 return try self.next();756 return try self.next();
755 },757 },
756 RLE.startx_endx => {758 RLE.startx_endx => {
757 const start_index = try self.fr.takeLeb128(usize);759 const start_index = try self.fr.takeLeb128(u64);
758 const start_addr = try self.di.readDebugAddr(endian, self.compile_unit, start_index);760 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);
761 const end_addr = try self.di.readDebugAddr(endian, self.compile_unit, end_index);763 const end_addr = try self.di.readDebugAddr(endian, self.compile_unit, end_index);
762764
763 return .{765 return .{
...@@ -766,10 +768,10 @@ const DebugRangeIterator = struct {...@@ -766,10 +768,10 @@ const DebugRangeIterator = struct {
766 };768 };
767 },769 },
768 RLE.startx_length => {770 RLE.startx_length => {
769 const start_index = try self.fr.takeLeb128(usize);771 const start_index = try self.fr.takeLeb128(u64);
770 const start_addr = try self.di.readDebugAddr(endian, self.compile_unit, start_index);772 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);
773 const end_addr = start_addr + len;775 const end_addr = start_addr + len;
774776
775 return .{777 return .{
...@@ -778,8 +780,8 @@ const DebugRangeIterator = struct {...@@ -778,8 +780,8 @@ const DebugRangeIterator = struct {
778 };780 };
779 },781 },
780 RLE.offset_pair => {782 RLE.offset_pair => {
781 const start_addr = try self.fr.takeLeb128(usize);783 const start_addr = try self.fr.takeLeb128(u64);
782 const end_addr = try self.fr.takeLeb128(usize);784 const end_addr = try self.fr.takeLeb128(u64);
783785
784 // This is the only kind that uses the base address786 // This is the only kind that uses the base address
785 return .{787 return .{
...@@ -788,12 +790,12 @@ const DebugRangeIterator = struct {...@@ -788,12 +790,12 @@ const DebugRangeIterator = struct {
788 };790 };
789 },791 },
790 RLE.base_address => {792 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);
792 return try self.next();794 return try self.next();
793 },795 },
794 RLE.start_end => {796 RLE.start_end => {
795 const start_addr = try self.fr.takeInt(usize, endian);797 const start_addr = try readAddress(&self.fr, endian, addr_size_bytes);
796 const end_addr = try self.fr.takeInt(usize, endian);798 const end_addr = try readAddress(&self.fr, endian, addr_size_bytes);
797799
798 return .{800 return .{
799 .start = start_addr,801 .start = start_addr,
...@@ -801,8 +803,8 @@ const DebugRangeIterator = struct {...@@ -801,8 +803,8 @@ const DebugRangeIterator = struct {
801 };803 };
802 },804 },
803 RLE.start_length => {805 RLE.start_length => {
804 const start_addr = try self.fr.takeInt(usize, endian);806 const start_addr = try readAddress(&self.fr, endian, addr_size_bytes);
805 const len = try self.fr.takeLeb128(usize);807 const len = try self.fr.takeLeb128(u64);
806 const end_addr = start_addr + len;808 const end_addr = start_addr + len;
807809
808 return .{810 return .{
...@@ -814,12 +816,13 @@ const DebugRangeIterator = struct {...@@ -814,12 +816,13 @@ const DebugRangeIterator = struct {
814 }816 }
815 },817 },
816 .debug_ranges => {818 .debug_ranges => {
817 const start_addr = try self.fr.takeInt(usize, endian);819 const start_addr = try readAddress(&self.fr, endian, addr_size_bytes);
818 const end_addr = try self.fr.takeInt(usize, endian);820 const end_addr = try readAddress(&self.fr, endian, addr_size_bytes);
819 if (start_addr == 0 and end_addr == 0) return null;821 if (start_addr == 0 and end_addr == 0) return null;
820822
821 // This entry selects a new value for the base address823 // The entry with start_addr = max_representable_address selects a new value for the base address
822 if (start_addr == maxInt(usize)) {824 const max_representable_address = ~@as(u64, 0) >> @intCast(64 - addr_size_bytes);
825 if (start_addr == max_representable_address) {
823 self.base_address = end_addr;826 self.base_address = end_addr;
824 return try self.next();827 return try self.next();
825 }828 }
...@@ -921,6 +924,7 @@ fn parseDie(...@@ -921,6 +924,7 @@ fn parseDie(
921 abbrev_table: *const Abbrev.Table,924 abbrev_table: *const Abbrev.Table,
922 format: Format,925 format: Format,
923 endian: Endian,926 endian: Endian,
927 addr_size_bytes: u8,
924) ScanError!?Die {928) ScanError!?Die {
925 const abbrev_code = try fr.takeLeb128(u64);929 const abbrev_code = try fr.takeLeb128(u64);
926 if (abbrev_code == 0) return null;930 if (abbrev_code == 0) return null;
...@@ -929,7 +933,7 @@ fn parseDie(...@@ -929,7 +933,7 @@ fn parseDie(
929 const attrs = attrs_buf[0..table_entry.attrs.len];933 const attrs = attrs_buf[0..table_entry.attrs.len];
930 for (attrs, table_entry.attrs) |*result_attr, attr| result_attr.* = .{934 for (attrs, table_entry.attrs) |*result_attr, attr| result_attr.* = .{
931 .id = attr.id,935 .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),
933 };937 };
934 return .{938 return .{
935 .tag_id = table_entry.tag_id,939 .tag_id = table_entry.tag_id,
...@@ -954,20 +958,16 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:...@@ -954,20 +958,16 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
954 const version = try fr.takeInt(u16, endian);958 const version = try fr.takeInt(u16, endian);
955 if (version < 2) return bad();959 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) .{
958 try fr.takeByte(),962 try fr.takeByte(),
959 try fr.takeByte(),963 try fr.takeByte(),
960 } else .{964 } else .{
961 switch (unit_header.format) {965 compile_unit.addr_size_bytes,
962 .@"32" => 4,
963 .@"64" => 8,
964 },
965 0,966 0,
966 };967 };
967 if (seg_size != 0) return bad(); // unsupported968 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);
971 const prog_start_offset = fr.seek + prologue_length;971 const prog_start_offset = fr.seek + prologue_length;
972972
973 const minimum_instruction_length = try fr.takeByte();973 const minimum_instruction_length = try fr.takeByte();
...@@ -1036,7 +1036,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:...@@ -1036,7 +1036,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
1036 for (try directories.addManyAsSlice(gpa, directories_count)) |*e| {1036 for (try directories.addManyAsSlice(gpa, directories_count)) |*e| {
1037 e.* = .{ .path = &.{} };1037 e.* = .{ .path = &.{} };
1038 for (dir_ent_fmt_buf[0..directory_entry_format_count]) |ent_fmt| {1038 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);
1040 switch (ent_fmt.content_type_code) {1040 switch (ent_fmt.content_type_code) {
1041 DW.LNCT.path => e.path = try form_value.getString(d.*),1041 DW.LNCT.path => e.path = try form_value.getString(d.*),
1042 DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32),1042 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:...@@ -1068,7 +1068,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
1068 for (try file_entries.addManyAsSlice(gpa, file_names_count)) |*e| {1068 for (try file_entries.addManyAsSlice(gpa, file_names_count)) |*e| {
1069 e.* = .{ .path = &.{} };1069 e.* = .{ .path = &.{} };
1070 for (file_ent_fmt_buf[0..file_name_entry_format_count]) |ent_fmt| {1070 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);
1072 switch (ent_fmt.content_type_code) {1072 switch (ent_fmt.content_type_code) {
1073 DW.LNCT.path => e.path = try form_value.getString(d.*),1073 DW.LNCT.path => e.path = try form_value.getString(d.*),
1074 DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32),1074 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:...@@ -1117,8 +1117,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
1117 prog.reset();1117 prog.reset();
1118 },1118 },
1119 DW.LNE.set_address => {1119 DW.LNE.set_address => {
1120 const addr = try fr.takeInt(usize, endian);1120 prog.address = try readAddress(&fr, endian, addr_size_bytes);
1121 prog.address = addr;
1122 },1121 },
1123 DW.LNE.define_file => {1122 DW.LNE.define_file => {
1124 const path = try fr.takeSentinel(0);1123 const path = try fr.takeSentinel(0);
...@@ -1150,7 +1149,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:...@@ -1150,7 +1149,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
1150 prog.basic_block = false;1149 prog.basic_block = false;
1151 },1150 },
1152 DW.LNS.advance_pc => {1151 DW.LNS.advance_pc => {
1153 const arg = try fr.takeLeb128(usize);1152 const arg = try fr.takeLeb128(u64);
1154 prog.address += arg * minimum_instruction_length;1153 prog.address += arg * minimum_instruction_length;
1155 },1154 },
1156 DW.LNS.advance_line => {1155 DW.LNS.advance_line => {
...@@ -1258,13 +1257,13 @@ fn readDebugAddr(di: Dwarf, endian: Endian, compile_unit: *const CompileUnit, in...@@ -1258,13 +1257,13 @@ fn readDebugAddr(di: Dwarf, endian: Endian, compile_unit: *const CompileUnit, in
1258 const addr_size = debug_addr[compile_unit.addr_base - 2];1257 const addr_size = debug_addr[compile_unit.addr_base - 2];
1259 const seg_size = debug_addr[compile_unit.addr_base - 1];1258 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;
1262 if (byte_offset + addr_size > debug_addr.len) return bad();1261 if (byte_offset + addr_size > debug_addr.len) return bad();
1263 return switch (addr_size) {1262 return switch (addr_size) {
1264 1 => debug_addr[byte_offset],1263 1 => debug_addr[@intCast(byte_offset)],
1265 2 => mem.readInt(u16, debug_addr[byte_offset..][0..2], endian),1264 2 => mem.readInt(u16, debug_addr[@intCast(byte_offset)..][0..2], endian),
1266 4 => mem.readInt(u32, debug_addr[byte_offset..][0..4], endian),1265 4 => mem.readInt(u32, debug_addr[@intCast(byte_offset)..][0..4], endian),
1267 8 => mem.readInt(u64, debug_addr[byte_offset..][0..8], endian),1266 8 => mem.readInt(u64, debug_addr[@intCast(byte_offset)..][0..8], endian),
1268 else => bad(),1267 else => bad(),
1269 };1268 };
1270}1269}
...@@ -1274,17 +1273,18 @@ fn parseFormValue(...@@ -1274,17 +1273,18 @@ fn parseFormValue(
1274 form_id: u64,1273 form_id: u64,
1275 format: Format,1274 format: Format,
1276 endian: Endian,1275 endian: Endian,
1276 addr_size_bytes: u8,
1277 implicit_const: ?i64,1277 implicit_const: ?i64,
1278) ScanError!FormValue {1278) ScanError!FormValue {
1279 return switch (form_id) {1279 return switch (form_id) {
1280 // DWARF5.pdf page 213: the size of this value is encoded in the1280 // DWARF5.pdf page 213: the size of this value is encoded in the
1281 // compilation unit header as address size.1281 // 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) },
1283 FORM.addrx1 => .{ .addrx = try r.takeByte() },1283 FORM.addrx1 => .{ .addrx = try r.takeByte() },
1284 FORM.addrx2 => .{ .addrx = try r.takeInt(u16, endian) },1284 FORM.addrx2 => .{ .addrx = try r.takeInt(u16, endian) },
1285 FORM.addrx3 => .{ .addrx = try r.takeInt(u24, endian) },1285 FORM.addrx3 => .{ .addrx = try r.takeInt(u24, endian) },
1286 FORM.addrx4 => .{ .addrx = try r.takeInt(u32, endian) },1286 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
1289 FORM.block1 => .{ .block = try r.take(try r.takeByte()) },1289 FORM.block1 => .{ .block = try r.take(try r.takeByte()) },
1290 FORM.block2 => .{ .block = try r.take(try r.takeInt(u16, endian)) },1290 FORM.block2 => .{ .block = try r.take(try r.takeInt(u16, endian)) },
...@@ -1301,7 +1301,7 @@ fn parseFormValue(...@@ -1301,7 +1301,7 @@ fn parseFormValue(
1301 FORM.exprloc => .{ .exprloc = try r.take(try r.takeLeb128(usize)) },1301 FORM.exprloc => .{ .exprloc = try r.take(try r.takeLeb128(usize)) },
1302 FORM.flag => .{ .flag = (try r.takeByte()) != 0 },1302 FORM.flag => .{ .flag = (try r.takeByte()) != 0 },
1303 FORM.flag_present => .{ .flag = true },1303 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
1306 FORM.ref1 => .{ .ref = try r.takeByte() },1306 FORM.ref1 => .{ .ref = try r.takeByte() },
1307 FORM.ref2 => .{ .ref = try r.takeInt(u16, endian) },1307 FORM.ref2 => .{ .ref = try r.takeInt(u16, endian) },
...@@ -1309,18 +1309,18 @@ fn parseFormValue(...@@ -1309,18 +1309,18 @@ fn parseFormValue(
1309 FORM.ref8 => .{ .ref = try r.takeInt(u64, endian) },1309 FORM.ref8 => .{ .ref = try r.takeInt(u64, endian) },
1310 FORM.ref_udata => .{ .ref = try r.takeLeb128(u64) },1310 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) },
1313 FORM.ref_sig8 => .{ .ref = try r.takeInt(u64, endian) },1313 FORM.ref_sig8 => .{ .ref = try r.takeInt(u64, endian) },
13141314
1315 FORM.string => .{ .string = try r.takeSentinel(0) },1315 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) },
1317 FORM.strx1 => .{ .strx = try r.takeByte() },1317 FORM.strx1 => .{ .strx = try r.takeByte() },
1318 FORM.strx2 => .{ .strx = try r.takeInt(u16, endian) },1318 FORM.strx2 => .{ .strx = try r.takeInt(u16, endian) },
1319 FORM.strx3 => .{ .strx = try r.takeInt(u24, endian) },1319 FORM.strx3 => .{ .strx = try r.takeInt(u24, endian) },
1320 FORM.strx4 => .{ .strx = try r.takeInt(u32, endian) },1320 FORM.strx4 => .{ .strx = try r.takeInt(u32, endian) },
1321 FORM.strx => .{ .strx = try r.takeLeb128(usize) },1321 FORM.strx => .{ .strx = try r.takeLeb128(usize) },
1322 FORM.line_strp => .{ .line_strp = try readAddress(r, format, endian) },1322 FORM.line_strp => .{ .line_strp = try readFormatSizedInt(r, format, endian) },
1323 FORM.indirect => parseFormValue(r, try r.takeLeb128(u64), format, endian, implicit_const),1323 FORM.indirect => parseFormValue(r, try r.takeLeb128(u64), format, endian, addr_size_bytes, implicit_const),
1324 FORM.implicit_const => .{ .sdata = implicit_const orelse return bad() },1324 FORM.implicit_const => .{ .sdata = implicit_const orelse return bad() },
1325 FORM.loclistx => .{ .loclistx = try r.takeLeb128(u64) },1325 FORM.loclistx => .{ .loclistx = try r.takeLeb128(u64) },
1326 FORM.rnglistx => .{ .rnglistx = try r.takeLeb128(u64) },1326 FORM.rnglistx => .{ .rnglistx = try r.takeLeb128(u64) },
...@@ -1464,20 +1464,24 @@ pub fn getSymbol(di: *Dwarf, allocator: Allocator, endian: Endian, address: u64)...@@ -1464,20 +1464,24 @@ pub fn getSymbol(di: *Dwarf, allocator: Allocator, endian: Endian, address: u64)
1464 };1464 };
1465}1465}
14661466
1467fn readAddress(r: *Reader, format: std.dwarf.Format, endian: Endian) !u64 {1467/// DWARF5 7.4: "In the 32-bit DWARF format, all values that represent lengths of DWARF sections and
1468 // MLUGG TODO FIX BEFORE MERGE: this function is slightly bogus. addresses have a byte width which is independent of the `dwarf.Format`!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 {
1469 return switch (format) {1474 return switch (format) {
1470 .@"32" => try r.takeInt(u32, endian),1475 .@"32" => try r.takeInt(u32, endian),
1471 .@"64" => try r.takeInt(u64, endian),1476 .@"64" => try r.takeInt(u64, endian),
1472 };1477 };
1473}1478}
14741479
1475fn nativeFormat() std.dwarf.Format {1480fn readAddress(r: *Reader, endian: Endian, addr_size_bytes: u8) !u64 {
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 FORMAT1481 return switch (addr_size_bytes) {
1477 // when parsing ARBITRARY DWARF.1482 2 => try r.takeInt(u16, endian),
1478 return switch (@sizeOf(usize)) {1483 4 => try r.takeInt(u32, endian),
1479 4 => .@"32",1484 8 => try r.takeInt(u64, endian),
1480 8 => .@"64",1485 else => return bad(),
1481 else => @compileError("unsupported @sizeOf(usize)"),
1482 };1486 };
1483}1487}
lib/std/debug/Dwarf/ElfModule.zig-2
...@@ -155,12 +155,10 @@ pub fn load(...@@ -155,12 +155,10 @@ pub fn load(
155 }155 }
156 break :blk .{156 break :blk .{
157 .data = try decompressed_section.toOwnedSlice(gpa),157 .data = try decompressed_section.toOwnedSlice(gpa),
158 .virtual_address = shdr.sh_addr,
159 .owned = true,158 .owned = true,
160 };159 };
161 } else .{160 } else .{
162 .data = section_bytes,161 .data = section_bytes,
163 .virtual_address = shdr.sh_addr,
164 .owned = false,162 .owned = false,
165 };163 };
166 }164 }
lib/std/debug/SelfInfo.zig-2
...@@ -465,7 +465,6 @@ const Module = switch (native_os) {...@@ -465,7 +465,6 @@ const Module = switch (native_os) {
465 const section_bytes = mapped_mem[sect.offset..][0..sect.size];465 const section_bytes = mapped_mem[sect.offset..][0..sect.size];
466 sections[section_index] = .{466 sections[section_index] = .{
467 .data = section_bytes,467 .data = section_bytes,
468 .virtual_address = @intCast(sect.addr),
469 .owned = false,468 .owned = false,
470 };469 };
471 }470 }
...@@ -751,7 +750,6 @@ const Module = switch (native_os) {...@@ -751,7 +750,6 @@ const Module = switch (native_os) {
751 di.dwarf.?.sections[i] = if (coff_obj.getSectionByName("." ++ section.name)) |section_header| blk: {750 di.dwarf.?.sections[i] = if (coff_obj.getSectionByName("." ++ section.name)) |section_header| blk: {
752 break :blk .{751 break :blk .{
753 .data = try coff_obj.getSectionDataAlloc(section_header, gpa),752 .data = try coff_obj.getSectionDataAlloc(section_header, gpa),
754 .virtual_address = section_header.virtual_address,
755 .owned = true,753 .owned = true,
756 };754 };
757 } else null;755 } else null;