[llvm] r309068 - [DWARF] Generalized verification of .apple_names accelerator table to be applicable to any acceleration table. Added verification for .apple_types, .apple_namespaces and .apple_objc sections.
Spyridoula Gravani via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 25 17:52:31 PDT 2017
Author: sgravani
Date: Tue Jul 25 17:52:31 2017
New Revision: 309068
URL: http://llvm.org/viewvc/llvm-project?rev=309068&view=rev
Log:
[DWARF] Generalized verification of .apple_names accelerator table to be applicable to any acceleration table. Added verification for .apple_types, .apple_namespaces and .apple_objc sections.
Differential Revision: https://reviews.llvm.org/D35853
Modified:
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
llvm/trunk/test/DebugInfo/dwarfdump-accel.test
llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_data.s
llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_form.s
llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_num_atoms.s
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h?rev=309068&r1=309067&r2=309068&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h Tue Jul 25 17:52:31 2017
@@ -23,6 +23,8 @@ class DWARFUnit;
class DWARFAcceleratorTable;
class DWARFDataExtractor;
class DWARFDebugAbbrev;
+class DataExtractor;
+struct DWARFSection;
/// A class that verifies DWARF debug information given a DWARF Context.
class DWARFVerifier {
@@ -33,7 +35,6 @@ class DWARFVerifier {
/// lies between to valid DIEs.
std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets;
uint32_t NumDebugLineErrors = 0;
- uint32_t NumAppleNamesErrors = 0;
/// Verifies the abbreviations section.
///
@@ -133,6 +134,25 @@ class DWARFVerifier {
/// - invalid file indexes
void verifyDebugLineRows();
+ /// Verify that an Apple-style accelerator table is valid.
+ ///
+ /// This function currently checks that:
+ /// - The fixed part of the header fits in the section
+ /// - The size of the section is as large as what the header describes
+ /// - There is at least one atom
+ /// - The form for each atom is valid
+ /// - The buckets have a valid index, or they are empty
+ /// - Each hashdata offset is valid
+ /// - Each DIE is valid
+ ///
+ /// \param AccelSection pointer to the section containing the acceleration table
+ /// \param StrData pointer to the string section
+ /// \param SectionName the name of the table we're verifying
+ ///
+ /// \returns The number of errors occured during verification
+ unsigned verifyAccelTable(const DWARFSection *AccelSection,
+ DataExtractor *StrData, const char *SectionName);
+
public:
DWARFVerifier(raw_ostream &S, DWARFContext &D)
: OS(S), DCtx(D) {}
@@ -162,13 +182,14 @@ public:
/// \returns true if the .debug_line verifies successfully, false otherwise.
bool handleDebugLine();
- /// Verify the information in the .apple_names accelerator table.
+ /// Verify the information in accelerator tables, if they exist.
///
/// Any errors are reported to the stream that was this object was
/// constructed with.
///
- /// \returns true if the .apple_names verifies successfully, false otherwise.
- bool handleAppleNames();
+ /// \returns true if the existing Apple-style accelerator tables verify
+ /// successfully, false otherwise.
+ bool handleAccelTables();
};
} // end namespace llvm
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=309068&r1=309067&r2=309068&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Tue Jul 25 17:52:31 2017
@@ -427,10 +427,7 @@ bool DWARFContext::verify(raw_ostream &O
if (!verifier.handleDebugLine())
Success = false;
}
- if (DumpType == DIDT_All || DumpType == DIDT_AppleNames) {
- if (!verifier.handleAppleNames())
- Success = false;
- }
+ Success &= verifier.handleAccelTables();
return Success;
}
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp?rev=309068&r1=309067&r2=309068&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp Tue Jul 25 17:52:31 2017
@@ -464,61 +464,62 @@ bool DWARFVerifier::handleDebugLine() {
return NumDebugLineErrors == 0;
}
-bool DWARFVerifier::handleAppleNames() {
- NumAppleNamesErrors = 0;
- const DWARFObject &D = DCtx.getDWARFObj();
- DWARFDataExtractor AppleNamesSection(D, D.getAppleNamesSection(),
- DCtx.isLittleEndian(), 0);
- DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
- DWARFAcceleratorTable AppleNames(AppleNamesSection, StrData);
-
- if (!AppleNames.extract()) {
- return true;
+unsigned DWARFVerifier::verifyAccelTable(const DWARFSection *AccelSection,
+ DataExtractor *StrData,
+ const char *SectionName) {
+ unsigned NumErrors = 0;
+ DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), *AccelSection,
+ DCtx.isLittleEndian(), 0);
+ DWARFAcceleratorTable AccelTable(AccelSectionData, *StrData);
+
+ OS << "Verifying " << SectionName << "...\n";
+ // Verify that the fixed part of the header is not too short.
+
+ if (!AccelSectionData.isValidOffset(AccelTable.getSizeHdr())) {
+ OS << "\terror: Section is too small to fit a section header.\n";
+ return 1;
+ }
+ // Verify that the section is not too short.
+ if (!AccelTable.extract()) {
+ OS << "\terror: Section is smaller than size described in section header.\n";
+ return 1;
}
-
- OS << "Verifying .apple_names...\n";
-
// Verify that all buckets have a valid hash index or are empty.
- uint32_t NumBuckets = AppleNames.getNumBuckets();
- uint32_t NumHashes = AppleNames.getNumHashes();
+ uint32_t NumBuckets = AccelTable.getNumBuckets();
+ uint32_t NumHashes = AccelTable.getNumHashes();
uint32_t BucketsOffset =
- AppleNames.getSizeHdr() + AppleNames.getHeaderDataLength();
+ AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength();
uint32_t HashesBase = BucketsOffset + NumBuckets * 4;
uint32_t OffsetsBase = HashesBase + NumHashes * 4;
-
for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
- uint32_t HashIdx = AppleNamesSection.getU32(&BucketsOffset);
+ uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
- OS << format("error: Bucket[%d] has invalid hash index: %u\n", BucketIdx,
+ OS << format("\terror: Bucket[%d] has invalid hash index: %u.\n", BucketIdx,
HashIdx);
- ++NumAppleNamesErrors;
+ ++NumErrors;
}
}
-
- uint32_t NumAtoms = AppleNames.getAtomsDesc().size();
+ uint32_t NumAtoms = AccelTable.getAtomsDesc().size();
if (NumAtoms == 0) {
- OS << "error: no atoms; failed to read HashData\n";
- ++NumAppleNamesErrors;
- return false;
+ OS << "\terror: no atoms; failed to read HashData.\n";
+ return 1;
}
-
- if (!AppleNames.validateForms()) {
- OS << "error: unsupported form; failed to read HashData\n";
- ++NumAppleNamesErrors;
- return false;
+ if (!AccelTable.validateForms()) {
+ OS << "\terror: unsupported form; failed to read HashData.\n";
+ return 1;
}
for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
uint32_t HashOffset = HashesBase + 4 * HashIdx;
uint32_t DataOffset = OffsetsBase + 4 * HashIdx;
- uint32_t Hash = AppleNamesSection.getU32(&HashOffset);
- uint32_t HashDataOffset = AppleNamesSection.getU32(&DataOffset);
- if (!AppleNamesSection.isValidOffsetForDataOfSize(HashDataOffset,
- sizeof(uint64_t))) {
- OS << format("error: Hash[%d] has invalid HashData offset: 0x%08x\n",
+ uint32_t Hash = AccelSectionData.getU32(&HashOffset);
+ uint32_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
+ if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
+ sizeof(uint64_t))) {
+ OS << format("\terror: Hash[%d] has invalid HashData offset: 0x%08x.\n",
HashIdx, HashDataOffset);
- ++NumAppleNamesErrors;
+ ++NumErrors;
}
uint32_t StrpOffset;
@@ -526,32 +527,51 @@ bool DWARFVerifier::handleAppleNames() {
uint32_t StringCount = 0;
uint32_t DieOffset = dwarf::DW_INVALID_OFFSET;
- while ((StrpOffset = AppleNamesSection.getU32(&HashDataOffset)) != 0) {
+ while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) {
const uint32_t NumHashDataObjects =
- AppleNamesSection.getU32(&HashDataOffset);
+ AccelSectionData.getU32(&HashDataOffset);
for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
++HashDataIdx) {
- DieOffset = AppleNames.readAtoms(HashDataOffset);
+ DieOffset = AccelTable.readAtoms(HashDataOffset);
if (!DCtx.getDIEForOffset(DieOffset)) {
const uint32_t BucketIdx =
NumBuckets ? (Hash % NumBuckets) : UINT32_MAX;
StringOffset = StrpOffset;
- const char *Name = StrData.getCStr(&StringOffset);
+ const char *Name = StrData->getCStr(&StringOffset);
if (!Name)
Name = "<NULL>";
OS << format(
- "error: .apple_names Bucket[%d] Hash[%d] = 0x%08x "
+ "\terror: %s Bucket[%d] Hash[%d] = 0x%08x "
"Str[%u] = 0x%08x "
"DIE[%d] = 0x%08x is not a valid DIE offset for \"%s\".\n",
- BucketIdx, HashIdx, Hash, StringCount, StrpOffset, HashDataIdx,
- DieOffset, Name);
+ SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
+ HashDataIdx, DieOffset, Name);
- ++NumAppleNamesErrors;
+ ++NumErrors;
}
}
++StringCount;
}
}
- return NumAppleNamesErrors == 0;
+ return NumErrors;
+}
+
+bool DWARFVerifier::handleAccelTables() {
+ const DWARFObject &D = DCtx.getDWARFObj();
+ DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
+ unsigned NumErrors = 0;
+ if (!D.getAppleNamesSection().Data.empty())
+ NumErrors +=
+ verifyAccelTable(&D.getAppleNamesSection(), &StrData, ".apple_names");
+ if (!D.getAppleTypesSection().Data.empty())
+ NumErrors +=
+ verifyAccelTable(&D.getAppleTypesSection(), &StrData, ".apple_types");
+ if (!D.getAppleNamespacesSection().Data.empty())
+ NumErrors += verifyAccelTable(&D.getAppleNamespacesSection(), &StrData,
+ ".apple_namespaces");
+ if (!D.getAppleObjCSection().Data.empty())
+ NumErrors +=
+ verifyAccelTable(&D.getAppleObjCSection(), &StrData, ".apple_objc");
+ return NumErrors == 0;
}
Modified: llvm/trunk/test/DebugInfo/dwarfdump-accel.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/dwarfdump-accel.test?rev=309068&r1=309067&r2=309068&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/dwarfdump-accel.test (original)
+++ llvm/trunk/test/DebugInfo/dwarfdump-accel.test Tue Jul 25 17:52:31 2017
@@ -1,5 +1,5 @@
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-objc.x86_64.o | FileCheck %s
-RUN: llvm-dwarfdump -verify %p/Inputs/dwarfdump-objc.x86_64.o | FileCheck %s --check-prefix=VERIFY
+RUN: not llvm-dwarfdump -verify %p/Inputs/dwarfdump-objc.x86_64.o | FileCheck %s --check-prefix=VERIFY
Gather some DIE indexes to verify the accelerator table contents.
CHECK: .debug_info contents
@@ -66,5 +66,9 @@ CHECK: {Atom[0]: [[ASSIGN]]}
CHECK: {Atom[0]: [[SETASSIGN]]}
Verify the debug info in the apple_names accelerator table.
-VERIFY: Verifying .apple_names
-VERIFY-NEXT: No errors.
+VERIFY: Verifying .apple_names...
+VERIFY-NEXT: Verifying .apple_types...
+VERIFY-NEXT: Verifying .apple_namespaces...
+VERIFY-NEXT: error: Section is smaller than size described in section header.
+VERIFY-NEXT: Verifying .apple_objc...
+VERIFY-NEXT: Errors detected.
Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_data.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_data.s?rev=309068&r1=309067&r2=309068&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_data.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_data.s Tue Jul 25 17:52:31 2017
@@ -3,9 +3,9 @@
# RUN: | FileCheck %s
# CHECK: Verifying .apple_names...
-# CHECK-NEXT: error: Bucket[0] has invalid hash index: 4294967294
-# CHECK-NEXT: error: Hash[0] has invalid HashData offset: 0x000000b4
-# CHECK-NEXT: error: .apple_names Bucket[1] Hash[1] = 0x0002b60f Str[0] = 0x0000005a DIE[0] = 0x00000001 is not a valid DIE offset for "j".
+# CHECK-NEXT: error: Bucket[0] has invalid hash index: 4294967294.
+# CHECK-NEXT: error: Hash[0] has invalid HashData offset: 0x000000b4.
+# CHECK-NEXT: error: .apple_names Bucket[1] Hash[1] = 0x0002b60f Str[0] = 0x0000005a DIE[0] = 0x00000001 is not a valid DIE offset for "j".
# This test is meant to verify that the -verify option
# in llvm-dwarfdump, correctly identifies
@@ -41,11 +41,11 @@ Lnames_begin:
.long 1 ## HeaderData Atom Count
.short 1 ## DW_ATOM_die_offset
.short 25 ## DW_FORM_data4 -- error: .apple_names Bucket[1] Hash[1] = 0x0002b60f Str[0] = 0x0000005a DIE[0] = 0x00000001 is not a valid DIE offset for "j".
- .long -2 ## Bucket 0 -- error: Bucket[0] has invalid hash index: 4294967294
+ .long -2 ## Bucket 0 -- error: Bucket[0] has invalid hash index: 4294967294.
.long 1 ## Bucket 1
.long 177678 ## Hash in Bucket 0
.long 177679 ## Hash in Bucket 1
- .long Lsection_line ## Offset in Bucket 0 -- error: Hash[0] has invalid HashData offset: 0x000000b4
+ .long Lsection_line ## Offset in Bucket 0 -- error: Hash[0] has invalid HashData offset: 0x000000b4.
.long LNames1-Lnames_begin ## Offset in Bucket 1
LNames0:
.long 84 ## i
Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_form.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_form.s?rev=309068&r1=309067&r2=309068&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_form.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_form.s Tue Jul 25 17:52:31 2017
@@ -3,7 +3,7 @@
# RUN: | FileCheck %s
# CHECK: Verifying .apple_names...
-# CHECK-NEXT: error: unsupported form; failed to read HashData
+# CHECK-NEXT: error: unsupported form; failed to read HashData.
# This test is meant to verify that the -verify option
# in llvm-dwarfdump, correctly identifies that Atom[0].form is unsupported.
@@ -34,7 +34,7 @@ Lnames_begin:
.long 0 ## HeaderData Die Offset Base
.long 1 ## HeaderData Atom Count
.short 1 ## DW_ATOM_die_offset
- .short 400 ## DW_FORM_data4 -- error: unsupported form; failed to read HashData
+ .short 400 ## DW_FORM_data4 -- error: unsupported form; failed to read HashData.
.long 0 ## Bucket 0
.long 1 ## Bucket 1
.long 177678 ## Hash in Bucket 0
Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_num_atoms.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_num_atoms.s?rev=309068&r1=309067&r2=309068&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_num_atoms.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/apple_names_verify_num_atoms.s Tue Jul 25 17:52:31 2017
@@ -3,7 +3,7 @@
# RUN: | FileCheck %s
# CHECK: Verifying .apple_names...
-# CHECK-NEXT: error: no atoms; failed to read HashData
+# CHECK-NEXT: error: no atoms; failed to read HashData.
# This test is meant to verify that the -verify option
# in llvm-dwarfdump, correctly identifies that there is not Atom.
@@ -33,7 +33,7 @@ Lnames_begin:
.long 2 ## Header Hash Count
.long 12 ## Header Data Length
.long 0 ## HeaderData Die Offset Base
- .long 0 ## HeaderData Atom Count -- error: no atoms; failed to read HashData
+ .long 0 ## HeaderData Atom Count -- error: no atoms; failed to read HashData.
.short 1 ## DW_ATOM_die_offset
.short 6 ## DW_FORM_data4
.long 0 ## Bucket 0
More information about the llvm-commits
mailing list