clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DWARFFormValue.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Analysis -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ASMParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/BinaryFormat -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitstream -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /include/llvm/CodeGen -I /include/llvm/CodeGen/PBQP -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Coroutines -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData/Coverage -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/CodeView -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/DWARF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/MSF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/PDB -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Demangle -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/JITLink -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/Orc -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenACC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenMP -I /include/llvm/CodeGen/GlobalISel -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IRReader -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/LTO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Linker -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC/MCParser -I /include/llvm/CodeGen/MIRParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Object -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Option -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Passes -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Scalar -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ADT -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Support -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/Symbolize -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Target -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Utils -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Vectorize -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/IPO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/libLLVM/../include -I /usr/src/gnu/usr.bin/clang/libLLVM/obj -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" |
| 10 | #include "llvm/ADT/ArrayRef.h" |
| 11 | #include "llvm/ADT/None.h" |
| 12 | #include "llvm/ADT/Optional.h" |
| 13 | #include "llvm/ADT/StringRef.h" |
| 14 | #include "llvm/BinaryFormat/Dwarf.h" |
| 15 | #include "llvm/DebugInfo/DWARF/DWARFContext.h" |
| 16 | #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" |
| 17 | #include "llvm/DebugInfo/DWARF/DWARFUnit.h" |
| 18 | #include "llvm/Support/ErrorHandling.h" |
| 19 | #include "llvm/Support/Format.h" |
| 20 | #include "llvm/Support/WithColor.h" |
| 21 | #include "llvm/Support/raw_ostream.h" |
| 22 | #include <cinttypes> |
| 23 | #include <cstdint> |
| 24 | #include <limits> |
| 25 | |
| 26 | using namespace llvm; |
| 27 | using namespace dwarf; |
| 28 | |
| 29 | static const DWARFFormValue::FormClass DWARF5FormClasses[] = { |
| 30 | DWARFFormValue::FC_Unknown, |
| 31 | DWARFFormValue::FC_Address, |
| 32 | DWARFFormValue::FC_Unknown, |
| 33 | DWARFFormValue::FC_Block, |
| 34 | DWARFFormValue::FC_Block, |
| 35 | DWARFFormValue::FC_Constant, |
| 36 | |
| 37 | DWARFFormValue::FC_Constant, |
| 38 | DWARFFormValue::FC_Constant, |
| 39 | |
| 40 | DWARFFormValue::FC_String, |
| 41 | DWARFFormValue::FC_Block, |
| 42 | DWARFFormValue::FC_Block, |
| 43 | DWARFFormValue::FC_Constant, |
| 44 | DWARFFormValue::FC_Flag, |
| 45 | DWARFFormValue::FC_Constant, |
| 46 | DWARFFormValue::FC_String, |
| 47 | DWARFFormValue::FC_Constant, |
| 48 | DWARFFormValue::FC_Reference, |
| 49 | DWARFFormValue::FC_Reference, |
| 50 | DWARFFormValue::FC_Reference, |
| 51 | DWARFFormValue::FC_Reference, |
| 52 | DWARFFormValue::FC_Reference, |
| 53 | DWARFFormValue::FC_Reference, |
| 54 | DWARFFormValue::FC_Indirect, |
| 55 | DWARFFormValue::FC_SectionOffset, |
| 56 | DWARFFormValue::FC_Exprloc, |
| 57 | DWARFFormValue::FC_Flag, |
| 58 | DWARFFormValue::FC_String, |
| 59 | DWARFFormValue::FC_Address, |
| 60 | DWARFFormValue::FC_Reference, |
| 61 | DWARFFormValue::FC_String, |
| 62 | DWARFFormValue::FC_Constant, |
| 63 | DWARFFormValue::FC_String, |
| 64 | DWARFFormValue::FC_Reference, |
| 65 | DWARFFormValue::FC_Constant, |
| 66 | DWARFFormValue::FC_SectionOffset, |
| 67 | DWARFFormValue::FC_SectionOffset, |
| 68 | DWARFFormValue::FC_Reference, |
| 69 | DWARFFormValue::FC_String, |
| 70 | DWARFFormValue::FC_String, |
| 71 | DWARFFormValue::FC_String, |
| 72 | DWARFFormValue::FC_String, |
| 73 | DWARFFormValue::FC_Address, |
| 74 | DWARFFormValue::FC_Address, |
| 75 | DWARFFormValue::FC_Address, |
| 76 | DWARFFormValue::FC_Address, |
| 77 | DWARFFormValue::FC_Address, |
| 78 | }; |
| 79 | |
| 80 | DWARFFormValue DWARFFormValue::createFromSValue(dwarf::Form F, int64_t V) { |
| 81 | return DWARFFormValue(F, ValueType(V)); |
| 82 | } |
| 83 | |
| 84 | DWARFFormValue DWARFFormValue::createFromUValue(dwarf::Form F, uint64_t V) { |
| 85 | return DWARFFormValue(F, ValueType(V)); |
| 86 | } |
| 87 | |
| 88 | DWARFFormValue DWARFFormValue::createFromPValue(dwarf::Form F, const char *V) { |
| 89 | return DWARFFormValue(F, ValueType(V)); |
| 90 | } |
| 91 | |
| 92 | DWARFFormValue DWARFFormValue::createFromBlockValue(dwarf::Form F, |
| 93 | ArrayRef<uint8_t> D) { |
| 94 | ValueType V; |
| 95 | V.uval = D.size(); |
| 96 | V.data = D.data(); |
| 97 | return DWARFFormValue(F, V); |
| 98 | } |
| 99 | |
| 100 | DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U, |
| 101 | uint64_t *OffsetPtr) { |
| 102 | DWARFFormValue FormValue(F); |
| 103 | FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, |
| 104 | U->getFormParams(), U); |
| 105 | return FormValue; |
| 106 | } |
| 107 | |
| 108 | bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, |
| 109 | uint64_t *OffsetPtr, |
| 110 | const dwarf::FormParams Params) { |
| 111 | bool Indirect = false; |
| 112 | do { |
| 113 | switch (Form) { |
| 114 | |
| 115 | |
| 116 | case DW_FORM_exprloc: |
| 117 | case DW_FORM_block: { |
| 118 | uint64_t size = DebugInfoData.getULEB128(OffsetPtr); |
| 119 | *OffsetPtr += size; |
| 120 | return true; |
| 121 | } |
| 122 | case DW_FORM_block1: { |
| 123 | uint8_t size = DebugInfoData.getU8(OffsetPtr); |
| 124 | *OffsetPtr += size; |
| 125 | return true; |
| 126 | } |
| 127 | case DW_FORM_block2: { |
| 128 | uint16_t size = DebugInfoData.getU16(OffsetPtr); |
| 129 | *OffsetPtr += size; |
| 130 | return true; |
| 131 | } |
| 132 | case DW_FORM_block4: { |
| 133 | uint32_t size = DebugInfoData.getU32(OffsetPtr); |
| 134 | *OffsetPtr += size; |
| 135 | return true; |
| 136 | } |
| 137 | |
| 138 | |
| 139 | case DW_FORM_string: |
| 140 | DebugInfoData.getCStr(OffsetPtr); |
| 141 | return true; |
| 142 | |
| 143 | case DW_FORM_addr: |
| 144 | case DW_FORM_ref_addr: |
| 145 | case DW_FORM_flag_present: |
| 146 | case DW_FORM_data1: |
| 147 | case DW_FORM_data2: |
| 148 | case DW_FORM_data4: |
| 149 | case DW_FORM_data8: |
| 150 | case DW_FORM_data16: |
| 151 | case DW_FORM_flag: |
| 152 | case DW_FORM_ref1: |
| 153 | case DW_FORM_ref2: |
| 154 | case DW_FORM_ref4: |
| 155 | case DW_FORM_ref8: |
| 156 | case DW_FORM_ref_sig8: |
| 157 | case DW_FORM_ref_sup4: |
| 158 | case DW_FORM_ref_sup8: |
| 159 | case DW_FORM_strx1: |
| 160 | case DW_FORM_strx2: |
| 161 | case DW_FORM_strx4: |
| 162 | case DW_FORM_addrx1: |
| 163 | case DW_FORM_addrx2: |
| 164 | case DW_FORM_addrx4: |
| 165 | case DW_FORM_sec_offset: |
| 166 | case DW_FORM_strp: |
| 167 | case DW_FORM_strp_sup: |
| 168 | case DW_FORM_line_strp: |
| 169 | case DW_FORM_GNU_ref_alt: |
| 170 | case DW_FORM_GNU_strp_alt: |
| 171 | case DW_FORM_implicit_const: |
| 172 | if (Optional<uint8_t> FixedSize = |
| 173 | dwarf::getFixedFormByteSize(Form, Params)) { |
| 174 | *OffsetPtr += *FixedSize; |
| 175 | return true; |
| 176 | } |
| 177 | return false; |
| 178 | |
| 179 | |
| 180 | case DW_FORM_sdata: |
| 181 | DebugInfoData.getSLEB128(OffsetPtr); |
| 182 | return true; |
| 183 | |
| 184 | case DW_FORM_udata: |
| 185 | case DW_FORM_ref_udata: |
| 186 | case DW_FORM_strx: |
| 187 | case DW_FORM_addrx: |
| 188 | case DW_FORM_loclistx: |
| 189 | case DW_FORM_rnglistx: |
| 190 | case DW_FORM_GNU_addr_index: |
| 191 | case DW_FORM_GNU_str_index: |
| 192 | DebugInfoData.getULEB128(OffsetPtr); |
| 193 | return true; |
| 194 | |
| 195 | case DW_FORM_LLVM_addrx_offset: |
| 196 | DebugInfoData.getULEB128(OffsetPtr); |
| 197 | *OffsetPtr += 4; |
| 198 | return true; |
| 199 | |
| 200 | case DW_FORM_indirect: |
| 201 | Indirect = true; |
| 202 | Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr)); |
| 203 | break; |
| 204 | |
| 205 | default: |
| 206 | return false; |
| 207 | } |
| 208 | } while (Indirect); |
| 209 | return true; |
| 210 | } |
| 211 | |
| 212 | bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { |
| 213 | |
| 214 | if (Form < makeArrayRef(DWARF5FormClasses).size() && |
| 9 | | Assuming the condition is true | |
|
| 215 | DWARF5FormClasses[Form] == FC) |
| 10 | | The left operand of '==' is a garbage value due to array index out of bounds |
|
| 216 | return true; |
| 217 | |
| 218 | switch (Form) { |
| 219 | case DW_FORM_GNU_ref_alt: |
| 220 | return (FC == FC_Reference); |
| 221 | case DW_FORM_GNU_addr_index: |
| 222 | return (FC == FC_Address); |
| 223 | case DW_FORM_GNU_str_index: |
| 224 | case DW_FORM_GNU_strp_alt: |
| 225 | return (FC == FC_String); |
| 226 | case DW_FORM_LLVM_addrx_offset: |
| 227 | return (FC == FC_Address); |
| 228 | default: |
| 229 | break; |
| 230 | } |
| 231 | |
| 232 | if (FC == FC_SectionOffset) { |
| 233 | if (Form == DW_FORM_strp || Form == DW_FORM_line_strp) |
| 234 | return true; |
| 235 | |
| 236 | |
| 237 | if (Form == DW_FORM_data4 || Form == DW_FORM_data8) |
| 238 | return !U || U->getVersion() <= 3; |
| 239 | } |
| 240 | |
| 241 | return false; |
| 242 | } |
| 243 | |
| 244 | bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, |
| 245 | uint64_t *OffsetPtr, dwarf::FormParams FP, |
| 246 | const DWARFContext *Ctx, |
| 247 | const DWARFUnit *CU) { |
| 248 | if (!Ctx && CU) |
| 249 | Ctx = &CU->getContext(); |
| 250 | C = Ctx; |
| 251 | U = CU; |
| 252 | Format = FP.Format; |
| 253 | bool Indirect = false; |
| 254 | bool IsBlock = false; |
| 255 | Value.data = nullptr; |
| 256 | |
| 257 | |
| 258 | Error Err = Error::success(); |
| 259 | do { |
| 260 | Indirect = false; |
| 261 | switch (Form) { |
| 262 | case DW_FORM_addr: |
| 263 | case DW_FORM_ref_addr: { |
| 264 | uint16_t Size = |
| 265 | (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize(); |
| 266 | Value.uval = |
| 267 | Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex, &Err); |
| 268 | break; |
| 269 | } |
| 270 | case DW_FORM_exprloc: |
| 271 | case DW_FORM_block: |
| 272 | Value.uval = Data.getULEB128(OffsetPtr, &Err); |
| 273 | IsBlock = true; |
| 274 | break; |
| 275 | case DW_FORM_block1: |
| 276 | Value.uval = Data.getU8(OffsetPtr, &Err); |
| 277 | IsBlock = true; |
| 278 | break; |
| 279 | case DW_FORM_block2: |
| 280 | Value.uval = Data.getU16(OffsetPtr, &Err); |
| 281 | IsBlock = true; |
| 282 | break; |
| 283 | case DW_FORM_block4: |
| 284 | Value.uval = Data.getU32(OffsetPtr, &Err); |
| 285 | IsBlock = true; |
| 286 | break; |
| 287 | case DW_FORM_data1: |
| 288 | case DW_FORM_ref1: |
| 289 | case DW_FORM_flag: |
| 290 | case DW_FORM_strx1: |
| 291 | case DW_FORM_addrx1: |
| 292 | Value.uval = Data.getU8(OffsetPtr, &Err); |
| 293 | break; |
| 294 | case DW_FORM_data2: |
| 295 | case DW_FORM_ref2: |
| 296 | case DW_FORM_strx2: |
| 297 | case DW_FORM_addrx2: |
| 298 | Value.uval = Data.getU16(OffsetPtr, &Err); |
| 299 | break; |
| 300 | case DW_FORM_strx3: |
| 301 | Value.uval = Data.getU24(OffsetPtr, &Err); |
| 302 | break; |
| 303 | case DW_FORM_data4: |
| 304 | case DW_FORM_ref4: |
| 305 | case DW_FORM_ref_sup4: |
| 306 | case DW_FORM_strx4: |
| 307 | case DW_FORM_addrx4: |
| 308 | Value.uval = Data.getRelocatedValue(4, OffsetPtr, nullptr, &Err); |
| 309 | break; |
| 310 | case DW_FORM_data8: |
| 311 | case DW_FORM_ref8: |
| 312 | case DW_FORM_ref_sup8: |
| 313 | Value.uval = Data.getRelocatedValue(8, OffsetPtr, nullptr, &Err); |
| 314 | break; |
| 315 | case DW_FORM_data16: |
| 316 | |
| 317 | Value.uval = 16; |
| 318 | IsBlock = true; |
| 319 | break; |
| 320 | case DW_FORM_sdata: |
| 321 | Value.sval = Data.getSLEB128(OffsetPtr, &Err); |
| 322 | break; |
| 323 | case DW_FORM_udata: |
| 324 | case DW_FORM_ref_udata: |
| 325 | case DW_FORM_rnglistx: |
| 326 | case DW_FORM_loclistx: |
| 327 | case DW_FORM_GNU_addr_index: |
| 328 | case DW_FORM_GNU_str_index: |
| 329 | case DW_FORM_addrx: |
| 330 | case DW_FORM_strx: |
| 331 | Value.uval = Data.getULEB128(OffsetPtr, &Err); |
| 332 | break; |
| 333 | case DW_FORM_LLVM_addrx_offset: |
| 334 | Value.uval = Data.getULEB128(OffsetPtr, &Err) << 32; |
| 335 | Value.uval = Data.getU32(OffsetPtr, &Err); |
| 336 | break; |
| 337 | case DW_FORM_string: |
| 338 | Value.cstr = Data.getCStr(OffsetPtr, &Err); |
| 339 | break; |
| 340 | case DW_FORM_indirect: |
| 341 | Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr, &Err)); |
| 342 | Indirect = true; |
| 343 | break; |
| 344 | case DW_FORM_strp: |
| 345 | case DW_FORM_sec_offset: |
| 346 | case DW_FORM_GNU_ref_alt: |
| 347 | case DW_FORM_GNU_strp_alt: |
| 348 | case DW_FORM_line_strp: |
| 349 | case DW_FORM_strp_sup: { |
| 350 | Value.uval = Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), |
| 351 | OffsetPtr, nullptr, &Err); |
| 352 | break; |
| 353 | } |
| 354 | case DW_FORM_flag_present: |
| 355 | Value.uval = 1; |
| 356 | break; |
| 357 | case DW_FORM_ref_sig8: |
| 358 | Value.uval = Data.getU64(OffsetPtr, &Err); |
| 359 | break; |
| 360 | case DW_FORM_implicit_const: |
| 361 | |
| 362 | break; |
| 363 | default: |
| 364 | |
| 365 | |
| 366 | llvm_unreachable("unsupported form"); |
| 367 | } |
| 368 | } while (Indirect && !Err); |
| 369 | |
| 370 | if (IsBlock) |
| 371 | Value.data = Data.getBytes(OffsetPtr, Value.uval, &Err).bytes_begin(); |
| 372 | |
| 373 | return !errorToBool(std::move(Err)); |
| 374 | } |
| 375 | |
| 376 | void DWARFFormValue::dumpAddress(raw_ostream &OS, uint8_t AddressSize, |
| 377 | uint64_t Address) { |
| 378 | uint8_t HexDigits = AddressSize * 2; |
| 379 | OS << format("0x%*.*" PRIx64, HexDigits, HexDigits, Address); |
| 380 | } |
| 381 | |
| 382 | void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS, |
| 383 | DIDumpOptions DumpOpts, |
| 384 | object::SectionedAddress SA) const { |
| 385 | dumpAddress(OS, U->getAddressByteSize(), SA.Address); |
| 386 | dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts, |
| 387 | SA.SectionIndex); |
| 388 | } |
| 389 | |
| 390 | void DWARFFormValue::dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS, |
| 391 | DIDumpOptions DumpOpts, |
| 392 | uint64_t SectionIndex) { |
| 393 | if (!DumpOpts.Verbose || SectionIndex == -1ULL) |
| 394 | return; |
| 395 | ArrayRef<SectionName> SectionNames = Obj.getSectionNames(); |
| 396 | const auto &SecRef = SectionNames[SectionIndex]; |
| 397 | |
| 398 | OS << " \"" << SecRef.Name << '\"'; |
| 399 | |
| 400 | |
| 401 | if (!SecRef.IsNameUnique) |
| 402 | OS << format(" [%" PRIu64 "]", SectionIndex); |
| 403 | } |
| 404 | |
| 405 | void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { |
| 406 | uint64_t UValue = Value.uval; |
| 407 | bool CURelativeOffset = false; |
| 408 | raw_ostream &AddrOS = DumpOpts.ShowAddresses |
| 1 | Assuming field 'ShowAddresses' is false | |
|
| |
| 409 | ? WithColor(OS, HighlightColor::Address).get() |
| 410 | : nulls(); |
| 411 | int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format); |
| 412 | switch (Form) { |
| 3 | | Control jumps to 'case DW_FORM_GNU_strp_alt:' at line 544 | |
|
| 413 | case DW_FORM_addr: |
| 414 | dumpSectionedAddress(AddrOS, DumpOpts, {Value.uval, Value.SectionIndex}); |
| 415 | break; |
| 416 | case DW_FORM_addrx: |
| 417 | case DW_FORM_addrx1: |
| 418 | case DW_FORM_addrx2: |
| 419 | case DW_FORM_addrx3: |
| 420 | case DW_FORM_addrx4: |
| 421 | case DW_FORM_GNU_addr_index: { |
| 422 | if (U == nullptr) { |
| 423 | OS << "<invalid dwarf unit>"; |
| 424 | break; |
| 425 | } |
| 426 | Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(UValue); |
| 427 | if (!A || DumpOpts.Verbose) |
| 428 | AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue); |
| 429 | if (A) |
| 430 | dumpSectionedAddress(AddrOS, DumpOpts, *A); |
| 431 | else |
| 432 | OS << "<unresolved>"; |
| 433 | break; |
| 434 | } |
| 435 | case DW_FORM_LLVM_addrx_offset: { |
| 436 | if (U == nullptr) { |
| 437 | OS << "<invalid dwarf unit>"; |
| 438 | break; |
| 439 | } |
| 440 | uint32_t Index = UValue >> 32; |
| 441 | uint32_t Offset = UValue & 0xffffffff; |
| 442 | Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(Index); |
| 443 | if (!A || DumpOpts.Verbose) |
| 444 | AddrOS << format("indexed (%8.8x) + 0x%x address = ", Index, Offset); |
| 445 | if (A) { |
| 446 | A->Address += Offset; |
| 447 | dumpSectionedAddress(AddrOS, DumpOpts, *A); |
| 448 | } else |
| 449 | OS << "<unresolved>"; |
| 450 | break; |
| 451 | } |
| 452 | case DW_FORM_flag_present: |
| 453 | OS << "true"; |
| 454 | break; |
| 455 | case DW_FORM_flag: |
| 456 | case DW_FORM_data1: |
| 457 | OS << format("0x%02x", (uint8_t)UValue); |
| 458 | break; |
| 459 | case DW_FORM_data2: |
| 460 | OS << format("0x%04x", (uint16_t)UValue); |
| 461 | break; |
| 462 | case DW_FORM_data4: |
| 463 | OS << format("0x%08x", (uint32_t)UValue); |
| 464 | break; |
| 465 | case DW_FORM_ref_sig8: |
| 466 | AddrOS << format("0x%016" PRIx64, UValue); |
| 467 | break; |
| 468 | case DW_FORM_data8: |
| 469 | OS << format("0x%016" PRIx64, UValue); |
| 470 | break; |
| 471 | case DW_FORM_data16: |
| 472 | OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16); |
| 473 | break; |
| 474 | case DW_FORM_string: |
| 475 | OS << '"'; |
| 476 | OS.write_escaped(Value.cstr); |
| 477 | OS << '"'; |
| 478 | break; |
| 479 | case DW_FORM_exprloc: |
| 480 | case DW_FORM_block: |
| 481 | case DW_FORM_block1: |
| 482 | case DW_FORM_block2: |
| 483 | case DW_FORM_block4: |
| 484 | if (UValue > 0) { |
| 485 | switch (Form) { |
| 486 | case DW_FORM_exprloc: |
| 487 | case DW_FORM_block: |
| 488 | AddrOS << format("<0x%" PRIx64 "> ", UValue); |
| 489 | break; |
| 490 | case DW_FORM_block1: |
| 491 | AddrOS << format("<0x%2.2x> ", (uint8_t)UValue); |
| 492 | break; |
| 493 | case DW_FORM_block2: |
| 494 | AddrOS << format("<0x%4.4x> ", (uint16_t)UValue); |
| 495 | break; |
| 496 | case DW_FORM_block4: |
| 497 | AddrOS << format("<0x%8.8x> ", (uint32_t)UValue); |
| 498 | break; |
| 499 | default: |
| 500 | break; |
| 501 | } |
| 502 | |
| 503 | const uint8_t *DataPtr = Value.data; |
| 504 | if (DataPtr) { |
| 505 | |
| 506 | const uint8_t *EndDataPtr = DataPtr + UValue; |
| 507 | while (DataPtr < EndDataPtr) { |
| 508 | AddrOS << format("%2.2x ", *DataPtr); |
| 509 | ++DataPtr; |
| 510 | } |
| 511 | } else |
| 512 | OS << "NULL"; |
| 513 | } |
| 514 | break; |
| 515 | |
| 516 | case DW_FORM_sdata: |
| 517 | case DW_FORM_implicit_const: |
| 518 | OS << Value.sval; |
| 519 | break; |
| 520 | case DW_FORM_udata: |
| 521 | OS << Value.uval; |
| 522 | break; |
| 523 | case DW_FORM_strp: |
| 524 | if (DumpOpts.Verbose) |
| 525 | OS << format(" .debug_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth, UValue); |
| 526 | dumpString(OS); |
| 527 | break; |
| 528 | case DW_FORM_line_strp: |
| 529 | if (DumpOpts.Verbose) |
| 530 | OS << format(" .debug_line_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth, |
| 531 | UValue); |
| 532 | dumpString(OS); |
| 533 | break; |
| 534 | case DW_FORM_strx: |
| 535 | case DW_FORM_strx1: |
| 536 | case DW_FORM_strx2: |
| 537 | case DW_FORM_strx3: |
| 538 | case DW_FORM_strx4: |
| 539 | case DW_FORM_GNU_str_index: |
| 540 | if (DumpOpts.Verbose) |
| 541 | OS << format("indexed (%8.8x) string = ", (uint32_t)UValue); |
| 542 | dumpString(OS); |
| 543 | break; |
| 544 | case DW_FORM_GNU_strp_alt: |
| 545 | if (DumpOpts.Verbose) |
| 4 | | Assuming field 'Verbose' is false | |
|
| |
| 546 | OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue); |
| 547 | dumpString(OS); |
| 6 | | Calling 'DWARFFormValue::dumpString' | |
|
| 548 | break; |
| 549 | case DW_FORM_ref_addr: |
| 550 | AddrOS << format("0x%016" PRIx64, UValue); |
| 551 | break; |
| 552 | case DW_FORM_ref1: |
| 553 | CURelativeOffset = true; |
| 554 | if (DumpOpts.Verbose) |
| 555 | AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue); |
| 556 | break; |
| 557 | case DW_FORM_ref2: |
| 558 | CURelativeOffset = true; |
| 559 | if (DumpOpts.Verbose) |
| 560 | AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue); |
| 561 | break; |
| 562 | case DW_FORM_ref4: |
| 563 | CURelativeOffset = true; |
| 564 | if (DumpOpts.Verbose) |
| 565 | AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue); |
| 566 | break; |
| 567 | case DW_FORM_ref8: |
| 568 | CURelativeOffset = true; |
| 569 | if (DumpOpts.Verbose) |
| 570 | AddrOS << format("cu + 0x%8.8" PRIx64, UValue); |
| 571 | break; |
| 572 | case DW_FORM_ref_udata: |
| 573 | CURelativeOffset = true; |
| 574 | if (DumpOpts.Verbose) |
| 575 | AddrOS << format("cu + 0x%" PRIx64, UValue); |
| 576 | break; |
| 577 | case DW_FORM_GNU_ref_alt: |
| 578 | AddrOS << format("<alt 0x%" PRIx64 ">", UValue); |
| 579 | break; |
| 580 | |
| 581 | |
| 582 | |
| 583 | case DW_FORM_indirect: |
| 584 | OS << "DW_FORM_indirect"; |
| 585 | break; |
| 586 | |
| 587 | case DW_FORM_rnglistx: |
| 588 | OS << format("indexed (0x%x) rangelist = ", (uint32_t)UValue); |
| 589 | break; |
| 590 | |
| 591 | case DW_FORM_loclistx: |
| 592 | OS << format("indexed (0x%x) loclist = ", (uint32_t)UValue); |
| 593 | break; |
| 594 | |
| 595 | case DW_FORM_sec_offset: |
| 596 | AddrOS << format("0x%0*" PRIx64, OffsetDumpWidth, UValue); |
| 597 | break; |
| 598 | |
| 599 | default: |
| 600 | OS << format("DW_FORM(0x%4.4x)", Form); |
| 601 | break; |
| 602 | } |
| 603 | |
| 604 | if (CURelativeOffset) { |
| 605 | if (DumpOpts.Verbose) |
| 606 | OS << " => {"; |
| 607 | if (DumpOpts.ShowAddresses) |
| 608 | WithColor(OS, HighlightColor::Address).get() |
| 609 | << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0)); |
| 610 | if (DumpOpts.Verbose) |
| 611 | OS << "}"; |
| 612 | } |
| 613 | } |
| 614 | |
| 615 | void DWARFFormValue::dumpString(raw_ostream &OS) const { |
| 616 | Optional<const char *> DbgStr = getAsCString(); |
| 7 | | Calling 'DWARFFormValue::getAsCString' | |
|
| 617 | if (DbgStr.hasValue()) { |
| 618 | auto COS = WithColor(OS, HighlightColor::String); |
| 619 | COS.get() << '"'; |
| 620 | COS.get().write_escaped(DbgStr.getValue()); |
| 621 | COS.get() << '"'; |
| 622 | } |
| 623 | } |
| 624 | |
| 625 | Optional<const char *> DWARFFormValue::getAsCString() const { |
| 626 | if (!isFormClass(FC_String)) |
| 8 | | Calling 'DWARFFormValue::isFormClass' | |
|
| 627 | return None; |
| 628 | if (Form == DW_FORM_string) |
| 629 | return Value.cstr; |
| 630 | |
| 631 | if (Form == DW_FORM_GNU_strp_alt || C == nullptr) |
| 632 | return None; |
| 633 | uint64_t Offset = Value.uval; |
| 634 | if (Form == DW_FORM_line_strp) { |
| 635 | |
| 636 | if (const char *Str = C->getLineStringExtractor().getCStr(&Offset)) |
| 637 | return Str; |
| 638 | return None; |
| 639 | } |
| 640 | if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx || |
| 641 | Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 || |
| 642 | Form == DW_FORM_strx4) { |
| 643 | if (!U) |
| 644 | return None; |
| 645 | Optional<uint64_t> StrOffset = U->getStringOffsetSectionItem(Offset); |
| 646 | if (!StrOffset) |
| 647 | return None; |
| 648 | Offset = *StrOffset; |
| 649 | } |
| 650 | |
| 651 | |
| 652 | if (U) { |
| 653 | if (const char *Str = U->getStringExtractor().getCStr(&Offset)) |
| 654 | return Str; |
| 655 | return None; |
| 656 | } |
| 657 | if (const char *Str = C->getStringExtractor().getCStr(&Offset)) |
| 658 | return Str; |
| 659 | return None; |
| 660 | } |
| 661 | |
| 662 | Optional<uint64_t> DWARFFormValue::getAsAddress() const { |
| 663 | if (auto SA = getAsSectionedAddress()) |
| 664 | return SA->Address; |
| 665 | return None; |
| 666 | } |
| 667 | |
| 668 | Optional<object::SectionedAddress> |
| 669 | DWARFFormValue::getAsSectionedAddress() const { |
| 670 | if (!isFormClass(FC_Address)) |
| 671 | return None; |
| 672 | bool AddrOffset = Form == dwarf::DW_FORM_LLVM_addrx_offset; |
| 673 | if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx || AddrOffset) { |
| 674 | |
| 675 | uint32_t Index = AddrOffset ? (Value.uval >> 32) : Value.uval; |
| 676 | if (!U) |
| 677 | return None; |
| 678 | Optional<object::SectionedAddress> SA = U->getAddrOffsetSectionItem(Index); |
| 679 | if (!SA) |
| 680 | return None; |
| 681 | if (AddrOffset) |
| 682 | SA->Address += (Value.uval & 0xffffffff); |
| 683 | return SA; |
| 684 | } |
| 685 | return {{Value.uval, Value.SectionIndex}}; |
| 686 | } |
| 687 | |
| 688 | Optional<uint64_t> DWARFFormValue::getAsReference() const { |
| 689 | if (auto R = getAsRelativeReference()) |
| 690 | return R->Unit ? R->Unit->getOffset() + R->Offset : R->Offset; |
| 691 | return None; |
| 692 | } |
| 693 | |
| 694 | Optional<DWARFFormValue::UnitOffset> DWARFFormValue::getAsRelativeReference() const { |
| 695 | if (!isFormClass(FC_Reference)) |
| 696 | return None; |
| 697 | switch (Form) { |
| 698 | case DW_FORM_ref1: |
| 699 | case DW_FORM_ref2: |
| 700 | case DW_FORM_ref4: |
| 701 | case DW_FORM_ref8: |
| 702 | case DW_FORM_ref_udata: |
| 703 | if (!U) |
| 704 | return None; |
| 705 | return UnitOffset{const_cast<DWARFUnit*>(U), Value.uval}; |
| 706 | case DW_FORM_ref_addr: |
| 707 | case DW_FORM_ref_sig8: |
| 708 | case DW_FORM_GNU_ref_alt: |
| 709 | return UnitOffset{nullptr, Value.uval}; |
| 710 | default: |
| 711 | return None; |
| 712 | } |
| 713 | } |
| 714 | |
| 715 | Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const { |
| 716 | if (!isFormClass(FC_SectionOffset)) |
| 717 | return None; |
| 718 | return Value.uval; |
| 719 | } |
| 720 | |
| 721 | Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const { |
| 722 | if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || |
| 723 | Form == DW_FORM_sdata) |
| 724 | return None; |
| 725 | return Value.uval; |
| 726 | } |
| 727 | |
| 728 | Optional<int64_t> DWARFFormValue::getAsSignedConstant() const { |
| 729 | if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || |
| 730 | (Form == DW_FORM_udata && |
| 731 | uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval)) |
| 732 | return None; |
| 733 | switch (Form) { |
| 734 | case DW_FORM_data4: |
| 735 | return int32_t(Value.uval); |
| 736 | case DW_FORM_data2: |
| 737 | return int16_t(Value.uval); |
| 738 | case DW_FORM_data1: |
| 739 | return int8_t(Value.uval); |
| 740 | case DW_FORM_sdata: |
| 741 | case DW_FORM_data8: |
| 742 | default: |
| 743 | return Value.sval; |
| 744 | } |
| 745 | } |
| 746 | |
| 747 | Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const { |
| 748 | if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) && |
| 749 | Form != DW_FORM_data16) |
| 750 | return None; |
| 751 | return makeArrayRef(Value.data, Value.uval); |
| 752 | } |
| 753 | |
| 754 | Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const { |
| 755 | if (!isFormClass(FC_String) && Form == DW_FORM_string) |
| 756 | return None; |
| 757 | return Value.uval; |
| 758 | } |
| 759 | |
| 760 | Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const { |
| 761 | if (!isFormClass(FC_Reference)) |
| 762 | return None; |
| 763 | return Value.uval; |
| 764 | } |