mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-26 13:01:34 +03:00
Uses dwarf iterator if dwarf symbols found for windows executable
This commit is contained in:
+28
-7
@@ -22,7 +22,9 @@ const cast = std.math.cast;
|
||||
const maxInt = std.math.maxInt;
|
||||
const ArrayList = std.ArrayList;
|
||||
const Endian = std.builtin.Endian;
|
||||
const Reader = std.Io.Reader;
|
||||
const Io = std.Io;
|
||||
const Reader = Io.Reader;
|
||||
const Error = std.debug.SelfInfoError;
|
||||
|
||||
const Dwarf = @This();
|
||||
|
||||
@@ -1543,21 +1545,40 @@ fn getStringGeneric(opt_str: ?[]const u8, offset: u64) ![:0]const u8 {
|
||||
return str[casted_offset..last :0];
|
||||
}
|
||||
|
||||
pub fn getSymbol(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) !std.debug.Symbol {
|
||||
pub const SymbolIterator = struct {
|
||||
curr: ?std.debug.SelfInfoError!std.debug.Symbol,
|
||||
|
||||
pub fn deinit(self: *SymbolIterator, _: Io) void {
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn next(self: *SymbolIterator) ?Error!std.debug.Symbol {
|
||||
const result = self.curr;
|
||||
self.curr = null;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn getSymbols(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) SymbolIterator {
|
||||
const compile_unit = di.findCompileUnit(endian, address) catch |err| switch (err) {
|
||||
error.MissingDebugInfo, error.InvalidDebugInfo => return .unknown,
|
||||
else => return err,
|
||||
error.EndOfStream, error.Overflow => return .{ .curr = error.InvalidDebugInfo },
|
||||
else => |e| return .{ .curr = e },
|
||||
};
|
||||
return .{
|
||||
return .{ .curr = .{
|
||||
.name = di.getSymbolName(address),
|
||||
.compile_unit_name = compile_unit.die.getAttrString(di, endian, std.dwarf.AT.name, di.section(.debug_str), compile_unit) catch |err| switch (err) {
|
||||
error.MissingDebugInfo, error.InvalidDebugInfo => null,
|
||||
},
|
||||
.source_location = di.getLineNumberInfo(gpa, endian, compile_unit, address) catch |err| switch (err) {
|
||||
error.MissingDebugInfo, error.InvalidDebugInfo => null,
|
||||
else => return err,
|
||||
error.ReadFailed,
|
||||
error.EndOfStream,
|
||||
error.Overflow,
|
||||
error.StreamTooLong,
|
||||
=> return .{ .curr = error.InvalidDebugInfo },
|
||||
else => |e| return .{ .curr = e },
|
||||
},
|
||||
};
|
||||
} };
|
||||
}
|
||||
|
||||
/// DWARF5 7.4: "In the 32-bit DWARF format, all values that represent lengths of DWARF sections and
|
||||
|
||||
@@ -358,7 +358,7 @@ pub const BinaryAnnotation = union(enum) {
|
||||
self.curr.file_id = file_id;
|
||||
},
|
||||
// LLVM never emits this opcode, but it's clear enough how to interpret it so we
|
||||
// may as well in case they use it in the future
|
||||
// may as well handle it in case they emit it in the future
|
||||
.change_code_length_and_code_offset => |info| {
|
||||
self.curr.code_length = info.length;
|
||||
self.curr.code_offset += info.delta;
|
||||
|
||||
@@ -30,19 +30,7 @@ pub fn deinit(si: *SelfInfo, io: Io) void {
|
||||
if (si.unwind_cache) |cache| gpa.free(cache);
|
||||
}
|
||||
|
||||
pub const SymbolIterator = struct {
|
||||
curr: ?Error!std.debug.Symbol,
|
||||
|
||||
pub fn deinit(self: *SymbolIterator, _: Io) void {
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn next(self: *SymbolIterator) ?Error!std.debug.Symbol {
|
||||
const result = self.curr;
|
||||
self.curr = null;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
pub const SymbolIterator = std.debug.Dwarf.SymbolIterator;
|
||||
|
||||
pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator {
|
||||
const gpa = std.debug.getDebugInfoAllocator();
|
||||
@@ -67,21 +55,7 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator {
|
||||
};
|
||||
loaded_elf.scanned_dwarf = true;
|
||||
}
|
||||
if (dwarf.getSymbol(gpa, native_endian, vaddr)) |sym| {
|
||||
return .{ .curr = sym };
|
||||
} else |err| switch (err) {
|
||||
error.MissingDebugInfo => {},
|
||||
|
||||
error.InvalidDebugInfo,
|
||||
error.OutOfMemory,
|
||||
=> |e| return .{ .curr = e },
|
||||
|
||||
error.ReadFailed,
|
||||
error.EndOfStream,
|
||||
error.Overflow,
|
||||
error.StreamTooLong,
|
||||
=> return .{ .curr = error.InvalidDebugInfo },
|
||||
}
|
||||
return dwarf.getSymbols(gpa, native_endian, vaddr);
|
||||
}
|
||||
// When DWARF is unavailable, fall back to searching the symtab.
|
||||
const symbol = loaded_elf.file.searchSymtab(gpa, vaddr) catch |err| switch (err) {
|
||||
|
||||
@@ -33,7 +33,7 @@ pub const SymbolIterator = struct {
|
||||
|
||||
pub fn deinit(self: *SymbolIterator, io: Io) void {
|
||||
if (self.lock) |lock| lock.unlockShared(io);
|
||||
self.symbols.deinit();
|
||||
self.symbols.deinit(io);
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
@@ -105,29 +105,7 @@ pub const SymbolIterator = struct {
|
||||
.source_location = pdb.getLineNumberInfo(info.module, info.addr) catch null,
|
||||
};
|
||||
},
|
||||
.dwarf => |info| {
|
||||
// The failure cases are unreachable because we only set the dwarf field if these
|
||||
// are set
|
||||
const di = if (self.module.di.?) |*di| di else |_| unreachable;
|
||||
const dwarf = if (di.dwarf) |*dwarf| dwarf else unreachable;
|
||||
|
||||
// Return the main symbol and then return the iterator
|
||||
defer self.symbols = .none;
|
||||
const gpa = std.debug.getDebugInfoAllocator();
|
||||
return dwarf.getSymbol(gpa, native_endian, info.addr) catch |err| switch (err) {
|
||||
error.MissingDebugInfo => return null,
|
||||
|
||||
error.InvalidDebugInfo,
|
||||
error.OutOfMemory,
|
||||
=> |e| return e,
|
||||
|
||||
error.ReadFailed,
|
||||
error.EndOfStream,
|
||||
error.Overflow,
|
||||
error.StreamTooLong,
|
||||
=> return error.InvalidDebugInfo,
|
||||
};
|
||||
},
|
||||
.dwarf => |*info| return info.next(),
|
||||
.none => return null,
|
||||
}
|
||||
}
|
||||
@@ -368,7 +346,7 @@ const Module = struct {
|
||||
/// iteration, e.g. because they only wanted the topmost call.
|
||||
inline_sites: std.ArrayList(*align(1) const std.pdb.InlineSiteSym),
|
||||
},
|
||||
dwarf: struct { addr: u64 },
|
||||
dwarf: std.debug.Dwarf.SymbolIterator,
|
||||
none: void,
|
||||
|
||||
fn init(di: *DebugInfo, vaddr: usize) Error!Symbols {
|
||||
@@ -425,23 +403,20 @@ const Module = struct {
|
||||
|
||||
// Dwarf
|
||||
dwarf: {
|
||||
if (di.dwarf == null) break :dwarf;
|
||||
const dwarf = &(di.dwarf orelse break :dwarf);
|
||||
const addr = vaddr + di.coff_image_base;
|
||||
return .{ .dwarf = .{
|
||||
.addr = addr,
|
||||
} };
|
||||
return .{ .dwarf = dwarf.getSymbols(gpa, native_endian, addr) };
|
||||
}
|
||||
|
||||
return error.MissingDebugInfo;
|
||||
}
|
||||
|
||||
fn deinit(self: *Symbols) void {
|
||||
fn deinit(self: *Symbols, io: Io) void {
|
||||
const gpa = std.debug.getDebugInfoAllocator();
|
||||
switch (self.*) {
|
||||
.pdb => |*info| {
|
||||
const gpa = std.debug.getDebugInfoAllocator();
|
||||
info.inline_sites.deinit(gpa);
|
||||
},
|
||||
.dwarf, .none => {},
|
||||
.pdb => |*info| info.inline_sites.deinit(gpa),
|
||||
.dwarf => |*info| info.deinit(io),
|
||||
.none => {},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user