Specifies a ``path`` to prepend to all debug symbol object file paths.
+.. option:: --object-prefix-map=<prefix=remapped>
+
+ 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
StringRef Path)>
objFileLoader;
typedef std::map<std::string, std::string> swiftInterfacesMap;
+typedef std::map<std::string, std::string> objectPrefixMap;
/// The core of the Dwarf linking logic.
///
Options.ParseableSwiftInterfaces = Map;
}
+ /// Set prefix map for objects.
+ void setObjectPrefixMap(objectPrefixMap *Map) {
+ Options.ObjectPrefixMap = Map;
+ }
+
private:
/// Flags passed to DwarfLinker::lookForDIEsToKeep
enum TraversalFlags {
/// 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;
};
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,
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);
--- /dev/null
+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:
HELP: -no-output
HELP: -no-swiftmodule-timestamp
HELP: -num-threads <threads>
+HELP: -object-prefix-map <prefix=remapped>
HELP: -oso-prepend-path <path>
HELP: -o <filename>
HELP: -papertrail
remarks::RemarkLinker RL;
if (!Options.RemarksPrependPath.empty())
RL.setExternalFilePrependPath(Options.RemarksPrependPath);
+ GeneralLinker.setObjectPrefixMap(&Options.ObjectPrefixMap);
std::function<StringRef(StringRef)> TranslationLambda = [&](StringRef Input) {
assert(Options.Translator);
/// -oso-prepend-path
std::string PrependPath;
+ /// The -object-prefix-map.
+ std::map<std::string, std::string> ObjectPrefixMap;
+
/// The Resources directory in the .dSYM bundle.
Optional<std::string> ResourceDir;
Group<grp_general>;
def: Joined<["--", "-"], "oso-prepend-path=">, Alias<oso_prepend_path>;
+def object_prefix_map: Separate<["--", "-"], "object-prefix-map">,
+ MetaVarName<"<prefix=remapped>">,
+ 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<grp_general>;
+def: Joined<["--", "-"], "object-prefix-map=">, Alias<object_prefix_map>;
+
def symbolmap: Separate<["--", "-"], "symbol-map">,
MetaVarName<"<bcsymbolmap>">,
HelpText<"Updates the existing dSYMs inplace using symbol map specified.">,
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();