aboutsummaryrefslogtreecommitdiff
path: root/lib/std/debug.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-08-22 19:48:14 +0200
committerJakub Konka <kubkon@jakubkonka.com>2022-08-23 08:55:04 +0200
commitc84e5ee87852eafff0cbf986bf02c5221cbcec35 (patch)
treea978b80bbcc7273ad3a0e3d4de843a8a3ec947e9 /lib/std/debug.zig
parent9043e665a549b87fa73ade7af06682368092d8a9 (diff)
downloadzig-c84e5ee87852eafff0cbf986bf02c5221cbcec35.tar.gz
zig-c84e5ee87852eafff0cbf986bf02c5221cbcec35.zip
coff: improve default COFF/PE object parser
We now do not allocate memory for headers and other metadata unless requested by the caller. Instead, we read-in the entire contents of the image into memory and operate on pointers and casts wherever possible. I have a left a TODO to hook up Windows' memory-mapped API here in-place of standard `readToEndAlloc` which should be more memory proof on memory constrained hosts. This commit also supplements our `std.coff` with a lot missing basic extern structs required to make our COFF linker.
Diffstat (limited to 'lib/std/debug.zig')
-rw-r--r--lib/std/debug.zig40
1 files changed, 22 insertions, 18 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index 5e217890b7..917354edf7 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -816,11 +816,11 @@ pub fn openSelfDebugInfo(allocator: mem.Allocator) anyerror!DebugInfo {
/// TODO it's weird to take ownership even on error, rework this code.
fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo {
nosuspend {
- errdefer coff_file.close();
+ defer coff_file.close();
const coff_obj = try allocator.create(coff.Coff);
errdefer allocator.destroy(coff_obj);
- coff_obj.* = coff.Coff.init(allocator, coff_file);
+ coff_obj.* = .{ .allocator = allocator };
var di = ModuleDebugInfo{
.base_address = undefined,
@@ -828,18 +828,21 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo
.debug_data = undefined,
};
- try di.coff.loadHeader();
- try di.coff.loadSections();
- if (di.coff.getSection(".debug_info")) |sec| {
+ // TODO convert to Windows' memory-mapped file API
+ const file_len = math.cast(usize, try coff_file.getEndPos()) orelse math.maxInt(usize);
+ const data = try coff_file.readToEndAlloc(allocator, file_len);
+ try di.coff.parse(data);
+
+ if (di.coff.getSectionByName(".debug_info")) |sec| {
// This coff file has embedded DWARF debug info
_ = sec;
// TODO: free the section data slices
- const debug_info_data = di.coff.getSectionData(".debug_info", allocator) catch null;
- const debug_abbrev_data = di.coff.getSectionData(".debug_abbrev", allocator) catch null;
- const debug_str_data = di.coff.getSectionData(".debug_str", allocator) catch null;
- const debug_line_data = di.coff.getSectionData(".debug_line", allocator) catch null;
- const debug_line_str_data = di.coff.getSectionData(".debug_line_str", allocator) catch null;
- const debug_ranges_data = di.coff.getSectionData(".debug_ranges", allocator) catch null;
+ const debug_info_data = di.coff.getSectionDataAlloc(".debug_info", allocator) catch null;
+ const debug_abbrev_data = di.coff.getSectionDataAlloc(".debug_abbrev", allocator) catch null;
+ const debug_str_data = di.coff.getSectionDataAlloc(".debug_str", allocator) catch null;
+ const debug_line_data = di.coff.getSectionDataAlloc(".debug_line", allocator) catch null;
+ const debug_line_str_data = di.coff.getSectionDataAlloc(".debug_line_str", allocator) catch null;
+ const debug_ranges_data = di.coff.getSectionDataAlloc(".debug_ranges", allocator) catch null;
var dwarf = DW.DwarfInfo{
.endian = native_endian,
@@ -1628,7 +1631,7 @@ pub const ModuleDebugInfo = switch (native_os) {
switch (self.debug_data) {
.dwarf => |*dwarf| {
- const dwarf_address = relocated_address + self.coff.pe_header.image_base;
+ const dwarf_address = relocated_address + self.coff.getImageBase();
return getSymbolFromDwarf(allocator, dwarf_address, dwarf);
},
.pdb => {
@@ -1636,13 +1639,14 @@ pub const ModuleDebugInfo = switch (native_os) {
},
}
- var coff_section: *coff.Section = undefined;
+ var coff_section: *align(1) const coff.SectionHeader = undefined;
const mod_index = for (self.debug_data.pdb.sect_contribs) |sect_contrib| {
- if (sect_contrib.Section > self.coff.sections.items.len) continue;
+ const sections = self.coff.getSectionHeaders();
+ if (sect_contrib.Section > sections.len) continue;
// Remember that SectionContribEntry.Section is 1-based.
- coff_section = &self.coff.sections.items[sect_contrib.Section - 1];
+ coff_section = &sections[sect_contrib.Section - 1];
- const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset;
+ const vaddr_start = coff_section.virtual_address + sect_contrib.Offset;
const vaddr_end = vaddr_start + sect_contrib.Size;
if (relocated_address >= vaddr_start and relocated_address < vaddr_end) {
break sect_contrib.ModuleIndex;
@@ -1658,11 +1662,11 @@ pub const ModuleDebugInfo = switch (native_os) {
const symbol_name = self.debug_data.pdb.getSymbolName(
module,
- relocated_address - coff_section.header.virtual_address,
+ relocated_address - coff_section.virtual_address,
) orelse "???";
const opt_line_info = try self.debug_data.pdb.getLineNumberInfo(
module,
- relocated_address - coff_section.header.virtual_address,
+ relocated_address - coff_section.virtual_address,
);
return SymbolInfo{