[llvm] 0135aa7 - [llvm-nm] add a new option -X to specify the type of object file llvm-nm should examine

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 15 06:43:51 PST 2022


Author: zhijian
Date: 2022-02-15T09:43:31-05:00
New Revision: 0135aa7b988f87626fa5640c92fae68dff4e2897

URL: https://github.com/llvm/llvm-project/commit/0135aa7b988f87626fa5640c92fae68dff4e2897
DIFF: https://github.com/llvm/llvm-project/commit/0135aa7b988f87626fa5640c92fae68dff4e2897.diff

LOG: [llvm-nm] add a new option -X to specify the type of object file llvm-nm should examine
Summary:
Added a new option "-X" to specify, which type of object file should be examine.

For example:

1. "llvm-nm -X64 archive.a" only deal with the 64bit object files in the archive.a ,ignore the all 32bit object files in the archive.a
2. "llvm-nm -X32 xcoffobj32.o xcoffobj64.o " only deal with the 32bit object file "xcoffobj32.o" , 64bit object file "xcoffobj64.o" will be ignored

Reviewers: James Henderson,Fangrui Song
Differential Revision: https://reviews.llvm.org/D118193

Added: 
    llvm/test/tools/llvm-nm/Inputs/bitcode-sym32.ll
    llvm/test/tools/llvm-nm/Inputs/bitcode-sym64.ll
    llvm/test/tools/llvm-nm/option-X.test

Modified: 
    llvm/docs/CommandGuide/llvm-nm.rst
    llvm/tools/llvm-nm/Opts.td
    llvm/tools/llvm-nm/llvm-nm.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-nm.rst b/llvm/docs/CommandGuide/llvm-nm.rst
index e2d96c8220df..dd78fd0afc34 100644
--- a/llvm/docs/CommandGuide/llvm-nm.rst
+++ b/llvm/docs/CommandGuide/llvm-nm.rst
@@ -126,6 +126,20 @@ OPTIONS
 
  Use BSD output format. Alias for ``--format=bsd``.
 
+.. option:: -X
+
+ Specify the type of XCOFF object file, ELF object file, or IR object file input
+ from command line or from archive files that llvm-nm should examine. The
+ mode must be one of the following:
+   32
+         Process only 32-bit object files.
+   64
+         Process only 64-bit object files.
+   32_64
+         Process both 32-bit and 64-bit object files.
+   any
+         Process all the supported object files.
+
 .. option:: --debug-syms, -a
 
  Show all symbols, even those usually suppressed.

diff  --git a/llvm/test/tools/llvm-nm/Inputs/bitcode-sym32.ll b/llvm/test/tools/llvm-nm/Inputs/bitcode-sym32.ll
new file mode 100644
index 000000000000..0c76f09fd22b
--- /dev/null
+++ b/llvm/test/tools/llvm-nm/Inputs/bitcode-sym32.ll
@@ -0,0 +1,14 @@
+target triple = "powerpcle-unknown-linux-gnu"
+
+ at C32 = dso_local global i32 5, align 4
+ at undef_var32 = external dso_local global i32, align 4
+
+define dso_local i32 @foo32(i32 %i) #0 {
+entry:
+  %i.addr = alloca i32, align 4
+  store i32 %i, i32* %i.addr, align 4
+  %0 = load i32, i32* %i.addr, align 4
+  %1 = load i32, i32* @undef_var32, align 4
+  %add = add nsw i32 %0, %1
+  ret i32 %add
+}

diff  --git a/llvm/test/tools/llvm-nm/Inputs/bitcode-sym64.ll b/llvm/test/tools/llvm-nm/Inputs/bitcode-sym64.ll
new file mode 100644
index 000000000000..cd749199fe79
--- /dev/null
+++ b/llvm/test/tools/llvm-nm/Inputs/bitcode-sym64.ll
@@ -0,0 +1,12 @@
+target triple = "powerpc64le-unknown-linux-gnu"
+
+ at C64 = dso_local global i32 5, align 4
+ at static_var64 = internal global i32 2, align 4
+
+define dso_local signext i32 @bar64() #0 {
+entry:
+  %0 = load i32, i32* @static_var64, align 4
+  %1 = load i32, i32* @C64, align 4
+  %add = add nsw i32 %0, %1
+  ret i32 %add
+}

