132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer//===-- llvm-size.cpp - Print the size of each object section -------------===// 232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// 332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// The LLVM Compiler Infrastructure 432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// 532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// This file is distributed under the University of Illinois Open Source 632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// License. See LICENSE.TXT for details. 732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// 832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer//===----------------------------------------------------------------------===// 932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// 1032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// This program is a utility that works like traditional Unix "size", 1132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// that is, it prints out the size of each section, and the total size of all 1232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// sections. 1332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer// 1432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer//===----------------------------------------------------------------------===// 1532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 1632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/ADT/APInt.h" 1732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Object/Archive.h" 18c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Object/MachO.h" 19c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Object/MachOUniversal.h" 20ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Object/ObjectFile.h" 2132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/Casting.h" 2232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/CommandLine.h" 2332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/FileSystem.h" 2432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/Format.h" 2532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/ManagedStatic.h" 2632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/MemoryBuffer.h" 2732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/PrettyStackTrace.h" 2832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/Signals.h" 29f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/raw_ostream.h" 3032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include <algorithm> 3132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include <string> 32c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error> 3332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerusing namespace llvm; 3432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerusing namespace object; 3532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 36c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesenum OutputFormatTy { berkeley, sysv, darwin }; 3775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencerstatic cl::opt<OutputFormatTy> 38c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesOutputFormat("format", cl::desc("Specify output format"), 39c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::values(clEnumVal(sysv, "System V format"), 40c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines clEnumVal(berkeley, "Berkeley format"), 41c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines clEnumVal(darwin, "Darwin -m format"), clEnumValEnd), 42c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::init(berkeley)); 43c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 44c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic cl::opt<OutputFormatTy> OutputFormatShort( 45c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::desc("Specify output format"), 46c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::values(clEnumValN(sysv, "A", "System V format"), 47c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines clEnumValN(berkeley, "B", "Berkeley format"), 48c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines clEnumValN(darwin, "m", "Darwin -m format"), clEnumValEnd), 49c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::init(berkeley)); 50c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 51c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic bool berkeleyHeaderPrinted = false; 52c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic bool moreThanOneFile = false; 53c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 54c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinescl::opt<bool> 55c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesDarwinLongFormat("l", cl::desc("When format is darwin, use long format " 56c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines "to include addresses and offsets.")); 5775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 58c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic cl::list<std::string> 59c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), 60c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::ZeroOrMore); 61c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool ArchAll = false; 6275c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 63c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesenum RadixTy { octal = 8, decimal = 10, hexadecimal = 16 }; 6475c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencerstatic cl::opt<unsigned int> 65c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesRadix("-radix", cl::desc("Print size in radix. Only 8, 10, and 16 are valid"), 66c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::init(decimal)); 6775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 6875c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencerstatic cl::opt<RadixTy> 69c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesRadixShort(cl::desc("Print size in radix:"), 70c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::values(clEnumValN(octal, "o", "Print size in octal"), 71c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines clEnumValN(decimal, "d", "Print size in decimal"), 72c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines clEnumValN(hexadecimal, "x", "Print size in hexadecimal"), 73c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines clEnumValEnd), 74c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::init(decimal)); 7575c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 7675c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencerstatic cl::list<std::string> 77c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesInputFilenames(cl::Positional, cl::desc("<input files>"), cl::ZeroOrMore); 7875c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 7975c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencerstatic std::string ToolName; 8075c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 8175c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer/// @brief If ec is not success, print the error and return true. 82c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic bool error(std::error_code ec) { 83c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!ec) 84c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return false; 8532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 8632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer outs() << ToolName << ": error reading file: " << ec.message() << ".\n"; 8732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer outs().flush(); 8832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer return true; 8932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer} 9032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 9175c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer/// @brief Get the length of the string that represents @p num in Radix 9275c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer/// including the leading 0x or 0 for hexadecimal and octal respectively. 93f47e870015439b1b47562533689a9dec17879befAndrew Trickstatic size_t getNumLengthAsString(uint64_t num) { 9432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer APInt conv(64, num); 9532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer SmallString<32> result; 9675c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer conv.toString(result, Radix, false, true); 9732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer return result.size(); 9832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer} 9932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 100c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// @brief Return the the printing format for the Radix. 101c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic const char *getRadixFmt(void) { 102c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines switch (Radix) { 103c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines case octal: 104c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return PRIo64; 105c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines case decimal: 106c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return PRIu64; 107c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines case hexadecimal: 108c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return PRIx64; 109c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 110c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return nullptr; 111c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 112c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 113c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// @brief Print the size of each Mach-O segment and section in @p MachO. 114c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// 115c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// This is when used when @c OutputFormat is darwin and produces the same 116c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// output as darwin's size(1) -m output. 117c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic void PrintDarwinSectionSizes(MachOObjectFile *MachO) { 118c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::string fmtbuf; 119c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines raw_string_ostream fmt(fmtbuf); 120c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const char *radix_fmt = getRadixFmt(); 121c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (Radix == hexadecimal) 122c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines fmt << "0x"; 123c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines fmt << "%" << radix_fmt; 124c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 125c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint32_t LoadCommandCount = MachO->getHeader().ncmds; 126c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint32_t Filetype = MachO->getHeader().filetype; 127c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile::LoadCommandInfo Load = MachO->getFirstLoadCommandInfo(); 128c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 129c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t total = 0; 130c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (unsigned I = 0;; ++I) { 131c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (Load.C.cmd == MachO::LC_SEGMENT_64) { 132c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Load); 133c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "Segment " << Seg.segname << ": " 134c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << format(fmt.str().c_str(), Seg.vmsize); 135c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (DarwinLongFormat) 136c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << " (vmaddr 0x" << format("%" PRIx64, Seg.vmaddr) << " fileoff " 137c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << Seg.fileoff << ")"; 138c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 139c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total += Seg.vmsize; 140c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t sec_total = 0; 141c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (unsigned J = 0; J < Seg.nsects; ++J) { 142c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::section_64 Sec = MachO->getSection64(Load, J); 143c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (Filetype == MachO::MH_OBJECT) 144c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\tSection (" << format("%.16s", &Sec.segname) << ", " 145c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << format("%.16s", &Sec.sectname) << "): "; 146c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 147c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\tSection " << format("%.16s", &Sec.sectname) << ": "; 148c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << format(fmt.str().c_str(), Sec.size); 149c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (DarwinLongFormat) 150c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << " (addr 0x" << format("%" PRIx64, Sec.addr) << " offset " 151c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << Sec.offset << ")"; 152c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 153c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines sec_total += Sec.size; 154c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 155c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (Seg.nsects != 0) 156c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\ttotal " << format(fmt.str().c_str(), sec_total) << "\n"; 157c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else if (Load.C.cmd == MachO::LC_SEGMENT) { 158c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::segment_command Seg = MachO->getSegmentLoadCommand(Load); 159c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "Segment " << Seg.segname << ": " 160c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << format(fmt.str().c_str(), Seg.vmsize); 161c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (DarwinLongFormat) 162c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << " (vmaddr 0x" << format("%" PRIx64, Seg.vmaddr) << " fileoff " 163c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << Seg.fileoff << ")"; 164c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 165c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total += Seg.vmsize; 166c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t sec_total = 0; 167c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (unsigned J = 0; J < Seg.nsects; ++J) { 168c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::section Sec = MachO->getSection(Load, J); 169c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (Filetype == MachO::MH_OBJECT) 170c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\tSection (" << format("%.16s", &Sec.segname) << ", " 171c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << format("%.16s", &Sec.sectname) << "): "; 172c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 173c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\tSection " << format("%.16s", &Sec.sectname) << ": "; 174c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << format(fmt.str().c_str(), Sec.size); 175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (DarwinLongFormat) 176c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << " (addr 0x" << format("%" PRIx64, Sec.addr) << " offset " 177c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << Sec.offset << ")"; 178c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 179c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines sec_total += Sec.size; 180c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 181c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (Seg.nsects != 0) 182c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\ttotal " << format(fmt.str().c_str(), sec_total) << "\n"; 183c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 184c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (I == LoadCommandCount - 1) 185c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines break; 186c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 187c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Load = MachO->getNextLoadCommandInfo(Load); 188c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 189c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "total " << format(fmt.str().c_str(), total) << "\n"; 190c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 191c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 192c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// @brief Print the summary sizes of the standard Mach-O segments in @p MachO. 193c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// 194c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// This is when used when @c OutputFormat is berkeley with a Mach-O file and 195c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// produces the same output as darwin's size(1) default output. 196c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic void PrintDarwinSegmentSizes(MachOObjectFile *MachO) { 197c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint32_t LoadCommandCount = MachO->getHeader().ncmds; 198c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile::LoadCommandInfo Load = MachO->getFirstLoadCommandInfo(); 199c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 200c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t total_text = 0; 201c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t total_data = 0; 202c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t total_objc = 0; 203c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t total_others = 0; 204c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (unsigned I = 0;; ++I) { 205c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (Load.C.cmd == MachO::LC_SEGMENT_64) { 206c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Load); 207c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (MachO->getHeader().filetype == MachO::MH_OBJECT) { 208c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (unsigned J = 0; J < Seg.nsects; ++J) { 209c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::section_64 Sec = MachO->getSection64(Load, J); 210c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef SegmentName = StringRef(Sec.segname); 211c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (SegmentName == "__TEXT") 212c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_text += Sec.size; 213c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (SegmentName == "__DATA") 214c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_data += Sec.size; 215c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (SegmentName == "__OBJC") 216c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_objc += Sec.size; 217c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 218c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_others += Sec.size; 219c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 220c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else { 221c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef SegmentName = StringRef(Seg.segname); 222c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (SegmentName == "__TEXT") 223c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_text += Seg.vmsize; 224c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (SegmentName == "__DATA") 225c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_data += Seg.vmsize; 226c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (SegmentName == "__OBJC") 227c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_objc += Seg.vmsize; 228c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 229c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_others += Seg.vmsize; 230c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 231c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else if (Load.C.cmd == MachO::LC_SEGMENT) { 232c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::segment_command Seg = MachO->getSegmentLoadCommand(Load); 233c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (MachO->getHeader().filetype == MachO::MH_OBJECT) { 234c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (unsigned J = 0; J < Seg.nsects; ++J) { 235c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::section Sec = MachO->getSection(Load, J); 236c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef SegmentName = StringRef(Sec.segname); 237c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (SegmentName == "__TEXT") 238c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_text += Sec.size; 239c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (SegmentName == "__DATA") 240c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_data += Sec.size; 241c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (SegmentName == "__OBJC") 242c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_objc += Sec.size; 243c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 244c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_others += Sec.size; 245c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 246c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else { 247c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef SegmentName = StringRef(Seg.segname); 248c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (SegmentName == "__TEXT") 249c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_text += Seg.vmsize; 250c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (SegmentName == "__DATA") 251c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_data += Seg.vmsize; 252c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (SegmentName == "__OBJC") 253c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_objc += Seg.vmsize; 254c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 255c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines total_others += Seg.vmsize; 256c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 257c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 258c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (I == LoadCommandCount - 1) 259c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines break; 260c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 261c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Load = MachO->getNextLoadCommandInfo(Load); 262c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 263c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t total = total_text + total_data + total_objc + total_others; 264c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 265c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!berkeleyHeaderPrinted) { 266c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "__TEXT\t__DATA\t__OBJC\tothers\tdec\thex\n"; 267c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines berkeleyHeaderPrinted = true; 268c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 269c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << total_text << "\t" << total_data << "\t" << total_objc << "\t" 270c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << total_others << "\t" << total << "\t" << format("%" PRIx64, total) 271c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << "\t"; 272c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 273c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// @brief Print the size of each section in @p Obj. 27575c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer/// 27675c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer/// The format used is determined by @c OutputFormat and @c Radix. 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void PrintObjectSectionSizes(ObjectFile *Obj) { 27832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t total = 0; 27932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer std::string fmtbuf; 28032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer raw_string_ostream fmt(fmtbuf); 281c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const char *radix_fmt = getRadixFmt(); 282c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 283c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // If OutputFormat is darwin and we have a MachOObjectFile print as darwin's 284c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // size(1) -m output, else if OutputFormat is darwin and not a Mach-O object 285c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // let it fall through to OutputFormat berkeley. 286c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj); 287c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == darwin && MachO) 288c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PrintDarwinSectionSizes(MachO); 289c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // If we have a MachOObjectFile and the OutputFormat is berkeley print as 290c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // darwin's default berkeley format for Mach-O files. 291c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (MachO && OutputFormat == berkeley) 292c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PrintDarwinSegmentSizes(MachO); 293c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (OutputFormat == sysv) { 29432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Run two passes over all sections. The first gets the lengths needed for 29532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // formatting the output. The second actually does the output. 29632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer std::size_t max_name_len = strlen("section"); 29775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer std::size_t max_size_len = strlen("size"); 29875c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer std::size_t max_addr_len = strlen("addr"); 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 30037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t size = Section.getSize(); 30132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total += size; 30232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 30332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer StringRef name; 30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getName(name))) 30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 30637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t addr = Section.getAddress(); 30732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer max_name_len = std::max(max_name_len, name.size()); 308f47e870015439b1b47562533689a9dec17879befAndrew Trick max_size_len = std::max(max_size_len, getNumLengthAsString(size)); 309f47e870015439b1b47562533689a9dec17879befAndrew Trick max_addr_len = std::max(max_addr_len, getNumLengthAsString(addr)); 31032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 31132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 31275c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // Add extra padding. 31332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer max_name_len += 2; 31432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer max_size_len += 2; 31532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer max_addr_len += 2; 31632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 31775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // Setup header format. 31832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmt << "%-" << max_name_len << "s " 31932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%" << max_size_len << "s " 32032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%" << max_addr_len << "s\n"; 32132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 32232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print header 323c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << format(fmt.str().c_str(), static_cast<const char *>("section"), 324c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines static_cast<const char *>("size"), 325c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines static_cast<const char *>("addr")); 32632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmtbuf.clear(); 32732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 32832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Setup per section format. 32932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmt << "%-" << max_name_len << "s " 33032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#" << max_size_len << radix_fmt << " " 33132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#" << max_addr_len << radix_fmt << "\n"; 33232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 33332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print each section. 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 33532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer StringRef name; 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getName(name))) 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t size = Section.getSize(); 33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t addr = Section.getAddress(); 34032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer std::string namestr = name; 34132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << format(fmt.str().c_str(), namestr.c_str(), size, addr); 34332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 34432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 34532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print total. 34632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmtbuf.clear(); 34732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmt << "%-" << max_name_len << "s " 34832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#" << max_size_len << radix_fmt << "\n"; 349c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << format(fmt.str().c_str(), static_cast<const char *>("Total"), 35032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total); 35132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } else { 35275c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // The Berkeley format does not display individual section sizes. It 35375c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // displays the cumulative size for each section type. 35432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t total_text = 0; 35532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t total_data = 0; 35632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t total_bss = 0; 35732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 35875c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // Make one pass over the section table to calculate sizes. 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t size = Section.getSize(); 36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool isText = Section.isText(); 36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool isData = Section.isData(); 36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool isBSS = Section.isBSS(); 36432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (isText) 36532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total_text += size; 36632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer else if (isData) 36732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total_data += size; 36832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer else if (isBSS) 36932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total_bss += size; 37032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 37132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 37232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total = total_text + total_data + total_bss; 37332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 374c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!berkeleyHeaderPrinted) { 375c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << " text data bss " 376c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << (Radix == octal ? "oct" : "dec") << " hex filename\n"; 377c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines berkeleyHeaderPrinted = true; 378c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 379c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 38032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print result. 38132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmt << "%#7" << radix_fmt << " " 38232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#7" << radix_fmt << " " 38332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#7" << radix_fmt << " "; 384c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << format(fmt.str().c_str(), total_text, total_data, total_bss); 38532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmtbuf.clear(); 38641a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer fmt << "%7" << (Radix == octal ? PRIo64 : PRIu64) << " " 38741a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer << "%7" PRIx64 " "; 388c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << format(fmt.str().c_str(), total, total); 389c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 390c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 391c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 392c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// @brief Checks to see if the @p o ObjectFile is a Mach-O file and if it is 393c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// and there is a list of architecture flags specified then check to 394c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// make sure this Mach-O file is one of those architectures or all 395c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// architectures was specificed. If not then an error is generated and 396c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// this routine returns false. Else it returns true. 397c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic bool checkMachOAndArchFlags(ObjectFile *o, StringRef file) { 398c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (isa<MachOObjectFile>(o) && !ArchAll && ArchFlags.size() != 0) { 399c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 400c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool ArchFound = false; 401c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::mach_header H; 402c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachO::mach_header_64 H_64; 403c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Triple T; 404c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (MachO->is64Bit()) { 405c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines H_64 = MachO->MachOObjectFile::getHeader64(); 406c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype); 407c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else { 408c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines H = MachO->MachOObjectFile::getHeader(); 409c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines T = MachOObjectFile::getArch(H.cputype, H.cpusubtype); 410c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 411c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines unsigned i; 412c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (i = 0; i < ArchFlags.size(); ++i) { 413c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ArchFlags[i] == T.getArchName()) 414c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ArchFound = true; 415c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines break; 416c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 417c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!ArchFound) { 418c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines errs() << ToolName << ": file: " << file 419c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << " does not contain architecture: " << ArchFlags[i] << ".\n"; 420c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return false; 421c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 42232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 423c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return true; 42432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer} 42532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 42675c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer/// @brief Print the section sizes for @p file. If @p file is an archive, print 42775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer/// the section sizes for each archive member. 42832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerstatic void PrintFileSectionSizes(StringRef file) { 42932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // If file is not stdin, check that it exists. 43032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (file != "-") { 43137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!sys::fs::exists(file)) { 432c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines errs() << ToolName << ": '" << file << "': " 433c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << "No such file\n"; 43432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer return; 43532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 43632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 43732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 43875c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // Attempt to open the binary. 43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file); 440c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = BinaryOrErr.getError()) { 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; 44232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer return; 44332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 44437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Binary &Bin = *BinaryOrErr.get().getBinary(); 44532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 44637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Archive *a = dyn_cast<Archive>(&Bin)) { 44775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // This is an archive. Iterate over each member and display its sizes. 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (object::Archive::child_iterator i = a->child_begin(), 449c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines e = a->child_end(); 450c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines i != e; ++i) { 451c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 452c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = ChildOrErr.getError()) { 453c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; 45432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer continue; 45532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 456c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { 457c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 458c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!checkMachOAndArchFlags(o, file)) 459c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return; 46032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (OutputFormat == sysv) 461c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (ex " << a->getFileName() << "):\n"; 462c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (MachO && OutputFormat == darwin) 463c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << a->getFileName() << "(" << o->getFileName() << "):\n"; 46432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer PrintObjectSectionSizes(o); 465c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == berkeley) { 466c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (MachO) 467c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << a->getFileName() << "(" << o->getFileName() << ")\n"; 468c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 469c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (ex " << a->getFileName() << ")\n"; 470c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 471c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 472c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 473c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else if (MachOUniversalBinary *UB = 47437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines dyn_cast<MachOUniversalBinary>(&Bin)) { 475c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // If we have a list of architecture flags specified dump only those. 476c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!ArchAll && ArchFlags.size() != 0) { 477c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Look for a slice in the universal binary that matches each ArchFlag. 478c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool ArchFound; 479c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (unsigned i = 0; i < ArchFlags.size(); ++i) { 480c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ArchFound = false; 481c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 482c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines E = UB->end_objects(); 483c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines I != E; ++I) { 484c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ArchFlags[i] == I->getArchTypeName()) { 485c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ArchFound = true; 486c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile(); 487c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (UO) { 488c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) { 489c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 490c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == sysv) 491c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " :\n"; 492c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (MachO && OutputFormat == darwin) { 493c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (moreThanOneFile || ArchFlags.size() > 1) 494c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (for architecture " 495c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << I->getArchTypeName() << "): \n"; 496c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 497c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PrintObjectSectionSizes(o); 498c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == berkeley) { 499c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!MachO || moreThanOneFile || ArchFlags.size() > 1) 500c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (for architecture " 501c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << I->getArchTypeName() << ")"; 502c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 503c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 504c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 505ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = 506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I->getAsArchive()) { 507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<Archive> &UA = *AOrErr; 508c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // This is an archive. Iterate over each member and display its 509c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // sizes. 510c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (object::Archive::child_iterator i = UA->child_begin(), 511c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines e = UA->child_end(); 512c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines i != e; ++i) { 513c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 514c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = ChildOrErr.getError()) { 515c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines errs() << ToolName << ": " << file << ": " << EC.message() 516c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ".\n"; 517c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines continue; 518c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 519c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { 520c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 521c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == sysv) 522c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 523c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << "):\n"; 524c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (MachO && OutputFormat == darwin) 525c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << UA->getFileName() << "(" << o->getFileName() 526c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ")" 527c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << " (for architecture " << I->getArchTypeName() 528c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << "):\n"; 529c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PrintObjectSectionSizes(o); 530c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == berkeley) { 531c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (MachO) { 532c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << UA->getFileName() << "(" << o->getFileName() 533c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ")"; 534c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ArchFlags.size() > 1) 535c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << " (for architecture " << I->getArchTypeName() 536c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ")"; 537c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 538c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else 539c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 540c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ")\n"; 541c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 542c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 543c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 544c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 545c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 546c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 547c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!ArchFound) { 548c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines errs() << ToolName << ": file: " << file 549c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << " does not contain architecture" << ArchFlags[i] << ".\n"; 550c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return; 551c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 552c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 553c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return; 554c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 555c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // No architecture flags were specified so if this contains a slice that 556c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // matches the host architecture dump only that. 557c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!ArchAll) { 558c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StringRef HostArchName = MachOObjectFile::getHostArch().getArchName(); 559c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 560c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines E = UB->end_objects(); 561c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines I != E; ++I) { 562c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (HostArchName == I->getArchTypeName()) { 563c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile(); 564c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (UO) { 565c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) { 566c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 567c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == sysv) 568c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " :\n"; 569c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (MachO && OutputFormat == darwin) { 570c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (moreThanOneFile) 571c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (for architecture " 572c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << I->getArchTypeName() << "):\n"; 573c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 574c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PrintObjectSectionSizes(o); 575c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == berkeley) { 576c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!MachO || moreThanOneFile) 577c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (for architecture " 578c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << I->getArchTypeName() << ")"; 579c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 580c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 581c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 582ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = 583ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I->getAsArchive()) { 584ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<Archive> &UA = *AOrErr; 585c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // This is an archive. Iterate over each member and display its 586c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // sizes. 587c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (object::Archive::child_iterator i = UA->child_begin(), 588c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines e = UA->child_end(); 589c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines i != e; ++i) { 590c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 591c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = ChildOrErr.getError()) { 592c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines errs() << ToolName << ": " << file << ": " << EC.message() 593c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ".\n"; 594c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines continue; 595c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 596c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { 597c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 598c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == sysv) 599c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 600c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << "):\n"; 601c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (MachO && OutputFormat == darwin) 602c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << UA->getFileName() << "(" << o->getFileName() << ")" 603c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << " (for architecture " << I->getArchTypeName() 604c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << "):\n"; 605c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PrintObjectSectionSizes(o); 606c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == berkeley) { 607c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (MachO) 608c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << UA->getFileName() << "(" << o->getFileName() 609c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ")\n"; 610c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 611c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 612c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ")\n"; 613c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 614c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 615c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 616c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 617c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return; 618c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 619c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 620c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 621c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Either all architectures have been specified or none have been specified 622c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // and this does not contain the host architecture so dump all the slices. 623c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool moreThanOneArch = UB->getNumberOfObjects() > 1; 624c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 625c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines E = UB->end_objects(); 626c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines I != E; ++I) { 627c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile(); 628c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (UO) { 629c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) { 630c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 631c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == sysv) 632c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " :\n"; 633c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (MachO && OutputFormat == darwin) { 634c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (moreThanOneFile || moreThanOneArch) 635c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (for architecture " 636c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << I->getArchTypeName() << "):"; 637c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 638c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 639c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PrintObjectSectionSizes(o); 640c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == berkeley) { 641c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!MachO || moreThanOneFile || moreThanOneArch) 642c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (for architecture " 643c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << I->getArchTypeName() << ")"; 644c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 645c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 646c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = 648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I->getAsArchive()) { 649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<Archive> &UA = *AOrErr; 650c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // This is an archive. Iterate over each member and display its sizes. 651c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (object::Archive::child_iterator i = UA->child_begin(), 652c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines e = UA->child_end(); 653c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines i != e; ++i) { 654c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 655c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = ChildOrErr.getError()) { 656c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; 657c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines continue; 658c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 659c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { 660c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 661c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == sysv) 662c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 663c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << "):\n"; 664c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else if (MachO && OutputFormat == darwin) 665c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << UA->getFileName() << "(" << o->getFileName() << ")" 666c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << " (for architecture " << I->getArchTypeName() << "):\n"; 667c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PrintObjectSectionSizes(o); 668c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == berkeley) { 669c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (MachO) 670c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << UA->getFileName() << "(" << o->getFileName() << ")" 671c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << " (for architecture " << I->getArchTypeName() 672c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ")\n"; 673c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines else 674c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 675c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << ")\n"; 676c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 677c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 678c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 67932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 68032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 68137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (ObjectFile *o = dyn_cast<ObjectFile>(&Bin)) { 682c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!checkMachOAndArchFlags(o, file)) 683c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return; 68432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (OutputFormat == sysv) 68532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer outs() << o->getFileName() << " :\n"; 68632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer PrintObjectSectionSizes(o); 687c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (OutputFormat == berkeley) { 688c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 689c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!MachO || moreThanOneFile) 690c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << o->getFileName(); 691c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << "\n"; 692c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 69332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } else { 694c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines errs() << ToolName << ": " << file << ": " 695c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << "Unrecognized file type.\n"; 69632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 69775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // System V adds an extra newline at the end of each file. 69832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (OutputFormat == sysv) 69932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer outs() << "\n"; 70032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer} 70132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 70232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerint main(int argc, char **argv) { 70332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print a stack trace if we signal out. 70432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer sys::PrintStackTraceOnErrorSignal(); 70532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer PrettyStackTraceProgram X(argc, argv); 70632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 707c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 70832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer cl::ParseCommandLineOptions(argc, argv, "llvm object size dumper\n"); 70932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 71032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer ToolName = argv[0]; 71132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (OutputFormatShort.getNumOccurrences()) 712ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OutputFormat = static_cast<OutputFormatTy>(OutputFormatShort); 71332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (RadixShort.getNumOccurrences()) 71475c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer Radix = RadixShort; 71532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 716c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (unsigned i = 0; i < ArchFlags.size(); ++i) { 717c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ArchFlags[i] == "all") { 718c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ArchAll = true; 719c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else { 72037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!MachOObjectFile::isValidArch(ArchFlags[i])) { 721c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines outs() << ToolName << ": for the -arch option: Unknown architecture " 722c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines << "named '" << ArchFlags[i] << "'"; 723c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return 1; 724c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 725c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 726c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 727c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 72832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (InputFilenames.size() == 0) 72932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer InputFilenames.push_back("a.out"); 73032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 731c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines moreThanOneFile = InputFilenames.size() > 1; 73232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer std::for_each(InputFilenames.begin(), InputFilenames.end(), 73332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer PrintFileSectionSizes); 73432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 73532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer return 0; 73632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer} 737