[llvm] [dsymutil] Add option to filter debug map objects by allowlist (PR #182083)
Roy Shi via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 4 11:03:08 PST 2026
https://github.com/royitaqi updated https://github.com/llvm/llvm-project/pull/182083
>From 96748362a750fec4cdd9c73766fd1adea9d98d2e Mon Sep 17 00:00:00 2001
From: Roy Shi <royshi at meta.com>
Date: Wed, 18 Feb 2026 07:41:12 -0800
Subject: [PATCH 1/5] [dsymutil] Allow filtering the debug map objects
according to input text file
---
llvm/docs/CommandGuide/dsymutil.rst | 5 +++
llvm/test/tools/dsymutil/cmdline.test | 4 +++
llvm/tools/dsymutil/MachODebugMapParser.cpp | 30 ++++++++++++++---
llvm/tools/dsymutil/Options.td | 7 ++++
llvm/tools/dsymutil/dsymutil.cpp | 37 ++++++++++++++++++++-
llvm/tools/dsymutil/dsymutil.h | 6 +++-
6 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/llvm/docs/CommandGuide/dsymutil.rst b/llvm/docs/CommandGuide/dsymutil.rst
index 0e442d657e987..5457d3b785ad4 100644
--- a/llvm/docs/CommandGuide/dsymutil.rst
+++ b/llvm/docs/CommandGuide/dsymutil.rst
@@ -23,6 +23,11 @@ OPTIONS
Specify the desired type of accelerator table. Valid options are 'Apple',
'Dwarf', 'Default' and 'None'.
+.. option:: --allowed-debug-map-objects <path>
+
+ Only process debug map objects listed in <path> (one object path per line;
+ exact match; only filters N_OSO entries).
+
.. option:: --arch <arch>
Link DWARF debug information only for specified CPU architecture types.
diff --git a/llvm/test/tools/dsymutil/cmdline.test b/llvm/test/tools/dsymutil/cmdline.test
index 0b0bce194d575..524a70efa25b1 100644
--- a/llvm/test/tools/dsymutil/cmdline.test
+++ b/llvm/test/tools/dsymutil/cmdline.test
@@ -6,6 +6,7 @@ HELP: USAGE: {{.*}}dsymutil{{[^ ]*}} [options] <input files>
HELP-NOT: -reverse-iterate
HELP: Dsymutil Options:
CHECK: -accelerator
+CHECK: -allowed-debug-map-objects <path>
CHECK: -arch <arch>
CHECK: -build-variant-suffix <suffix=buildvariant>
CHECK: -dump-debug-map
@@ -52,3 +53,6 @@ BOGUS: warning: ignoring unknown option: -bogus
RUN: not dsymutil --quiet --verbose 2>&1 | FileCheck --check-prefix=CONFLICT %s
CONFLICT: error: --quiet and --verbose cannot be specified together
+
+RUN: not dsymutil -y file1 --allowed-debug-map-objects file2 2>&1 | FileCheck --check-prefix=CONFLICT2 %s
+CONFLICT2: error: -y and --allowed-debug-map-objects cannot be specified together
diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp
index a0ba2512e12f2..1db0f12979f3a 100644
--- a/llvm/tools/dsymutil/MachODebugMapParser.cpp
+++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp
@@ -12,6 +12,7 @@
#include "RelocationMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/Path.h"
@@ -31,11 +32,14 @@ class MachODebugMapParser {
ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths,
StringRef PathPrefix = "", StringRef VariantSuffix = "",
- bool Verbose = false)
+ bool Verbose = false,
+ const std::optional<StringSet<>>
+ &AllowedDebugMapObjects = std::nullopt)
: BinaryPath(std::string(BinaryPath)), Archs(Archs),
DSYMSearchPaths(DSYMSearchPaths), PathPrefix(std::string(PathPrefix)),
VariantSuffix(std::string(VariantSuffix)), BinHolder(BinHolder),
- CurrentDebugMapObject(nullptr), SkipDebugMapObject(false) {}
+ CurrentDebugMapObject(nullptr), SkipDebugMapObject(false),
+ AllowedDebugMapObjects(AllowedDebugMapObjects) {}
/// Parses and returns the DebugMaps of the input binary. The binary contains
/// multiple maps in case it is a universal binary.
@@ -80,6 +84,10 @@ class MachODebugMapParser {
/// Whether we need to skip the current debug map object.
bool SkipDebugMapObject;
+ /// Optional set of allowed debug map object paths. If set, only objects
+ /// whose path is in this set will be included.
+ const std::optional<StringSet<>> &AllowedDebugMapObjects;
+
/// Holds function info while function scope processing.
const char *CurrentFunctionName;
uint64_t CurrentFunctionAddress;
@@ -120,6 +128,13 @@ class MachODebugMapParser {
void addCommonSymbols();
+ /// Check if a debug map object should be included based on the allowed list.
+ bool shouldIncludeObject(StringRef Path) const {
+ if (!AllowedDebugMapObjects.has_value())
+ return true;
+ return AllowedDebugMapObjects->contains(Path);
+ }
+
/// Dump the symbol table output header.
void dumpSymTabHeader(raw_ostream &OS, StringRef Arch);
@@ -191,6 +206,11 @@ void MachODebugMapParser::switchToNewDebugMapObject(
SmallString<80> Path(PathPrefix);
sys::path::append(Path, Filename);
+ if (!shouldIncludeObject(Path)) {
+ SkipDebugMapObject = true;
+ return;
+ }
+
auto ObjectEntry = BinHolder.getObjectEntry(Path, Timestamp);
if (!ObjectEntry) {
auto Err = ObjectEntry.takeError();
@@ -857,13 +877,15 @@ llvm::ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
parseDebugMap(BinaryHolder &BinHolder, StringRef InputFile,
ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
- StringRef VariantSuffix, bool Verbose, bool InputIsYAML) {
+ StringRef VariantSuffix, bool Verbose, bool InputIsYAML,
+ const std::optional<StringSet<>> &AllowedDebugMapObjects) {
if (InputIsYAML)
return DebugMap::parseYAMLDebugMap(BinHolder, InputFile, PrependPath,
Verbose);
MachODebugMapParser Parser(BinHolder, InputFile, Archs, DSYMSearchPaths,
- PrependPath, VariantSuffix, Verbose);
+ PrependPath, VariantSuffix, Verbose,
+ AllowedDebugMapObjects);
return Parser.parse();
}
diff --git a/llvm/tools/dsymutil/Options.td b/llvm/tools/dsymutil/Options.td
index 5334aa0a747b1..6c4061bff8e77 100644
--- a/llvm/tools/dsymutil/Options.td
+++ b/llvm/tools/dsymutil/Options.td
@@ -229,6 +229,13 @@ def build_variant_suffix: Separate<["--", "-"], "build-variant-suffix">,
Group<grp_general>;
def: Joined<["--", "-"], "build-variant-suffix=">, Alias<build_variant_suffix>;
+def allowed_debug_map_objects: Separate<["--", "-"], "allowed-debug-map-objects">,
+ MetaVarName<"<path>">,
+ HelpText<"Only process debug map objects listed in <path> (one object path "
+ "per line; exact match; only filters N_OSO entries).">,
+ Group<grp_general>;
+def: Joined<["--", "-"], "allowed-debug-map-objects=">, Alias<allowed_debug_map_objects>;
+
def dsym_search_path: Separate<["-", "--"], "D">,
MetaVarName<"<path>">,
HelpText<"Specify a directory that contain dSYM files to search for.">,
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index ce55b7f6183e6..b5166d47b3f69 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
@@ -38,6 +39,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/LLVMDriver.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ThreadPool.h"
@@ -114,6 +116,7 @@ struct DsymutilOptions {
std::string OutputFile;
std::string Toolchain;
std::string ReproducerPath;
+ std::string AllowedDebugMapObjectsFile;
std::vector<std::string> Archs;
std::vector<std::string> InputFiles;
unsigned NumThreads;
@@ -200,6 +203,11 @@ static Error verifyOptions(const DsymutilOptions &Options) {
"cannot combine --gen-reproducer and --use-reproducer.",
errc::invalid_argument);
+ if (Options.InputIsYAMLDebugMap && !Options.AllowedDebugMapObjectsFile.empty())
+ return make_error<StringError>(
+ "-y and --allowed-debug-map-objects cannot be specified together",
+ errc::invalid_argument);
+
return Error::success();
}
@@ -402,6 +410,10 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
for (auto *SearchPath : Args.filtered(OPT_dsym_search_path))
Options.LinkOpts.DSYMSearchPaths.push_back(SearchPath->getValue());
+ if (opt::Arg *AllowedObjs =
+ Args.getLastArg(OPT_allowed_debug_map_objects))
+ Options.AllowedDebugMapObjectsFile = AllowedObjs->getValue();
+
if (Error E = verifyOptions(Options))
return std::move(E);
return Options;
@@ -688,10 +700,33 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
continue;
}
+ // Read the allowed debug map objects file if specified.
+ std::optional<StringSet<>> AllowedDebugMapObjects;
+ if (!Options.AllowedDebugMapObjectsFile.empty()) {
+ auto BufOrErr =
+ MemoryBuffer::getFile(Options.AllowedDebugMapObjectsFile);
+ if (!BufOrErr) {
+ WithColor::error() << "cannot open allowed debug map objects file '"
+ << Options.AllowedDebugMapObjectsFile
+ << "': " << BufOrErr.getError().message() << '\n';
+ return EXIT_FAILURE;
+ }
+ AllowedDebugMapObjects.emplace();
+ StringRef Content = (*BufOrErr)->getBuffer();
+ SmallVector<StringRef, 0> Lines;
+ Content.split(Lines, '\n');
+ for (StringRef Line : Lines) {
+ Line = Line.trim();
+ if (!Line.empty())
+ AllowedDebugMapObjects->insert(Line);
+ }
+ }
+
auto DebugMapPtrsOrErr = parseDebugMap(
BinHolder, InputFile, Options.Archs, Options.LinkOpts.DSYMSearchPaths,
Options.LinkOpts.PrependPath, Options.LinkOpts.BuildVariantSuffix,
- Options.LinkOpts.Verbose, Options.InputIsYAMLDebugMap);
+ Options.LinkOpts.Verbose, Options.InputIsYAMLDebugMap,
+ AllowedDebugMapObjects);
if (auto EC = DebugMapPtrsOrErr.getError()) {
WithColor::error() << "cannot parse the debug map for '" << InputFile
diff --git a/llvm/tools/dsymutil/dsymutil.h b/llvm/tools/dsymutil/dsymutil.h
index 7b97b8bcd3a25..04d2cf1a5954a 100644
--- a/llvm/tools/dsymutil/dsymutil.h
+++ b/llvm/tools/dsymutil/dsymutil.h
@@ -21,9 +21,11 @@
#include "LinkUtils.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorOr.h"
#include <memory>
+#include <optional>
#include <string>
#include <vector>
@@ -37,7 +39,9 @@ ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
parseDebugMap(BinaryHolder &BinHolder, StringRef InputFile,
ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
- StringRef VariantSuffix, bool Verbose, bool InputIsYAML);
+ StringRef VariantSuffix, bool Verbose, bool InputIsYAML,
+ const std::optional<StringSet<>> &AllowedDebugMapObjects =
+ std::nullopt);
/// Dump the symbol table.
bool dumpStab(BinaryHolder &BinHolder, StringRef InputFile,
>From 3665482582dc796433a474d8724d7a6fd749c087 Mon Sep 17 00:00:00 2001
From: Roy Shi <royshi at meta.com>
Date: Wed, 18 Feb 2026 10:25:14 -0800
Subject: [PATCH 2/5] Add missing files; do clang-format
---
.../AArch64/allowed-debug-map-objects.test | 59 +++++++++++++++++++
llvm/tools/dsymutil/MachODebugMapParser.cpp | 13 ++--
llvm/tools/dsymutil/dsymutil.cpp | 9 ++-
llvm/tools/dsymutil/dsymutil.h | 12 ++--
4 files changed, 74 insertions(+), 19 deletions(-)
create mode 100644 llvm/test/tools/dsymutil/AArch64/allowed-debug-map-objects.test
diff --git a/llvm/test/tools/dsymutil/AArch64/allowed-debug-map-objects.test b/llvm/test/tools/dsymutil/AArch64/allowed-debug-map-objects.test
new file mode 100644
index 0000000000000..58486f50b14dd
--- /dev/null
+++ b/llvm/test/tools/dsymutil/AArch64/allowed-debug-map-objects.test
@@ -0,0 +1,59 @@
+# Extract filenames from the debug map for use in allow-lists.
+RUN: dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
+RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 2>/dev/null \
+RUN: | grep 'filename:' | sed "s/.*filename:[[:space:]]*//" | tr -d "'" \
+RUN: > %t.all-objects
+
+# Build allow-lists from the extracted filenames.
+RUN: grep 'basic1' %t.all-objects > %t.allow-one
+RUN: grep -e 'basic1' -e 'basic3' %t.all-objects > %t.allow-two
+RUN: touch %t.allow-empty
+
+# Test filtering to a single object file.
+RUN: dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
+RUN: --allowed-debug-map-objects=%t.allow-one \
+RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 \
+RUN: | FileCheck %s --check-prefix=ALLOW-ONE
+
+# Test filtering to two object files.
+RUN: dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
+RUN: --allowed-debug-map-objects=%t.allow-two \
+RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 \
+RUN: | FileCheck %s --check-prefix=ALLOW-TWO
+
+# Test empty allow-list (allow nothing).
+RUN: dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
+RUN: --allowed-debug-map-objects=%t.allow-empty \
+RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 \
+RUN: | FileCheck %s --check-prefix=ALLOW-NONE
+
+# Test error when allow-list file does not exist.
+RUN: not dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
+RUN: --allowed-debug-map-objects=/nonexistent/path \
+RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 2>&1 \
+RUN: | FileCheck %s --check-prefix=MISSING-FILE
+
+# Test error when combined with -y.
+RUN: not dsymutil --allowed-debug-map-objects=%t.allow-one \
+RUN: -y %p/../Inputs/remarks/basic.macho.remarks.arm64 2>&1 \
+RUN: | FileCheck %s --check-prefix=YAML-CONFLICT
+
+ALLOW-ONE: ---
+ALLOW-ONE: filename:{{.*}}basic1.macho.remarks.arm64.o
+ALLOW-ONE-NOT: filename:
+ALLOW-ONE: ...
+
+ALLOW-TWO: ---
+ALLOW-TWO: filename:{{.*}}basic1.macho.remarks.arm64.o
+ALLOW-TWO-NOT: filename:{{.*}}basic2
+ALLOW-TWO: filename:{{.*}}basic3.macho.remarks.arm64.o
+ALLOW-TWO-NOT: filename:
+ALLOW-TWO: ...
+
+ALLOW-NONE: ---
+ALLOW-NONE-NOT: filename:
+ALLOW-NONE: ...
+
+MISSING-FILE: error: cannot open allowed debug map objects file
+
+YAML-CONFLICT: error: -y and --allowed-debug-map-objects cannot be specified together
diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp
index 1db0f12979f3a..b65db3789b7c4 100644
--- a/llvm/tools/dsymutil/MachODebugMapParser.cpp
+++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp
@@ -28,13 +28,12 @@ using namespace llvm::object;
class MachODebugMapParser {
public:
- MachODebugMapParser(BinaryHolder &BinHolder, StringRef BinaryPath,
- ArrayRef<std::string> Archs,
- ArrayRef<std::string> DSYMSearchPaths,
- StringRef PathPrefix = "", StringRef VariantSuffix = "",
- bool Verbose = false,
- const std::optional<StringSet<>>
- &AllowedDebugMapObjects = std::nullopt)
+ MachODebugMapParser(
+ BinaryHolder &BinHolder, StringRef BinaryPath,
+ ArrayRef<std::string> Archs, ArrayRef<std::string> DSYMSearchPaths,
+ StringRef PathPrefix = "", StringRef VariantSuffix = "",
+ bool Verbose = false,
+ const std::optional<StringSet<>> &AllowedDebugMapObjects = std::nullopt)
: BinaryPath(std::string(BinaryPath)), Archs(Archs),
DSYMSearchPaths(DSYMSearchPaths), PathPrefix(std::string(PathPrefix)),
VariantSuffix(std::string(VariantSuffix)), BinHolder(BinHolder),
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index b5166d47b3f69..df693cb0e6644 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -203,7 +203,8 @@ static Error verifyOptions(const DsymutilOptions &Options) {
"cannot combine --gen-reproducer and --use-reproducer.",
errc::invalid_argument);
- if (Options.InputIsYAMLDebugMap && !Options.AllowedDebugMapObjectsFile.empty())
+ if (Options.InputIsYAMLDebugMap &&
+ !Options.AllowedDebugMapObjectsFile.empty())
return make_error<StringError>(
"-y and --allowed-debug-map-objects cannot be specified together",
errc::invalid_argument);
@@ -410,8 +411,7 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
for (auto *SearchPath : Args.filtered(OPT_dsym_search_path))
Options.LinkOpts.DSYMSearchPaths.push_back(SearchPath->getValue());
- if (opt::Arg *AllowedObjs =
- Args.getLastArg(OPT_allowed_debug_map_objects))
+ if (opt::Arg *AllowedObjs = Args.getLastArg(OPT_allowed_debug_map_objects))
Options.AllowedDebugMapObjectsFile = AllowedObjs->getValue();
if (Error E = verifyOptions(Options))
@@ -703,8 +703,7 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
// Read the allowed debug map objects file if specified.
std::optional<StringSet<>> AllowedDebugMapObjects;
if (!Options.AllowedDebugMapObjectsFile.empty()) {
- auto BufOrErr =
- MemoryBuffer::getFile(Options.AllowedDebugMapObjectsFile);
+ auto BufOrErr = MemoryBuffer::getFile(Options.AllowedDebugMapObjectsFile);
if (!BufOrErr) {
WithColor::error() << "cannot open allowed debug map objects file '"
<< Options.AllowedDebugMapObjectsFile
diff --git a/llvm/tools/dsymutil/dsymutil.h b/llvm/tools/dsymutil/dsymutil.h
index 04d2cf1a5954a..12ada635f5131 100644
--- a/llvm/tools/dsymutil/dsymutil.h
+++ b/llvm/tools/dsymutil/dsymutil.h
@@ -35,13 +35,11 @@ namespace dsymutil {
/// Extract the DebugMaps from the given file.
/// 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(BinaryHolder &BinHolder, StringRef InputFile,
- ArrayRef<std::string> Archs,
- ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
- StringRef VariantSuffix, bool Verbose, bool InputIsYAML,
- const std::optional<StringSet<>> &AllowedDebugMapObjects =
- std::nullopt);
+ErrorOr<std::vector<std::unique_ptr<DebugMap>>> parseDebugMap(
+ BinaryHolder &BinHolder, StringRef InputFile, ArrayRef<std::string> Archs,
+ ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
+ StringRef VariantSuffix, bool Verbose, bool InputIsYAML,
+ const std::optional<StringSet<>> &AllowedDebugMapObjects = std::nullopt);
/// Dump the symbol table.
bool dumpStab(BinaryHolder &BinHolder, StringRef InputFile,
>From d442fafb3a1bd7e1ff2ed7b3d053991f09ab0e67 Mon Sep 17 00:00:00 2001
From: Roy Shi <royshi at meta.com>
Date: Mon, 23 Feb 2026 13:43:15 -0800
Subject: [PATCH 3/5] Update according to Jonas comment
---
llvm/docs/CommandGuide/dsymutil.rst | 13 ++-
.../dsymutil/AArch64/allow-disallow.test | 98 ++++++++++++++++
.../AArch64/allowed-debug-map-objects.test | 59 ----------
.../Inputs/allow-disallow/a.out.arm64 | Bin 0 -> 17496 bytes
.../dsymutil/Inputs/allow-disallow/empty.yaml | 2 +
.../dsymutil/Inputs/allow-disallow/one.yaml | 3 +
.../dsymutil/Inputs/allow-disallow/two.yaml | 4 +
.../Inputs/private/tmp/allow-disallow/1.o | Bin 0 -> 1752 bytes
.../Inputs/private/tmp/allow-disallow/2.o | Bin 0 -> 1752 bytes
.../Inputs/private/tmp/allow-disallow/3.o | Bin 0 -> 1792 bytes
llvm/test/tools/dsymutil/cmdline.test | 7 +-
llvm/tools/dsymutil/MachODebugMapParser.cpp | 27 +++--
llvm/tools/dsymutil/Options.td | 19 +++-
llvm/tools/dsymutil/dsymutil.cpp | 107 ++++++++++++++----
llvm/tools/dsymutil/dsymutil.h | 3 +-
15 files changed, 240 insertions(+), 102 deletions(-)
create mode 100644 llvm/test/tools/dsymutil/AArch64/allow-disallow.test
delete mode 100644 llvm/test/tools/dsymutil/AArch64/allowed-debug-map-objects.test
create mode 100755 llvm/test/tools/dsymutil/Inputs/allow-disallow/a.out.arm64
create mode 100644 llvm/test/tools/dsymutil/Inputs/allow-disallow/empty.yaml
create mode 100644 llvm/test/tools/dsymutil/Inputs/allow-disallow/one.yaml
create mode 100644 llvm/test/tools/dsymutil/Inputs/allow-disallow/two.yaml
create mode 100644 llvm/test/tools/dsymutil/Inputs/private/tmp/allow-disallow/1.o
create mode 100644 llvm/test/tools/dsymutil/Inputs/private/tmp/allow-disallow/2.o
create mode 100644 llvm/test/tools/dsymutil/Inputs/private/tmp/allow-disallow/3.o
diff --git a/llvm/docs/CommandGuide/dsymutil.rst b/llvm/docs/CommandGuide/dsymutil.rst
index 5457d3b785ad4..c40cd18f32d19 100644
--- a/llvm/docs/CommandGuide/dsymutil.rst
+++ b/llvm/docs/CommandGuide/dsymutil.rst
@@ -23,10 +23,11 @@ OPTIONS
Specify the desired type of accelerator table. Valid options are 'Apple',
'Dwarf', 'Default' and 'None'.
-.. option:: --allowed-debug-map-objects <path>
+.. option:: --allow <path>
- Only process debug map objects listed in <path> (one object path per line;
- exact match; only filters N_OSO entries).
+ Only process debug map objects listed in the YAML file at <path>. Only filters
+ N_OSO entries. If `--oso-prepend-path` is specified, the path prefix applies,
+ i.e. paths in the file should exact match that of N_OSO entries.
.. option:: --arch <arch>
@@ -45,6 +46,12 @@ OPTIONS
'profile'. Setting the DYLD_IMAGE_SUFFIX environment variable will
cause dyld to load the specified variant at runtime.
+.. option:: --disallow <path>
+
+ Exclude debug map objects listed in the YAML file at <path>. Only filters
+ N_OSO entries. If `--oso-prepend-path` is specified, the path prefix applies,
+ i.e. paths in the file should exact match that of N_OSO entries.
+
.. option:: --dump-debug-map
Dump the *executable*'s debug-map (the list of the object files containing the
diff --git a/llvm/test/tools/dsymutil/AArch64/allow-disallow.test b/llvm/test/tools/dsymutil/AArch64/allow-disallow.test
new file mode 100644
index 0000000000000..976e7e79a60ea
--- /dev/null
+++ b/llvm/test/tools/dsymutil/AArch64/allow-disallow.test
@@ -0,0 +1,98 @@
+# Test --allow to include one object file (1.o).
+RUN: dsymutil --dump-debug-map \
+RUN: %p/../Inputs/allow-disallow/a.out.arm64 \
+RUN: --oso-prepend-path=%p/../Inputs \
+RUN: --allow=%p/../Inputs/allow-disallow/one.yaml \
+RUN: | FileCheck %s --check-prefix=ALLOW-ONE
+
+# Test --allow to include two object files (1.o and 3.o).
+RUN: dsymutil --dump-debug-map \
+RUN: %p/../Inputs/allow-disallow/a.out.arm64 \
+RUN: --oso-prepend-path=%p/../Inputs \
+RUN: --allow=%p/../Inputs/allow-disallow/two.yaml \
+RUN: | FileCheck %s --check-prefix=ALLOW-TWO
+
+# Test --allow to include no object files (empty allow list).
+RUN: dsymutil --dump-debug-map \
+RUN: %p/../Inputs/allow-disallow/a.out.arm64 \
+RUN: --oso-prepend-path=%p/../Inputs \
+RUN: --allow=%p/../Inputs/allow-disallow/empty.yaml \
+RUN: | FileCheck %s --check-prefix=ALLOW-NONE
+
+# Test --disallow to exclude one object file (1.o).
+RUN: dsymutil --dump-debug-map \
+RUN: %p/../Inputs/allow-disallow/a.out.arm64 \
+RUN: --oso-prepend-path=%p/../Inputs \
+RUN: --disallow=%p/../Inputs/allow-disallow/one.yaml \
+RUN: | FileCheck %s --check-prefix=DISALLOW-ONE
+
+# Test --disallow to exclude two object files (1.o and 3.o).
+RUN: dsymutil --dump-debug-map \
+RUN: %p/../Inputs/allow-disallow/a.out.arm64 \
+RUN: --oso-prepend-path=%p/../Inputs \
+RUN: --disallow=%p/../Inputs/allow-disallow/two.yaml \
+RUN: | FileCheck %s --check-prefix=DISALLOW-TWO
+
+# Test --disallow to exclude no object files (empty allow list).
+RUN: dsymutil --dump-debug-map \
+RUN: %p/../Inputs/allow-disallow/a.out.arm64 \
+RUN: --oso-prepend-path=%p/../Inputs \
+RUN: --disallow=%p/../Inputs/allow-disallow/empty.yaml \
+RUN: | FileCheck %s --check-prefix=DISALLOW-NONE
+
+# Test error when allow-list file does not exist.
+RUN: not dsymutil --dump-debug-map \
+RUN: %p/../Inputs/allow-disallow/a.out.arm64 \
+RUN: --allow=/nonexistent/path 2>&1 \
+RUN: | FileCheck %s --check-prefix=MISSING-FILE
+
+# Test error when disallow-list file does not exist.
+RUN: not dsymutil --dump-debug-map \
+RUN: %p/../Inputs/allow-disallow/a.out.arm64 \
+RUN: --disallow=/nonexistent/path 2>&1 \
+RUN: | FileCheck %s --check-prefix=MISSING-FILE
+
+# Test error when combined with -y.
+RUN: not dsymutil --allow=%t.allow-one.yaml \
+RUN: -y %p/../Inputs/remarks/basic.macho.remarks.arm64 2>&1 \
+RUN: | FileCheck %s --check-prefix=YAML-CONFLICT
+
+ALLOW-ONE: ---
+ALLOW-ONE: filename: {{.*}}1.o
+ALLOW-ONE-NOT: filename:
+ALLOW-ONE: ...
+
+ALLOW-TWO: ---
+ALLOW-TWO: filename: {{.*}}1.o
+ALLOW-TWO-NOT: filename: {{.*}}2.o
+ALLOW-TWO: filename: {{.*}}3.o
+ALLOW-TWO-NOT: filename:
+ALLOW-TWO: ...
+
+ALLOW-NONE: ---
+ALLOW-NONE-NOT: filename:
+ALLOW-NONE: ...
+
+DISALLOW-ONE: ---
+DISALLOW-ONE-NOT: filename: {{.*}}1.o
+DISALLOW-ONE: filename: {{.*}}2.o
+DISALLOW-ONE: filename: {{.*}}3.o
+DISALLOW-ONE-NOT: filename:
+DISALLOW-ONE: ...
+
+DISALLOW-TWO: ---
+DISALLOW-TWO-NOT: filename: {{.*}}1.o
+DISALLOW-TWO: filename: {{.*}}2.o
+DISALLOW-TWO-NOT: filename: {{.*}}3.o
+DISALLOW-TWO-NOT: filename:
+DISALLOW-TWO: ...
+
+DISALLOW-NONE: ---
+DISALLOW-NONE: filename: {{.*}}1.o
+DISALLOW-NONE: filename: {{.*}}2.o
+DISALLOW-NONE: filename: {{.*}}3.o
+DISALLOW-NONE: ...
+
+MISSING-FILE: error: cannot open allow/disallow file
+
+YAML-CONFLICT: error: -y and --allow/--disallow cannot be specified together
diff --git a/llvm/test/tools/dsymutil/AArch64/allowed-debug-map-objects.test b/llvm/test/tools/dsymutil/AArch64/allowed-debug-map-objects.test
deleted file mode 100644
index 58486f50b14dd..0000000000000
--- a/llvm/test/tools/dsymutil/AArch64/allowed-debug-map-objects.test
+++ /dev/null
@@ -1,59 +0,0 @@
-# Extract filenames from the debug map for use in allow-lists.
-RUN: dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
-RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 2>/dev/null \
-RUN: | grep 'filename:' | sed "s/.*filename:[[:space:]]*//" | tr -d "'" \
-RUN: > %t.all-objects
-
-# Build allow-lists from the extracted filenames.
-RUN: grep 'basic1' %t.all-objects > %t.allow-one
-RUN: grep -e 'basic1' -e 'basic3' %t.all-objects > %t.allow-two
-RUN: touch %t.allow-empty
-
-# Test filtering to a single object file.
-RUN: dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
-RUN: --allowed-debug-map-objects=%t.allow-one \
-RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 \
-RUN: | FileCheck %s --check-prefix=ALLOW-ONE
-
-# Test filtering to two object files.
-RUN: dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
-RUN: --allowed-debug-map-objects=%t.allow-two \
-RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 \
-RUN: | FileCheck %s --check-prefix=ALLOW-TWO
-
-# Test empty allow-list (allow nothing).
-RUN: dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
-RUN: --allowed-debug-map-objects=%t.allow-empty \
-RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 \
-RUN: | FileCheck %s --check-prefix=ALLOW-NONE
-
-# Test error when allow-list file does not exist.
-RUN: not dsymutil --dump-debug-map --oso-prepend-path=%p/../Inputs \
-RUN: --allowed-debug-map-objects=/nonexistent/path \
-RUN: %p/../Inputs/remarks/basic.macho.remarks.arm64 2>&1 \
-RUN: | FileCheck %s --check-prefix=MISSING-FILE
-
-# Test error when combined with -y.
-RUN: not dsymutil --allowed-debug-map-objects=%t.allow-one \
-RUN: -y %p/../Inputs/remarks/basic.macho.remarks.arm64 2>&1 \
-RUN: | FileCheck %s --check-prefix=YAML-CONFLICT
-
-ALLOW-ONE: ---
-ALLOW-ONE: filename:{{.*}}basic1.macho.remarks.arm64.o
-ALLOW-ONE-NOT: filename:
-ALLOW-ONE: ...
-
-ALLOW-TWO: ---
-ALLOW-TWO: filename:{{.*}}basic1.macho.remarks.arm64.o
-ALLOW-TWO-NOT: filename:{{.*}}basic2
-ALLOW-TWO: filename:{{.*}}basic3.macho.remarks.arm64.o
-ALLOW-TWO-NOT: filename:
-ALLOW-TWO: ...
-
-ALLOW-NONE: ---
-ALLOW-NONE-NOT: filename:
-ALLOW-NONE: ...
-
-MISSING-FILE: error: cannot open allowed debug map objects file
-
-YAML-CONFLICT: error: -y and --allowed-debug-map-objects cannot be specified together
diff --git a/llvm/test/tools/dsymutil/Inputs/allow-disallow/a.out.arm64 b/llvm/test/tools/dsymutil/Inputs/allow-disallow/a.out.arm64
new file mode 100755
index 0000000000000000000000000000000000000000..c321e003b722d33da72474f82b5e66fa3e7ab6b9
GIT binary patch
literal 17496
zcmeI4U1(HS5XUE*H7bUr)s$+~cBN@)jqY}{f<Y|3HEvauM6BQvs3)83O|zI}<7N{-
z2s8+SZJ at LW;zKFL7hh}(QYob$>_hRz&p<!04<Utuw%R`RrBY1)|8wtc?#8IlJ{4wQ
z&bc#l=FFVmp4YS2?*4YKR-{TG5$NO4<<%m`C5A7N70~TaV|Kr?E!~;k(?M^g*yKvr
zeHQn*1vO at GI<vPjZ1bH;pZN9yxT)-oVob?BT=Kp>yK=uS^v?ZO`AcXAxz-hxaX(}y
zV at 3uK<p*;nKiFG<XKsIE{(fD4677ope19;_^4hhdeP?>>j^M104;ix+f6hcblRbwy
zZV(xNj3Gy)6;sN$TVd~p%^sFR--W#zbJrG;Y0OKYj8oVPl_j|5-$)&jVo=->NsJ5^
z6aD$_MD9p`4mM>alzmJsJ%48GVEa>_Or at T^lH2%Q3w$xCccw-(+-Sdn56-L6wV3Sr
zXhWXI`M6J?U0_{yVBHs?j9Kn&*B5fve|kYbJ<ZMWWE at T9yKSGX;q|f$*Qav*Ye$Al
z?m&EtpMupQ&q3MG2}fiR<`;aMd at 1C|xYLGS!ao#)50P at U`JOt{CX+bgo|$_29N+KJ
z$8Cap8lHJh-dhJVm3NNf*l~8CyH+C70HvUBZW%$Np2K=|Py$Lo2`B+2pahhF5>Nt4
zKnW-TC7=Y9fD%vwN<axH0VSXWlz<XY0!ly$C;=s)1eAahPy$Lo2`B+2pahhF5>Nt4
zKnW-TC7=Y9fD%vwN<axH0VSXWlz<XY0!rZjL?DJ{`No<`2|sW4pB{UG at K|N!W!lv;
zU4!B08azDCj>_WhQK_ at 9k0YH)SvJsT+{13qNXa#QZZ_u at Wp%aO;#wnX2D14<+2n0H
zT@$r0;aNKuYJl&=gSX~f$(mt14Z9Z|-}veMJmXA_W8nK~ezTRPkWF6`)E2``yM0bP
zT;D}JT<_={dmQ$B^>cpx#fY<hU_YpSI3BM5A at alZFU+yOfIVM*zM~Inv3_6&z6Rt`
zX!HExc(^|K)gvD8<auZZ{qjwGeHF*qdW;AA#qf^`ok?5_PPiM!+<zsEy$FfYz)&LF
z-(NViK9?W19|=judxnN2F;vWtW=rmTOOo+|%;%SuN2azsC^hxS)D%*!+?}c|<K#>I
z<I~pwAF<t&2yR)#UcvpaGYmrTe*|q#EMotv!1FwO4E`FRDjP41l;q>4`h^pB&ed&N
zQ~cIhv90;-%`csJ;<HnKzH|A~<v0E~aPy-#&z;W{F8<P6j{Yz?c_7k}Suiv9>DbZZ
zKYlf_{jGIp|7-mB+uxjd`qhbFKY0CY<LPHk788HnE<c(2dSA!-@|7<ekCnZ{{0(r<
BEQ|mE
literal 0
HcmV?d00001
diff --git a/llvm/test/tools/dsymutil/Inputs/allow-disallow/empty.yaml b/llvm/test/tools/dsymutil/Inputs/allow-disallow/empty.yaml
new file mode 100644
index 0000000000000..013bc460dee1c
--- /dev/null
+++ b/llvm/test/tools/dsymutil/Inputs/allow-disallow/empty.yaml
@@ -0,0 +1,2 @@
+objects:
+...
diff --git a/llvm/test/tools/dsymutil/Inputs/allow-disallow/one.yaml b/llvm/test/tools/dsymutil/Inputs/allow-disallow/one.yaml
new file mode 100644
index 0000000000000..177c16828b87a
--- /dev/null
+++ b/llvm/test/tools/dsymutil/Inputs/allow-disallow/one.yaml
@@ -0,0 +1,3 @@
+objects:
+ - filename: '/private/tmp/allow-disallow/1.o'
+...
diff --git a/llvm/test/tools/dsymutil/Inputs/allow-disallow/two.yaml b/llvm/test/tools/dsymutil/Inputs/allow-disallow/two.yaml
new file mode 100644
index 0000000000000..e464ced4d0dd9
--- /dev/null
+++ b/llvm/test/tools/dsymutil/Inputs/allow-disallow/two.yaml
@@ -0,0 +1,4 @@
+objects:
+ - filename: '/private/tmp/allow-disallow/1.o'
+ - filename: '/private/tmp/allow-disallow/3.o'
+...
diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/allow-disallow/1.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/allow-disallow/1.o
new file mode 100644
index 0000000000000000000000000000000000000000..4451a6ddc1518818d4e3b7818774c886a6eef0cd
GIT binary patch
literal 1752
zcma)6Jxmlq6rS1pkv|U*6F?F<6E{&4cJEH*5-b!rY&aqc>OnKvyWN8gd%K(4<)AQu
zSXmM)dlO3=6B{kiXk%k%Ol<75F}D7N_}=X7!EHeAC2!u(y!Xw{dvEsruWx%jgir#6
zOC0!X43;!7&@k{S+DFiu6l`>0B2Z`_10A^woj{EF#-<<WfxS3WTHLooO~4Su6VSm{
zoNR|NC>hg@^7;zX%H_JzK)Y~v^49fcNQg5oJUyYK8PN(K;+b~U!H_84gviSYIn^ef
z=hvB2t$I;BOW>Rp(r+J+XGHOK1kO7lAGL|6>3SVgqIk=EA_(adc;!T(Y$nC9MA{S9
z&(>;&cL<&(@Kyz$4|py8jhKv8oSLgue70_Hn6}PXu^>{p_$ctw!uc8Sa7?%V^L>_S
z8<-Nk?+<~uB=88}AU$XUk71J|^LJBR?o<FnmIR(KQM6ni=V}Nz_zcLBf=moT{|@Bi
z{dPg3-3>esjD#`BnEQ{X3cE+sZj61P{Zy6*5;6JyJ^A~VTp#Qk9FhA+P9(iSI6xt&
ze%TtnHe|~&d7}GD_f`BmD8LCqI}n?aGlWVpu7erpzZ0}1u2CnEgqSoq#5nQnOJF|+
zehT~s_%-mP>sm&-VrlkDx?$8k)3MXpypmBe>2usWmd$4}%D8e-$(<)zrQ*6o#U!($
z`4H@>rHZ2)EH|#?lnl$}r!VJNwXA5at4=$%Z`i)47L0~rIj&Jx=Pk{zI`x{T&S{k!
z3nj%Bjsr0Zh1uq|r>_waiK^<?Tvf9yXJbq^J+2Uqu;r}QAn<pE+lD0pgXr87_8L9=
zJ?sP>V~fQ*a~ZfH?upSP$>$Pz^66&^>w|Sd!m*-CY#@%Upfb9G6}1Bt4|E)p7P<`<
zeqA0UrSx~|I0`%w7?e?dc#Mupy@}KGB<8*-{xWCwN-rP2efFns>cXoyNzg9R*@PaD
z;*fb*NrE;Z2EQXf^H+g#7JMjEAXEHIj0)mXP>}Gw<5us1eR#;c$`*7WOK{~SBYy$U
C-_ynb
literal 0
HcmV?d00001
diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/allow-disallow/2.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/allow-disallow/2.o
new file mode 100644
index 0000000000000000000000000000000000000000..afc80bc9139121a239eff2f0e0a97a11a57afc79
GIT binary patch
literal 1752
zcma)6O=#3W6rS15_TTNF(AI*DU_cK|c315}6|{Eir7c!lwJpeyO|tFMY!Wx=wueHC
zCy%`ddiE+FJr at xKLBxv)9`vRc@#r6j?@cD#Zm_x!-n^fA?@Q*rH}m at Em)~84Py&RD
z1pGM(iwq1j1iXs&A+(kVH`*`}D6(5YNA5r;5MzP08H9RhFH9{i?AwthU<l#~=x|FS
zJ5dZu#!RcYzQXikv1--OF5H^9ex)7~;fx7SSLCQiG{Q%CWvAp~NE~lm<mH6C+$5eK
zRGC{U`Efj3;G7gPXdaJe#PN0o&PyR5G>NC1W))N7c*}eu2<Z`c#Z;(lwuoVgwI`~d
zqgO2dFL<`VTNQW#;5GC&W-?~D6;C$;w(e|{9h0${f=K1!oxqcY^CRHlnC|@N|Ln43
zVM_eG-v!>1z$1Wzbgv0KhE0ym-!*Z#V<8M#5_rNy(Qtg6t3lxKHy|q!W?~TfcOf6o
zw+9mKPT)CUB#c4E+<#nE*gc%~lI$(*rHay at N-B4^l&{-Lb)aWpSm_<^Yw-u*11drF
z)ArD%K}Sg{<DKU_FXHQ<0;dRVLu^V;5SmDG9ZZQoCuk+OM%`2k#K_<f<HWPig8c~i
z3Gj2^XTTGlXIrvi>&}W?v#NgCb>wVb&8Qjq6!(s1^O=k~rk+uAr%6sVJdbFYR5tVg
zf_-h#a7~Nl#?+jeVcGoTxg0AMRo(NnN!JN1C-Aj`RkLi at v#Q#htp_EyTJg16-MBix
zsCvS2AZETWUElW2H6kKW)q;wr>9*}|jGASiE2K!+a<*6_ at VdfjqmqC@Ozw$#jh_7;
zwu6qbGcz}5GjKxOL&Dy+K24Ap?|-DRK3FFt94o3O`z34zRnQf#s2w0F)NxE2=muE$
zcX^PM(qHK#DDZ2*pp2kOl5`}|ojOjBqVX_&;m!TqTOayfeXE&wrXEWqMLS4)9lAdu
zLFV5|61E93_!$A3-wKq|;6s at PndaZbs4y-K1&QuEZgn5nhl|XsY(odK1lO=+e*j`T
B()<7b
literal 0
HcmV?d00001
diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/allow-disallow/3.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/allow-disallow/3.o
new file mode 100644
index 0000000000000000000000000000000000000000..4ab34d0dde819de41a20cf4850d97d263628eef7
GIT binary patch
literal 1792
zcma)7O=uHQ5T4ylYHaMERoYsy5xP(h-E30Zpn_T&#cGSCt!+W&u}L;Hy4hW_+aIvf
zq6nTu4~lpaya+-O58~fJym;^+3VQTvFXCOnI<xx{+ojbE%$uJ#^S$@x&D;I(^ZV~@
z00JP<5JFy&aEKuzwIN?1dlR}N`V$dKL at L``P$#Y>ClX_>KJWUvZ;v0F8vkpTwH;g`
zJPz%9La<bhA<0-y&&*6SEt4tfvt*|y`$vygLdrP(+_RhSuM!Y|FXI)=yhSlVyfZxU
z0GH>h#B<ydv+{W-h<B6YbaHvOdOR;9i1(D^yyx;|m3Ue%SE7_4-W9JS02(>o^{}rz
zsNv1BN&QT%s5=|r-QsvQ$GeAk>+UyTGM2T9ww86-j5${@bBqn8d8#jXa*R78xG!qc
zNB`NMQ80B%37$8`@y>F*F2o^vQUxBPOAhqkWsbMYhk<JxkDDac9Y2YVR%E|Sm?ip|
z6h!{#m`~?hK}mKLc?6k=Vu&gCA5Rr$H>cGB_z18xy4nCQP`~{~Vqb(NL6)1tl6-YR
z{;?>RS{hs0<)-%SHBJjIr~s+o7Tb=tO7g+zq3B at q5&T+6ogm4Fqfy#mFLD@!2rVnX
zUJyjd)6on8y->15PZO*#g!ZE;)r3P3LxndSD5%rKL*!-Tx5)31`)%9MV_8Epr(?5v
z$thT7ERj-FMU8cN-tI(7Rh2%aM at jC39wlqr5T~R<R&z1fiBDy%oX(PcN>Wi-A~n#P
zWciGu*>-%uGF{ztop at TG)eXzmOYspybMscI=){M$?CG&7#paGRF=Oddm1!q;33w!_
zakps4HN&vxx^o4`Q=q67OemNx;0G9wTP_V60EXu(_k-uE+;bC}6g)IEF|6VlX_h}P
zP?v5*FD~9+pbAl?h^Y01PN_MB*CQ&v1c7P_qD<o&qFcd7PwljhCeflTrcerk at T<O#
z1g(mUN{6=rN$3z8!g~Y{B|IdaoPYdzaANtZdhYeJPxwXJTEX2JmTIG~#0chYR2u)f
u5S`A6(BA7Id4k(@DC at m7Q9+`AO+5wk6=<qq%{(x#+6G=j0%-KA2Ji>eBHN<?
literal 0
HcmV?d00001
diff --git a/llvm/test/tools/dsymutil/cmdline.test b/llvm/test/tools/dsymutil/cmdline.test
index 524a70efa25b1..7b815f6ef232c 100644
--- a/llvm/test/tools/dsymutil/cmdline.test
+++ b/llvm/test/tools/dsymutil/cmdline.test
@@ -6,9 +6,10 @@ HELP: USAGE: {{.*}}dsymutil{{[^ ]*}} [options] <input files>
HELP-NOT: -reverse-iterate
HELP: Dsymutil Options:
CHECK: -accelerator
-CHECK: -allowed-debug-map-objects <path>
+CHECK: -allow <path>
CHECK: -arch <arch>
CHECK: -build-variant-suffix <suffix=buildvariant>
+CHECK: -disallow <path>
CHECK: -dump-debug-map
CHECK: -D <path>
CHECK: -fat64
@@ -54,5 +55,5 @@ BOGUS: warning: ignoring unknown option: -bogus
RUN: not dsymutil --quiet --verbose 2>&1 | FileCheck --check-prefix=CONFLICT %s
CONFLICT: error: --quiet and --verbose cannot be specified together
-RUN: not dsymutil -y file1 --allowed-debug-map-objects file2 2>&1 | FileCheck --check-prefix=CONFLICT2 %s
-CONFLICT2: error: -y and --allowed-debug-map-objects cannot be specified together
+RUN: not dsymutil -y file1 --allow file2 2>&1 | FileCheck --check-prefix=CONFLICT2 %s
+CONFLICT2: error: -y and --allow/--disallow cannot be specified together
diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp
index b65db3789b7c4..144f533deb32c 100644
--- a/llvm/tools/dsymutil/MachODebugMapParser.cpp
+++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp
@@ -33,12 +33,13 @@ class MachODebugMapParser {
ArrayRef<std::string> Archs, ArrayRef<std::string> DSYMSearchPaths,
StringRef PathPrefix = "", StringRef VariantSuffix = "",
bool Verbose = false,
- const std::optional<StringSet<>> &AllowedDebugMapObjects = std::nullopt)
+ const std::optional<StringSet<>> &AllowedObjects = std::nullopt,
+ const std::optional<StringSet<>> &DisallowedObjects = std::nullopt)
: BinaryPath(std::string(BinaryPath)), Archs(Archs),
DSYMSearchPaths(DSYMSearchPaths), PathPrefix(std::string(PathPrefix)),
VariantSuffix(std::string(VariantSuffix)), BinHolder(BinHolder),
CurrentDebugMapObject(nullptr), SkipDebugMapObject(false),
- AllowedDebugMapObjects(AllowedDebugMapObjects) {}
+ AllowedObjects(AllowedObjects), DisallowedObjects(DisallowedObjects) {}
/// Parses and returns the DebugMaps of the input binary. The binary contains
/// multiple maps in case it is a universal binary.
@@ -85,7 +86,11 @@ class MachODebugMapParser {
/// Optional set of allowed debug map object paths. If set, only objects
/// whose path is in this set will be included.
- const std::optional<StringSet<>> &AllowedDebugMapObjects;
+ const std::optional<StringSet<>> &AllowedObjects;
+
+ /// Optional set of disallowed debug map object paths. If set, objects
+ /// whose path is in this set will be excluded.
+ const std::optional<StringSet<>> &DisallowedObjects;
/// Holds function info while function scope processing.
const char *CurrentFunctionName;
@@ -127,11 +132,14 @@ class MachODebugMapParser {
void addCommonSymbols();
- /// Check if a debug map object should be included based on the allowed list.
+ /// Check if a debug map object should be included based on the
+ /// allow/disallow lists.
bool shouldIncludeObject(StringRef Path) const {
- if (!AllowedDebugMapObjects.has_value())
- return true;
- return AllowedDebugMapObjects->contains(Path);
+ if (AllowedObjects.has_value() && !AllowedObjects->contains(Path))
+ return false;
+ if (DisallowedObjects.has_value() && DisallowedObjects->contains(Path))
+ return false;
+ return true;
}
/// Dump the symbol table output header.
@@ -877,14 +885,15 @@ parseDebugMap(BinaryHolder &BinHolder, StringRef InputFile,
ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
StringRef VariantSuffix, bool Verbose, bool InputIsYAML,
- const std::optional<StringSet<>> &AllowedDebugMapObjects) {
+ const std::optional<StringSet<>> &AllowedObjects,
+ const std::optional<StringSet<>> &DisallowedObjects) {
if (InputIsYAML)
return DebugMap::parseYAMLDebugMap(BinHolder, InputFile, PrependPath,
Verbose);
MachODebugMapParser Parser(BinHolder, InputFile, Archs, DSYMSearchPaths,
PrependPath, VariantSuffix, Verbose,
- AllowedDebugMapObjects);
+ AllowedObjects, DisallowedObjects);
return Parser.parse();
}
diff --git a/llvm/tools/dsymutil/Options.td b/llvm/tools/dsymutil/Options.td
index 6c4061bff8e77..9b262660fe99a 100644
--- a/llvm/tools/dsymutil/Options.td
+++ b/llvm/tools/dsymutil/Options.td
@@ -229,12 +229,23 @@ def build_variant_suffix: Separate<["--", "-"], "build-variant-suffix">,
Group<grp_general>;
def: Joined<["--", "-"], "build-variant-suffix=">, Alias<build_variant_suffix>;
-def allowed_debug_map_objects: Separate<["--", "-"], "allowed-debug-map-objects">,
+def allow: Separate<["--", "-"], "allow">,
MetaVarName<"<path>">,
- HelpText<"Only process debug map objects listed in <path> (one object path "
- "per line; exact match; only filters N_OSO entries).">,
+ HelpText<"Only process debug map objects listed in the YAML file at <path>. "
+ "Only filters N_OSO entries. If `--oso-prepend-path` is specified, the path "
+ "prefix applies, i.e. paths in the file should exact match that of N_OSO "
+ "entries.">,
Group<grp_general>;
-def: Joined<["--", "-"], "allowed-debug-map-objects=">, Alias<allowed_debug_map_objects>;
+def: Joined<["--", "-"], "allow=">, Alias<allow>;
+
+def disallow: Separate<["--", "-"], "disallow">,
+ MetaVarName<"<path>">,
+ HelpText<"Exclude debug map objects listed in the YAML file at <path>. "
+ "Only filters N_OSO entries. If `--oso-prepend-path` is specified, the path "
+ "prefix applies, i.e. paths in the file should exact match that of N_OSO "
+ "entries.">,
+ Group<grp_general>;
+def: Joined<["--", "-"], "disallow=">, Alias<disallow>;
def dsym_search_path: Separate<["-", "--"], "D">,
MetaVarName<"<path>">,
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index df693cb0e6644..99f326cbd7c9f 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -44,6 +44,7 @@
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/WithColor.h"
+#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/thread.h"
#include "llvm/TargetParser/Triple.h"
@@ -58,6 +59,33 @@ using namespace llvm::dsymutil;
using namespace object;
using namespace llvm::dwarf_linker;
+/// YAML structure for --allow / --disallow object list files.
+struct ObjectFileEntry {
+ std::string Filename;
+};
+
+struct ObjectFileList {
+ std::vector<ObjectFileEntry> Objects;
+};
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(ObjectFileEntry)
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<ObjectFileEntry> {
+ static void mapping(IO &IO, ObjectFileEntry &Entry) {
+ IO.mapRequired("filename", Entry.Filename);
+ }
+};
+
+template <> struct MappingTraits<ObjectFileList> {
+ static void mapping(IO &IO, ObjectFileList &List) {
+ IO.mapOptional("objects", List.Objects);
+ }
+};
+} // namespace yaml
+} // namespace llvm
+
namespace {
enum ID {
OPT_INVALID = 0, // This is not an option ID.
@@ -116,7 +144,8 @@ struct DsymutilOptions {
std::string OutputFile;
std::string Toolchain;
std::string ReproducerPath;
- std::string AllowedDebugMapObjectsFile;
+ std::string AllowFile;
+ std::string DisallowFile;
std::vector<std::string> Archs;
std::vector<std::string> InputFiles;
unsigned NumThreads;
@@ -204,9 +233,9 @@ static Error verifyOptions(const DsymutilOptions &Options) {
errc::invalid_argument);
if (Options.InputIsYAMLDebugMap &&
- !Options.AllowedDebugMapObjectsFile.empty())
+ (!Options.AllowFile.empty() || !Options.DisallowFile.empty()))
return make_error<StringError>(
- "-y and --allowed-debug-map-objects cannot be specified together",
+ "-y and --allow/--disallow cannot be specified together",
errc::invalid_argument);
return Error::success();
@@ -411,8 +440,11 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
for (auto *SearchPath : Args.filtered(OPT_dsym_search_path))
Options.LinkOpts.DSYMSearchPaths.push_back(SearchPath->getValue());
- if (opt::Arg *AllowedObjs = Args.getLastArg(OPT_allowed_debug_map_objects))
- Options.AllowedDebugMapObjectsFile = AllowedObjs->getValue();
+ if (opt::Arg *AllowArg = Args.getLastArg(OPT_allow))
+ Options.AllowFile = AllowArg->getValue();
+
+ if (opt::Arg *DisallowArg = Args.getLastArg(OPT_disallow))
+ Options.DisallowFile = DisallowArg->getValue();
if (Error E = verifyOptions(Options))
return std::move(E);
@@ -700,32 +732,61 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
continue;
}
- // Read the allowed debug map objects file if specified.
- std::optional<StringSet<>> AllowedDebugMapObjects;
- if (!Options.AllowedDebugMapObjectsFile.empty()) {
- auto BufOrErr = MemoryBuffer::getFile(Options.AllowedDebugMapObjectsFile);
- if (!BufOrErr) {
- WithColor::error() << "cannot open allowed debug map objects file '"
- << Options.AllowedDebugMapObjectsFile
- << "': " << BufOrErr.getError().message() << '\n';
+ // Parse allow/disallow object list YAML files if specified.
+ std::optional<StringSet<>> AllowedObjects;
+ std::optional<StringSet<>> DisallowedObjects;
+
+ auto ParseAllowDisallowFile =
+ [&](const std::string &FilePath) -> Expected<StringSet<>> {
+ auto BufOrErr = MemoryBuffer::getFile(FilePath);
+ if (!BufOrErr)
+ return make_error<StringError>(
+ Twine("cannot open allow/disallow file '") + FilePath +
+ "': " + BufOrErr.getError().message(),
+ BufOrErr.getError());
+
+ StringSet<> Result;
+ StringRef Content = (*BufOrErr)->getBuffer();
+ if (!Content.trim().empty()) {
+ yaml::Input YAMLIn(Content);
+ ObjectFileList ObjList;
+ YAMLIn >> ObjList;
+ if (YAMLIn.error())
+ return make_error<StringError>(
+ Twine("cannot parse allow/disallow file '") + FilePath + "'",
+ YAMLIn.error());
+ for (const auto &Entry : ObjList.Objects) {
+ SmallString<80> Path(Options.LinkOpts.PrependPath);
+ sys::path::append(Path, Entry.Filename);
+ Result.insert(Path);
+ }
+ }
+ return Result;
+ };
+
+ if (!Options.AllowFile.empty()) {
+ auto AllowedOrErr = ParseAllowDisallowFile(Options.AllowFile);
+ if (!AllowedOrErr) {
+ WithColor::error() << toString(AllowedOrErr.takeError()) << '\n';
return EXIT_FAILURE;
}
- AllowedDebugMapObjects.emplace();
- StringRef Content = (*BufOrErr)->getBuffer();
- SmallVector<StringRef, 0> Lines;
- Content.split(Lines, '\n');
- for (StringRef Line : Lines) {
- Line = Line.trim();
- if (!Line.empty())
- AllowedDebugMapObjects->insert(Line);
+ AllowedObjects = std::move(*AllowedOrErr);
+ }
+
+ if (!Options.DisallowFile.empty()) {
+ auto DisallowedOrErr = ParseAllowDisallowFile(Options.DisallowFile);
+ if (!DisallowedOrErr) {
+ WithColor::error() << toString(DisallowedOrErr.takeError()) << '\n';
+ return EXIT_FAILURE;
}
+ DisallowedObjects = std::move(*DisallowedOrErr);
}
auto DebugMapPtrsOrErr = parseDebugMap(
BinHolder, InputFile, Options.Archs, Options.LinkOpts.DSYMSearchPaths,
Options.LinkOpts.PrependPath, Options.LinkOpts.BuildVariantSuffix,
- Options.LinkOpts.Verbose, Options.InputIsYAMLDebugMap,
- AllowedDebugMapObjects);
+ Options.LinkOpts.Verbose, Options.InputIsYAMLDebugMap, AllowedObjects,
+ DisallowedObjects);
if (auto EC = DebugMapPtrsOrErr.getError()) {
WithColor::error() << "cannot parse the debug map for '" << InputFile
diff --git a/llvm/tools/dsymutil/dsymutil.h b/llvm/tools/dsymutil/dsymutil.h
index 12ada635f5131..80318a09f5bda 100644
--- a/llvm/tools/dsymutil/dsymutil.h
+++ b/llvm/tools/dsymutil/dsymutil.h
@@ -39,7 +39,8 @@ ErrorOr<std::vector<std::unique_ptr<DebugMap>>> parseDebugMap(
BinaryHolder &BinHolder, StringRef InputFile, ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
StringRef VariantSuffix, bool Verbose, bool InputIsYAML,
- const std::optional<StringSet<>> &AllowedDebugMapObjects = std::nullopt);
+ const std::optional<StringSet<>> &AllowedObjects = std::nullopt,
+ const std::optional<StringSet<>> &DisallowedObjects = std::nullopt);
/// Dump the symbol table.
bool dumpStab(BinaryHolder &BinHolder, StringRef InputFile,
>From 27e5c1eefa39580e356dbce67a8635e2723495a9 Mon Sep 17 00:00:00 2001
From: Roy Shi <royshi at meta.com>
Date: Wed, 4 Mar 2026 09:59:16 -0800
Subject: [PATCH 4/5] Try the polymorphism approach
---
llvm/tools/dsymutil/DebugMap.cpp | 31 ++++++++++++++++--
llvm/tools/dsymutil/DebugMap.h | 55 +++++++++++++++++++++++++++-----
2 files changed, 75 insertions(+), 11 deletions(-)
diff --git a/llvm/tools/dsymutil/DebugMap.cpp b/llvm/tools/dsymutil/DebugMap.cpp
index 8798601754ff4..b33e5f7bff644 100644
--- a/llvm/tools/dsymutil/DebugMap.cpp
+++ b/llvm/tools/dsymutil/DebugMap.cpp
@@ -40,7 +40,7 @@ using namespace llvm::object;
DebugMapObject::DebugMapObject(StringRef ObjectFilename,
sys::TimePoint<std::chrono::seconds> Timestamp,
uint8_t Type)
- : Filename(std::string(ObjectFilename)), Timestamp(Timestamp), Type(Type) {}
+ : DebugMapObjectFilter(ObjectFilename), Timestamp(Timestamp), Type(Type) {}
bool DebugMapObject::addSymbol(StringRef Name,
std::optional<uint64_t> ObjectAddress,
@@ -94,8 +94,8 @@ DebugMapObject &
DebugMap::addDebugMapObject(StringRef ObjectFilePath,
sys::TimePoint<std::chrono::seconds> Timestamp,
uint8_t Type) {
- Objects.emplace_back(new DebugMapObject(ObjectFilePath, Timestamp, Type));
- return *Objects.back();
+ getObjects().emplace_back(new DebugMapObject(ObjectFilePath, Timestamp, Type));
+ return *getObjects().back();
}
const DebugMapObject::DebugMapEntry *
@@ -123,6 +123,10 @@ void DebugMap::print(raw_ostream &OS) const {
void DebugMap::dump() const { print(errs()); }
#endif
+DebugMapObjectFilter::DebugMapObjectFilter(StringRef ObjectFilename)
+ : Filename(std::string(ObjectFilename)) {}
+
+
namespace {
struct YAMLContext {
@@ -219,6 +223,27 @@ SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObject>>>::element(
return *seq[index];
}
+size_t
+SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObjectFilter>>>::
+ size(IO &io,
+ std::vector<std::unique_ptr<dsymutil::DebugMapObjectFilter>> &seq) {
+ return seq.size();
+}
+
+dsymutil::DebugMapObject &
+SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObjectFilter>>>::
+ element(IO &io,
+ std::vector<std::unique_ptr<dsymutil::DebugMapObjectFilter>> &seq,
+ size_t index) {
+ auto &Objects =
+ reinterpret_cast<std::vector<std::unique_ptr<dsymutil::DebugMapObject>> &>(
+ seq);
+ return SequenceTraits<
+ std::vector<std::unique_ptr<dsymutil::DebugMapObject>>>::element(io,
+ Objects,
+ index);
+}
+
void MappingTraits<dsymutil::DebugMap>::mapping(IO &io,
dsymutil::DebugMap &DM) {
io.mapRequired("triple", DM.BinaryTriple);
diff --git a/llvm/tools/dsymutil/DebugMap.h b/llvm/tools/dsymutil/DebugMap.h
index 9a518222a56da..c6d5fd960dfb0 100644
--- a/llvm/tools/dsymutil/DebugMap.h
+++ b/llvm/tools/dsymutil/DebugMap.h
@@ -48,6 +48,12 @@ class raw_ostream;
namespace dsymutil {
class DebugMapObject;
+class DebugMapObjectFilter;
+
+class DebugMapFilter {
+protected:
+ std::vector<std::unique_ptr<DebugMapObjectFilter>> Objects;
+};
/// The DebugMap object stores the list of object files to query for debug
/// information along with the mapping between the symbols' addresses in the
@@ -73,13 +79,14 @@ class DebugMapObject;
/// DIE.discardSubtree();
/// }
/// }
-class DebugMap {
+class DebugMap : public DebugMapFilter {
Triple BinaryTriple;
std::string BinaryPath;
std::vector<uint8_t> BinaryUUID;
using ObjectContainer = std::vector<std::unique_ptr<DebugMapObject>>;
- ObjectContainer Objects;
+ ObjectContainer& getObjects() { return reinterpret_cast<ObjectContainer&>(Objects); }
+ const ObjectContainer& getObjects() const { return reinterpret_cast<const ObjectContainer&>(Objects); }
/// For YAML IO support.
///@{
@@ -99,9 +106,9 @@ class DebugMap {
return make_range(begin(), end());
}
- const_iterator begin() const { return Objects.begin(); }
+ const_iterator begin() const { return getObjects().begin(); }
- const_iterator end() const { return Objects.end(); }
+ const_iterator end() const { return getObjects().end(); }
unsigned getNumberOfObjects() const { return Objects.size(); }
@@ -130,10 +137,36 @@ class DebugMap {
StringRef PrependPath, bool Verbose);
};
+class DebugMapObjectFilter {
+public:
+ StringRef getObjectFilename() const { return Filename; }
+
+protected:
+ std::string Filename;
+
+private:
+ friend class DebugMapFilter;
+ friend class DebugMapObject;
+
+ DebugMapObjectFilter(StringRef ObjectFilename);
+
+ /// For YAMLIO support.
+ ///@{
+ friend yaml::MappingTraits<dsymutil::DebugMapObjectFilter>;
+ friend yaml::SequenceTraits<std::vector<std::unique_ptr<DebugMapObjectFilter>>>;
+
+ DebugMapObjectFilter() = default;
+
+public:
+ DebugMapObjectFilter(DebugMapObjectFilter &&) = default;
+ DebugMapObjectFilter &operator=(DebugMapObjectFilter &&) = default;
+ ///@}
+};
+
/// The DebugMapObject represents one object file described by the DebugMap. It
/// contains a list of mappings between addresses in the object file and in the
/// linked binary for all the linked atoms in this object file.
-class DebugMapObject {
+class DebugMapObject : public DebugMapObjectFilter {
public:
using YAMLSymbolMapping = std::pair<std::string, SymbolMapping>;
using DebugMapEntry = StringMapEntry<SymbolMapping>;
@@ -152,8 +185,6 @@ class DebugMapObject {
/// \returns null if the address isn't found.
const DebugMapEntry *lookupObjectAddress(uint64_t Address) const;
- StringRef getObjectFilename() const { return Filename; }
-
sys::TimePoint<std::chrono::seconds> getTimestamp() const {
return Timestamp;
}
@@ -189,7 +220,6 @@ class DebugMapObject {
DebugMapObject(StringRef ObjectFilename,
sys::TimePoint<std::chrono::seconds> Timestamp, uint8_t Type);
- std::string Filename;
sys::TimePoint<std::chrono::seconds> Timestamp;
StringMap<struct SymbolMapping> Symbols;
DenseMap<uint64_t, DebugMapEntry *> AddressToMapping;
@@ -242,6 +272,15 @@ struct SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObject>>> {
size_t index);
};
+template <>
+struct SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObjectFilter>>> {
+ static size_t
+ size(IO &io, std::vector<std::unique_ptr<dsymutil::DebugMapObjectFilter>> &seq);
+ static dsymutil::DebugMapObject &
+ element(IO &, std::vector<std::unique_ptr<dsymutil::DebugMapObjectFilter>> &seq,
+ size_t index);
+};
+
template <> struct MappingTraits<dsymutil::DebugMap> {
static void mapping(IO &io, dsymutil::DebugMap &DM);
};
>From 894099c09361d3170eb52c28f54af4940e5e590e Mon Sep 17 00:00:00 2001
From: Roy Shi <royshi at meta.com>
Date: Wed, 4 Mar 2026 10:38:33 -0800
Subject: [PATCH 5/5] Merge AllowedObjects and DisallowedObjects into one
---
.../dsymutil/AArch64/allow-disallow.test | 9 ++++-
llvm/tools/dsymutil/MachODebugMapParser.cpp | 34 +++++++++----------
llvm/tools/dsymutil/dsymutil.cpp | 19 +++++++----
llvm/tools/dsymutil/dsymutil.h | 6 ++--
4 files changed, 41 insertions(+), 27 deletions(-)
diff --git a/llvm/test/tools/dsymutil/AArch64/allow-disallow.test b/llvm/test/tools/dsymutil/AArch64/allow-disallow.test
index 976e7e79a60ea..b496829e7b6a1 100644
--- a/llvm/test/tools/dsymutil/AArch64/allow-disallow.test
+++ b/llvm/test/tools/dsymutil/AArch64/allow-disallow.test
@@ -53,10 +53,15 @@ RUN: --disallow=/nonexistent/path 2>&1 \
RUN: | FileCheck %s --check-prefix=MISSING-FILE
# Test error when combined with -y.
-RUN: not dsymutil --allow=%t.allow-one.yaml \
+RUN: not dsymutil --allow=some.file.yaml \
RUN: -y %p/../Inputs/remarks/basic.macho.remarks.arm64 2>&1 \
RUN: | FileCheck %s --check-prefix=YAML-CONFLICT
+# Test error when --allow and --disallow are both specified.
+RUN: not dsymutil --allow=some.file.yaml --disallow=some.file.yaml \
+RUN: %p/../Inputs/allow-disallow/a.out.arm64 2>&1 \
+RUN: | FileCheck %s --check-prefix=ALLOW-DISALLOW-CONFLICT
+
ALLOW-ONE: ---
ALLOW-ONE: filename: {{.*}}1.o
ALLOW-ONE-NOT: filename:
@@ -96,3 +101,5 @@ DISALLOW-NONE: ...
MISSING-FILE: error: cannot open allow/disallow file
YAML-CONFLICT: error: -y and --allow/--disallow cannot be specified together
+
+ALLOW-DISALLOW-CONFLICT: error: --allow and --disallow cannot be specified together
diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp
index 144f533deb32c..f402b677a21e1 100644
--- a/llvm/tools/dsymutil/MachODebugMapParser.cpp
+++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp
@@ -10,6 +10,7 @@
#include "DebugMap.h"
#include "MachOUtils.h"
#include "RelocationMap.h"
+#include "dsymutil.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringSet.h"
@@ -33,13 +34,13 @@ class MachODebugMapParser {
ArrayRef<std::string> Archs, ArrayRef<std::string> DSYMSearchPaths,
StringRef PathPrefix = "", StringRef VariantSuffix = "",
bool Verbose = false,
- const std::optional<StringSet<>> &AllowedObjects = std::nullopt,
- const std::optional<StringSet<>> &DisallowedObjects = std::nullopt)
+ const std::optional<StringSet<>> &ObjectFilter = std::nullopt,
+ ObjectFilterType ObjectFilterType = ObjectFilterType::Allow)
: BinaryPath(std::string(BinaryPath)), Archs(Archs),
DSYMSearchPaths(DSYMSearchPaths), PathPrefix(std::string(PathPrefix)),
VariantSuffix(std::string(VariantSuffix)), BinHolder(BinHolder),
CurrentDebugMapObject(nullptr), SkipDebugMapObject(false),
- AllowedObjects(AllowedObjects), DisallowedObjects(DisallowedObjects) {}
+ ObjectFilter(ObjectFilter), ObjectFilterType(ObjectFilterType) {}
/// Parses and returns the DebugMaps of the input binary. The binary contains
/// multiple maps in case it is a universal binary.
@@ -84,13 +85,11 @@ class MachODebugMapParser {
/// Whether we need to skip the current debug map object.
bool SkipDebugMapObject;
- /// Optional set of allowed debug map object paths. If set, only objects
- /// whose path is in this set will be included.
- const std::optional<StringSet<>> &AllowedObjects;
+ /// Optional set of object paths to filter on.
+ const std::optional<StringSet<>> &ObjectFilter;
- /// Optional set of disallowed debug map object paths. If set, objects
- /// whose path is in this set will be excluded.
- const std::optional<StringSet<>> &DisallowedObjects;
+ /// Whether ObjectFilter is an allow list or a disallow list.
+ enum ObjectFilterType ObjectFilterType;
/// Holds function info while function scope processing.
const char *CurrentFunctionName;
@@ -133,13 +132,12 @@ class MachODebugMapParser {
void addCommonSymbols();
/// Check if a debug map object should be included based on the
- /// allow/disallow lists.
+ /// object filter.
bool shouldIncludeObject(StringRef Path) const {
- if (AllowedObjects.has_value() && !AllowedObjects->contains(Path))
- return false;
- if (DisallowedObjects.has_value() && DisallowedObjects->contains(Path))
- return false;
- return true;
+ if (!ObjectFilter.has_value())
+ return true;
+ bool InSet = ObjectFilter->contains(Path);
+ return ObjectFilterType == Allow ? InSet : !InSet;
}
/// Dump the symbol table output header.
@@ -885,15 +883,15 @@ parseDebugMap(BinaryHolder &BinHolder, StringRef InputFile,
ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
StringRef VariantSuffix, bool Verbose, bool InputIsYAML,
- const std::optional<StringSet<>> &AllowedObjects,
- const std::optional<StringSet<>> &DisallowedObjects) {
+ const std::optional<StringSet<>> &ObjectFilter,
+ enum ObjectFilterType ObjectFilterType) {
if (InputIsYAML)
return DebugMap::parseYAMLDebugMap(BinHolder, InputFile, PrependPath,
Verbose);
MachODebugMapParser Parser(BinHolder, InputFile, Archs, DSYMSearchPaths,
PrependPath, VariantSuffix, Verbose,
- AllowedObjects, DisallowedObjects);
+ ObjectFilter, ObjectFilterType);
return Parser.parse();
}
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index 99f326cbd7c9f..2f32a48b38804 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -238,6 +238,11 @@ static Error verifyOptions(const DsymutilOptions &Options) {
"-y and --allow/--disallow cannot be specified together",
errc::invalid_argument);
+ if (!Options.AllowFile.empty() && !Options.DisallowFile.empty())
+ return make_error<StringError>(
+ "--allow and --disallow cannot be specified together",
+ errc::invalid_argument);
+
return Error::success();
}
@@ -733,8 +738,8 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
}
// Parse allow/disallow object list YAML files if specified.
- std::optional<StringSet<>> AllowedObjects;
- std::optional<StringSet<>> DisallowedObjects;
+ std::optional<StringSet<>> ObjectFilter;
+ enum ObjectFilterType ObjectFilterType = Allow;
auto ParseAllowDisallowFile =
[&](const std::string &FilePath) -> Expected<StringSet<>> {
@@ -770,7 +775,8 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
WithColor::error() << toString(AllowedOrErr.takeError()) << '\n';
return EXIT_FAILURE;
}
- AllowedObjects = std::move(*AllowedOrErr);
+ ObjectFilter = std::move(*AllowedOrErr);
+ ObjectFilterType = Allow;
}
if (!Options.DisallowFile.empty()) {
@@ -779,14 +785,15 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
WithColor::error() << toString(DisallowedOrErr.takeError()) << '\n';
return EXIT_FAILURE;
}
- DisallowedObjects = std::move(*DisallowedOrErr);
+ ObjectFilter = std::move(*DisallowedOrErr);
+ ObjectFilterType = Disallow;
}
auto DebugMapPtrsOrErr = parseDebugMap(
BinHolder, InputFile, Options.Archs, Options.LinkOpts.DSYMSearchPaths,
Options.LinkOpts.PrependPath, Options.LinkOpts.BuildVariantSuffix,
- Options.LinkOpts.Verbose, Options.InputIsYAMLDebugMap, AllowedObjects,
- DisallowedObjects);
+ Options.LinkOpts.Verbose, Options.InputIsYAMLDebugMap, ObjectFilter,
+ ObjectFilterType);
if (auto EC = DebugMapPtrsOrErr.getError()) {
WithColor::error() << "cannot parse the debug map for '" << InputFile
diff --git a/llvm/tools/dsymutil/dsymutil.h b/llvm/tools/dsymutil/dsymutil.h
index 80318a09f5bda..2a27dab156376 100644
--- a/llvm/tools/dsymutil/dsymutil.h
+++ b/llvm/tools/dsymutil/dsymutil.h
@@ -32,6 +32,8 @@
namespace llvm {
namespace dsymutil {
+enum ObjectFilterType { Allow, Disallow };
+
/// Extract the DebugMaps from the given file.
/// The file has to be a MachO object file. Multiple debug maps can be
/// returned when the file is universal (aka fat) binary.
@@ -39,8 +41,8 @@ ErrorOr<std::vector<std::unique_ptr<DebugMap>>> parseDebugMap(
BinaryHolder &BinHolder, StringRef InputFile, ArrayRef<std::string> Archs,
ArrayRef<std::string> DSYMSearchPaths, StringRef PrependPath,
StringRef VariantSuffix, bool Verbose, bool InputIsYAML,
- const std::optional<StringSet<>> &AllowedObjects = std::nullopt,
- const std::optional<StringSet<>> &DisallowedObjects = std::nullopt);
+ const std::optional<StringSet<>> &ObjectFilter = std::nullopt,
+ ObjectFilterType ObjectFilterType = ObjectFilterType::Allow);
/// Dump the symbol table.
bool dumpStab(BinaryHolder &BinHolder, StringRef InputFile,
More information about the llvm-commits
mailing list