brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 4d879b6 Raw
119 lines · cpp
1//===- DWARFCFIPrinter.cpp - Print the cfi-portions of .debug_frame -------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/DebugInfo/DWARF/DWARFCFIPrinter.h"10#include "llvm/DebugInfo/DIContext.h"11#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"12#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"13#include "llvm/Support/Compiler.h"14#include "llvm/Support/ErrorHandling.h"15#include "llvm/Support/Format.h"16#include "llvm/Support/raw_ostream.h"17#include <cassert>18#include <cinttypes>19#include <cstdint>20#include <optional>21 22using namespace llvm;23using namespace dwarf;24 25static void printRegister(raw_ostream &OS, const DIDumpOptions &DumpOpts,26                          unsigned RegNum) {27  if (DumpOpts.GetNameForDWARFReg) {28    auto RegName = DumpOpts.GetNameForDWARFReg(RegNum, DumpOpts.IsEH);29    if (!RegName.empty()) {30      OS << RegName;31      return;32    }33  }34  OS << "reg" << RegNum;35}36 37/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.38static void printOperand(raw_ostream &OS, const DIDumpOptions &DumpOpts,39                         const CFIProgram &P,40                         const CFIProgram::Instruction &Instr,41                         unsigned OperandIdx, uint64_t Operand,42                         std::optional<uint64_t> &Address) {43  assert(OperandIdx < CFIProgram::MaxOperands);44  uint8_t Opcode = Instr.Opcode;45  CFIProgram::OperandType Type = P.getOperandTypes()[Opcode][OperandIdx];46 47  switch (Type) {48  case CFIProgram::OT_Unset: {49    OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";50    auto OpcodeName = P.callFrameString(Opcode);51    if (!OpcodeName.empty())52      OS << " " << OpcodeName;53    else54      OS << format(" Opcode %x", Opcode);55    break;56  }57  case CFIProgram::OT_None:58    break;59  case CFIProgram::OT_Address:60    OS << format(" %" PRIx64, Operand);61    Address = Operand;62    break;63  case CFIProgram::OT_Offset:64    // The offsets are all encoded in a unsigned form, but in practice65    // consumers use them signed. It's most certainly legacy due to66    // the lack of signed variants in the first Dwarf standards.67    OS << format(" %+" PRId64, int64_t(Operand));68    break;69  case CFIProgram::OT_FactoredCodeOffset: // Always Unsigned70    if (P.codeAlign())71      OS << format(" %" PRId64, Operand * P.codeAlign());72    else73      OS << format(" %" PRId64 "*code_alignment_factor", Operand);74    if (Address && P.codeAlign()) {75      *Address += Operand * P.codeAlign();76      OS << format(" to 0x%" PRIx64, *Address);77    }78    break;79  case CFIProgram::OT_SignedFactDataOffset:80    if (P.dataAlign())81      OS << format(" %" PRId64, int64_t(Operand) * P.dataAlign());82    else83      OS << format(" %" PRId64 "*data_alignment_factor", int64_t(Operand));84    break;85  case CFIProgram::OT_UnsignedFactDataOffset:86    if (P.dataAlign())87      OS << format(" %" PRId64, Operand * P.dataAlign());88    else89      OS << format(" %" PRId64 "*data_alignment_factor", Operand);90    break;91  case CFIProgram::OT_Register:92    OS << ' ';93    printRegister(OS, DumpOpts, Operand);94    break;95  case CFIProgram::OT_AddressSpace:96    OS << format(" in addrspace%" PRId64, Operand);97    break;98  case CFIProgram::OT_Expression:99    assert(Instr.Expression && "missing DWARFExpression object");100    OS << " ";101    printDwarfExpression(&Instr.Expression.value(), OS, DumpOpts, nullptr);102    break;103  }104}105 106void llvm::dwarf::printCFIProgram(const CFIProgram &P, raw_ostream &OS,107                                  const DIDumpOptions &DumpOpts,108                                  unsigned IndentLevel,109                                  std::optional<uint64_t> Address) {110  for (const auto &Instr : P) {111    uint8_t Opcode = Instr.Opcode;112    OS.indent(2 * IndentLevel);113    OS << P.callFrameString(Opcode) << ":";114    for (size_t i = 0; i < Instr.Ops.size(); ++i)115      printOperand(OS, DumpOpts, P, Instr, i, Instr.Ops[i], Address);116    OS << '\n';117  }118}119