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