[llvm] [win][x64] Updated `llvm-objdump` and `llvm-readobj` to be able to dump Windows x64 Unwind v3 information. (PR #199120)
Evgenii Kudriashov via llvm-commits
llvm-commits at lists.llvm.org
Fri May 22 05:36:49 PDT 2026
================
@@ -407,8 +409,185 @@ void Dumper::printRuntimeFunction(const Context &Ctx,
if (Offset > Contents.size())
return;
- const auto UI = reinterpret_cast<const UnwindInfo*>(Contents.data() + Offset);
- printUnwindInfo(Ctx, XData, Offset, *UI);
+ // Check version before casting to UnwindInfo struct.
+ // Only byte 0 (VersionAndFlags) is layout-compatible between V1/V2 and V3.
+ uint8_t VersionByte = Contents[Offset];
+ uint8_t Version = VersionByte & 0x07;
+
+ if (Version == 3) {
+ ArrayRef<uint8_t> RawData = Contents.slice(Offset);
+ printUnwindInfoV3(Ctx, XData, Offset, RawData);
+ } else {
+ const auto UI =
+ reinterpret_cast<const UnwindInfo *>(Contents.data() + Offset);
+ printUnwindInfo(Ctx, XData, Offset, *UI);
+ }
+}
+
+/// Helper to print decoded WOD fields for llvm-readobj.
+static void printDecodedWOD(ScopedPrinter &SW, raw_ostream &OS,
+ const DecodedWOD &W) {
+ switch (W.Opcode) {
+ case WOD_PUSH:
+ OS << "PUSH Reg=" << getRegisterNameV3(W.Register);
+ break;
+ case WOD_PUSH2:
+ OS << "PUSH2 Reg1=" << getRegisterNameV3(W.Register)
+ << ", Reg2=" << getRegisterNameV3(W.Register2);
+ break;
+ case WOD_PUSH_CONSECUTIVE_2:
+ OS << "PUSH_CONSECUTIVE_2 Reg=" << getRegisterNameV3(W.Register) << " (+"
+ << getRegisterNameV3(W.Register + 1) << ")";
+ break;
+ case WOD_ALLOC_SMALL:
+ OS << format("ALLOC_SMALL Size=0x%X", W.Size);
+ break;
+ case WOD_ALLOC_LARGE:
+ OS << format("ALLOC_LARGE Size=0x%X", W.Size);
+ break;
+ case WOD_ALLOC_HUGE:
+ OS << format("ALLOC_HUGE Size=0x%X", W.Size);
+ break;
+ case WOD_SET_FPREG:
+ OS << "SET_FPREG Reg=" << getRegisterNameV3(W.Register)
+ << format(", Offset=0x%X", W.Displacement);
+ break;
+ case WOD_SAVE_NONVOL:
+ OS << "SAVE_NONVOL Reg=" << getRegisterNameV3(W.Register)
+ << format(", Disp=0x%X", W.Displacement);
+ break;
+ case WOD_SAVE_NONVOL_FAR:
+ OS << "SAVE_NONVOL_FAR Reg=" << getRegisterNameV3(W.Register)
+ << format(", Disp=0x%X", W.Displacement);
+ break;
+ case WOD_SAVE_XMM128:
+ OS << "SAVE_XMM128 Reg=XMM" << static_cast<unsigned>(W.Register)
+ << format(", Disp=0x%X", W.Displacement);
+ break;
+ case WOD_SAVE_XMM128_FAR:
+ OS << "SAVE_XMM128_FAR Reg=XMM" << static_cast<unsigned>(W.Register)
+ << format(", Disp=0x%X", W.Displacement);
+ break;
+ case WOD_PUSH_CANONICAL_FRAME:
+ OS << "PUSH_CANONICAL_FRAME Type=" << static_cast<unsigned>(W.Type);
----------------
e-kud wrote:
> (Exact type values are defined by the OS; consult the Windows SDK headers.)
Do we want to describe them or keep as values for now?
https://github.com/llvm/llvm-project/pull/199120
More information about the llvm-commits
mailing list