1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[dsymutil] Thread the VFS through dsymutil (NFC)

This patch threads the virtual file system through dsymutil.

Currently there is no good way to find out exactly what files are
necessary in order to reproduce a dsymutil link, at least not without
knowledge of how dsymutil's internals.  My motivation for this change is
to add lightweight "reproducers" that automatically gather the input
object files through the FileCollectorFileSystem. The files together
with the YAML mapping will allow us to transparently reproduce a
dsymutil link, even without having to mess with the OSO path prefix.

Differential revision: https://reviews.llvm.org/D79376
This commit is contained in:
Jonas Devlieghere 2020-05-04 20:19:15 -07:00
parent ef34a4ddd4
commit 6f1978ec1f
10 changed files with 59 additions and 31 deletions

View File

@ -41,12 +41,15 @@ getMachOFatMemoryBuffers(StringRef Filename, MemoryBuffer &Mem,
return Buffers;
}
Error BinaryHolder::ArchiveEntry::load(StringRef Filename,
Error BinaryHolder::ArchiveEntry::load(IntrusiveRefCntPtr<vfs::FileSystem> VFS,
StringRef Filename,
TimestampTy Timestamp, bool Verbose) {
StringRef ArchiveFilename = getArchiveAndObjectName(Filename).first;
// Try to load archive and force it to be memory mapped.
auto ErrOrBuff = MemoryBuffer::getFileOrSTDIN(ArchiveFilename, -1, false);
auto ErrOrBuff = (ArchiveFilename == "-")
? MemoryBuffer::getSTDIN()
: VFS->getBufferForFile(ArchiveFilename, -1, false);
if (auto Err = ErrOrBuff.getError())
return errorCodeToError(Err);
@ -83,9 +86,12 @@ Error BinaryHolder::ArchiveEntry::load(StringRef Filename,
return Error::success();
}
Error BinaryHolder::ObjectEntry::load(StringRef Filename, bool Verbose) {
Error BinaryHolder::ObjectEntry::load(IntrusiveRefCntPtr<vfs::FileSystem> VFS,
StringRef Filename, bool Verbose) {
// Try to load regular binary and force it to be memory mapped.
auto ErrOrBuff = MemoryBuffer::getFileOrSTDIN(Filename, -1, false);
auto ErrOrBuff = (Filename == "-")
? MemoryBuffer::getSTDIN()
: VFS->getBufferForFile(Filename, -1, false);
if (auto Err = ErrOrBuff.getError())
return errorCodeToError(Err);
@ -223,7 +229,7 @@ BinaryHolder::getObjectEntry(StringRef Filename, TimestampTy Timestamp) {
Verbose);
} else {
ArchiveEntry &AE = ArchiveCache[ArchiveFilename];
auto Err = AE.load(Filename, Timestamp, Verbose);
auto Err = AE.load(VFS, Filename, Timestamp, Verbose);
if (Err) {
ArchiveCache.erase(ArchiveFilename);
// Don't return the error here: maybe the file wasn't an archive.
@ -240,7 +246,7 @@ BinaryHolder::getObjectEntry(StringRef Filename, TimestampTy Timestamp) {
std::lock_guard<std::mutex> Lock(ObjectCacheMutex);
if (!ObjectCache.count(Filename)) {
ObjectEntry &OE = ObjectCache[Filename];
auto Err = OE.load(Filename, Verbose);
auto Err = OE.load(VFS, Filename, Verbose);
if (Err) {
ObjectCache.erase(Filename);
return std::move(Err);

View File

@ -23,6 +23,7 @@
#include "llvm/Support/Chrono.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <mutex>
@ -37,7 +38,8 @@ class BinaryHolder {
public:
using TimestampTy = sys::TimePoint<std::chrono::seconds>;
BinaryHolder(bool Verbose = false) : Verbose(Verbose) {}
BinaryHolder(IntrusiveRefCntPtr<vfs::FileSystem> VFS, bool Verbose = false)
: VFS(VFS), Verbose(Verbose) {}
// Forward declarations for friend declaration.
class ObjectEntry;
@ -55,7 +57,8 @@ public:
class ObjectEntry : public EntryBase {
public:
/// Load the given object binary in memory.
Error load(StringRef Filename, bool Verbose = false);
Error load(IntrusiveRefCntPtr<vfs::FileSystem> VFS, StringRef Filename,
bool Verbose = false);
/// Access all owned ObjectFiles.
std::vector<const object::ObjectFile *> getObjects() const;
@ -106,7 +109,8 @@ public:
};
/// Load the given object binary in memory.
Error load(StringRef Filename, TimestampTy Timestamp, bool Verbose = false);
Error load(IntrusiveRefCntPtr<vfs::FileSystem> VFS, StringRef Filename,
TimestampTy Timestamp, bool Verbose = false);
Expected<const ObjectEntry &> getObjectEntry(StringRef Filename,
TimestampTy Timestamp,
@ -133,6 +137,9 @@ private:
StringMap<ObjectEntry> ObjectCache;
std::mutex ObjectCacheMutex;
/// Virtual File System instance.
IntrusiveRefCntPtr<vfs::FileSystem> VFS;
bool Verbose;
};

View File

@ -234,7 +234,7 @@ MappingTraits<dsymutil::DebugMapObject>::YamlDMO::YamlDMO(
dsymutil::DebugMapObject
MappingTraits<dsymutil::DebugMapObject>::YamlDMO::denormalize(IO &IO) {
BinaryHolder BinHolder(/* Verbose =*/false);
BinaryHolder BinHolder(vfs::getRealFileSystem(), /* Verbose =*/false);
const auto &Ctxt = *reinterpret_cast<YAMLContext *>(IO.getContext());
SmallString<80> Path(Ctxt.PrependPath);
StringMap<uint64_t> SymbolAddresses;

View File

@ -455,8 +455,8 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) {
if (Map.getTriple().isOSDarwin() && !Map.getBinaryPath().empty() &&
Options.FileType == OutputFileType::Object)
return MachOUtils::generateDsymCompanion(
Map, Options.Translator, *Streamer->getAsmPrinter().OutStreamer,
OutFile);
Options.VFS, Map, Options.Translator,
*Streamer->getAsmPrinter().OutStreamer, OutFile);
Streamer->finish();
return true;

View File

@ -13,6 +13,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Remarks/RemarkFormat.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/WithColor.h"
#include "llvm/DWARFLinker/DWARFLinker.h"
@ -62,6 +63,10 @@ struct LinkOptions {
/// Symbol map translator.
SymbolMapTranslator Translator;
/// Virtual File System.
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
vfs::getRealFileSystem();
/// Fields used for linking and placing remarks into the .dSYM bundle.
/// @{

View File

@ -23,12 +23,13 @@ using namespace llvm::object;
class MachODebugMapParser {
public:
MachODebugMapParser(StringRef BinaryPath, ArrayRef<std::string> Archs,
MachODebugMapParser(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef BinaryPath, ArrayRef<std::string> Archs,
StringRef PathPrefix = "",
bool PaperTrailWarnings = false, bool Verbose = false)
: BinaryPath(std::string(BinaryPath)), Archs(Archs.begin(), Archs.end()),
PathPrefix(std::string(PathPrefix)),
PaperTrailWarnings(PaperTrailWarnings), BinHolder(Verbose),
PaperTrailWarnings(PaperTrailWarnings), BinHolder(VFS, Verbose),
CurrentDebugMapObject(nullptr) {}
/// Parses and returns the DebugMaps of the input binary. The binary contains
@ -190,7 +191,8 @@ MachODebugMapParser::parseOneBinary(const MachOObjectFile &MainBinary,
StringRef BinaryPath) {
loadMainBinarySymbols(MainBinary);
ArrayRef<uint8_t> UUID = MainBinary.getUuid();
Result = std::make_unique<DebugMap>(MainBinary.getArchTriple(), BinaryPath, UUID);
Result =
std::make_unique<DebugMap>(MainBinary.getArchTriple(), BinaryPath, UUID);
MainBinaryStrings = MainBinary.getStringTableData();
for (const SymbolRef &Symbol : MainBinary.symbols()) {
const DataRefImpl &DRI = Symbol.getRawDataRefImpl();
@ -583,20 +585,22 @@ void MachODebugMapParser::loadMainBinarySymbols(
namespace llvm {
namespace dsymutil {
llvm::ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
parseDebugMap(StringRef InputFile, ArrayRef<std::string> Archs,
parseDebugMap(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef InputFile, ArrayRef<std::string> Archs,
StringRef PrependPath, bool PaperTrailWarnings, bool Verbose,
bool InputIsYAML) {
if (InputIsYAML)
return DebugMap::parseYAMLDebugMap(InputFile, PrependPath, Verbose);
MachODebugMapParser Parser(InputFile, Archs, PrependPath, PaperTrailWarnings,
Verbose);
MachODebugMapParser Parser(VFS, InputFile, Archs, PrependPath,
PaperTrailWarnings, Verbose);
return Parser.parse();
}
bool dumpStab(StringRef InputFile, ArrayRef<std::string> Archs,
bool dumpStab(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef InputFile, ArrayRef<std::string> Archs,
StringRef PrependPath) {
MachODebugMapParser Parser(InputFile, Archs, PrependPath, false);
MachODebugMapParser Parser(VFS, InputFile, Archs, PrependPath, false);
return Parser.dumpStab();
}
} // namespace dsymutil

View File

@ -332,7 +332,8 @@ static unsigned segmentLoadCommandSize(bool Is64Bit, unsigned NumSections) {
// Stream a dSYM companion binary file corresponding to the binary referenced
// by \a DM to \a OutFile. The passed \a MS MCStreamer is setup to write to
// \a OutFile and it must be using a MachObjectWriter object to do so.
bool generateDsymCompanion(const DebugMap &DM, SymbolMapTranslator &Translator,
bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
const DebugMap &DM, SymbolMapTranslator &Translator,
MCStreamer &MS, raw_fd_ostream &OutFile) {
auto &ObjectStreamer = static_cast<MCObjectStreamer &>(MS);
MCAssembler &MCAsm = ObjectStreamer.getAssembler();
@ -343,7 +344,7 @@ bool generateDsymCompanion(const DebugMap &DM, SymbolMapTranslator &Translator,
MCAsmLayout Layout(MCAsm);
MCAsm.layout(Layout);
BinaryHolder InputBinaryHolder(false);
BinaryHolder InputBinaryHolder(VFS, false);
auto ObjectEntry = InputBinaryHolder.getObjectEntry(DM.getBinaryPath());
if (!ObjectEntry) {

View File

@ -12,6 +12,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <string>
@ -40,7 +41,8 @@ bool generateUniversalBinary(SmallVectorImpl<ArchAndFile> &ArchFiles,
StringRef OutputFileName, const LinkOptions &,
StringRef SDKPath);
bool generateDsymCompanion(const DebugMap &DM, SymbolMapTranslator &Translator,
bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
const DebugMap &DM, SymbolMapTranslator &Translator,
MCStreamer &MS, raw_fd_ostream &OutFile);
std::string getArchName(StringRef Arch);

View File

@ -510,15 +510,16 @@ int main(int argc, char **argv) {
for (auto &InputFile : Options.InputFiles) {
// Dump the symbol table for each input file and requested arch
if (Options.DumpStab) {
if (!dumpStab(InputFile, Options.Archs, Options.LinkOpts.PrependPath))
if (!dumpStab(Options.LinkOpts.VFS, InputFile, Options.Archs,
Options.LinkOpts.PrependPath))
return 1;
continue;
}
auto DebugMapPtrsOrErr =
parseDebugMap(InputFile, Options.Archs, Options.LinkOpts.PrependPath,
Options.PaperTrailWarnings, Options.LinkOpts.Verbose,
Options.InputIsYAMLDebugMap);
parseDebugMap(Options.LinkOpts.VFS, InputFile, Options.Archs,
Options.LinkOpts.PrependPath, Options.PaperTrailWarnings,
Options.LinkOpts.Verbose, Options.InputIsYAMLDebugMap);
if (auto EC = DebugMapPtrsOrErr.getError()) {
WithColor::error() << "cannot parse the debug map for '" << InputFile
@ -545,7 +546,7 @@ int main(int argc, char **argv) {
}
// Shared a single binary holder for all the link steps.
BinaryHolder BinHolder;
BinaryHolder BinHolder(Options.LinkOpts.VFS);
ThreadPoolStrategy S = hardware_concurrency(Options.LinkOpts.Threads);
if (Options.LinkOpts.Threads == 0) {

View File

@ -35,12 +35,14 @@ class BinaryHolder;
/// The file has to be a MachO object file. Multiple debug maps can be
/// returned when the file is universal (aka fat) binary.
ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
parseDebugMap(StringRef InputFile, ArrayRef<std::string> Archs,
parseDebugMap(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef InputFile, ArrayRef<std::string> Archs,
StringRef PrependPath, bool PaperTrailWarnings, bool Verbose,
bool InputIsYAML);
/// Dump the symbol table
bool dumpStab(StringRef InputFile, ArrayRef<std::string> Archs,
/// Dump the symbol table.
bool dumpStab(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
StringRef InputFile, ArrayRef<std::string> Archs,
StringRef PrependPath = "");
/// Link the Dwarf debug info as directed by the passed DebugMap \p DM into a