X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-size%2Fllvm-size.cpp;h=3de6605285bf2f22d8a2511ef49aab1c9b19e475;hb=1b0dc64919e947bb4f4677b138c734e33061f7c4;hp=25937583a15b9016a3022263bf640978ef90d604;hpb=32a12ba8c0736a74681563a8f5ec8d81108514b5;p=oota-llvm.git diff --git a/tools/llvm-size/llvm-size.cpp b/tools/llvm-size/llvm-size.cpp index 25937583a15..3de6605285b 100644 --- a/tools/llvm-size/llvm-size.cpp +++ b/tools/llvm-size/llvm-size.cpp @@ -23,52 +23,51 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" #include #include using namespace llvm; using namespace object; -namespace { - enum OutputFormatTy {berkeley, sysv}; - cl::opt - OutputFormat("format", - cl::desc("Specify output format"), - cl::values(clEnumVal(sysv, "System V format"), - clEnumVal(berkeley, "Berkeley format"), - clEnumValEnd), - cl::init(berkeley)); - - cl::opt - OutputFormatShort(cl::desc("Specify output format"), - cl::values(clEnumValN(sysv, "A", "System V format"), - clEnumValN(berkeley, "B", "Berkeley format"), - clEnumValEnd), - cl::init(berkeley)); - - enum RadixTy {octal = 8, decimal = 10, hexadecimal = 16}; - cl::opt - Radix("-radix", - cl::desc("Print size in radix. Only 8, 10, and 16 are valid"), - cl::init(decimal)); - - cl::opt - RadixShort(cl::desc("Print size in radix:"), - cl::values(clEnumValN(octal, "o", "Print size in octal"), - clEnumValN(decimal, "d", "Print size in decimal"), - clEnumValN(hexadecimal, "x", "Print size in hexadecimal"), - clEnumValEnd), - cl::init(decimal)); - - cl::list - InputFilenames(cl::Positional, cl::desc(""), - cl::ZeroOrMore); - - std::string ToolName; -} - +enum OutputFormatTy {berkeley, sysv}; +static cl::opt + OutputFormat("format", + cl::desc("Specify output format"), + cl::values(clEnumVal(sysv, "System V format"), + clEnumVal(berkeley, "Berkeley format"), + clEnumValEnd), + cl::init(berkeley)); + +static cl::opt + OutputFormatShort(cl::desc("Specify output format"), + cl::values(clEnumValN(sysv, "A", "System V format"), + clEnumValN(berkeley, "B", "Berkeley format"), + clEnumValEnd), + cl::init(berkeley)); + +enum RadixTy {octal = 8, decimal = 10, hexadecimal = 16}; +static cl::opt + Radix("-radix", + cl::desc("Print size in radix. Only 8, 10, and 16 are valid"), + cl::init(decimal)); + +static cl::opt + RadixShort(cl::desc("Print size in radix:"), + cl::values(clEnumValN(octal, "o", "Print size in octal"), + clEnumValN(decimal, "d", "Print size in decimal"), + clEnumValN(hexadecimal, "x", "Print size in hexadecimal"), + clEnumValEnd), + cl::init(decimal)); + +static cl::list + InputFilenames(cl::Positional, cl::desc(""), + cl::ZeroOrMore); + +static std::string ToolName; + +/// @brief If ec is not success, print the error and return true. static bool error(error_code ec) { if (!ec) return false; @@ -77,13 +76,18 @@ static bool error(error_code ec) { return true; } -static int getNumLengthAsString(uint64_t num) { +/// @brief Get the length of the string that represents @p num in Radix +/// including the leading 0x or 0 for hexadecimal and octal respectively. +static size_t getNumLengthAsString(uint64_t num) { APInt conv(64, num); SmallString<32> result; - conv.toString(result, unsigned int(Radix), false, true); + conv.toString(result, Radix, false, true); return result.size(); } +/// @brief Print the size of each section in @p o. +/// +/// The format used is determined by @c OutputFormat and @c Radix. static void PrintObjectSectionSizes(ObjectFile *o) { uint64_t total = 0; std::string fmtbuf; @@ -92,25 +96,25 @@ static void PrintObjectSectionSizes(ObjectFile *o) { const char *radix_fmt = 0; switch (Radix) { case octal: - radix_fmt = "llo"; + radix_fmt = PRIo64; break; case decimal: - radix_fmt = "llu"; + radix_fmt = PRIu64; break; case hexadecimal: - radix_fmt = "llx"; + radix_fmt = PRIx64; break; } if (OutputFormat == sysv) { // Run two passes over all sections. The first gets the lengths needed for // formatting the output. The second actually does the output. std::size_t max_name_len = strlen("section"); - int max_size_len = strlen("size"); - int max_addr_len = strlen("addr"); + std::size_t max_size_len = strlen("size"); + std::size_t max_addr_len = strlen("addr"); error_code ec; - for (ObjectFile::section_iterator i = o->begin_sections(), - e = o->end_sections(); i != e; - i.increment(ec)) { + for (section_iterator i = o->begin_sections(), + e = o->end_sections(); i != e; + i.increment(ec)) { if (error(ec)) return; uint64_t size = 0; @@ -127,10 +131,12 @@ static void PrintObjectSectionSizes(ObjectFile *o) { max_addr_len = std::max(max_addr_len, getNumLengthAsString(addr)); } + // Add extra padding. max_name_len += 2; max_size_len += 2; max_addr_len += 2; + // Setup header format. fmt << "%-" << max_name_len << "s " << "%" << max_size_len << "s " << "%" << max_addr_len << "s\n"; @@ -148,9 +154,9 @@ static void PrintObjectSectionSizes(ObjectFile *o) { << "%#" << max_addr_len << radix_fmt << "\n"; // Print each section. - for (ObjectFile::section_iterator i = o->begin_sections(), - e = o->end_sections(); i != e; - i.increment(ec)) { + for (section_iterator i = o->begin_sections(), + e = o->end_sections(); i != e; + i.increment(ec)) { if (error(ec)) return; @@ -176,15 +182,17 @@ static void PrintObjectSectionSizes(ObjectFile *o) { static_cast("Total"), total); } else { + // The Berkeley format does not display individual section sizes. It + // displays the cumulative size for each section type. uint64_t total_text = 0; uint64_t total_data = 0; uint64_t total_bss = 0; + // Make one pass over the section table to calculate sizes. error_code ec; - // Collect section data. - for (ObjectFile::section_iterator i = o->begin_sections(), - e = o->end_sections(); i != e; - i.increment(ec)) { + for (section_iterator i = o->begin_sections(), + e = o->end_sections(); i != e; + i.increment(ec)) { if (error(ec)) return; @@ -215,14 +223,16 @@ static void PrintObjectSectionSizes(ObjectFile *o) { total_data, total_bss); fmtbuf.clear(); - fmt << "%7" << (Radix == octal ? "llo" : "llu") << " " - << "%7llx "; + fmt << "%7" << (Radix == octal ? PRIo64 : PRIu64) << " " + << "%7" PRIx64 " "; outs() << format(fmt.str().c_str(), total, total); } } +/// @brief Print the section sizes for @p file. If @p file is an archive, print +/// the section sizes for each archive member. static void PrintFileSectionSizes(StringRef file) { // If file is not stdin, check that it exists. if (file != "-") { @@ -233,6 +243,7 @@ static void PrintFileSectionSizes(StringRef file) { } } + // Attempt to open the binary. OwningPtr binary; if (error_code ec = createBinary(file, binary)) { errs() << ToolName << ": " << file << ": " << ec.message() << ".\n"; @@ -240,8 +251,9 @@ static void PrintFileSectionSizes(StringRef file) { } if (Archive *a = dyn_cast(binary.get())) { + // This is an archive. Iterate over each member and display its sizes. for (object::Archive::child_iterator i = a->begin_children(), - e = a->end_children(); i != e; ++i) { + e = a->end_children(); i != e; ++i) { OwningPtr child; if (error_code ec = i->getAsBinary(child)) { errs() << ToolName << ": " << file << ": " << ec.message() << ".\n"; @@ -265,6 +277,7 @@ static void PrintFileSectionSizes(StringRef file) { } else { errs() << ToolName << ": " << file << ": " << "Unrecognized file type.\n"; } + // System V adds an extra newline at the end of each file. if (OutputFormat == sysv) outs() << "\n"; } @@ -281,14 +294,14 @@ int main(int argc, char **argv) { if (OutputFormatShort.getNumOccurrences()) OutputFormat = OutputFormatShort; if (RadixShort.getNumOccurrences()) - Radix = int(RadixShort); + Radix = RadixShort; if (InputFilenames.size() == 0) InputFilenames.push_back("a.out"); if (OutputFormat == berkeley) outs() << " text data bss " - << (Radix == int(octal) ? "oct" : "dec") + << (Radix == octal ? "oct" : "dec") << " hex filename\n"; std::for_each(InputFilenames.begin(), InputFilenames.end(),