diff --git a/llvm/docs/CommandGuide/llvm-nm.rst b/llvm/docs/CommandGuide/llvm-nm.rst --- a/llvm/docs/CommandGuide/llvm-nm.rst +++ b/llvm/docs/CommandGuide/llvm-nm.rst @@ -141,6 +141,15 @@ any Process all the supported object files. + On AIX OS, the default is to process 32-bit object files only and to ignore + 64-bit objects. The can be changed by setting the OBJECT_MODE environment + variable. For example, OBJECT_MODE=64 causes :program:`llvm-nm` to process + 64-bit objects and ignore 32-bit objects. The -X flag overrides the OBJECT_MODE + variable. + + On other operating systems, the default is to process all object files: the + OBJECT_MODE environment variable is not supported. + .. option:: --debug-syms, -a Show all symbols, even those usually suppressed. diff --git a/llvm/test/tools/llvm-nm/option-X-AIX.test b/llvm/test/tools/llvm-nm/option-X-AIX.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-nm/option-X-AIX.test @@ -0,0 +1,52 @@ +# REQUIRES: system-aix +## Test default "-X" option and environment variable "OBJECT_MODE" on AIX OS. + +# RUN: yaml2obj -DFLAG=0x1DF %s -o %t_xcoff32.o +# RUN: yaml2obj -DFLAG=0x1F7 %s -o %t_xcoff64.o +# RUN: rm -rf %t.a +# RUN: unset OBJECT_MODE +# RUN: env OBJECT_MODE=any llvm-ar -q -c %t.a %t_xcoff32.o %t_xcoff64.o + +## Test default "-X" option. +# RUN: llvm-nm --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ +# RUN: FileCheck -DFILE32=%t_xcoff32.o --check-prefixes=XCOFF32 %s --implicit-check-not={{.}} + +## Test environment variable "OBJECT_MODE". +# RUN: env OBJECT_MODE=32 llvm-nm --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ +# RUN: FileCheck -DFILE32=%t_xcoff32.o --check-prefixes=XCOFF32 %s --implicit-check-not={{.}} +# RUN: env OBJECT_MODE=64 llvm-nm --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ +# RUN: FileCheck -DFILE64=%t_xcoff64.o --check-prefixes=XCOFF64 %s --implicit-check-not={{.}} +# RUN: env OBJECT_MODE=32_64 llvm-nm --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ +# RUN: FileCheck --check-prefixes=XCOFF32,XCOFF64 %s -DFILE32=%t_xcoff32.o -DFILE64=%t_xcoff64.o --match-full-lines +# RUN: env OBJECT_MODE=any llvm-nm --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ +# RUN: FileCheck --check-prefixes=XCOFF32,XCOFF64 %s -DFILE32=%t_xcoff32.o -DFILE64=%t_xcoff64.o --match-full-lines +# RUN: env OBJECT_MODE=32 llvm-nm --format=just-symbols %t.a | \ +# RUN: FileCheck -DFILE=%basename_t --check-prefixes=ARC32 %s --implicit-check-not={{.}} +# RUN: env OBJECT_MODE=64 llvm-nm --format=just-symbols %t.a | \ +# RUN: FileCheck -DFILE=%basename_t --check-prefixes=ARC64 %s --implicit-check-not={{.}} + +## Test -X option overrides environment variable "OBJECT_MODE". +# RUN: env OBJECT_MODE=any llvm-nm -X32 --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ +# RUN: FileCheck -DFILE32=%t_xcoff32.o --check-prefixes=XCOFF32 %s --implicit-check-not={{.}} +# RUN: env OBJECT_MODE=any llvm-nm -X64 --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ +# RUN: FileCheck -DFILE64=%t_xcoff64.o --check-prefixes=XCOFF64 %s --implicit-check-not={{.}} +# RUN: env OBJECT_MODE=any llvm-nm -X32_64 --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ +# RUN: FileCheck --check-prefixes=XCOFF32,XCOFF64 %s -DFILE32=%t_xcoff32.o -DFILE64=%t_xcoff64.o --match-full-lines +# RUN: env OBJECT_MODE=32 llvm-nm -Xany --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ +# RUN: FileCheck --check-prefixes=XCOFF32,XCOFF64 %s -DFILE32=%t_xcoff32.o -DFILE64=%t_xcoff64.o --match-full-lines + +# XCOFF32: [[FILE32]]: +# XCOFF32-NEXT: var_0x1DF +# XCOFF64: [[FILE64]]: +# XCOFF64-NEXT: var_0x1F7 + +# ARC32: [[FILE]].tmp_xcoff32.o: +# ARC32-NEXT: var_0x1DF +# ARC64: [[FILE]].tmp_xcoff64.o: +# ARC64-NEXT: var_0x1F7 + +--- !XCOFF +FileHeader: + MagicNumber: [[FLAG]] +Symbols: + - Name: var_[[FLAG]] diff --git a/llvm/test/tools/llvm-nm/option-X-Non-AIX.test b/llvm/test/tools/llvm-nm/option-X-Non-AIX.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-nm/option-X-Non-AIX.test @@ -0,0 +1,24 @@ +# REQUIRES: !system-aix + +# RUN: yaml2obj -DCLASS=ELFCLASS32 %s -o %t_elf32.o +# RUN: yaml2obj -DCLASS=ELFCLASS64 %s -o %t_elf64.o + +--- !ELF +FileHeader: + Class: [[CLASS]] + Data: ELFDATA2LSB + Type: ET_REL +Symbols: + - Name: [[CLASS]]_var + +## Test that the environment variable "OBJECT_MODE" is ignored on non-AIX OS. +# RUN: env OBJECT_MODE=32 llvm-nm --format=just-symbols %t_elf32.o %t_elf64.o | \ +# RUN: FileCheck %s -DFILE1=%t_elf32.o -DFILE2=%t_elf64.o --match-full-lines +# RUN: env OBJECT_MODE=64 llvm-nm --format=just-symbols %t_elf32.o %t_elf64.o | \ +# RUN: FileCheck %s -DFILE1=%t_elf32.o -DFILE2=%t_elf64.o --match-full-lines + +# CHECK: [[FILE1]]: +# CHECK-NEXT: ELFCLASS32_var +# CHECK-EMPTY: +# CHECK-NEXT: [[FILE2]]: +# CHECK-NEXT: ELFCLASS64_var diff --git a/llvm/test/tools/llvm-nm/option-X.test b/llvm/test/tools/llvm-nm/option-X.test --- a/llvm/test/tools/llvm-nm/option-X.test +++ b/llvm/test/tools/llvm-nm/option-X.test @@ -8,8 +8,6 @@ # 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 | \ @@ -32,8 +30,6 @@ # 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 | \ @@ -85,8 +81,6 @@ # 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 | \ diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -16,6 +16,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/XCOFF.h" #include "llvm/Demangle/Demangle.h" @@ -39,6 +40,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" +#include "llvm/Support/Host.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Program.h" @@ -2371,17 +2373,32 @@ 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") + // Get BitMode from enviornment variable "OBJECT_MODE" for AIX OS, if + // specified. + Triple HostTriple(sys::getProcessTriple()); + if (HostTriple.isOSAIX()) { + BitMode = StringSwitch(getenv("OBJECT_MODE")) + .Case("32", BitModeTy::Bit32) + .Case("64", BitModeTy::Bit64) + .Case("32_64", BitModeTy::Bit32_64) + .Case("any", BitModeTy::Any) + .Default(BitModeTy::Bit32); + } else BitMode = BitModeTy::Any; - else - error("-X value should be one of: 32, 64, 32_64, (default) any"); + + if (Arg *A = Args.getLastArg(OPT_X)) { + StringRef Mode = A->getValue(); + 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);