diff options
| author | kcbanner <kcbanner@gmail.com> | 2023-07-16 02:00:17 -0400 |
|---|---|---|
| committer | kcbanner <kcbanner@gmail.com> | 2023-07-20 22:58:16 -0400 |
| commit | 618b0eb3d3ac5ecb84acb4296c591f53ba9c4298 (patch) | |
| tree | a2e012a08c04a5f83f61ce895dcb0819e336d97a /lib/std/debug.zig | |
| parent | 5e399d97d7b8ed3fc4c5b3664acfa7c79e72136c (diff) | |
| download | zig-618b0eb3d3ac5ecb84acb4296c591f53ba9c4298.tar.gz zig-618b0eb3d3ac5ecb84acb4296c591f53ba9c4298.zip | |
dwarf: fixup integer overflow in readEhPointer
debug: handle the possibility of eh_frame / debug_frame being mapped in memory or loaded from disk
Diffstat (limited to 'lib/std/debug.zig')
| -rw-r--r-- | lib/std/debug.zig | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 1048071313..131b13943c 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -987,23 +987,19 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu .debug_data = undefined, }; - if (coff_obj.getSectionByName(".debug_info")) |sec| { + if (coff_obj.getSectionByName(".debug_info")) |_| { // This coff file has embedded DWARF debug info - _ = sec; - var sections: DW.DwarfInfo.SectionArray = DW.DwarfInfo.null_section_array; errdefer for (sections) |section| if (section) |s| if (s.owned) allocator.free(s.data); inline for (@typeInfo(DW.DwarfSection).Enum.fields, 0..) |section, i| { - sections[i] = if (coff_obj.getSectionDataAlloc("." ++ section.name, allocator)) |data| blk: { + sections[i] = if (coff_obj.getSectionByName("." ++ section.name)) |section_header| blk: { break :blk .{ - .data = data, + .data = try coff_obj.getSectionDataAlloc(section_header, allocator), + .virtual_address = section_header.virtual_address, .owned = true, }; - } else |err| blk: { - if (err == error.MissingCoffSection) break :blk null; - return err; - }; + } else null; } var dwarf = DW.DwarfInfo{ @@ -1012,7 +1008,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu .is_macho = false, }; - try DW.openDwarfDebugInfo(&dwarf, allocator, coff_obj.data); + try DW.openDwarfDebugInfo(&dwarf, allocator); di.debug_data = PdbOrDwarf{ .dwarf = dwarf }; return di; } @@ -1049,6 +1045,10 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) error{Overflow}![]const u8 return ptr[start..end]; } +/// Reads debug info from an ELF file, or the current binary if none in specified. +/// If the required sections aren't present but a reference to external debug info is, +/// then this this function will recurse to attempt to load the debug sections from +/// an external file. pub fn readElfDebugInfo( allocator: mem.Allocator, elf_filename: ?[]const u8, @@ -1146,10 +1146,12 @@ pub fn readElfDebugInfo( break :blk .{ .data = decompressed_section, + .virtual_address = shdr.sh_addr, .owned = true, }; } else .{ .data = section_bytes, + .virtual_address = shdr.sh_addr, .owned = false, }; } @@ -1232,7 +1234,7 @@ pub fn readElfDebugInfo( .is_macho = false, }; - try DW.openDwarfDebugInfo(&di, allocator, parent_mapped_mem orelse mapped_mem); + try DW.openDwarfDebugInfo(&di, allocator); return ModuleDebugInfo{ .base_address = undefined, @@ -1900,6 +1902,10 @@ pub const DebugInfo = struct { obj_di.* = try readElfDebugInfo(self.allocator, if (ctx.name.len > 0) ctx.name else null, ctx.build_id, null, §ions, null); obj_di.base_address = ctx.base_address; + // TODO: Don't actually scan everything, search on demand + // Missing unwind info isn't treated as a failure, as the unwinder will fall back to FP-based unwinding + obj_di.dwarf.scanAllUnwindInfo(self.allocator, ctx.base_address) catch {}; + try self.address_map.putNoClobber(ctx.base_address, obj_di); return obj_di; @@ -2004,11 +2010,12 @@ pub const ModuleDebugInfo = switch (native_os) { inline for (@typeInfo(DW.DwarfSection).Enum.fields, 0..) |section, i| { if (mem.eql(u8, "__" ++ section.name, sect.sectName())) section_index = i; } - if (section_index == null or sections[section_index.?] != null) continue; + if (section_index == null) continue; const section_bytes = try chopSlice(mapped_mem, sect.offset, sect.size); sections[section_index.?] = .{ .data = section_bytes, + .virtual_address = sect.addr, .owned = false, }; } @@ -2026,9 +2033,11 @@ pub const ModuleDebugInfo = switch (native_os) { .is_macho = true, }; - // TODO: Don't actually need to scan unwind info in this case, since __unwind_info points us to the entries + try DW.openDwarfDebugInfo(&di, allocator); + + // TODO: Don't actually scan everything, search on demand + di.scanAllUnwindInfo(allocator, self.base_address) catch {}; - try DW.openDwarfDebugInfo(&di, allocator, mapped_mem); var info = OFileInfo{ .di = di, .addr_table = addr_table, |
