[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
This commit is contained in:
zhijian 2022-03-09 14:45:27 -05:00
parent 0a4dec6cc2
commit bef2592c09
2 changed files with 131 additions and 123 deletions

View File

@ -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

View File

@ -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) {