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