1 //===- DWARFFormValue.h -----------------------------------------*- C++ -*-===// 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 #ifndef LLVM_DEBUGINFO_DWARF_DWARFFORMVALUE_H 10 #define LLVM_DEBUGINFO_DWARF_DWARFFORMVALUE_H 11 12 #include "llvm/ADT/ArrayRef.h" 13 #include "llvm/BinaryFormat/Dwarf.h" 14 #include "llvm/DebugInfo/DIContext.h" 15 #include "llvm/Support/DataExtractor.h" 16 #include <cstdint> 17 18 namespace llvm { 19 20 class DWARFContext; 21 class DWARFObject; 22 class DWARFDataExtractor; 23 class DWARFUnit; 24 class raw_ostream; 25 26 class DWARFFormValue { 27 public: 28 enum FormClass { 29 FC_Unknown, 30 FC_Address, 31 FC_Block, 32 FC_Constant, 33 FC_String, 34 FC_Flag, 35 FC_Reference, 36 FC_Indirect, 37 FC_SectionOffset, 38 FC_Exprloc 39 }; 40 41 private: 42 struct ValueType { 43 ValueType() { uval = 0; } 44 ValueType(int64_t V) : sval(V) {} 45 ValueType(uint64_t V) : uval(V) {} 46 ValueType(const char *V) : cstr(V) {} 47 48 union { 49 uint64_t uval; 50 int64_t sval; 51 const char *cstr; 52 }; 53 const uint8_t *data = nullptr; 54 uint64_t SectionIndex; /// Section index for reference forms. 55 }; 56 57 dwarf::Form Form; /// Form for this value. 58 dwarf::DwarfFormat Format = 59 dwarf::DWARF32; /// Remember the DWARF format at extract time. 60 ValueType Value; /// Contains all data for the form. 61 const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time. 62 const DWARFContext *C = nullptr; /// Context for extract time. 63 64 DWARFFormValue(dwarf::Form F, ValueType V) : Form(F), Value(V) {} 65 66 public: 67 DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {} 68 69 static DWARFFormValue createFromSValue(dwarf::Form F, int64_t V); 70 static DWARFFormValue createFromUValue(dwarf::Form F, uint64_t V); 71 static DWARFFormValue createFromPValue(dwarf::Form F, const char *V); 72 static DWARFFormValue createFromBlockValue(dwarf::Form F, 73 ArrayRef<uint8_t> D); 74 static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit, 75 uint64_t *OffsetPtr); 76 77 dwarf::Form getForm() const { return Form; } 78 uint64_t getRawUValue() const { return Value.uval; } 79 80 bool isFormClass(FormClass FC) const; 81 const DWARFUnit *getUnit() const { return U; } 82 void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const; 83 void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts, 84 object::SectionedAddress SA) const; 85 void dumpAddress(raw_ostream &OS, uint64_t Address) const; 86 static void dumpAddress(raw_ostream &OS, uint8_t AddressSize, 87 uint64_t Address); 88 static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS, 89 DIDumpOptions DumpOpts, uint64_t SectionIndex); 90 91 /// Extracts a value in \p Data at offset \p *OffsetPtr. The information 92 /// in \p FormParams is needed to interpret some forms. The optional 93 /// \p Context and \p Unit allows extracting information if the form refers 94 /// to other sections (e.g., .debug_str). 95 bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, 96 dwarf::FormParams FormParams, 97 const DWARFContext *Context = nullptr, 98 const DWARFUnit *Unit = nullptr); 99 100 bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, 101 dwarf::FormParams FormParams, const DWARFUnit *U) { 102 return extractValue(Data, OffsetPtr, FormParams, nullptr, U); 103 } 104 105 /// getAsFoo functions below return the extracted value as Foo if only 106 /// DWARFFormValue has form class is suitable for representing Foo. 107 std::optional<uint64_t> getAsReference() const; 108 struct UnitOffset { 109 DWARFUnit *Unit; 110 uint64_t Offset; 111 }; 112 std::optional<UnitOffset> getAsRelativeReference() const; 113 std::optional<uint64_t> getAsUnsignedConstant() const; 114 std::optional<int64_t> getAsSignedConstant() const; 115 Expected<const char *> getAsCString() const; 116 std::optional<uint64_t> getAsAddress() const; 117 std::optional<object::SectionedAddress> getAsSectionedAddress() const; 118 std::optional<uint64_t> getAsSectionOffset() const; 119 std::optional<ArrayRef<uint8_t>> getAsBlock() const; 120 std::optional<uint64_t> getAsCStringOffset() const; 121 std::optional<uint64_t> getAsReferenceUVal() const; 122 /// Correctly extract any file paths from a form value. 123 /// 124 /// These attributes can be in the from DW_AT_decl_file or DW_AT_call_file 125 /// attributes. We need to use the file index in the correct DWARFUnit's line 126 /// table prologue, and each DWARFFormValue has the DWARFUnit the form value 127 /// was extracted from. 128 /// 129 /// \param Kind The kind of path to extract. 130 /// 131 /// \returns A valid string value on success, or std::nullopt if the form 132 /// class is not FC_Constant, or if the file index is not valid. 133 std::optional<std::string> 134 getAsFile(DILineInfoSpecifier::FileLineInfoKind Kind) const; 135 136 /// Skip a form's value in \p DebugInfoData at the offset specified by 137 /// \p OffsetPtr. 138 /// 139 /// Skips the bytes for the current form and updates the offset. 140 /// 141 /// \param DebugInfoData The data where we want to skip the value. 142 /// \param OffsetPtr A reference to the offset that will be updated. 143 /// \param Params DWARF parameters to help interpret forms. 144 /// \returns true on success, false if the form was not skipped. 145 bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, 146 const dwarf::FormParams Params) const { 147 return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); 148 } 149 150 /// Skip a form's value in \p DebugInfoData at the offset specified by 151 /// \p OffsetPtr. 152 /// 153 /// Skips the bytes for the specified form and updates the offset. 154 /// 155 /// \param Form The DW_FORM enumeration that indicates the form to skip. 156 /// \param DebugInfoData The data where we want to skip the value. 157 /// \param OffsetPtr A reference to the offset that will be updated. 158 /// \param FormParams DWARF parameters to help interpret forms. 159 /// \returns true on success, false if the form was not skipped. 160 static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, 161 uint64_t *OffsetPtr, 162 const dwarf::FormParams FormParams); 163 164 private: 165 void dumpString(raw_ostream &OS) const; 166 }; 167 168 namespace dwarf { 169 170 /// Take an optional DWARFFormValue and try to extract a string value from it. 171 /// 172 /// \param V and optional DWARFFormValue to attempt to extract the value from. 173 /// \returns an optional value that contains a value if the form value 174 /// was valid and was a string. 175 inline std::optional<const char *> 176 toString(const std::optional<DWARFFormValue> &V) { 177 if (!V) 178 return std::nullopt; 179 Expected<const char*> E = V->getAsCString(); 180 if (!E) { 181 consumeError(E.takeError()); 182 return std::nullopt; 183 } 184 return *E; 185 } 186 187 /// Take an optional DWARFFormValue and try to extract a string value from it. 188 /// 189 /// \param V and optional DWARFFormValue to attempt to extract the value from. 190 /// \returns an optional value that contains a value if the form value 191 /// was valid and was a string. 192 inline StringRef toStringRef(const std::optional<DWARFFormValue> &V, 193 StringRef Default = {}) { 194 if (!V) 195 return Default; 196 auto S = V->getAsCString(); 197 if (!S) { 198 consumeError(S.takeError()); 199 return Default; 200 } 201 if (!*S) 202 return Default; 203 return *S; 204 } 205 206 /// Take an optional DWARFFormValue and extract a string value from it. 207 /// 208 /// \param V and optional DWARFFormValue to attempt to extract the value from. 209 /// \param Default the default value to return in case of failure. 210 /// \returns the string value or Default if the V doesn't have a value or the 211 /// form value's encoding wasn't a string. 212 inline const char *toString(const std::optional<DWARFFormValue> &V, 213 const char *Default) { 214 if (auto E = toString(V)) 215 return *E; 216 return Default; 217 } 218 219 /// Take an optional DWARFFormValue and try to extract an unsigned constant. 220 /// 221 /// \param V and optional DWARFFormValue to attempt to extract the value from. 222 /// \returns an optional value that contains a value if the form value 223 /// was valid and has a unsigned constant form. 224 inline std::optional<uint64_t> 225 toUnsigned(const std::optional<DWARFFormValue> &V) { 226 if (V) 227 return V->getAsUnsignedConstant(); 228 return std::nullopt; 229 } 230 231 /// Take an optional DWARFFormValue and extract a unsigned constant. 232 /// 233 /// \param V and optional DWARFFormValue to attempt to extract the value from. 234 /// \param Default the default value to return in case of failure. 235 /// \returns the extracted unsigned value or Default if the V doesn't have a 236 /// value or the form value's encoding wasn't an unsigned constant form. 237 inline uint64_t toUnsigned(const std::optional<DWARFFormValue> &V, 238 uint64_t Default) { 239 return toUnsigned(V).value_or(Default); 240 } 241 242 /// Take an optional DWARFFormValue and try to extract an reference. 243 /// 244 /// \param V and optional DWARFFormValue to attempt to extract the value from. 245 /// \returns an optional value that contains a value if the form value 246 /// was valid and has a reference form. 247 inline std::optional<uint64_t> 248 toReference(const std::optional<DWARFFormValue> &V) { 249 if (V) 250 return V->getAsReference(); 251 return std::nullopt; 252 } 253 254 /// Take an optional DWARFFormValue and extract a reference. 255 /// 256 /// \param V and optional DWARFFormValue to attempt to extract the value from. 257 /// \param Default the default value to return in case of failure. 258 /// \returns the extracted reference value or Default if the V doesn't have a 259 /// value or the form value's encoding wasn't a reference form. 260 inline uint64_t toReference(const std::optional<DWARFFormValue> &V, 261 uint64_t Default) { 262 return toReference(V).value_or(Default); 263 } 264 265 /// Take an optional DWARFFormValue and try to extract an signed constant. 266 /// 267 /// \param V and optional DWARFFormValue to attempt to extract the value from. 268 /// \returns an optional value that contains a value if the form value 269 /// was valid and has a signed constant form. 270 inline std::optional<int64_t> toSigned(const std::optional<DWARFFormValue> &V) { 271 if (V) 272 return V->getAsSignedConstant(); 273 return std::nullopt; 274 } 275 276 /// Take an optional DWARFFormValue and extract a signed integer. 277 /// 278 /// \param V and optional DWARFFormValue to attempt to extract the value from. 279 /// \param Default the default value to return in case of failure. 280 /// \returns the extracted signed integer value or Default if the V doesn't 281 /// have a value or the form value's encoding wasn't a signed integer form. 282 inline int64_t toSigned(const std::optional<DWARFFormValue> &V, 283 int64_t Default) { 284 return toSigned(V).value_or(Default); 285 } 286 287 /// Take an optional DWARFFormValue and try to extract an address. 288 /// 289 /// \param V and optional DWARFFormValue to attempt to extract the value from. 290 /// \returns an optional value that contains a value if the form value 291 /// was valid and has a address form. 292 inline std::optional<uint64_t> 293 toAddress(const std::optional<DWARFFormValue> &V) { 294 if (V) 295 return V->getAsAddress(); 296 return std::nullopt; 297 } 298 299 inline std::optional<object::SectionedAddress> 300 toSectionedAddress(const std::optional<DWARFFormValue> &V) { 301 if (V) 302 return V->getAsSectionedAddress(); 303 return std::nullopt; 304 } 305 306 /// Take an optional DWARFFormValue and extract a address. 307 /// 308 /// \param V and optional DWARFFormValue to attempt to extract the value from. 309 /// \param Default the default value to return in case of failure. 310 /// \returns the extracted address value or Default if the V doesn't have a 311 /// value or the form value's encoding wasn't an address form. 312 inline uint64_t toAddress(const std::optional<DWARFFormValue> &V, 313 uint64_t Default) { 314 return toAddress(V).value_or(Default); 315 } 316 317 /// Take an optional DWARFFormValue and try to extract an section offset. 318 /// 319 /// \param V and optional DWARFFormValue to attempt to extract the value from. 320 /// \returns an optional value that contains a value if the form value 321 /// was valid and has a section offset form. 322 inline std::optional<uint64_t> 323 toSectionOffset(const std::optional<DWARFFormValue> &V) { 324 if (V) 325 return V->getAsSectionOffset(); 326 return std::nullopt; 327 } 328 329 /// Take an optional DWARFFormValue and extract a section offset. 330 /// 331 /// \param V and optional DWARFFormValue to attempt to extract the value from. 332 /// \param Default the default value to return in case of failure. 333 /// \returns the extracted section offset value or Default if the V doesn't 334 /// have a value or the form value's encoding wasn't a section offset form. 335 inline uint64_t toSectionOffset(const std::optional<DWARFFormValue> &V, 336 uint64_t Default) { 337 return toSectionOffset(V).value_or(Default); 338 } 339 340 /// Take an optional DWARFFormValue and try to extract block data. 341 /// 342 /// \param V and optional DWARFFormValue to attempt to extract the value from. 343 /// \returns an optional value that contains a value if the form value 344 /// was valid and has a block form. 345 inline std::optional<ArrayRef<uint8_t>> 346 toBlock(const std::optional<DWARFFormValue> &V) { 347 if (V) 348 return V->getAsBlock(); 349 return std::nullopt; 350 } 351 352 } // end namespace dwarf 353 354 } // end namespace llvm 355 356 #endif // LLVM_DEBUGINFO_DWARF_DWARFFORMVALUE_H 357