mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
llvm-dwarfdump: implement --find for .apple_names
This patch implements the dwarfdump option --find=<name>. This option looks for a DIE in the accelerator tables and dumps it if found. This initial patch only adds support for .apple_names to keep the review small, adding the other sections and pubnames support should be trivial though. Differential Revision: https://reviews.llvm.org/D38282 llvm-svn: 314439
This commit is contained in:
parent
fdd0433d80
commit
9a78f28e7e
@ -491,6 +491,9 @@ private:
|
|||||||
/// Constants that define the DWARF format as 32 or 64 bit.
|
/// Constants that define the DWARF format as 32 or 64 bit.
|
||||||
enum DwarfFormat : uint8_t { DWARF32, DWARF64 };
|
enum DwarfFormat : uint8_t { DWARF32, DWARF64 };
|
||||||
|
|
||||||
|
/// The Bernstein hash function used by the accelerator tables.
|
||||||
|
uint32_t djbHash(StringRef Buffer);
|
||||||
|
|
||||||
} // End of namespace dwarf
|
} // End of namespace dwarf
|
||||||
|
|
||||||
} // End of namespace llvm
|
} // End of namespace llvm
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
|
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@ -21,6 +21,9 @@ namespace llvm {
|
|||||||
|
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
|
|
||||||
|
/// This implements the Apple accelerator table format, a precursor of the
|
||||||
|
/// DWARF 5 accelerator table format.
|
||||||
|
/// TODO: Factor out a common base class for both formats.
|
||||||
class DWARFAcceleratorTable {
|
class DWARFAcceleratorTable {
|
||||||
struct Header {
|
struct Header {
|
||||||
uint32_t Magic;
|
uint32_t Magic;
|
||||||
@ -43,8 +46,46 @@ class DWARFAcceleratorTable {
|
|||||||
struct HeaderData HdrData;
|
struct HeaderData HdrData;
|
||||||
DWARFDataExtractor AccelSection;
|
DWARFDataExtractor AccelSection;
|
||||||
DataExtractor StringSection;
|
DataExtractor StringSection;
|
||||||
|
bool IsValid = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// An iterator for the entries associated with one key. Each entry can have
|
||||||
|
/// multiple DWARFFormValues.
|
||||||
|
class ValueIterator : public std::iterator<std::input_iterator_tag,
|
||||||
|
ArrayRef<DWARFFormValue>> {
|
||||||
|
const DWARFAcceleratorTable *AccelTable = nullptr;
|
||||||
|
SmallVector<DWARFFormValue, 3> AtomForms; ///< The decoded data entry.
|
||||||
|
|
||||||
|
unsigned DataOffset = 0; ///< Offset into the section.
|
||||||
|
unsigned Data = 0; ///< Current data entry.
|
||||||
|
unsigned NumData = 0; ///< Number of data entries.
|
||||||
|
|
||||||
|
/// Advance the iterator.
|
||||||
|
void Next();
|
||||||
|
public:
|
||||||
|
/// Construct a new iterator for the entries at \p DataOffset.
|
||||||
|
ValueIterator(const DWARFAcceleratorTable &AccelTable, unsigned DataOffset);
|
||||||
|
/// End marker.
|
||||||
|
ValueIterator() : NumData(0) {}
|
||||||
|
|
||||||
|
const ArrayRef<DWARFFormValue> operator*() const {
|
||||||
|
return AtomForms;
|
||||||
|
}
|
||||||
|
ValueIterator &operator++() { Next(); return *this; }
|
||||||
|
ValueIterator operator++(int) {
|
||||||
|
ValueIterator I(*this);
|
||||||
|
Next();
|
||||||
|
return I;
|
||||||
|
}
|
||||||
|
friend bool operator==(const ValueIterator &A, const ValueIterator &B) {
|
||||||
|
return A.NumData == B.NumData && A.DataOffset == B.DataOffset;
|
||||||
|
}
|
||||||
|
friend bool operator!=(const ValueIterator &A, const ValueIterator &B) {
|
||||||
|
return !(A == B);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
DWARFAcceleratorTable(const DWARFDataExtractor &AccelSection,
|
DWARFAcceleratorTable(const DWARFDataExtractor &AccelSection,
|
||||||
DataExtractor StringSection)
|
DataExtractor StringSection)
|
||||||
: AccelSection(AccelSection), StringSection(StringSection) {}
|
: AccelSection(AccelSection), StringSection(StringSection) {}
|
||||||
@ -67,6 +108,9 @@ public:
|
|||||||
/// DieTag is the tag of the DIE
|
/// DieTag is the tag of the DIE
|
||||||
std::pair<uint32_t, dwarf::Tag> readAtoms(uint32_t &HashDataOffset);
|
std::pair<uint32_t, dwarf::Tag> readAtoms(uint32_t &HashDataOffset);
|
||||||
void dump(raw_ostream &OS) const;
|
void dump(raw_ostream &OS) const;
|
||||||
|
|
||||||
|
/// Look up all entries in the accelerator table matching \c Key.
|
||||||
|
iterator_range<ValueIterator> equal_range(StringRef Key) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/iterator_range.h"
|
#include "llvm/ADT/iterator_range.h"
|
||||||
#include "llvm/DebugInfo/DIContext.h"
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
|
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
|
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
|
||||||
@ -68,6 +69,7 @@ class DWARFContext : public DIContext {
|
|||||||
std::unique_ptr<DWARFDebugFrame> DebugFrame;
|
std::unique_ptr<DWARFDebugFrame> DebugFrame;
|
||||||
std::unique_ptr<DWARFDebugFrame> EHFrame;
|
std::unique_ptr<DWARFDebugFrame> EHFrame;
|
||||||
std::unique_ptr<DWARFDebugMacro> Macro;
|
std::unique_ptr<DWARFDebugMacro> Macro;
|
||||||
|
std::unique_ptr<DWARFAcceleratorTable> AppleNames;
|
||||||
|
|
||||||
DWARFUnitSection<DWARFCompileUnit> DWOCUs;
|
DWARFUnitSection<DWARFCompileUnit> DWOCUs;
|
||||||
std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
|
std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
|
||||||
@ -237,6 +239,9 @@ public:
|
|||||||
/// Get a pointer to the parsed DebugMacro object.
|
/// Get a pointer to the parsed DebugMacro object.
|
||||||
const DWARFDebugMacro *getDebugMacro();
|
const DWARFDebugMacro *getDebugMacro();
|
||||||
|
|
||||||
|
/// Get a reference to the parsed accelerator table object.
|
||||||
|
const DWARFAcceleratorTable &getAppleNames();
|
||||||
|
|
||||||
/// Get a pointer to a parsed line table corresponding to a compile unit.
|
/// Get a pointer to a parsed line table corresponding to a compile unit.
|
||||||
const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);
|
const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);
|
||||||
|
|
||||||
|
@ -575,3 +575,10 @@ bool llvm::dwarf::isValidFormForVersion(Form F, unsigned Version,
|
|||||||
}
|
}
|
||||||
return ExtensionsOk;
|
return ExtensionsOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t llvm::dwarf::djbHash(StringRef Buffer) {
|
||||||
|
uint32_t H = 5381;
|
||||||
|
for (char C : Buffer.bytes())
|
||||||
|
H = ((H << 5) + H) + C;
|
||||||
|
return H;
|
||||||
|
}
|
||||||
|
@ -68,13 +68,6 @@ class AsmPrinter;
|
|||||||
class DwarfDebug;
|
class DwarfDebug;
|
||||||
|
|
||||||
class DwarfAccelTable {
|
class DwarfAccelTable {
|
||||||
static uint32_t HashDJB(StringRef Str) {
|
|
||||||
uint32_t h = 5381;
|
|
||||||
for (unsigned i = 0, e = Str.size(); i != e; ++i)
|
|
||||||
h = ((h << 5) + h) + Str[i];
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to compute the number of buckets needed based on
|
// Helper function to compute the number of buckets needed based on
|
||||||
// the number of unique hashes.
|
// the number of unique hashes.
|
||||||
void ComputeBucketCount();
|
void ComputeBucketCount();
|
||||||
@ -199,7 +192,7 @@ private:
|
|||||||
|
|
||||||
HashData(StringRef S, DwarfAccelTable::DataArray &Data)
|
HashData(StringRef S, DwarfAccelTable::DataArray &Data)
|
||||||
: Str(S), Data(Data) {
|
: Str(S), Data(Data) {
|
||||||
HashValue = DwarfAccelTable::HashDJB(S);
|
HashValue = dwarf::djbHash(S);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
|
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
|
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
@ -52,6 +51,7 @@ bool DWARFAcceleratorTable::extract() {
|
|||||||
HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
|
HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IsValid = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +109,9 @@ DWARFAcceleratorTable::readAtoms(uint32_t &HashDataOffset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const {
|
LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const {
|
||||||
|
if (!IsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
// Dump the header.
|
// Dump the header.
|
||||||
OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
|
OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
|
||||||
<< "Version = " << format("0x%04x", Hdr.Version) << '\n'
|
<< "Version = " << format("0x%04x", Hdr.Version) << '\n'
|
||||||
@ -190,3 +193,67 @@ LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWARFAcceleratorTable::ValueIterator::ValueIterator(
|
||||||
|
const DWARFAcceleratorTable &AccelTable, unsigned Offset)
|
||||||
|
: AccelTable(&AccelTable), DataOffset(Offset) {
|
||||||
|
if (!AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const auto &Atom : AccelTable.HdrData.Atoms)
|
||||||
|
AtomForms.push_back(DWARFFormValue(Atom.second));
|
||||||
|
|
||||||
|
// Read the first entry.
|
||||||
|
NumData = AccelTable.AccelSection.getU32(&DataOffset);
|
||||||
|
Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DWARFAcceleratorTable::ValueIterator::Next() {
|
||||||
|
assert(NumData > 0 && "attempted to increment iterator past the end");
|
||||||
|
auto &AccelSection = AccelTable->AccelSection;
|
||||||
|
if (Data >= NumData ||
|
||||||
|
!AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
|
||||||
|
NumData = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (auto &Atom : AtomForms)
|
||||||
|
Atom.extractValue(AccelSection, &DataOffset, nullptr);
|
||||||
|
++Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator_range<DWARFAcceleratorTable::ValueIterator>
|
||||||
|
DWARFAcceleratorTable::equal_range(StringRef Key) const {
|
||||||
|
if (!IsValid)
|
||||||
|
return make_range(ValueIterator(), ValueIterator());
|
||||||
|
|
||||||
|
// Find the bucket.
|
||||||
|
unsigned HashValue = dwarf::djbHash(Key);
|
||||||
|
unsigned Bucket = HashValue % Hdr.NumBuckets;
|
||||||
|
unsigned BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength;
|
||||||
|
unsigned HashesBase = BucketBase + Hdr.NumBuckets * 4;
|
||||||
|
unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
|
||||||
|
|
||||||
|
unsigned BucketOffset = BucketBase + Bucket * 4;
|
||||||
|
unsigned Index = AccelSection.getU32(&BucketOffset);
|
||||||
|
|
||||||
|
// Search through all hashes in the bucket.
|
||||||
|
for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
|
||||||
|
unsigned HashOffset = HashesBase + HashIdx * 4;
|
||||||
|
unsigned OffsetsOffset = OffsetsBase + HashIdx * 4;
|
||||||
|
uint32_t Hash = AccelSection.getU32(&HashOffset);
|
||||||
|
|
||||||
|
if (Hash % Hdr.NumBuckets != Bucket)
|
||||||
|
// We are already in the next bucket.
|
||||||
|
break;
|
||||||
|
|
||||||
|
unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
|
||||||
|
unsigned StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
|
||||||
|
if (!StringOffset)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Finally, compare the key.
|
||||||
|
if (Key == StringSection.getCStr(&StringOffset))
|
||||||
|
return make_range({*this, DataOffset}, ValueIterator());
|
||||||
|
}
|
||||||
|
return make_range(ValueIterator(), ValueIterator());
|
||||||
|
}
|
||||||
|
@ -453,8 +453,7 @@ void DWARFContext::dump(
|
|||||||
|
|
||||||
if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
|
if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
|
||||||
DObj->getAppleNamesSection().Data))
|
DObj->getAppleNamesSection().Data))
|
||||||
dumpAccelSection(OS, *DObj, DObj->getAppleNamesSection(),
|
getAppleNames().dump(OS);
|
||||||
DObj->getStringSection(), isLittleEndian());
|
|
||||||
|
|
||||||
if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
|
if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
|
||||||
DObj->getAppleTypesSection().Data))
|
DObj->getAppleTypesSection().Data))
|
||||||
@ -638,6 +637,24 @@ const DWARFDebugMacro *DWARFContext::getDebugMacro() {
|
|||||||
return Macro.get();
|
return Macro.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWARFAcceleratorTable &
|
||||||
|
getAccelTable(std::unique_ptr<DWARFAcceleratorTable> &Cache,
|
||||||
|
const DWARFObject &Obj, const DWARFSection &Section,
|
||||||
|
StringRef StringSection, bool IsLittleEndian) {
|
||||||
|
if (Cache)
|
||||||
|
return *Cache;
|
||||||
|
DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
|
||||||
|
DataExtractor StrData(StringSection, IsLittleEndian, 0);
|
||||||
|
Cache.reset(new DWARFAcceleratorTable(AccelSection, StrData));
|
||||||
|
Cache->extract();
|
||||||
|
return *Cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DWARFAcceleratorTable &DWARFContext::getAppleNames() {
|
||||||
|
return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
|
||||||
|
DObj->getStringSection(), isLittleEndian());
|
||||||
|
}
|
||||||
|
|
||||||
const DWARFLineTable *
|
const DWARFLineTable *
|
||||||
DWARFContext::getLineTableForUnit(DWARFUnit *U) {
|
DWARFContext::getLineTableForUnit(DWARFUnit *U) {
|
||||||
if (!Line)
|
if (!Line)
|
||||||
|
28
test/tools/llvm-dwarfdump/X86/find.test
Normal file
28
test/tools/llvm-dwarfdump/X86/find.test
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
RUN: llvm-mc %S/brief.s -filetype obj -triple x86_64-apple-darwin -o - \
|
||||||
|
RUN: | llvm-dwarfdump -find=not_there_at_all - | \
|
||||||
|
RUN: FileCheck %s --check-prefix=EMPTY --allow-empty
|
||||||
|
EMPTY: {{^$}}
|
||||||
|
|
||||||
|
RUN: llvm-mc %S/brief.s -filetype obj -triple x86_64-apple-darwin -o - \
|
||||||
|
RUN: | llvm-dwarfdump -find=main - | FileCheck %s
|
||||||
|
CHECK: .debug_info contents:
|
||||||
|
CHECK-NOT: {{:}}
|
||||||
|
CHECK: : DW_TAG_subprogram
|
||||||
|
CHECK-NOT: {{:}}
|
||||||
|
CHECK: DW_AT_name ("main")
|
||||||
|
CHECK-NOT: {{:}}
|
||||||
|
|
||||||
|
RUN: llvm-dwarfdump --debug-info %S/../../dsymutil/Inputs/libfat-test.a \
|
||||||
|
RUN: -find=x86_64h_var -find=i386_var \
|
||||||
|
RUN: | FileCheck %s --check-prefix=MULTI
|
||||||
|
MULTI: .debug_info contents:
|
||||||
|
MULTI-NOT: {{: DW}}
|
||||||
|
MULTI: : DW_TAG_variable
|
||||||
|
MULTI-NOT: {{: DW}}
|
||||||
|
MULTI: DW_AT_name ("i386_var")
|
||||||
|
MULTI-NOT: {{: DW}}
|
||||||
|
MULTI: .debug_info contents:
|
||||||
|
MULTI: : DW_TAG_variable
|
||||||
|
MULTI-NOT: {{: DW}}
|
||||||
|
MULTI: DW_AT_name ("x86_64h_var")
|
||||||
|
MULTI-NOT: {{: DW}}
|
@ -6,6 +6,7 @@ HELP: Section-specific Dump Options
|
|||||||
HELP: -debug-info - Dump the .debug_info section
|
HELP: -debug-info - Dump the .debug_info section
|
||||||
HELP: -eh-frame
|
HELP: -eh-frame
|
||||||
HELP: Specific Options
|
HELP: Specific Options
|
||||||
|
HELP: -find
|
||||||
HELP: -recurse-depth=<N>
|
HELP: -recurse-depth=<N>
|
||||||
HELP: -show-children
|
HELP: -show-children
|
||||||
HELP: -show-parents
|
HELP: -show-parents
|
||||||
|
@ -134,6 +134,13 @@ static list<std::string>
|
|||||||
"name or by number. This option can be specified "
|
"name or by number. This option can be specified "
|
||||||
"multiple times, once for each desired architecture."),
|
"multiple times, once for each desired architecture."),
|
||||||
cat(DwarfDumpCategory));
|
cat(DwarfDumpCategory));
|
||||||
|
static list<std::string>
|
||||||
|
Find("find",
|
||||||
|
desc("Search for the exact match for <name> in the accelerator tables "
|
||||||
|
"and print the matching debug information entries."),
|
||||||
|
value_desc("name"), cat(DwarfDumpCategory));
|
||||||
|
static alias FindAlias("f", desc("Alias for -find"), aliasopt(Find));
|
||||||
|
|
||||||
static opt<bool> DumpUUID("uuid", desc("Show the UUID for each architecture"),
|
static opt<bool> DumpUUID("uuid", desc("Show the UUID for each architecture"),
|
||||||
cat(DwarfDumpCategory));
|
cat(DwarfDumpCategory));
|
||||||
static alias DumpUUIDAlias("u", desc("Alias for -uuid"), aliasopt(DumpUUID));
|
static alias DumpUUIDAlias("u", desc("Alias for -uuid"), aliasopt(DumpUUID));
|
||||||
@ -164,7 +171,7 @@ static opt<unsigned> RecurseDepth(
|
|||||||
cat(DwarfDumpCategory), init(-1U), value_desc("N"));
|
cat(DwarfDumpCategory), init(-1U), value_desc("N"));
|
||||||
static alias RecurseDepthAlias("r", desc("Alias for -recurse-depth"),
|
static alias RecurseDepthAlias("r", desc("Alias for -recurse-depth"),
|
||||||
aliasopt(RecurseDepth));
|
aliasopt(RecurseDepth));
|
||||||
|
|
||||||
static opt<bool>
|
static opt<bool>
|
||||||
SummarizeTypes("summarize-types",
|
SummarizeTypes("summarize-types",
|
||||||
desc("Abbreviate the description of type unit entries"),
|
desc("Abbreviate the description of type unit entries"),
|
||||||
@ -236,6 +243,22 @@ static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
|
|||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
|
logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
|
||||||
Filename.str() + ": ");
|
Filename.str() + ": ");
|
||||||
|
|
||||||
|
// Handle the --find option and lower it to --debug-info=<offset>.
|
||||||
|
if (!Find.empty()) {
|
||||||
|
DumpOffsets[DIDT_ID_DebugInfo] = [&]() -> Optional<uint64_t> {
|
||||||
|
for (auto Name : Find)
|
||||||
|
for (auto Entry : DICtx.getAppleNames().equal_range(Name))
|
||||||
|
for (auto Atom : Entry)
|
||||||
|
if (auto Offset = Atom.getAsSectionOffset())
|
||||||
|
return DumpOffsets[DIDT_ID_DebugInfo] = *Offset;
|
||||||
|
return None;
|
||||||
|
}();
|
||||||
|
// Early exit if --find was specified but the current file doesn't have it.
|
||||||
|
if (!DumpOffsets[DIDT_ID_DebugInfo])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// The UUID dump already contains all the same information.
|
// The UUID dump already contains all the same information.
|
||||||
if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
|
if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
|
||||||
OS << Filename << ":\tfile format " << Obj.getFileFormatName() << '\n';
|
OS << Filename << ":\tfile format " << Obj.getFileFormatName() << '\n';
|
||||||
|
Loading…
Reference in New Issue
Block a user