diff  --git a/llvm/test/tools/llvm-nm/option-X.test b/llvm/test/tools/llvm-nm/option-X.test
new file mode 100644
index 000000000000..caa21f9d7961
--- /dev/null
+++ b/llvm/test/tools/llvm-nm/option-X.test
@@ -0,0 +1,111 @@
+## Test the "-X" option.
+## The option specifies the type of object file to examine.
+
+# RUN: llvm-as -o %t32.bc %p/Inputs/bitcode-sym32.ll
+# RUN: llvm-as -o %t64.bc %p/Inputs/bitcode-sym64.ll
+
+# RUN: llvm-nm --format=just-symbols -X32 %t32.bc %t64.bc | \
+# RUN:   FileCheck %s -DFILE1=%t32.bc --check-prefixes=BITCODE32 --implicit-check-not={{.}}
+# RUN: llvm-nm --format=just-symbols -X64 %t32.bc %t64.bc | \
+# RUN:   FileCheck %s -DFILE2=%t64.bc --check-prefixes=BITCODE64 --implicit-check-not={{.}}
+# RUN: llvm-nm --format=just-symbols %t32.bc %t64.bc | \
+# RUN:   FileCheck %s -DFILE1=%t32.bc -DFILE2=%t64.bc --check-prefixes=BITCODE32,BITCODE64
+# RUN: llvm-nm --format=just-symbols -X32_64 %t32.bc %t64.bc | \
+# RUN:   FileCheck %s -DFILE1=%t32.bc -DFILE2=%t64.bc --check-prefixes=BITCODE32,BITCODE64
+# RUN: llvm-nm --format=just-symbols -Xany %t32.bc %t64.bc | \
+# RUN:   FileCheck %s -DFILE1=%t32.bc -DFILE2=%t64.bc --check-prefixes=BITCODE32,BITCODE64
+
+# BITCODE32:      [[FILE1]]:
+# BITCODE32-NEXT: C32
+# BITCODE32-NEXT: foo32
+# BITCODE32-NEXT: undef_var32
+
+# BITCODE64:      [[FILE2]]:
+# BITCODE64-NEXT: C64
+# BITCODE64-NEXT: bar64
+# BITCODE64-NEXT: static_var64
+
+# RUN: yaml2obj --docnum=1 -DCLASS=ELFCLASS32 %s -o %t_elf32.o
+# RUN: yaml2obj --docnum=1 -DCLASS=ELFCLASS64 %s -o %t_elf64.o
+
+# RUN: llvm-nm --format=just-symbols -X32 %t_elf32.o %t_elf64.o | \
+# RUN:   FileCheck %s -DFILE32=%t_elf32.o --check-prefixes=ELF32 --implicit-check-not={{.}}
+# RUN: llvm-nm --format=just-symbols -X64 %t_elf32.o %t_elf64.o | \
+# RUN:   FileCheck %s -DFILE64=%t_elf64.o --check-prefixes=ELF64 --implicit-check-not={{.}}
+# RUN: llvm-nm --format=just-symbols %t_elf32.o %t_elf64.o | \
+# RUN:   FileCheck %s -DFILE32=%t_elf32.o -DFILE64=%t_elf64.o --check-prefixes=ELF32,ELF64
+# RUN: llvm-nm --format=just-symbols -X32_64 %t_elf32.o %t_elf64.o | \
+# RUN:   FileCheck %s -DFILE32=%t_elf32.o -DFILE64=%t_elf64.o --check-prefixes=ELF32,ELF64
+# RUN: llvm-nm --format=just-symbols -Xany %t_elf32.o %t_elf64.o | \
+# RUN:   FileCheck %s -DFILE32=%t_elf32.o -DFILE64=%t_elf64.o --check-prefixes=ELF32,ELF64
+
+# ELF32:      [[FILE32]]:
+# ELF32-NEXT: ELFCLASS32_var
+
+# ELF64:      [[FILE64]]:
+# ELF64-NEXT: ELFCLASS64_var
+
+--- !ELF
+FileHeader:
+  Class:   [[CLASS]]
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+Symbols:
+  - Name:    [[CLASS]]_var
+
+# RUN: yaml2obj --docnum=2 -DFLAG=0x1DF %s -o %t_xcoff32.o
+# RUN: yaml2obj --docnum=2 -DFLAG=0x1F7 %s -o %t_xcoff64.o
+# RUN: rm -f %t.a
+# RUN: llvm-ar -q -c %t.a %t_xcoff32.o %t_xcoff64.o
+
+# RUN: llvm-nm --format=just-symbols -X32 %t_xcoff32.o | \
+# RUN:   FileCheck --check-prefixes=XCOFF32 %s --implicit-check-not={{.}}
+# RUN: llvm-nm --format=just-symbols -X32 %t.a | \
+# RUN:   FileCheck --check-prefixes=ARC32,XCOFF32 %s -DFILE=%basename_t --implicit-check-not={{.}}
+# ARC32:      [[FILE]].tmp_xcoff32.o:
+# XCOFF32:      var_0x1DF
+
+# RUN: llvm-nm --format=just-symbols -X64 %t_xcoff64.o | \
+# RUN:   FileCheck --check-prefixes=XCOFF64 %s --implicit-check-not={{.}}
+# RUN: llvm-nm --format=just-symbols -X64 %t.a | \
+# RUN:   FileCheck --check-prefixes=ARC64,XCOFF64 -DFILE=%basename_t %s --implicit-check-not={{.}}
+# ARC64:       [[FILE]].tmp_xcoff64.o:
+# XCOFF64:       var_0x1F7
+
+# RUN: llvm-nm --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \
+# RUN:   FileCheck --check-prefixes=BOTH %s -DFILE32=%t_xcoff32.o -DFILE64=%t_xcoff64.o --match-full-lines
+# RUN: llvm-nm --format=just-symbols -X32_64 %t_xcoff32.o %t_xcoff64.o | \
+# RUN:   FileCheck --check-prefixes=BOTH %s -DFILE32=%t_xcoff32.o -DFILE64=%t_xcoff64.o --match-full-lines
+# RUN: llvm-nm --format=just-symbols -Xany %t_xcoff32.o %t_xcoff64.o | \
+# RUN:   FileCheck --check-prefixes=BOTH %s -DFILE32=%t_xcoff32.o -DFILE64=%t_xcoff64.o --match-full-lines
+
+# BOTH:        [[FILE32]]:
+# BOTH-NEXT:   var_0x1DF
+# BOTH-EMPTY:
+# BOTH-NEXT:   [[FILE64]]:
+# BOTH-NEXT:   var_0x1F7
+
+# RUN: llvm-nm --format=just-symbols %t.a | \
+# RUN:   FileCheck --check-prefixes=ARCHIVE-BOTH -DFILE=%basename_t --match-full-lines %s
+# RUN: llvm-nm --format=just-symbols -X32_64 %t.a | \
+# RUN:   FileCheck --check-prefixes=ARCHIVE-BOTH -DFILE=%basename_t --match-full-lines %s
+# RUN: llvm-nm --format=just-symbols -Xany %t.a | \
+# RUN:   FileCheck --check-prefixes=ARCHIVE-BOTH -DFILE=%basename_t --match-full-lines %s
+
+# ARCHIVE-BOTH:      [[FILE]].tmp_xcoff32.o:
+# ARCHIVE-BOTH-NEXT: var_0x1DF{{[[:space:]]}}
+# ARCHIVE-BOTH-NEXT: [[FILE]].tmp_xcoff64.o:
+# ARCHIVE-BOTH-NEXT: var_0x1F7
+
+# RUN: llvm-nm --format=just-symbols -X64 %t_xcoff32.o | count 0
+# RUN: llvm-nm --format=just-symbols -X32 %t_xcoff64.o | count 0
+
+# RUN: not llvm-nm --format=just-symbols -X33 %t_xcoff32.o 2>&1 |  FileCheck %s --check-prefixes=ERR
+# ERR:      error: : -X value should be one of: 32, 64, 32_64, (default) any
+# ERR-NEXT: var_0x1DF
+
+--- !XCOFF
+FileHeader:
+  MagicNumber:       [[FLAG]]
+Symbols:
+  - Name:            var_[[FLAG]]

