1321369Sdim//===- DWARFFormValue.h -----------------------------------------*- C++ -*-===// 2283625Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6283625Sdim// 7283625Sdim//===----------------------------------------------------------------------===// 8283625Sdim 9283625Sdim#ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H 10283625Sdim#define LLVM_DEBUGINFO_DWARFFORMVALUE_H 11283625Sdim 12321369Sdim#include "llvm/ADT/ArrayRef.h" 13321369Sdim#include "llvm/ADT/None.h" 14283625Sdim#include "llvm/ADT/Optional.h" 15321369Sdim#include "llvm/BinaryFormat/Dwarf.h" 16327952Sdim#include "llvm/DebugInfo/DIContext.h" 17321369Sdim#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" 18321369Sdim#include <cstdint> 19283625Sdim 20283625Sdimnamespace llvm { 21283625Sdim 22341825Sdimclass DWARFContext; 23283625Sdimclass DWARFUnit; 24283625Sdimclass raw_ostream; 25283625Sdim 26283625Sdimclass DWARFFormValue { 27283625Sdimpublic: 28283625Sdim enum FormClass { 29283625Sdim FC_Unknown, 30283625Sdim FC_Address, 31283625Sdim FC_Block, 32283625Sdim FC_Constant, 33283625Sdim FC_String, 34283625Sdim FC_Flag, 35283625Sdim FC_Reference, 36283625Sdim FC_Indirect, 37283625Sdim FC_SectionOffset, 38283625Sdim FC_Exprloc 39283625Sdim }; 40283625Sdim 41283625Sdimprivate: 42283625Sdim struct ValueType { 43321369Sdim ValueType() { uval = 0; } 44353358Sdim ValueType(int64_t V) : sval(V) {} 45353358Sdim ValueType(uint64_t V) : uval(V) {} 46353358Sdim ValueType(const char *V) : cstr(V) {} 47283625Sdim 48283625Sdim union { 49283625Sdim uint64_t uval; 50283625Sdim int64_t sval; 51321369Sdim const char *cstr; 52283625Sdim }; 53321369Sdim const uint8_t *data = nullptr; 54321369Sdim uint64_t SectionIndex; /// Section index for reference forms. 55283625Sdim }; 56283625Sdim 57321369Sdim dwarf::Form Form; /// Form for this value. 58321369Sdim ValueType Value; /// Contains all data for the form. 59321369Sdim const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time. 60341825Sdim const DWARFContext *C = nullptr; /// Context for extract time. 61353358Sdim 62353358Sdim DWARFFormValue(dwarf::Form F, ValueType V) : Form(F), Value(V) {} 63353358Sdim 64283625Sdimpublic: 65321369Sdim DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {} 66321369Sdim 67353358Sdim static DWARFFormValue createFromSValue(dwarf::Form F, int64_t V); 68353358Sdim static DWARFFormValue createFromUValue(dwarf::Form F, uint64_t V); 69353358Sdim static DWARFFormValue createFromPValue(dwarf::Form F, const char *V); 70353358Sdim static DWARFFormValue createFromBlockValue(dwarf::Form F, 71353358Sdim ArrayRef<uint8_t> D); 72353358Sdim static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit, 73360784Sdim uint64_t *OffsetPtr); 74353358Sdim 75314564Sdim dwarf::Form getForm() const { return Form; } 76321369Sdim uint64_t getRawUValue() const { return Value.uval; } 77321369Sdim 78283625Sdim bool isFormClass(FormClass FC) const; 79314564Sdim const DWARFUnit *getUnit() const { return U; } 80327952Sdim void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const; 81344779Sdim void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts, 82353358Sdim object::SectionedAddress SA) const; 83344779Sdim static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS, 84344779Sdim DIDumpOptions DumpOpts, uint64_t SectionIndex); 85283625Sdim 86327952Sdim /// Extracts a value in \p Data at offset \p *OffsetPtr. The information 87327952Sdim /// in \p FormParams is needed to interpret some forms. The optional 88341825Sdim /// \p Context and \p Unit allows extracting information if the form refers 89341825Sdim /// to other sections (e.g., .debug_str). 90360784Sdim bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, 91341825Sdim dwarf::FormParams FormParams, 92341825Sdim const DWARFContext *Context = nullptr, 93341825Sdim const DWARFUnit *Unit = nullptr); 94321369Sdim 95360784Sdim bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, 96341825Sdim dwarf::FormParams FormParams, const DWARFUnit *U) { 97341825Sdim return extractValue(Data, OffsetPtr, FormParams, nullptr, U); 98341825Sdim } 99341825Sdim 100283625Sdim bool isInlinedCStr() const { 101321369Sdim return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr; 102283625Sdim } 103283625Sdim 104283625Sdim /// getAsFoo functions below return the extracted value as Foo if only 105283625Sdim /// DWARFFormValue has form class is suitable for representing Foo. 106314564Sdim Optional<uint64_t> getAsReference() const; 107353358Sdim struct UnitOffset { 108353358Sdim DWARFUnit *Unit; 109353358Sdim uint64_t Offset; 110353358Sdim }; 111353358Sdim Optional<UnitOffset> getAsRelativeReference() const; 112283625Sdim Optional<uint64_t> getAsUnsignedConstant() const; 113283625Sdim Optional<int64_t> getAsSignedConstant() const; 114314564Sdim Optional<const char *> getAsCString() const; 115314564Sdim Optional<uint64_t> getAsAddress() const; 116353358Sdim Optional<object::SectionedAddress> getAsSectionedAddress() const; 117283625Sdim Optional<uint64_t> getAsSectionOffset() const; 118283625Sdim Optional<ArrayRef<uint8_t>> getAsBlock() const; 119314564Sdim Optional<uint64_t> getAsCStringOffset() const; 120314564Sdim Optional<uint64_t> getAsReferenceUVal() const; 121321369Sdim 122321369Sdim /// Skip a form's value in \p DebugInfoData at the offset specified by 123321369Sdim /// \p OffsetPtr. 124314564Sdim /// 125321369Sdim /// Skips the bytes for the current form and updates the offset. 126314564Sdim /// 127321369Sdim /// \param DebugInfoData The data where we want to skip the value. 128321369Sdim /// \param OffsetPtr A reference to the offset that will be updated. 129321369Sdim /// \param Params DWARF parameters to help interpret forms. 130314564Sdim /// \returns true on success, false if the form was not skipped. 131360784Sdim bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, 132341825Sdim const dwarf::FormParams Params) const { 133321369Sdim return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); 134321369Sdim } 135321369Sdim 136321369Sdim /// Skip a form's value in \p DebugInfoData at the offset specified by 137321369Sdim /// \p OffsetPtr. 138314564Sdim /// 139321369Sdim /// Skips the bytes for the specified form and updates the offset. 140314564Sdim /// 141321369Sdim /// \param Form The DW_FORM enumeration that indicates the form to skip. 142321369Sdim /// \param DebugInfoData The data where we want to skip the value. 143321369Sdim /// \param OffsetPtr A reference to the offset that will be updated. 144321369Sdim /// \param FormParams DWARF parameters to help interpret forms. 145314564Sdim /// \returns true on success, false if the form was not skipped. 146321369Sdim static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, 147360784Sdim uint64_t *OffsetPtr, 148341825Sdim const dwarf::FormParams FormParams); 149283625Sdim 150283625Sdimprivate: 151314564Sdim void dumpString(raw_ostream &OS) const; 152283625Sdim}; 153283625Sdim 154321369Sdimnamespace dwarf { 155321369Sdim 156321369Sdim/// Take an optional DWARFFormValue and try to extract a string value from it. 157321369Sdim/// 158321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 159321369Sdim/// \returns an optional value that contains a value if the form value 160321369Sdim/// was valid and was a string. 161321369Sdiminline Optional<const char *> toString(const Optional<DWARFFormValue> &V) { 162321369Sdim if (V) 163321369Sdim return V->getAsCString(); 164321369Sdim return None; 165285181Sdim} 166283625Sdim 167353358Sdim/// Take an optional DWARFFormValue and try to extract a string value from it. 168353358Sdim/// 169353358Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 170353358Sdim/// \returns an optional value that contains a value if the form value 171353358Sdim/// was valid and was a string. 172353358Sdiminline StringRef toStringRef(const Optional<DWARFFormValue> &V, 173353358Sdim StringRef Default = {}) { 174353358Sdim if (V) 175353358Sdim if (auto S = V->getAsCString()) 176353358Sdim return *S; 177353358Sdim return Default; 178353358Sdim} 179353358Sdim 180321369Sdim/// Take an optional DWARFFormValue and extract a string value from it. 181321369Sdim/// 182321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 183321369Sdim/// \param Default the default value to return in case of failure. 184321369Sdim/// \returns the string value or Default if the V doesn't have a value or the 185321369Sdim/// form value's encoding wasn't a string. 186321369Sdiminline const char *toString(const Optional<DWARFFormValue> &V, 187321369Sdim const char *Default) { 188321369Sdim return toString(V).getValueOr(Default); 189321369Sdim} 190321369Sdim 191321369Sdim/// Take an optional DWARFFormValue and try to extract an unsigned constant. 192321369Sdim/// 193321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 194321369Sdim/// \returns an optional value that contains a value if the form value 195321369Sdim/// was valid and has a unsigned constant form. 196321369Sdiminline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue> &V) { 197321369Sdim if (V) 198321369Sdim return V->getAsUnsignedConstant(); 199321369Sdim return None; 200321369Sdim} 201321369Sdim 202321369Sdim/// Take an optional DWARFFormValue and extract a unsigned constant. 203321369Sdim/// 204321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 205321369Sdim/// \param Default the default value to return in case of failure. 206321369Sdim/// \returns the extracted unsigned value or Default if the V doesn't have a 207321369Sdim/// value or the form value's encoding wasn't an unsigned constant form. 208321369Sdiminline uint64_t toUnsigned(const Optional<DWARFFormValue> &V, 209321369Sdim uint64_t Default) { 210321369Sdim return toUnsigned(V).getValueOr(Default); 211321369Sdim} 212321369Sdim 213321369Sdim/// Take an optional DWARFFormValue and try to extract an reference. 214321369Sdim/// 215321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 216321369Sdim/// \returns an optional value that contains a value if the form value 217321369Sdim/// was valid and has a reference form. 218321369Sdiminline Optional<uint64_t> toReference(const Optional<DWARFFormValue> &V) { 219321369Sdim if (V) 220321369Sdim return V->getAsReference(); 221321369Sdim return None; 222321369Sdim} 223321369Sdim 224321369Sdim/// Take an optional DWARFFormValue and extract a reference. 225321369Sdim/// 226321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 227321369Sdim/// \param Default the default value to return in case of failure. 228321369Sdim/// \returns the extracted reference value or Default if the V doesn't have a 229321369Sdim/// value or the form value's encoding wasn't a reference form. 230321369Sdiminline uint64_t toReference(const Optional<DWARFFormValue> &V, 231321369Sdim uint64_t Default) { 232321369Sdim return toReference(V).getValueOr(Default); 233321369Sdim} 234321369Sdim 235321369Sdim/// Take an optional DWARFFormValue and try to extract an signed constant. 236321369Sdim/// 237321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 238321369Sdim/// \returns an optional value that contains a value if the form value 239321369Sdim/// was valid and has a signed constant form. 240321369Sdiminline Optional<int64_t> toSigned(const Optional<DWARFFormValue> &V) { 241321369Sdim if (V) 242321369Sdim return V->getAsSignedConstant(); 243321369Sdim return None; 244321369Sdim} 245321369Sdim 246321369Sdim/// Take an optional DWARFFormValue and extract a signed integer. 247321369Sdim/// 248321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 249321369Sdim/// \param Default the default value to return in case of failure. 250321369Sdim/// \returns the extracted signed integer value or Default if the V doesn't 251321369Sdim/// have a value or the form value's encoding wasn't a signed integer form. 252321369Sdiminline int64_t toSigned(const Optional<DWARFFormValue> &V, int64_t Default) { 253321369Sdim return toSigned(V).getValueOr(Default); 254321369Sdim} 255321369Sdim 256321369Sdim/// Take an optional DWARFFormValue and try to extract an address. 257321369Sdim/// 258321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 259321369Sdim/// \returns an optional value that contains a value if the form value 260321369Sdim/// was valid and has a address form. 261321369Sdiminline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) { 262321369Sdim if (V) 263321369Sdim return V->getAsAddress(); 264321369Sdim return None; 265321369Sdim} 266321369Sdim 267353358Sdiminline Optional<object::SectionedAddress> 268344779SdimtoSectionedAddress(const Optional<DWARFFormValue> &V) { 269344779Sdim if (V) 270344779Sdim return V->getAsSectionedAddress(); 271344779Sdim return None; 272344779Sdim} 273344779Sdim 274321369Sdim/// Take an optional DWARFFormValue and extract a address. 275321369Sdim/// 276321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 277321369Sdim/// \param Default the default value to return in case of failure. 278321369Sdim/// \returns the extracted address value or Default if the V doesn't have a 279321369Sdim/// value or the form value's encoding wasn't an address form. 280321369Sdiminline uint64_t toAddress(const Optional<DWARFFormValue> &V, uint64_t Default) { 281321369Sdim return toAddress(V).getValueOr(Default); 282321369Sdim} 283321369Sdim 284321369Sdim/// Take an optional DWARFFormValue and try to extract an section offset. 285321369Sdim/// 286321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 287321369Sdim/// \returns an optional value that contains a value if the form value 288321369Sdim/// was valid and has a section offset form. 289321369Sdiminline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue> &V) { 290321369Sdim if (V) 291321369Sdim return V->getAsSectionOffset(); 292321369Sdim return None; 293321369Sdim} 294321369Sdim 295321369Sdim/// Take an optional DWARFFormValue and extract a section offset. 296321369Sdim/// 297321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 298321369Sdim/// \param Default the default value to return in case of failure. 299321369Sdim/// \returns the extracted section offset value or Default if the V doesn't 300321369Sdim/// have a value or the form value's encoding wasn't a section offset form. 301321369Sdiminline uint64_t toSectionOffset(const Optional<DWARFFormValue> &V, 302321369Sdim uint64_t Default) { 303321369Sdim return toSectionOffset(V).getValueOr(Default); 304321369Sdim} 305321369Sdim 306321369Sdim/// Take an optional DWARFFormValue and try to extract block data. 307321369Sdim/// 308321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from. 309321369Sdim/// \returns an optional value that contains a value if the form value 310321369Sdim/// was valid and has a block form. 311321369Sdiminline Optional<ArrayRef<uint8_t>> toBlock(const Optional<DWARFFormValue> &V) { 312321369Sdim if (V) 313321369Sdim return V->getAsBlock(); 314321369Sdim return None; 315321369Sdim} 316321369Sdim 317321369Sdim} // end namespace dwarf 318321369Sdim 319321369Sdim} // end namespace llvm 320321369Sdim 321321369Sdim#endif // LLVM_DEBUGINFO_DWARFFORMVALUE_H 322