summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzhijian <zhijian@ca.ibm.com>2022-03-09 14:45:27 -0500
committerzhijian <zhijian@ca.ibm.com>2022-03-09 14:45:27 -0500
commitbef2592c092f453078d8762d6d3d9c811f23c25d (patch)
tree49d641e3fe25ac4b5833810ee6af7a22da84a002
parent0a4dec6cc2bf17acacc883cd897481028f1cf425 (diff)
[llvm-nm]add helper function to print out the object file name, archive name, architecture name
Summary: 1. added helper function printObjectNamesInfo() to print out object file name, archive name, architecture name. 2. One small behaviors change. in the function dumpMachOUniversalBinaryArchAll , delete the functionality: if (moreThanOneArch) outs() << "\n"; Reviewer : James Henderson,Fangrui Song Differential Revision: https://reviews.llvm.org/D120357
-rw-r--r--llvm/test/Object/nm-universal-binary.test32
-rw-r--r--llvm/tools/llvm-nm/llvm-nm.cpp222
2 files changed, 131 insertions, 123 deletions
diff --git a/llvm/test/Object/nm-universal-binary.test b/llvm/test/Object/nm-universal-binary.test
index 379f8cdc776d..1a1d80a7aee3 100644
--- a/llvm/test/Object/nm-universal-binary.test
+++ b/llvm/test/Object/nm-universal-binary.test
@@ -35,25 +35,27 @@ CHECK-OBJ-armv7m: error: file: {{.*}} does not contain architecture
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: 0000000000000068 s EH_frame0
-CHECK-AR: 000000000000003b s L_.str
-CHECK-AR: 0000000000000000 T _main
-CHECK-AR: 0000000000000080 S _main.eh
-CHECK-AR: U _printf
+CHECK-AR: {{^$}}
+CHECK-AR-NEXT: 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
+CHECK-AR: 0000000000000080 S _main.eh
+CHECK-AR: U _printf
CHECK-AR: macho-universal-archive.x86_64.i386(foo.o) (for architecture i386):
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: 00000008 D _bar
-CHECK-64-AR: 00000000 T _foo
-CHECK-64-AR: macho-universal64-archive.x86_64.i386(hello.o) (for architecture x86_64):
-CHECK-64-AR: 0000000000000068 s EH_frame0
-CHECK-64-AR: 000000000000003b s L_.str
-CHECK-64-AR: 0000000000000000 T _main
-CHECK-64-AR: 0000000000000080 S _main.eh
-CHECK-64-AR: U _printf
+CHECK-64-AR: {{^$}}
+CHECK-64-AR-NEXT: 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):
+CHECK-64-AR: 0000000000000068 s EH_frame0
+CHECK-64-AR: 000000000000003b s L_.str
+CHECK-64-AR: 0000000000000000 T _main
+CHECK-64-AR: 0000000000000080 S _main.eh
+CHECK-64-AR: U _printf
CHECK-AR-i386: macho-universal-archive.x86_64.i386(foo.o):
CHECK-AR-i386: 00000008 D _bar
diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp
index 5e67e76447cd..4e415f2fa777 100644
--- a/llvm/tools/llvm-nm/llvm-nm.cpp
+++ b/llvm/tools/llvm-nm/llvm-nm.cpp
@@ -1154,7 +1154,7 @@ static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I,
// 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 @@ static unsigned getNsectForSegSect(MachOObjectFile *Obj) {
// 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,37 +1742,37 @@ static void getXCOFFExports(XCOFFObjectFile *XCOFFObj, StringRef ArchiveName) {
}
}
-static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
- StringRef ArchiveName = {},
- StringRef ArchitectureName = {}) {
- if (!shouldDump(Obj))
- return;
-
- if (ExportSymbols && Obj.isXCOFF()) {
- XCOFFObjectFile *XCOFFObj = cast<XCOFFObjectFile>(&Obj);
- getXCOFFExports(XCOFFObj, ArchiveName);
- return;
- }
+static Expected<SymbolicFile::basic_symbol_iterator_range>
+getDynamicSyms(SymbolicFile &Obj) {
+ const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
+ if (!E)
+ return createError("File format has no dynamic symbol table");
+ return E->getDynamicSymbolIterators();
+}
+// Returns false if an error is encounted or true otherwise.
+static bool getSymbolNamesFromObject(SymbolicFile &Obj) {
auto Symbols = Obj.symbols();
std::vector<VersionEntry> SymbolVersions;
+
if (DynamicSyms) {
- const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
- if (!E) {
- error("File format has no dynamic symbol table", Obj.getFileName());
- return;
+ Expected<SymbolicFile::basic_symbol_iterator_range> SymbolsOrErr =
+ getDynamicSyms(Obj);
+ if (!SymbolsOrErr) {
+ error(SymbolsOrErr.takeError(), Obj.getFileName());
+ return false;
+ }
+ Symbols = *SymbolsOrErr;
+ if (const auto *E = dyn_cast<ELFObjectFileBase>(&Obj)) {
+ if (Expected<std::vector<VersionEntry>> VersionsOrErr =
+ E->readDynsymVersions())
+ SymbolVersions = std::move(*VersionsOrErr);
+ else
+ WithColor::warning(errs(), ToolName)
+ << "unable to read symbol versions: "
+ << toString(VersionsOrErr.takeError()) << "\n";
}
- Symbols = E->getDynamicSymbolIterators();
-
- if (Expected<std::vector<VersionEntry>> VersionsOrErr =
- E->readDynsymVersions())
- SymbolVersions = std::move(*VersionsOrErr);
- else
- WithColor::warning(errs(), ToolName)
- << "unable to read symbol versions: "
- << toString(VersionsOrErr.takeError()) << "\n";
}
-
// If a "-s segname sectname" option was specified and this is a Mach-O
// file get the section number for that section in this object file.
unsigned int Nsect = 0;
@@ -1781,7 +1781,7 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
Nsect = getNsectForSegSect(MachO);
// If this section is not in the object file no symbols are printed.
if (Nsect == 0)
- return;
+ return false;
}
if (!(MachO && DyldInfoOnly)) {
@@ -1791,7 +1791,7 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
if (!SymFlagsOrErr) {
error(SymFlagsOrErr.takeError(), Obj.getFileName());
- return;
+ return false;
}
// Don't drop format specifc symbols for ARM and AArch64 ELF targets, they
@@ -1857,19 +1857,64 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
// all symbols from the dyld export trie as well as the bind info.
if (MachO && !NoDyldInfo)
dumpSymbolsFromDLInfoMachO(*MachO);
+ return true;
+}
- 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 Expected<bool> hasSymbols(SymbolicFile &Obj) {
+ if (DynamicSyms) {
+ Expected<SymbolicFile::basic_symbol_iterator_range> DynamicSymsOrErr =
+ getDynamicSyms(Obj);
+ if (!DynamicSymsOrErr)
+ return DynamicSymsOrErr.takeError();
+ return !DynamicSymsOrErr->empty();
+ }
+ return !Obj.symbols().empty();
+}
+
+static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool PrintSymbolObject,
+ bool PrintObjectLabel,
+ StringRef ArchiveName = {},
+ StringRef ArchitectureName = {},
+ StringRef ObjectName = {},
+ bool PrintArchiveName = true) {
+ if (!shouldDump(Obj))
return;
+ if (ExportSymbols && Obj.isXCOFF()) {
+ XCOFFObjectFile *XCOFFObj = cast<XCOFFObjectFile>(&Obj);
+ getXCOFFExports(XCOFFObj, ArchiveName);
+ return;
+ }
+
+ if (PrintObjectLabel && !ExportSymbols)
+ printObjectLabel(PrintArchiveName, ArchiveName, ArchitectureName,
+ ObjectName.empty() ? Obj.getFileName() : ObjectName);
+ if (!getSymbolNamesFromObject(Obj) || ExportSymbols)
+ return;
CurrentFilename = Obj.getFileName();
- if (Symbols.empty() && SymbolList.empty() && !Quiet) {
+ // If there is an error in hasSymbols(), the error should be encountered in
+ // function getSymbolNamesFromObject first.
+ if (!cantFail(hasSymbols(Obj)) && 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 +1993,10 @@ static void dumpArchive(Archive *A, std::string &Filename,
}
if (!checkMachOAndArchFlags(O, Filename))
return;
- if (!PrintFileName && shouldDump(*O) && !ExportSymbols) {
- outs() << "\n";
- if (isa<MachOObjectFile>(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 +2022,11 @@ static void dumpMachOUniversalBinaryMatchArchFlags(MachOUniversalBinary *UB,
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 +2050,11 @@ static void dumpMachOUniversalBinaryMatchArchFlags(MachOUniversalBinary *UB,
continue;
}
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*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 +2092,8 @@ static bool dumpMachOUniversalBinaryMatchHost(MachOUniversalBinary *UB,
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<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
@@ -2082,13 +2109,9 @@ static bool dumpMachOUniversalBinaryMatchHost(MachOUniversalBinary *UB,
continue;
}
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*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 +2141,10 @@ static void dumpMachOUniversalBinaryArchAll(MachOUniversalBinary *UB,
ArchitectureName.clear();
if (ObjOrErr) {
ObjectFile &Obj = *ObjOrErr.get();
- if (PrintFileName) {
- if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
- ArchitectureName = O.getArchFlagName();
- } else {
- if (moreThanOneArch)
- outs() << "\n";
- outs() << Obj.getFileName();
- if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
- outs() << " (for architecture " << O.getArchFlagName() << ")";
- outs() << ":\n";
- }
- dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName);
+ if (isa<MachOObjectFile>(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 +2162,12 @@ static void dumpMachOUniversalBinaryArchAll(MachOUniversalBinary *UB,
continue;
}
if (SymbolicFile *F = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
- if (PrintFileName) {
- ArchiveName = std::string(A->getFileName());
- if (isa<MachOObjectFile>(F) && moreThanOneArch)
- ArchitectureName = O.getArchFlagName();
- } else {
- outs() << "\n" << A->getFileName();
- if (isa<MachOObjectFile>(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<MachOObjectFile>(F) && moreThanOneArch)
+ ArchitectureName = O.getArchFlagName();
+ dumpSymbolNamesFromObject(*F, /*PrintSymbolObject=*/false,
+ !PrintFileName, ArchiveName,
+ ArchitectureName);
}
}
if (Err)
@@ -2203,13 +2209,12 @@ static void dumpTapiUniversal(TapiUniversal *TU, std::string &Filename) {
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 +2228,8 @@ static void dumpSymbolicFile(SymbolicFile *O, std::string &Filename) {
}
if (!checkMachOAndArchFlags(O, Filename))
return;
- dumpSymbolNamesFromObject(*O, true);
+ dumpSymbolNamesFromObject(*O, /*PrintSymbolObject=*/true,
+ /*PrintObjectLabel=*/false);
}
static void dumpSymbolNamesFromFile(std::string &Filename) {