diff --git a/llvm/test/tools/llvm-nm/elf-archive.test b/llvm/test/tools/llvm-nm/elf-archive.test --- a/llvm/test/tools/llvm-nm/elf-archive.test +++ b/llvm/test/tools/llvm-nm/elf-archive.test @@ -5,17 +5,17 @@ # RUN: rm -f %t.symtab # RUN: llvm-ar rc %t.symtab %t1.o %t2.o -# RUN: llvm-nm %t.symtab | FileCheck %s --match-full-lines +# RUN: llvm-nm %t.symtab | FileCheck %s -DARCHIVE=%t.symtab -DOBJ=%basename_t --match-full-lines # RUN: rm -f %t.nosymtab # RUN: llvm-ar rcS %t.nosymtab %t1.o %t2.o -# RUN: llvm-nm %t.nosymtab | FileCheck %s --match-full-lines +# RUN: llvm-nm %t.nosymtab | FileCheck %s -DARCHIVE=%t.nosymtab -DOBJ=%basename_t --match-full-lines -# CHECK: {{.*}}1.o: +# CHECK: [[ARCHIVE]]([[OBJ]].tmp1.o): # CHECK-NEXT: 00000002 D global_data_symbol # CHECK-NEXT: 00000000 T global_function_symbol # CHECK-EMPTY: -# CHECK-NEXT: {{.*}}2.o: +# CHECK-NEXT: [[ARCHIVE]]([[OBJ]].tmp2.o): # CHECK-NEXT: 00000001 D another_data_symbol --- !ELF 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 @@ -61,15 +61,15 @@ # 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: +# RUN: FileCheck --check-prefixes=ARC32,XCOFF32 %s -DFILE=%basename_t -DARCHIVEFILE=%t.a --implicit-check-not={{.}} +# ARC32: [[ARCHIVEFILE]]([[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: +# RUN: FileCheck --check-prefixes=ARC64,XCOFF64 -DFILE=%basename_t -DARCHIVEFILE=%t.a %s --implicit-check-not={{.}} +# ARC64: [[ARCHIVEFILE]]([[FILE]].tmp_xcoff64.o): # XCOFF64: var_0x1F7 # RUN: llvm-nm --format=just-symbols %t_xcoff32.o %t_xcoff64.o | \ @@ -86,15 +86,15 @@ # 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: FileCheck --check-prefixes=ARCHIVE-BOTH -DFILE=%basename_t -DARCHIVEFILE=%t.a --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: FileCheck --check-prefixes=ARCHIVE-BOTH -DFILE=%basename_t -DARCHIVEFILE=%t.a --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 +# RUN: FileCheck --check-prefixes=ARCHIVE-BOTH -DFILE=%basename_t -DARCHIVEFILE=%t.a --match-full-lines %s -# ARCHIVE-BOTH: [[FILE]].tmp_xcoff32.o: +# ARCHIVE-BOTH: [[ARCHIVEFILE]]([[FILE]].tmp_xcoff32.o): # ARCHIVE-BOTH-NEXT: var_0x1DF{{[[:space:]]}} -# ARCHIVE-BOTH-NEXT: [[FILE]].tmp_xcoff64.o: +# ARCHIVE-BOTH-NEXT: [[ARCHIVEFILE]]([[FILE]].tmp_xcoff64.o): # ARCHIVE-BOTH-NEXT: var_0x1F7 # RUN: llvm-nm --format=just-symbols -X64 %t_xcoff32.o | count 0 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 @@ -1154,7 +1154,7 @@ // getNsectForSegSect() is used to implement the Mach-O "-s segname sectname" // option to dump only those symbols from that section in a Mach-O file. -// It is called once for each Mach-O file from dumpSymbolNamesFromObject() +// It is called once for each Mach-O file from getSymbolNamesFromObject() // to get the section number for that named section from the command line // arguments. It returns the section number for that section in the Mach-O // file or zero it is not present. @@ -1176,7 +1176,7 @@ // getNsectInMachO() is used to implement the Mach-O "-s segname sectname" // option to dump only those symbols from that section in a Mach-O file. // It is called once for each symbol in a Mach-O file from -// dumpSymbolNamesFromObject() and returns the section number for that symbol +// getSymbolNamesFromObject() and returns the section number for that symbol // if it is in a section, else it returns 0. static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) { DataRefImpl Symb = Sym.getRawDataRefImpl(); @@ -1742,18 +1742,7 @@ } } -static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, - StringRef ArchiveName = {}, - StringRef ArchitectureName = {}) { - if (!shouldDump(Obj)) - return; - - if (ExportSymbols && Obj.isXCOFF()) { - XCOFFObjectFile *XCOFFObj = cast(&Obj); - getXCOFFExports(XCOFFObj, ArchiveName); - return; - } - +static void getSymbolNamesFromObject(SymbolicFile &Obj) { auto Symbols = Obj.symbols(); std::vector SymbolVersions; if (DynamicSyms) { @@ -1857,19 +1846,50 @@ // all symbols from the dyld export trie as well as the bind info. if (MachO && !NoDyldInfo) dumpSymbolsFromDLInfoMachO(*MachO); +} - if (ExportSymbols) +static void printObjectNamesInfo(StringRef ArchiveName, + StringRef ArchitectureName, + StringRef OjectFileName) { + outs() << "\n"; + if (ArchiveName.empty()) + outs() << OjectFileName; + else + outs() << ArchiveName << "(" << OjectFileName << ")"; + if (!ArchitectureName.empty()) + outs() << " (for architecture " << ArchitectureName << ")"; + outs() << ":\n"; +} + +static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool PrintName, + bool PrintObjectNameInfo, + StringRef ArchiveName = {}, + StringRef ArchitectureName = {}, + StringRef ObjectName = {}) { + if (!shouldDump(Obj)) return; - CurrentFilename = Obj.getFileName(); + if (ExportSymbols && Obj.isXCOFF()) { + XCOFFObjectFile *XCOFFObj = cast(&Obj); + getXCOFFExports(XCOFFObj, ArchiveName); + return; + } - if (Symbols.empty() && SymbolList.empty() && !Quiet) { + if (PrintObjectNameInfo && !ExportSymbols) + printObjectNamesInfo(ArchiveName, ArchitectureName, + ObjectName.empty() ? Obj.getFileName() : ObjectName); + + getSymbolNamesFromObject(Obj); + if (ExportSymbols) + return; + CurrentFilename = Obj.getFileName(); + if (Obj.symbols().empty() && SymbolList.empty() && !Quiet) { writeFileName(errs(), ArchiveName, ArchitectureName); errs() << "no symbols\n"; } sortSymbolList(); - printSymbolList(Obj, printName, ArchiveName, ArchitectureName); + printSymbolList(Obj, PrintName, ArchiveName, ArchitectureName); } // checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file @@ -1948,15 +1968,8 @@ } if (!checkMachOAndArchFlags(O, Filename)) return; - if (!PrintFileName && shouldDump(*O) && !ExportSymbols) { - outs() << "\n"; - if (isa(O)) { - outs() << Filename << "(" << O->getFileName() << ")"; - } else - outs() << O->getFileName(); - outs() << ":\n"; - } - dumpSymbolNamesFromObject(*O, false, Filename); + dumpSymbolNamesFromObject(*O, false, !PrintFileName, Filename, {}, + O->getFileName()); } } if (Err) @@ -1982,16 +1995,11 @@ ArchitectureName.clear(); if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); - if (ArchFlags.size() > 1) { - if (PrintFileName) - ArchitectureName = I->getArchFlagName(); - else - outs() << "\n" - << Obj.getFileName() << " (for architecture " - << I->getArchFlagName() << ")" - << ":\n"; - } - dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); + if (ArchFlags.size() > 1) + ArchitectureName = I->getArchFlagName(); + dumpSymbolNamesFromObject(Obj, false, + (ArchFlags.size() > 1) && !PrintFileName, + ArchiveName, ArchitectureName); } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { error(std::move(E), Filename, @@ -2015,20 +2023,10 @@ continue; } if (SymbolicFile *O = dyn_cast(&*ChildOrErr.get())) { - if (PrintFileName) { - ArchiveName = std::string(A->getFileName()); - if (ArchFlags.size() > 1) - ArchitectureName = I->getArchFlagName(); - } else { - outs() << "\n" << A->getFileName(); - outs() << "(" << O->getFileName() << ")"; - if (ArchFlags.size() > 1) { - outs() << " (for architecture " << I->getArchFlagName() - << ")"; - } - outs() << ":\n"; - } - dumpSymbolNamesFromObject(*O, false, ArchiveName, + ArchiveName = std::string(A->getFileName()); + if (ArchFlags.size() > 1) + ArchitectureName = I->getArchFlagName(); + dumpSymbolNamesFromObject(*O, false, !PrintFileName, ArchiveName, ArchitectureName); } } @@ -2066,7 +2064,7 @@ std::string ArchiveName; if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); - dumpSymbolNamesFromObject(Obj, false); + dumpSymbolNamesFromObject(Obj, false, false); } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) error(std::move(E), Filename); else if (Expected> AOrErr = I->getAsArchive()) { @@ -2082,13 +2080,8 @@ continue; } if (SymbolicFile *O = dyn_cast(&*ChildOrErr.get())) { - if (PrintFileName) - ArchiveName = std::string(A->getFileName()); - else - outs() << "\n" - << A->getFileName() << "(" << O->getFileName() << ")" - << ":\n"; - dumpSymbolNamesFromObject(*O, false, ArchiveName); + ArchiveName = std::string(A->getFileName()); + dumpSymbolNamesFromObject(*O, false, !PrintFileName, ArchiveName); } } if (Err) @@ -2118,18 +2111,10 @@ ArchitectureName.clear(); if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); - if (PrintFileName) { - if (isa(Obj) && moreThanOneArch) - ArchitectureName = O.getArchFlagName(); - } else { - if (moreThanOneArch) - outs() << "\n"; - outs() << Obj.getFileName(); - if (isa(Obj) && moreThanOneArch) - outs() << " (for architecture " << O.getArchFlagName() << ")"; - outs() << ":\n"; - } - dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); + if (isa(Obj) && moreThanOneArch) + ArchitectureName = O.getArchFlagName(); + dumpSymbolNamesFromObject(Obj, false, !PrintFileName, ArchiveName, + ArchitectureName); } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { error(std::move(E), Filename, moreThanOneArch ? StringRef(O.getArchFlagName()) : StringRef()); @@ -2147,21 +2132,11 @@ continue; } if (SymbolicFile *F = dyn_cast(&*ChildOrErr.get())) { - if (PrintFileName) { - ArchiveName = std::string(A->getFileName()); - if (isa(F) && moreThanOneArch) - ArchitectureName = O.getArchFlagName(); - } else { - outs() << "\n" << A->getFileName(); - if (isa(F)) { - outs() << "(" << F->getFileName() << ")"; - if (moreThanOneArch) - outs() << " (for architecture " << O.getArchFlagName() << ")"; - } else - outs() << ":" << F->getFileName(); - outs() << ":\n"; - } - dumpSymbolNamesFromObject(*F, false, ArchiveName, ArchitectureName); + ArchiveName = std::string(A->getFileName()); + if (isa(F) && moreThanOneArch) + ArchitectureName = O.getArchFlagName(); + dumpSymbolNamesFromObject(*F, false, !PrintFileName, ArchiveName, + ArchitectureName); } } if (Err) @@ -2203,13 +2178,10 @@ continue; if (!AddInlinedInfo && !I.isTopLevelLib()) continue; - if (auto ObjOrErr = I.getAsObjectFile()) { - outs() << "\n" - << I.getInstallName() << " (for architecture " << ArchName << ")" - << ":\n"; - dumpSymbolNamesFromObject(*ObjOrErr.get(), false, {}, ArchName); - } else if (Error E = - isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { + if (auto ObjOrErr = I.getAsObjectFile()) + dumpSymbolNamesFromObject(*ObjOrErr.get(), false, true, {}, ArchName, + I.getInstallName()); + else if (Error E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { error(std::move(E), Filename, ArchName); } } @@ -2223,7 +2195,7 @@ } if (!checkMachOAndArchFlags(O, Filename)) return; - dumpSymbolNamesFromObject(*O, true); + dumpSymbolNamesFromObject(*O, true, false); } static void dumpSymbolNamesFromFile(std::string &Filename) {