1 //===- DWARFFormValue.h -----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H 11 #define LLVM_DEBUGINFO_DWARFFORMVALUE_H 12 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/ADT/None.h" 15 #include "llvm/ADT/Optional.h" 16 #include "llvm/BinaryFormat/Dwarf.h" 17 #include "llvm/DebugInfo/DIContext.h" 18 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" 19 #include <cstdint> 20 21 namespace llvm { 22 23 class DWARFUnit; 24 class raw_ostream; 25 26 /// A helper struct for DWARFFormValue methods, providing information that 27 /// allows it to know the byte size of DW_FORM values that vary in size 28 /// depending on the DWARF version, address byte size, or DWARF32/DWARF64. 29 struct DWARFFormParams { 30 uint16_t Version; 31 uint8_t AddrSize; 32 dwarf::DwarfFormat Format; 33 34 /// The definition of the size of form DW_FORM_ref_addr depends on the 35 /// version. In DWARF v2 it's the size of an address; after that, it's the 36 /// size of a reference. 37 uint8_t getRefAddrByteSize() const { 38 if (Version == 2) 39 return AddrSize; 40 return getDwarfOffsetByteSize(); 41 } 42 43 /// The size of a reference is determined by the DWARF 32/64-bit format. 44 uint8_t getDwarfOffsetByteSize() const { 45 switch (Format) { 46 case dwarf::DwarfFormat::DWARF32: 47 return 4; 48 case dwarf::DwarfFormat::DWARF64: 49 return 8; 50 } 51 llvm_unreachable("Invalid Format value"); 52 } 53 }; 54 55 class DWARFFormValue { 56 public: 57 enum FormClass { 58 FC_Unknown, 59 FC_Address, 60 FC_Block, 61 FC_Constant, 62 FC_String, 63 FC_Flag, 64 FC_Reference, 65 FC_Indirect, 66 FC_SectionOffset, 67 FC_Exprloc 68 }; 69 70 private: 71 struct ValueType { 72 ValueType() { uval = 0; } 73 74 union { 75 uint64_t uval; 76 int64_t sval; 77 const char *cstr; 78 }; 79 const uint8_t *data = nullptr; 80 uint64_t SectionIndex; /// Section index for reference forms. 81 }; 82 83 dwarf::Form Form; /// Form for this value. 84 ValueType Value; /// Contains all data for the form. 85 const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time. 86 87 public: 88 DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {} 89 90 dwarf::Form getForm() const { return Form; } 91 uint64_t getRawUValue() const { return Value.uval; } 92 uint64_t getSectionIndex() const { return Value.SectionIndex; } 93 void setForm(dwarf::Form F) { Form = F; } 94 void setUValue(uint64_t V) { Value.uval = V; } 95 void setSValue(int64_t V) { Value.sval = V; } 96 void setPValue(const char *V) { Value.cstr = V; } 97 98 void setBlockValue(const ArrayRef<uint8_t> &Data) { 99 Value.data = Data.data(); 100 setUValue(Data.size()); 101 } 102 103 bool isFormClass(FormClass FC) const; 104 const DWARFUnit *getUnit() const { return U; } 105 void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const; 106 107 /// Extracts a value in \p Data at offset \p *OffsetPtr. 108 /// 109 /// The passed DWARFUnit is allowed to be nullptr, in which case some 110 /// kind of forms that depend on Unit information are disallowed. 111 /// \param Data The DWARFDataExtractor to use. 112 /// \param OffsetPtr The offset within \p Data where the data starts. 113 /// \param U The optional DWARFUnit supplying information for some forms. 114 /// \returns whether the extraction succeeded. 115 bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, 116 const DWARFUnit *U); 117 118 bool isInlinedCStr() const { 119 return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr; 120 } 121 122 /// getAsFoo functions below return the extracted value as Foo if only 123 /// DWARFFormValue has form class is suitable for representing Foo. 124 Optional<uint64_t> getAsReference() const; 125 Optional<uint64_t> getAsUnsignedConstant() const; 126 Optional<int64_t> getAsSignedConstant() const; 127 Optional<const char *> getAsCString() const; 128 Optional<uint64_t> getAsAddress() const; 129 Optional<uint64_t> getAsSectionOffset() const; 130 Optional<ArrayRef<uint8_t>> getAsBlock() const; 131 Optional<uint64_t> getAsCStringOffset() const; 132 Optional<uint64_t> getAsReferenceUVal() const; 133 134 /// Get the fixed byte size for a given form. 135 /// 136 /// If the form has a fixed byte size, then an Optional with a value will be 137 /// returned. If the form is always encoded using a variable length storage 138 /// format (ULEB or SLEB numbers or blocks) then None will be returned. 139 /// 140 /// \param Form DWARF form to get the fixed byte size for. 141 /// \param FormParams DWARF parameters to help interpret forms. 142 /// \returns Optional<uint8_t> value with the fixed byte size or None if 143 /// \p Form doesn't have a fixed byte size. 144 static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, 145 const DWARFFormParams FormParams); 146 147 /// Skip a form's value in \p DebugInfoData at the offset specified by 148 /// \p OffsetPtr. 149 /// 150 /// Skips the bytes for the current form and updates the offset. 151 /// 152 /// \param DebugInfoData The data where we want to skip the value. 153 /// \param OffsetPtr A reference to the offset that will be updated. 154 /// \param Params DWARF parameters to help interpret forms. 155 /// \returns true on success, false if the form was not skipped. 156 bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr, 157 const DWARFFormParams Params) const { 158 return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); 159 } 160 161 /// Skip a form's value in \p DebugInfoData at the offset specified by 162 /// \p OffsetPtr. 163 /// 164 /// Skips the bytes for the specified form and updates the offset. 165 /// 166 /// \param Form The DW_FORM enumeration that indicates the form to skip. 167 /// \param DebugInfoData The data where we want to skip the value. 168 /// \param OffsetPtr A reference to the offset that will be updated. 169 /// \param FormParams DWARF parameters to help interpret forms. 170 /// \returns true on success, false if the form was not skipped. 171 static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, 172 uint32_t *OffsetPtr, const DWARFFormParams FormParams); 173 174 private: 175 void dumpString(raw_ostream &OS) const; 176 }; 177 178 namespace dwarf { 179 180 /// Take an optional DWARFFormValue and try to extract a string value from it. 181 /// 182 /// \param V and optional DWARFFormValue to attempt to extract the value from. 183 /// \returns an optional value that contains a value if the form value 184 /// was valid and was a string. 185 inline Optional<const char *> toString(const Optional<DWARFFormValue> &V) { 186 if (V) 187 return V->getAsCString(); 188 return None; 189 } 190 191 /// Take an optional DWARFFormValue and extract a string value from it. 192 /// 193 /// \param V and optional DWARFFormValue to attempt to extract the value from. 194 /// \param Default the default value to return in case of failure. 195 /// \returns the string value or Default if the V doesn't have a value or the 196 /// form value's encoding wasn't a string. 197 inline const char *toString(const Optional<DWARFFormValue> &V, 198 const char *Default) { 199 return toString(V).getValueOr(Default); 200 } 201 202 /// Take an optional DWARFFormValue and try to extract an unsigned constant. 203 /// 204 /// \param V and optional DWARFFormValue to attempt to extract the value from. 205 /// \returns an optional value that contains a value if the form value 206 /// was valid and has a unsigned constant form. 207 inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue> &V) { 208 if (V) 209 return V->getAsUnsignedConstant(); 210 return None; 211 } 212 213 /// Take an optional DWARFFormValue and extract a unsigned constant. 214 /// 215 /// \param V and optional DWARFFormValue to attempt to extract the value from. 216 /// \param Default the default value to return in case of failure. 217 /// \returns the extracted unsigned value or Default if the V doesn't have a 218 /// value or the form value's encoding wasn't an unsigned constant form. 219 inline uint64_t toUnsigned(const Optional<DWARFFormValue> &V, 220 uint64_t Default) { 221 return toUnsigned(V).getValueOr(Default); 222 } 223 224 /// Take an optional DWARFFormValue and try to extract an reference. 225 /// 226 /// \param V and optional DWARFFormValue to attempt to extract the value from. 227 /// \returns an optional value that contains a value if the form value 228 /// was valid and has a reference form. 229 inline Optional<uint64_t> toReference(const Optional<DWARFFormValue> &V) { 230 if (V) 231 return V->getAsReference(); 232 return None; 233 } 234 235 /// Take an optional DWARFFormValue and extract a reference. 236 /// 237 /// \param V and optional DWARFFormValue to attempt to extract the value from. 238 /// \param Default the default value to return in case of failure. 239 /// \returns the extracted reference value or Default if the V doesn't have a 240 /// value or the form value's encoding wasn't a reference form. 241 inline uint64_t toReference(const Optional<DWARFFormValue> &V, 242 uint64_t Default) { 243 return toReference(V).getValueOr(Default); 244 } 245 246 /// Take an optional DWARFFormValue and try to extract an signed constant. 247 /// 248 /// \param V and optional DWARFFormValue to attempt to extract the value from. 249 /// \returns an optional value that contains a value if the form value 250 /// was valid and has a signed constant form. 251 inline Optional<int64_t> toSigned(const Optional<DWARFFormValue> &V) { 252 if (V) 253 return V->getAsSignedConstant(); 254 return None; 255 } 256 257 /// Take an optional DWARFFormValue and extract a signed integer. 258 /// 259 /// \param V and optional DWARFFormValue to attempt to extract the value from. 260 /// \param Default the default value to return in case of failure. 261 /// \returns the extracted signed integer value or Default if the V doesn't 262 /// have a value or the form value's encoding wasn't a signed integer form. 263 inline int64_t toSigned(const Optional<DWARFFormValue> &V, int64_t Default) { 264 return toSigned(V).getValueOr(Default); 265 } 266 267 /// Take an optional DWARFFormValue and try to extract an address. 268 /// 269 /// \param V and optional DWARFFormValue to attempt to extract the value from. 270 /// \returns an optional value that contains a value if the form value 271 /// was valid and has a address form. 272 inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) { 273 if (V) 274 return V->getAsAddress(); 275 return None; 276 } 277 278 /// Take an optional DWARFFormValue and extract a address. 279 /// 280 /// \param V and optional DWARFFormValue to attempt to extract the value from. 281 /// \param Default the default value to return in case of failure. 282 /// \returns the extracted address value or Default if the V doesn't have a 283 /// value or the form value's encoding wasn't an address form. 284 inline uint64_t toAddress(const Optional<DWARFFormValue> &V, uint64_t Default) { 285 return toAddress(V).getValueOr(Default); 286 } 287 288 /// Take an optional DWARFFormValue and try to extract an section offset. 289 /// 290 /// \param V and optional DWARFFormValue to attempt to extract the value from. 291 /// \returns an optional value that contains a value if the form value 292 /// was valid and has a section offset form. 293 inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue> &V) { 294 if (V) 295 return V->getAsSectionOffset(); 296 return None; 297 } 298 299 /// Take an optional DWARFFormValue and extract a section offset. 300 /// 301 /// \param V and optional DWARFFormValue to attempt to extract the value from. 302 /// \param Default the default value to return in case of failure. 303 /// \returns the extracted section offset value or Default if the V doesn't 304 /// have a value or the form value's encoding wasn't a section offset form. 305 inline uint64_t toSectionOffset(const Optional<DWARFFormValue> &V, 306 uint64_t Default) { 307 return toSectionOffset(V).getValueOr(Default); 308 } 309 310 /// Take an optional DWARFFormValue and try to extract block data. 311 /// 312 /// \param V and optional DWARFFormValue to attempt to extract the value from. 313 /// \returns an optional value that contains a value if the form value 314 /// was valid and has a block form. 315 inline Optional<ArrayRef<uint8_t>> toBlock(const Optional<DWARFFormValue> &V) { 316 if (V) 317 return V->getAsBlock(); 318 return None; 319 } 320 321 } // end namespace dwarf 322 323 } // end namespace llvm 324 325 #endif // LLVM_DEBUGINFO_DWARFFORMVALUE_H 326