DWARFFormValue.h revision 327952
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 21namespace llvm { 22 23class DWARFUnit; 24class 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. 29struct 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 55class DWARFFormValue { 56public: 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 70private: 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 87public: 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. The information 108 /// in \p FormParams is needed to interpret some forms. The optional 109 /// \p Unit allows extracting information if the form refers to other 110 /// sections (e.g., .debug_str). 111 bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, 112 DWARFFormParams FormParams, const DWARFUnit *U = nullptr); 113 114 bool isInlinedCStr() const { 115 return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr; 116 } 117 118 /// getAsFoo functions below return the extracted value as Foo if only 119 /// DWARFFormValue has form class is suitable for representing Foo. 120 Optional<uint64_t> getAsReference() const; 121 Optional<uint64_t> getAsUnsignedConstant() const; 122 Optional<int64_t> getAsSignedConstant() const; 123 Optional<const char *> getAsCString() const; 124 Optional<uint64_t> getAsAddress() const; 125 Optional<uint64_t> getAsSectionOffset() const; 126 Optional<ArrayRef<uint8_t>> getAsBlock() const; 127 Optional<uint64_t> getAsCStringOffset() const; 128 Optional<uint64_t> getAsReferenceUVal() const; 129 130 /// Get the fixed byte size for a given form. 131 /// 132 /// If the form has a fixed byte size, then an Optional with a value will be 133 /// returned. If the form is always encoded using a variable length storage 134 /// format (ULEB or SLEB numbers or blocks) then None will be returned. 135 /// 136 /// \param Form DWARF form to get the fixed byte size for. 137 /// \param FormParams DWARF parameters to help interpret forms. 138 /// \returns Optional<uint8_t> value with the fixed byte size or None if 139 /// \p Form doesn't have a fixed byte size. 140 static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, 141 const DWARFFormParams FormParams); 142 143 /// Skip a form's value in \p DebugInfoData at the offset specified by 144 /// \p OffsetPtr. 145 /// 146 /// Skips the bytes for the current form and updates the offset. 147 /// 148 /// \param DebugInfoData The data where we want to skip the value. 149 /// \param OffsetPtr A reference to the offset that will be updated. 150 /// \param Params DWARF parameters to help interpret forms. 151 /// \returns true on success, false if the form was not skipped. 152 bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr, 153 const DWARFFormParams Params) const { 154 return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); 155 } 156 157 /// Skip a form's value in \p DebugInfoData at the offset specified by 158 /// \p OffsetPtr. 159 /// 160 /// Skips the bytes for the specified form and updates the offset. 161 /// 162 /// \param Form The DW_FORM enumeration that indicates the form to skip. 163 /// \param DebugInfoData The data where we want to skip the value. 164 /// \param OffsetPtr A reference to the offset that will be updated. 165 /// \param FormParams DWARF parameters to help interpret forms. 166 /// \returns true on success, false if the form was not skipped. 167 static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, 168 uint32_t *OffsetPtr, const DWARFFormParams FormParams); 169 170private: 171 void dumpString(raw_ostream &OS) const; 172}; 173 174namespace dwarf { 175 176/// Take an optional DWARFFormValue and try to extract a string value from it. 177/// 178/// \param V and optional DWARFFormValue to attempt to extract the value from. 179/// \returns an optional value that contains a value if the form value 180/// was valid and was a string. 181inline Optional<const char *> toString(const Optional<DWARFFormValue> &V) { 182 if (V) 183 return V->getAsCString(); 184 return None; 185} 186 187/// Take an optional DWARFFormValue and extract a string value from it. 188/// 189/// \param V and optional DWARFFormValue to attempt to extract the value from. 190/// \param Default the default value to return in case of failure. 191/// \returns the string value or Default if the V doesn't have a value or the 192/// form value's encoding wasn't a string. 193inline const char *toString(const Optional<DWARFFormValue> &V, 194 const char *Default) { 195 return toString(V).getValueOr(Default); 196} 197 198/// Take an optional DWARFFormValue and try to extract an unsigned constant. 199/// 200/// \param V and optional DWARFFormValue to attempt to extract the value from. 201/// \returns an optional value that contains a value if the form value 202/// was valid and has a unsigned constant form. 203inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue> &V) { 204 if (V) 205 return V->getAsUnsignedConstant(); 206 return None; 207} 208 209/// Take an optional DWARFFormValue and extract a unsigned constant. 210/// 211/// \param V and optional DWARFFormValue to attempt to extract the value from. 212/// \param Default the default value to return in case of failure. 213/// \returns the extracted unsigned value or Default if the V doesn't have a 214/// value or the form value's encoding wasn't an unsigned constant form. 215inline uint64_t toUnsigned(const Optional<DWARFFormValue> &V, 216 uint64_t Default) { 217 return toUnsigned(V).getValueOr(Default); 218} 219 220/// Take an optional DWARFFormValue and try to extract an reference. 221/// 222/// \param V and optional DWARFFormValue to attempt to extract the value from. 223/// \returns an optional value that contains a value if the form value 224/// was valid and has a reference form. 225inline Optional<uint64_t> toReference(const Optional<DWARFFormValue> &V) { 226 if (V) 227 return V->getAsReference(); 228 return None; 229} 230 231/// Take an optional DWARFFormValue and extract a reference. 232/// 233/// \param V and optional DWARFFormValue to attempt to extract the value from. 234/// \param Default the default value to return in case of failure. 235/// \returns the extracted reference value or Default if the V doesn't have a 236/// value or the form value's encoding wasn't a reference form. 237inline uint64_t toReference(const Optional<DWARFFormValue> &V, 238 uint64_t Default) { 239 return toReference(V).getValueOr(Default); 240} 241 242/// Take an optional DWARFFormValue and try to extract an signed constant. 243/// 244/// \param V and optional DWARFFormValue to attempt to extract the value from. 245/// \returns an optional value that contains a value if the form value 246/// was valid and has a signed constant form. 247inline Optional<int64_t> toSigned(const Optional<DWARFFormValue> &V) { 248 if (V) 249 return V->getAsSignedConstant(); 250 return None; 251} 252 253/// Take an optional DWARFFormValue and extract a signed integer. 254/// 255/// \param V and optional DWARFFormValue to attempt to extract the value from. 256/// \param Default the default value to return in case of failure. 257/// \returns the extracted signed integer value or Default if the V doesn't 258/// have a value or the form value's encoding wasn't a signed integer form. 259inline int64_t toSigned(const Optional<DWARFFormValue> &V, int64_t Default) { 260 return toSigned(V).getValueOr(Default); 261} 262 263/// Take an optional DWARFFormValue and try to extract an address. 264/// 265/// \param V and optional DWARFFormValue to attempt to extract the value from. 266/// \returns an optional value that contains a value if the form value 267/// was valid and has a address form. 268inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) { 269 if (V) 270 return V->getAsAddress(); 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