diff options
Diffstat (limited to 'llvm/tools/llvm-objdump')
-rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 117 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 3 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.h | 1 |
3 files changed, 118 insertions, 3 deletions
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 03fad5f922f..51140c29ced 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -66,9 +66,14 @@ static cl::opt<bool> PrintImmHex("print-imm-hex", cl::desc("Use hex format for immediate values")); +cl::opt<bool> llvm::UniversalHeaders("universal-headers", + cl::desc("Print Mach-O universal headers " + "(requires -macho)")); + cl::opt<bool> - llvm::UniversalHeaders("universal-headers", - cl::desc("Print Mach-O universal headers")); + llvm::ArchiveHeaders("archive-headers", + cl::desc("Print archive headers for Mach-O archives " + "(requires -macho)")); static cl::list<std::string> ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), @@ -514,6 +519,106 @@ static void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB, } } +static void printArchiveChild(Archive::Child &C, bool verbose, + bool print_offset) { + if (print_offset) + outs() << C.getChildOffset() << "\t"; + sys::fs::perms Mode = C.getAccessMode(); + if (verbose) { + // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG. + // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG. + outs() << "-"; + if (Mode & sys::fs::owner_read) + outs() << "r"; + else + outs() << "-"; + if (Mode & sys::fs::owner_write) + outs() << "w"; + else + outs() << "-"; + if (Mode & sys::fs::owner_exe) + outs() << "x"; + else + outs() << "-"; + if (Mode & sys::fs::group_read) + outs() << "r"; + else + outs() << "-"; + if (Mode & sys::fs::group_write) + outs() << "w"; + else + outs() << "-"; + if (Mode & sys::fs::group_exe) + outs() << "x"; + else + outs() << "-"; + if (Mode & sys::fs::others_read) + outs() << "r"; + else + outs() << "-"; + if (Mode & sys::fs::others_write) + outs() << "w"; + else + outs() << "-"; + if (Mode & sys::fs::others_exe) + outs() << "x"; + else + outs() << "-"; + } else { + outs() << format("0%o ", Mode); + } + + unsigned UID = C.getUID(); + outs() << format("%3d/", UID); + unsigned GID = C.getGID(); + outs() << format("%-3d ", GID); + uint64_t Size = C.getRawSize() - sizeof(object::ArchiveMemberHeader); + outs() << format("%5d ", Size); + + StringRef RawLastModified = C.getRawLastModified(); + if (verbose) { + unsigned Seconds; + if (RawLastModified.getAsInteger(10, Seconds)) + outs() << "(date: \"%s\" contains non-decimal chars) " << RawLastModified; + else { + // Since cime(3) returns a 26 character string of the form: + // "Sun Sep 16 01:03:52 1973\n\0" + // just print 24 characters. + time_t t = Seconds; + outs() << format("%.24s ", ctime(&t)); + } + } else { + outs() << RawLastModified << " "; + } + + if (verbose) { + ErrorOr<StringRef> NameOrErr = C.getName(); + if (NameOrErr.getError()) { + StringRef RawName = C.getRawName(); + outs() << RawName << "\n"; + } else { + StringRef Name = NameOrErr.get(); + outs() << Name << "\n"; + } + } else { + StringRef RawName = C.getRawName(); + outs() << RawName << "\n"; + } +} + +static void printArchiveHeaders(Archive *A, bool verbose, bool print_offset) { + if (A->hasSymbolTable()) { + Archive::child_iterator S = A->getSymbolTableChild(); + Archive::Child C = *S; + printArchiveChild(C, verbose, print_offset); + } + for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E; + ++I) { + Archive::Child C = *I; + printArchiveChild(C, verbose, print_offset); + } +} + // ParseInputMachO() parses the named Mach-O file in Filename and handles the // -arch flags selecting just those slices as specified by them and also parses // archive files. Then for each individual Mach-O file ProcessMachO() is @@ -542,6 +647,8 @@ void llvm::ParseInputMachO(StringRef Filename) { if (Archive *A = dyn_cast<Archive>(&Bin)) { outs() << "Archive : " << Filename << "\n"; + if (ArchiveHeaders) + printArchiveHeaders(A, true, false); for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E; ++I) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary(); @@ -587,6 +694,8 @@ void llvm::ParseInputMachO(StringRef Filename) { if (!ArchitectureName.empty()) outs() << " (architecture " << ArchitectureName << ")"; outs() << "\n"; + if (ArchiveHeaders) + printArchiveHeaders(A.get(), true, false); for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { @@ -627,6 +736,8 @@ void llvm::ParseInputMachO(StringRef Filename) { I->getAsArchive()) { std::unique_ptr<Archive> &A = *AOrErr; outs() << "Archive : " << Filename << "\n"; + if (ArchiveHeaders) + printArchiveHeaders(A.get(), true, false); for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { @@ -662,6 +773,8 @@ void llvm::ParseInputMachO(StringRef Filename) { if (!ArchitectureName.empty()) outs() << " (architecture " << ArchitectureName << ")"; outs() << "\n"; + if (ArchiveHeaders) + printArchiveHeaders(A.get(), true, false); for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary(); diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index aff6272d2fa..6334859b257 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -892,7 +892,8 @@ int main(int argc, char **argv) { && !Bind && !LazyBind && !WeakBind - && !(UniversalHeaders && MachOOpt)) { + && !(UniversalHeaders && MachOOpt) + && !(ArchiveHeaders && MachOOpt)) { cl::PrintHelpMessage(); return 2; } diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h index f829dd1a71c..491a819132e 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.h +++ b/llvm/tools/llvm-objdump/llvm-objdump.h @@ -35,6 +35,7 @@ extern cl::opt<bool> Bind; extern cl::opt<bool> LazyBind; extern cl::opt<bool> WeakBind; extern cl::opt<bool> UniversalHeaders; +extern cl::opt<bool> ArchiveHeaders; // Various helper functions. bool error(std::error_code ec); |