[llvm] r230551 - [dwarfdump] Make debug_frame dump actually useful.
Frederic Riss
friss at apple.com
Wed Feb 25 13:30:22 PST 2015
Author: friss
Date: Wed Feb 25 15:30:22 2015
New Revision: 230551
URL: http://llvm.org/viewvc/llvm-project?rev=230551&view=rev
Log:
[dwarfdump] Make debug_frame dump actually useful.
This adds support for pretty-printing instruction operands. The new
output looks like:
00000000 00000010 ffffffff CIE
Version: 1
Augmentation:
Code alignment factor: 1
Data alignment factor: -4
Return address column: 8
DW_CFA_def_cfa: reg4 +4
DW_CFA_offset: reg8 -4
DW_CFA_nop:
DW_CFA_nop:
00000014 00000010 00000000 FDE cie=00000000 pc=00000000...00000022
DW_CFA_advance_loc: 3
DW_CFA_def_cfa_offset: +12
DW_CFA_nop:
Modified:
llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
llvm/trunk/test/DebugInfo/dwarfdump-debug-frame-simple.test
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp?rev=230551&r1=230550&r2=230551&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp Wed Feb 25 15:30:22 2015
@@ -8,7 +8,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
@@ -267,16 +269,147 @@ private:
uint64_t AddressRange;
CIE *LinkedCIE;
};
+
+/// \brief Types of operands to CF instructions.
+enum OperandType {
+ OT_Unset,
+ OT_None,
+ OT_Address,
+ OT_Offset,
+ OT_FactoredCodeOffset,
+ OT_SignedFactDataOffset,
+ OT_UnsignedFactDataOffset,
+ OT_Register,
+ OT_Expression
+};
+
} // end anonymous namespace
+/// \brief Initialize the array describing the types of operands.
+static ArrayRef<OperandType[2]> getOperandTypes() {
+ static OperandType OpTypes[DW_CFA_restore+1][2];
+
+#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
+ do { \
+ OpTypes[OP][0] = OPTYPE0; \
+ OpTypes[OP][1] = OPTYPE1; \
+ } while (0)
+#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
+#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
+
+ DECLARE_OP1(DW_CFA_set_loc, OT_Address);
+ DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
+ DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
+ DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
+ DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
+ DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
+ DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
+ DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
+ DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
+ DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
+ DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
+ DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
+ DECLARE_OP1(DW_CFA_undefined, OT_Register);
+ DECLARE_OP1(DW_CFA_same_value, OT_Register);
+ DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
+ DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
+ DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
+ DECLARE_OP1(DW_CFA_restore, OT_Register);
+ DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
+ DECLARE_OP0(DW_CFA_remember_state);
+ DECLARE_OP0(DW_CFA_restore_state);
+ DECLARE_OP0(DW_CFA_GNU_window_save);
+ DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
+ DECLARE_OP0(DW_CFA_nop);
+
+#undef DECLARE_OP0
+#undef DECLARE_OP1
+#undef DECLARE_OP2
+ return OpTypes;
+}
+
+static ArrayRef<OperandType[2]> OpTypes = getOperandTypes();
+
+/// \brief Print \p Opcode's operand number \p OperandIdx which has
+/// value \p Operand.
+static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx,
+ uint64_t Operand, uint64_t CodeAlignmentFactor,
+ int64_t DataAlignmentFactor) {
+ assert(OperandIdx < 2);
+ OperandType Type = OpTypes[Opcode][OperandIdx];
+
+ switch (Type) {
+ case OT_Unset:
+ OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
+ if (const char *OpcodeName = CallFrameString(Opcode))
+ OS << " " << OpcodeName;
+ else
+ OS << format(" Opcode %x", Opcode);
+ break;
+ case OT_None:
+ break;
+ case OT_Address:
+ OS << format(" %" PRIx64, Operand);
+ break;
+ case OT_Offset:
+ // The offsets are all encoded in a unsigned form, but in practice
+ // consumers use them signed. It's most certainly legacy due to
+ // the lack of signed variants in the first Dwarf standards.
+ OS << format(" %+" PRId64, int64_t(Operand));
+ break;
+ case OT_FactoredCodeOffset: // Always Unsigned
+ if (CodeAlignmentFactor)
+ OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
+ else
+ OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
+ break;
+ case OT_SignedFactDataOffset:
+ if (DataAlignmentFactor)
+ OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
+ else
+ OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
+ break;
+ case OT_UnsignedFactDataOffset:
+ if (DataAlignmentFactor)
+ OS << format(" %" PRId64, Operand * DataAlignmentFactor);
+ else
+ OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
+ break;
+ case OT_Register:
+ OS << format(" reg%d", Operand);
+ break;
+ case OT_Expression:
+ OS << " expression";
+ break;
+ }
+}
+
void FrameEntry::dumpInstructions(raw_ostream &OS) const {
- // TODO: at the moment only instruction names are dumped. Expand this to
- // dump operands as well.
+ uint64_t CodeAlignmentFactor = 0;
+ int64_t DataAlignmentFactor = 0;
+ const CIE *Cie = dyn_cast<CIE>(this);
+
+ if (!Cie)
+ Cie = cast<FDE>(this)->getLinkedCIE();
+ if (Cie) {
+ CodeAlignmentFactor = Cie->getCodeAlignmentFactor();
+ DataAlignmentFactor = Cie->getDataAlignmentFactor();
+ }
+
for (const auto &Instr : Instructions) {
uint8_t Opcode = Instr.Opcode;
if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
- OS << " " << CallFrameString(Opcode) << ":\n";
+ OS << " " << CallFrameString(Opcode) << ":";
+ for (unsigned i = 0; i < Instr.Ops.size(); ++i)
+ printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor,
+ DataAlignmentFactor);
+ OS << '\n';
}
}
Modified: llvm/trunk/test/DebugInfo/dwarfdump-debug-frame-simple.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/dwarfdump-debug-frame-simple.test?rev=230551&r1=230550&r2=230551&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/dwarfdump-debug-frame-simple.test (original)
+++ llvm/trunk/test/DebugInfo/dwarfdump-debug-frame-simple.test Wed Feb 25 15:30:22 2015
@@ -6,22 +6,22 @@
; FRAMES: 00000000 00000010 ffffffff CIE
; FRAMES: Version: 1
-; FRAMES: DW_CFA_def_cfa
-; FRAMES-NEXT: DW_CFA_offset
-; FRAMES-NEXT: DW_CFA_nop
-; FRAMES-NEXT: DW_CFA_nop
+; FRAMES: DW_CFA_def_cfa: reg4 +4
+; FRAMES-NEXT: DW_CFA_offset: reg8 -4
+; FRAMES-NEXT: DW_CFA_nop:
+; FRAMES-NEXT: DW_CFA_nop:
; FRAMES: 00000014 00000010 00000000 FDE cie=00000000 pc=00000000...00000022
-; FRAMES: DW_CFA_advance_loc
-; FRAMES-NEXT: DW_CFA_def_cfa_offset
-; FRAMES-NEXT: DW_CFA_nop
+; FRAMES: DW_CFA_advance_loc: 3
+; FRAMES-NEXT: DW_CFA_def_cfa_offset: +12
+; FRAMES-NEXT: DW_CFA_nop:
; FRAMES: 00000028 00000014 00000000 FDE cie=00000000 pc=00000030...00000080
-; FRAMES: DW_CFA_advance_loc
-; FRAMES-NEXT: DW_CFA_def_cfa_offset
-; FRAMES-NEXT: DW_CFA_offset
-; FRAMES-NEXT: DW_CFA_advance_loc
-; FRAMES-NEXT: DW_CFA_def_cfa_register
+; FRAMES: DW_CFA_advance_loc: 1
+; FRAMES-NEXT: DW_CFA_def_cfa_offset: +8
+; FRAMES-NEXT: DW_CFA_offset: reg5 -8
+; FRAMES-NEXT: DW_CFA_advance_loc: 2
+; FRAMES-NEXT: DW_CFA_def_cfa_register: reg5
; FRAMES-NOT: CIE
; FRAMES-NOT: FDE
More information about the llvm-commits
mailing list