Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
213845 views
//===- DWARFCFIProgram.cpp - Parsing the cfi-portions of .debug_frame -----===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"9#include "llvm/Support/Compiler.h"10#include "llvm/Support/Errc.h"11#include "llvm/Support/ErrorHandling.h"12#include "llvm/Support/raw_ostream.h"13#include <cassert>14#include <cinttypes>15#include <cstdint>1617using namespace llvm;18using namespace dwarf;1920StringRef CFIProgram::callFrameString(unsigned Opcode) const {21return dwarf::CallFrameString(Opcode, Arch);22}2324const char *CFIProgram::operandTypeString(CFIProgram::OperandType OT) {25#define ENUM_TO_CSTR(e) \26case e: \27return #e;28switch (OT) {29ENUM_TO_CSTR(OT_Unset);30ENUM_TO_CSTR(OT_None);31ENUM_TO_CSTR(OT_Address);32ENUM_TO_CSTR(OT_Offset);33ENUM_TO_CSTR(OT_FactoredCodeOffset);34ENUM_TO_CSTR(OT_SignedFactDataOffset);35ENUM_TO_CSTR(OT_UnsignedFactDataOffset);36ENUM_TO_CSTR(OT_Register);37ENUM_TO_CSTR(OT_AddressSpace);38ENUM_TO_CSTR(OT_Expression);39}40return "<unknown CFIProgram::OperandType>";41}4243llvm::Expected<uint64_t>44CFIProgram::Instruction::getOperandAsUnsigned(const CFIProgram &CFIP,45uint32_t OperandIdx) const {46if (OperandIdx >= MaxOperands)47return createStringError(errc::invalid_argument,48"operand index %" PRIu32 " is not valid",49OperandIdx);50OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];51uint64_t Operand = Ops[OperandIdx];52switch (Type) {53case OT_Unset:54case OT_None:55case OT_Expression:56return createStringError(errc::invalid_argument,57"op[%" PRIu32 "] has type %s which has no value",58OperandIdx, CFIProgram::operandTypeString(Type));5960case OT_Offset:61case OT_SignedFactDataOffset:62case OT_UnsignedFactDataOffset:63return createStringError(64errc::invalid_argument,65"op[%" PRIu32 "] has OperandType OT_Offset which produces a signed "66"result, call getOperandAsSigned instead",67OperandIdx);6869case OT_Address:70case OT_Register:71case OT_AddressSpace:72return Operand;7374case OT_FactoredCodeOffset: {75const uint64_t CodeAlignmentFactor = CFIP.codeAlign();76if (CodeAlignmentFactor == 0)77return createStringError(78errc::invalid_argument,79"op[%" PRIu32 "] has type OT_FactoredCodeOffset but code alignment "80"is zero",81OperandIdx);82return Operand * CodeAlignmentFactor;83}84}85llvm_unreachable("invalid operand type");86}8788llvm::Expected<int64_t>89CFIProgram::Instruction::getOperandAsSigned(const CFIProgram &CFIP,90uint32_t OperandIdx) const {91if (OperandIdx >= MaxOperands)92return createStringError(errc::invalid_argument,93"operand index %" PRIu32 " is not valid",94OperandIdx);95OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];96uint64_t Operand = Ops[OperandIdx];97switch (Type) {98case OT_Unset:99case OT_None:100case OT_Expression:101return createStringError(errc::invalid_argument,102"op[%" PRIu32 "] has type %s which has no value",103OperandIdx, CFIProgram::operandTypeString(Type));104105case OT_Address:106case OT_Register:107case OT_AddressSpace:108return createStringError(109errc::invalid_argument,110"op[%" PRIu32 "] has OperandType %s which produces an unsigned result, "111"call getOperandAsUnsigned instead",112OperandIdx, CFIProgram::operandTypeString(Type));113114case OT_Offset:115return (int64_t)Operand;116117case OT_FactoredCodeOffset:118case OT_SignedFactDataOffset: {119const int64_t DataAlignmentFactor = CFIP.dataAlign();120if (DataAlignmentFactor == 0)121return createStringError(errc::invalid_argument,122"op[%" PRIu32 "] has type %s but data "123"alignment is zero",124OperandIdx, CFIProgram::operandTypeString(Type));125return int64_t(Operand) * DataAlignmentFactor;126}127128case OT_UnsignedFactDataOffset: {129const int64_t DataAlignmentFactor = CFIP.dataAlign();130if (DataAlignmentFactor == 0)131return createStringError(errc::invalid_argument,132"op[%" PRIu32133"] has type OT_UnsignedFactDataOffset but data "134"alignment is zero",135OperandIdx);136return Operand * DataAlignmentFactor;137}138}139llvm_unreachable("invalid operand type");140}141142ArrayRef<CFIProgram::OperandType[CFIProgram::MaxOperands]>143CFIProgram::getOperandTypes() {144static OperandType OpTypes[DW_CFA_restore + 1][MaxOperands];145static bool Initialized = false;146if (Initialized) {147return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);148}149Initialized = true;150151#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2) \152do { \153OpTypes[OP][0] = OPTYPE0; \154OpTypes[OP][1] = OPTYPE1; \155OpTypes[OP][2] = OPTYPE2; \156} while (false)157#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \158DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OT_None)159#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)160#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)161162DECLARE_OP1(DW_CFA_set_loc, OT_Address);163DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);164DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);165DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);166DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);167DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);168DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);169DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);170DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);171DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa, OT_Register, OT_Offset,172OT_AddressSpace);173DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa_sf, OT_Register,174OT_SignedFactDataOffset, OT_AddressSpace);175DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);176DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);177DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);178DECLARE_OP1(DW_CFA_undefined, OT_Register);179DECLARE_OP1(DW_CFA_same_value, OT_Register);180DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);181DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);182DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);183DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);184DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);185DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);186DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);187DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);188DECLARE_OP1(DW_CFA_restore, OT_Register);189DECLARE_OP1(DW_CFA_restore_extended, OT_Register);190DECLARE_OP0(DW_CFA_remember_state);191DECLARE_OP0(DW_CFA_restore_state);192DECLARE_OP0(DW_CFA_GNU_window_save);193DECLARE_OP0(DW_CFA_AARCH64_negate_ra_state_with_pc);194DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);195DECLARE_OP0(DW_CFA_nop);196197#undef DECLARE_OP0198#undef DECLARE_OP1199#undef DECLARE_OP2200201return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);202}203204205