Index: test/tools/llvm-size/X86/ignore-sections.s =================================================================== --- test/tools/llvm-size/X86/ignore-sections.s +++ test/tools/llvm-size/X86/ignore-sections.s @@ -1,6 +1,6 @@ // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux // RUN: llvm-size -A %t.o | FileCheck --check-prefix="SYSV" %s -// RUN: llvm-size -B %t.o| FileCheck --check-prefix="BSD" %s +// RUN: llvm-size -B -t %t.o| FileCheck --check-prefix="BSD" %s .text .zero 4 @@ -26,3 +26,4 @@ // BSD: text data bss dec hex filename // BSD-NEXT: 4 4 4 12 c {{[ -\(\)_A-Za-z0-9.\\/:]+}} +// BSD-NEXT: 4 4 4 12 c (TOTALS) Index: tools/llvm-size/llvm-size.cpp =================================================================== --- tools/llvm-size/llvm-size.cpp +++ tools/llvm-size/llvm-size.cpp @@ -52,6 +52,10 @@ static bool BerkeleyHeaderPrinted = false; static bool MoreThanOneFile = false; +static uint64_t TotalObjectText = 0; +static uint64_t TotalObjectData = 0; +static uint64_t TotalObjectBss = 0; +static uint64_t TotalObjectTotal = 0; cl::opt DarwinLongFormat("l", cl::desc("When format is darwin, use long format " @@ -81,6 +85,14 @@ clEnumValEnd), cl::init(decimal)); +static cl::opt + TotalSizes("totals", + cl::desc("Print totals of all objects - Berkeley format only"), + cl::init(false)); + +static cl::alias TotalSizesShort("t", cl::desc("Short for --totals"), + cl::aliasopt(TotalSizes)); + static cl::list InputFilenames(cl::Positional, cl::desc(""), cl::ZeroOrMore); @@ -108,7 +120,7 @@ // This version of error() prints the archive name and member name, for example: // "libx.a(foo.o)" after the ToolName before the error message. It sets -// HadError but returns allowing the code to move on to other archive members. +// HadError but returns allowing the code to move on to other archive members. static void error(llvm::Error E, StringRef FileName, const Archive::Child &C, StringRef ArchitectureName = StringRef()) { HadError = true; @@ -136,7 +148,7 @@ // This version of error() prints the file name and which architecture slice it // is from, for example: "foo.o (for architecture i386)" after the ToolName // before the error message. It sets HadError but returns allowing the code to -// move on to other architecture slices. +// move on to other architecture slices. static void error(llvm::Error E, StringRef FileName, StringRef ArchitectureName = StringRef()) { HadError = true; @@ -462,6 +474,13 @@ total = total_text + total_data + total_bss; + if (TotalSizes) { + TotalObjectText += total_text; + TotalObjectData += total_data; + TotalObjectBss += total_bss; + TotalObjectTotal += total; + } + if (!BerkeleyHeaderPrinted) { outs() << " text data bss " << (Radix == octal ? "oct" : "dec") << " hex filename\n"; @@ -821,6 +840,22 @@ outs() << "\n"; } +static void printBerkelyTotals() { + std::string fmtbuf; + raw_string_ostream fmt(fmtbuf); + const char *radix_fmt = getRadixFmt(); + fmt << "%#7" << radix_fmt << " " + << "%#7" << radix_fmt << " " + << "%#7" << radix_fmt << " "; + outs() << format(fmt.str().c_str(), TotalObjectText, TotalObjectData, + TotalObjectBss); + fmtbuf.clear(); + fmt << "%7" << (Radix == octal ? PRIo64 : PRIu64) << " " + << "%7" PRIx64 " "; + outs() << format(fmt.str().c_str(), TotalObjectTotal, TotalObjectTotal) + << "(TOTALS)\n"; +} + int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(argv[0]); @@ -853,6 +888,8 @@ MoreThanOneFile = InputFilenames.size() > 1; std::for_each(InputFilenames.begin(), InputFilenames.end(), printFileSectionSizes); + if (OutputFormat == berkeley && TotalSizes) + printBerkelyTotals(); if (HadError) return 1;