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 20namespace llvm { 21 22class DWARFContext; 23class DWARFUnit; 24class raw_ostream; 25 26class DWARFFormValue { 27public: 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 41private: 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 64public: 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 150private: 151 void dumpString(raw_ostream &OS) const; 152}; 153 154namespace 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. 161inline 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. 172inline 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. 186inline 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. 196inline 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. 208inline 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. 218inline 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. 230inline 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. 240inline 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. 252inline 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. 261inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) { 262 if (V) 263 return V->getAsAddress(); 264 return None; 265} 266 267inline Optional<object::SectionedAddress> 268toSectionedAddress(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. 280inline 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. 289inline 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. 301inline 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. 311inline 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