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_DWARFFORMVALUE_H 10 #define LLVM_DEBUGINFO_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/DebugInfo/DWARF/DWARFDataExtractor.h" 18 #include <cstdint> 19 20 namespace llvm { 21 22 class DWARFContext; 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 bool isInlinedCStr() const { 106 return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr; 107 } 108 109 /// getAsFoo functions below return the extracted value as Foo if only 110 /// DWARFFormValue has form class is suitable for representing Foo. 111 Optional<uint64_t> getAsReference() const; 112 struct UnitOffset { 113 DWARFUnit *Unit; 114 uint64_t Offset; 115 }; 116 Optional<UnitOffset> getAsRelativeReference() const; 117 Optional<uint64_t> getAsUnsignedConstant() const; 118 Optional<int64_t> getAsSignedConstant() const; 119 Optional<const char *> getAsCString() const; 120 Optional<uint64_t> getAsAddress() const; 121 Optional<object::SectionedAddress> getAsSectionedAddress() const; 122 Optional<uint64_t> getAsSectionOffset() const; 123 Optional<ArrayRef<uint8_t>> getAsBlock() const; 124 Optional<uint64_t> getAsCStringOffset() const; 125 Optional<uint64_t> getAsReferenceUVal() const; 126 127 /// Skip a form's value in \p DebugInfoData at the offset specified by 128 /// \p OffsetPtr. 129 /// 130 /// Skips the bytes for the current form and updates the offset. 131 /// 132 /// \param DebugInfoData The data where we want to skip the value. 133 /// \param OffsetPtr A reference to the offset that will be updated. 134 /// \param Params DWARF parameters to help interpret forms. 135 /// \returns true on success, false if the form was not skipped. 136 bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, 137 const dwarf::FormParams Params) const { 138 return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); 139 } 140 141 /// Skip a form's value in \p DebugInfoData at the offset specified by 142 /// \p OffsetPtr. 143 /// 144 /// Skips the bytes for the specified form and updates the offset. 145 /// 146 /// \param Form The DW_FORM enumeration that indicates the form to skip. 147 /// \param DebugInfoData The data where we want to skip the value. 148 /// \param OffsetPtr A reference to the offset that will be updated. 149 /// \param FormParams DWARF parameters to help interpret forms. 150 /// \returns true on success, false if the form was not skipped. 151 static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, 152 uint64_t *OffsetPtr, 153 const dwarf::FormParams FormParams); 154 155 private: 156 void dumpString(raw_ostream &OS) const; 157 }; 158 159 namespace dwarf { 160 161 /// Take an optional DWARFFormValue and try to extract a string value from it. 162 /// 163 /// \param V and optional DWARFFormValue to attempt to extract the value from. 164 /// \returns an optional value that contains a value if the form value 165 /// was valid and was a string. 166 inline Optional<const char *> toString(const Optional<DWARFFormValue> &V) { 167 if (V) 168 return V->getAsCString(); 169 return None; 170 } 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 StringRef toStringRef(const Optional<DWARFFormValue> &V, 178 StringRef Default = {}) { 179 if (V) 180 if (auto S = V->getAsCString()) 181 return *S; 182 return Default; 183 } 184 185 /// Take an optional DWARFFormValue and extract a string value from it. 186 /// 187 /// \param V and optional DWARFFormValue to attempt to extract the value from. 188 /// \param Default the default value to return in case of failure. 189 /// \returns the string value or Default if the V doesn't have a value or the 190 /// form value's encoding wasn't a string. 191 inline const char *toString(const Optional<DWARFFormValue> &V, 192 const char *Default) { 193 return toString(V).getValueOr(Default); 194 } 195 196 /// Take an optional DWARFFormValue and try to extract an unsigned constant. 197 /// 198 /// \param V and optional DWARFFormValue to attempt to extract the value from. 199 /// \returns an optional value that contains a value if the form value 200 /// was valid and has a unsigned constant form. 201 inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue> &V) { 202 if (V) 203 return V->getAsUnsignedConstant(); 204 return None; 205 } 206 207 /// Take an optional DWARFFormValue and extract a unsigned constant. 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 extracted unsigned value or Default if the V doesn't have a 212 /// value or the form value's encoding wasn't an unsigned constant form. 213 inline uint64_t toUnsigned(const Optional<DWARFFormValue> &V, 214 uint64_t Default) { 215 return toUnsigned(V).getValueOr(Default); 216 } 217 218 /// Take an optional DWARFFormValue and try to extract an reference. 219 /// 220 /// \param V and optional DWARFFormValue to attempt to extract the value from. 221 /// \returns an optional value that contains a value if the form value 222 /// was valid and has a reference form. 223 inline Optional<uint64_t> toReference(const Optional<DWARFFormValue> &V) { 224 if (V) 225 return V->getAsReference(); 226 return None; 227 } 228 229 /// Take an optional DWARFFormValue and extract a reference. 230 /// 231 /// \param V and optional DWARFFormValue to attempt to extract the value from. 232 /// \param Default the default value to return in case of failure. 233 /// \returns the extracted reference value or Default if the V doesn't have a 234 /// value or the form value's encoding wasn't a reference form. 235 inline uint64_t toReference(const Optional<DWARFFormValue> &V, 236 uint64_t Default) { 237 return toReference(V).getValueOr(Default); 238 } 239 240 /// Take an optional DWARFFormValue and try to extract an signed constant. 241 /// 242 /// \param V and optional DWARFFormValue to attempt to extract the value from. 243 /// \returns an optional value that contains a value if the form value 244 /// was valid and has a signed constant form. 245 inline Optional<int64_t> toSigned(const Optional<DWARFFormValue> &V) { 246 if (V) 247 return V->getAsSignedConstant(); 248 return None; 249 } 250 251 /// Take an optional DWARFFormValue and extract a signed integer. 252 /// 253 /// \param V and optional DWARFFormValue to attempt to extract the value from. 254 /// \param Default the default value to return in case of failure. 255 /// \returns the extracted signed integer value or Default if the V doesn't 256 /// have a value or the form value's encoding wasn't a signed integer form. 257 inline int64_t toSigned(const Optional<DWARFFormValue> &V, int64_t Default) { 258 return toSigned(V).getValueOr(Default); 259 } 260 261 /// Take an optional DWARFFormValue and try to extract an address. 262 /// 263 /// \param V and optional DWARFFormValue to attempt to extract the value from. 264 /// \returns an optional value that contains a value if the form value 265 /// was valid and has a address form. 266 inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) { 267 if (V) 268 return V->getAsAddress(); 269 return None; 270 } 271 272 inline Optional<object::SectionedAddress> 273 toSectionedAddress(const Optional<DWARFFormValue> &V) { 274 if (V) 275 return V->getAsSectionedAddress(); 276 return None; 277 } 278 279 /// Take an optional DWARFFormValue and extract a address. 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 address value or Default if the V doesn't have a 284 /// value or the form value's encoding wasn't an address form. 285 inline uint64_t toAddress(const Optional<DWARFFormValue> &V, uint64_t Default) { 286 return toAddress(V).getValueOr(Default); 287 } 288 289 /// Take an optional DWARFFormValue and try to extract an section offset. 290 /// 291 /// \param V and optional DWARFFormValue to attempt to extract the value from. 292 /// \returns an optional value that contains a value if the form value 293 /// was valid and has a section offset form. 294 inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue> &V) { 295 if (V) 296 return V->getAsSectionOffset(); 297 return None; 298 } 299 300 /// Take an optional DWARFFormValue and extract a section offset. 301 /// 302 /// \param V and optional DWARFFormValue to attempt to extract the value from. 303 /// \param Default the default value to return in case of failure. 304 /// \returns the extracted section offset value or Default if the V doesn't 305 /// have a value or the form value's encoding wasn't a section offset form. 306 inline uint64_t toSectionOffset(const Optional<DWARFFormValue> &V, 307 uint64_t Default) { 308 return toSectionOffset(V).getValueOr(Default); 309 } 310 311 /// Take an optional DWARFFormValue and try to extract block data. 312 /// 313 /// \param V and optional DWARFFormValue to attempt to extract the value from. 314 /// \returns an optional value that contains a value if the form value 315 /// was valid and has a block form. 316 inline Optional<ArrayRef<uint8_t>> toBlock(const Optional<DWARFFormValue> &V) { 317 if (V) 318 return V->getAsBlock(); 319 return None; 320 } 321 322 } // end namespace dwarf 323 324 } // end namespace llvm 325 326 #endif // LLVM_DEBUGINFO_DWARFFORMVALUE_H 327