| author | |
| committer | |
| log | 5a4b5c8b94236429263ef25d9287b6c5cc829bde |
| tree | 52bc7eedf23bb607811581b04d1d5edfc3e27f66 |
| parent | 825ba5a350cab21fff5531d645d18cd9d2facd8f |
4 files changed, 41 insertions(+), 71 deletions(-)
lib/std/debug/Dwarf.zig+28-7| ... | @@ -22,7 +22,9 @@ const cast = std.math.cast; | ... | @@ -22,7 +22,9 @@ const cast = std.math.cast; |
| 22 | const maxInt = std.math.maxInt; | 22 | const maxInt = std.math.maxInt; |
| 23 | const ArrayList = std.ArrayList; | 23 | const ArrayList = std.ArrayList; |
| 24 | const Endian = std.builtin.Endian; | 24 | const Endian = std.builtin.Endian; |
| 25 | const Reader = std.Io.Reader; | 25 | const Io = std.Io; |
| 26 | const Reader = Io.Reader; | ||
| 27 | const Error = std.debug.SelfInfoError; | ||
| 26 | 28 | ||
| 27 | const Dwarf = @This(); | 29 | const Dwarf = @This(); |
| 28 | 30 | ||
| ... | @@ -1543,21 +1545,40 @@ fn getStringGeneric(opt_str: ?[]const u8, offset: u64) ![:0]const u8 { | ... | @@ -1543,21 +1545,40 @@ fn getStringGeneric(opt_str: ?[]const u8, offset: u64) ![:0]const u8 { |
| 1543 | return str[casted_offset..last :0]; | 1545 | return str[casted_offset..last :0]; |
| 1544 | } | 1546 | } |
| 1545 | 1547 | ||
| 1546 | pub fn getSymbol(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) !std.debug.Symbol { | 1548 | pub const SymbolIterator = struct { |
| 1549 | curr: ?std.debug.SelfInfoError!std.debug.Symbol, | ||
| 1550 | |||
| 1551 | pub fn deinit(self: *SymbolIterator, _: Io) void { | ||
| 1552 | self.* = undefined; | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | pub fn next(self: *SymbolIterator) ?Error!std.debug.Symbol { | ||
| 1556 | const result = self.curr; | ||
| 1557 | self.curr = null; | ||
| 1558 | return result; | ||
| 1559 | } | ||
| 1560 | }; | ||
| 1561 | |||
| 1562 | pub fn getSymbols(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) SymbolIterator { | ||
| 1547 | const compile_unit = di.findCompileUnit(endian, address) catch |err| switch (err) { | 1563 | const compile_unit = di.findCompileUnit(endian, address) catch |err| switch (err) { |
| 1548 | error.MissingDebugInfo, error.InvalidDebugInfo => return .unknown, | 1564 | error.EndOfStream, error.Overflow => return .{ .curr = error.InvalidDebugInfo }, |
| 1549 | else => return err, | 1565 | else => |e| return .{ .curr = e }, |
| 1550 | }; | 1566 | }; |
| 1551 | return .{ | 1567 | return .{ .curr = .{ |
| 1552 | .name = di.getSymbolName(address), | 1568 | .name = di.getSymbolName(address), |
| 1553 | .compile_unit_name = compile_unit.die.getAttrString(di, endian, std.dwarf.AT.name, di.section(.debug_str), compile_unit) catch |err| switch (err) { | 1569 | .compile_unit_name = compile_unit.die.getAttrString(di, endian, std.dwarf.AT.name, di.section(.debug_str), compile_unit) catch |err| switch (err) { |
| 1554 | error.MissingDebugInfo, error.InvalidDebugInfo => null, | 1570 | error.MissingDebugInfo, error.InvalidDebugInfo => null, |
| 1555 | }, | 1571 | }, |
| 1556 | .source_location = di.getLineNumberInfo(gpa, endian, compile_unit, address) catch |err| switch (err) { | 1572 | .source_location = di.getLineNumberInfo(gpa, endian, compile_unit, address) catch |err| switch (err) { |
| 1557 | error.MissingDebugInfo, error.InvalidDebugInfo => null, | 1573 | error.MissingDebugInfo, error.InvalidDebugInfo => null, |
| 1558 | else => return err, | 1574 | error.ReadFailed, |
| 1575 | error.EndOfStream, | ||
| 1576 | error.Overflow, | ||
| 1577 | error.StreamTooLong, | ||
| 1578 | => return .{ .curr = error.InvalidDebugInfo }, | ||
| 1579 | else => |e| return .{ .curr = e }, | ||
| 1559 | }, | 1580 | }, |
| 1560 | }; | 1581 | } }; |
| 1561 | } | 1582 | } |
| 1562 | 1583 | ||
| 1563 | /// DWARF5 7.4: "In the 32-bit DWARF format, all values that represent lengths of DWARF sections and | 1584 | /// DWARF5 7.4: "In the 32-bit DWARF format, all values that represent lengths of DWARF sections and |
lib/std/debug/Pdb.zig+1-1| ... | @@ -358,7 +358,7 @@ pub const BinaryAnnotation = union(enum) { | ... | @@ -358,7 +358,7 @@ pub const BinaryAnnotation = union(enum) { |
| 358 | self.curr.file_id = file_id; | 358 | self.curr.file_id = file_id; |
| 359 | }, | 359 | }, |
| 360 | // LLVM never emits this opcode, but it's clear enough how to interpret it so we | 360 | // LLVM never emits this opcode, but it's clear enough how to interpret it so we |
| 361 | // may as well in case they use it in the future | 361 | // may as well handle it in case they emit it in the future |
| 362 | .change_code_length_and_code_offset => |info| { | 362 | .change_code_length_and_code_offset => |info| { |
| 363 | self.curr.code_length = info.length; | 363 | self.curr.code_length = info.length; |
| 364 | self.curr.code_offset += info.delta; | 364 | self.curr.code_offset += info.delta; |
lib/std/debug/SelfInfo/Elf.zig+2-28| ... | @@ -30,19 +30,7 @@ pub fn deinit(si: *SelfInfo, io: Io) void { | ... | @@ -30,19 +30,7 @@ pub fn deinit(si: *SelfInfo, io: Io) void { |
| 30 | if (si.unwind_cache) |cache| gpa.free(cache); | 30 | if (si.unwind_cache) |cache| gpa.free(cache); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub const SymbolIterator = struct { | 33 | pub const SymbolIterator = std.debug.Dwarf.SymbolIterator; |
| 34 | curr: ?Error!std.debug.Symbol, | ||
| 35 | |||
| 36 | pub fn deinit(self: *SymbolIterator, _: Io) void { | ||
| 37 | self.* = undefined; | ||
| 38 | } | ||
| 39 | |||
| 40 | pub fn next(self: *SymbolIterator) ?Error!std.debug.Symbol { | ||
| 41 | const result = self.curr; | ||
| 42 | self.curr = null; | ||
| 43 | return result; | ||
| 44 | } | ||
| 45 | }; | ||
| 46 | 34 | ||
| 47 | pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator { | 35 | pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator { |
| 48 | const gpa = std.debug.getDebugInfoAllocator(); | 36 | const gpa = std.debug.getDebugInfoAllocator(); |
| ... | @@ -67,21 +55,7 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator { | ... | @@ -67,21 +55,7 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator { |
| 67 | }; | 55 | }; |
| 68 | loaded_elf.scanned_dwarf = true; | 56 | loaded_elf.scanned_dwarf = true; |
| 69 | } | 57 | } |
| 70 | if (dwarf.getSymbol(gpa, native_endian, vaddr)) |sym| { | 58 | return dwarf.getSymbols(gpa, native_endian, vaddr); |
| 71 | return .{ .curr = sym }; | ||
| 72 | } else |err| switch (err) { | ||
| 73 | error.MissingDebugInfo => {}, | ||
| 74 | |||
| 75 | error.InvalidDebugInfo, | ||
| 76 | error.OutOfMemory, | ||
| 77 | => |e| return .{ .curr = e }, | ||
| 78 | |||
| 79 | error.ReadFailed, | ||
| 80 | error.EndOfStream, | ||
| 81 | error.Overflow, | ||
| 82 | error.StreamTooLong, | ||
| 83 | => return .{ .curr = error.InvalidDebugInfo }, | ||
| 84 | } | ||
| 85 | } | 59 | } |
| 86 | // When DWARF is unavailable, fall back to searching the symtab. | 60 | // When DWARF is unavailable, fall back to searching the symtab. |
| 87 | const symbol = loaded_elf.file.searchSymtab(gpa, vaddr) catch |err| switch (err) { | 61 | const symbol = loaded_elf.file.searchSymtab(gpa, vaddr) catch |err| switch (err) { |
lib/std/debug/SelfInfo/Windows.zig+10-35| ... | @@ -33,7 +33,7 @@ pub const SymbolIterator = struct { | ... | @@ -33,7 +33,7 @@ pub const SymbolIterator = struct { |
| 33 | 33 | ||
| 34 | pub fn deinit(self: *SymbolIterator, io: Io) void { | 34 | pub fn deinit(self: *SymbolIterator, io: Io) void { |
| 35 | if (self.lock) |lock| lock.unlockShared(io); | 35 | if (self.lock) |lock| lock.unlockShared(io); |
| 36 | self.symbols.deinit(); | 36 | self.symbols.deinit(io); |
| 37 | self.* = undefined; | 37 | self.* = undefined; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| ... | @@ -105,29 +105,7 @@ pub const SymbolIterator = struct { | ... | @@ -105,29 +105,7 @@ pub const SymbolIterator = struct { |
| 105 | .source_location = pdb.getLineNumberInfo(info.module, info.addr) catch null, | 105 | .source_location = pdb.getLineNumberInfo(info.module, info.addr) catch null, |
| 106 | }; | 106 | }; |
| 107 | }, | 107 | }, |
| 108 | .dwarf => |info| { | 108 | .dwarf => |*info| return info.next(), |
| 109 | // The failure cases are unreachable because we only set the dwarf field if these | ||
| 110 | // are set | ||
| 111 | const di = if (self.module.di.?) |*di| di else |_| unreachable; | ||
| 112 | const dwarf = if (di.dwarf) |*dwarf| dwarf else unreachable; | ||
| 113 | |||
| 114 | // Return the main symbol and then return the iterator | ||
| 115 | defer self.symbols = .none; | ||
| 116 | const gpa = std.debug.getDebugInfoAllocator(); | ||
| 117 | return dwarf.getSymbol(gpa, native_endian, info.addr) catch |err| switch (err) { | ||
| 118 | error.MissingDebugInfo => return null, | ||
| 119 | |||
| 120 | error.InvalidDebugInfo, | ||
| 121 | error.OutOfMemory, | ||
| 122 | => |e| return e, | ||
| 123 | |||
| 124 | error.ReadFailed, | ||
| 125 | error.EndOfStream, | ||
| 126 | error.Overflow, | ||
| 127 | error.StreamTooLong, | ||
| 128 | => return error.InvalidDebugInfo, | ||
| 129 | }; | ||
| 130 | }, | ||
| 131 | .none => return null, | 109 | .none => return null, |
| 132 | } | 110 | } |
| 133 | } | 111 | } |
| ... | @@ -368,7 +346,7 @@ const Module = struct { | ... | @@ -368,7 +346,7 @@ const Module = struct { |
| 368 | /// iteration, e.g. because they only wanted the topmost call. | 346 | /// iteration, e.g. because they only wanted the topmost call. |
| 369 | inline_sites: std.ArrayList(*align(1) const std.pdb.InlineSiteSym), | 347 | inline_sites: std.ArrayList(*align(1) const std.pdb.InlineSiteSym), |
| 370 | }, | 348 | }, |
| 371 | dwarf: struct { addr: u64 }, | 349 | dwarf: std.debug.Dwarf.SymbolIterator, |
| 372 | none: void, | 350 | none: void, |
| 373 | 351 | ||
| 374 | fn init(di: *DebugInfo, vaddr: usize) Error!Symbols { | 352 | fn init(di: *DebugInfo, vaddr: usize) Error!Symbols { |
| ... | @@ -425,23 +403,20 @@ const Module = struct { | ... | @@ -425,23 +403,20 @@ const Module = struct { |
| 425 | 403 | ||
| 426 | // Dwarf | 404 | // Dwarf |
| 427 | dwarf: { | 405 | dwarf: { |
| 428 | if (di.dwarf == null) break :dwarf; | 406 | const dwarf = &(di.dwarf orelse break :dwarf); |
| 429 | const addr = vaddr + di.coff_image_base; | 407 | const addr = vaddr + di.coff_image_base; |
| 430 | return .{ .dwarf = .{ | 408 | return .{ .dwarf = dwarf.getSymbols(gpa, native_endian, addr) }; |
| 431 | .addr = addr, | ||
| 432 | } }; | ||
| 433 | } | 409 | } |
| 434 | 410 | ||
| 435 | return error.MissingDebugInfo; | 411 | return error.MissingDebugInfo; |
| 436 | } | 412 | } |
| 437 | 413 | ||
| 438 | fn deinit(self: *Symbols) void { | 414 | fn deinit(self: *Symbols, io: Io) void { |
| 415 | const gpa = std.debug.getDebugInfoAllocator(); | ||
| 439 | switch (self.*) { | 416 | switch (self.*) { |
| 440 | .pdb => |*info| { | 417 | .pdb => |*info| info.inline_sites.deinit(gpa), |
| 441 | const gpa = std.debug.getDebugInfoAllocator(); | 418 | .dwarf => |*info| info.deinit(io), |
| 442 | info.inline_sites.deinit(gpa); | 419 | .none => {}, |
| 443 | }, | ||
| 444 | .dwarf, .none => {}, | ||
| 445 | } | 420 | } |
| 446 | } | 421 | } |
| 447 | }; | 422 | }; |