forked from OSchip/llvm-project
[DWARF] Versioning for DWARF constants; verify FORMs
Associate the version-when-defined with definitions of standard DWARF constants. Identify the "vendor" for DWARF extensions. Use this information to verify FORMs in .debug_abbrev are defined as of the DWARF version specified in the associated unit. Removed two tests that had specified DWARF v1 (which essentially does not exist). Differential Revision: http://reviews.llvm.org/D30785 llvm-svn: 300875
This commit is contained in:
parent
8431e996d3
commit
70b34533c2
|
@ -236,7 +236,7 @@ template <> struct MappingTraits<DWARFYAML::InitialLength> {
|
||||||
static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
|
static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HANDLE_DW_TAG(unused, name) \
|
#define HANDLE_DW_TAG(unused, name, unused2, unused3) \
|
||||||
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
|
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
|
||||||
|
|
||||||
template <> struct ScalarEnumerationTraits<dwarf::Tag> {
|
template <> struct ScalarEnumerationTraits<dwarf::Tag> {
|
||||||
|
@ -266,7 +266,7 @@ template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HANDLE_DW_AT(unused, name) \
|
#define HANDLE_DW_AT(unused, name, unused2, unused3) \
|
||||||
io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
|
io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
|
||||||
|
|
||||||
template <> struct ScalarEnumerationTraits<dwarf::Attribute> {
|
template <> struct ScalarEnumerationTraits<dwarf::Attribute> {
|
||||||
|
@ -276,7 +276,7 @@ template <> struct ScalarEnumerationTraits<dwarf::Attribute> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HANDLE_DW_FORM(unused, name) \
|
#define HANDLE_DW_FORM(unused, name, unused2, unused3) \
|
||||||
io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name);
|
io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name);
|
||||||
|
|
||||||
template <> struct ScalarEnumerationTraits<dwarf::Form> {
|
template <> struct ScalarEnumerationTraits<dwarf::Form> {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -46,7 +46,15 @@ enum LLVMConstants : uint32_t {
|
||||||
DWARF_VERSION = 4, // Default dwarf version we output.
|
DWARF_VERSION = 4, // Default dwarf version we output.
|
||||||
DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
|
DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
|
||||||
DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
|
DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
|
||||||
DW_ARANGES_VERSION = 2 // Section version number for .debug_aranges.
|
DW_ARANGES_VERSION = 2, // Section version number for .debug_aranges.
|
||||||
|
// Identifiers we use to distinguish vendor extensions.
|
||||||
|
DWARF_VENDOR_DWARF = 0, // Defined in v2 or later of the DWARF standard.
|
||||||
|
DWARF_VENDOR_APPLE = 1,
|
||||||
|
DWARF_VENDOR_BORLAND = 2,
|
||||||
|
DWARF_VENDOR_GNU = 3,
|
||||||
|
DWARF_VENDOR_GOOGLE = 4,
|
||||||
|
DWARF_VENDOR_LLVM = 5,
|
||||||
|
DWARF_VENDOR_MIPS = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
|
// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
|
||||||
|
@ -55,7 +63,7 @@ const uint32_t DW_CIE_ID = UINT32_MAX;
|
||||||
const uint64_t DW64_CIE_ID = UINT64_MAX;
|
const uint64_t DW64_CIE_ID = UINT64_MAX;
|
||||||
|
|
||||||
enum Tag : uint16_t {
|
enum Tag : uint16_t {
|
||||||
#define HANDLE_DW_TAG(ID, NAME) DW_TAG_##NAME = ID,
|
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) DW_TAG_##NAME = ID,
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
DW_TAG_lo_user = 0x4080,
|
DW_TAG_lo_user = 0x4080,
|
||||||
DW_TAG_hi_user = 0xffff,
|
DW_TAG_hi_user = 0xffff,
|
||||||
|
@ -92,20 +100,20 @@ inline bool isType(Tag T) {
|
||||||
|
|
||||||
/// Attributes.
|
/// Attributes.
|
||||||
enum Attribute : uint16_t {
|
enum Attribute : uint16_t {
|
||||||
#define HANDLE_DW_AT(ID, NAME) DW_AT_##NAME = ID,
|
#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) DW_AT_##NAME = ID,
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
DW_AT_lo_user = 0x2000,
|
DW_AT_lo_user = 0x2000,
|
||||||
DW_AT_hi_user = 0x3fff,
|
DW_AT_hi_user = 0x3fff,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Form : uint16_t {
|
enum Form : uint16_t {
|
||||||
#define HANDLE_DW_FORM(ID, NAME) DW_FORM_##NAME = ID,
|
#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) DW_FORM_##NAME = ID,
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
DW_FORM_lo_user = 0x1f00, ///< Not specified by DWARF.
|
DW_FORM_lo_user = 0x1f00, ///< Not specified by DWARF.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LocationAtom {
|
enum LocationAtom {
|
||||||
#define HANDLE_DW_OP(ID, NAME) DW_OP_##NAME = ID,
|
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) DW_OP_##NAME = ID,
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
DW_OP_lo_user = 0xe0,
|
DW_OP_lo_user = 0xe0,
|
||||||
DW_OP_hi_user = 0xff,
|
DW_OP_hi_user = 0xff,
|
||||||
|
@ -113,7 +121,7 @@ enum LocationAtom {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TypeKind {
|
enum TypeKind {
|
||||||
#define HANDLE_DW_ATE(ID, NAME) DW_ATE_##NAME = ID,
|
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) DW_ATE_##NAME = ID,
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
DW_ATE_lo_user = 0x80,
|
DW_ATE_lo_user = 0x80,
|
||||||
DW_ATE_hi_user = 0xff
|
DW_ATE_hi_user = 0xff
|
||||||
|
@ -164,7 +172,7 @@ enum DefaultedMemberAttribute {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SourceLanguage {
|
enum SourceLanguage {
|
||||||
#define HANDLE_DW_LANG(ID, NAME) DW_LANG_##NAME = ID,
|
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) DW_LANG_##NAME = ID,
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
DW_LANG_lo_user = 0x8000,
|
DW_LANG_lo_user = 0x8000,
|
||||||
DW_LANG_hi_user = 0xffff
|
DW_LANG_hi_user = 0xffff
|
||||||
|
@ -406,6 +414,40 @@ unsigned getAttributeEncoding(StringRef EncodingString);
|
||||||
unsigned getMacinfo(StringRef MacinfoString);
|
unsigned getMacinfo(StringRef MacinfoString);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
/// \defgroup DwarfConstantsVersioning Dwarf version for constants
|
||||||
|
///
|
||||||
|
/// For constants defined by DWARF, returns the DWARF version when the constant
|
||||||
|
/// was first defined. For vendor extensions, if there is a version-related
|
||||||
|
/// policy for when to emit it, returns a version number for that policy.
|
||||||
|
/// Otherwise returns 0.
|
||||||
|
///
|
||||||
|
/// @{
|
||||||
|
unsigned TagVersion(Tag T);
|
||||||
|
unsigned AttributeVersion(Attribute A);
|
||||||
|
unsigned FormVersion(Form F);
|
||||||
|
unsigned OperationVersion(LocationAtom O);
|
||||||
|
unsigned AttributeEncodingVersion(TypeKind E);
|
||||||
|
unsigned LanguageVersion(SourceLanguage L);
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// \defgroup DwarfConstantsVendor Dwarf "vendor" for constants
|
||||||
|
///
|
||||||
|
/// These functions return an identifier describing "who" defined the constant,
|
||||||
|
/// either the DWARF standard itself or the vendor who defined the extension.
|
||||||
|
///
|
||||||
|
/// @{
|
||||||
|
unsigned TagVendor(Tag T);
|
||||||
|
unsigned AttributeVendor(Attribute A);
|
||||||
|
unsigned FormVendor(Form F);
|
||||||
|
unsigned OperationVendor(LocationAtom O);
|
||||||
|
unsigned AttributeEncodingVendor(TypeKind E);
|
||||||
|
unsigned LanguageVendor(SourceLanguage L);
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// 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);
|
||||||
|
|
||||||
/// \brief Returns the symbolic string representing Val when used as a value
|
/// \brief Returns the symbolic string representing Val when used as a value
|
||||||
/// for attribute Attr.
|
/// for attribute Attr.
|
||||||
StringRef AttributeValueString(uint16_t Attr, unsigned Val);
|
StringRef AttributeValueString(uint16_t Attr, unsigned Val);
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
#define DEBUG_TYPE "dwarfdebug"
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// DIEAbbrevData Implementation
|
// DIEAbbrevData Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -79,15 +81,22 @@ void DIEAbbrev::Emit(const AsmPrinter *AP) const {
|
||||||
dwarf::AttributeString(AttrData.getAttribute()).data());
|
dwarf::AttributeString(AttrData.getAttribute()).data());
|
||||||
|
|
||||||
// Emit form type.
|
// Emit form type.
|
||||||
|
#ifndef NDEBUG
|
||||||
|
// Could be an assertion, but this way we can see the failing form code
|
||||||
|
// easily, which helps track down where it came from.
|
||||||
|
if (!dwarf::isValidFormForVersion(AttrData.getForm(),
|
||||||
|
AP->getDwarfVersion())) {
|
||||||
|
DEBUG(dbgs() << "Invalid form " << format("0x%x", AttrData.getForm())
|
||||||
|
<< " for DWARF version " << AP->getDwarfVersion() << "\n");
|
||||||
|
llvm_unreachable("Invalid form for specified DWARF version");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
AP->EmitULEB128(AttrData.getForm(),
|
AP->EmitULEB128(AttrData.getForm(),
|
||||||
dwarf::FormEncodingString(AttrData.getForm()).data());
|
dwarf::FormEncodingString(AttrData.getForm()).data());
|
||||||
|
|
||||||
// Emit value for DW_FORM_implicit_const.
|
// Emit value for DW_FORM_implicit_const.
|
||||||
if (AttrData.getForm() == dwarf::DW_FORM_implicit_const) {
|
if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
|
||||||
assert(AP->getDwarfVersion() >= 5 &&
|
|
||||||
"DW_FORM_implicit_const is supported starting from DWARFv5");
|
|
||||||
AP->EmitSLEB128(AttrData.getValue());
|
AP->EmitSLEB128(AttrData.getValue());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark end of abbreviation.
|
// Mark end of abbreviation.
|
||||||
|
|
|
@ -22,7 +22,7 @@ StringRef llvm::dwarf::TagString(unsigned Tag) {
|
||||||
switch (Tag) {
|
switch (Tag) {
|
||||||
default:
|
default:
|
||||||
return StringRef();
|
return StringRef();
|
||||||
#define HANDLE_DW_TAG(ID, NAME) \
|
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
|
||||||
case DW_TAG_##NAME: \
|
case DW_TAG_##NAME: \
|
||||||
return "DW_TAG_" #NAME;
|
return "DW_TAG_" #NAME;
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
@ -31,11 +31,34 @@ StringRef llvm::dwarf::TagString(unsigned Tag) {
|
||||||
|
|
||||||
unsigned llvm::dwarf::getTag(StringRef TagString) {
|
unsigned llvm::dwarf::getTag(StringRef TagString) {
|
||||||
return StringSwitch<unsigned>(TagString)
|
return StringSwitch<unsigned>(TagString)
|
||||||
#define HANDLE_DW_TAG(ID, NAME) .Case("DW_TAG_" #NAME, DW_TAG_##NAME)
|
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
|
||||||
|
.Case("DW_TAG_" #NAME, DW_TAG_##NAME)
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
.Default(DW_TAG_invalid);
|
.Default(DW_TAG_invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::TagVersion(dwarf::Tag Tag) {
|
||||||
|
switch (Tag) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_TAG_##NAME: \
|
||||||
|
return VERSION;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::TagVendor(dwarf::Tag Tag) {
|
||||||
|
switch (Tag) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_TAG_##NAME: \
|
||||||
|
return DWARF_VENDOR_##VENDOR;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StringRef llvm::dwarf::ChildrenString(unsigned Children) {
|
StringRef llvm::dwarf::ChildrenString(unsigned Children) {
|
||||||
switch (Children) {
|
switch (Children) {
|
||||||
case DW_CHILDREN_no: return "DW_CHILDREN_no";
|
case DW_CHILDREN_no: return "DW_CHILDREN_no";
|
||||||
|
@ -48,29 +71,73 @@ StringRef llvm::dwarf::AttributeString(unsigned Attribute) {
|
||||||
switch (Attribute) {
|
switch (Attribute) {
|
||||||
default:
|
default:
|
||||||
return StringRef();
|
return StringRef();
|
||||||
#define HANDLE_DW_AT(ID, NAME) \
|
#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \
|
||||||
case DW_AT_##NAME: \
|
case DW_AT_##NAME: \
|
||||||
return "DW_AT_" #NAME;
|
return "DW_AT_" #NAME;
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::AttributeVersion(dwarf::Attribute Attribute) {
|
||||||
|
switch (Attribute) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_AT_##NAME: \
|
||||||
|
return VERSION;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::AttributeVendor(dwarf::Attribute Attribute) {
|
||||||
|
switch (Attribute) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_AT_##NAME: \
|
||||||
|
return DWARF_VENDOR_##VENDOR;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StringRef llvm::dwarf::FormEncodingString(unsigned Encoding) {
|
StringRef llvm::dwarf::FormEncodingString(unsigned Encoding) {
|
||||||
switch (Encoding) {
|
switch (Encoding) {
|
||||||
default:
|
default:
|
||||||
return StringRef();
|
return StringRef();
|
||||||
#define HANDLE_DW_FORM(ID, NAME) \
|
#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \
|
||||||
case DW_FORM_##NAME: \
|
case DW_FORM_##NAME: \
|
||||||
return "DW_FORM_" #NAME;
|
return "DW_FORM_" #NAME;
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::FormVersion(dwarf::Form Form) {
|
||||||
|
switch (Form) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_FORM_##NAME: \
|
||||||
|
return VERSION;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::FormVendor(dwarf::Form Form) {
|
||||||
|
switch (Form) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_FORM_##NAME: \
|
||||||
|
return DWARF_VENDOR_##VENDOR;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) {
|
StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) {
|
||||||
switch (Encoding) {
|
switch (Encoding) {
|
||||||
default:
|
default:
|
||||||
return StringRef();
|
return StringRef();
|
||||||
#define HANDLE_DW_OP(ID, NAME) \
|
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
|
||||||
case DW_OP_##NAME: \
|
case DW_OP_##NAME: \
|
||||||
return "DW_OP_" #NAME;
|
return "DW_OP_" #NAME;
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
@ -81,17 +148,40 @@ StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) {
|
||||||
|
|
||||||
unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) {
|
unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) {
|
||||||
return StringSwitch<unsigned>(OperationEncodingString)
|
return StringSwitch<unsigned>(OperationEncodingString)
|
||||||
#define HANDLE_DW_OP(ID, NAME) .Case("DW_OP_" #NAME, DW_OP_##NAME)
|
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
|
||||||
|
.Case("DW_OP_" #NAME, DW_OP_##NAME)
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
.Case("DW_OP_LLVM_fragment", DW_OP_LLVM_fragment)
|
.Case("DW_OP_LLVM_fragment", DW_OP_LLVM_fragment)
|
||||||
.Default(0);
|
.Default(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::OperationVersion(dwarf::LocationAtom Op) {
|
||||||
|
switch (Op) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_OP_##NAME: \
|
||||||
|
return VERSION;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::OperationVendor(dwarf::LocationAtom Op) {
|
||||||
|
switch (Op) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_OP_##NAME: \
|
||||||
|
return DWARF_VENDOR_##VENDOR;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StringRef llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
|
StringRef llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
|
||||||
switch (Encoding) {
|
switch (Encoding) {
|
||||||
default:
|
default:
|
||||||
return StringRef();
|
return StringRef();
|
||||||
#define HANDLE_DW_ATE(ID, NAME) \
|
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
|
||||||
case DW_ATE_##NAME: \
|
case DW_ATE_##NAME: \
|
||||||
return "DW_ATE_" #NAME;
|
return "DW_ATE_" #NAME;
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
@ -100,11 +190,34 @@ StringRef llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
|
||||||
|
|
||||||
unsigned llvm::dwarf::getAttributeEncoding(StringRef EncodingString) {
|
unsigned llvm::dwarf::getAttributeEncoding(StringRef EncodingString) {
|
||||||
return StringSwitch<unsigned>(EncodingString)
|
return StringSwitch<unsigned>(EncodingString)
|
||||||
#define HANDLE_DW_ATE(ID, NAME) .Case("DW_ATE_" #NAME, DW_ATE_##NAME)
|
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
|
||||||
|
.Case("DW_ATE_" #NAME, DW_ATE_##NAME)
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
.Default(0);
|
.Default(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::AttributeEncodingVersion(dwarf::TypeKind ATE) {
|
||||||
|
switch (ATE) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_ATE_##NAME: \
|
||||||
|
return VERSION;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::AttributeEncodingVendor(dwarf::TypeKind ATE) {
|
||||||
|
switch (ATE) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_ATE_##NAME: \
|
||||||
|
return DWARF_VENDOR_##VENDOR;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StringRef llvm::dwarf::DecimalSignString(unsigned Sign) {
|
StringRef llvm::dwarf::DecimalSignString(unsigned Sign) {
|
||||||
switch (Sign) {
|
switch (Sign) {
|
||||||
case DW_DS_unsigned: return "DW_DS_unsigned";
|
case DW_DS_unsigned: return "DW_DS_unsigned";
|
||||||
|
@ -169,7 +282,7 @@ StringRef llvm::dwarf::LanguageString(unsigned Language) {
|
||||||
switch (Language) {
|
switch (Language) {
|
||||||
default:
|
default:
|
||||||
return StringRef();
|
return StringRef();
|
||||||
#define HANDLE_DW_LANG(ID, NAME) \
|
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \
|
||||||
case DW_LANG_##NAME: \
|
case DW_LANG_##NAME: \
|
||||||
return "DW_LANG_" #NAME;
|
return "DW_LANG_" #NAME;
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
@ -178,11 +291,34 @@ StringRef llvm::dwarf::LanguageString(unsigned Language) {
|
||||||
|
|
||||||
unsigned llvm::dwarf::getLanguage(StringRef LanguageString) {
|
unsigned llvm::dwarf::getLanguage(StringRef LanguageString) {
|
||||||
return StringSwitch<unsigned>(LanguageString)
|
return StringSwitch<unsigned>(LanguageString)
|
||||||
#define HANDLE_DW_LANG(ID, NAME) .Case("DW_LANG_" #NAME, DW_LANG_##NAME)
|
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \
|
||||||
|
.Case("DW_LANG_" #NAME, DW_LANG_##NAME)
|
||||||
#include "llvm/Support/Dwarf.def"
|
#include "llvm/Support/Dwarf.def"
|
||||||
.Default(0);
|
.Default(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::LanguageVersion(dwarf::SourceLanguage Lang) {
|
||||||
|
switch (Lang) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_LANG_##NAME: \
|
||||||
|
return VERSION;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned llvm::dwarf::LanguageVendor(dwarf::SourceLanguage Lang) {
|
||||||
|
switch (Lang) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \
|
||||||
|
case DW_LANG_##NAME: \
|
||||||
|
return DWARF_VENDOR_##VENDOR;
|
||||||
|
#include "llvm/Support/Dwarf.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StringRef llvm::dwarf::CaseString(unsigned Case) {
|
StringRef llvm::dwarf::CaseString(unsigned Case) {
|
||||||
switch (Case) {
|
switch (Case) {
|
||||||
case DW_ID_case_sensitive: return "DW_ID_case_sensitive";
|
case DW_ID_case_sensitive: return "DW_ID_case_sensitive";
|
||||||
|
@ -394,3 +530,12 @@ StringRef llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) {
|
||||||
|
|
||||||
return StringRef();
|
return StringRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool llvm::dwarf::isValidFormForVersion(Form F, unsigned Version,
|
||||||
|
bool ExtensionsOk) {
|
||||||
|
if (FormVendor(F) == DWARF_VENDOR_DWARF) {
|
||||||
|
unsigned FV = FormVersion(F);
|
||||||
|
return FV > 0 && FV <= Version;
|
||||||
|
}
|
||||||
|
return ExtensionsOk;
|
||||||
|
}
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
; RUN: llc -O0 -mtriple=amdgcn--amdhsa -mcpu=fiji -verify-machineinstrs -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
|
|
||||||
|
|
||||||
; LLVM IR generated with the following command and OpenCL source:
|
|
||||||
;
|
|
||||||
; $clang -cl-std=CL2.0 -g -O0 -target amdgcn-amd-amdhsa -S -emit-llvm <path-to-file>
|
|
||||||
;
|
|
||||||
; kernel void kernel1() {
|
|
||||||
; global int *FuncVar0 = 0;
|
|
||||||
; constant int *FuncVar1 = 0;
|
|
||||||
; local int *FuncVar2 = 0;
|
|
||||||
; private int *FuncVar3 = 0;
|
|
||||||
; int *FuncVar4 = 0;
|
|
||||||
; }
|
|
||||||
|
|
||||||
; DW_AT_address_class is available since Dwarf Version 2.
|
|
||||||
; CHECK-NOT: DW_AT_address_class
|
|
||||||
|
|
||||||
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
|
|
||||||
|
|
||||||
define amdgpu_kernel void @kernel1() #0 !dbg !7 {
|
|
||||||
entry:
|
|
||||||
%FuncVar0 = alloca i32 addrspace(1)*, align 4
|
|
||||||
%FuncVar1 = alloca i32 addrspace(2)*, align 4
|
|
||||||
%FuncVar2 = alloca i32 addrspace(3)*, align 4
|
|
||||||
%FuncVar3 = alloca i32*, align 4
|
|
||||||
%FuncVar4 = alloca i32 addrspace(4)*, align 4
|
|
||||||
call void @llvm.dbg.declare(metadata i32 addrspace(1)** %FuncVar0, metadata !10, metadata !13), !dbg !14
|
|
||||||
store i32 addrspace(1)* null, i32 addrspace(1)** %FuncVar0, align 4, !dbg !14
|
|
||||||
call void @llvm.dbg.declare(metadata i32 addrspace(2)** %FuncVar1, metadata !15, metadata !13), !dbg !16
|
|
||||||
store i32 addrspace(2)* null, i32 addrspace(2)** %FuncVar1, align 4, !dbg !16
|
|
||||||
call void @llvm.dbg.declare(metadata i32 addrspace(3)** %FuncVar2, metadata !17, metadata !13), !dbg !19
|
|
||||||
store i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*), i32 addrspace(3)** %FuncVar2, align 4, !dbg !19
|
|
||||||
call void @llvm.dbg.declare(metadata i32** %FuncVar3, metadata !20, metadata !13), !dbg !22
|
|
||||||
store i32* addrspacecast (i32 addrspace(4)* null to i32*), i32** %FuncVar3, align 4, !dbg !22
|
|
||||||
call void @llvm.dbg.declare(metadata i32 addrspace(4)** %FuncVar4, metadata !23, metadata !13), !dbg !24
|
|
||||||
store i32 addrspace(4)* null, i32 addrspace(4)** %FuncVar4, align 4, !dbg !24
|
|
||||||
ret void, !dbg !25
|
|
||||||
}
|
|
||||||
|
|
||||||
!llvm.dbg.cu = !{!0}
|
|
||||||
!opencl.ocl.version = !{!3}
|
|
||||||
!llvm.module.flags = !{!4, !5}
|
|
||||||
!llvm.ident = !{!6}
|
|
||||||
|
|
||||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
|
|
||||||
!1 = !DIFile(filename: "pointer-address-space-dwarf-v1.cl", directory: "/some/random/directory")
|
|
||||||
!2 = !{}
|
|
||||||
!3 = !{i32 2, i32 0}
|
|
||||||
!4 = !{i32 2, !"Dwarf Version", i32 1}
|
|
||||||
!5 = !{i32 2, !"Debug Info Version", i32 3}
|
|
||||||
!6 = !{!""}
|
|
||||||
!7 = distinct !DISubprogram(name: "kernel1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, variables: !2)
|
|
||||||
!8 = !DISubroutineType(types: !9)
|
|
||||||
!9 = !{null}
|
|
||||||
!10 = !DILocalVariable(name: "FuncVar0", scope: !7, file: !1, line: 2, type: !11)
|
|
||||||
!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
|
|
||||||
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
||||||
!13 = !DIExpression()
|
|
||||||
!14 = !DILocation(line: 2, column: 15, scope: !7)
|
|
||||||
!15 = !DILocalVariable(name: "FuncVar1", scope: !7, file: !1, line: 3, type: !11)
|
|
||||||
!16 = !DILocation(line: 3, column: 17, scope: !7)
|
|
||||||
!17 = !DILocalVariable(name: "FuncVar2", scope: !7, file: !1, line: 4, type: !18)
|
|
||||||
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 32, dwarfAddressSpace: 2)
|
|
||||||
!19 = !DILocation(line: 4, column: 14, scope: !7)
|
|
||||||
!20 = !DILocalVariable(name: "FuncVar3", scope: !7, file: !1, line: 5, type: !21)
|
|
||||||
!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 32, dwarfAddressSpace: 1)
|
|
||||||
!22 = !DILocation(line: 5, column: 16, scope: !7)
|
|
||||||
!23 = !DILocalVariable(name: "FuncVar4", scope: !7, file: !1, line: 6, type: !11)
|
|
||||||
!24 = !DILocation(line: 6, column: 8, scope: !7)
|
|
||||||
!25 = !DILocation(line: 7, column: 1, scope: !7)
|
|
|
@ -1,92 +0,0 @@
|
||||||
; RUN: llc -O0 -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -verify-machineinstrs -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
|
|
||||||
|
|
||||||
; LLVM IR generated with the following command and OpenCL source:
|
|
||||||
;
|
|
||||||
; $clang -cl-std=CL2.0 -g -O0 -target amdgcn-amd-amdhsa -S -emit-llvm <path-to-file>
|
|
||||||
;
|
|
||||||
; global int GlobA;
|
|
||||||
; global int GlobB;
|
|
||||||
;
|
|
||||||
; kernel void kernel1(unsigned int ArgN, global int *ArgA, global int *ArgB) {
|
|
||||||
; ArgA[ArgN] += ArgB[ArgN];
|
|
||||||
; }
|
|
||||||
|
|
||||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
|
||||||
|
|
||||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x05> 03 00 00 00 00 )
|
|
||||||
@GlobA = common addrspace(1) global i32 0, align 4, !dbg !0
|
|
||||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x05> 03 00 00 00 00 )
|
|
||||||
@GlobB = common addrspace(1) global i32 0, align 4, !dbg !6
|
|
||||||
|
|
||||||
define amdgpu_kernel void @kernel1(
|
|
||||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x06> 91 04 10 01 16 18 )
|
|
||||||
i32 %ArgN,
|
|
||||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x06> 91 08 10 01 16 18 )
|
|
||||||
i32 addrspace(1)* %ArgA,
|
|
||||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x06> 91 10 10 01 16 18 )
|
|
||||||
i32 addrspace(1)* %ArgB) !dbg !13 {
|
|
||||||
entry:
|
|
||||||
%ArgN.addr = alloca i32, align 4
|
|
||||||
%ArgA.addr = alloca i32 addrspace(1)*, align 4
|
|
||||||
%ArgB.addr = alloca i32 addrspace(1)*, align 4
|
|
||||||
store i32 %ArgN, i32* %ArgN.addr, align 4
|
|
||||||
call void @llvm.dbg.declare(metadata i32* %ArgN.addr, metadata !22, metadata !23), !dbg !24
|
|
||||||
store i32 addrspace(1)* %ArgA, i32 addrspace(1)** %ArgA.addr, align 4
|
|
||||||
call void @llvm.dbg.declare(metadata i32 addrspace(1)** %ArgA.addr, metadata !25, metadata !23), !dbg !26
|
|
||||||
store i32 addrspace(1)* %ArgB, i32 addrspace(1)** %ArgB.addr, align 4
|
|
||||||
call void @llvm.dbg.declare(metadata i32 addrspace(1)** %ArgB.addr, metadata !27, metadata !23), !dbg !28
|
|
||||||
%0 = load i32 addrspace(1)*, i32 addrspace(1)** %ArgB.addr, align 4, !dbg !29
|
|
||||||
%1 = load i32, i32* %ArgN.addr, align 4, !dbg !30
|
|
||||||
%idxprom = zext i32 %1 to i64, !dbg !29
|
|
||||||
%arrayidx = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 %idxprom, !dbg !29
|
|
||||||
%2 = load i32, i32 addrspace(1)* %arrayidx, align 4, !dbg !29
|
|
||||||
%3 = load i32 addrspace(1)*, i32 addrspace(1)** %ArgA.addr, align 4, !dbg !31
|
|
||||||
%4 = load i32, i32* %ArgN.addr, align 4, !dbg !32
|
|
||||||
%idxprom1 = zext i32 %4 to i64, !dbg !31
|
|
||||||
%arrayidx2 = getelementptr inbounds i32, i32 addrspace(1)* %3, i64 %idxprom1, !dbg !31
|
|
||||||
%5 = load i32, i32 addrspace(1)* %arrayidx2, align 4, !dbg !33
|
|
||||||
%add = add nsw i32 %5, %2, !dbg !33
|
|
||||||
store i32 %add, i32 addrspace(1)* %arrayidx2, align 4, !dbg !33
|
|
||||||
ret void, !dbg !34
|
|
||||||
}
|
|
||||||
|
|
||||||
!llvm.dbg.cu = !{!2}
|
|
||||||
!opencl.ocl.version = !{!9}
|
|
||||||
!llvm.module.flags = !{!10, !11}
|
|
||||||
!llvm.ident = !{!12}
|
|
||||||
|
|
||||||
!0 = !DIGlobalVariableExpression(var: !1)
|
|
||||||
!1 = distinct !DIGlobalVariable(name: "GlobA", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true)
|
|
||||||
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 5.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
|
|
||||||
!3 = !DIFile(filename: "variable-locations-dwarf-v1.cl", directory: "/some/random/directory")
|
|
||||||
!4 = !{}
|
|
||||||
!5 = !{!0, !6}
|
|
||||||
!6 = !DIGlobalVariableExpression(var: !7)
|
|
||||||
!7 = distinct !DIGlobalVariable(name: "GlobB", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true)
|
|
||||||
!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
||||||
!9 = !{i32 2, i32 0}
|
|
||||||
!10 = !{i32 2, !"Dwarf Version", i32 1}
|
|
||||||
!11 = !{i32 2, !"Debug Info Version", i32 3}
|
|
||||||
!12 = !{!"clang version 5.0.0"}
|
|
||||||
!13 = distinct !DISubprogram(name: "kernel1", scope: !3, file: !3, line: 4, type: !14, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, unit: !2, variables: !4)
|
|
||||||
!14 = !DISubroutineType(types: !15)
|
|
||||||
!15 = !{null, !16, !17, !17}
|
|
||||||
!16 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
|
|
||||||
!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64)
|
|
||||||
!18 = !{i32 0, i32 1, i32 1}
|
|
||||||
!19 = !{!"none", !"none", !"none"}
|
|
||||||
!20 = !{!"uint", !"int*", !"int*"}
|
|
||||||
!21 = !{!"", !"", !""}
|
|
||||||
!22 = !DILocalVariable(name: "ArgN", arg: 1, scope: !13, file: !3, line: 4, type: !16)
|
|
||||||
!23 = !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)
|
|
||||||
!24 = !DILocation(line: 4, column: 34, scope: !13)
|
|
||||||
!25 = !DILocalVariable(name: "ArgA", arg: 2, scope: !13, file: !3, line: 4, type: !17)
|
|
||||||
!26 = !DILocation(line: 4, column: 52, scope: !13)
|
|
||||||
!27 = !DILocalVariable(name: "ArgB", arg: 3, scope: !13, file: !3, line: 4, type: !17)
|
|
||||||
!28 = !DILocation(line: 4, column: 70, scope: !13)
|
|
||||||
!29 = !DILocation(line: 5, column: 17, scope: !13)
|
|
||||||
!30 = !DILocation(line: 5, column: 22, scope: !13)
|
|
||||||
!31 = !DILocation(line: 5, column: 3, scope: !13)
|
|
||||||
!32 = !DILocation(line: 5, column: 8, scope: !13)
|
|
||||||
!33 = !DILocation(line: 5, column: 14, scope: !13)
|
|
||||||
!34 = !DILocation(line: 6, column: 1, scope: !13)
|
|
|
@ -522,7 +522,8 @@ public:
|
||||||
|
|
||||||
/// \brief Emit the abbreviation table \p Abbrevs to the
|
/// \brief Emit the abbreviation table \p Abbrevs to the
|
||||||
/// debug_abbrev section.
|
/// debug_abbrev section.
|
||||||
void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs);
|
void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
|
||||||
|
unsigned DwarfVersion);
|
||||||
|
|
||||||
/// \brief Emit the string table described by \p Pool.
|
/// \brief Emit the string table described by \p Pool.
|
||||||
void emitStrings(const NonRelocatableStringpool &Pool);
|
void emitStrings(const NonRelocatableStringpool &Pool);
|
||||||
|
@ -690,8 +691,10 @@ void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit) {
|
||||||
/// \brief Emit the \p Abbrevs array as the shared abbreviation table
|
/// \brief Emit the \p Abbrevs array as the shared abbreviation table
|
||||||
/// for the linked Dwarf file.
|
/// for the linked Dwarf file.
|
||||||
void DwarfStreamer::emitAbbrevs(
|
void DwarfStreamer::emitAbbrevs(
|
||||||
const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs) {
|
const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
|
||||||
|
unsigned DwarfVersion) {
|
||||||
MS->SwitchSection(MOFI->getDwarfAbbrevSection());
|
MS->SwitchSection(MOFI->getDwarfAbbrevSection());
|
||||||
|
MC->setDwarfVersion(DwarfVersion);
|
||||||
Asm->emitDwarfAbbrevs(Abbrevs);
|
Asm->emitDwarfAbbrevs(Abbrevs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1129,6 +1132,12 @@ private:
|
||||||
/// \brief Called at the end of a debug object link.
|
/// \brief Called at the end of a debug object link.
|
||||||
void endDebugObject();
|
void endDebugObject();
|
||||||
|
|
||||||
|
/// Remembers the newest DWARF version we've seen in a unit.
|
||||||
|
void maybeUpdateMaxDwarfVersion(unsigned Version) {
|
||||||
|
if (MaxDwarfVersion < Version)
|
||||||
|
MaxDwarfVersion = Version;
|
||||||
|
}
|
||||||
|
|
||||||
/// Keeps track of relocations.
|
/// Keeps track of relocations.
|
||||||
class RelocationManager {
|
class RelocationManager {
|
||||||
struct ValidReloc {
|
struct ValidReloc {
|
||||||
|
@ -1430,6 +1439,7 @@ private:
|
||||||
std::unique_ptr<DwarfStreamer> Streamer;
|
std::unique_ptr<DwarfStreamer> Streamer;
|
||||||
uint64_t OutputDebugInfoSize;
|
uint64_t OutputDebugInfoSize;
|
||||||
unsigned UnitID; ///< A unique ID that identifies each compile unit.
|
unsigned UnitID; ///< A unique ID that identifies each compile unit.
|
||||||
|
unsigned MaxDwarfVersion = 0;
|
||||||
|
|
||||||
/// The units of the current debug map object.
|
/// The units of the current debug map object.
|
||||||
std::vector<std::unique_ptr<CompileUnit>> Units;
|
std::vector<std::unique_ptr<CompileUnit>> Units;
|
||||||
|
@ -3435,9 +3445,11 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||||
CUDie.dump(outs(), 0);
|
CUDie.dump(outs(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!registerModuleReference(CUDie, *CU, ModuleMap))
|
if (!registerModuleReference(CUDie, *CU, ModuleMap)) {
|
||||||
Units.push_back(llvm::make_unique<CompileUnit>(*CU, UnitID++,
|
Units.push_back(llvm::make_unique<CompileUnit>(*CU, UnitID++,
|
||||||
!Options.NoODR, ""));
|
!Options.NoODR, ""));
|
||||||
|
maybeUpdateMaxDwarfVersion(CU->getVersion());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now build the DIE parent links that we will use during the next phase.
|
// Now build the DIE parent links that we will use during the next phase.
|
||||||
|
@ -3471,7 +3483,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||||
|
|
||||||
// Emit everything that's global.
|
// Emit everything that's global.
|
||||||
if (!Options.NoOutput) {
|
if (!Options.NoOutput) {
|
||||||
Streamer->emitAbbrevs(Abbreviations);
|
Streamer->emitAbbrevs(Abbreviations, MaxDwarfVersion);
|
||||||
Streamer->emitStrings(StringPool);
|
Streamer->emitStrings(StringPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,8 @@ void TestAllForms() {
|
||||||
CUDie.addAttribute(Attr_DW_FORM_ref8, DW_FORM_ref8, Data8);
|
CUDie.addAttribute(Attr_DW_FORM_ref8, DW_FORM_ref8, Data8);
|
||||||
|
|
||||||
const auto Attr_DW_FORM_ref_sig8 = static_cast<dwarf::Attribute>(Attr++);
|
const auto Attr_DW_FORM_ref_sig8 = static_cast<dwarf::Attribute>(Attr++);
|
||||||
CUDie.addAttribute(Attr_DW_FORM_ref_sig8, DW_FORM_ref_sig8, Data8_2);
|
if (Version >= 4)
|
||||||
|
CUDie.addAttribute(Attr_DW_FORM_ref_sig8, DW_FORM_ref_sig8, Data8_2);
|
||||||
|
|
||||||
const auto Attr_DW_FORM_ref_udata = static_cast<dwarf::Attribute>(Attr++);
|
const auto Attr_DW_FORM_ref_udata = static_cast<dwarf::Attribute>(Attr++);
|
||||||
CUDie.addAttribute(Attr_DW_FORM_ref_udata, DW_FORM_ref_udata, UData[0]);
|
CUDie.addAttribute(Attr_DW_FORM_ref_udata, DW_FORM_ref_udata, UData[0]);
|
||||||
|
@ -185,7 +186,8 @@ void TestAllForms() {
|
||||||
CUDie.addAttribute(Attr_DW_FORM_flag_false, DW_FORM_flag, false);
|
CUDie.addAttribute(Attr_DW_FORM_flag_false, DW_FORM_flag, false);
|
||||||
|
|
||||||
const auto Attr_DW_FORM_flag_present = static_cast<dwarf::Attribute>(Attr++);
|
const auto Attr_DW_FORM_flag_present = static_cast<dwarf::Attribute>(Attr++);
|
||||||
CUDie.addAttribute(Attr_DW_FORM_flag_present, DW_FORM_flag_present);
|
if (Version >= 4)
|
||||||
|
CUDie.addAttribute(Attr_DW_FORM_flag_present, DW_FORM_flag_present);
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Test SLEB128 based forms
|
// Test SLEB128 based forms
|
||||||
|
@ -213,8 +215,9 @@ void TestAllForms() {
|
||||||
Dwarf32Values[0]);
|
Dwarf32Values[0]);
|
||||||
|
|
||||||
const auto Attr_DW_FORM_sec_offset = static_cast<dwarf::Attribute>(Attr++);
|
const auto Attr_DW_FORM_sec_offset = static_cast<dwarf::Attribute>(Attr++);
|
||||||
CUDie.addAttribute(Attr_DW_FORM_sec_offset, DW_FORM_sec_offset,
|
if (Version >= 4)
|
||||||
Dwarf32Values[1]);
|
CUDie.addAttribute(Attr_DW_FORM_sec_offset, DW_FORM_sec_offset,
|
||||||
|
Dwarf32Values[1]);
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Add an address at the end to make sure we can decode this value
|
// Add an address at the end to make sure we can decode this value
|
||||||
|
@ -307,7 +310,8 @@ void TestAllForms() {
|
||||||
EXPECT_EQ(Data2, toReference(DieDG.find(Attr_DW_FORM_ref2), 0));
|
EXPECT_EQ(Data2, toReference(DieDG.find(Attr_DW_FORM_ref2), 0));
|
||||||
EXPECT_EQ(Data4, toReference(DieDG.find(Attr_DW_FORM_ref4), 0));
|
EXPECT_EQ(Data4, toReference(DieDG.find(Attr_DW_FORM_ref4), 0));
|
||||||
EXPECT_EQ(Data8, toReference(DieDG.find(Attr_DW_FORM_ref8), 0));
|
EXPECT_EQ(Data8, toReference(DieDG.find(Attr_DW_FORM_ref8), 0));
|
||||||
EXPECT_EQ(Data8_2, toReference(DieDG.find(Attr_DW_FORM_ref_sig8), 0));
|
if (Version >= 4)
|
||||||
|
EXPECT_EQ(Data8_2, toReference(DieDG.find(Attr_DW_FORM_ref_sig8), 0));
|
||||||
EXPECT_EQ(UData[0], toReference(DieDG.find(Attr_DW_FORM_ref_udata), 0));
|
EXPECT_EQ(UData[0], toReference(DieDG.find(Attr_DW_FORM_ref_udata), 0));
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -315,7 +319,8 @@ void TestAllForms() {
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_true), 0));
|
EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_true), 0));
|
||||||
EXPECT_EQ(0ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_false), 1));
|
EXPECT_EQ(0ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_false), 1));
|
||||||
EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_present), 0));
|
if (Version >= 4)
|
||||||
|
EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_present), 0));
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Test SLEB128 based forms
|
// Test SLEB128 based forms
|
||||||
|
@ -334,8 +339,9 @@ void TestAllForms() {
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
EXPECT_EQ(Dwarf32Values[0],
|
EXPECT_EQ(Dwarf32Values[0],
|
||||||
toReference(DieDG.find(Attr_DW_FORM_GNU_ref_alt), 0));
|
toReference(DieDG.find(Attr_DW_FORM_GNU_ref_alt), 0));
|
||||||
EXPECT_EQ(Dwarf32Values[1],
|
if (Version >= 4)
|
||||||
toSectionOffset(DieDG.find(Attr_DW_FORM_sec_offset), 0));
|
EXPECT_EQ(Dwarf32Values[1],
|
||||||
|
toSectionOffset(DieDG.find(Attr_DW_FORM_sec_offset), 0));
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Add an address at the end to make sure we can decode this value
|
// Add an address at the end to make sure we can decode this value
|
||||||
|
|
Loading…
Reference in New Issue