[dsymutil] Implement the BinaryHolder object and gain archive support.
This object is meant to own the ObjectFiles and their underlying
MemoryBuffer. It is basically the equivalent of an OwningBinary
except that it efficiently handles Archives. It is optimized for
efficiently providing mappings of members of the same archive when
they are opened successively (which is standard in Darwin debug
maps, objects from the same archive will be contiguous).
Of course, the BinaryHolder will also be used by the DWARF linker
once it is commited, but for now only the debug map parser uses it.
With this change, you can run llvm-dsymutil on your Darwin debug build
of clang and get a complete debug map for it.
Differential Revision: http://reviews.llvm.org/D6690
llvm-svn: 225207
diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp
index 152cbcc..fbb5ad6 100644
--- a/llvm/tools/dsymutil/MachODebugMapParser.cpp
+++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "BinaryHolder.h"
#include "DebugMap.h"
#include "dsymutil.h"
#include "llvm/Object/MachO.h"
@@ -20,9 +21,10 @@
class MachODebugMapParser {
public:
- MachODebugMapParser(StringRef BinaryPath, StringRef PathPrefix = "")
+ MachODebugMapParser(StringRef BinaryPath, StringRef PathPrefix = "",
+ bool Verbose = false)
: BinaryPath(BinaryPath), PathPrefix(PathPrefix),
- CurrentDebugMapObject(nullptr) {}
+ MainBinaryHolder(Verbose), CurrentObjectHolder(Verbose) {}
/// \brief Parses and returns the DebugMap of the input binary.
/// \returns an error in case the provided BinaryPath doesn't exist
@@ -33,16 +35,16 @@
std::string BinaryPath;
std::string PathPrefix;
- /// OwningBinary constructed from the BinaryPath.
- object::OwningBinary<object::MachOObjectFile> MainOwningBinary;
+ /// Owns the MemoryBuffer for the main binary.
+ BinaryHolder MainBinaryHolder;
/// Map of the binary symbol addresses.
StringMap<uint64_t> MainBinarySymbolAddresses;
StringRef MainBinaryStrings;
/// The constructed DebugMap.
std::unique_ptr<DebugMap> Result;
- /// Handle to the currently processed object file.
- object::OwningBinary<object::MachOObjectFile> CurrentObjectFile;
+ /// Owns the MemoryBuffer for the currently handled object file.
+ BinaryHolder CurrentObjectHolder;
/// Map of the currently processed object file symbol addresses.
StringMap<uint64_t> CurrentObjectAddresses;
/// Element of the debug map corresponfing to the current object file.
@@ -66,26 +68,10 @@
static void Warning(const Twine &Msg) { errs() << "warning: " + Msg + "\n"; }
}
-static ErrorOr<OwningBinary<MachOObjectFile>>
-createMachOBinary(StringRef File) {
- auto MemBufOrErr = MemoryBuffer::getFile(File);
- if (auto Error = MemBufOrErr.getError())
- return Error;
-
- MemoryBufferRef BufRef = (*MemBufOrErr)->getMemBufferRef();
- auto MachOOrErr = ObjectFile::createMachOObjectFile(BufRef);
- if (auto Error = MachOOrErr.getError())
- return Error;
-
- return OwningBinary<MachOObjectFile>(std::move(*MachOOrErr),
- std::move(*MemBufOrErr));
-}
-
/// Reset the parser state coresponding to the current object
/// file. This is to be called after an object file is finished
/// processing.
void MachODebugMapParser::resetParserState() {
- CurrentObjectFile = OwningBinary<object::MachOObjectFile>();
CurrentObjectAddresses.clear();
CurrentDebugMapObject = nullptr;
}
@@ -99,14 +85,13 @@
SmallString<80> Path(PathPrefix);
sys::path::append(Path, Filename);
- auto MachOOrError = createMachOBinary(Path);
+ auto MachOOrError = CurrentObjectHolder.GetFileAs<MachOObjectFile>(Path);
if (auto Error = MachOOrError.getError()) {
Warning(Twine("cannot open debug object \"") + Path.str() + "\": " +
Error.message() + "\n");
return;
}
- CurrentObjectFile = std::move(*MachOOrError);
loadCurrentObjectFileSymbols();
CurrentDebugMapObject = &Result->addDebugMapObject(Path);
}
@@ -115,14 +100,13 @@
/// successful iterates over the STAB entries. The real parsing is
/// done in handleStabSymbolTableEntry.
ErrorOr<std::unique_ptr<DebugMap>> MachODebugMapParser::parse() {
- auto MainBinaryOrError = createMachOBinary(BinaryPath);
- if (auto Error = MainBinaryOrError.getError())
+ auto MainBinOrError = MainBinaryHolder.GetFileAs<MachOObjectFile>(BinaryPath);
+ if (auto Error = MainBinOrError.getError())
return Error;
- MainOwningBinary = std::move(*MainBinaryOrError);
+ const MachOObjectFile &MainBinary = *MainBinOrError;
loadMainBinarySymbols();
Result = make_unique<DebugMap>();
- const auto &MainBinary = *MainOwningBinary.getBinary();
MainBinaryStrings = MainBinary.getStringTableData();
for (const SymbolRef &Symbol : MainBinary.symbols()) {
const DataRefImpl &DRI = Symbol.getRawDataRefImpl();
@@ -190,9 +174,8 @@
/// Load the current object file symbols into CurrentObjectAddresses.
void MachODebugMapParser::loadCurrentObjectFileSymbols() {
CurrentObjectAddresses.clear();
- const auto &Binary = *CurrentObjectFile.getBinary();
- for (auto Sym : Binary.symbols()) {
+ for (auto Sym : CurrentObjectHolder.Get().symbols()) {
StringRef Name;
uint64_t Addr;
if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize ||
@@ -215,9 +198,9 @@
/// Load the interesting main binary symbols' addresses into
/// MainBinarySymbolAddresses.
void MachODebugMapParser::loadMainBinarySymbols() {
- const MachOObjectFile &Binary = *MainOwningBinary.getBinary();
- section_iterator Section = Binary.section_end();
- for (const auto &Sym : Binary.symbols()) {
+ const MachOObjectFile &MainBinary = MainBinaryHolder.GetAs<MachOObjectFile>();
+ section_iterator Section = MainBinary.section_end();
+ for (const auto &Sym : MainBinary.symbols()) {
SymbolRef::Type Type;
// Skip undefined and STAB entries.
if (Sym.getType(Type) || (Type & SymbolRef::ST_Debug) ||
@@ -243,7 +226,7 @@
llvm::ErrorOr<std::unique_ptr<DebugMap>> parseDebugMap(StringRef InputFile,
StringRef PrependPath,
bool Verbose) {
- MachODebugMapParser Parser(InputFile, PrependPath);
+ MachODebugMapParser Parser(InputFile, PrependPath, Verbose);
return Parser.parse();
}
}