static void dumpSymbolNamesFromFile(std::string &Filename) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (error(BufferOrErr.getError(), Filename)) return; LLVMContext &Context = getGlobalContext(); ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary( BufferOrErr.get()->getMemBufferRef(), NoLLVMBitcode ? nullptr : &Context); if (error(BinaryOrErr.getError(), Filename)) return; Binary &Bin = *BinaryOrErr.get(); if (Archive *A = dyn_cast<Archive>(&Bin)) { if (ArchiveMap) { Archive::symbol_iterator I = A->symbol_begin(); Archive::symbol_iterator E = A->symbol_end(); if (I != E) { outs() << "Archive map\n"; for (; I != E; ++I) { ErrorOr<Archive::Child> C = I->getMember(); if (error(C.getError())) return; ErrorOr<StringRef> FileNameOrErr = C->getName(); if (error(FileNameOrErr.getError())) return; StringRef SymName = I->getName(); outs() << SymName << " in " << FileNameOrErr.get() << "\n"; } outs() << "\n"; } } 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"; } dumpSymbolNamesFromObject(*O, false, Filename); } } return; } 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. bool ArchFound; for (unsigned i = 0; i < ArchFlags.size(); ++i) { ArchFound = false; for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { if (ArchFlags[i] == I->getArchTypeName()) { ArchFound = true; ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; std::string ArchitectureName; ArchiveName.clear(); ArchitectureName.clear(); if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); if (ArchFlags.size() > 1) { if (PrintFileName) ArchitectureName = I->getArchTypeName(); else outs() << "\n" << Obj.getFileName() << " (for architecture " << I->getArchTypeName() << ")" << ":\n"; } 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) { if (error(AI->getError())) return; auto &C = AI->get(); ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { if (PrintFileName) { ArchiveName = A->getFileName(); if (ArchFlags.size() > 1) ArchitectureName = I->getArchTypeName(); } else { outs() << "\n" << A->getFileName(); outs() << "(" << O->getFileName() << ")"; if (ArchFlags.size() > 1) { outs() << " (for architecture " << I->getArchTypeName() << ")"; } outs() << ":\n"; } dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName); } } } } } if (!ArchFound) { error(ArchFlags[i], "file: " + Filename + " does not contain architecture"); return; } } return; } // No architecture flags were specified so if this contains a slice that // matches the host architecture dump only that. if (!ArchAll) { StringRef HostArchName = MachOObjectFile::getHostArch().getArchName(); for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { if (HostArchName == I->getArchTypeName()) { ErrorOr<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 = 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()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { if (PrintFileName) ArchiveName = A->getFileName(); else outs() << "\n" << A->getFileName() << "(" << O->getFileName() << ")" << ":\n"; dumpSymbolNamesFromObject(*O, false, ArchiveName); } } } return; } } } // Either all architectures have been specified or none have been specified // and this does not contain the host architecture so dump all the slices. bool moreThanOneArch = UB->getNumberOfObjects() > 1; for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; std::string ArchitectureName; ArchiveName.clear(); ArchitectureName.clear(); if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); if (PrintFileName) { if (isa<MachOObjectFile>(Obj) && moreThanOneArch) ArchitectureName = I->getArchTypeName(); } else { if (moreThanOneArch) outs() << "\n"; outs() << Obj.getFileName(); if (isa<MachOObjectFile>(Obj) && moreThanOneArch) outs() << " (for architecture " << I->getArchTypeName() << ")"; outs() << ":\n"; } 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) { if (error(AI->getError())) return; auto &C = AI->get(); ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { if (PrintFileName) { ArchiveName = A->getFileName(); if (isa<MachOObjectFile>(O) && moreThanOneArch) ArchitectureName = I->getArchTypeName(); } else { outs() << "\n" << A->getFileName(); if (isa<MachOObjectFile>(O)) { outs() << "(" << O->getFileName() << ")"; if (moreThanOneArch) outs() << " (for architecture " << I->getArchTypeName() << ")"; } else outs() << ":" << O->getFileName(); outs() << ":\n"; } dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName); } } } } return; } if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) { if (!checkMachOAndArchFlags(O, Filename)) return; dumpSymbolNamesFromObject(*O, true); } }