1ff0cc061SDimitry Andric //===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===// 2ff0cc061SDimitry Andric // 3ff0cc061SDimitry Andric // The LLVM Compiler Infrastructure 4ff0cc061SDimitry Andric // 5ff0cc061SDimitry Andric // This file is distributed under the University of Illinois Open Source 6ff0cc061SDimitry Andric // License. See LICENSE.TXT for details. 7ff0cc061SDimitry Andric // 8ff0cc061SDimitry Andric //===----------------------------------------------------------------------===// 9ff0cc061SDimitry Andric 10ff0cc061SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" 11ff0cc061SDimitry Andric #include "llvm/ADT/ArrayRef.h" 12ff0cc061SDimitry Andric #include "llvm/ADT/DenseMap.h" 13ff0cc061SDimitry Andric #include "llvm/ADT/SmallString.h" 14ff0cc061SDimitry Andric #include "llvm/Support/Casting.h" 15ff0cc061SDimitry Andric #include "llvm/Support/DataTypes.h" 16ff0cc061SDimitry Andric #include "llvm/Support/Dwarf.h" 17ff0cc061SDimitry Andric #include "llvm/Support/ErrorHandling.h" 18ff0cc061SDimitry Andric #include "llvm/Support/Format.h" 19ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h" 20ff0cc061SDimitry Andric #include <string> 21ff0cc061SDimitry Andric #include <vector> 22ff0cc061SDimitry Andric 23ff0cc061SDimitry Andric using namespace llvm; 24ff0cc061SDimitry Andric using namespace dwarf; 25ff0cc061SDimitry Andric 26ff0cc061SDimitry Andric 27ff0cc061SDimitry Andric /// \brief Abstract frame entry defining the common interface concrete 28ff0cc061SDimitry Andric /// entries implement. 29ff0cc061SDimitry Andric class llvm::FrameEntry { 30ff0cc061SDimitry Andric public: 31ff0cc061SDimitry Andric enum FrameKind {FK_CIE, FK_FDE}; 32ff0cc061SDimitry Andric FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length) 33ff0cc061SDimitry Andric : Kind(K), Offset(Offset), Length(Length) {} 34ff0cc061SDimitry Andric 35ff0cc061SDimitry Andric virtual ~FrameEntry() { 36ff0cc061SDimitry Andric } 37ff0cc061SDimitry Andric 38ff0cc061SDimitry Andric FrameKind getKind() const { return Kind; } 39ff0cc061SDimitry Andric virtual uint64_t getOffset() const { return Offset; } 40ff0cc061SDimitry Andric 41ff0cc061SDimitry Andric /// \brief Parse and store a sequence of CFI instructions from Data, 42ff0cc061SDimitry Andric /// starting at *Offset and ending at EndOffset. If everything 43ff0cc061SDimitry Andric /// goes well, *Offset should be equal to EndOffset when this method 44ff0cc061SDimitry Andric /// returns. Otherwise, an error occurred. 45ff0cc061SDimitry Andric virtual void parseInstructions(DataExtractor Data, uint32_t *Offset, 46ff0cc061SDimitry Andric uint32_t EndOffset); 47ff0cc061SDimitry Andric 48ff0cc061SDimitry Andric /// \brief Dump the entry header to the given output stream. 49ff0cc061SDimitry Andric virtual void dumpHeader(raw_ostream &OS) const = 0; 50ff0cc061SDimitry Andric 51ff0cc061SDimitry Andric /// \brief Dump the entry's instructions to the given output stream. 52ff0cc061SDimitry Andric virtual void dumpInstructions(raw_ostream &OS) const; 53ff0cc061SDimitry Andric 54ff0cc061SDimitry Andric protected: 55ff0cc061SDimitry Andric const FrameKind Kind; 56ff0cc061SDimitry Andric 57ff0cc061SDimitry Andric /// \brief Offset of this entry in the section. 58ff0cc061SDimitry Andric uint64_t Offset; 59ff0cc061SDimitry Andric 60ff0cc061SDimitry Andric /// \brief Entry length as specified in DWARF. 61ff0cc061SDimitry Andric uint64_t Length; 62ff0cc061SDimitry Andric 63ff0cc061SDimitry Andric /// An entry may contain CFI instructions. An instruction consists of an 64ff0cc061SDimitry Andric /// opcode and an optional sequence of operands. 65ff0cc061SDimitry Andric typedef std::vector<uint64_t> Operands; 66ff0cc061SDimitry Andric struct Instruction { 67ff0cc061SDimitry Andric Instruction(uint8_t Opcode) 68ff0cc061SDimitry Andric : Opcode(Opcode) 69ff0cc061SDimitry Andric {} 70ff0cc061SDimitry Andric 71ff0cc061SDimitry Andric uint8_t Opcode; 72ff0cc061SDimitry Andric Operands Ops; 73ff0cc061SDimitry Andric }; 74ff0cc061SDimitry Andric 75ff0cc061SDimitry Andric std::vector<Instruction> Instructions; 76ff0cc061SDimitry Andric 77ff0cc061SDimitry Andric /// Convenience methods to add a new instruction with the given opcode and 78ff0cc061SDimitry Andric /// operands to the Instructions vector. 79ff0cc061SDimitry Andric void addInstruction(uint8_t Opcode) { 80ff0cc061SDimitry Andric Instructions.push_back(Instruction(Opcode)); 81ff0cc061SDimitry Andric } 82ff0cc061SDimitry Andric 83ff0cc061SDimitry Andric void addInstruction(uint8_t Opcode, uint64_t Operand1) { 84ff0cc061SDimitry Andric Instructions.push_back(Instruction(Opcode)); 85ff0cc061SDimitry Andric Instructions.back().Ops.push_back(Operand1); 86ff0cc061SDimitry Andric } 87ff0cc061SDimitry Andric 88ff0cc061SDimitry Andric void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) { 89ff0cc061SDimitry Andric Instructions.push_back(Instruction(Opcode)); 90ff0cc061SDimitry Andric Instructions.back().Ops.push_back(Operand1); 91ff0cc061SDimitry Andric Instructions.back().Ops.push_back(Operand2); 92ff0cc061SDimitry Andric } 93ff0cc061SDimitry Andric }; 94ff0cc061SDimitry Andric 95ff0cc061SDimitry Andric 96ff0cc061SDimitry Andric // See DWARF standard v3, section 7.23 97ff0cc061SDimitry Andric const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0; 98ff0cc061SDimitry Andric const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f; 99ff0cc061SDimitry Andric 100ff0cc061SDimitry Andric void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset, 101ff0cc061SDimitry Andric uint32_t EndOffset) { 102ff0cc061SDimitry Andric while (*Offset < EndOffset) { 103ff0cc061SDimitry Andric uint8_t Opcode = Data.getU8(Offset); 104ff0cc061SDimitry Andric // Some instructions have a primary opcode encoded in the top bits. 105ff0cc061SDimitry Andric uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK; 106ff0cc061SDimitry Andric 107ff0cc061SDimitry Andric if (Primary) { 108ff0cc061SDimitry Andric // If it's a primary opcode, the first operand is encoded in the bottom 109ff0cc061SDimitry Andric // bits of the opcode itself. 110ff0cc061SDimitry Andric uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK; 111ff0cc061SDimitry Andric switch (Primary) { 112ff0cc061SDimitry Andric default: llvm_unreachable("Impossible primary CFI opcode"); 113ff0cc061SDimitry Andric case DW_CFA_advance_loc: 114ff0cc061SDimitry Andric case DW_CFA_restore: 115ff0cc061SDimitry Andric addInstruction(Primary, Op1); 116ff0cc061SDimitry Andric break; 117ff0cc061SDimitry Andric case DW_CFA_offset: 118ff0cc061SDimitry Andric addInstruction(Primary, Op1, Data.getULEB128(Offset)); 119ff0cc061SDimitry Andric break; 120ff0cc061SDimitry Andric } 121ff0cc061SDimitry Andric } else { 122ff0cc061SDimitry Andric // Extended opcode - its value is Opcode itself. 123ff0cc061SDimitry Andric switch (Opcode) { 124ff0cc061SDimitry Andric default: llvm_unreachable("Invalid extended CFI opcode"); 125ff0cc061SDimitry Andric case DW_CFA_nop: 126ff0cc061SDimitry Andric case DW_CFA_remember_state: 127ff0cc061SDimitry Andric case DW_CFA_restore_state: 128ff0cc061SDimitry Andric case DW_CFA_GNU_window_save: 129ff0cc061SDimitry Andric // No operands 130ff0cc061SDimitry Andric addInstruction(Opcode); 131ff0cc061SDimitry Andric break; 132ff0cc061SDimitry Andric case DW_CFA_set_loc: 133ff0cc061SDimitry Andric // Operands: Address 134ff0cc061SDimitry Andric addInstruction(Opcode, Data.getAddress(Offset)); 135ff0cc061SDimitry Andric break; 136ff0cc061SDimitry Andric case DW_CFA_advance_loc1: 137ff0cc061SDimitry Andric // Operands: 1-byte delta 138ff0cc061SDimitry Andric addInstruction(Opcode, Data.getU8(Offset)); 139ff0cc061SDimitry Andric break; 140ff0cc061SDimitry Andric case DW_CFA_advance_loc2: 141ff0cc061SDimitry Andric // Operands: 2-byte delta 142ff0cc061SDimitry Andric addInstruction(Opcode, Data.getU16(Offset)); 143ff0cc061SDimitry Andric break; 144ff0cc061SDimitry Andric case DW_CFA_advance_loc4: 145ff0cc061SDimitry Andric // Operands: 4-byte delta 146ff0cc061SDimitry Andric addInstruction(Opcode, Data.getU32(Offset)); 147ff0cc061SDimitry Andric break; 148ff0cc061SDimitry Andric case DW_CFA_restore_extended: 149ff0cc061SDimitry Andric case DW_CFA_undefined: 150ff0cc061SDimitry Andric case DW_CFA_same_value: 151ff0cc061SDimitry Andric case DW_CFA_def_cfa_register: 152ff0cc061SDimitry Andric case DW_CFA_def_cfa_offset: 153ff0cc061SDimitry Andric // Operands: ULEB128 154ff0cc061SDimitry Andric addInstruction(Opcode, Data.getULEB128(Offset)); 155ff0cc061SDimitry Andric break; 156ff0cc061SDimitry Andric case DW_CFA_def_cfa_offset_sf: 157ff0cc061SDimitry Andric // Operands: SLEB128 158ff0cc061SDimitry Andric addInstruction(Opcode, Data.getSLEB128(Offset)); 159ff0cc061SDimitry Andric break; 160ff0cc061SDimitry Andric case DW_CFA_offset_extended: 161ff0cc061SDimitry Andric case DW_CFA_register: 162ff0cc061SDimitry Andric case DW_CFA_def_cfa: 163ff0cc061SDimitry Andric case DW_CFA_val_offset: 164ff0cc061SDimitry Andric // Operands: ULEB128, ULEB128 165ff0cc061SDimitry Andric addInstruction(Opcode, Data.getULEB128(Offset), 166ff0cc061SDimitry Andric Data.getULEB128(Offset)); 167ff0cc061SDimitry Andric break; 168ff0cc061SDimitry Andric case DW_CFA_offset_extended_sf: 169ff0cc061SDimitry Andric case DW_CFA_def_cfa_sf: 170ff0cc061SDimitry Andric case DW_CFA_val_offset_sf: 171ff0cc061SDimitry Andric // Operands: ULEB128, SLEB128 172ff0cc061SDimitry Andric addInstruction(Opcode, Data.getULEB128(Offset), 173ff0cc061SDimitry Andric Data.getSLEB128(Offset)); 174ff0cc061SDimitry Andric break; 175ff0cc061SDimitry Andric case DW_CFA_def_cfa_expression: 176ff0cc061SDimitry Andric case DW_CFA_expression: 177ff0cc061SDimitry Andric case DW_CFA_val_expression: 178ff0cc061SDimitry Andric // TODO: implement this 179ff0cc061SDimitry Andric report_fatal_error("Values with expressions not implemented yet!"); 180ff0cc061SDimitry Andric } 181ff0cc061SDimitry Andric } 182ff0cc061SDimitry Andric } 183ff0cc061SDimitry Andric } 184ff0cc061SDimitry Andric 185ff0cc061SDimitry Andric namespace { 186ff0cc061SDimitry Andric /// \brief DWARF Common Information Entry (CIE) 187ff0cc061SDimitry Andric class CIE : public FrameEntry { 188ff0cc061SDimitry Andric public: 189ff0cc061SDimitry Andric // CIEs (and FDEs) are simply container classes, so the only sensible way to 190ff0cc061SDimitry Andric // create them is by providing the full parsed contents in the constructor. 191ff0cc061SDimitry Andric CIE(uint64_t Offset, uint64_t Length, uint8_t Version, 192ff0cc061SDimitry Andric SmallString<8> Augmentation, uint8_t AddressSize, 193ff0cc061SDimitry Andric uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor, 194ff0cc061SDimitry Andric int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister) 195ff0cc061SDimitry Andric : FrameEntry(FK_CIE, Offset, Length), Version(Version), 196ff0cc061SDimitry Andric Augmentation(std::move(Augmentation)), 197ff0cc061SDimitry Andric AddressSize(AddressSize), 198ff0cc061SDimitry Andric SegmentDescriptorSize(SegmentDescriptorSize), 199ff0cc061SDimitry Andric CodeAlignmentFactor(CodeAlignmentFactor), 200ff0cc061SDimitry Andric DataAlignmentFactor(DataAlignmentFactor), 201ff0cc061SDimitry Andric ReturnAddressRegister(ReturnAddressRegister) {} 202ff0cc061SDimitry Andric 203ff0cc061SDimitry Andric ~CIE() override {} 204ff0cc061SDimitry Andric 205ff0cc061SDimitry Andric uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; } 206ff0cc061SDimitry Andric int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; } 207ff0cc061SDimitry Andric 208ff0cc061SDimitry Andric void dumpHeader(raw_ostream &OS) const override { 209ff0cc061SDimitry Andric OS << format("%08x %08x %08x CIE", 210ff0cc061SDimitry Andric (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID) 211ff0cc061SDimitry Andric << "\n"; 212ff0cc061SDimitry Andric OS << format(" Version: %d\n", Version); 213ff0cc061SDimitry Andric OS << " Augmentation: \"" << Augmentation << "\"\n"; 214ff0cc061SDimitry Andric if (Version >= 4) { 215ff0cc061SDimitry Andric OS << format(" Address size: %u\n", 216ff0cc061SDimitry Andric (uint32_t)AddressSize); 217ff0cc061SDimitry Andric OS << format(" Segment desc size: %u\n", 218ff0cc061SDimitry Andric (uint32_t)SegmentDescriptorSize); 219ff0cc061SDimitry Andric } 220ff0cc061SDimitry Andric OS << format(" Code alignment factor: %u\n", 221ff0cc061SDimitry Andric (uint32_t)CodeAlignmentFactor); 222ff0cc061SDimitry Andric OS << format(" Data alignment factor: %d\n", 223ff0cc061SDimitry Andric (int32_t)DataAlignmentFactor); 224ff0cc061SDimitry Andric OS << format(" Return address column: %d\n", 225ff0cc061SDimitry Andric (int32_t)ReturnAddressRegister); 226ff0cc061SDimitry Andric OS << "\n"; 227ff0cc061SDimitry Andric } 228ff0cc061SDimitry Andric 229ff0cc061SDimitry Andric static bool classof(const FrameEntry *FE) { 230ff0cc061SDimitry Andric return FE->getKind() == FK_CIE; 231ff0cc061SDimitry Andric } 232ff0cc061SDimitry Andric 233ff0cc061SDimitry Andric private: 234ff0cc061SDimitry Andric /// The following fields are defined in section 6.4.1 of the DWARF standard v4 235ff0cc061SDimitry Andric uint8_t Version; 236ff0cc061SDimitry Andric SmallString<8> Augmentation; 237ff0cc061SDimitry Andric uint8_t AddressSize; 238ff0cc061SDimitry Andric uint8_t SegmentDescriptorSize; 239ff0cc061SDimitry Andric uint64_t CodeAlignmentFactor; 240ff0cc061SDimitry Andric int64_t DataAlignmentFactor; 241ff0cc061SDimitry Andric uint64_t ReturnAddressRegister; 242ff0cc061SDimitry Andric }; 243ff0cc061SDimitry Andric 244ff0cc061SDimitry Andric 245ff0cc061SDimitry Andric /// \brief DWARF Frame Description Entry (FDE) 246ff0cc061SDimitry Andric class FDE : public FrameEntry { 247ff0cc061SDimitry Andric public: 248ff0cc061SDimitry Andric // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with 249ff0cc061SDimitry Andric // an offset to the CIE (provided by parsing the FDE header). The CIE itself 250ff0cc061SDimitry Andric // is obtained lazily once it's actually required. 251ff0cc061SDimitry Andric FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset, 252ff0cc061SDimitry Andric uint64_t InitialLocation, uint64_t AddressRange, 253ff0cc061SDimitry Andric CIE *Cie) 254ff0cc061SDimitry Andric : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset), 255ff0cc061SDimitry Andric InitialLocation(InitialLocation), AddressRange(AddressRange), 256ff0cc061SDimitry Andric LinkedCIE(Cie) {} 257ff0cc061SDimitry Andric 258ff0cc061SDimitry Andric ~FDE() override {} 259ff0cc061SDimitry Andric 260ff0cc061SDimitry Andric CIE *getLinkedCIE() const { return LinkedCIE; } 261ff0cc061SDimitry Andric 262ff0cc061SDimitry Andric void dumpHeader(raw_ostream &OS) const override { 263ff0cc061SDimitry Andric OS << format("%08x %08x %08x FDE ", 264ff0cc061SDimitry Andric (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset); 265ff0cc061SDimitry Andric OS << format("cie=%08x pc=%08x...%08x\n", 266ff0cc061SDimitry Andric (int32_t)LinkedCIEOffset, 267ff0cc061SDimitry Andric (uint32_t)InitialLocation, 268ff0cc061SDimitry Andric (uint32_t)InitialLocation + (uint32_t)AddressRange); 269ff0cc061SDimitry Andric } 270ff0cc061SDimitry Andric 271ff0cc061SDimitry Andric static bool classof(const FrameEntry *FE) { 272ff0cc061SDimitry Andric return FE->getKind() == FK_FDE; 273ff0cc061SDimitry Andric } 274ff0cc061SDimitry Andric 275ff0cc061SDimitry Andric private: 276ff0cc061SDimitry Andric /// The following fields are defined in section 6.4.1 of the DWARF standard v3 277ff0cc061SDimitry Andric uint64_t LinkedCIEOffset; 278ff0cc061SDimitry Andric uint64_t InitialLocation; 279ff0cc061SDimitry Andric uint64_t AddressRange; 280ff0cc061SDimitry Andric CIE *LinkedCIE; 281ff0cc061SDimitry Andric }; 282ff0cc061SDimitry Andric 283ff0cc061SDimitry Andric /// \brief Types of operands to CF instructions. 284ff0cc061SDimitry Andric enum OperandType { 285ff0cc061SDimitry Andric OT_Unset, 286ff0cc061SDimitry Andric OT_None, 287ff0cc061SDimitry Andric OT_Address, 288ff0cc061SDimitry Andric OT_Offset, 289ff0cc061SDimitry Andric OT_FactoredCodeOffset, 290ff0cc061SDimitry Andric OT_SignedFactDataOffset, 291ff0cc061SDimitry Andric OT_UnsignedFactDataOffset, 292ff0cc061SDimitry Andric OT_Register, 293ff0cc061SDimitry Andric OT_Expression 294ff0cc061SDimitry Andric }; 295ff0cc061SDimitry Andric 296ff0cc061SDimitry Andric } // end anonymous namespace 297ff0cc061SDimitry Andric 298ff0cc061SDimitry Andric /// \brief Initialize the array describing the types of operands. 299ff0cc061SDimitry Andric static ArrayRef<OperandType[2]> getOperandTypes() { 300ff0cc061SDimitry Andric static OperandType OpTypes[DW_CFA_restore+1][2]; 301ff0cc061SDimitry Andric 302ff0cc061SDimitry Andric #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \ 303ff0cc061SDimitry Andric do { \ 304ff0cc061SDimitry Andric OpTypes[OP][0] = OPTYPE0; \ 305ff0cc061SDimitry Andric OpTypes[OP][1] = OPTYPE1; \ 306ff0cc061SDimitry Andric } while (0) 307ff0cc061SDimitry Andric #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None) 308ff0cc061SDimitry Andric #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None) 309ff0cc061SDimitry Andric 310ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_set_loc, OT_Address); 311ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset); 312ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset); 313ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset); 314ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset); 315ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset); 316ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset); 317ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset); 318ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register); 319ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset); 320ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset); 321ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression); 322ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_undefined, OT_Register); 323ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_same_value, OT_Register); 324ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset); 325ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset); 326ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset); 327ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset); 328ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset); 329ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register); 330ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression); 331ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression); 332ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_restore, OT_Register); 333ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_restore_extended, OT_Register); 334ff0cc061SDimitry Andric DECLARE_OP0(DW_CFA_remember_state); 335ff0cc061SDimitry Andric DECLARE_OP0(DW_CFA_restore_state); 336ff0cc061SDimitry Andric DECLARE_OP0(DW_CFA_GNU_window_save); 337ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset); 338ff0cc061SDimitry Andric DECLARE_OP0(DW_CFA_nop); 339ff0cc061SDimitry Andric 340ff0cc061SDimitry Andric #undef DECLARE_OP0 341ff0cc061SDimitry Andric #undef DECLARE_OP1 342ff0cc061SDimitry Andric #undef DECLARE_OP2 343ff0cc061SDimitry Andric return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1); 344ff0cc061SDimitry Andric } 345ff0cc061SDimitry Andric 346ff0cc061SDimitry Andric static ArrayRef<OperandType[2]> OpTypes = getOperandTypes(); 347ff0cc061SDimitry Andric 348ff0cc061SDimitry Andric /// \brief Print \p Opcode's operand number \p OperandIdx which has 349ff0cc061SDimitry Andric /// value \p Operand. 350ff0cc061SDimitry Andric static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx, 351ff0cc061SDimitry Andric uint64_t Operand, uint64_t CodeAlignmentFactor, 352ff0cc061SDimitry Andric int64_t DataAlignmentFactor) { 353ff0cc061SDimitry Andric assert(OperandIdx < 2); 354ff0cc061SDimitry Andric OperandType Type = OpTypes[Opcode][OperandIdx]; 355ff0cc061SDimitry Andric 356ff0cc061SDimitry Andric switch (Type) { 357ff0cc061SDimitry Andric case OT_Unset: 358ff0cc061SDimitry Andric OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to"; 359ff0cc061SDimitry Andric if (const char *OpcodeName = CallFrameString(Opcode)) 360ff0cc061SDimitry Andric OS << " " << OpcodeName; 361ff0cc061SDimitry Andric else 362ff0cc061SDimitry Andric OS << format(" Opcode %x", Opcode); 363ff0cc061SDimitry Andric break; 364ff0cc061SDimitry Andric case OT_None: 365ff0cc061SDimitry Andric break; 366ff0cc061SDimitry Andric case OT_Address: 367ff0cc061SDimitry Andric OS << format(" %" PRIx64, Operand); 368ff0cc061SDimitry Andric break; 369ff0cc061SDimitry Andric case OT_Offset: 370ff0cc061SDimitry Andric // The offsets are all encoded in a unsigned form, but in practice 371ff0cc061SDimitry Andric // consumers use them signed. It's most certainly legacy due to 372ff0cc061SDimitry Andric // the lack of signed variants in the first Dwarf standards. 373ff0cc061SDimitry Andric OS << format(" %+" PRId64, int64_t(Operand)); 374ff0cc061SDimitry Andric break; 375ff0cc061SDimitry Andric case OT_FactoredCodeOffset: // Always Unsigned 376ff0cc061SDimitry Andric if (CodeAlignmentFactor) 377ff0cc061SDimitry Andric OS << format(" %" PRId64, Operand * CodeAlignmentFactor); 378ff0cc061SDimitry Andric else 379ff0cc061SDimitry Andric OS << format(" %" PRId64 "*code_alignment_factor" , Operand); 380ff0cc061SDimitry Andric break; 381ff0cc061SDimitry Andric case OT_SignedFactDataOffset: 382ff0cc061SDimitry Andric if (DataAlignmentFactor) 383ff0cc061SDimitry Andric OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor); 384ff0cc061SDimitry Andric else 385ff0cc061SDimitry Andric OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand)); 386ff0cc061SDimitry Andric break; 387ff0cc061SDimitry Andric case OT_UnsignedFactDataOffset: 388ff0cc061SDimitry Andric if (DataAlignmentFactor) 389ff0cc061SDimitry Andric OS << format(" %" PRId64, Operand * DataAlignmentFactor); 390ff0cc061SDimitry Andric else 391ff0cc061SDimitry Andric OS << format(" %" PRId64 "*data_alignment_factor" , Operand); 392ff0cc061SDimitry Andric break; 393ff0cc061SDimitry Andric case OT_Register: 394ff0cc061SDimitry Andric OS << format(" reg%" PRId64, Operand); 395ff0cc061SDimitry Andric break; 396ff0cc061SDimitry Andric case OT_Expression: 397ff0cc061SDimitry Andric OS << " expression"; 398ff0cc061SDimitry Andric break; 399ff0cc061SDimitry Andric } 400ff0cc061SDimitry Andric } 401ff0cc061SDimitry Andric 402ff0cc061SDimitry Andric void FrameEntry::dumpInstructions(raw_ostream &OS) const { 403ff0cc061SDimitry Andric uint64_t CodeAlignmentFactor = 0; 404ff0cc061SDimitry Andric int64_t DataAlignmentFactor = 0; 405ff0cc061SDimitry Andric const CIE *Cie = dyn_cast<CIE>(this); 406ff0cc061SDimitry Andric 407ff0cc061SDimitry Andric if (!Cie) 408ff0cc061SDimitry Andric Cie = cast<FDE>(this)->getLinkedCIE(); 409ff0cc061SDimitry Andric if (Cie) { 410ff0cc061SDimitry Andric CodeAlignmentFactor = Cie->getCodeAlignmentFactor(); 411ff0cc061SDimitry Andric DataAlignmentFactor = Cie->getDataAlignmentFactor(); 412ff0cc061SDimitry Andric } 413ff0cc061SDimitry Andric 414ff0cc061SDimitry Andric for (const auto &Instr : Instructions) { 415ff0cc061SDimitry Andric uint8_t Opcode = Instr.Opcode; 416ff0cc061SDimitry Andric if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) 417ff0cc061SDimitry Andric Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK; 418ff0cc061SDimitry Andric OS << " " << CallFrameString(Opcode) << ":"; 419ff0cc061SDimitry Andric for (unsigned i = 0; i < Instr.Ops.size(); ++i) 420ff0cc061SDimitry Andric printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor, 421ff0cc061SDimitry Andric DataAlignmentFactor); 422ff0cc061SDimitry Andric OS << '\n'; 423ff0cc061SDimitry Andric } 424ff0cc061SDimitry Andric } 425ff0cc061SDimitry Andric 426ff0cc061SDimitry Andric DWARFDebugFrame::DWARFDebugFrame() { 427ff0cc061SDimitry Andric } 428ff0cc061SDimitry Andric 429ff0cc061SDimitry Andric DWARFDebugFrame::~DWARFDebugFrame() { 430ff0cc061SDimitry Andric } 431ff0cc061SDimitry Andric 432ff0cc061SDimitry Andric static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, 433ff0cc061SDimitry Andric uint32_t Offset, int Length) { 434ff0cc061SDimitry Andric errs() << "DUMP: "; 435ff0cc061SDimitry Andric for (int i = 0; i < Length; ++i) { 436ff0cc061SDimitry Andric uint8_t c = Data.getU8(&Offset); 437ff0cc061SDimitry Andric errs().write_hex(c); errs() << " "; 438ff0cc061SDimitry Andric } 439ff0cc061SDimitry Andric errs() << "\n"; 440ff0cc061SDimitry Andric } 441ff0cc061SDimitry Andric 442ff0cc061SDimitry Andric 443ff0cc061SDimitry Andric void DWARFDebugFrame::parse(DataExtractor Data) { 444ff0cc061SDimitry Andric uint32_t Offset = 0; 445ff0cc061SDimitry Andric DenseMap<uint32_t, CIE *> CIEs; 446ff0cc061SDimitry Andric 447ff0cc061SDimitry Andric while (Data.isValidOffset(Offset)) { 448ff0cc061SDimitry Andric uint32_t StartOffset = Offset; 449ff0cc061SDimitry Andric 450ff0cc061SDimitry Andric bool IsDWARF64 = false; 451ff0cc061SDimitry Andric uint64_t Length = Data.getU32(&Offset); 452ff0cc061SDimitry Andric uint64_t Id; 453ff0cc061SDimitry Andric 454ff0cc061SDimitry Andric if (Length == UINT32_MAX) { 455ff0cc061SDimitry Andric // DWARF-64 is distinguished by the first 32 bits of the initial length 456ff0cc061SDimitry Andric // field being 0xffffffff. Then, the next 64 bits are the actual entry 457ff0cc061SDimitry Andric // length. 458ff0cc061SDimitry Andric IsDWARF64 = true; 459ff0cc061SDimitry Andric Length = Data.getU64(&Offset); 460ff0cc061SDimitry Andric } 461ff0cc061SDimitry Andric 462ff0cc061SDimitry Andric // At this point, Offset points to the next field after Length. 463ff0cc061SDimitry Andric // Length is the structure size excluding itself. Compute an offset one 464ff0cc061SDimitry Andric // past the end of the structure (needed to know how many instructions to 465ff0cc061SDimitry Andric // read). 466ff0cc061SDimitry Andric // TODO: For honest DWARF64 support, DataExtractor will have to treat 467ff0cc061SDimitry Andric // offset_ptr as uint64_t* 468ff0cc061SDimitry Andric uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length); 469ff0cc061SDimitry Andric 470ff0cc061SDimitry Andric // The Id field's size depends on the DWARF format 471ff0cc061SDimitry Andric Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4); 472ff0cc061SDimitry Andric bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID); 473ff0cc061SDimitry Andric 474ff0cc061SDimitry Andric if (IsCIE) { 475ff0cc061SDimitry Andric uint8_t Version = Data.getU8(&Offset); 476ff0cc061SDimitry Andric const char *Augmentation = Data.getCStr(&Offset); 477ff0cc061SDimitry Andric uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : Data.getU8(&Offset); 478ff0cc061SDimitry Andric Data.setAddressSize(AddressSize); 479ff0cc061SDimitry Andric uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset); 480ff0cc061SDimitry Andric uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset); 481ff0cc061SDimitry Andric int64_t DataAlignmentFactor = Data.getSLEB128(&Offset); 482ff0cc061SDimitry Andric uint64_t ReturnAddressRegister = Data.getULEB128(&Offset); 483ff0cc061SDimitry Andric 484ff0cc061SDimitry Andric auto Cie = make_unique<CIE>(StartOffset, Length, Version, 485ff0cc061SDimitry Andric StringRef(Augmentation), AddressSize, 486ff0cc061SDimitry Andric SegmentDescriptorSize, CodeAlignmentFactor, 487ff0cc061SDimitry Andric DataAlignmentFactor, ReturnAddressRegister); 488ff0cc061SDimitry Andric CIEs[StartOffset] = Cie.get(); 489ff0cc061SDimitry Andric Entries.emplace_back(std::move(Cie)); 490ff0cc061SDimitry Andric } else { 491ff0cc061SDimitry Andric // FDE 492ff0cc061SDimitry Andric uint64_t CIEPointer = Id; 493ff0cc061SDimitry Andric uint64_t InitialLocation = Data.getAddress(&Offset); 494ff0cc061SDimitry Andric uint64_t AddressRange = Data.getAddress(&Offset); 495ff0cc061SDimitry Andric 496ff0cc061SDimitry Andric Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer, 497ff0cc061SDimitry Andric InitialLocation, AddressRange, 498ff0cc061SDimitry Andric CIEs[CIEPointer])); 499ff0cc061SDimitry Andric } 500ff0cc061SDimitry Andric 501ff0cc061SDimitry Andric Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset); 502ff0cc061SDimitry Andric 503ff0cc061SDimitry Andric if (Offset != EndStructureOffset) { 504ff0cc061SDimitry Andric std::string Str; 505ff0cc061SDimitry Andric raw_string_ostream OS(Str); 506ff0cc061SDimitry Andric OS << format("Parsing entry instructions at %lx failed", StartOffset); 507ff0cc061SDimitry Andric report_fatal_error(Str); 508ff0cc061SDimitry Andric } 509ff0cc061SDimitry Andric } 510ff0cc061SDimitry Andric } 511ff0cc061SDimitry Andric 512ff0cc061SDimitry Andric 513ff0cc061SDimitry Andric void DWARFDebugFrame::dump(raw_ostream &OS) const { 514ff0cc061SDimitry Andric OS << "\n"; 515ff0cc061SDimitry Andric for (const auto &Entry : Entries) { 516ff0cc061SDimitry Andric Entry->dumpHeader(OS); 517ff0cc061SDimitry Andric Entry->dumpInstructions(OS); 518ff0cc061SDimitry Andric OS << "\n"; 519ff0cc061SDimitry Andric } 520ff0cc061SDimitry Andric } 521ff0cc061SDimitry Andric 522