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" 1832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Object/ObjectFile.h" 19cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Object/MachO.h" 20cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Object/MachOUniversal.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> 32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <system_error> 3332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerusing namespace llvm; 3432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerusing namespace object; 3532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 36cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesenum OutputFormatTy { berkeley, sysv, darwin }; 3775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencerstatic cl::opt<OutputFormatTy> 38cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesOutputFormat("format", cl::desc("Specify output format"), 39cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::values(clEnumVal(sysv, "System V format"), 40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines clEnumVal(berkeley, "Berkeley format"), 41cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines clEnumVal(darwin, "Darwin -m format"), clEnumValEnd), 42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::init(berkeley)); 43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic cl::opt<OutputFormatTy> OutputFormatShort( 45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::desc("Specify output format"), 46cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::values(clEnumValN(sysv, "A", "System V format"), 47cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines clEnumValN(berkeley, "B", "Berkeley format"), 48cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines clEnumValN(darwin, "m", "Darwin -m format"), clEnumValEnd), 49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::init(berkeley)); 50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic bool berkeleyHeaderPrinted = false; 52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic bool moreThanOneFile = false; 53cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinescl::opt<bool> 55cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesDarwinLongFormat("l", cl::desc("When format is darwin, use long format " 56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "to include addresses and offsets.")); 5775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 58cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic cl::list<std::string> 59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), 60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::ZeroOrMore); 61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool ArchAll = false; 6275c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesenum RadixTy { octal = 8, decimal = 10, hexadecimal = 16 }; 6475c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencerstatic cl::opt<unsigned int> 65cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesRadix("-radix", cl::desc("Print size in radix. Only 8, 10, and 16 are valid"), 66cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::init(decimal)); 6775c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 6875c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencerstatic cl::opt<RadixTy> 69cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesRadixShort(cl::desc("Print size in radix:"), 70cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::values(clEnumValN(octal, "o", "Print size in octal"), 71cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines clEnumValN(decimal, "d", "Print size in decimal"), 72cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines clEnumValN(hexadecimal, "x", "Print size in hexadecimal"), 73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines clEnumValEnd), 74cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::init(decimal)); 7575c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer 7675c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencerstatic cl::list<std::string> 77cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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. 82cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic bool error(std::error_code ec) { 83cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!ec) 84cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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 100cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// @brief Return the the printing format for the Radix. 101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic const char *getRadixFmt(void) { 102cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines switch (Radix) { 103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case octal: 104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return PRIo64; 105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case decimal: 106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return PRIu64; 107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case hexadecimal: 108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return PRIx64; 109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return nullptr; 111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// @brief Print the size of each Mach-O segment and section in @p MachO. 114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// 115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// This is when used when @c OutputFormat is darwin and produces the same 116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// output as darwin's size(1) -m output. 117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic void PrintDarwinSectionSizes(MachOObjectFile *MachO) { 118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::string fmtbuf; 119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines raw_string_ostream fmt(fmtbuf); 120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const char *radix_fmt = getRadixFmt(); 121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Radix == hexadecimal) 122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines fmt << "0x"; 123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines fmt << "%" << radix_fmt; 124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint32_t LoadCommandCount = MachO->getHeader().ncmds; 126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint32_t Filetype = MachO->getHeader().filetype; 127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile::LoadCommandInfo Load = MachO->getFirstLoadCommandInfo(); 128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t total = 0; 130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned I = 0;; ++I) { 131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Load.C.cmd == MachO::LC_SEGMENT_64) { 132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Load); 133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "Segment " << Seg.segname << ": " 134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << format(fmt.str().c_str(), Seg.vmsize); 135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (DarwinLongFormat) 136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << " (vmaddr 0x" << format("%" PRIx64, Seg.vmaddr) << " fileoff " 137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << Seg.fileoff << ")"; 138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total += Seg.vmsize; 140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t sec_total = 0; 141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned J = 0; J < Seg.nsects; ++J) { 142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::section_64 Sec = MachO->getSection64(Load, J); 143cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Filetype == MachO::MH_OBJECT) 144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\tSection (" << format("%.16s", &Sec.segname) << ", " 145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << format("%.16s", &Sec.sectname) << "): "; 146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 147cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\tSection " << format("%.16s", &Sec.sectname) << ": "; 148cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << format(fmt.str().c_str(), Sec.size); 149cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (DarwinLongFormat) 150cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << " (addr 0x" << format("%" PRIx64, Sec.addr) << " offset " 151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << Sec.offset << ")"; 152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sec_total += Sec.size; 154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Seg.nsects != 0) 156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\ttotal " << format(fmt.str().c_str(), sec_total) << "\n"; 157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (Load.C.cmd == MachO::LC_SEGMENT) { 158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::segment_command Seg = MachO->getSegmentLoadCommand(Load); 159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "Segment " << Seg.segname << ": " 160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << format(fmt.str().c_str(), Seg.vmsize); 161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (DarwinLongFormat) 162cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << " (vmaddr 0x" << format("%" PRIx64, Seg.vmaddr) << " fileoff " 163cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << Seg.fileoff << ")"; 164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total += Seg.vmsize; 166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t sec_total = 0; 167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned J = 0; J < Seg.nsects; ++J) { 168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::section Sec = MachO->getSection(Load, J); 169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Filetype == MachO::MH_OBJECT) 170cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\tSection (" << format("%.16s", &Sec.segname) << ", " 171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << format("%.16s", &Sec.sectname) << "): "; 172cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 173cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\tSection " << format("%.16s", &Sec.sectname) << ": "; 174cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << format(fmt.str().c_str(), Sec.size); 175cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (DarwinLongFormat) 176cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << " (addr 0x" << format("%" PRIx64, Sec.addr) << " offset " 177cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << Sec.offset << ")"; 178cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 179cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sec_total += Sec.size; 180cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 181cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Seg.nsects != 0) 182cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\ttotal " << format(fmt.str().c_str(), sec_total) << "\n"; 183cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 184cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (I == LoadCommandCount - 1) 185cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 186cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Load = MachO->getNextLoadCommandInfo(Load); 188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "total " << format(fmt.str().c_str(), total) << "\n"; 190cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 191cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 192cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// @brief Print the summary sizes of the standard Mach-O segments in @p MachO. 193cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// 194cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// This is when used when @c OutputFormat is berkeley with a Mach-O file and 195cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// produces the same output as darwin's size(1) default output. 196cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic void PrintDarwinSegmentSizes(MachOObjectFile *MachO) { 197cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint32_t LoadCommandCount = MachO->getHeader().ncmds; 198cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile::LoadCommandInfo Load = MachO->getFirstLoadCommandInfo(); 199cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 200cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t total_text = 0; 201cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t total_data = 0; 202cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t total_objc = 0; 203cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t total_others = 0; 204cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned I = 0;; ++I) { 205cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Load.C.cmd == MachO::LC_SEGMENT_64) { 206cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Load); 207cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MachO->getHeader().filetype == MachO::MH_OBJECT) { 208cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned J = 0; J < Seg.nsects; ++J) { 209cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::section_64 Sec = MachO->getSection64(Load, J); 210cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef SegmentName = StringRef(Sec.segname); 211cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SegmentName == "__TEXT") 212cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_text += Sec.size; 213cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (SegmentName == "__DATA") 214cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_data += Sec.size; 215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (SegmentName == "__OBJC") 216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_objc += Sec.size; 217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_others += Sec.size; 219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef SegmentName = StringRef(Seg.segname); 222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SegmentName == "__TEXT") 223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_text += Seg.vmsize; 224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (SegmentName == "__DATA") 225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_data += Seg.vmsize; 226cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (SegmentName == "__OBJC") 227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_objc += Seg.vmsize; 228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_others += Seg.vmsize; 230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 231cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (Load.C.cmd == MachO::LC_SEGMENT) { 232cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::segment_command Seg = MachO->getSegmentLoadCommand(Load); 233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MachO->getHeader().filetype == MachO::MH_OBJECT) { 234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned J = 0; J < Seg.nsects; ++J) { 235cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::section Sec = MachO->getSection(Load, J); 236cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef SegmentName = StringRef(Sec.segname); 237cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SegmentName == "__TEXT") 238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_text += Sec.size; 239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (SegmentName == "__DATA") 240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_data += Sec.size; 241cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (SegmentName == "__OBJC") 242cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_objc += Sec.size; 243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 244cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_others += Sec.size; 245cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 246cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 247cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef SegmentName = StringRef(Seg.segname); 248cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SegmentName == "__TEXT") 249cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_text += Seg.vmsize; 250cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (SegmentName == "__DATA") 251cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_data += Seg.vmsize; 252cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (SegmentName == "__OBJC") 253cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_objc += Seg.vmsize; 254cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 255cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines total_others += Seg.vmsize; 256cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 257cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 258cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (I == LoadCommandCount - 1) 259cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 260cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 261cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Load = MachO->getNextLoadCommandInfo(Load); 262cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 263cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t total = total_text + total_data + total_objc + total_others; 264cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 265cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!berkeleyHeaderPrinted) { 266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "__TEXT\t__DATA\t__OBJC\tothers\tdec\thex\n"; 267cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines berkeleyHeaderPrinted = true; 268cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 269cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << total_text << "\t" << total_data << "\t" << total_objc << "\t" 270cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << total_others << "\t" << total << "\t" << format("%" PRIx64, total) 271cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "\t"; 272cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 273cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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); 281cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const char *radix_fmt = getRadixFmt(); 282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 283cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // If OutputFormat is darwin and we have a MachOObjectFile print as darwin's 284cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // size(1) -m output, else if OutputFormat is darwin and not a Mach-O object 285cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // let it fall through to OutputFormat berkeley. 286cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj); 287cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == darwin && MachO) 288cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PrintDarwinSectionSizes(MachO); 289cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // If we have a MachOObjectFile and the OutputFormat is berkeley print as 290cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // darwin's default berkeley format for Mach-O files. 291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (MachO && OutputFormat == berkeley) 292cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PrintDarwinSegmentSizes(MachO); 293cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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()) { 30032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t size = 0; 30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getSize(size))) 30232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer return; 30332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total += size; 30432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 30532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer StringRef name; 30632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t addr = 0; 30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getName(name))) 30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getAddress(addr))) 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 31132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer max_name_len = std::max(max_name_len, name.size()); 312f47e870015439b1b47562533689a9dec17879befAndrew Trick max_size_len = std::max(max_size_len, getNumLengthAsString(size)); 313f47e870015439b1b47562533689a9dec17879befAndrew Trick max_addr_len = std::max(max_addr_len, getNumLengthAsString(addr)); 31432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 31532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 31675c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // Add extra padding. 31732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer max_name_len += 2; 31832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer max_size_len += 2; 31932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer max_addr_len += 2; 32032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 32175c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // Setup header format. 32232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmt << "%-" << max_name_len << "s " 32332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%" << max_size_len << "s " 32432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%" << max_addr_len << "s\n"; 32532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 32632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print header 327cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << format(fmt.str().c_str(), static_cast<const char *>("section"), 328cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static_cast<const char *>("size"), 329cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static_cast<const char *>("addr")); 33032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmtbuf.clear(); 33132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 33232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Setup per section format. 33332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmt << "%-" << max_name_len << "s " 33432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#" << max_size_len << radix_fmt << " " 33532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#" << max_addr_len << radix_fmt << "\n"; 33632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 33732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print each section. 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 33932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer StringRef name; 34032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t size = 0; 34132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t addr = 0; 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getName(name))) 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getSize(size))) 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getAddress(addr))) 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 34832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer std::string namestr = name; 34932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << format(fmt.str().c_str(), namestr.c_str(), size, addr); 35132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 35232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 35332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print total. 35432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmtbuf.clear(); 35532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmt << "%-" << max_name_len << "s " 35632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#" << max_size_len << radix_fmt << "\n"; 357cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << format(fmt.str().c_str(), static_cast<const char *>("Total"), 35832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total); 35932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } else { 36075c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // The Berkeley format does not display individual section sizes. It 36175c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // displays the cumulative size for each section type. 36232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t total_text = 0; 36332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t total_data = 0; 36432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t total_bss = 0; 36532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 36675c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // Make one pass over the section table to calculate sizes. 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 36832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer uint64_t size = 0; 36932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer bool isText = false; 37032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer bool isData = false; 37132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer bool isBSS = false; 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getSize(size))) 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.isText(isText))) 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.isData(isData))) 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.isBSS(isBSS))) 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 38032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (isText) 38132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total_text += size; 38232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer else if (isData) 38332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total_data += size; 38432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer else if (isBSS) 38532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total_bss += size; 38632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 38732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 38832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer total = total_text + total_data + total_bss; 38932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 390cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!berkeleyHeaderPrinted) { 391cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << " text data bss " 392cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << (Radix == octal ? "oct" : "dec") << " hex filename\n"; 393cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines berkeleyHeaderPrinted = true; 394cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 395cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 39632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print result. 39732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmt << "%#7" << radix_fmt << " " 39832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#7" << radix_fmt << " " 39932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer << "%#7" << radix_fmt << " "; 400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << format(fmt.str().c_str(), total_text, total_data, total_bss); 40132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer fmtbuf.clear(); 40241a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer fmt << "%7" << (Radix == octal ? PRIo64 : PRIu64) << " " 40341a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer << "%7" PRIx64 " "; 404cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << format(fmt.str().c_str(), total, total); 405cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 406cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 407cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 408cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// @brief Checks to see if the @p o ObjectFile is a Mach-O file and if it is 409cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// and there is a list of architecture flags specified then check to 410cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// make sure this Mach-O file is one of those architectures or all 411cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// architectures was specificed. If not then an error is generated and 412cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// this routine returns false. Else it returns true. 413cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic bool checkMachOAndArchFlags(ObjectFile *o, StringRef file) { 414cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (isa<MachOObjectFile>(o) && !ArchAll && ArchFlags.size() != 0) { 415cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 416cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool ArchFound = false; 417cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::mach_header H; 418cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachO::mach_header_64 H_64; 419cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Triple T; 420cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MachO->is64Bit()) { 421cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines H_64 = MachO->MachOObjectFile::getHeader64(); 422cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype); 423cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 424cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines H = MachO->MachOObjectFile::getHeader(); 425cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines T = MachOObjectFile::getArch(H.cputype, H.cpusubtype); 426cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 427cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned i; 428cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (i = 0; i < ArchFlags.size(); ++i) { 429cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ArchFlags[i] == T.getArchName()) 430cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ArchFound = true; 431cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 432cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 433cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!ArchFound) { 434cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << ToolName << ": file: " << file 435cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " does not contain architecture: " << ArchFlags[i] << ".\n"; 436cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 437cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 43832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 439cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 44032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer} 44132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 44275c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer/// @brief Print the section sizes for @p file. If @p file is an archive, print 44375c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer/// the section sizes for each archive member. 44432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerstatic void PrintFileSectionSizes(StringRef file) { 44532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // If file is not stdin, check that it exists. 44632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (file != "-") { 44732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer bool exists; 44832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (sys::fs::exists(file, exists) || !exists) { 449cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << ToolName << ": '" << file << "': " 450cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "No such file\n"; 45132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer return; 45232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 45332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 45432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 45575c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // Attempt to open the binary. 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorOr<Binary *> BinaryOrErr = createBinary(file); 457cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = BinaryOrErr.getError()) { 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; 45932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer return; 46032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Binary> binary(BinaryOrErr.get()); 46232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 46332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (Archive *a = dyn_cast<Archive>(binary.get())) { 46475c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // This is an archive. Iterate over each member and display its sizes. 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (object::Archive::child_iterator i = a->child_begin(), 466cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines e = a->child_end(); 467cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines i != e; ++i) { 468cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 469cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = ChildOrErr.getError()) { 470cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; 47132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer continue; 47232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 473cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { 474cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 475cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!checkMachOAndArchFlags(o, file)) 476cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return; 47732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (OutputFormat == sysv) 478cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (ex " << a->getFileName() << "):\n"; 479cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (MachO && OutputFormat == darwin) 480cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << a->getFileName() << "(" << o->getFileName() << "):\n"; 48132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer PrintObjectSectionSizes(o); 482cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == berkeley) { 483cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MachO) 484cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << a->getFileName() << "(" << o->getFileName() << ")\n"; 485cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 486cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (ex " << a->getFileName() << ")\n"; 487cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 488cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 489cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 490cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (MachOUniversalBinary *UB = 491cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines dyn_cast<MachOUniversalBinary>(binary.get())) { 492cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // If we have a list of architecture flags specified dump only those. 493cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!ArchAll && ArchFlags.size() != 0) { 494cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Look for a slice in the universal binary that matches each ArchFlag. 495cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool ArchFound; 496cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned i = 0; i < ArchFlags.size(); ++i) { 497cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ArchFound = false; 498cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 499cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines E = UB->end_objects(); 500cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines I != E; ++I) { 501cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ArchFlags[i] == I->getArchTypeName()) { 502cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ArchFound = true; 503cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile(); 504cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<Archive> UA; 505cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (UO) { 506cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) { 507cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 508cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == sysv) 509cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " :\n"; 510cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (MachO && OutputFormat == darwin) { 511cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (moreThanOneFile || ArchFlags.size() > 1) 512cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (for architecture " 513cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << I->getArchTypeName() << "): \n"; 514cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 515cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PrintObjectSectionSizes(o); 516cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == berkeley) { 517cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!MachO || moreThanOneFile || ArchFlags.size() > 1) 518cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (for architecture " 519cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << I->getArchTypeName() << ")"; 520cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 521cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 522cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 523cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (!I->getAsArchive(UA)) { 524cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // This is an archive. Iterate over each member and display its 525cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // sizes. 526cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (object::Archive::child_iterator i = UA->child_begin(), 527cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines e = UA->child_end(); 528cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines i != e; ++i) { 529cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 530cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = ChildOrErr.getError()) { 531cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << ToolName << ": " << file << ": " << EC.message() 532cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ".\n"; 533cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines continue; 534cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 535cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { 536cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 537cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == sysv) 538cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 539cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "):\n"; 540cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (MachO && OutputFormat == darwin) 541cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << UA->getFileName() << "(" << o->getFileName() 542cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ")" 543cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " (for architecture " << I->getArchTypeName() 544cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "):\n"; 545cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PrintObjectSectionSizes(o); 546cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == berkeley) { 547cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MachO) { 548cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << UA->getFileName() << "(" << o->getFileName() 549cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ")"; 550cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ArchFlags.size() > 1) 551cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << " (for architecture " << I->getArchTypeName() 552cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ")"; 553cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 554cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else 555cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 556cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ")\n"; 557cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 558cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 559cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 560cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 561cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 562cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 563cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!ArchFound) { 564cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << ToolName << ": file: " << file 565cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " does not contain architecture" << ArchFlags[i] << ".\n"; 566cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return; 567cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 568cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 569cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return; 570cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 571cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // No architecture flags were specified so if this contains a slice that 572cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // matches the host architecture dump only that. 573cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!ArchAll) { 574cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef HostArchName = MachOObjectFile::getHostArch().getArchName(); 575cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 576cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines E = UB->end_objects(); 577cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines I != E; ++I) { 578cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (HostArchName == I->getArchTypeName()) { 579cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile(); 580cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<Archive> UA; 581cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (UO) { 582cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) { 583cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 584cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == sysv) 585cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " :\n"; 586cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (MachO && OutputFormat == darwin) { 587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (moreThanOneFile) 588cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (for architecture " 589cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << I->getArchTypeName() << "):\n"; 590cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 591cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PrintObjectSectionSizes(o); 592cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == berkeley) { 593cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!MachO || moreThanOneFile) 594cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (for architecture " 595cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << I->getArchTypeName() << ")"; 596cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 597cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 598cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 599cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (!I->getAsArchive(UA)) { 600cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // This is an archive. Iterate over each member and display its 601cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // sizes. 602cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (object::Archive::child_iterator i = UA->child_begin(), 603cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines e = UA->child_end(); 604cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines i != e; ++i) { 605cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 606cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = ChildOrErr.getError()) { 607cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << ToolName << ": " << file << ": " << EC.message() 608cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ".\n"; 609cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines continue; 610cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 611cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { 612cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 613cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == sysv) 614cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 615cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "):\n"; 616cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (MachO && OutputFormat == darwin) 617cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << UA->getFileName() << "(" << o->getFileName() << ")" 618cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " (for architecture " << I->getArchTypeName() 619cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "):\n"; 620cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PrintObjectSectionSizes(o); 621cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == berkeley) { 622cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MachO) 623cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << UA->getFileName() << "(" << o->getFileName() 624cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ")\n"; 625cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 626cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 627cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ")\n"; 628cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 629cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 630cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 631cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 632cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return; 633cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 634cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 635cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 636cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Either all architectures have been specified or none have been specified 637cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // and this does not contain the host architecture so dump all the slices. 638cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool moreThanOneArch = UB->getNumberOfObjects() > 1; 639cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 640cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines E = UB->end_objects(); 641cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines I != E; ++I) { 642cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile(); 643cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<Archive> UA; 644cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (UO) { 645cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) { 646cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 647cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == sysv) 648cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " :\n"; 649cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (MachO && OutputFormat == darwin) { 650cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (moreThanOneFile || moreThanOneArch) 651cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (for architecture " 652cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << I->getArchTypeName() << "):"; 653cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 654cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 655cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PrintObjectSectionSizes(o); 656cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == berkeley) { 657cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!MachO || moreThanOneFile || moreThanOneArch) 658cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (for architecture " 659cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << I->getArchTypeName() << ")"; 660cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 661cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 662cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 663cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (!I->getAsArchive(UA)) { 664cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // This is an archive. Iterate over each member and display its sizes. 665cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (object::Archive::child_iterator i = UA->child_begin(), 666cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines e = UA->child_end(); 667cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines i != e; ++i) { 668cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 669cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = ChildOrErr.getError()) { 670cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; 671cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines continue; 672cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 673cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) { 674cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 675cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == sysv) 676cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 677cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "):\n"; 678cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (MachO && OutputFormat == darwin) 679cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << UA->getFileName() << "(" << o->getFileName() << ")" 680cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " (for architecture " << I->getArchTypeName() << "):\n"; 681cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PrintObjectSectionSizes(o); 682cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == berkeley) { 683cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MachO) 684cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << UA->getFileName() << "(" << o->getFileName() << ")" 685cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " (for architecture " << I->getArchTypeName() 686cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ")\n"; 687cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 688cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName() << " (ex " << UA->getFileName() 689cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << ")\n"; 690cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 691cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 692cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 69332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 69432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 69532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) { 696cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!checkMachOAndArchFlags(o, file)) 697cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return; 69832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (OutputFormat == sysv) 69932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer outs() << o->getFileName() << " :\n"; 70032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer PrintObjectSectionSizes(o); 701cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OutputFormat == berkeley) { 702cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o); 703cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!MachO || moreThanOneFile) 704cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << o->getFileName(); 705cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << "\n"; 706cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 70732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } else { 708cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << ToolName << ": " << file << ": " 709cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "Unrecognized file type.\n"; 71032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer } 71175c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer // System V adds an extra newline at the end of each file. 71232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (OutputFormat == sysv) 71332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer outs() << "\n"; 71432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer} 71532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 71632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerint main(int argc, char **argv) { 71732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer // Print a stack trace if we signal out. 71832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer sys::PrintStackTraceOnErrorSignal(); 71932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer PrettyStackTraceProgram X(argc, argv); 72032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 721cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 72232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer cl::ParseCommandLineOptions(argc, argv, "llvm object size dumper\n"); 72332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 72432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer ToolName = argv[0]; 72532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (OutputFormatShort.getNumOccurrences()) 72632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer OutputFormat = OutputFormatShort; 72732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (RadixShort.getNumOccurrences()) 72875c4abacaa8047f4e2971e98f093c6b731e3b0a8Michael J. Spencer Radix = RadixShort; 72932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 730cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned i = 0; i < ArchFlags.size(); ++i) { 731cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ArchFlags[i] == "all") { 732cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ArchAll = true; 733cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 734cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Triple T = MachOObjectFile::getArch(ArchFlags[i]); 735cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (T.getArch() == Triple::UnknownArch) { 736cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines outs() << ToolName << ": for the -arch option: Unknown architecture " 737cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "named '" << ArchFlags[i] << "'"; 738cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return 1; 739cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 740cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 741cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 742cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 74332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer if (InputFilenames.size() == 0) 74432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer InputFilenames.push_back("a.out"); 74532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 746cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines moreThanOneFile = InputFilenames.size() > 1; 74732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer std::for_each(InputFilenames.begin(), InputFilenames.end(), 74832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer PrintFileSectionSizes); 74932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer 75032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer return 0; 75132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer} 752