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