llvm-size.cpp revision 32a12ba8c0736a74681563a8f5ec8d81108514b5
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"
1932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/Casting.h"
2032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/CommandLine.h"
2132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/FileSystem.h"
2232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/Format.h"
2332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/ManagedStatic.h"
2432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/MemoryBuffer.h"
2532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/PrettyStackTrace.h"
2632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/raw_ostream.h"
2732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/Signals.h"
2832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include "llvm/Support/system_error.h"
2932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include <algorithm>
3032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer#include <string>
3132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerusing namespace llvm;
3232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerusing namespace object;
3332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
3432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencernamespace {
3532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  enum OutputFormatTy {berkeley, sysv};
3632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  cl::opt<OutputFormatTy>
3732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  OutputFormat("format",
3832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    cl::desc("Specify output format"),
3932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    cl::values(clEnumVal(sysv, "System V format"),
4032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer               clEnumVal(berkeley, "Berkeley format"),
4132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer               clEnumValEnd),
4232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    cl::init(berkeley));
4332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
4432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  cl::opt<OutputFormatTy>
4532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  OutputFormatShort(cl::desc("Specify output format"),
4632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    cl::values(clEnumValN(sysv, "A", "System V format"),
4732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer               clEnumValN(berkeley, "B", "Berkeley format"),
4832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer               clEnumValEnd),
4932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    cl::init(berkeley));
5032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
5132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  enum RadixTy {octal = 8, decimal = 10, hexadecimal = 16};
5232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  cl::opt<int>
5332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  Radix("-radix",
5432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    cl::desc("Print size in radix. Only 8, 10, and 16 are valid"),
5532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    cl::init(decimal));
5632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
5732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  cl::opt<RadixTy>
5832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  RadixShort(cl::desc("Print size in radix:"),
5932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  cl::values(clEnumValN(octal, "o", "Print size in octal"),
6032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer             clEnumValN(decimal, "d", "Print size in decimal"),
6132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer             clEnumValN(hexadecimal, "x", "Print size in hexadecimal"),
6232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer             clEnumValEnd),
6332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  cl::init(decimal));
6432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
6532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  cl::list<std::string>
6632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  InputFilenames(cl::Positional, cl::desc("<input files>"),
6732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                 cl::ZeroOrMore);
6832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
6932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  std::string ToolName;
7032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer}
7132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
7232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerstatic bool error(error_code ec) {
7332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (!ec) return false;
7432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
7532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
7632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  outs().flush();
7732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  return true;
7832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer}
7932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
8032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerstatic int getNumLengthAsString(uint64_t num) {
8132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  APInt conv(64, num);
8232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  SmallString<32> result;
8332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  conv.toString(result, unsigned int(Radix), false, true);
8432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  return result.size();
8532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer}
8632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
8732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerstatic void PrintObjectSectionSizes(ObjectFile *o) {
8832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  uint64_t total = 0;
8932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  std::string fmtbuf;
9032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  raw_string_ostream fmt(fmtbuf);
9132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
9232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  const char *radix_fmt = 0;
9332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  switch (Radix) {
9432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  case octal:
9532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    radix_fmt = "llo";
9632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    break;
9732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  case decimal:
9832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    radix_fmt = "llu";
9932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    break;
10032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  case hexadecimal:
10132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    radix_fmt = "llx";
10232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    break;
10332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  }
10432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (OutputFormat == sysv) {
10532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    // Run two passes over all sections. The first gets the lengths needed for
10632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    // formatting the output. The second actually does the output.
10732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    std::size_t max_name_len = strlen("section");
10832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    int max_size_len = strlen("size");
10932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    int max_addr_len = strlen("addr");
11032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    error_code ec;
11132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    for (ObjectFile::section_iterator i = o->begin_sections(),
11232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                                      e = o->end_sections(); i != e;
11332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                                      i.increment(ec)) {
11432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(ec))
11532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        return;
11632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      uint64_t size = 0;
11732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->getSize(size)))
11832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        return;
11932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      total += size;
12032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
12132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      StringRef name;
12232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      uint64_t addr = 0;
12332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->getName(name))) return;
12432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->getAddress(addr))) return;
12532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      max_name_len = std::max(max_name_len, name.size());
12632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      max_size_len = std::max(max_size_len, getNumLengthAsString(size));
12732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      max_addr_len = std::max(max_addr_len, getNumLengthAsString(addr));
12832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    }
12932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
13032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    max_name_len += 2;
13132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    max_size_len += 2;
13232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    max_addr_len += 2;
13332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
13432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    fmt << "%-" << max_name_len << "s "
13532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        << "%" << max_size_len << "s "
13632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        << "%" << max_addr_len << "s\n";
13732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
13832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    // Print header
13932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    outs() << format(fmt.str().c_str(),
14032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     static_cast<const char*>("section"),
14132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     static_cast<const char*>("size"),
14232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     static_cast<const char*>("addr"));
14332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    fmtbuf.clear();
14432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
14532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    // Setup per section format.
14632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    fmt << "%-" << max_name_len << "s "
14732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        << "%#" << max_size_len << radix_fmt << " "
14832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        << "%#" << max_addr_len << radix_fmt << "\n";
14932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
15032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    // Print each section.
15132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    for (ObjectFile::section_iterator i = o->begin_sections(),
15232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                                      e = o->end_sections(); i != e;
15332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                                      i.increment(ec)) {
15432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(ec))
15532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        return;
15632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
15732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      StringRef name;
15832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      uint64_t size = 0;
15932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      uint64_t addr = 0;
16032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->getName(name))) return;
16132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->getSize(size))) return;
16232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->getAddress(addr))) return;
16332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      std::string namestr = name;
16432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
16532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      outs() << format(fmt.str().c_str(),
16632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                       namestr.c_str(),
16732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                       size,
16832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                       addr);
16932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    }
17032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
17132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    // Print total.
17232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    fmtbuf.clear();
17332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    fmt << "%-" << max_name_len << "s "
17432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        << "%#" << max_size_len << radix_fmt << "\n";
17532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    outs() << format(fmt.str().c_str(),
17632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     static_cast<const char*>("Total"),
17732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     total);
17832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  } else {
17932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    uint64_t total_text = 0;
18032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    uint64_t total_data = 0;
18132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    uint64_t total_bss = 0;
18232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
18332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    error_code ec;
18432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    // Collect section data.
18532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    for (ObjectFile::section_iterator i = o->begin_sections(),
18632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                                      e = o->end_sections(); i != e;
18732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                                      i.increment(ec)) {
18832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(ec))
18932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        return;
19032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
19132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      uint64_t size = 0;
19232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      bool isText = false;
19332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      bool isData = false;
19432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      bool isBSS = false;
19532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->getSize(size))) return;
19632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->isText(isText))) return;
19732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->isData(isData))) return;
19832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error(i->isBSS(isBSS))) return;
19932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (isText)
20032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        total_text += size;
20132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      else if (isData)
20232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        total_data += size;
20332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      else if (isBSS)
20432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        total_bss += size;
20532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    }
20632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
20732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    total = total_text + total_data + total_bss;
20832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
20932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    // Print result.
21032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    fmt << "%#7" << radix_fmt << " "
21132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        << "%#7" << radix_fmt << " "
21232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        << "%#7" << radix_fmt << " ";
21332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    outs() << format(fmt.str().c_str(),
21432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     total_text,
21532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     total_data,
21632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     total_bss);
21732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    fmtbuf.clear();
21832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    fmt << "%7" << (Radix == octal ? "llo" : "llu") << " "
21932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        << "%7llx ";
22032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    outs() << format(fmt.str().c_str(),
22132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     total,
22232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                     total);
22332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  }
22432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer}
22532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
22632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerstatic void PrintFileSectionSizes(StringRef file) {
22732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  // If file is not stdin, check that it exists.
22832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (file != "-") {
22932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    bool exists;
23032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    if (sys::fs::exists(file, exists) || !exists) {
23132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      errs() << ToolName << ": '" << file << "': " << "No such file\n";
23232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      return;
23332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    }
23432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  }
23532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
23632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  OwningPtr<Binary> binary;
23732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (error_code ec = createBinary(file, binary)) {
23832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    errs() << ToolName << ": " << file << ": " << ec.message() << ".\n";
23932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    return;
24032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  }
24132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
24232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (Archive *a = dyn_cast<Archive>(binary.get())) {
24332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    for (object::Archive::child_iterator i = a->begin_children(),
24432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                                          e = a->end_children(); i != e; ++i) {
24532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      OwningPtr<Binary> child;
24632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (error_code ec = i->getAsBinary(child)) {
24732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        errs() << ToolName << ": " << file << ": " << ec.message() << ".\n";
24832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        continue;
24932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      }
25032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      if (ObjectFile *o = dyn_cast<ObjectFile>(child.get())) {
25132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        if (OutputFormat == sysv)
25232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer          outs() << o->getFileName() << "   (ex " << a->getFileName()
25332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                  << "):\n";
25432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        PrintObjectSectionSizes(o);
25532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer        if (OutputFormat == berkeley)
25632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer          outs() << o->getFileName() << " (ex " << a->getFileName() << ")\n";
25732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      }
25832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    }
25932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  } else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) {
26032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    if (OutputFormat == sysv)
26132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      outs() << o->getFileName() << "  :\n";
26232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    PrintObjectSectionSizes(o);
26332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    if (OutputFormat == berkeley)
26432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer      outs() << o->getFileName() << "\n";
26532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  } else {
26632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    errs() << ToolName << ": " << file << ": " << "Unrecognized file type.\n";
26732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  }
26832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (OutputFormat == sysv)
26932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    outs() << "\n";
27032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer}
27132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
27232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencerint main(int argc, char **argv) {
27332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  // Print a stack trace if we signal out.
27432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  sys::PrintStackTraceOnErrorSignal();
27532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  PrettyStackTraceProgram X(argc, argv);
27632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
27732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
27832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  cl::ParseCommandLineOptions(argc, argv, "llvm object size dumper\n");
27932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
28032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  ToolName = argv[0];
28132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (OutputFormatShort.getNumOccurrences())
28232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    OutputFormat = OutputFormatShort;
28332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (RadixShort.getNumOccurrences())
28432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    Radix = int(RadixShort);
28532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
28632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (InputFilenames.size() == 0)
28732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    InputFilenames.push_back("a.out");
28832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
28932a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  if (OutputFormat == berkeley)
29032a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer    outs() << "   text    data     bss     "
29132a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer           << (Radix == int(octal) ? "oct" : "dec")
29232a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer           << "     hex filename\n";
29332a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
29432a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  std::for_each(InputFilenames.begin(), InputFilenames.end(),
29532a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer                PrintFileSectionSizes);
29632a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer
29732a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer  return 0;
29832a12ba8c0736a74681563a8f5ec8d81108514b5Michael J. Spencer}
299