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-exception 6 // 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 18 using namespace llvm; 19 using namespace dwarf; 20 21 StringRef CFIProgram::callFrameString(unsigned Opcode) const { 22 return dwarf::CallFrameString(Opcode, Arch); 23 } 24 25 const 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 44 llvm::Expected<uint64_t> 45 CFIProgram::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 89 llvm::Expected<int64_t> 90 CFIProgram::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[%" PRIu32 134 "] 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 143 ArrayRef<CFIProgram::OperandType[CFIProgram::MaxOperands]> 144 CFIProgram::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_OP0 199 #undef DECLARE_OP1 200 #undef DECLARE_OP2 201 202 return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1); 203 } 204