diff --git a/llvm/test/Object/nm-universal-binary.test b/llvm/test/Object/nm-universal-binary.test --- a/llvm/test/Object/nm-universal-binary.test +++ b/llvm/test/Object/nm-universal-binary.test @@ -35,7 +35,7 @@ CHECK-OBJ-foobar: error: for the --arch option: Unknown architecture named 'foobar' -CHECK-AR: macho-universal-archive.x86_64.i386(hello.o) (for architecture x86_64): +CHECK-AR: {{[[:space:]].*}}macho-universal-archive.x86_64.i386(hello.o) (for architecture x86_64): CHECK-AR: 0000000000000068 s EH_frame0 CHECK-AR: 000000000000003b s L_.str CHECK-AR: 0000000000000000 T _main @@ -45,7 +45,7 @@ CHECK-AR: 00000008 D _bar CHECK-AR: 00000000 T _foo -CHECK-64-AR: macho-universal64-archive.x86_64.i386(foo.o) (for architecture i386): +CHECK-64-AR: {{[[:space:]].*}}macho-universal64-archive.x86_64.i386(foo.o) (for architecture i386): CHECK-64-AR: 00000008 D _bar CHECK-64-AR: 00000000 T _foo CHECK-64-AR: macho-universal64-archive.x86_64.i386(hello.o) (for architecture x86_64): 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,19 +1742,10 @@ } } -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; - } - - auto Symbols = Obj.symbols(); +static void +getSymbolNamesFromObject(SymbolicFile &Obj, + SymbolicFile::basic_symbol_iterator_range &Symbols) { + Symbols = Obj.symbols(); std::vector SymbolVersions; if (DynamicSyms) { const auto *E = dyn_cast(&Obj); @@ -1857,19 +1848,51 @@ // all symbols from the dyld export trie as well as the bind info. if (MachO && !NoDyldInfo) dumpSymbolsFromDLInfoMachO(*MachO); +} - if (ExportSymbols) +static void printObjectLabel(bool PrintArchiveName, StringRef ArchiveName, + StringRef ArchitectureName, + StringRef ObjectFileName) { + outs() << "\n"; + if (ArchiveName.empty() || !PrintArchiveName) + outs() << ObjectFileName; + else + outs() << ArchiveName << "(" << ObjectFileName << ")"; + if (!ArchitectureName.empty()) + outs() << " (for architecture " << ArchitectureName << ")"; + outs() << ":\n"; +} + +static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool PrintSymbolObject, + bool PrintObjectLabel, + StringRef ArchiveName = {}, + StringRef ArchitectureName = {}, + StringRef ObjectName = {}, + bool PrintArchiveName = true) { + if (!shouldDump(Obj)) return; - CurrentFilename = Obj.getFileName(); + if (ExportSymbols && Obj.isXCOFF()) { + XCOFFObjectFile *XCOFFObj = cast(&Obj); + getXCOFFExports(XCOFFObj, ArchiveName); + return; + } + if (PrintObjectLabel && !ExportSymbols) + printObjectLabel(PrintArchiveName, ArchiveName, ArchitectureName, + ObjectName.empty() ? Obj.getFileName() : ObjectName); + SymbolicFile::basic_symbol_iterator_range Symbols = Obj.symbols(); + getSymbolNamesFromObject(Obj, Symbols); + if (ExportSymbols) + return; + CurrentFilename = Obj.getFileName(); if (Symbols.empty() && SymbolList.empty() && !Quiet) { writeFileName(errs(), ArchiveName, ArchitectureName); errs() << "no symbols\n"; } sortSymbolList(); - printSymbolList(Obj, printName, ArchiveName, ArchitectureName); + printSymbolList(Obj, PrintSymbolObject, ArchiveName, ArchitectureName); } // checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file @@ -1948,15 +1971,10 @@ } 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, /*PrintSymbolObject=*/false, !PrintFileName, + Filename, + /*ArchitectureName=*/{}, O->getFileName(), + /*PrintArchiveName=*/false); } } if (Err) @@ -1982,16 +2000,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, /*PrintSymbolObject=*/false, + (ArchFlags.size() > 1) && !PrintFileName, + ArchiveName, ArchitectureName); } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { error(std::move(E), Filename, @@ -2015,20 +2028,11 @@ 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, /*PrintSymbolObject=*/false, + !PrintFileName, ArchiveName, ArchitectureName); } } @@ -2066,7 +2070,8 @@ std::string ArchiveName; if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); - dumpSymbolNamesFromObject(Obj, false); + dumpSymbolNamesFromObject(Obj, /*PrintSymbolObject=*/false, + /*PrintObjectLabel=*/false); } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) error(std::move(E), Filename); else if (Expected> AOrErr = I->getAsArchive()) { @@ -2082,13 +2087,9 @@ 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, /*PrintSymbolObject=*/false, + !PrintFileName, ArchiveName); } } if (Err) @@ -2118,18 +2119,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, /*PrintSymbolObject=*/false, + !PrintFileName, ArchiveName, ArchitectureName); } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { error(std::move(E), Filename, moreThanOneArch ? StringRef(O.getArchFlagName()) : StringRef()); @@ -2147,21 +2140,12 @@ 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, /*PrintSymbolObject=*/false, + !PrintFileName, ArchiveName, + ArchitectureName); } } if (Err) @@ -2203,13 +2187,12 @@ 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(), /*PrintSymbolObject=*/false, + /*PrintObjectLabel=*/true, + /*ArchiveName=*/{}, ArchName, + I.getInstallName()); + else if (Error E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { error(std::move(E), Filename, ArchName); } } @@ -2223,7 +2206,8 @@ } if (!checkMachOAndArchFlags(O, Filename)) return; - dumpSymbolNamesFromObject(*O, true); + dumpSymbolNamesFromObject(*O, /*PrintSymbolObject=*/true, + /*PrintObjectLabel=*/false); } static void dumpSymbolNamesFromFile(std::string &Filename) {