/// @brief Print the section sizes for @p file. If @p file is an archive, print /// the section sizes for each archive member. static void PrintFileSectionSizes(StringRef file) { // If file is not stdin, check that it exists. if (file != "-") { if (!sys::fs::exists(file)) { errs() << ToolName << ": '" << file << "': " << "No such file\n"; return; } } // Attempt to open the binary. ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file); if (std::error_code EC = BinaryOrErr.getError()) { errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; return; } Binary &Bin = *BinaryOrErr.get().getBinary(); if (Archive *a = dyn_cast<Archive>(&Bin)) { // This is an archive. Iterate over each member and display its sizes. for (object::Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e; ++i) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); if (std::error_code EC = ChildOrErr.getError()) { errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; continue; } if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); if (!checkMachOAndArchFlags(o, file)) return; if (OutputFormat == sysv) outs() << o->getFileName() << " (ex " << a->getFileName() << "):\n"; else if (MachO && OutputFormat == darwin) outs() << a->getFileName() << "(" << o->getFileName() << "):\n"; PrintObjectSectionSizes(o); if (OutputFormat == berkeley) { if (MachO) outs() << a->getFileName() << "(" << o->getFileName() << ")\n"; else outs() << o->getFileName() << " (ex " << a->getFileName() << ")\n"; } } } } else 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>> UO = I->getAsObjectFile(); if (UO) { if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) { MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); if (OutputFormat == sysv) outs() << o->getFileName() << " :\n"; else if (MachO && OutputFormat == darwin) { if (moreThanOneFile || ArchFlags.size() > 1) outs() << o->getFileName() << " (for architecture " << I->getArchTypeName() << "): \n"; } PrintObjectSectionSizes(o); if (OutputFormat == berkeley) { if (!MachO || moreThanOneFile || ArchFlags.size() > 1) outs() << o->getFileName() << " (for architecture " << I->getArchTypeName() << ")"; outs() << "\n"; } } } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) { std::unique_ptr<Archive> &UA = *AOrErr; // This is an archive. Iterate over each member and display its // sizes. for (object::Archive::child_iterator i = UA->child_begin(), e = UA->child_end(); i != e; ++i) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); if (std::error_code EC = ChildOrErr.getError()) { errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; continue; } if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); if (OutputFormat == sysv) outs() << o->getFileName() << " (ex " << UA->getFileName() << "):\n"; else if (MachO && OutputFormat == darwin) outs() << UA->getFileName() << "(" << o->getFileName() << ")" << " (for architecture " << I->getArchTypeName() << "):\n"; PrintObjectSectionSizes(o); if (OutputFormat == berkeley) { if (MachO) { outs() << UA->getFileName() << "(" << o->getFileName() << ")"; if (ArchFlags.size() > 1) outs() << " (for architecture " << I->getArchTypeName() << ")"; outs() << "\n"; } else outs() << o->getFileName() << " (ex " << UA->getFileName() << ")\n"; } } } } } } if (!ArchFound) { errs() << ToolName << ": file: " << file << " does not contain architecture" << ArchFlags[i] << ".\n"; 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>> UO = I->getAsObjectFile(); if (UO) { if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) { MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); if (OutputFormat == sysv) outs() << o->getFileName() << " :\n"; else if (MachO && OutputFormat == darwin) { if (moreThanOneFile) outs() << o->getFileName() << " (for architecture " << I->getArchTypeName() << "):\n"; } PrintObjectSectionSizes(o); if (OutputFormat == berkeley) { if (!MachO || moreThanOneFile) outs() << o->getFileName() << " (for architecture " << I->getArchTypeName() << ")"; outs() << "\n"; } } } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) { std::unique_ptr<Archive> &UA = *AOrErr; // This is an archive. Iterate over each member and display its // sizes. for (object::Archive::child_iterator i = UA->child_begin(), e = UA->child_end(); i != e; ++i) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); if (std::error_code EC = ChildOrErr.getError()) { errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; continue; } if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); if (OutputFormat == sysv) outs() << o->getFileName() << " (ex " << UA->getFileName() << "):\n"; else if (MachO && OutputFormat == darwin) outs() << UA->getFileName() << "(" << o->getFileName() << ")" << " (for architecture " << I->getArchTypeName() << "):\n"; PrintObjectSectionSizes(o); if (OutputFormat == berkeley) { if (MachO) outs() << UA->getFileName() << "(" << o->getFileName() << ")\n"; else outs() << o->getFileName() << " (ex " << UA->getFileName() << ")\n"; } } } } 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>> UO = I->getAsObjectFile(); if (UO) { if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) { MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); if (OutputFormat == sysv) outs() << o->getFileName() << " :\n"; else if (MachO && OutputFormat == darwin) { if (moreThanOneFile || moreThanOneArch) outs() << o->getFileName() << " (for architecture " << I->getArchTypeName() << "):"; outs() << "\n"; } PrintObjectSectionSizes(o); if (OutputFormat == berkeley) { if (!MachO || moreThanOneFile || moreThanOneArch) outs() << o->getFileName() << " (for architecture " << I->getArchTypeName() << ")"; outs() << "\n"; } } } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) { std::unique_ptr<Archive> &UA = *AOrErr; // This is an archive. Iterate over each member and display its sizes. for (object::Archive::child_iterator i = UA->child_begin(), e = UA->child_end(); i != e; ++i) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); if (std::error_code EC = ChildOrErr.getError()) { errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; continue; } if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); if (OutputFormat == sysv) outs() << o->getFileName() << " (ex " << UA->getFileName() << "):\n"; else if (MachO && OutputFormat == darwin) outs() << UA->getFileName() << "(" << o->getFileName() << ")" << " (for architecture " << I->getArchTypeName() << "):\n"; PrintObjectSectionSizes(o); if (OutputFormat == berkeley) { if (MachO) outs() << UA->getFileName() << "(" << o->getFileName() << ")" << " (for architecture " << I->getArchTypeName() << ")\n"; else outs() << o->getFileName() << " (ex " << UA->getFileName() << ")\n"; } } } } } } else if (ObjectFile *o = dyn_cast<ObjectFile>(&Bin)) { if (!checkMachOAndArchFlags(o, file)) return; if (OutputFormat == sysv) outs() << o->getFileName() << " :\n"; PrintObjectSectionSizes(o); if (OutputFormat == berkeley) { MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); if (!MachO || moreThanOneFile) outs() << o->getFileName(); outs() << "\n"; } } else { errs() << ToolName << ": " << file << ": " << "Unrecognized file type.\n"; } // System V adds an extra newline at the end of each file. if (OutputFormat == sysv) outs() << "\n"; }
static void dumpSymbolNamesFromFile(std::string &Filename) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (error(BufferOrErr.getError(), Filename)) return; std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); LLVMContext &Context = getGlobalContext(); ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer, &Context); if (error(BinaryOrErr.getError(), Filename)) return; Buffer.release(); std::unique_ptr<Binary> Bin(BinaryOrErr.get()); if (Archive *A = dyn_cast<Archive>(Bin.get())) { 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_iterator> C = I->getMember(); if (error(C.getError())) return; ErrorOr<StringRef> FileNameOrErr = C.get()->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) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { if (!checkMachOAndArchFlags(O, Filename)) return; outs() << "\n"; if (isa<MachOObjectFile>(O)) { outs() << Filename << "(" << O->getFileName() << ")"; } else outs() << O->getFileName(); outs() << ":\n"; dumpSymbolNamesFromObject(O, false); } } return; } if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin.get())) { // 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::unique_ptr<Archive> A; if (ObjOrErr) { std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); if (ArchFlags.size() > 1) { outs() << "\n" << Obj->getFileName() << " (for architecture " << I->getArchTypeName() << ")" << ":\n"; } dumpSymbolNamesFromObject(Obj.get(), false); } else if (!I->getAsArchive(A)) { for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { outs() << "\n" << A->getFileName(); outs() << "(" << O->getFileName() << ")"; if (ArchFlags.size() > 1) { outs() << " (for architecture " << I->getArchTypeName() << ")"; } outs() << ":\n"; dumpSymbolNamesFromObject(O, false); } } } } } 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::unique_ptr<Archive> A; if (ObjOrErr) { std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); dumpSymbolNamesFromObject(Obj.get(), false); } else if (!I->getAsArchive(A)) { for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { outs() << "\n" << A->getFileName() << "(" << O->getFileName() << ")" << ":\n"; dumpSymbolNamesFromObject(O, false); } } } 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::unique_ptr<Archive> A; if (ObjOrErr) { std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); if (moreThanOneArch) outs() << "\n"; outs() << Obj->getFileName(); if (isa<MachOObjectFile>(Obj.get()) && moreThanOneArch) outs() << " (for architecture " << I->getArchTypeName() << ")"; outs() << ":\n"; dumpSymbolNamesFromObject(Obj.get(), false); } else if (!I->getAsArchive(A)) { for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 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); } } } } return; } if (SymbolicFile *O = dyn_cast<SymbolicFile>(Bin.get())) { if (!checkMachOAndArchFlags(O, Filename)) return; dumpSymbolNamesFromObject(O, true); return; } error("unrecognizable file type", Filename); return; }
static void dumpSymbolNamesFromFile(std::string &Filename) { std::unique_ptr<MemoryBuffer> Buffer; if (error(MemoryBuffer::getFileOrSTDIN(Filename, Buffer), Filename)) return; LLVMContext &Context = getGlobalContext(); ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer.release(), &Context); if (error(BinaryOrErr.getError(), Filename)) return; std::unique_ptr<Binary> Bin(BinaryOrErr.get()); if (Archive *A = dyn_cast<Archive>(Bin.get())) { 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) { Archive::child_iterator C; StringRef SymName; StringRef FileName; if (error(I->getMember(C))) return; if (error(I->getName(SymName))) return; if (error(C->getName(FileName))) return; outs() << SymName << " in " << FileName << "\n"; } outs() << "\n"; } } for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E; ++I) { std::unique_ptr<Binary> Child; if (I->getAsBinary(Child, &Context)) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) { outs() << O->getFileName() << ":\n"; dumpSymbolNamesFromObject(O); } } return; } if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin.get())) { for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { std::unique_ptr<ObjectFile> Obj; std::unique_ptr<Archive> A; if (!I->getAsObjectFile(Obj)) { outs() << Obj->getFileName() << ":\n"; dumpSymbolNamesFromObject(Obj.get()); } else if (!I->getAsArchive(A)) { for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { std::unique_ptr<Binary> Child; if (AI->getAsBinary(Child, &Context)) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) { outs() << A->getFileName() << ":"; outs() << O->getFileName() << ":\n"; dumpSymbolNamesFromObject(O); } } } } return; } if (SymbolicFile *O = dyn_cast<SymbolicFile>(Bin.get())) { dumpSymbolNamesFromObject(O); return; } error("unrecognizable file type", Filename); return; }