diff  --git a/llvm/tools/llvm-nm/Opts.td b/llvm/tools/llvm-nm/Opts.td
index 3a790890909a..434a70b1fbc9 100644
--- a/llvm/tools/llvm-nm/Opts.td
+++ b/llvm/tools/llvm-nm/Opts.td
@@ -13,6 +13,7 @@ multiclass Eq<string name, string help> {
   def : Separate<["--"], name>, Alias<!cast<Joined>(NAME #_EQ)>;
 }
 
+def X : JoinedOrSeparate<["-"], "X">, HelpText<"Specifies the type of ELF, XCOFF, or IR object file to examine. The value must be one of: 32, 64, 32_64, any (default)">;
 def debug_syms : FF<"debug-syms", "Show all symbols, even debugger only">;
 def defined_only : FF<"defined-only", "Show only defined symbols">;
 defm demangle : BB<"demangle", "Demangle C++ symbol names", "Don't demangle symbol names">;

diff  --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp
index b5d78d1d8c4b..2196faf933b8 100644
--- a/llvm/tools/llvm-nm/llvm-nm.cpp
+++ b/llvm/tools/llvm-nm/llvm-nm.cpp
@@ -83,9 +83,11 @@ class NmOptTable : public opt::OptTable {
 };
 
 enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols };
