diff options
Diffstat (limited to 'tools/llvm-nm/llvm-nm.cpp')
-rw-r--r-- | tools/llvm-nm/llvm-nm.cpp | 415 |
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; } |