From ed8ad6ec1562a980d8d6a8fea29703030acc125b Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Wed, 18 Mar 2020 15:31:39 -0700 Subject: [PATCH] Add an -object-path-prefix option to dsymutil to remap object file paths (but no source paths) before processing. This is meant to be used for Clang objects where the module cache location was remapped using ``-fdebug-prefix-map``; to help dsymutil find the Clang module cache. Differential Revision: https://reviews.llvm.org/D76391 --- llvm/docs/CommandGuide/dsymutil.rst | 6 ++++++ llvm/include/llvm/DWARFLinker/DWARFLinker.h | 9 +++++++++ llvm/lib/DWARFLinker/DWARFLinker.cpp | 10 ++++++++++ llvm/test/tools/dsymutil/X86/object-prefix-path.test | 11 +++++++++++ llvm/test/tools/dsymutil/cmdline.test | 1 + llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 1 + llvm/tools/dsymutil/LinkUtils.h | 3 +++ llvm/tools/dsymutil/Options.td | 9 +++++++++ llvm/tools/dsymutil/dsymutil.cpp | 6 ++++++ 9 files changed, 56 insertions(+) create mode 100644 llvm/test/tools/dsymutil/X86/object-prefix-path.test diff --git a/llvm/docs/CommandGuide/dsymutil.rst b/llvm/docs/CommandGuide/dsymutil.rst index 4aa9c1c7c49d..2f638daf2ae3 100644 --- a/llvm/docs/CommandGuide/dsymutil.rst +++ b/llvm/docs/CommandGuide/dsymutil.rst @@ -71,6 +71,12 @@ OPTIONS Specifies a ``path`` to prepend to all debug symbol object file paths. +.. option:: --object-prefix-map= + + Remap object file paths (but no source paths) before processing. Use + this for Clang objects where the module cache location was remapped using + ``-fdebug-prefix-map``; to help dsymutil find the Clang module cache. + .. option:: --papertrail When running dsymutil as part of your build system, it can be desirable for diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h index af49665391bb..d75ed8b98949 100644 --- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -226,6 +226,7 @@ typedef std::function(StringRef ContainerName, StringRef Path)> objFileLoader; typedef std::map swiftInterfacesMap; +typedef std::map objectPrefixMap; /// The core of the Dwarf linking logic. /// @@ -311,6 +312,11 @@ public: Options.ParseableSwiftInterfaces = Map; } + /// Set prefix map for objects. + void setObjectPrefixMap(objectPrefixMap *Map) { + Options.ObjectPrefixMap = Map; + } + private: /// Flags passed to DwarfLinker::lookForDIEsToKeep enum TraversalFlags { @@ -783,6 +789,9 @@ private: /// per compile unit, which is why this is a std::map. /// this is dsymutil specific fag. swiftInterfacesMap *ParseableSwiftInterfaces = nullptr; + + /// A list of remappings to apply to file paths. + objectPrefixMap *ObjectPrefixMap = nullptr; } Options; }; diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp index ab18cb005a3a..6444af9046b8 100644 --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -1918,6 +1918,14 @@ static uint64_t getDwoId(const DWARFDie &CUDie, const DWARFUnit &Unit) { return 0; } +static std::string remapPath(StringRef Path, + const objectPrefixMap &ObjectPrefixMap) { + for (const auto &Entry : ObjectPrefixMap) + if (Path.startswith(Entry.first)) + return (Twine(Entry.second) + Path.substr(Entry.first.size())).str(); + return Path.str(); +} + bool DWARFLinker::registerModuleReference( DWARFDie CUDie, const DWARFUnit &Unit, const DwarfFile &File, OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool, @@ -1927,6 +1935,8 @@ bool DWARFLinker::registerModuleReference( CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), ""); if (PCMfile.empty()) return false; + if (Options.ObjectPrefixMap) + PCMfile = remapPath(PCMfile, *Options.ObjectPrefixMap); // Clang module DWARF skeleton CUs abuse this for the path to the module. uint64_t DwoId = getDwoId(CUDie, Unit); diff --git a/llvm/test/tools/dsymutil/X86/object-prefix-path.test b/llvm/test/tools/dsymutil/X86/object-prefix-path.test new file mode 100644 index 000000000000..16956e0f9452 --- /dev/null +++ b/llvm/test/tools/dsymutil/X86/object-prefix-path.test @@ -0,0 +1,11 @@ +RUN: rm -rf %t.dir && mkdir %t.dir && mkdir %t.dir/ModuleCacheRenamed +RUN: cp %p/../Inputs/module-warnings/1.o %t.dir +RUN: cp %p/../Inputs/module-warnings/Foo.pcm %t.dir/ModuleCacheRenamed + +RUN: dsymutil -verify -f -oso-prepend-path=%t.dir -y \ +RUN: %p/dummy-debug-map.map -o %t \ +RUN: -object-prefix-map=/ModuleCache=/ModuleCacheRenamed \ +RUN: 2>&1 | FileCheck %s + +CHECK: warning: {{.*}}Bar.pcm: +CHECK-NOT: warning: {{.*}}Foo.pcm: diff --git a/llvm/test/tools/dsymutil/cmdline.test b/llvm/test/tools/dsymutil/cmdline.test index fc3f00b369fd..701de29637dd 100644 --- a/llvm/test/tools/dsymutil/cmdline.test +++ b/llvm/test/tools/dsymutil/cmdline.test @@ -12,6 +12,7 @@ HELP: -no-odr HELP: -no-output HELP: -no-swiftmodule-timestamp HELP: -num-threads +HELP: -object-prefix-map HELP: -oso-prepend-path HELP: -o HELP: -papertrail diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp index 51912c78769b..c1c247d1baa0 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -297,6 +297,7 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) { remarks::RemarkLinker RL; if (!Options.RemarksPrependPath.empty()) RL.setExternalFilePrependPath(Options.RemarksPrependPath); + GeneralLinker.setObjectPrefixMap(&Options.ObjectPrefixMap); std::function TranslationLambda = [&](StringRef Input) { assert(Options.Translator); diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h index 92de81da8fa0..0339f4485e73 100644 --- a/llvm/tools/dsymutil/LinkUtils.h +++ b/llvm/tools/dsymutil/LinkUtils.h @@ -57,6 +57,9 @@ struct LinkOptions { /// -oso-prepend-path std::string PrependPath; + /// The -object-prefix-map. + std::map ObjectPrefixMap; + /// The Resources directory in the .dSYM bundle. Optional ResourceDir; diff --git a/llvm/tools/dsymutil/Options.td b/llvm/tools/dsymutil/Options.td index eb86c2f3ae1b..5360bf09ac75 100644 --- a/llvm/tools/dsymutil/Options.td +++ b/llvm/tools/dsymutil/Options.td @@ -110,6 +110,15 @@ def oso_prepend_path: Separate<["--", "-"], "oso-prepend-path">, Group; def: Joined<["--", "-"], "oso-prepend-path=">, Alias; +def object_prefix_map: Separate<["--", "-"], "object-prefix-map">, + MetaVarName<"">, + HelpText<"Remap object file paths (but no source paths) before processing." + "Use this for Clang objects where the module cache location was" + "remapped using -fdebug-prefix-map; to help dsymutil" + "find the Clang module cache.">, + Group; +def: Joined<["--", "-"], "object-prefix-map=">, Alias; + def symbolmap: Separate<["--", "-"], "symbol-map">, MetaVarName<"">, HelpText<"Updates the existing dSYMs inplace using symbol map specified.">, diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index 54adeaa11c1a..8b70673785da 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -246,6 +246,12 @@ static Expected getOptions(opt::InputArgList &Args) { if (opt::Arg *OsoPrependPath = Args.getLastArg(OPT_oso_prepend_path)) Options.LinkOpts.PrependPath = OsoPrependPath->getValue(); + for (const auto &Arg : Args.getAllArgValues(OPT_object_prefix_map)) { + auto Split = StringRef(Arg).split('='); + Options.LinkOpts.ObjectPrefixMap.insert( + {std::string(Split.first), std::string(Split.second)}); + } + if (opt::Arg *OutputFile = Args.getLastArg(OPT_output)) Options.OutputFile = OutputFile->getValue();