| author | |
| committer | |
| log | 97bda56306622784b2f2e4f036d817bbe5f2025e |
| tree | ecec2a45ed278bf105155049695526d9d32b4006 |
| parent | 774dc2fdb75dc7f6b7e0bd2cfe947fffb9829ba1 |
3 files changed, 29 insertions(+), 15 deletions(-)
lib/std/debug.zig+1-5| ... | ... | @@ -642,7 +642,7 @@ pub const StackIterator = struct { |
| 642 | 642 | // __unwind_info is a requirement for unwinding on Darwin. It may fall back to DWARF, but unwinding |
| 643 | 643 | // via DWARF before attempting to use the compact unwind info will produce incorrect results. |
| 644 | 644 | if (module.unwind_info) |unwind_info| { |
| 645 | if (macho.unwindFrame(&unwind_state.dwarf_context, unwind_info, module.base_address)) |return_address| { | |
| 645 | if (macho.unwindFrame(&unwind_state.dwarf_context, unwind_info, module.eh_frame, module.base_address)) |return_address| { | |
| 646 | 646 | return return_address; |
| 647 | 647 | } else |err| { |
| 648 | 648 | if (err != error.RequiresDWARFUnwind) return err; |
| ... | ... | @@ -2026,10 +2026,6 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 2026 | 2026 | }; |
| 2027 | 2027 | |
| 2028 | 2028 | try DW.openDwarfDebugInfo(&di, allocator); |
| 2029 | ||
| 2030 | // TODO: Don't actually scan everything, search on demand | |
| 2031 | di.scanAllUnwindInfo(allocator, self.base_address) catch {}; | |
| 2032 | ||
| 2033 | 2029 | var info = OFileInfo{ |
| 2034 | 2030 | .di = di, |
| 2035 | 2031 | .addr_table = addr_table, |
lib/std/dwarf.zig+4-5| ... | ... | @@ -686,7 +686,8 @@ pub const DwarfInfo = struct { |
| 686 | 686 | pub const null_section_array = [_]?Section{null} ** num_sections; |
| 687 | 687 | |
| 688 | 688 | endian: std.builtin.Endian, |
| 689 | sections: SectionArray, | |
| 689 | sections: SectionArray = null_section_array, | |
| 690 | is_macho: bool, | |
| 690 | 691 | |
| 691 | 692 | // Filled later by the initializer |
| 692 | 693 | abbrev_table_list: std.ArrayListUnmanaged(AbbrevTableHeader) = .{}, |
| ... | ... | @@ -699,8 +700,6 @@ pub const DwarfInfo = struct { |
| 699 | 700 | // Sorted by start_pc |
| 700 | 701 | fde_list: std.ArrayListUnmanaged(FrameDescriptionEntry) = .{}, |
| 701 | 702 | |
| 702 | is_macho: bool, | |
| 703 | ||
| 704 | 703 | pub fn section(di: DwarfInfo, dwarf_section: DwarfSection) ?[]const u8 { |
| 705 | 704 | return if (di.sections[@intFromEnum(dwarf_section)]) |s| s.data else null; |
| 706 | 705 | } |
| ... | ... | @@ -1672,6 +1671,8 @@ pub const DwarfInfo = struct { |
| 1672 | 1671 | if (fde_offset >= frame_section.len) return error.MissingFDE; |
| 1673 | 1672 | |
| 1674 | 1673 | var stream = io.fixedBufferStream(frame_section); |
| 1674 | try stream.seekTo(fde_offset); | |
| 1675 | ||
| 1675 | 1676 | const fde_entry_header = try EntryHeader.read(&stream, dwarf_section, di.endian); |
| 1676 | 1677 | if (fde_entry_header.type != .fde) return error.MissingFDE; |
| 1677 | 1678 | |
| ... | ... | @@ -1701,8 +1702,6 @@ pub const DwarfInfo = struct { |
| 1701 | 1702 | builtin.cpu.arch.endian(), |
| 1702 | 1703 | ); |
| 1703 | 1704 | } else if (di.eh_frame_hdr) |header| { |
| 1704 | std.debug.print("EH_FRAME_HDR\n", .{}); | |
| 1705 | ||
| 1706 | 1705 | const eh_frame_len = if (di.section(.eh_frame)) |eh_frame| eh_frame.len else null; |
| 1707 | 1706 | try header.findEntry( |
| 1708 | 1707 | context.isValidMemory, |
lib/std/macho.zig+24-5| ... | ... | @@ -2142,7 +2142,7 @@ fn dwarfRegNumber(unwind_reg_number: u3) !u8 { |
| 2142 | 2142 | const dwarf = std.dwarf; |
| 2143 | 2143 | const abi = dwarf.abi; |
| 2144 | 2144 | |
| 2145 | pub fn unwindFrame(context: *dwarf.UnwindContext, unwind_info: []const u8, module_base_address: usize) !usize { | |
| 2145 | pub fn unwindFrame(context: *dwarf.UnwindContext, unwind_info: []const u8, eh_frame: ?[]const u8, module_base_address: usize) !usize { | |
| 2146 | 2146 | const header = mem.bytesAsValue( |
| 2147 | 2147 | unwind_info_section_header, |
| 2148 | 2148 | unwind_info[0..@sizeOf(unwind_info_section_header)], |
| ... | ... | @@ -2396,7 +2396,9 @@ pub fn unwindFrame(context: *dwarf.UnwindContext, unwind_info: []const u8, modul |
| 2396 | 2396 | |
| 2397 | 2397 | break :blk new_ip; |
| 2398 | 2398 | }, |
| 2399 | .DWARF => return error.RequiresDWARFUnwind, | |
| 2399 | .DWARF => { | |
| 2400 | return unwindFrameDwarf(context, eh_frame orelse return error.MissingEhFrame, @intCast(encoding.value.x86_64.dwarf)); | |
| 2401 | }, | |
| 2400 | 2402 | }, |
| 2401 | 2403 | .aarch64 => switch (encoding.mode.arm64) { |
| 2402 | 2404 | .OLD => return error.UnimplementedUnwindEncoding, |
| ... | ... | @@ -2408,8 +2410,10 @@ pub fn unwindFrame(context: *dwarf.UnwindContext, unwind_info: []const u8, modul |
| 2408 | 2410 | (try abi.regValueNative(usize, context.thread_context, abi.spRegNum(reg_context), reg_context)).* = new_sp; |
| 2409 | 2411 | break :blk new_ip; |
| 2410 | 2412 | }, |
| 2411 | .DWARF => return error.RequiresDWARFUnwind, | |
| 2412 | .FRAME => { | |
| 2413 | .DWARF => { | |
| 2414 | return unwindFrameDwarf(context, eh_frame orelse return error.MissingEhFrame, @intCast(encoding.value.arm64.dwarf)); | |
| 2415 | }, | |
| 2416 | .FRAME => blk: { | |
| 2413 | 2417 | const fp = (try abi.regValueNative(usize, context.thread_context, abi.fpRegNum(reg_context), reg_context)).*; |
| 2414 | 2418 | const new_sp = fp + 16; |
| 2415 | 2419 | const ip_ptr = fp + @sizeOf(usize); |
| ... | ... | @@ -2453,7 +2457,7 @@ pub fn unwindFrame(context: *dwarf.UnwindContext, unwind_info: []const u8, modul |
| 2453 | 2457 | (try abi.regValueNative(usize, context.thread_context, abi.fpRegNum(reg_context), reg_context)).* = new_fp; |
| 2454 | 2458 | (try abi.regValueNative(usize, context.thread_context, abi.ipRegNum(), reg_context)).* = new_ip; |
| 2455 | 2459 | |
| 2456 | return error.UnimplementedUnwindEncoding; | |
| 2460 | break :blk new_ip; | |
| 2457 | 2461 | }, |
| 2458 | 2462 | }, |
| 2459 | 2463 | else => return error.UnimplementedArch, |
| ... | ... | @@ -2463,3 +2467,18 @@ pub fn unwindFrame(context: *dwarf.UnwindContext, unwind_info: []const u8, modul |
| 2463 | 2467 | if (context.pc > 0) context.pc -= 1; |
| 2464 | 2468 | return new_ip; |
| 2465 | 2469 | } |
| 2470 | ||
| 2471 | fn unwindFrameDwarf(context: *dwarf.UnwindContext, eh_frame: []const u8, fde_offset: usize) !usize { | |
| 2472 | var di = dwarf.DwarfInfo{ | |
| 2473 | .endian = builtin.cpu.arch.endian(), | |
| 2474 | .is_macho = true, | |
| 2475 | }; | |
| 2476 | defer di.deinit(context.allocator); | |
| 2477 | ||
| 2478 | di.sections[@intFromEnum(dwarf.DwarfSection.eh_frame)] = .{ | |
| 2479 | .data = eh_frame, | |
| 2480 | .owned = false, | |
| 2481 | }; | |
| 2482 | ||
| 2483 | return di.unwindFrame(context, fde_offset); | |
| 2484 | } |