brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · eaf56b3 Raw
204 lines · cpp
1//===- DWARFCFIProgram.cpp - Parsing 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/LowLevel/DWARFCFIProgram.h"10#include "llvm/Support/Compiler.h"11#include "llvm/Support/Errc.h"12#include "llvm/Support/ErrorHandling.h"13#include "llvm/Support/raw_ostream.h"14#include <cassert>15#include <cinttypes>16#include <cstdint>17 18using namespace llvm;19using namespace dwarf;20 21StringRef CFIProgram::callFrameString(unsigned Opcode) const {22  return dwarf::CallFrameString(Opcode, Arch);23}24 25const char *CFIProgram::operandTypeString(CFIProgram::OperandType OT) {26#define ENUM_TO_CSTR(e)                                                        \27  case e:                                                                      \28    return #e;29  switch (OT) {30    ENUM_TO_CSTR(OT_Unset);31    ENUM_TO_CSTR(OT_None);32    ENUM_TO_CSTR(OT_Address);33    ENUM_TO_CSTR(OT_Offset);34    ENUM_TO_CSTR(OT_FactoredCodeOffset);35    ENUM_TO_CSTR(OT_SignedFactDataOffset);36    ENUM_TO_CSTR(OT_UnsignedFactDataOffset);37    ENUM_TO_CSTR(OT_Register);38    ENUM_TO_CSTR(OT_AddressSpace);39    ENUM_TO_CSTR(OT_Expression);40  }41  return "<unknown CFIProgram::OperandType>";42}43 44llvm::Expected<uint64_t>45CFIProgram::Instruction::getOperandAsUnsigned(const CFIProgram &CFIP,46                                              uint32_t OperandIdx) const {47  if (OperandIdx >= MaxOperands)48    return createStringError(errc::invalid_argument,49                             "operand index %" PRIu32 " is not valid",50                             OperandIdx);51  OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];52  uint64_t Operand = Ops[OperandIdx];53  switch (Type) {54  case OT_Unset:55  case OT_None:56  case OT_Expression:57    return createStringError(errc::invalid_argument,58                             "op[%" PRIu32 "] has type %s which has no value",59                             OperandIdx, CFIProgram::operandTypeString(Type));60 61  case OT_Offset:62  case OT_SignedFactDataOffset:63  case OT_UnsignedFactDataOffset:64    return createStringError(65        errc::invalid_argument,66        "op[%" PRIu32 "] has OperandType OT_Offset which produces a signed "67        "result, call getOperandAsSigned instead",68        OperandIdx);69 70  case OT_Address:71  case OT_Register:72  case OT_AddressSpace:73    return Operand;74 75  case OT_FactoredCodeOffset: {76    const uint64_t CodeAlignmentFactor = CFIP.codeAlign();77    if (CodeAlignmentFactor == 0)78      return createStringError(79          errc::invalid_argument,80          "op[%" PRIu32 "] has type OT_FactoredCodeOffset but code alignment "81          "is zero",82          OperandIdx);83    return Operand * CodeAlignmentFactor;84  }85  }86  llvm_unreachable("invalid operand type");87}88 89llvm::Expected<int64_t>90CFIProgram::Instruction::getOperandAsSigned(const CFIProgram &CFIP,91                                            uint32_t OperandIdx) const {92  if (OperandIdx >= MaxOperands)93    return createStringError(errc::invalid_argument,94                             "operand index %" PRIu32 " is not valid",95                             OperandIdx);96  OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];97  uint64_t Operand = Ops[OperandIdx];98  switch (Type) {99  case OT_Unset:100  case OT_None:101  case OT_Expression:102    return createStringError(errc::invalid_argument,103                             "op[%" PRIu32 "] has type %s which has no value",104                             OperandIdx, CFIProgram::operandTypeString(Type));105 106  case OT_Address:107  case OT_Register:108  case OT_AddressSpace:109    return createStringError(110        errc::invalid_argument,111        "op[%" PRIu32 "] has OperandType %s which produces an unsigned result, "112        "call getOperandAsUnsigned instead",113        OperandIdx, CFIProgram::operandTypeString(Type));114 115  case OT_Offset:116    return (int64_t)Operand;117 118  case OT_FactoredCodeOffset:119  case OT_SignedFactDataOffset: {120    const int64_t DataAlignmentFactor = CFIP.dataAlign();121    if (DataAlignmentFactor == 0)122      return createStringError(errc::invalid_argument,123                               "op[%" PRIu32 "] has type %s but data "124                               "alignment is zero",125                               OperandIdx, CFIProgram::operandTypeString(Type));126    return int64_t(Operand) * DataAlignmentFactor;127  }128 129  case OT_UnsignedFactDataOffset: {130    const int64_t DataAlignmentFactor = CFIP.dataAlign();131    if (DataAlignmentFactor == 0)132      return createStringError(errc::invalid_argument,133                               "op[%" PRIu32134                               "] has type OT_UnsignedFactDataOffset but data "135                               "alignment is zero",136                               OperandIdx);137    return Operand * DataAlignmentFactor;138  }139  }140  llvm_unreachable("invalid operand type");141}142 143ArrayRef<CFIProgram::OperandType[CFIProgram::MaxOperands]>144CFIProgram::getOperandTypes() {145  static OperandType OpTypes[DW_CFA_restore + 1][MaxOperands];146  static bool Initialized = false;147  if (Initialized) {148    return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);149  }150  Initialized = true;151 152#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2)                             \153  do {                                                                         \154    OpTypes[OP][0] = OPTYPE0;                                                  \155    OpTypes[OP][1] = OPTYPE1;                                                  \156    OpTypes[OP][2] = OPTYPE2;                                                  \157  } while (false)158#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)                                      \159  DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OT_None)160#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)161#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)162 163  DECLARE_OP1(DW_CFA_set_loc, OT_Address);164  DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);165  DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);166  DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);167  DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);168  DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);169  DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);170  DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);171  DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);172  DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa, OT_Register, OT_Offset,173              OT_AddressSpace);174  DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa_sf, OT_Register,175              OT_SignedFactDataOffset, OT_AddressSpace);176  DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);177  DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);178  DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);179  DECLARE_OP1(DW_CFA_undefined, OT_Register);180  DECLARE_OP1(DW_CFA_same_value, OT_Register);181  DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);182  DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);183  DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);184  DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);185  DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);186  DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);187  DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);188  DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);189  DECLARE_OP1(DW_CFA_restore, OT_Register);190  DECLARE_OP1(DW_CFA_restore_extended, OT_Register);191  DECLARE_OP0(DW_CFA_remember_state);192  DECLARE_OP0(DW_CFA_restore_state);193  DECLARE_OP0(DW_CFA_GNU_window_save);194  DECLARE_OP0(DW_CFA_AARCH64_negate_ra_state_with_pc);195  DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);196  DECLARE_OP0(DW_CFA_nop);197 198#undef DECLARE_OP0199#undef DECLARE_OP1200#undef DECLARE_OP2201 202  return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);203}204