[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