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 struct ValueType { 42 ValueType() { uval = 0; } 43 ValueType(int64_t V) : sval(V) {} 44 ValueType(uint64_t V) : uval(V) {} 45 ValueType(const char *V) : cstr(V) {} 46 47 union { 48 uint64_t uval; 49 int64_t sval; 50 const char *cstr; 51 }; 52 const uint8_t *data = nullptr; 53 uint64_t SectionIndex; /// Section index for reference forms. 54 }; 55 56 private: 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, const 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 static std::optional<object::SectionedAddress> 77 getAsSectionedAddress(const ValueType &Val, const dwarf::Form Form, 78 const DWARFUnit *U); 79 80 dwarf::Form getForm() const { return Form; } 81 uint64_t getRawUValue() const { return Value.uval; } 82 83 bool isFormClass(FormClass FC) const; 84 const DWARFUnit *getUnit() const { return U; } 85 void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const; 86 void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts, 87 object::SectionedAddress SA) const; 88 void dumpAddress(raw_ostream &OS, uint64_t Address) const; 89 static void dumpAddress(raw_ostream &OS, uint8_t AddressSize, 90 uint64_t Address); 91 static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS, 92 DIDumpOptions DumpOpts, uint64_t SectionIndex); 93 94 /// Extracts a value in \p Data at offset \p *OffsetPtr. The information 95 /// in \p FormParams is needed to interpret some forms. The optional 96 /// \p Context and \p Unit allows extracting information if the form refers 97 /// to other sections (e.g., .debug_str). 98 bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, 99 dwarf::FormParams FormParams, 100 const DWARFContext *Context = nullptr, 101 const DWARFUnit *Unit = nullptr); 102 103 bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, 104 dwarf::FormParams FormParams, const DWARFUnit *U) { 105 return extractValue(Data, OffsetPtr, FormParams, nullptr, U); 106 } 107 108 /// getAsFoo functions below return the extracted value as Foo if only 109 /// DWARFFormValue has form class is suitable for representing Foo. 110 std::optional<uint64_t> getAsRelativeReference() const; 111 std::optional<uint64_t> getAsDebugInfoReference() const; 112 std::optional<uint64_t> getAsSignatureReference() const; 113 std::optional<uint64_t> getAsSupplementaryReference() const; 114 std::optional<uint64_t> getAsUnsignedConstant() const; 115 std::optional<int64_t> getAsSignedConstant() const; 116 Expected<const char *> getAsCString() const; 117 std::optional<uint64_t> getAsAddress() const; 118 std::optional<object::SectionedAddress> getAsSectionedAddress() const; 119 std::optional<uint64_t> getAsSectionOffset() const; 120 std::optional<ArrayRef<uint8_t>> getAsBlock() const; 121 std::optional<uint64_t> getAsCStringOffset() const; 122 std::optional<uint64_t> getAsReferenceUVal() const; 123 /// Correctly extract any file paths from a form value. 124 /// 125 /// These attributes can be in the from DW_AT_decl_file or DW_AT_call_file 126 /// attributes. We need to use the file index in the correct DWARFUnit's line 127 /// table prologue, and each DWARFFormValue has the DWARFUnit the form value 128 /// was extracted from. 129 /// 130 /// \param Kind The kind of path to extract. 131 /// 132 /// \returns A valid string value on success, or std::nullopt if the form 133 /// class is not FC_Constant, or if the file index is not valid. 134 std::optional<std::string> 135 getAsFile(DILineInfoSpecifier::FileLineInfoKind Kind) const; 136 137 /// Skip a form's value in \p DebugInfoData at the offset specified by 138 /// \p OffsetPtr. 139 /// 140 /// Skips the bytes for the current form and updates the offset. 141 /// 142 /// \param DebugInfoData The data where we want to skip the value. 143 /// \param OffsetPtr A reference to the offset that will be updated. 144 /// \param Params DWARF parameters to help interpret forms. 145 /// \returns true on success, false if the form was not skipped. 146 bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, 147 const dwarf::FormParams Params) const { 148 return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); 149 } 150 151 /// Skip a form's value in \p DebugInfoData at the offset specified by 152 /// \p OffsetPtr. 153 /// 154 /// Skips the bytes for the specified form and updates the offset. 155 /// 156 /// \param Form The DW_FORM enumeration that indicates the form to skip. 157 /// \param DebugInfoData The data where we want to skip the value. 158 /// \param OffsetPtr A reference to the offset that will be updated. 159 /// \param FormParams DWARF parameters to help interpret forms. 160 /// \returns true on success, false if the form was not skipped. 161 static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, 162 uint64_t *OffsetPtr, 163 const dwarf::FormParams FormParams); 164 165 private: 166 void dumpString(raw_ostream &OS) const; 167 }; 168 169 namespace dwarf { 170 171 /// Take an optional DWARFFormValue and try to extract a string value from it. 172 /// 173 /// \param V and optional DWARFFormValue to attempt to extract the value from. 174 /// \returns an optional value that contains a value if the form value 175 /// was valid and was a string. 176 inline std::optional<const char *> 177 toString(const std::optional<DWARFFormValue> &V) { 178 if (!V) 179 return std::nullopt; 180 Expected<const char*> E = V->getAsCString(); 181 if (!E) { 182 consumeError(E.takeError()); 183 return std::nullopt; 184 } 185 return *E; 186 } 187 188 /// Take an optional DWARFFormValue and try to extract a string value from it. 189 /// 190 /// \param V and optional DWARFFormValue to attempt to extract the value from. 191 /// \returns an optional value that contains a value if the form value 192 /// was valid and was a string. 193 inline StringRef toStringRef(const std::optional<DWARFFormValue> &V, 194 StringRef Default = {}) { 195 if (!V) 196 return Default; 197 auto S = V->getAsCString(); 198 if (!S) { 199 consumeError(S.takeError()); 200 return Default; 201 } 202 if (!*S) 203 return Default; 204 return *S; 205 } 206 207 /// Take an optional DWARFFormValue and extract a string value from it. 208 /// 209 /// \param V and optional DWARFFormValue to attempt to extract the value from. 210 /// \param Default the default value to return in case of failure. 211 /// \returns the string value or Default if the V doesn't have a value or the 212 /// form value's encoding wasn't a string. 213 inline const char *toString(const std::optional<DWARFFormValue> &V, 214 const char *Default) { 215 if (auto E = toString(V)) 216 return *E; 217 return Default; 218 } 219 220 /// Take an optional DWARFFormValue and try to extract an unsigned constant. 221 /// 222 /// \param V and optional DWARFFormValue to attempt to extract the value from. 223 /// \returns an optional value that contains a value if the form value 224 /// was valid and has a unsigned constant form. 225 inline std::optional<uint64_t> 226 toUnsigned(const std::optional<DWARFFormValue> &V) { 227 if (V) 228 return V->getAsUnsignedConstant(); 229 return std::nullopt; 230 } 231 232 /// Take an optional DWARFFormValue and extract a unsigned constant. 233 /// 234 /// \param V and optional DWARFFormValue to attempt to extract the value from. 235 /// \param Default the default value to return in case of failure. 236 /// \returns the extracted unsigned value or Default if the V doesn't have a 237 /// value or the form value's encoding wasn't an unsigned constant form. 238 inline uint64_t toUnsigned(const std::optional<DWARFFormValue> &V, 239 uint64_t Default) { 240 return toUnsigned(V).value_or(Default); 241 } 242 243 /// Take an optional DWARFFormValue and try to extract a relative offset 244 /// reference. 245 /// 246 /// \param V an optional DWARFFormValue to attempt to extract the value from. 247 /// \returns an optional value that contains a value if the form value 248 /// was valid and has a relative reference form. 249 inline std::optional<uint64_t> 250 toRelativeReference(const std::optional<DWARFFormValue> &V) { 251 if (V) 252 return V->getAsRelativeReference(); 253 return std::nullopt; 254 } 255 256 /// Take an optional DWARFFormValue and extract a relative offset reference. 257 /// 258 /// \param V an optional DWARFFormValue to attempt to extract the value from. 259 /// \param Default the default value to return in case of failure. 260 /// \returns the extracted reference value or Default if the V doesn't have a 261 /// value or the form value's encoding wasn't a relative offset reference form. 262 inline uint64_t toRelativeReference(const std::optional<DWARFFormValue> &V, 263 uint64_t Default) { 264 return toRelativeReference(V).value_or(Default); 265 } 266 267 /// Take an optional DWARFFormValue and try to extract an absolute debug info 268 /// offset reference. 269 /// 270 /// \param V an optional DWARFFormValue to attempt to extract the value from. 271 /// \returns an optional value that contains a value if the form value 272 /// was valid and has an (absolute) debug info offset reference form. 273 inline std::optional<uint64_t> 274 toDebugInfoReference(const std::optional<DWARFFormValue> &V) { 275 if (V) 276 return V->getAsDebugInfoReference(); 277 return std::nullopt; 278 } 279 280 /// Take an optional DWARFFormValue and extract an absolute debug info offset 281 /// reference. 282 /// 283 /// \param V an optional DWARFFormValue to attempt to extract the value from. 284 /// \param Default the default value to return in case of failure. 285 /// \returns the extracted reference value or Default if the V doesn't have a 286 /// value or the form value's encoding wasn't an absolute debug info offset 287 /// reference form. 288 inline uint64_t toDebugInfoReference(const std::optional<DWARFFormValue> &V, 289 uint64_t Default) { 290 return toDebugInfoReference(V).value_or(Default); 291 } 292 293 /// Take an optional DWARFFormValue and try to extract a signature reference. 294 /// 295 /// \param V an optional DWARFFormValue to attempt to extract the value from. 296 /// \returns an optional value that contains a value if the form value 297 /// was valid and has a signature reference form. 298 inline std::optional<uint64_t> 299 toSignatureReference(const std::optional<DWARFFormValue> &V) { 300 if (V) 301 return V->getAsSignatureReference(); 302 return std::nullopt; 303 } 304 305 /// Take an optional DWARFFormValue and extract a signature reference. 306 /// 307 /// \param V an optional DWARFFormValue to attempt to extract the value from. 308 /// \param Default the default value to return in case of failure. 309 /// \returns the extracted reference value or Default if the V doesn't have a 310 /// value or the form value's encoding wasn't a signature reference form. 311 inline uint64_t toSignatureReference(const std::optional<DWARFFormValue> &V, 312 uint64_t Default) { 313 return toSignatureReference(V).value_or(Default); 314 } 315 316 /// Take an optional DWARFFormValue and try to extract a supplementary debug 317 /// info reference. 318 /// 319 /// \param V an 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 supplementary reference form. 322 inline std::optional<uint64_t> 323 toSupplementaryReference(const std::optional<DWARFFormValue> &V) { 324 if (V) 325 return V->getAsSupplementaryReference(); 326 return std::nullopt; 327 } 328 329 /// Take an optional DWARFFormValue and extract a supplementary debug info 330 /// reference. 331 /// 332 /// \param V an optional DWARFFormValue to attempt to extract the value from. 333 /// \param Default the default value to return in case of failure. 334 /// \returns the extracted reference value or Default if the V doesn't have a 335 /// value or the form value's encoding wasn't a supplementary reference form. 336 inline uint64_t toSupplementaryReference(const std::optional<DWARFFormValue> &V, 337 uint64_t Default) { 338 return toSupplementaryReference(V).value_or(Default); 339 } 340 341 /// Take an optional DWARFFormValue and try to extract an signed constant. 342 /// 343 /// \param V and optional DWARFFormValue to attempt to extract the value from. 344 /// \returns an optional value that contains a value if the form value 345 /// was valid and has a signed constant form. 346 inline std::optional<int64_t> toSigned(const std::optional<DWARFFormValue> &V) { 347 if (V) 348 return V->getAsSignedConstant(); 349 return std::nullopt; 350 } 351 352 /// Take an optional DWARFFormValue and extract a signed integer. 353 /// 354 /// \param V and optional DWARFFormValue to attempt to extract the value from. 355 /// \param Default the default value to return in case of failure. 356 /// \returns the extracted signed integer value or Default if the V doesn't 357 /// have a value or the form value's encoding wasn't a signed integer form. 358 inline int64_t toSigned(const std::optional<DWARFFormValue> &V, 359 int64_t Default) { 360 return toSigned(V).value_or(Default); 361 } 362 363 /// Take an optional DWARFFormValue and try to extract an address. 364 /// 365 /// \param V and optional DWARFFormValue to attempt to extract the value from. 366 /// \returns an optional value that contains a value if the form value 367 /// was valid and has a address form. 368 inline std::optional<uint64_t> 369 toAddress(const std::optional<DWARFFormValue> &V) { 370 if (V) 371 return V->getAsAddress(); 372 return std::nullopt; 373 } 374 375 inline std::optional<object::SectionedAddress> 376 toSectionedAddress(const std::optional<DWARFFormValue> &V) { 377 if (V) 378 return V->getAsSectionedAddress(); 379 return std::nullopt; 380 } 381 382 /// Take an optional DWARFFormValue and extract a address. 383 /// 384 /// \param V and optional DWARFFormValue to attempt to extract the value from. 385 /// \param Default the default value to return in case of failure. 386 /// \returns the extracted address value or Default if the V doesn't have a 387 /// value or the form value's encoding wasn't an address form. 388 inline uint64_t toAddress(const std::optional<DWARFFormValue> &V, 389 uint64_t Default) { 390 return toAddress(V).value_or(Default); 391 } 392 393 /// Take an optional DWARFFormValue and try to extract an section offset. 394 /// 395 /// \param V and optional DWARFFormValue to attempt to extract the value from. 396 /// \returns an optional value that contains a value if the form value 397 /// was valid and has a section offset form. 398 inline std::optional<uint64_t> 399 toSectionOffset(const std::optional<DWARFFormValue> &V) { 400 if (V) 401 return V->getAsSectionOffset(); 402 return std::nullopt; 403 } 404 405 /// Take an optional DWARFFormValue and extract a section offset. 406 /// 407 /// \param V and optional DWARFFormValue to attempt to extract the value from. 408 /// \param Default the default value to return in case of failure. 409 /// \returns the extracted section offset value or Default if the V doesn't 410 /// have a value or the form value's encoding wasn't a section offset form. 411 inline uint64_t toSectionOffset(const std::optional<DWARFFormValue> &V, 412 uint64_t Default) { 413 return toSectionOffset(V).value_or(Default); 414 } 415 416 /// Take an optional DWARFFormValue and try to extract block data. 417 /// 418 /// \param V and optional DWARFFormValue to attempt to extract the value from. 419 /// \returns an optional value that contains a value if the form value 420 /// was valid and has a block form. 421 inline std::optional<ArrayRef<uint8_t>> 422 toBlock(const std::optional<DWARFFormValue> &V) { 423 if (V) 424 return V->getAsBlock(); 425 return std::nullopt; 426 } 427 428 /// Check whether specified \p Form belongs to the \p FC class. 429 /// \param Form an attribute form. 430 /// \param FC an attribute form class to check. 431 /// \param DwarfVersion the version of DWARF debug info keeping the attribute. 432 /// \returns true if specified \p Form belongs to the \p FC class. 433 bool doesFormBelongToClass(dwarf::Form Form, DWARFFormValue::FormClass FC, 434 uint16_t DwarfVersion); 435 436 } // end namespace dwarf 437 438 } // end namespace llvm 439 440 #endif // LLVM_DEBUGINFO_DWARF_DWARFFORMVALUE_H 441