mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-13 22:00:14 +00:00
[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:
parent
0a4dec6cc2
commit
bef2592c09
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user