summaryrefslogtreecommitdiff
path: root/tools/llvm-nm/llvm-nm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-nm/llvm-nm.cpp')
-rw-r--r--tools/llvm-nm/llvm-nm.cpp415
1 files changed, 266 insertions, 149 deletions
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp
index b812233034eee..9b2f5220badbc 100644
--- a/tools/llvm-nm/llvm-nm.cpp
+++ b/tools/llvm-nm/llvm-nm.cpp
@@ -16,6 +16,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
@@ -138,6 +139,15 @@ cl::opt<bool> ArchiveMap("print-armap", cl::desc("Print the archive map"));
cl::alias ArchiveMaps("M", cl::desc("Alias for --print-armap"),
cl::aliasopt(ArchiveMap), cl::Grouping);
+enum Radix { d, o, x };
+cl::opt<Radix>
+ AddressRadix("radix", cl::desc("Radix (o/d/x) for printing symbol Values"),
+ cl::values(clEnumVal(d, "decimal"), clEnumVal(o, "octal"),
+ clEnumVal(x, "hexadecimal"), clEnumValEnd),
+ cl::init(x));
+cl::alias RadixAlias("t", cl::desc("Alias for --radix"),
+ cl::aliasopt(AddressRadix));
+
cl::opt<bool> JustSymbolName("just-symbol-name",
cl::desc("Print just the symbol's name"));
cl::alias JustSymbolNames("j", cl::desc("Alias for --just-symbol-name"),
@@ -180,6 +190,52 @@ static bool error(std::error_code EC, Twine Path = Twine()) {
return false;
}
+// This version of error() prints the archive name and member name, for example:
+// "libx.a(foo.o)" after the ToolName before the error message. It sets
+// HadError but returns allowing the code to move on to other archive members.
+static void error(llvm::Error E, StringRef FileName, const Archive::Child &C,
+ StringRef ArchitectureName = StringRef()) {
+ HadError = true;
+ errs() << ToolName << ": " << FileName;
+
+ ErrorOr<StringRef> NameOrErr = C.getName();
+ // TODO: if we have a error getting the name then it would be nice to print
+ // the index of which archive member this is and or its offset in the
+ // archive instead of "???" as the name.
+ if (NameOrErr.getError())
+ errs() << "(" << "???" << ")";
+ else
+ errs() << "(" << NameOrErr.get() << ")";
+
+ if (!ArchitectureName.empty())
+ errs() << " (for architecture " << ArchitectureName << ") ";
+
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(std::move(E), OS, "");
+ OS.flush();
+ errs() << " " << Buf << "\n";
+}
+
+// This version of error() prints the file name and which architecture slice it
+// is from, for example: "foo.o (for architecture i386)" after the ToolName
+// before the error message. It sets HadError but returns allowing the code to
+// move on to other architecture slices.
+static void error(llvm::Error E, StringRef FileName,
+ StringRef ArchitectureName = StringRef()) {
+ HadError = true;
+ errs() << ToolName << ": " << FileName;
+
+ if (!ArchitectureName.empty())
+ errs() << " (for architecture " << ArchitectureName << ") ";
+
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(std::move(E), OS, "");
+ OS.flush();
+ errs() << " " << Buf << "\n";
+}
+
namespace {
struct NMSymbol {
uint64_t Address;
@@ -260,15 +316,11 @@ static void darwinPrintSymbol(SymbolicFile &Obj, SymbolListT::iterator I,
// use 1, 2 and 3 for section numbers. See below where they are used to
// print out fake section names.
NType |= MachO::N_SECT;
- if(SymFlags & SymbolRef::SF_Const)
+ if (SymFlags & SymbolRef::SF_Const)
NSect = 3;
else {
IRObjectFile *IRobj = dyn_cast<IRObjectFile>(&Obj);
- char c = getSymbolNMTypeChar(*IRobj, I->Sym);
- if (c == 't')
- NSect = 1;
- else
- NSect = 2;
+ NSect = (getSymbolNMTypeChar(*IRobj, I->Sym) == 't') ? 1 : 2;
}
}
if (SymFlags & SymbolRef::SF_Weak)
@@ -338,7 +390,7 @@ static void darwinPrintSymbol(SymbolicFile &Obj, SymbolListT::iterator I,
MachO::REFERENCE_FLAG_UNDEFINED_LAZY)
outs() << "undefined [lazy bound]) ";
else if ((NDesc & MachO::REFERENCE_TYPE) ==
- MachO::REFERENCE_FLAG_UNDEFINED_LAZY)
+ MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY)
outs() << "undefined [private lazy bound]) ";
else if ((NDesc & MachO::REFERENCE_TYPE) ==
MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY)
@@ -367,7 +419,14 @@ static void darwinPrintSymbol(SymbolicFile &Obj, SymbolListT::iterator I,
outs() << "(?,?) ";
break;
}
- section_iterator Sec = *MachO->getSymbolSection(I->Sym.getRawDataRefImpl());
+ Expected<section_iterator> SecOrErr =
+ MachO->getSymbolSection(I->Sym.getRawDataRefImpl());
+ if (!SecOrErr) {
+ consumeError(SecOrErr.takeError());
+ outs() << "(?,?) ";
+ break;
+ }
+ section_iterator Sec = *SecOrErr;
DataRefImpl Ref = Sec->getRawDataRefImpl();
StringRef SectionName;
MachO->getSectionName(Ref, SectionName);
@@ -538,8 +597,8 @@ static void darwinPrintStab(MachOObjectFile *MachO, SymbolListT::iterator I) {
}
static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
- std::string ArchiveName,
- std::string ArchitectureName) {
+ const std::string &ArchiveName,
+ const std::string &ArchitectureName) {
if (!NoSort) {
std::function<bool(const NMSymbol &, const NMSymbol &)> Cmp;
if (NumericSort)
@@ -570,32 +629,49 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
if (isSymbolList64Bit(Obj)) {
printBlanks = " ";
printDashes = "----------------";
- printFormat = "%016" PRIx64;
+ switch (AddressRadix) {
+ case Radix::o:
+ printFormat = OutputFormat == posix ? "%" PRIo64 : "%016" PRIo64;
+ break;
+ case Radix::x:
+ printFormat = OutputFormat == posix ? "%" PRIx64 : "%016" PRIx64;
+ break;
+ default:
+ printFormat = OutputFormat == posix ? "%" PRId64 : "%016" PRId64;
+ }
} else {
printBlanks = " ";
printDashes = "--------";
- printFormat = "%08" PRIx64;
+ switch (AddressRadix) {
+ case Radix::o:
+ printFormat = OutputFormat == posix ? "%" PRIo64 : "%08" PRIo64;
+ break;
+ case Radix::x:
+ printFormat = OutputFormat == posix ? "%" PRIx64 : "%08" PRIx64;
+ break;
+ default:
+ printFormat = OutputFormat == posix ? "%" PRId64 : "%08" PRId64;
+ }
}
for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end();
I != E; ++I) {
uint32_t SymFlags = I->Sym.getFlags();
bool Undefined = SymFlags & SymbolRef::SF_Undefined;
- if (!Undefined && UndefinedOnly)
- continue;
- if (Undefined && DefinedOnly)
- continue;
bool Global = SymFlags & SymbolRef::SF_Global;
- if (!Global && ExternalOnly)
- continue;
- if (SizeSort && !PrintAddress)
+ if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) ||
+ (!Global && ExternalOnly) || (SizeSort && !PrintAddress))
continue;
if (PrintFileName) {
if (!ArchitectureName.empty())
outs() << "(for architecture " << ArchitectureName << "):";
- if (!ArchiveName.empty())
- outs() << ArchiveName << ":";
- outs() << CurrentFilename << ": ";
+ if (OutputFormat == posix && !ArchiveName.empty())
+ outs() << ArchiveName << "[" << CurrentFilename << "]: ";
+ else {
+ if (!ArchiveName.empty())
+ outs() << ArchiveName << ":";
+ outs() << CurrentFilename << ": ";
+ }
}
if ((JustSymbolName || (UndefinedOnly && isa<MachOObjectFile>(Obj) &&
OutputFormat != darwin)) && OutputFormat != posix) {
@@ -606,8 +682,13 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
char SymbolAddrStr[18] = "";
char SymbolSizeStr[18] = "";
- if (OutputFormat == sysv || I->TypeChar == 'U')
- strcpy(SymbolAddrStr, printBlanks);
+ if (OutputFormat == sysv || I->TypeChar == 'U') {
+ if (OutputFormat == posix)
+ format(printFormat, I->Address)
+ .print(SymbolAddrStr, sizeof(SymbolAddrStr));
+ else
+ strcpy(SymbolAddrStr, printBlanks);
+ }
if (OutputFormat == sysv)
strcpy(SymbolSizeStr, printBlanks);
@@ -632,9 +713,9 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
} else if (OutputFormat == posix) {
outs() << I->Name << " " << I->TypeChar << " ";
if (MachO)
- outs() << I->Address << " " << "0" /* SymbolSizeStr */ << "\n";
+ outs() << SymbolAddrStr << " " << "0" /* SymbolSizeStr */ << "\n";
else
- outs() << SymbolAddrStr << SymbolSizeStr << "\n";
+ outs() << SymbolAddrStr << " " << SymbolSizeStr << "\n";
} else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) {
if (PrintAddress)
outs() << SymbolAddrStr << ' ';
@@ -663,9 +744,11 @@ static char getSymbolNMTypeChar(ELFObjectFileBase &Obj,
// OK, this is ELF
elf_symbol_iterator SymI(I);
- ErrorOr<elf_section_iterator> SecIOrErr = SymI->getSection();
- if (error(SecIOrErr.getError()))
+ Expected<elf_section_iterator> SecIOrErr = SymI->getSection();
+ if (!SecIOrErr) {
+ consumeError(SecIOrErr.takeError());
return '?';
+ }
elf_section_iterator SecI = *SecIOrErr;
if (SecI != Obj.section_end()) {
@@ -690,9 +773,11 @@ static char getSymbolNMTypeChar(ELFObjectFileBase &Obj,
}
if (SymI->getELFType() == ELF::STT_SECTION) {
- ErrorOr<StringRef> Name = SymI->getName();
- if (error(Name.getError()))
+ Expected<StringRef> Name = SymI->getName();
+ if (!Name) {
+ consumeError(Name.takeError());
return '?';
+ }
return StringSwitch<char>(*Name)
.StartsWith(".debug", 'N')
.StartsWith(".note", 'n')
@@ -707,9 +792,11 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) {
// OK, this is COFF.
symbol_iterator SymI(I);
- ErrorOr<StringRef> Name = SymI->getName();
- if (error(Name.getError()))
+ Expected<StringRef> Name = SymI->getName();
+ if (!Name) {
+ consumeError(Name.takeError());
return '?';
+ }
char Ret = StringSwitch<char>(*Name)
.StartsWith(".debug", 'N')
@@ -721,9 +808,11 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) {
uint32_t Characteristics = 0;
if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) {
- ErrorOr<section_iterator> SecIOrErr = SymI->getSection();
- if (error(SecIOrErr.getError()))
+ Expected<section_iterator> SecIOrErr = SymI->getSection();
+ if (!SecIOrErr) {
+ consumeError(SecIOrErr.takeError());
return '?';
+ }
section_iterator SecI = *SecIOrErr;
const coff_section *Section = Obj.getCOFFSection(*SecI);
Characteristics = Section->Characteristics;
@@ -750,18 +839,10 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) {
return '?';
}
-static uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) {
- if (Obj.is64Bit()) {
- MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
- return STE.n_type;
- }
- MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
- return STE.n_type;
-}
-
static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
DataRefImpl Symb = I->getRawDataRefImpl();
- uint8_t NType = getNType(Obj, Symb);
+ uint8_t NType = Obj.is64Bit() ? Obj.getSymbol64TableEntry(Symb).n_type
+ : Obj.getSymbolTableEntry(Symb).n_type;
if (NType & MachO::N_STAB)
return '-';
@@ -772,19 +853,23 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
case MachO::N_INDR:
return 'i';
case MachO::N_SECT: {
- section_iterator Sec = *Obj.getSymbolSection(Symb);
+ Expected<section_iterator> SecOrErr = Obj.getSymbolSection(Symb);
+ if (!SecOrErr) {
+ consumeError(SecOrErr.takeError());
+ return 's';
+ }
+ section_iterator Sec = *SecOrErr;
DataRefImpl Ref = Sec->getRawDataRefImpl();
StringRef SectionName;
Obj.getSectionName(Ref, SectionName);
StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref);
if (SegmentName == "__TEXT" && SectionName == "__text")
return 't';
- else if (SegmentName == "__DATA" && SectionName == "__data")
+ if (SegmentName == "__DATA" && SectionName == "__data")
return 'd';
- else if (SegmentName == "__DATA" && SectionName == "__bss")
+ if (SegmentName == "__DATA" && SectionName == "__bss")
return 'b';
- else
- return 's';
+ return 's';
}
}
@@ -792,35 +877,27 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
}
static char getSymbolNMTypeChar(const GlobalValue &GV) {
- if (GV.getType()->getElementType()->isFunctionTy())
- return 't';
// FIXME: should we print 'b'? At the IR level we cannot be sure if this
// will be in bss or not, but we could approximate.
- return 'd';
+ return GV.getValueType()->isFunctionTy() ? 't' : 'd';
}
static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) {
const GlobalValue *GV = Obj.getSymbolGV(I->getRawDataRefImpl());
- if (!GV)
- return 't';
- return getSymbolNMTypeChar(*GV);
+ return !GV ? 't' : getSymbolNMTypeChar(*GV);
}
static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) {
- auto *ELF = dyn_cast<ELFObjectFileBase>(&Obj);
- if (!ELF)
- return false;
-
- return elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT;
+ return !dyn_cast<ELFObjectFileBase>(&Obj)
+ ? false
+ : elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT;
}
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';
- if (!(Symflags & object::SymbolRef::SF_Undefined))
- Ret = toupper(Ret);
- return Ret;
+ return (!(Symflags & object::SymbolRef::SF_Undefined)) ? toupper(Ret) : Ret;
}
if (Symflags & object::SymbolRef::SF_Undefined)
@@ -835,10 +912,8 @@ static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) {
else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) {
Ret = getSymbolNMTypeChar(*IR, I);
Triple Host(sys::getDefaultTargetTriple());
- if (Ret == 'd' && Host.isOSDarwin()) {
- if(Symflags & SymbolRef::SF_Const)
- Ret = 's';
- }
+ if (Ret == 'd' && Host.isOSDarwin() && Symflags & SymbolRef::SF_Const)
+ Ret = 's';
}
else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj))
Ret = getSymbolNMTypeChar(*COFF, I);
@@ -861,9 +936,8 @@ static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) {
// file or zero it is not present.
static unsigned getNsectForSegSect(MachOObjectFile *Obj) {
unsigned Nsect = 1;
- for (section_iterator I = Obj->section_begin(), E = Obj->section_end();
- I != E; ++I) {
- DataRefImpl Ref = I->getRawDataRefImpl();
+ for (auto &S : Obj->sections()) {
+ DataRefImpl Ref = S.getRawDataRefImpl();
StringRef SectionName;
Obj->getSectionName(Ref, SectionName);
StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref);
@@ -883,20 +957,16 @@ static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) {
DataRefImpl Symb = Sym.getRawDataRefImpl();
if (Obj.is64Bit()) {
MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
- if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT)
- return STE.n_sect;
- return 0;
+ return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0;
}
MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
- if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT)
- return STE.n_sect;
- return 0;
+ return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0;
}
-static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
- std::string ArchiveName = std::string(),
- std::string ArchitectureName =
- std::string()) {
+static void
+dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
+ const std::string &ArchiveName = std::string(),
+ const std::string &ArchitectureName = std::string()) {
auto Symbols = Obj.symbols();
if (DynamicSyms) {
const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
@@ -945,14 +1015,19 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
}
if (PrintAddress && isa<ObjectFile>(Obj)) {
SymbolRef SymRef(Sym);
- ErrorOr<uint64_t> AddressOrErr = SymRef.getAddress();
- if (error(AddressOrErr.getError()))
+ Expected<uint64_t> AddressOrErr = SymRef.getAddress();
+ if (!AddressOrErr) {
+ consumeError(AddressOrErr.takeError());
break;
+ }
S.Address = *AddressOrErr;
}
S.TypeChar = getNMTypeChar(Obj, Sym);
- if (error(Sym.printName(OS)))
- break;
+ std::error_code EC = Sym.printName(OS);
+ if (EC && MachO)
+ OS << "bad string index";
+ else
+ error(EC);
OS << '\0';
S.Sym = Sym;
SymbolList.push_back(S);
@@ -985,10 +1060,10 @@ static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) {
Triple T;
if (MachO->is64Bit()) {
H_64 = MachO->MachOObjectFile::getHeader64();
- T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype);
+ T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype);
} else {
H = MachO->MachOObjectFile::getHeader();
- T = MachOObjectFile::getArch(H.cputype, H.cpusubtype);
+ T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype);
}
if (std::none_of(
ArchFlags.begin(), ArchFlags.end(),
@@ -1005,11 +1080,13 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
if (error(BufferOrErr.getError(), Filename))
return;
- LLVMContext &Context = getGlobalContext();
- ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(
+ LLVMContext Context;
+ Expected<std::unique_ptr<Binary>> BinaryOrErr = createBinary(
BufferOrErr.get()->getMemBufferRef(), NoLLVMBitcode ? nullptr : &Context);
- if (error(BinaryOrErr.getError(), Filename))
+ if (!BinaryOrErr) {
+ error(errorToErrorCode(BinaryOrErr.takeError()), Filename);
return;
+ }
Binary &Bin = *BinaryOrErr.get();
if (Archive *A = dyn_cast<Archive>(&Bin)) {
@@ -1032,27 +1109,31 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
}
}
- for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
- I != E; ++I) {
- if (error(I->getError()))
- return;
- auto &C = I->get();
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
- if (ChildOrErr.getError())
- continue;
- if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
- if (!checkMachOAndArchFlags(O, Filename))
- return;
- if (!PrintFileName) {
- outs() << "\n";
- if (isa<MachOObjectFile>(O)) {
- outs() << Filename << "(" << O->getFileName() << ")";
- } else
- outs() << O->getFileName();
- outs() << ":\n";
+ {
+ Error Err;
+ for (auto &C : A->children(Err)) {
+ Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
+ if (!ChildOrErr) {
+ if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
+ error(std::move(E), Filename, C);
+ continue;
+ }
+ if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
+ if (!checkMachOAndArchFlags(O, Filename))
+ return;
+ if (!PrintFileName) {
+ outs() << "\n";
+ if (isa<MachOObjectFile>(O)) {
+ outs() << Filename << "(" << O->getFileName() << ")";
+ } else
+ outs() << O->getFileName();
+ outs() << ":\n";
+ }
+ dumpSymbolNamesFromObject(*O, false, Filename);
}
- dumpSymbolNamesFromObject(*O, false, Filename);
}
+ if (Err)
+ error(std::move(Err), A->getFileName());
}
return;
}
@@ -1068,7 +1149,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
I != E; ++I) {
if (ArchFlags[i] == I->getArchTypeName()) {
ArchFound = true;
- ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
+ Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
I->getAsObjectFile();
std::string ArchiveName;
std::string ArchitectureName;
@@ -1086,19 +1167,26 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
}
dumpSymbolNamesFromObject(Obj, false, ArchiveName,
ArchitectureName);
- } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
+ } else if (auto E = isNotObjectErrorInvalidFileType(
+ ObjOrErr.takeError())) {
+ error(std::move(E), Filename, ArchFlags.size() > 1 ?
+ StringRef(I->getArchTypeName()) : StringRef());
+ continue;
+ } else if (Expected<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) {
- if (error(AI->getError()))
- return;
- auto &C = AI->get();
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
+ Error Err;
+ for (auto &C : A->children(Err)) {
+ Expected<std::unique_ptr<Binary>> ChildOrErr =
C.getAsBinary(&Context);
- if (ChildOrErr.getError())
+ if (!ChildOrErr) {
+ if (auto E = isNotObjectErrorInvalidFileType(
+ ChildOrErr.takeError())) {
+ error(std::move(E), Filename, C, ArchFlags.size() > 1 ?
+ StringRef(I->getArchTypeName()) : StringRef());
+ }
continue;
+ }
if (SymbolicFile *O =
dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
if (PrintFileName) {
@@ -1118,6 +1206,14 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
ArchitectureName);
}
}
+ if (Err)
+ error(std::move(Err), A->getFileName());
+ } else {
+ consumeError(AOrErr.takeError());
+ error(Filename + " for architecture " +
+ StringRef(I->getArchTypeName()) +
+ " is not a Mach-O file or an archive file",
+ "Mach-O universal file");
}
}
}
@@ -1137,25 +1233,29 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
E = UB->end_objects();
I != E; ++I) {
if (HostArchName == I->getArchTypeName()) {
- ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
+ Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
std::string ArchiveName;
ArchiveName.clear();
if (ObjOrErr) {
ObjectFile &Obj = *ObjOrErr.get();
dumpSymbolNamesFromObject(Obj, false);
- } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
+ } else if (auto E = isNotObjectErrorInvalidFileType(
+ ObjOrErr.takeError())) {
+ error(std::move(E), Filename);
+ return;
+ } else if (Expected<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) {
- if (error(AI->getError()))
- return;
- auto &C = AI->get();
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
+ Error Err;
+ for (auto &C : A->children(Err)) {
+ Expected<std::unique_ptr<Binary>> ChildOrErr =
C.getAsBinary(&Context);
- if (ChildOrErr.getError())
+ if (!ChildOrErr) {
+ if (auto E = isNotObjectErrorInvalidFileType(
+ ChildOrErr.takeError()))
+ error(std::move(E), Filename, C);
continue;
+ }
if (SymbolicFile *O =
dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
if (PrintFileName)
@@ -1167,6 +1267,14 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
dumpSymbolNamesFromObject(*O, false, ArchiveName);
}
}
+ if (Err)
+ error(std::move(Err), A->getFileName());
+ } else {
+ consumeError(AOrErr.takeError());
+ error(Filename + " for architecture " +
+ StringRef(I->getArchTypeName()) +
+ " is not a Mach-O file or an archive file",
+ "Mach-O universal file");
}
return;
}
@@ -1178,7 +1286,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
E = UB->end_objects();
I != E; ++I) {
- ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
+ Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
std::string ArchiveName;
std::string ArchitectureName;
ArchiveName.clear();
@@ -1197,16 +1305,25 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
outs() << ":\n";
}
dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName);
- } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
+ } else if (auto E = isNotObjectErrorInvalidFileType(
+ ObjOrErr.takeError())) {
+ error(std::move(E), Filename, moreThanOneArch ?
+ StringRef(I->getArchTypeName()) : StringRef());
+ continue;
+ } else if (Expected<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) {
- if (error(AI->getError()))
- return;
- auto &C = AI->get();
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
- if (ChildOrErr.getError())
+ Error Err;
+ for (auto &C : A->children(Err)) {
+ Expected<std::unique_ptr<Binary>> ChildOrErr =
+ C.getAsBinary(&Context);
+ if (!ChildOrErr) {
+ if (auto E = isNotObjectErrorInvalidFileType(
+ ChildOrErr.takeError()))
+ error(std::move(E), Filename, C, moreThanOneArch ?
+ StringRef(ArchitectureName) : StringRef());
continue;
+ }
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
if (PrintFileName) {
ArchiveName = A->getFileName();
@@ -1226,6 +1343,14 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName);
}
}
+ if (Err)
+ error(std::move(Err), A->getFileName());
+ } else {
+ consumeError(AOrErr.takeError());
+ error(Filename + " for architecture " +
+ StringRef(I->getArchTypeName()) +
+ " is not a Mach-O file or an archive file",
+ "Mach-O universal file");
}
}
return;
@@ -1234,14 +1359,12 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
if (!checkMachOAndArchFlags(O, Filename))
return;
dumpSymbolNamesFromObject(*O, true);
- return;
}
- error("unrecognizable file type", Filename);
}
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
- sys::PrintStackTraceOnErrorSignal();
+ sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
@@ -1251,6 +1374,7 @@ int main(int argc, char **argv) {
if (error(sys::ChangeStdinToBinary()))
return 1;
+ // These calls are needed so that we can read bitcode correctly.
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmParsers();
@@ -1270,15 +1394,10 @@ int main(int argc, char **argv) {
PrintAddress = false;
if (OutputFormat == sysv || SizeSort)
PrintSize = true;
-
- switch (InputFilenames.size()) {
- case 0:
+ if (InputFilenames.empty())
InputFilenames.push_back("a.out");
- case 1:
- break;
- default:
+ if (InputFilenames.size() > 1)
MultipleFiles = true;
- }
for (unsigned i = 0; i < ArchFlags.size(); ++i) {
if (ArchFlags[i] == "all") {
@@ -1299,6 +1418,4 @@ int main(int argc, char **argv) {
if (HadError)
return 1;
-
- return 0;
}