#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cctype>
#include <cerrno>
cl::opt<bool> FormatMachOasHex("x", cl::desc("Print symbol entry in hex, "
"Mach-O only"));
+cl::opt<bool> NoLLVMBitcode("no-llvm-bc",
+ cl::desc("Disable LLVM bitcode reader"));
+
bool PrintAddress = true;
bool MultipleFiles = false;
if (!ReverseSort) {
if (A.Address < B.Address)
return true;
- else if (A.Address == B.Address && A.Name < B.Name)
- return true;
- else if (A.Address == B.Address && A.Name == B.Name && A.Size < B.Size)
- return true;
- else
- return false;
- } else {
- if (A.Address > B.Address)
- return true;
- else if (A.Address == B.Address && A.Name > B.Name)
+ if (A.Address == B.Address && A.Name < B.Name)
return true;
- else if (A.Address == B.Address && A.Name == B.Name && A.Size > B.Size)
+ if (A.Address == B.Address && A.Name == B.Name && A.Size < B.Size)
return true;
- else
- return false;
+ return false;
}
+
+ if (A.Address > B.Address)
+ return true;
+ if (A.Address == B.Address && A.Name > B.Name)
+ return true;
+ if (A.Address == B.Address && A.Name == B.Name && A.Size > B.Size)
+ return true;
+ return false;
}
static bool compareSymbolSize(const NMSymbol &A, const NMSymbol &B) {
if (!ReverseSort) {
if (A.Size < B.Size)
return true;
- else if (A.Size == B.Size && A.Name < B.Name)
+ if (A.Size == B.Size && A.Name < B.Name)
return true;
- else if (A.Size == B.Size && A.Name == B.Name && A.Address < B.Address)
+ if (A.Size == B.Size && A.Name == B.Name && A.Address < B.Address)
return true;
- else
- return false;
- } else {
- if (A.Size > B.Size)
- return true;
- else if (A.Size == B.Size && A.Name > B.Name)
- return true;
- else if (A.Size == B.Size && A.Name == B.Name && A.Address > B.Address)
- return true;
- else
- return false;
+ return false;
}
+
+ if (A.Size > B.Size)
+ return true;
+ if (A.Size == B.Size && A.Name > B.Name)
+ return true;
+ if (A.Size == B.Size && A.Name == B.Name && A.Address > B.Address)
+ return true;
+ return false;
}
static bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) {
if (!ReverseSort) {
if (A.Name < B.Name)
return true;
- else if (A.Name == B.Name && A.Size < B.Size)
- return true;
- else if (A.Name == B.Name && A.Size == B.Size && A.Address < B.Address)
- return true;
- else
- return false;
- } else {
- if (A.Name > B.Name)
- return true;
- else if (A.Name == B.Name && A.Size > B.Size)
+ if (A.Name == B.Name && A.Size < B.Size)
return true;
- else if (A.Name == B.Name && A.Size == B.Size && A.Address > B.Address)
+ if (A.Name == B.Name && A.Size == B.Size && A.Address < B.Address)
return true;
- else
- return false;
+ return false;
}
+ if (A.Name > B.Name)
+ return true;
+ if (A.Name == B.Name && A.Size > B.Size)
+ return true;
+ if (A.Name == B.Name && A.Size == B.Size && A.Address > B.Address)
+ return true;
+ return false;
}
-static char isSymbolList64Bit(SymbolicFile *Obj) {
+static char isSymbolList64Bit(SymbolicFile &Obj) {
if (isa<IRObjectFile>(Obj))
return false;
- else if (isa<COFFObjectFile>(Obj))
+ if (isa<COFFObjectFile>(Obj))
return false;
- else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj))
+ if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
return MachO->is64Bit();
- else if (isa<ELF32LEObjectFile>(Obj))
+ if (isa<ELF32LEObjectFile>(Obj))
return false;
- else if (isa<ELF64LEObjectFile>(Obj))
+ if (isa<ELF64LEObjectFile>(Obj))
return true;
- else if (isa<ELF32BEObjectFile>(Obj))
+ if (isa<ELF32BEObjectFile>(Obj))
return false;
- else if (isa<ELF64BEObjectFile>(Obj))
+ if (isa<ELF64BEObjectFile>(Obj))
return true;
- else
- return false;
+ return false;
}
static StringRef CurrentFilename;
outs() << Str;
}
-static void sortAndPrintSymbolList(SymbolicFile *Obj, bool printName,
+static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
std::string ArchiveName,
std::string ArchitectureName) {
if (!NoSort) {
// nm(1) -m output or hex, else if OutputFormat is darwin or we are
// printing Mach-O symbols in hex and not a Mach-O object fall back to
// OutputFormat bsd (see below).
- MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj);
+ MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
if ((OutputFormat == darwin || FormatMachOasHex) && MachO) {
darwinPrintSymbol(MachO, I, SymbolAddrStr, printBlanks);
} else if (OutputFormat == posix) {
}
static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) {
- const coff_symbol *Symb = Obj.getCOFFSymbol(*I);
+ COFFSymbolRef Symb = Obj.getCOFFSymbol(*I);
// OK, this is COFF.
symbol_iterator SymI(I);
return Ret;
uint32_t Characteristics = 0;
- if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) {
+ if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) {
section_iterator SecI = Obj.section_end();
if (error(SymI->getSection(SecI)))
return '?';
Characteristics = Section->Characteristics;
}
- switch (Symb->SectionNumber) {
+ switch (Symb.getSectionNumber()) {
case COFF::IMAGE_SYM_DEBUG:
return 'n';
default:
// Check section type.
if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
return 't';
- else if (Characteristics & COFF::IMAGE_SCN_MEM_READ &&
- ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
- return 'r';
- else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
- return 'd';
- else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
+ return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r';
+ if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
return 'b';
- else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
+ if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
return 'i';
-
// Check for section symbol.
- else if (Symb->isSectionDefinition())
+ if (Symb.isSectionDefinition())
return 's';
}
}
template <class ELFT>
-static bool isObject(ELFObjectFile<ELFT> &Obj, symbol_iterator I) {
+static bool isELFObject(ELFObjectFile<ELFT> &Obj, symbol_iterator I) {
typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
DataRefImpl Symb = I->getRawDataRefImpl();
return ESym->getType() == ELF::STT_OBJECT;
}
-static bool isObject(SymbolicFile *Obj, basic_symbol_iterator I) {
- if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj))
- return isObject(*ELF, I);
- if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj))
- return isObject(*ELF, I);
- if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj))
- return isObject(*ELF, I);
- if (ELF64BEObjectFile *ELF = dyn_cast<ELF64BEObjectFile>(Obj))
- return isObject(*ELF, I);
+static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) {
+ if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(&Obj))
+ return isELFObject(*ELF, I);
+ if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(&Obj))
+ return isELFObject(*ELF, I);
+ if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(&Obj))
+ return isELFObject(*ELF, I);
+ if (ELF64BEObjectFile *ELF = dyn_cast<ELF64BEObjectFile>(&Obj))
+ return isELFObject(*ELF, I);
return false;
}
-static char getNMTypeChar(SymbolicFile *Obj, basic_symbol_iterator I) {
+static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) {
uint32_t Symflags = I->getFlags();
if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) {
char Ret = isObject(Obj, I) ? 'v' : 'w';
char Ret = '?';
if (Symflags & object::SymbolRef::SF_Absolute)
Ret = 'a';
- else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(Obj))
+ else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj))
Ret = getSymbolNMTypeChar(*IR, I);
- else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(Obj))
+ else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj))
Ret = getSymbolNMTypeChar(*COFF, I);
- else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj))
+ else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
Ret = getSymbolNMTypeChar(*MachO, I);
- else if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj))
+ else if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(&Obj))
Ret = getSymbolNMTypeChar(*ELF, I);
- else if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj))
+ else if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(&Obj))
Ret = getSymbolNMTypeChar(*ELF, I);
- else if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj))
+ else if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(&Obj))
Ret = getSymbolNMTypeChar(*ELF, I);
else
- Ret = getSymbolNMTypeChar(*cast<ELF64BEObjectFile>(Obj), I);
+ Ret = getSymbolNMTypeChar(cast<ELF64BEObjectFile>(Obj), I);
if (Symflags & object::SymbolRef::SF_Global)
Ret = toupper(Ret);
return 0;
}
-static void dumpSymbolNamesFromObject(SymbolicFile *Obj, bool printName,
+static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
std::string ArchiveName = std::string(),
std::string ArchitectureName =
std::string()) {
- basic_symbol_iterator IBegin = Obj->symbol_begin();
- basic_symbol_iterator IEnd = Obj->symbol_end();
+ basic_symbol_iterator IBegin = Obj.symbol_begin();
+ basic_symbol_iterator IEnd = Obj.symbol_end();
if (DynamicSyms) {
- if (!Obj->isELF()) {
- error("File format has no dynamic symbol table", Obj->getFileName());
+ if (!Obj.isELF()) {
+ error("File format has no dynamic symbol table", Obj.getFileName());
return;
}
std::pair<symbol_iterator, symbol_iterator> IDyn =
- getELFDynamicSymbolIterators(Obj);
+ getELFDynamicSymbolIterators(&Obj);
IBegin = IDyn.first;
IEnd = IDyn.second;
}
// 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;
- MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj);
+ MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
if (SegSect.size() != 0 && MachO) {
Nsect = getNsectForSegSect(MachO);
// If this section is not in the object file no symbols are printed.
if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific))
continue;
if (WithoutAliases) {
- if (IRObjectFile *IR = dyn_cast<IRObjectFile>(Obj)) {
+ if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) {
const GlobalValue *GV = IR->getSymbolGV(I->getRawDataRefImpl());
if (GV && isa<GlobalAlias>(GV))
continue;
NMSymbol S;
S.Size = UnknownAddressOrSize;
S.Address = UnknownAddressOrSize;
- if ((PrintSize || SizeSort) && isa<ObjectFile>(Obj)) {
+ if (PrintSize && isa<ELFObjectFileBase>(Obj)) {
symbol_iterator SymI = I;
- if (error(SymI->getSize(S.Size)))
- break;
+ S.Size = SymI->getSize();
}
if (PrintAddress && isa<ObjectFile>(Obj))
if (error(symbol_iterator(I)->getAddress(S.Address)))
P += strlen(P) + 1;
}
- CurrentFilename = Obj->getFileName();
+ CurrentFilename = Obj.getFileName();
sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName);
}
// architectures was specificed. If not then an error is generated and this
// routine returns false. Else it returns true.
static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) {
- if (isa<MachOObjectFile>(O) && !ArchAll && ArchFlags.size() != 0) {
- MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O);
- bool ArchFound = false;
- MachO::mach_header H;
- MachO::mach_header_64 H_64;
- Triple T;
- if (MachO->is64Bit()) {
- H_64 = MachO->MachOObjectFile::getHeader64();
- T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype);
- } else {
- H = MachO->MachOObjectFile::getHeader();
- T = MachOObjectFile::getArch(H.cputype, H.cpusubtype);
- }
- unsigned i;
- for (i = 0; i < ArchFlags.size(); ++i) {
- if (ArchFlags[i] == T.getArchName())
- ArchFound = true;
- break;
- }
- if (!ArchFound) {
- error(ArchFlags[i],
- "file: " + Filename + " does not contain architecture");
- return false;
- }
+ MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O);
+
+ if (!MachO || ArchAll || ArchFlags.size() == 0)
+ return true;
+
+ MachO::mach_header H;
+ MachO::mach_header_64 H_64;
+ Triple T;
+ if (MachO->is64Bit()) {
+ H_64 = MachO->MachOObjectFile::getHeader64();
+ T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype);
+ } else {
+ H = MachO->MachOObjectFile::getHeader();
+ T = MachOObjectFile::getArch(H.cputype, H.cpusubtype);
+ }
+ if (std::none_of(
+ ArchFlags.begin(), ArchFlags.end(),
+ [&](const std::string &Name) { return Name == T.getArchName(); })) {
+ error("No architecture specified", Filename);
+ return false;
}
return true;
}
return;
LLVMContext &Context = getGlobalContext();
- ErrorOr<Binary *> BinaryOrErr =
- createBinary(std::move(*BufferOrErr), &Context);
+ ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(
+ BufferOrErr.get()->getMemBufferRef(), NoLLVMBitcode ? nullptr : &Context);
if (error(BinaryOrErr.getError(), Filename))
return;
- std::unique_ptr<Binary> Bin(BinaryOrErr.get());
+ Binary &Bin = *BinaryOrErr.get();
- if (Archive *A = dyn_cast<Archive>(Bin.get())) {
+ if (Archive *A = dyn_cast<Archive>(&Bin)) {
if (ArchiveMap) {
Archive::symbol_iterator I = A->symbol_begin();
Archive::symbol_iterator E = A->symbol_end();
outs() << O->getFileName();
outs() << ":\n";
}
- dumpSymbolNamesFromObject(O, false, Filename);
+ dumpSymbolNamesFromObject(*O, false, Filename);
}
}
return;
}
- if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin.get())) {
+ if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
// If we have a list of architecture flags specified dump only those.
if (!ArchAll && ArchFlags.size() != 0) {
// Look for a slice in the universal binary that matches each ArchFlag.
ArchFound = true;
ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
I->getAsObjectFile();
- std::unique_ptr<Archive> A;
std::string ArchiveName;
std::string ArchitectureName;
ArchiveName.clear();
ArchitectureName.clear();
if (ObjOrErr) {
- std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
+ ObjectFile &Obj = *ObjOrErr.get();
if (ArchFlags.size() > 1) {
if (PrintFileName)
ArchitectureName = I->getArchTypeName();
else
- outs() << "\n" << Obj->getFileName() << " (for architecture "
+ outs() << "\n" << Obj.getFileName() << " (for architecture "
<< I->getArchTypeName() << ")"
<< ":\n";
}
- dumpSymbolNamesFromObject(Obj.get(), false, ArchiveName,
+ dumpSymbolNamesFromObject(Obj, false, ArchiveName,
ArchitectureName);
- } else if (!I->getAsArchive(A)) {
+ } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
+ I->getAsArchive()) {
+ std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
}
outs() << ":\n";
}
- dumpSymbolNamesFromObject(O, false, ArchiveName,
+ dumpSymbolNamesFromObject(*O, false, ArchiveName,
ArchitectureName);
}
}
I != E; ++I) {
if (HostArchName == I->getArchTypeName()) {
ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
- std::unique_ptr<Archive> A;
std::string ArchiveName;
ArchiveName.clear();
if (ObjOrErr) {
- std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
- dumpSymbolNamesFromObject(Obj.get(), false);
- } else if (!I->getAsArchive(A)) {
+ ObjectFile &Obj = *ObjOrErr.get();
+ dumpSymbolNamesFromObject(Obj, false);
+ } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
+ I->getAsArchive()) {
+ std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
outs() << "\n" << A->getFileName() << "(" << O->getFileName()
<< ")"
<< ":\n";
- dumpSymbolNamesFromObject(O, false, ArchiveName);
+ dumpSymbolNamesFromObject(*O, false, ArchiveName);
}
}
}
E = UB->end_objects();
I != E; ++I) {
ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
- std::unique_ptr<Archive> A;
std::string ArchiveName;
std::string ArchitectureName;
ArchiveName.clear();
ArchitectureName.clear();
if (ObjOrErr) {
- std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
+ ObjectFile &Obj = *ObjOrErr.get();
if (PrintFileName) {
- if (isa<MachOObjectFile>(Obj.get()) && moreThanOneArch)
+ if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
ArchitectureName = I->getArchTypeName();
} else {
if (moreThanOneArch)
outs() << "\n";
- outs() << Obj->getFileName();
- if (isa<MachOObjectFile>(Obj.get()) && moreThanOneArch)
+ outs() << Obj.getFileName();
+ if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
outs() << " (for architecture " << I->getArchTypeName() << ")";
outs() << ":\n";
}
- dumpSymbolNamesFromObject(Obj.get(), false, ArchiveName,
- ArchitectureName);
- } else if (!I->getAsArchive(A)) {
+ dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName);
+ } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
+ std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
AI != AE; ++AI) {
ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
outs() << ":" << O->getFileName();
outs() << ":\n";
}
- dumpSymbolNamesFromObject(O, false, ArchiveName, ArchitectureName);
+ dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName);
}
}
}
}
return;
}
- if (SymbolicFile *O = dyn_cast<SymbolicFile>(Bin.get())) {
+ if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) {
if (!checkMachOAndArchFlags(O, Filename))
return;
- dumpSymbolNamesFromObject(O, true);
+ dumpSymbolNamesFromObject(*O, true);
return;
}
error("unrecognizable file type", Filename);
if (ArchFlags[i] == "all") {
ArchAll = true;
} else {
- Triple T = MachOObjectFile::getArch(ArchFlags[i]);
- if (T.getArch() == Triple::UnknownArch)
+ if (!MachOObjectFile::isValidArch(ArchFlags[i]))
error("Unknown architecture named '" + ArchFlags[i] + "'",
"for the -arch option");
}