From 4398850779b8d6f21ac6376440d5c857a11d40b3 Mon Sep 17 00:00:00 2001 From: Frederic Riss Date: Mon, 5 Jan 2015 21:29:28 +0000 Subject: [PATCH] [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 --- .../dsymutil/Inputs/basic-archive.macho.x86_64 | Bin 0 -> 9352 bytes llvm/test/tools/dsymutil/Inputs/basic1.c | 3 + llvm/test/tools/dsymutil/Inputs/libbasic.a | Bin 0 -> 6840 bytes llvm/test/tools/dsymutil/debug-map-parsing.test | 29 ++++++ llvm/tools/dsymutil/BinaryHolder.cpp | 111 +++++++++++++++++++++ llvm/tools/dsymutil/BinaryHolder.h | 104 +++++++++++++++++++ llvm/tools/dsymutil/CMakeLists.txt | 1 + llvm/tools/dsymutil/MachODebugMapParser.cpp | 51 ++++------ 8 files changed, 265 insertions(+), 34 deletions(-) create mode 100755 llvm/test/tools/dsymutil/Inputs/basic-archive.macho.x86_64 create mode 100644 llvm/test/tools/dsymutil/Inputs/libbasic.a create mode 100644 llvm/tools/dsymutil/BinaryHolder.cpp create mode 100644 llvm/tools/dsymutil/BinaryHolder.h diff --git a/llvm/test/tools/dsymutil/Inputs/basic-archive.macho.x86_64 b/llvm/test/tools/dsymutil/Inputs/basic-archive.macho.x86_64 new file mode 100755 index 0000000000000000000000000000000000000000..abffb06147d936c7783ac0e1586c0c5eb79aab74 GIT binary patch literal 9352 zcmeHNU1(fI6rS5;?b@c@P>Mfj?L|XPs@{!FC=pZ|?cxSa4K;-#$awdUEM#}f{?VB{tuQ07LFvYMT%`fVS#`@6aqi$TYuK~lt6PD^^lLJQDe zt#~e9%*cE(S3*Z;e&57=f8>BdtaI@#?IqVahS*XbAD(u z%(zvTEnoi5-`3jTZ@avtOjRn{8R|}dy+M9k{xBx&Pvzb=KV2#mN=0qz^cVe?{#yI& zorx1~Cyr0(Jz{t8228meBud`Gxjl=0Jgi3iLt*>-nrnOlx&-_Z>JOh2Vh|2@qdf(s zJRd0c;fv64Jivz%Y(rr~`=Ie!r5vBlr{bCOvl(E@Q&8sd<>a-W5BxE_eC5LW{jctP zduaeRP$|T&T}lsYOdDhn>*YM|^RO_^7?gef_xK$cvs$qc|Go2-YPR6K;UJHE%Ab7* z72_psA)=^<0z3swc>&6P;$x_d7zPXjh5^HXVZbn87%&VN2L4M1P9?oxk{5sNUrB7x ztvBCHdbQu{^UcOSz~sdn{U2Ok3W*+{{4_Fz`*d%9qmED1T5Fu-^hC44JLvjk(^{@a zHfdT}T;UD9_u5^Q*0Q(iJB=M&02cIDkK95lqDDp5&aD7X1W$7i zBwX|Up7;NwsHtD$KPrW7{-^B2eSd%JUklxA2{Sfg7%&VN1`Gp+0mFb{z%XDKFbo(5 z32>+f@Cfc1XcLyR4- z-*?yt?0@KyxyL7pXKK|-T%_DeKK-(j-m(OSf}5TxIdfx2<1Ns_ipe*qvQdd>03qs literal 0 HcmV?d00001 diff --git a/llvm/test/tools/dsymutil/Inputs/basic1.c b/llvm/test/tools/dsymutil/Inputs/basic1.c index 04e8f93..cedf83ae 100644 --- a/llvm/test/tools/dsymutil/Inputs/basic1.c +++ b/llvm/test/tools/dsymutil/Inputs/basic1.c @@ -16,6 +16,9 @@ clang basic1-lto.o basic2-lto.o basic3-lto.o -o basic-lto.macho.x86_64 -Wl,-object_path_lto,$PWD/basic-lto.macho.x86_64.o -Wl,-dead_strip rm basic1-lto.o basic2-lto.o basic3-lto.o + Archive compilation (after basic compilation): + ar -q libbasic.a basic2.macho.x86_64.o basic3.macho.x86_64.o + clang basic1.macho.x86_64.o -lbasic -o basic-archive.macho.x86_64 -Wl,-dead_strip -L. */ int foo(int); diff --git a/llvm/test/tools/dsymutil/Inputs/libbasic.a b/llvm/test/tools/dsymutil/Inputs/libbasic.a new file mode 100644 index 0000000000000000000000000000000000000000..9657e7895578c9e26469e57cb1e861c7905969b6 GIT binary patch literal 6840 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 literal 0 HcmV?d00001 diff --git a/llvm/test/tools/dsymutil/debug-map-parsing.test b/llvm/test/tools/dsymutil/debug-map-parsing.test index 4fa7e71..f1b310f 100644 --- a/llvm/test/tools/dsymutil/debug-map-parsing.test +++ b/llvm/test/tools/dsymutil/debug-map-parsing.test @@ -1,7 +1,10 @@ RUN: llvm-dsymutil -v -parse-only -oso-prepend-path=%p %p/Inputs/basic.macho.x86_64 | FileCheck %s RUN: llvm-dsymutil -v -parse-only -oso-prepend-path=%p %p/Inputs/basic-lto.macho.x86_64 | FileCheck %s --check-prefix=CHECK-LTO +RUN: llvm-dsymutil -v -parse-only -oso-prepend-path=%p %p/Inputs/basic-archive.macho.x86_64 | FileCheck %s --check-prefix=CHECK-ARCHIVE RUN: llvm-dsymutil -v -parse-only %p/Inputs/basic.macho.x86_64 2>&1 | FileCheck %s --check-prefix=NOT-FOUND RUN: not llvm-dsymutil -v -parse-only %p/Inputs/inexistant 2>&1 | FileCheck %s --check-prefix=NO-EXECUTABLE + + Check that We can parse the debug map of the basic executable. CHECK-NOT: error @@ -33,6 +36,32 @@ CHECK-LTO: 00000000000008e8 => 0000000100001008 _private_int CHECK-LTO: 00000000000008ec => 0000000100001004 _val CHECK-LTO: END DEBUG MAP +Check thet we correctly handle debug maps with archive members (including only +opening the archive once if mulitple of its members are used). + +CHECK-ARCHIVE: trying to open {{.*}}basic-archive.macho.x86_64' +CHECK-ARCHIVE-NEXT: loaded file. +CHECK-ARCHIVE-NEXT: trying to open {{.*}}/Inputs/basic1.macho.x86_64.o' +CHECK-ARCHIVE-NEXT: loaded file. +CHECK-ARCHIVE-NEXT: trying to open {{.*}}/libbasic.a(basic2.macho.x86_64.o)' +CHECK-ARCHIVE-NEXT: opened new archive {{.*}}/libbasic.a' +CHECK-ARCHIVE-NEXT: found member in current archive. +CHECK-ARCHIVE-NEXT: trying to open {{.*}}/libbasic.a(basic3.macho.x86_64.o)' +CHECK-ARCHIVE-NEXT: found member in current archive. +CHECK-ARCHIVE: DEBUG MAP: object addr => executable addr symbol name +CHECK-ARCHIVE: /Inputs/basic1.macho.x86_64.o: +CHECK-ARCHIVE: 0000000000000000 => 0000000100000ea0 _main +CHECK-ARCHIVE: /Inputs/./libbasic.a(basic2.macho.x86_64.o): +CHECK-ARCHIVE: 0000000000000310 => 0000000100001000 _baz +CHECK-ARCHIVE: 0000000000000020 => 0000000100000ed0 _foo +CHECK-ARCHIVE: 0000000000000070 => 0000000100000f20 _inc +CHECK-ARCHIVE: 0000000000000560 => 0000000100001004 _private_int +CHECK-ARCHIVE: /Inputs/./libbasic.a(basic3.macho.x86_64.o): +CHECK-ARCHIVE: 0000000000000020 => 0000000100000f40 _bar +CHECK-ARCHIVE: 0000000000000070 => 0000000100000f90 _inc +CHECK-ARCHIVE: 0000000000000004 => 0000000100001008 _val +CHECK-ARCHIVE: END DEBUG MAP + Check that we warn about missing object files (this presumes that the files aren't present in the machine's /Inputs/ folder, which should be a pretty safe bet). diff --git a/llvm/tools/dsymutil/BinaryHolder.cpp b/llvm/tools/dsymutil/BinaryHolder.cpp new file mode 100644 index 0000000..ad66105 --- /dev/null +++ b/llvm/tools/dsymutil/BinaryHolder.cpp @@ -0,0 +1,111 @@ +//===-- BinaryHolder.cpp --------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program is a utility that aims to be a dropin replacement for +// Darwin's dsymutil. +// +//===----------------------------------------------------------------------===// + +#include "BinaryHolder.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +namespace dsymutil { + +ErrorOr +BinaryHolder::GetMemoryBufferForFile(StringRef Filename) { + if (Verbose) + outs() << "trying to open '" << Filename << "'\n"; + + // Try that first as it doesn't involve any filesystem access. + if (auto ErrOrArchiveMember = GetArchiveMemberBuffer(Filename)) + return *ErrOrArchiveMember; + + // If the name ends with a closing paren, there is a huge chance + // it is an archive member specification. + if (Filename.endswith(")")) + if (auto ErrOrArchiveMember = MapArchiveAndGetMemberBuffer(Filename)) + return *ErrOrArchiveMember; + + // Otherwise, just try opening a standard file. If this is an + // archive member specifiaction and any of the above didn't handle it + // (either because the archive is not there anymore, or because the + // archive doesn't contain the requested member), this will still + // provide a sensible error message. + auto ErrOrFile = MemoryBuffer::getFileOrSTDIN(Filename); + if (auto Err = ErrOrFile.getError()) + return Err; + + if (Verbose) + outs() << "\tloaded file.\n"; + CurrentArchive.reset(); + CurrentMemoryBuffer = std::move(ErrOrFile.get()); + return CurrentMemoryBuffer->getMemBufferRef(); +} + +ErrorOr +BinaryHolder::GetArchiveMemberBuffer(StringRef Filename) { + if (!CurrentArchive) + return make_error_code(errc::no_such_file_or_directory); + + StringRef CurArchiveName = CurrentArchive->getFileName(); + if (!Filename.startswith(Twine(CurArchiveName, "(").str())) + return make_error_code(errc::no_such_file_or_directory); + + // Remove the archive name and the parens around the archive member name. + Filename = Filename.substr(CurArchiveName.size() + 1).drop_back(); + + for (const auto &Child : CurrentArchive->children()) { + if (auto NameOrErr = Child.getName()) + if (*NameOrErr == Filename) { + if (Verbose) + outs() << "\tfound member in current archive.\n"; + return Child.getMemoryBufferRef(); + } + } + + return make_error_code(errc::no_such_file_or_directory); +} + +ErrorOr +BinaryHolder::MapArchiveAndGetMemberBuffer(StringRef Filename) { + StringRef ArchiveFilename = Filename.substr(0, Filename.find('(')); + + auto ErrOrBuff = MemoryBuffer::getFileOrSTDIN(ArchiveFilename); + if (auto Err = ErrOrBuff.getError()) + return Err; + + if (Verbose) + outs() << "\topened new archive '" << ArchiveFilename << "'\n"; + auto ErrOrArchive = object::Archive::create((*ErrOrBuff)->getMemBufferRef()); + if (auto Err = ErrOrArchive.getError()) + return Err; + + CurrentArchive = std::move(*ErrOrArchive); + CurrentMemoryBuffer = std::move(*ErrOrBuff); + + return GetArchiveMemberBuffer(Filename); +} + +ErrorOr +BinaryHolder::GetObjectFile(StringRef Filename) { + auto ErrOrMemBufferRef = GetMemoryBufferForFile(Filename); + if (auto Err = ErrOrMemBufferRef.getError()) + return Err; + + auto ErrOrObjectFile = + object::ObjectFile::createObjectFile(*ErrOrMemBufferRef); + if (auto Err = ErrOrObjectFile.getError()) + return Err; + + CurrentObjectFile = std::move(*ErrOrObjectFile); + return *CurrentObjectFile; +} +} +} diff --git a/llvm/tools/dsymutil/BinaryHolder.h b/llvm/tools/dsymutil/BinaryHolder.h new file mode 100644 index 0000000..04871b5 --- /dev/null +++ b/llvm/tools/dsymutil/BinaryHolder.h @@ -0,0 +1,104 @@ +//===-- BinaryHolder.h - Utility class for accessing binaries -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program is a utility that aims to be a dropin replacement for +// Darwin's dsymutil. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H +#define LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H + +#include "llvm/Object/Archive.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/ErrorOr.h" + +namespace llvm { +namespace dsymutil { + +/// \brief The BinaryHolder class is responsible for creating and +/// owning ObjectFile objects and their underlying MemoryBuffer. This +/// is different from a simple OwningBinary in that it handles +/// accessing to archive members. +/// +/// As an optimization, this class will reuse an already mapped and +/// parsed Archive object if 2 successive requests target the same +/// archive file (Which is always the case in debug maps). +/// Currently it only owns one memory buffer at any given time, +/// meaning that a mapping request will invalidate the previous memory +/// mapping. +class BinaryHolder { + std::unique_ptr CurrentArchive; + std::unique_ptr CurrentMemoryBuffer; + std::unique_ptr CurrentObjectFile; + bool Verbose; + + /// \brief Get the MemoryBufferRef for the file specification in \p + /// Filename from the current archive. + /// + /// This function performs no system calls, it just looks up a + /// potential match for the given \p Filename in the currently + /// mapped archive if there is one. + ErrorOr GetArchiveMemberBuffer(StringRef Filename); + + /// \brief Interpret Filename as an archive member specification, + /// map the corresponding archive to memory and return the + /// MemoryBufferRef corresponding to the described member. + ErrorOr MapArchiveAndGetMemberBuffer(StringRef Filename); + + /// \brief Return the MemoryBufferRef that holds the memory + /// mapping for the given \p Filename. This function will try to + /// parse archive member specifications of the form + /// /path/to/archive.a(member.o). + /// + /// The returned MemoryBufferRef points to a buffer owned by this + /// object. The buffer is valid until the next call to + /// GetMemoryBufferForFile() on this object. + ErrorOr GetMemoryBufferForFile(StringRef Filename); + +public: + BinaryHolder(bool Verbose) : Verbose(Verbose) {} + + /// \brief Get the ObjectFile designated by the \p Filename. This + /// might be an archive member specification of the form + /// /path/to/archive.a(member.o). + /// + /// Calling this function invalidates the previous mapping owned by + /// the BinaryHolder. + ErrorOr GetObjectFile(StringRef Filename); + + /// \brief Wraps GetObjectFile() to return a derived ObjectFile type. + template + ErrorOr GetFileAs(StringRef Filename) { + auto ErrOrObjFile = GetObjectFile(Filename); + if (auto Err = ErrOrObjFile.getError()) + return Err; + if (const auto *Derived = dyn_cast(CurrentObjectFile.get())) + return *Derived; + return make_error_code(object::object_error::invalid_file_type); + } + + /// \brief Access the currently owned ObjectFile. As successfull + /// call to GetObjectFile() or GetFileAs() must have been performed + /// before calling this. + const object::ObjectFile &Get() { + assert(CurrentObjectFile); + return *CurrentObjectFile; + } + + /// \brief Access to a derived version of the currently owned + /// ObjectFile. The conversion must be known to be valid. + template const ObjectFileType &GetAs() { + return cast(*CurrentObjectFile); + } +}; +} +} +#endif diff --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt index ead9848..bfe7c70 100644 --- a/llvm/tools/dsymutil/CMakeLists.txt +++ b/llvm/tools/dsymutil/CMakeLists.txt @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS add_llvm_tool(llvm-dsymutil dsymutil.cpp + BinaryHolder.cpp DebugMap.cpp DwarfLinker.cpp MachODebugMapParser.cpp 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 @@ using namespace llvm::object; 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 @@ private: std::string BinaryPath; std::string PathPrefix; - /// OwningBinary constructed from the BinaryPath. - object::OwningBinary MainOwningBinary; + /// Owns the MemoryBuffer for the main binary. + BinaryHolder MainBinaryHolder; /// Map of the binary symbol addresses. StringMap MainBinarySymbolAddresses; StringRef MainBinaryStrings; /// The constructed DebugMap. std::unique_ptr Result; - /// Handle to the currently processed object file. - object::OwningBinary CurrentObjectFile; + /// Owns the MemoryBuffer for the currently handled object file. + BinaryHolder CurrentObjectHolder; /// Map of the currently processed object file symbol addresses. StringMap CurrentObjectAddresses; /// Element of the debug map corresponfing to the current object file. @@ -66,26 +68,10 @@ private: static void Warning(const Twine &Msg) { errs() << "warning: " + Msg + "\n"; } } -static ErrorOr> -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(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(); CurrentObjectAddresses.clear(); CurrentDebugMapObject = nullptr; } @@ -99,14 +85,13 @@ void MachODebugMapParser::switchToNewDebugMapObject(StringRef Filename) { SmallString<80> Path(PathPrefix); sys::path::append(Path, Filename); - auto MachOOrError = createMachOBinary(Path); + auto MachOOrError = CurrentObjectHolder.GetFileAs(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 @@ void MachODebugMapParser::switchToNewDebugMapObject(StringRef Filename) { /// successful iterates over the STAB entries. The real parsing is /// done in handleStabSymbolTableEntry. ErrorOr> MachODebugMapParser::parse() { - auto MainBinaryOrError = createMachOBinary(BinaryPath); - if (auto Error = MainBinaryOrError.getError()) + auto MainBinOrError = MainBinaryHolder.GetFileAs(BinaryPath); + if (auto Error = MainBinOrError.getError()) return Error; - MainOwningBinary = std::move(*MainBinaryOrError); + const MachOObjectFile &MainBinary = *MainBinOrError; loadMainBinarySymbols(); Result = make_unique(); - const auto &MainBinary = *MainOwningBinary.getBinary(); MainBinaryStrings = MainBinary.getStringTableData(); for (const SymbolRef &Symbol : MainBinary.symbols()) { const DataRefImpl &DRI = Symbol.getRawDataRefImpl(); @@ -190,9 +174,8 @@ void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex, /// 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 @@ uint64_t MachODebugMapParser::getMainBinarySymbolAddress(StringRef Name) { /// 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(); + 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 @@ namespace dsymutil { llvm::ErrorOr> parseDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose) { - MachODebugMapParser Parser(InputFile, PrependPath); + MachODebugMapParser Parser(InputFile, PrependPath, Verbose); return Parser.parse(); } } -- 2.7.4