DWARFDebugFrame.cpp revision 7bf3d6a0438485df61c438f26cfbaef2f8d8a3c4
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" 137bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky#include "llvm/Support/ErrorHandling.h" 1460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky#include "llvm/Support/Dwarf.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}; 2960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky FrameEntry(FrameKind K, DataExtractor D, uint64_t Offset, uint64_t Length) 30ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky : Kind(K), Data(D), 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 387bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// \brief Parse and store a sequence of CFI instructions from our data 397bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// stream, starting at Offset and ending at EndOffset. If everything 407bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// goes well, Offset should be equal to EndOffset when this method 417bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// returns. Otherwise, an error occurred. 427bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// TODO: Improve error reporting... 437bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky virtual void parseInstructions(uint32_t &Offset, 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 The data stream holding the section from which the entry was 55ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky /// parsed. 5660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky DataExtractor Data; 57ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky 58ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky /// \brief Offset of this entry in the section. 5960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t Offset; 60ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky 61ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky /// \brief Entry length as specified in DWARF. 6260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t Length; 637bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 647bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// An entry may contain CFI instructions. An instruction consists of an 657bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// opcode and an optional sequence of operands. 667bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky typedef std::vector<uint64_t> Operands; 677bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky struct Instruction { 687bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instruction(uint8_t Opcode) 697bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky : Opcode(Opcode) 707bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky {} 717bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 727bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky uint8_t Opcode; 737bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Operands Ops; 747bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky }; 757bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 767bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky std::vector<Instruction> Instructions; 777bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 787bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// Convenience methods to add a new instruction with the given opcode and 797bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky /// operands to the Instructions vector. 807bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky void addInstruction(uint8_t Opcode) { 817bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.push_back(Instruction(Opcode)); 827bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 837bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 847bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky void addInstruction(uint8_t Opcode, uint64_t Operand1) { 857bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.push_back(Instruction(Opcode)); 867bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.back().Ops.push_back(Operand1); 877bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 887bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 897bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) { 907bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.push_back(Instruction(Opcode)); 917bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.back().Ops.push_back(Operand1); 927bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Instructions.back().Ops.push_back(Operand2); 937bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 9460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky}; 9560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 967bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 977bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky// See DWARF standard v3, section 7.23 987bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Benderskyconst uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0; 997bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Benderskyconst uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f; 1007bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1017bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1027bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Benderskyvoid FrameEntry::parseInstructions(uint32_t &Offset, uint32_t EndOffset) { 1037bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky while (Offset < EndOffset) { 1047bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky uint8_t Opcode = Data.getU8(&Offset); 1057bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Some instructions have a primary opcode encoded in the top bits. 1067bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK; 1077bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1087bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky if (Primary) { 1097bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // If it's a primary opcode, the first operand is encoded in the bottom 1107bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // bits of the opcode itself. 1117bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK; 1127bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky switch (Primary) { 1137bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky default: llvm_unreachable("Impossible primary CFI opcode"); 1147bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_advance_loc: 1157bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_restore: 1167bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Primary, Op1); 1177bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1187bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_offset: 1197bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Primary, Op1, Data.getULEB128(&Offset)); 1207bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1217bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1227bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } else { 1237bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Extended opcode - its value is Opcode itself. 1247bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky switch (Opcode) { 1257bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky default: llvm_unreachable("Invalid extended CFI opcode"); 1267bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_nop: 1277bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_remember_state: 1287bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_restore_state: 1297bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // No operands 1307bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode); 1317bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1327bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_set_loc: 1337bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: Address 1347bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode, Data.getAddress(&Offset)); 1357bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1367bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_advance_loc1: 1377bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: 1-byte delta 1387bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode, Data.getU8(&Offset)); 1397bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1407bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_advance_loc2: 1417bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: 2-byte delta 1427bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode, Data.getU16(&Offset)); 1437bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1447bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_advance_loc4: 1457bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: 4-byte delta 1467bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode, Data.getU32(&Offset)); 1477bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1487bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_restore_extended: 1497bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_undefined: 1507bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_same_value: 1517bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_register: 1527bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_offset: 1537bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: ULEB128 1547bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode, Data.getULEB128(&Offset)); 1557bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1567bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_offset_sf: 1577bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: SLEB128 1587bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode, Data.getSLEB128(&Offset)); 1597bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1607bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_offset_extended: 1617bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_register: 1627bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa: 1637bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_val_offset: 1647bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: ULEB128, ULEB128 1657bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode, Data.getULEB128(&Offset), 1667bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Data.getULEB128(&Offset)); 1677bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1687bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_offset_extended_sf: 1697bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_sf: 1707bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_val_offset_sf: 1717bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // Operands: ULEB128, SLEB128 1727bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky addInstruction(Opcode, Data.getULEB128(&Offset), 1737bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Data.getSLEB128(&Offset)); 1747bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky break; 1757bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_def_cfa_expression: 1767bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_expression: 1777bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky case DW_CFA_val_expression: 1787bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // TODO: implement this 1797bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky report_fatal_error("Values with expressions not implemented yet!"); 1807bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1817bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1827bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1837bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky} 1847bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1857bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1867bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Benderskyvoid FrameEntry::dumpInstructions(raw_ostream &OS) const { 1877bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // TODO: at the moment only instruction names are dumped. Expand this to 1887bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky // dump operands as well. 1897bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky for (std::vector<Instruction>::const_iterator I = Instructions.begin(), 1907bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky E = Instructions.end(); 1917bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky I != E; ++I) { 1927bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky uint8_t Opcode = I->Opcode; 1937bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) 1947bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK; 1957bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << " " << CallFrameString(Opcode) << ":\n"; 1967bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 1977bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky} 1987bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 1997bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 20074b3c8da4800c7e8ba8f019879db29738ecc5f74Benjamin Kramernamespace { 2012e402d5b5f2fce8bfe29509cc771b9919946003bEli Bendersky/// \brief DWARF Common Information Entry (CIE) 20260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyclass CIE : public FrameEntry { 20360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskypublic: 20460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // CIEs (and FDEs) are simply container classes, so the only sensible way to 20560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // create them is by providing the full parsed contents in the constructor. 20660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky CIE(DataExtractor D, uint64_t Offset, uint64_t Length, uint8_t Version, 20760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky SmallString<8> Augmentation, uint64_t CodeAlignmentFactor, 20860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister) 20960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky : FrameEntry(FK_CIE, D, Offset, Length), Version(Version), 21060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky Augmentation(Augmentation), CodeAlignmentFactor(CodeAlignmentFactor), 21160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky DataAlignmentFactor(DataAlignmentFactor), 212ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky ReturnAddressRegister(ReturnAddressRegister) {} 21360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 2148a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky ~CIE() { 2158a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky } 2168a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky 21760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky void dumpHeader(raw_ostream &OS) const { 21890e01ac0ea5bdc6dd6bccd9c59c3acb04e339666NAKAMURA Takumi OS << format("%08x %08x %08x CIE", 21990e01ac0ea5bdc6dd6bccd9c59c3acb04e339666NAKAMURA Takumi (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID) 22090e01ac0ea5bdc6dd6bccd9c59c3acb04e339666NAKAMURA Takumi << "\n"; 22160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << format(" Version: %d\n", Version); 22260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << " Augmentation: \"" << Augmentation << "\"\n"; 2237bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << format(" Code alignment factor: %u\n", 2247bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky (uint32_t)CodeAlignmentFactor); 2257bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << format(" Data alignment factor: %d\n", 2267bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky (int32_t)DataAlignmentFactor); 2277bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << format(" Return address column: %d\n", 2287bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky (int32_t)ReturnAddressRegister); 22960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << "\n"; 23060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 23160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 23260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky static bool classof(const FrameEntry *FE) { 23360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky return FE->getKind() == FK_CIE; 23460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 235ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky 23660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyprivate: 237ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky /// The following fields are defined in section 6.4.1 of the DWARF standard v3 23860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint8_t Version; 23960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky SmallString<8> Augmentation; 24060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t CodeAlignmentFactor; 24160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky int64_t DataAlignmentFactor; 24260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t ReturnAddressRegister; 24360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky}; 24460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 24560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 2462e402d5b5f2fce8bfe29509cc771b9919946003bEli Bendersky/// \brief DWARF Frame Description Entry (FDE) 24760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyclass FDE : public FrameEntry { 24860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskypublic: 24960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with 25060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // an offset to the CIE (provided by parsing the FDE header). The CIE itself 25160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // is obtained lazily once it's actually required. 252ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky FDE(DataExtractor D, uint64_t Offset, uint64_t Length, 253ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky int64_t LinkedCIEOffset, uint64_t InitialLocation, uint64_t AddressRange) 25460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky : FrameEntry(FK_FDE, D, Offset, Length), LinkedCIEOffset(LinkedCIEOffset), 25560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky InitialLocation(InitialLocation), AddressRange(AddressRange), 256ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky LinkedCIE(NULL) {} 25760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 2588a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky ~FDE() { 2598a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky } 2608a0329e6ffc290fb177fd058a64b4cf81d4b620aEli Bendersky 26160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky void dumpHeader(raw_ostream &OS) const { 26290e01ac0ea5bdc6dd6bccd9c59c3acb04e339666NAKAMURA Takumi OS << format("%08x %08x %08x FDE ", 263d9a8d43ed3e7c6c32f52ab5d0f627f7b1cdb6aacNAKAMURA Takumi (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset); 26460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << format("cie=%08x pc=%08x...%08x\n", 265d9a8d43ed3e7c6c32f52ab5d0f627f7b1cdb6aacNAKAMURA Takumi (int32_t)LinkedCIEOffset, 2668ff0631967c64d51b193b862aa0a6f1e8eb06f78NAKAMURA Takumi (uint32_t)InitialLocation, 2678ff0631967c64d51b193b862aa0a6f1e8eb06f78NAKAMURA Takumi (uint32_t)InitialLocation + (uint32_t)AddressRange); 268b2ac7c09b17efadea2a9f90f45801d9d2ee687aaEli Bendersky if (LinkedCIE) { 269b2ac7c09b17efadea2a9f90f45801d9d2ee687aaEli Bendersky OS << format("%p\n", LinkedCIE); 270b2ac7c09b17efadea2a9f90f45801d9d2ee687aaEli Bendersky } 27160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 27260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 27360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky static bool classof(const FrameEntry *FE) { 27460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky return FE->getKind() == FK_FDE; 27560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 27660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyprivate: 277ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky 278ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli Bendersky /// The following fields are defined in section 6.4.1 of the DWARF standard v3 27960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t LinkedCIEOffset; 28060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t InitialLocation; 28160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t AddressRange; 28260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky CIE *LinkedCIE; 28360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky}; 28474b3c8da4800c7e8ba8f019879db29738ecc5f74Benjamin Kramer} // end anonymous namespace 28560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 28660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 287ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli BenderskyDWARFDebugFrame::DWARFDebugFrame() { 28860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 28960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 29060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 291ba42625074aa7f4f1324a5d6666bd0e302b57f2bEli BenderskyDWARFDebugFrame::~DWARFDebugFrame() { 29260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky for (EntryVector::iterator I = Entries.begin(), E = Entries.end(); 29360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky I != E; ++I) { 29460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky delete *I; 29560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 29660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 29760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 29860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 29960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskystatic void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, 30060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint32_t Offset, int Length) { 30160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky errs() << "DUMP: "; 30260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky for (int i = 0; i < Length; ++i) { 30360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint8_t c = Data.getU8(&Offset); 30460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky errs().write_hex(c); errs() << " "; 30560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 30660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky errs() << "\n"; 30760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 30860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 30960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 31060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyvoid DWARFDebugFrame::parse(DataExtractor Data) { 31160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint32_t Offset = 0; 31260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 31360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky while (Data.isValidOffset(Offset)) { 31460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint32_t StartOffset = Offset; 31560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 31660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky bool IsDWARF64 = false; 31760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t Length = Data.getU32(&Offset); 31860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t Id; 31960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 32060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky if (Length == UINT32_MAX) { 32160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // DWARF-64 is distinguished by the first 32 bits of the initial length 32260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // field being 0xffffffff. Then, the next 64 bits are the actual entry 32360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // length. 32460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky IsDWARF64 = true; 32560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky Length = Data.getU64(&Offset); 32660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 32760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 32860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // At this point, Offset points to the next field after Length. 32960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // Length is the structure size excluding itself. Compute an offset one 33060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // past the end of the structure (needed to know how many instructions to 33160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // read). 33260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // TODO: For honest DWARF64 support, DataExtractor will have to treat 33360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // offset_ptr as uint64_t* 33460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length); 33560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 33660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // The Id field's size depends on the DWARF format 33760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4); 33860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID); 33960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 34060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky if (IsCIE) { 34160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // Note: this is specifically DWARFv3 CIE header structure. It was 34260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // changed in DWARFv4. 34360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint8_t Version = Data.getU8(&Offset); 34460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky const char *Augmentation = Data.getCStr(&Offset); 34560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset); 34660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky int64_t DataAlignmentFactor = Data.getSLEB128(&Offset); 34760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t ReturnAddressRegister = Data.getULEB128(&Offset); 34860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 34960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky CIE *NewCIE = new CIE(Data, StartOffset, Length, Version, 35060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky StringRef(Augmentation), CodeAlignmentFactor, 35160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky DataAlignmentFactor, ReturnAddressRegister); 35260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky Entries.push_back(NewCIE); 35360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } else { 35460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky // FDE 35560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t CIEPointer = Id; 35660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t InitialLocation = Data.getAddress(&Offset); 35760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky uint64_t AddressRange = Data.getAddress(&Offset); 35860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 35960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky FDE *NewFDE = new FDE(Data, StartOffset, Length, CIEPointer, 36060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky InitialLocation, AddressRange); 36160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky Entries.push_back(NewFDE); 36260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 36360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 3647bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Entries.back()->parseInstructions(Offset, EndStructureOffset); 3657bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky 3667bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky if (Offset != EndStructureOffset) { 3677bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky std::string Str; 3687bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky raw_string_ostream OS(Str); 3697bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << format("Parsing entry instructions at %lx failed", 3707bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Entries.back()->getOffset()); 3717bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky report_fatal_error(Str); 3727bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky } 37360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 37460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 37560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 37660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 37760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyvoid DWARFDebugFrame::dump(raw_ostream &OS) const { 37860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky OS << "\n"; 37960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky for (EntryVector::const_iterator I = Entries.begin(), E = Entries.end(); 38060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky I != E; ++I) { 3817bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky FrameEntry *Entry = *I; 3827bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Entry->dumpHeader(OS); 3837bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky Entry->dumpInstructions(OS); 3847bf3d6a0438485df61c438f26cfbaef2f8d8a3c4Eli Bendersky OS << "\n"; 38560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky } 38660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky} 38760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky 388