160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky//===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===// 260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky// 360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky// The LLVM Compiler Infrastructure 460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky// 560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky// This file is distributed under the University of Illinois Open Source 660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky// License. See LICENSE.TXT for details. 760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky// 860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky//===----------------------------------------------------------------------===// 960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 1060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky#include "DWARFDebugFrame.h" 1160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky#include "llvm/ADT/SmallString.h" 1260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky#include "llvm/Support/DataTypes.h" 1360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky#include "llvm/Support/Dwarf.h" 1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ErrorHandling.h" 1560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky#include "llvm/Support/Format.h" 167bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky#include "llvm/Support/raw_ostream.h" 177bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky#include <string> 187bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky#include <vector> 1960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 2060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyusing namespace llvm; 2160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyusing namespace dwarf; 2260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 2360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 242e402d5b5f2fce8bfe29509cc771b9919946003bEli Bendersky/// \brief Abstract frame entry defining the common interface concrete 252e402d5b5f2fce8bfe29509cc771b9919946003bEli Bendersky/// entries implement. 2660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyclass llvm::FrameEntry { 2760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskypublic: 2860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky enum FrameKind {FK_CIE, FK_FDE}; 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length) 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : Kind(K), Offset(Offset), Length(Length) {} 3160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 328a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky virtual ~FrameEntry() { 338a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky } 348a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky 3560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky FrameKind getKind() const { return Kind; } 367bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky virtual uint64_t getOffset() const { return Offset; } 3760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// \brief Parse and store a sequence of CFI instructions from Data, 39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// starting at *Offset and ending at EndOffset. If everything 4046e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky /// goes well, *Offset should be equal to EndOffset when this method 417bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// returns. Otherwise, an error occurred. 42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines virtual void parseInstructions(DataExtractor Data, uint32_t *Offset, 43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t EndOffset); 447bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 457bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// \brief Dump the entry header to the given output stream. 4660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky virtual void dumpHeader(raw_ostream &OS) const = 0; 47ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky 487bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// \brief Dump the entry's instructions to the given output stream. 497bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky virtual void dumpInstructions(raw_ostream &OS) const; 507bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 5160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyprotected: 5260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky const FrameKind Kind; 53ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky 54ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky /// \brief Offset of this entry in the section. 5560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t Offset; 56ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky 57ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky /// \brief Entry length as specified in DWARF. 5860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t Length; 597bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 607bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// An entry may contain CFI instructions. An instruction consists of an 617bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// opcode and an optional sequence of operands. 627bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky typedef std::vector<uint64_t> Operands; 637bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky struct Instruction { 647bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instruction(uint8_t Opcode) 657bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky : Opcode(Opcode) 667bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky {} 677bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 687bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky uint8_t Opcode; 697bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Operands Ops; 707bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky }; 717bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 727bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky std::vector<Instruction> Instructions; 737bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 747bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// Convenience methods to add a new instruction with the given opcode and 757bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// operands to the Instructions vector. 767bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky void addInstruction(uint8_t Opcode) { 777bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.push_back(Instruction(Opcode)); 787bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 797bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 807bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky void addInstruction(uint8_t Opcode, uint64_t Operand1) { 817bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.push_back(Instruction(Opcode)); 827bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.back().Ops.push_back(Operand1); 837bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 847bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 857bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) { 867bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.push_back(Instruction(Opcode)); 877bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.back().Ops.push_back(Operand1); 887bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.back().Ops.push_back(Operand2); 897bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 9060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky}; 9160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 927bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 937bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky// See DWARF standard v3, section 7.23 947bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Benderskyconst uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0; 957bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Benderskyconst uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f; 967bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset, 98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t EndOffset) { 9946e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky while (*Offset < EndOffset) { 10046e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky uint8_t Opcode = Data.getU8(Offset); 1017bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Some instructions have a primary opcode encoded in the top bits. 1027bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK; 1037bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1047bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky if (Primary) { 1057bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // If it's a primary opcode, the first operand is encoded in the bottom 1067bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // bits of the opcode itself. 1077bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK; 1087bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky switch (Primary) { 1097bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky default: llvm_unreachable("Impossible primary CFI opcode"); 1107bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_advance_loc: 1117bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_restore: 1127bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Primary, Op1); 1137bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1147bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_offset: 11546e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky addInstruction(Primary, Op1, Data.getULEB128(Offset)); 1167bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1177bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1187bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } else { 1197bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Extended opcode - its value is Opcode itself. 1207bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky switch (Opcode) { 1217bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky default: llvm_unreachable("Invalid extended CFI opcode"); 1227bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_nop: 1237bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_remember_state: 1247bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_restore_state: 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DW_CFA_GNU_window_save: 1267bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // No operands 1277bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode); 1287bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1297bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_set_loc: 1307bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: Address 13146e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky addInstruction(Opcode, Data.getAddress(Offset)); 1327bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1337bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_advance_loc1: 1347bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: 1-byte delta 13546e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky addInstruction(Opcode, Data.getU8(Offset)); 1367bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1377bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_advance_loc2: 1387bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: 2-byte delta 13946e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky addInstruction(Opcode, Data.getU16(Offset)); 1407bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1417bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_advance_loc4: 1427bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: 4-byte delta 14346e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky addInstruction(Opcode, Data.getU32(Offset)); 1447bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1457bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_restore_extended: 1467bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_undefined: 1477bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_same_value: 1487bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_register: 1497bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_offset: 1507bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: ULEB128 15146e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky addInstruction(Opcode, Data.getULEB128(Offset)); 1527bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1537bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_offset_sf: 1547bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: SLEB128 15546e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky addInstruction(Opcode, Data.getSLEB128(Offset)); 1567bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1577bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_offset_extended: 1587bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_register: 1597bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa: 1607bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_val_offset: 1617bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: ULEB128, ULEB128 16246e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky addInstruction(Opcode, Data.getULEB128(Offset), 16346e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky Data.getULEB128(Offset)); 1647bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1657bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_offset_extended_sf: 1667bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_sf: 1677bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_val_offset_sf: 1687bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: ULEB128, SLEB128 16946e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky addInstruction(Opcode, Data.getULEB128(Offset), 17046e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky Data.getSLEB128(Offset)); 1717bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1727bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_expression: 1737bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_expression: 1747bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_val_expression: 1757bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // TODO: implement this 1767bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky report_fatal_error("Values with expressions not implemented yet!"); 1777bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1787bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1797bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1807bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky} 1817bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1827bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1837bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Benderskyvoid FrameEntry::dumpInstructions(raw_ostream &OS) const { 1847bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // TODO: at the moment only instruction names are dumped. Expand this to 1857bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // dump operands as well. 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const auto &Instr : Instructions) { 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Opcode = Instr.Opcode; 1887bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) 1897bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK; 1907bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << " " << CallFrameString(Opcode) << ":\n"; 1917bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1927bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky} 1937bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1947bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 19574b3c8da4800c7e8ba8f019879db29738ecc5f74Benjamin Kramernamespace { 1962e402d5b5f2fce8bfe29509cc771b9919946003bEli Bendersky/// \brief DWARF Common Information Entry (CIE) 19760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyclass CIE : public FrameEntry { 19860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskypublic: 19960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // CIEs (and FDEs) are simply container classes, so the only sensible way to 20060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // create them is by providing the full parsed contents in the constructor. 201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CIE(uint64_t Offset, uint64_t Length, uint8_t Version, 20260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky SmallString<8> Augmentation, uint64_t CodeAlignmentFactor, 20360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister) 204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : FrameEntry(FK_CIE, Offset, Length), Version(Version), 205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Augmentation(Augmentation), CodeAlignmentFactor(CodeAlignmentFactor), 206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DataAlignmentFactor(DataAlignmentFactor), 207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ReturnAddressRegister(ReturnAddressRegister) {} 20860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 2098a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky ~CIE() { 2108a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky } 2118a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void dumpHeader(raw_ostream &OS) const override { 21390e01ac0ea5bdc6dd6bccd9c59c3acb04e339666NAKAMURA Takumi OS << format("%08x %08x %08x CIE", 21490e01ac0ea5bdc6dd6bccd9c59c3acb04e339666NAKAMURA Takumi (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID) 21590e01ac0ea5bdc6dd6bccd9c59c3acb04e339666NAKAMURA Takumi << "\n"; 21660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << format(" Version: %d\n", Version); 21760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << " Augmentation: \"" << Augmentation << "\"\n"; 2187bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << format(" Code alignment factor: %u\n", 2197bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky (uint32_t)CodeAlignmentFactor); 2207bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << format(" Data alignment factor: %d\n", 2217bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky (int32_t)DataAlignmentFactor); 2227bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << format(" Return address column: %d\n", 2237bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky (int32_t)ReturnAddressRegister); 22460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << "\n"; 22560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 22660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 22760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky static bool classof(const FrameEntry *FE) { 22860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky return FE->getKind() == FK_CIE; 229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 230ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky 23160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyprivate: 232ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky /// The following fields are defined in section 6.4.1 of the DWARF standard v3 23360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint8_t Version; 23460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky SmallString<8> Augmentation; 23560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t CodeAlignmentFactor; 23660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky int64_t DataAlignmentFactor; 23760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t ReturnAddressRegister; 23860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky}; 23960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 24060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 2412e402d5b5f2fce8bfe29509cc771b9919946003bEli Bendersky/// \brief DWARF Frame Description Entry (FDE) 24260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyclass FDE : public FrameEntry { 24360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskypublic: 24460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with 24560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // an offset to the CIE (provided by parsing the FDE header). The CIE itself 24660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // is obtained lazily once it's actually required. 247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset, 248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t InitialLocation, uint64_t AddressRange) 249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset), 250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines InitialLocation(InitialLocation), AddressRange(AddressRange), 251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines LinkedCIE(nullptr) {} 25260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 2538a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky ~FDE() { 2548a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky } 2558a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky 25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void dumpHeader(raw_ostream &OS) const override { 25790e01ac0ea5bdc6dd6bccd9c59c3acb04e339666NAKAMURA Takumi OS << format("%08x %08x %08x FDE ", 258d9a8d43ed3e7c6c32f52ab5d0f627f7b1cdb6aacNAKAMURA Takumi (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset); 25960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << format("cie=%08x pc=%08x...%08x\n", 260d9a8d43ed3e7c6c32f52ab5d0f627f7b1cdb6aacNAKAMURA Takumi (int32_t)LinkedCIEOffset, 2618ff0631967c64d51b193b862aa0a6f1e8eb06f78NAKAMURA Takumi (uint32_t)InitialLocation, 2628ff0631967c64d51b193b862aa0a6f1e8eb06f78NAKAMURA Takumi (uint32_t)InitialLocation + (uint32_t)AddressRange); 263b2ac7c09b17efadea2a9f90f45801d9d2ee687aaEli Bendersky if (LinkedCIE) { 264b2ac7c09b17efadea2a9f90f45801d9d2ee687aaEli Bendersky OS << format("%p\n", LinkedCIE); 265b2ac7c09b17efadea2a9f90f45801d9d2ee687aaEli Bendersky } 26660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 26760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 26860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky static bool classof(const FrameEntry *FE) { 26960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky return FE->getKind() == FK_FDE; 270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 271ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky 272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesprivate: 273ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky /// The following fields are defined in section 6.4.1 of the DWARF standard v3 27460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t LinkedCIEOffset; 27560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t InitialLocation; 27660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t AddressRange; 27760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky CIE *LinkedCIE; 27860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky}; 27974b3c8da4800c7e8ba8f019879db29738ecc5f74Benjamin Kramer} // end anonymous namespace 28060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 28160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 282ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli BenderskyDWARFDebugFrame::DWARFDebugFrame() { 28360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 28460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 285ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli BenderskyDWARFDebugFrame::~DWARFDebugFrame() { 28660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 28760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 28860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskystatic void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, 28960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint32_t Offset, int Length) { 29060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky errs() << "DUMP: "; 29160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky for (int i = 0; i < Length; ++i) { 29260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint8_t c = Data.getU8(&Offset); 29360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky errs().write_hex(c); errs() << " "; 29460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 29560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky errs() << "\n"; 29660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 29760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 29860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 29960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyvoid DWARFDebugFrame::parse(DataExtractor Data) { 30060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint32_t Offset = 0; 30160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 30260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky while (Data.isValidOffset(Offset)) { 30360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint32_t StartOffset = Offset; 30460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 30560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky bool IsDWARF64 = false; 30660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t Length = Data.getU32(&Offset); 30760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t Id; 30860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 30960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky if (Length == UINT32_MAX) { 31060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // DWARF-64 is distinguished by the first 32 bits of the initial length 31160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // field being 0xffffffff. Then, the next 64 bits are the actual entry 31260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // length. 31360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky IsDWARF64 = true; 31460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky Length = Data.getU64(&Offset); 31560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 31660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 31760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // At this point, Offset points to the next field after Length. 31860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // Length is the structure size excluding itself. Compute an offset one 31960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // past the end of the structure (needed to know how many instructions to 32060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // read). 32160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // TODO: For honest DWARF64 support, DataExtractor will have to treat 32260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // offset_ptr as uint64_t* 32360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length); 32460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 32560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // The Id field's size depends on the DWARF format 32660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4); 32760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID); 32860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 32960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky if (IsCIE) { 33060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // Note: this is specifically DWARFv3 CIE header structure. It was 33146e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky // changed in DWARFv4. We currently don't support reading DWARFv4 33246e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky // here because LLVM itself does not emit it (and LLDB doesn't 33346e0d1d58c9c1f288cbf943e4c930efd1a2968afEli Bendersky // support it either). 33460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint8_t Version = Data.getU8(&Offset); 33560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky const char *Augmentation = Data.getCStr(&Offset); 33660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset); 33760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky int64_t DataAlignmentFactor = Data.getSLEB128(&Offset); 33860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t ReturnAddressRegister = Data.getULEB128(&Offset); 33960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Entries.emplace_back(new CIE(StartOffset, Length, Version, 341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef(Augmentation), CodeAlignmentFactor, 342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DataAlignmentFactor, ReturnAddressRegister)); 34360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } else { 34460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // FDE 34560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t CIEPointer = Id; 34660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t InitialLocation = Data.getAddress(&Offset); 34760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t AddressRange = Data.getAddress(&Offset); 34860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer, 350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines InitialLocation, AddressRange)); 35160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 35260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset); 3547bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Offset != EndStructureOffset) { 3567bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky std::string Str; 3577bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky raw_string_ostream OS(Str); 358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS << format("Parsing entry instructions at %lx failed", StartOffset); 3597bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky report_fatal_error(Str); 3607bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 36160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 36260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 36360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 36460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 36560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyvoid DWARFDebugFrame::dump(raw_ostream &OS) const { 36660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << "\n"; 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const auto &Entry : Entries) { 3687bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Entry->dumpHeader(OS); 3697bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Entry->dumpInstructions(OS); 3707bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << "\n"; 37160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 37260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 37360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 374