summaryrefslogtreecommitdiff
path: root/include/llvm/BinaryFormat/Dwarf.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/BinaryFormat/Dwarf.h')
-rw-r--r--include/llvm/BinaryFormat/Dwarf.h115
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