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, 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> getAsReference() const; 111 struct UnitOffset { 112 DWARFUnit *Unit; 113 uint64_t Offset; 114 }; 115 std::optional<UnitOffset> getAsRelativeReference() const; 116 std::optional<uint64_t> getAsUnsignedConstant() const; 117 std::optional<int64_t> getAsSignedConstant() const; 118 Expected<const char *> getAsCString() const; 119 std::optional<uint64_t> getAsAddress() const; 120 std::optional<object::SectionedAddress> getAsSectionedAddress() const; 121 std::optional<uint64_t> getAsSectionOffset() const; 122 std::optional<ArrayRef<uint8_t>> getAsBlock() const; 123 std::optional<uint64_t> getAsCStringOffset() const; 124 std::optional<uint64_t> getAsReferenceUVal() const; 125 /// Correctly extract any file paths from a form value. 126 /// 127 /// These attributes can be in the from DW_AT_decl_file or DW_AT_call_file 128 /// attributes. We need to use the file index in the correct DWARFUnit's line 129 /// table prologue, and each DWARFFormValue has the DWARFUnit the form value 130 /// was extracted from. 131 /// 132 /// \param Kind The kind of path to extract. 133 /// 134 /// \returns A valid string value on success, or std::nullopt if the form 135 /// class is not FC_Constant, or if the file index is not valid. 136 std::optional<std::string> 137 getAsFile(DILineInfoSpecifier::FileLineInfoKind Kind) const; 138 139 /// Skip a form's value in \p DebugInfoData at the offset specified by 140 /// \p OffsetPtr. 141 /// 142 /// Skips the bytes for the current form and updates the offset. 143 /// 144 /// \param DebugInfoData The data where we want to skip the value. 145 /// \param OffsetPtr A reference to the offset that will be updated. 146 /// \param Params DWARF parameters to help interpret forms. 147 /// \returns true on success, false if the form was not skipped. 148 bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, 149 const dwarf::FormParams Params) const { 150 return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); 151 } 152 153 /// Skip a form's value in \p DebugInfoData at the offset specified by 154 /// \p OffsetPtr. 155 /// 156 /// Skips the bytes for the specified form and updates the offset. 157 /// 158 /// \param Form The DW_FORM enumeration that indicates the form to skip. 159 /// \param DebugInfoData The data where we want to skip the value. 160 /// \param OffsetPtr A reference to the offset that will be updated. 161 /// \param FormParams DWARF parameters to help interpret forms. 162 /// \returns true on success, false if the form was not skipped. 163 static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, 164 uint64_t *OffsetPtr, 165 const dwarf::FormParams FormParams); 166 167 private: 168 void dumpString(raw_ostream &OS) const; 169 }; 170 171 namespace dwarf { 172 173 /// Take an optional DWARFFormValue and try to extract a string value from it. 174 /// 175 /// \param V and optional DWARFFormValue to attempt to extract the value from. 176 /// \returns an optional value that contains a value if the form value 177 /// was valid and was a string. 178 inline std::optional<const char *> 179 toString(const std::optional<DWARFFormValue> &V) { 180 if (!V) 181 return std::nullopt; 182 Expected<const char*> E = V->getAsCString(); 183 if (!E) { 184 consumeError(E.takeError()); 185 return std::nullopt; 186 } 187 return *E; 188 } 189 190 /// Take an optional DWARFFormValue and try to extract a string value from it. 191 /// 192 /// \param V and optional DWARFFormValue to attempt to extract the value from. 193 /// \returns an optional value that contains a value if the form value 194 /// was valid and was a string. 195 inline StringRef toStringRef(const std::optional<DWARFFormValue> &V, 196 StringRef Default = {}) { 197 if (!V) 198 return Default; 199 auto S = V->getAsCString(); 200 if (!S) { 201 consumeError(S.takeError()); 202 return Default; 203 } 204 if (!*S) 205 return Default; 206 return *S; 207 } 208 209 /// Take an optional DWARFFormValue and extract a string value from it. 210 /// 211 /// \param V and optional DWARFFormValue to attempt to extract the value from. 212 /// \param Default the default value to return in case of failure. 213 /// \returns the string value or Default if the V doesn't have a value or the 214 /// form value's encoding wasn't a string. 215 inline const char *toString(const std::optional<DWARFFormValue> &V, 216 const char *Default) { 217 if (auto E = toString(V)) 218 return *E; 219 return Default; 220 } 221 222 /// Take an optional DWARFFormValue and try to extract an unsigned constant. 223 /// 224 /// \param V and optional DWARFFormValue to attempt to extract the value from. 225 /// \returns an optional value that contains a value if the form value 226 /// was valid and has a unsigned constant form. 227 inline std::optional<uint64_t> 228 toUnsigned(const std::optional<DWARFFormValue> &V) { 229 if (V) 230 return V->getAsUnsignedConstant(); 231 return std::nullopt; 232 } 233 234 /// Take an optional DWARFFormValue and extract a unsigned constant. 235 /// 236 /// \param V and optional DWARFFormValue to attempt to extract the value from. 237 /// \param Default the default value to return in case of failure. 238 /// \returns the extracted unsigned value or Default if the V doesn't have a 239 /// value or the form value's encoding wasn't an unsigned constant form. 240 inline uint64_t toUnsigned(const std::optional<DWARFFormValue> &V, 241 uint64_t Default) { 242 return toUnsigned(V).value_or(Default); 243 } 244 245 /// Take an optional DWARFFormValue and try to extract an reference. 246 /// 247 /// \param V and optional DWARFFormValue to attempt to extract the value from. 248 /// \returns an optional value that contains a value if the form value 249 /// was valid and has a reference form. 250 inline std::optional<uint64_t> 251 toReference(const std::optional<DWARFFormValue> &V) { 252 if (V) 253 return V->getAsReference(); 254 return std::nullopt; 255 } 256 257 /// Take an optional DWARFFormValue and extract a reference. 258 /// 259 /// \param V and optional DWARFFormValue to attempt to extract the value from. 260 /// \param Default the default value to return in case of failure. 261 /// \returns the extracted reference value or Default if the V doesn't have a 262 /// value or the form value's encoding wasn't a reference form. 263 inline uint64_t toReference(const std::optional<DWARFFormValue> &V, 264 uint64_t Default) { 265 return toReference(V).value_or(Default); 266 } 267 268 /// Take an optional DWARFFormValue and try to extract an signed constant. 269 /// 270 /// \param V and 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 a signed constant form. 273 inline std::optional<int64_t> toSigned(const std::optional<DWARFFormValue> &V) { 274 if (V) 275 return V->getAsSignedConstant(); 276 return std::nullopt; 277 } 278 279 /// Take an optional DWARFFormValue and extract a signed integer. 280 /// 281 /// \param V and optional DWARFFormValue to attempt to extract the value from. 282 /// \param Default the default value to return in case of failure. 283 /// \returns the extracted signed integer value or Default if the V doesn't 284 /// have a value or the form value's encoding wasn't a signed integer form. 285 inline int64_t toSigned(const std::optional<DWARFFormValue> &V, 286 int64_t Default) { 287 return toSigned(V).value_or(Default); 288 } 289 290 /// Take an optional DWARFFormValue and try to extract an address. 291 /// 292 /// \param V and optional DWARFFormValue to attempt to extract the value from. 293 /// \returns an optional value that contains a value if the form value 294 /// was valid and has a address form. 295 inline std::optional<uint64_t> 296 toAddress(const std::optional<DWARFFormValue> &V) { 297 if (V) 298 return V->getAsAddress(); 299 return std::nullopt; 300 } 301 302 inline std::optional<object::SectionedAddress> 303 toSectionedAddress(const std::optional<DWARFFormValue> &V) { 304 if (V) 305 return V->getAsSectionedAddress(); 306 return std::nullopt; 307 } 308 309 /// Take an optional DWARFFormValue and extract a address. 310 /// 311 /// \param V and optional DWARFFormValue to attempt to extract the value from. 312 /// \param Default the default value to return in case of failure. 313 /// \returns the extracted address value or Default if the V doesn't have a 314 /// value or the form value's encoding wasn't an address form. 315 inline uint64_t toAddress(const std::optional<DWARFFormValue> &V, 316 uint64_t Default) { 317 return toAddress(V).value_or(Default); 318 } 319 320 /// Take an optional DWARFFormValue and try to extract an section offset. 321 /// 322 /// \param V and optional DWARFFormValue to attempt to extract the value from. 323 /// \returns an optional value that contains a value if the form value 324 /// was valid and has a section offset form. 325 inline std::optional<uint64_t> 326 toSectionOffset(const std::optional<DWARFFormValue> &V) { 327 if (V) 328 return V->getAsSectionOffset(); 329 return std::nullopt; 330 } 331 332 /// Take an optional DWARFFormValue and extract a section offset. 333 /// 334 /// \param V and optional DWARFFormValue to attempt to extract the value from. 335 /// \param Default the default value to return in case of failure. 336 /// \returns the extracted section offset value or Default if the V doesn't 337 /// have a value or the form value's encoding wasn't a section offset form. 338 inline uint64_t toSectionOffset(const std::optional<DWARFFormValue> &V, 339 uint64_t Default) { 340 return toSectionOffset(V).value_or(Default); 341 } 342 343 /// Take an optional DWARFFormValue and try to extract block data. 344 /// 345 /// \param V and optional DWARFFormValue to attempt to extract the value from. 346 /// \returns an optional value that contains a value if the form value 347 /// was valid and has a block form. 348 inline std::optional<ArrayRef<uint8_t>> 349 toBlock(const std::optional<DWARFFormValue> &V) { 350 if (V) 351 return V->getAsBlock(); 352 return std::nullopt; 353 } 354 355 /// Check whether specified \p Form belongs to the \p FC class. 356 /// \param Form an attribute form. 357 /// \param FC an attribute form class to check. 358 /// \param DwarfVersion the version of DWARF debug info keeping the attribute. 359 /// \returns true if specified \p Form belongs to the \p FC class. 360 bool doesFormBelongToClass(dwarf::Form Form, DWARFFormValue::FormClass FC, 361 uint16_t DwarfVersion); 362 363 } // end namespace dwarf 364 365 } // end namespace llvm 366 367 #endif // LLVM_DEBUGINFO_DWARF_DWARFFORMVALUE_H 368