diff options
author | Paul Robinson <paul.robinson@sony.com> | 2017-04-20 19:16:51 +0000 |
---|---|---|
committer | Paul Robinson <paul.robinson@sony.com> | 2017-04-20 19:16:51 +0000 |
commit | 70b34533c22703b51a95598afceb58a0257d434b (patch) | |
tree | 9736c54d2e6d8f90923d10ba1c5a8b35661ed9d6 /llvm/lib | |
parent | 8431e996d323bbafda2cad67a3d6672d69e2bef8 (diff) | |
download | bcm5719-llvm-70b34533c22703b51a95598afceb58a0257d434b.tar.gz bcm5719-llvm-70b34533c22703b51a95598afceb58a0257d434b.zip |
[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
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DIE.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Support/Dwarf.cpp | 169 |
2 files changed, 170 insertions, 16 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp index 299c78439c2..31c2b3b5e75 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -31,6 +31,8 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; +#define DEBUG_TYPE "dwarfdebug" + //===----------------------------------------------------------------------===// // DIEAbbrevData Implementation //===----------------------------------------------------------------------===// @@ -79,15 +81,22 @@ void DIEAbbrev::Emit(const AsmPrinter *AP) const { dwarf::AttributeString(AttrData.getAttribute()).data()); // 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(), dwarf::FormEncodingString(AttrData.getForm()).data()); // Emit value for 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"); + if (AttrData.getForm() == dwarf::DW_FORM_implicit_const) AP->EmitSLEB128(AttrData.getValue()); - } } // Mark end of abbreviation. diff --git a/llvm/lib/Support/Dwarf.cpp b/llvm/lib/Support/Dwarf.cpp index f13da62e4a8..200546857de 100644 --- a/llvm/lib/Support/Dwarf.cpp +++ b/llvm/lib/Support/Dwarf.cpp @@ -22,7 +22,7 @@ StringRef llvm::dwarf::TagString(unsigned Tag) { switch (Tag) { default: return StringRef(); -#define HANDLE_DW_TAG(ID, NAME) \ +#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \ case DW_TAG_##NAME: \ return "DW_TAG_" #NAME; #include "llvm/Support/Dwarf.def" @@ -31,11 +31,34 @@ StringRef llvm::dwarf::TagString(unsigned Tag) { unsigned llvm::dwarf::getTag(StringRef 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" .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) { switch (Children) { case DW_CHILDREN_no: return "DW_CHILDREN_no"; @@ -48,29 +71,73 @@ StringRef llvm::dwarf::AttributeString(unsigned Attribute) { switch (Attribute) { default: return StringRef(); -#define HANDLE_DW_AT(ID, NAME) \ - case DW_AT_##NAME: \ +#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \ + case DW_AT_##NAME: \ return "DW_AT_" #NAME; #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) { switch (Encoding) { default: return StringRef(); -#define HANDLE_DW_FORM(ID, NAME) \ - case DW_FORM_##NAME: \ +#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \ + case DW_FORM_##NAME: \ return "DW_FORM_" #NAME; #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) { switch (Encoding) { default: return StringRef(); -#define HANDLE_DW_OP(ID, NAME) \ +#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \ case DW_OP_##NAME: \ return "DW_OP_" #NAME; #include "llvm/Support/Dwarf.def" @@ -81,17 +148,40 @@ StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) { unsigned llvm::dwarf::getOperationEncoding(StringRef 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" .Case("DW_OP_LLVM_fragment", DW_OP_LLVM_fragment) .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) { switch (Encoding) { default: return StringRef(); -#define HANDLE_DW_ATE(ID, NAME) \ +#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \ case DW_ATE_##NAME: \ return "DW_ATE_" #NAME; #include "llvm/Support/Dwarf.def" @@ -100,11 +190,34 @@ StringRef llvm::dwarf::AttributeEncodingString(unsigned Encoding) { unsigned llvm::dwarf::getAttributeEncoding(StringRef 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" .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) { switch (Sign) { case DW_DS_unsigned: return "DW_DS_unsigned"; @@ -169,7 +282,7 @@ StringRef llvm::dwarf::LanguageString(unsigned Language) { switch (Language) { default: return StringRef(); -#define HANDLE_DW_LANG(ID, NAME) \ +#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \ case DW_LANG_##NAME: \ return "DW_LANG_" #NAME; #include "llvm/Support/Dwarf.def" @@ -178,11 +291,34 @@ StringRef llvm::dwarf::LanguageString(unsigned Language) { unsigned llvm::dwarf::getLanguage(StringRef 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" .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) { switch (Case) { 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(); } + +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; +} |