diff options
Diffstat (limited to 'include/llvm/BinaryFormat/Dwarf.h')
-rw-r--r-- | include/llvm/BinaryFormat/Dwarf.h | 115 |
1 files changed, 106 insertions, 9 deletions
diff --git a/include/llvm/BinaryFormat/Dwarf.h b/include/llvm/BinaryFormat/Dwarf.h index a0e5367b412c..9036f405eaea 100644 --- a/include/llvm/BinaryFormat/Dwarf.h +++ b/include/llvm/BinaryFormat/Dwarf.h @@ -20,8 +20,12 @@ #ifndef LLVM_BINARYFORMAT_DWARF_H #define LLVM_BINARYFORMAT_DWARF_H +#include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/FormatVariadicDetails.h" namespace llvm { class StringRef; @@ -57,6 +61,9 @@ enum LLVMConstants : uint32_t { DWARF_VENDOR_MIPS = 6 }; +/// Constants that define the DWARF format as 32 or 64 bit. +enum DwarfFormat : uint8_t { DWARF32, DWARF64 }; + /// Special ID values that distinguish a CIE from a FDE in DWARF CFI. /// Not inside an enum because a 64-bit value is needed. /// @{ @@ -125,7 +132,7 @@ enum LocationAtom { DW_OP_LLVM_fragment = 0x1000 ///< Only used in LLVM metadata. }; -enum TypeKind { +enum TypeKind : uint8_t { #define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) DW_ATE_##NAME = ID, #include "llvm/BinaryFormat/Dwarf.def" DW_ATE_lo_user = 0x80, @@ -325,6 +332,13 @@ enum UnitType : unsigned char { DW_UT_hi_user = 0xff }; +enum Index { +#define HANDLE_DW_IDX(ID, NAME) DW_IDX_##NAME = ID, +#include "llvm/BinaryFormat/Dwarf.def" + DW_IDX_lo_user = 0x2000, + DW_IDX_hi_user = 0x3fff +}; + inline bool isUnitType(uint8_t UnitType) { switch (UnitType) { case DW_UT_compile: @@ -354,13 +368,16 @@ inline bool isUnitType(dwarf::Tag T) { // Constants for the DWARF v5 Accelerator Table Proposal enum AcceleratorTable { // Data layout descriptors. - DW_ATOM_null = 0u, // Marker as the end of a list of atoms. + DW_ATOM_null = 0u, /// Marker as the end of a list of atoms. DW_ATOM_die_offset = 1u, // DIE offset in the debug_info section. DW_ATOM_cu_offset = 2u, // Offset of the compile unit header that contains the // item in question. DW_ATOM_die_tag = 3u, // A tag entry. DW_ATOM_type_flags = 4u, // Set of flags for a type. + DW_ATOM_type_type_flags = 5u, // Dsymutil type extension. + DW_ATOM_qual_name_hash = 6u, // Dsymutil qualified hash extension. + // DW_ATOM_type_flags values. // Always set for C++, only set for ObjC if this is the @implementation for a @@ -390,8 +407,8 @@ enum GDBIndexEntryLinkage { GIEL_EXTERNAL, GIEL_STATIC }; /// \defgroup DwarfConstantsDumping Dwarf constants dumping functions /// /// All these functions map their argument's value back to the -/// corresponding enumerator name or return nullptr if the value isn't -/// known. +/// corresponding enumerator name or return an empty StringRef if the value +/// isn't known. /// /// @{ StringRef TagString(unsigned Tag); @@ -410,16 +427,17 @@ StringRef CaseString(unsigned Case); StringRef ConventionString(unsigned Convention); StringRef InlineCodeString(unsigned Code); StringRef ArrayOrderString(unsigned Order); -StringRef DiscriminantString(unsigned Discriminant); StringRef LNStandardString(unsigned Standard); StringRef LNExtendedString(unsigned Encoding); StringRef MacinfoString(unsigned Encoding); +StringRef RangeListEncodingString(unsigned Encoding); StringRef CallFrameString(unsigned Encoding); StringRef ApplePropertyString(unsigned); StringRef UnitTypeString(unsigned); StringRef AtomTypeString(unsigned Atom); StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind); StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage); +StringRef IndexString(unsigned Idx); /// @} /// \defgroup DwarfConstantsParsing Dwarf constants parsing functions @@ -471,6 +489,49 @@ unsigned AttributeEncodingVendor(TypeKind E); unsigned LanguageVendor(SourceLanguage L); /// @} +/// A helper struct providing information about the byte size of DW_FORM +/// values that vary in size depending on the DWARF version, address byte +/// size, or DWARF32/DWARF64. +struct FormParams { + uint16_t Version; + uint8_t AddrSize; + DwarfFormat Format; + + /// The definition of the size of form DW_FORM_ref_addr depends on the + /// version. In DWARF v2 it's the size of an address; after that, it's the + /// size of a reference. + uint8_t getRefAddrByteSize() const { + if (Version == 2) + return AddrSize; + return getDwarfOffsetByteSize(); + } + + /// The size of a reference is determined by the DWARF 32/64-bit format. + uint8_t getDwarfOffsetByteSize() const { + switch (Format) { + case DwarfFormat::DWARF32: + return 4; + case DwarfFormat::DWARF64: + return 8; + } + llvm_unreachable("Invalid Format value"); + } + + explicit operator bool() const { return Version && AddrSize; } +}; + +/// Get the fixed byte size for a given form. +/// +/// If the form has a fixed byte size, then an Optional with a value will be +/// returned. If the form is always encoded using a variable length storage +/// format (ULEB or SLEB numbers or blocks) then None will be returned. +/// +/// \param Form DWARF form to get the fixed byte size for. +/// \param Params DWARF parameters to help interpret forms. +/// \returns Optional<uint8_t> value with the fixed byte size or None if +/// \p Form doesn't have a fixed byte size. +Optional<uint8_t> getFixedFormByteSize(dwarf::Form Form, FormParams Params); + /// Tells whether the specified form is defined in the specified version, /// or is an extension if extensions are allowed. bool isValidFormForVersion(Form F, unsigned Version, bool ExtensionsOk = true); @@ -479,6 +540,10 @@ bool isValidFormForVersion(Form F, unsigned Version, bool ExtensionsOk = true); /// for attribute Attr. StringRef AttributeValueString(uint16_t Attr, unsigned Val); +/// Returns the symbolic string representing Val when used as a value +/// for atom Atom. +StringRef AtomValueString(uint16_t Atom, unsigned Val); + /// Describes an entry of the various gnu_pub* debug sections. /// /// The gnu_pub* kind looks like: @@ -514,14 +579,46 @@ private: }; }; -/// Constants that define the DWARF format as 32 or 64 bit. -enum DwarfFormat : uint8_t { DWARF32, DWARF64 }; +template <typename Enum> struct EnumTraits : public std::false_type {}; + +template <> struct EnumTraits<Attribute> : public std::true_type { + static constexpr char Type[3] = "AT"; + static constexpr StringRef (*StringFn)(unsigned) = &AttributeString; +}; -/// The Bernstein hash function used by the accelerator tables. -uint32_t djbHash(StringRef Buffer); +template <> struct EnumTraits<Form> : public std::true_type { + static constexpr char Type[5] = "FORM"; + static constexpr StringRef (*StringFn)(unsigned) = &FormEncodingString; +}; + +template <> struct EnumTraits<Index> : public std::true_type { + static constexpr char Type[4] = "IDX"; + static constexpr StringRef (*StringFn)(unsigned) = &IndexString; +}; +template <> struct EnumTraits<Tag> : public std::true_type { + static constexpr char Type[4] = "TAG"; + static constexpr StringRef (*StringFn)(unsigned) = &TagString; +}; } // End of namespace dwarf +/// Dwarf constants format_provider +/// +/// Specialization of the format_provider template for dwarf enums. Unlike the +/// dumping functions above, these format unknown enumerator values as +/// DW_TYPE_unknown_1234 (e.g. DW_TAG_unknown_ffff). +template <typename Enum> +struct format_provider< + Enum, typename std::enable_if<dwarf::EnumTraits<Enum>::value>::type> { + static void format(const Enum &E, raw_ostream &OS, StringRef Style) { + StringRef Str = dwarf::EnumTraits<Enum>::StringFn(E); + if (Str.empty()) { + OS << "DW_" << dwarf::EnumTraits<Enum>::Type << "_unknown_" + << llvm::format("%x", E); + } else + OS << Str; + } +}; } // End of namespace llvm #endif |