+enum class BitModeTy { Bit32, Bit64, Bit32_64, Any };
 } // namespace
 
 static bool ArchiveMap;
+static BitModeTy BitMode;
 static bool DebugSyms;
 static bool DefinedOnly;
 static bool Demangle;
@@ -1624,9 +1626,23 @@ static void dumpSymbolsFromDLInfoMachO(MachOObjectFile &MachO) {
   }
 }
 
+static bool shouldDump(SymbolicFile &Obj) {
+  // The -X option is currently only implemented for XCOFF, ELF, and IR object
+  // files. The option isn't fundamentally impossible with other formats, just
+  // isn't implemented.
+  if (!isa<XCOFFObjectFile>(Obj) && !isa<ELFObjectFileBase>(Obj) &&
+      !isa<IRObjectFile>(Obj))
+    return true;
+
+  return isSymbolList64Bit(Obj) ? BitMode != BitModeTy::Bit32
+                                : BitMode != BitModeTy::Bit64;
+}
+
 static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
                                       StringRef ArchiveName = {},
                                       StringRef ArchitectureName = {}) {
+  if (!shouldDump(Obj))
+    return;
   auto Symbols = Obj.symbols();
   std::vector<VersionEntry> SymbolVersions;
   if (DynamicSyms) {
@@ -1830,7 +1846,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
           }
           if (!checkMachOAndArchFlags(O, Filename))
             return;
-          if (!PrintFileName) {
+          if (!PrintFileName && shouldDump(*O)) {
             outs() << "\n";
             if (isa<MachOObjectFile>(O)) {
               outs() << Filename << "(" << O->getFileName() << ")";
@@ -2168,6 +2184,18 @@ int main(int argc, char **argv) {
   UndefinedOnly = Args.hasArg(OPT_undefined_only);
   WithoutAliases = Args.hasArg(OPT_without_aliases);
 
+  StringRef Mode = Args.getLastArgValue(OPT_X, "any");
+  if (Mode == "32")
+    BitMode = BitModeTy::Bit32;
+  else if (Mode == "64")
+    BitMode = BitModeTy::Bit64;
+  else if (Mode == "32_64")
+    BitMode = BitModeTy::Bit32_64;
+  else if (Mode == "any")
+    BitMode = BitModeTy::Any;
+  else
+    error("-X value should be one of: 32, 64, 32_64, (default) any");
+
   // Mach-O specific options.
   FormatMachOasHex = Args.hasArg(OPT_x);
   AddDyldInfo = Args.hasArg(OPT_add_dyldinfo);


        


More information about the llvm-commits mailing list