[llvm] 0ddc75f - Add option to llvm-gsymutil to read addresses from stdin.
Simon Giesecke via llvm-commits
llvm-commits at lists.llvm.org
Wed May 19 23:11:45 PDT 2021
Author: Simon Giesecke
Date: 2021-05-20T06:10:35Z
New Revision: 0ddc75fd08346d0b81f1345f3ca6164880bf9770
URL: https://github.com/llvm/llvm-project/commit/0ddc75fd08346d0b81f1345f3ca6164880bf9770
DIFF: https://github.com/llvm/llvm-project/commit/0ddc75fd08346d0b81f1345f3ca6164880bf9770.diff
LOG: Add option to llvm-gsymutil to read addresses from stdin.
Differential Revision: https://reviews.llvm.org/D102224
Added:
Modified:
llvm/test/tools/llvm-gsymutil/X86/elf-dwarf.yaml
llvm/test/tools/llvm-gsymutil/cmdline.test
llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-gsymutil/X86/elf-dwarf.yaml b/llvm/test/tools/llvm-gsymutil/X86/elf-dwarf.yaml
index 6fec33d842625..4816d074d711e 100644
--- a/llvm/test/tools/llvm-gsymutil/X86/elf-dwarf.yaml
+++ b/llvm/test/tools/llvm-gsymutil/X86/elf-dwarf.yaml
@@ -5,6 +5,8 @@
# RUN: yaml2obj %s -o %t
# RUN: llvm-gsymutil --convert %t -o %t.gsym 2>&1 | FileCheck %s --check-prefix=CONVERT
# RUN: llvm-gsymutil --address=0x400391 --address=0x4004cd %t.gsym 2>&1 | FileCheck %s --check-prefix=ADDR
+# RUN: echo -e "0x400391 %/t.gsym\n0x4004cd %/t.gsym" | llvm-gsymutil --addresses-from-stdin 2>&1 | FileCheck %s --check-prefix=ADDRI --dump-input=always
+# RUN: llvm-gsymutil --address=0x400391 --address=0x4004cd --verbose %t.gsym 2>&1 | FileCheck %s --check-prefix=ADDRV --dump-input=always
# RUN: llvm-gsymutil --address=0x400391 --address=0x4004cd --verbose %t.gsym 2>&1 | FileCheck %s --check-prefix=ADDRV --dump-input=always
# RUN: llvm-gsymutil %t.gsym 2>&1 | FileCheck %s --check-prefix=DUMP
@@ -12,6 +14,11 @@
# ADDR: 0x0000000000400391: _init
# ADDR: 0x00000000004004cd: main @ /tmp/main.cpp:1
+# ADDRI: 0x0000000000400391: _init
+# ADDRI-EMPTY:
+# ADDRI: 0x00000000004004cd: main @ /tmp/main.cpp:1
+# ADDRI-EMPTY:
+
# ADDRV: Looking up addresses in "{{.*\.yaml\.tmp\.gsym}}":
# ADDRV: FunctionInfo for 0x0000000000400391:
# ADDRV: [0x0000000000400390 - 0x0000000000400390) "_init"
diff --git a/llvm/test/tools/llvm-gsymutil/cmdline.test b/llvm/test/tools/llvm-gsymutil/cmdline.test
index e9c764f31253d..1f940270492cb 100644
--- a/llvm/test/tools/llvm-gsymutil/cmdline.test
+++ b/llvm/test/tools/llvm-gsymutil/cmdline.test
@@ -14,8 +14,13 @@ HELP: --help
HELP: --version
HELP: Lookup Options:
HELP: --address=<addr>
+HELP: --addresses-from-stdin
HELP: Options:
HELP: --verbose
RUN: llvm-gsymutil --version 2>&1 | FileCheck --check-prefix=VERSION %s
VERSION: {{ version }}
+
+RUN: not llvm-gsymutil --addresses-from-stdin --address 0x12345678 | FileCheck --check-prefix=INCOMPATIBLE %s
+RUN: not llvm-gsymutil --addresses-from-stdin llvm-gsymutil | FileCheck --check-prefix=INCOMPATIBLE %s
+INCOMPATIBLE: error: no input files or addresses can be specified when using the --addresses-from-stdin option.
diff --git a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp
index 155eee07e055d..167d34cb9ab90 100644
--- a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp
+++ b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp
@@ -30,6 +30,7 @@
#include <algorithm>
#include <cstring>
#include <inttypes.h>
+#include <iostream>
#include <map>
#include <string>
#include <system_error>
@@ -112,7 +113,11 @@ static list<uint64_t> LookupAddresses("address",
cl::value_desc("addr"),
cat(LookupOptions));
-
+static opt<bool> LookupAddressesFromStdin(
+ "addresses-from-stdin",
+ desc("Lookup addresses in a GSYM file that are read from stdin\nEach input "
+ "line is expected to be of the following format: <addr> <gsym-path>"),
+ cat(LookupOptions));
} // namespace
/// @}
@@ -133,7 +138,6 @@ static void error(StringRef Prefix, std::error_code EC) {
exit(1);
}
-
/// If the input path is a .dSYM bundle (as created by the dsymutil tool),
/// replace it with individual entries for each of the object files inside the
/// bundle otherwise return the input path.
@@ -271,7 +275,6 @@ static llvm::Optional<uint64_t> getImageBaseAddress(object::ObjectFile &Obj) {
return llvm::None;
}
-
static llvm::Error handleObjectFile(ObjectFile &Obj,
const std::string &OutFile) {
auto ThreadCount =
@@ -306,8 +309,7 @@ static llvm::Error handleObjectFile(ObjectFile &Obj,
if (!DICtx)
return createStringError(std::errc::invalid_argument,
"unable to create DWARF context");
- logAllUnhandledErrors(DICtx->loadRegisterInfo(Obj), OS,
- "DwarfTransformer: ");
+ logAllUnhandledErrors(DICtx->loadRegisterInfo(Obj), OS, "DwarfTransformer: ");
// Make a DWARF transformer object and populate the ranges of the code
// so we don't end up adding invalid functions to GSYM data.
@@ -330,8 +332,8 @@ static llvm::Error handleObjectFile(ObjectFile &Obj,
return Err;
// Save the GSYM file to disk.
- support::endianness Endian = Obj.makeTriple().isLittleEndian() ?
- support::little : support::big;
+ support::endianness Endian =
+ Obj.makeTriple().isLittleEndian() ? support::little : support::big;
if (auto Err = Gsym.save(OutFile.c_str(), Endian))
return Err;
@@ -360,7 +362,7 @@ static llvm::Error handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
// Iterate over all contained architectures and filter out any that were
// not specified with the "--arch <arch>" option. If the --arch option was
// not specified on the command line, we will process all architectures.
- std::vector< std::unique_ptr<MachOObjectFile> > FilterObjs;
+ std::vector<std::unique_ptr<MachOObjectFile>> FilterObjs;
for (auto &ObjForArch : Fat->objects()) {
if (auto MachOOrErr = ObjForArch.getAsObjectFile()) {
auto &Obj = **MachOOrErr;
@@ -375,7 +377,7 @@ static llvm::Error handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
"no matching architectures found"));
// Now handle each architecture we need to convert.
- for (auto &Obj: FilterObjs) {
+ for (auto &Obj : FilterObjs) {
Triple ObjTriple(Obj->getArchTriple());
auto ArchName = ObjTriple.getArchName();
std::string ArchOutFile(OutFile);
@@ -425,6 +427,27 @@ static llvm::Error convertFileToGSYM(raw_ostream &OS) {
return Error::success();
}
+static void doLookup(GsymReader &Gsym, uint64_t Addr, raw_ostream &OS) {
+ if (auto Result = Gsym.lookup(Addr)) {
+ // If verbose is enabled dump the full function info for the address.
+ if (Verbose) {
+ if (auto FI = Gsym.getFunctionInfo(Addr)) {
+ OS << "FunctionInfo for " << HEX64(Addr) << ":\n";
+ Gsym.dump(OS, *FI);
+ OS << "\nLookupResult for " << HEX64(Addr) << ":\n";
+ }
+ }
+ OS << Result.get();
+ } else {
+ if (Verbose)
+ OS << "\nLookupResult for " << HEX64(Addr) << ":\n";
+ OS << HEX64(Addr) << ": ";
+ logAllUnhandledErrors(Result.takeError(), OS, "error: ");
+ }
+ if (Verbose)
+ OS << "\n";
+}
+
int main(int argc, char const *argv[]) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal(argv[0]);
@@ -441,8 +464,7 @@ int main(int argc, char const *argv[]) {
"lookup addresses within that GSYM file.\n"
"Use the --convert option to specify a file with option --out-file "
"option to convert to GSYM format.\n";
- HideUnrelatedOptions(
- {&GeneralOptions, &ConversionOptions, &LookupOptions});
+ HideUnrelatedOptions({&GeneralOptions, &ConversionOptions, &LookupOptions});
cl::ParseCommandLineOptions(argc, argv, Overview);
if (Help) {
@@ -465,6 +487,50 @@ int main(int argc, char const *argv[]) {
return 0;
}
+ if (LookupAddressesFromStdin) {
+ if (!LookupAddresses.empty() || !InputFilenames.empty()) {
+ OS << "error: no input files or addresses can be specified when using "
+ "the --addresses-from-stdin "
+ "option.\n";
+ return 1;
+ }
+
+ std::string InputLine;
+ std::string CurrentGSYMPath;
+ llvm::Optional<Expected<GsymReader>> CurrentGsym;
+
+ while (std::getline(std::cin, InputLine)) {
+ // Strip newline characters.
+ std::string StrippedInputLine(InputLine);
+ llvm::erase_if(StrippedInputLine,
+ [](char c) { return c == '\r' || c == '\n'; });
+
+ StringRef AddrStr, GSYMPath;
+ std::tie(AddrStr, GSYMPath) =
+ llvm::StringRef{StrippedInputLine}.split(' ');
+
+ if (GSYMPath != CurrentGSYMPath) {
+ CurrentGsym = GsymReader::openFile(GSYMPath);
+ if (!*CurrentGsym)
+ error(GSYMPath, CurrentGsym->takeError());
+ }
+
+ uint64_t Addr;
+ if (AddrStr.getAsInteger(0, Addr)) {
+ OS << "error: invalid address " << AddrStr
+ << ", expected: Address GsymFile.\n";
+ return 1;
+ }
+
+ doLookup(**CurrentGsym, Addr, OS);
+
+ OS << "\n";
+ OS.flush();
+ }
+
+ return EXIT_SUCCESS;
+ }
+
// Dump or access data inside GSYM files
for (const auto &GSYMPath : InputFilenames) {
auto Gsym = GsymReader::openFile(GSYMPath);
@@ -478,25 +544,8 @@ int main(int argc, char const *argv[]) {
// Lookup an address in a GSYM file and print any matches.
OS << "Looking up addresses in \"" << GSYMPath << "\":\n";
- for (auto Addr: LookupAddresses) {
- if (auto Result = Gsym->lookup(Addr)) {
- // If verbose is enabled dump the full function info for the address.
- if (Verbose) {
- if (auto FI = Gsym->getFunctionInfo(Addr)) {
- OS << "FunctionInfo for " << HEX64(Addr) << ":\n";
- Gsym->dump(OS, *FI);
- OS << "\nLookupResult for " << HEX64(Addr) << ":\n";
- }
- }
- OS << Result.get();
- } else {
- if (Verbose)
- OS << "\nLookupResult for " << HEX64(Addr) << ":\n";
- OS << HEX64(Addr) << ": ";
- logAllUnhandledErrors(Result.takeError(), OS, "error: ");
- }
- if (Verbose)
- OS << "\n";
+ for (auto Addr : LookupAddresses) {
+ doLookup(*Gsym, Addr, OS);
}
}
return EXIT_SUCCESS;
More information about the llvm-commits
mailing list