Specify the target architecture when disassembling. Use :option:`--version`
for a list of available targets.
+.. option:: --build-id=<string>
+
+ Look up the object using the given build ID, specified as a hexadecimal
+ string. The found object is handled as if it were an input filename.
+
.. option:: -C, --demangle
Demangle symbol names in the output.
RUN: FileCheck %s --check-prefix=NOTFOUND
RUN: count 0 < %t.err
+# Use debuginfod to look up build IDs.
+RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-objdump -d --source \
+RUN: --build-id 1512f769114c011387393822af15dd660c080295 | \
+RUN: FileCheck %s --check-prefix=FOUND
+
+# Produce an error if malformed (not a hex string).
+RUN: not env DEBUGINFOD_CACHE_PATH=%t llvm-objdump -d --source --build-id foo \
+RUN: 2> %t.err
+RUN: FileCheck %s --check-prefix=MALFORMEDERROR --input-file %t.err
+MALFORMEDERROR: error: --build-id: expected a build ID, but got 'foo'
+
+# Produce an error if not found.
+RUN: not env DEBUGINFOD_CACHE_PATH=%t llvm-objdump -d --source --build-id abc \
+RUN: 2> %t.err
+RUN: FileCheck %s --check-prefix=NOTFOUNDERROR --input-file %t.err
+NOTFOUNDERROR: error: --build-id: could not find build ID 'abc'
+
# Use debuginfod to recover symbols.
RUN: llvm-strip --strip-sections %t/stripped
RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-objdump -d --debuginfod \
def archive_headers : Flag<["--"], "archive-headers">,
HelpText<"Display archive header information">;
+defm build_id :
+ Eq<"build-id", "Build ID to look up. Once found, added as an input file">,
+ MetaVarName<"<dir>">;
+
def : Flag<["-"], "a">, Alias<archive_headers>,
HelpText<"Alias for --archive-headers">;
}
}
+static object::BuildID parseBuildIDArg(const opt::Arg *A) {
+ StringRef V(A->getValue());
+ std::string Bytes;
+ if (!tryGetFromHex(V, Bytes))
+ reportCmdLineError(A->getSpelling() + ": expected a build ID, but got '" +
+ V + "'");
+ ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()),
+ Bytes.size());
+ return object::BuildID(BuildID.begin(), BuildID.end());
+}
+
static void invalidArgValue(const opt::Arg *A) {
reportCmdLineError("'" + StringRef(A->getValue()) +
"' is not a valid value for '" + A->getSpelling() + "'");
llvm::cl::ParseCommandLineOptions(2, Argv);
}
+ // Look up any provided build IDs, then append them to the input filenames.
+ for (const opt::Arg *A : InputArgs.filtered(OBJDUMP_build_id)) {
+ object::BuildID BuildID = parseBuildIDArg(A);
+ Optional<std::string> Path = BIDFetcher->fetch(BuildID);
+ if (!Path) {
+ reportCmdLineError(A->getSpelling() + ": could not find build ID '" +
+ A->getValue() + "'");
+ }
+ InputFilenames.push_back(std::move(*Path));
+ }
+
// objdump defaults to a.out if no filenames specified.
if (InputFilenames.empty())
InputFilenames.push_back("a.out");
// Initialize debuginfod.
const bool ShouldUseDebuginfodByDefault =
- HTTPClient::isAvailable() &&
- !ExitOnErr(getDefaultDebuginfodUrls()).empty();
+ InputArgs.hasArg(OBJDUMP_build_id) ||
+ (HTTPClient::isAvailable() &&
+ !ExitOnErr(getDefaultDebuginfodUrls()).empty());
std::vector<std::string> DebugFileDirectories =
InputArgs.getAllArgValues(OBJDUMP_debug_file_directory);
if (InputArgs.hasFlag(OBJDUMP_debuginfod, OBJDUMP_no_debuginfod,