1 //===-- llvm-size.cpp - Print the size of each object section ---*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This program is a utility that works like traditional Unix "size",
11 // that is, it prints out the size of each section, and the total size of all
14 //===----------------------------------------------------------------------===//
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/Object/Archive.h"
18 #include "llvm/Object/MachO.h"
19 #include "llvm/Object/MachOUniversal.h"
20 #include "llvm/Object/ObjectFile.h"
21 #include "llvm/Support/Casting.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/Format.h"
25 #include "llvm/Support/ManagedStatic.h"
26 #include "llvm/Support/MemoryBuffer.h"
27 #include "llvm/Support/PrettyStackTrace.h"
28 #include "llvm/Support/Signals.h"
29 #include "llvm/Support/raw_ostream.h"
32 #include <system_error>
35 using namespace object;
37 enum OutputFormatTy { berkeley, sysv, darwin };
38 static cl::opt<OutputFormatTy>
39 OutputFormat("format", cl::desc("Specify output format"),
40 cl::values(clEnumVal(sysv, "System V format"),
41 clEnumVal(berkeley, "Berkeley format"),
42 clEnumVal(darwin, "Darwin -m format"), clEnumValEnd),
45 static cl::opt<OutputFormatTy> OutputFormatShort(
46 cl::desc("Specify output format"),
47 cl::values(clEnumValN(sysv, "A", "System V format"),
48 clEnumValN(berkeley, "B", "Berkeley format"),
49 clEnumValN(darwin, "m", "Darwin -m format"), clEnumValEnd),
52 static bool berkeleyHeaderPrinted = false;
53 static bool moreThanOneFile = false;
56 DarwinLongFormat("l", cl::desc("When format is darwin, use long format "
57 "to include addresses and offsets."));
59 static cl::list<std::string>
60 ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
64 enum RadixTy { octal = 8, decimal = 10, hexadecimal = 16 };
65 static cl::opt<unsigned int>
66 Radix("-radix", cl::desc("Print size in radix. Only 8, 10, and 16 are valid"),
69 static cl::opt<RadixTy>
70 RadixShort(cl::desc("Print size in radix:"),
71 cl::values(clEnumValN(octal, "o", "Print size in octal"),
72 clEnumValN(decimal, "d", "Print size in decimal"),
73 clEnumValN(hexadecimal, "x", "Print size in hexadecimal"),
77 static cl::list<std::string>
78 InputFilenames(cl::Positional, cl::desc("<input files>"), cl::ZeroOrMore);
80 static std::string ToolName;
82 /// @brief If ec is not success, print the error and return true.
83 static bool error(std::error_code ec) {
87 outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
92 /// @brief Get the length of the string that represents @p num in Radix
93 /// including the leading 0x or 0 for hexadecimal and octal respectively.
94 static size_t getNumLengthAsString(uint64_t num) {
96 SmallString<32> result;
97 conv.toString(result, Radix, false, true);
101 /// @brief Return the printing format for the Radix.
102 static const char *getRadixFmt() {
114 /// @brief Print the size of each Mach-O segment and section in @p MachO.
116 /// This is when used when @c OutputFormat is darwin and produces the same
117 /// output as darwin's size(1) -m output.
118 static void PrintDarwinSectionSizes(MachOObjectFile *MachO) {
120 raw_string_ostream fmt(fmtbuf);
121 const char *radix_fmt = getRadixFmt();
122 if (Radix == hexadecimal)
124 fmt << "%" << radix_fmt;
126 uint32_t Filetype = MachO->getHeader().filetype;
129 for (const auto &Load : MachO->load_commands()) {
130 if (Load.C.cmd == MachO::LC_SEGMENT_64) {
131 MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Load);
132 outs() << "Segment " << Seg.segname << ": "
133 << format(fmt.str().c_str(), Seg.vmsize);
134 if (DarwinLongFormat)
135 outs() << " (vmaddr 0x" << format("%" PRIx64, Seg.vmaddr) << " fileoff "
136 << Seg.fileoff << ")";
139 uint64_t sec_total = 0;
140 for (unsigned J = 0; J < Seg.nsects; ++J) {
141 MachO::section_64 Sec = MachO->getSection64(Load, J);
142 if (Filetype == MachO::MH_OBJECT)
143 outs() << "\tSection (" << format("%.16s", &Sec.segname) << ", "
144 << format("%.16s", &Sec.sectname) << "): ";
146 outs() << "\tSection " << format("%.16s", &Sec.sectname) << ": ";
147 outs() << format(fmt.str().c_str(), Sec.size);
148 if (DarwinLongFormat)
149 outs() << " (addr 0x" << format("%" PRIx64, Sec.addr) << " offset "
150 << Sec.offset << ")";
152 sec_total += Sec.size;
155 outs() << "\ttotal " << format(fmt.str().c_str(), sec_total) << "\n";
156 } else if (Load.C.cmd == MachO::LC_SEGMENT) {
157 MachO::segment_command Seg = MachO->getSegmentLoadCommand(Load);
158 outs() << "Segment " << Seg.segname << ": "
159 << format(fmt.str().c_str(), Seg.vmsize);
160 if (DarwinLongFormat)
161 outs() << " (vmaddr 0x" << format("%" PRIx64, Seg.vmaddr) << " fileoff "
162 << Seg.fileoff << ")";
165 uint64_t sec_total = 0;
166 for (unsigned J = 0; J < Seg.nsects; ++J) {
167 MachO::section Sec = MachO->getSection(Load, J);
168 if (Filetype == MachO::MH_OBJECT)
169 outs() << "\tSection (" << format("%.16s", &Sec.segname) << ", "
170 << format("%.16s", &Sec.sectname) << "): ";
172 outs() << "\tSection " << format("%.16s", &Sec.sectname) << ": ";
173 outs() << format(fmt.str().c_str(), Sec.size);
174 if (DarwinLongFormat)
175 outs() << " (addr 0x" << format("%" PRIx64, Sec.addr) << " offset "
176 << Sec.offset << ")";
178 sec_total += Sec.size;
181 outs() << "\ttotal " << format(fmt.str().c_str(), sec_total) << "\n";
184 outs() << "total " << format(fmt.str().c_str(), total) << "\n";
187 /// @brief Print the summary sizes of the standard Mach-O segments in @p MachO.
189 /// This is when used when @c OutputFormat is berkeley with a Mach-O file and
190 /// produces the same output as darwin's size(1) default output.
191 static void PrintDarwinSegmentSizes(MachOObjectFile *MachO) {
192 uint64_t total_text = 0;
193 uint64_t total_data = 0;
194 uint64_t total_objc = 0;
195 uint64_t total_others = 0;
196 for (const auto &Load : MachO->load_commands()) {
197 if (Load.C.cmd == MachO::LC_SEGMENT_64) {
198 MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Load);
199 if (MachO->getHeader().filetype == MachO::MH_OBJECT) {
200 for (unsigned J = 0; J < Seg.nsects; ++J) {
201 MachO::section_64 Sec = MachO->getSection64(Load, J);
202 StringRef SegmentName = StringRef(Sec.segname);
203 if (SegmentName == "__TEXT")
204 total_text += Sec.size;
205 else if (SegmentName == "__DATA")
206 total_data += Sec.size;
207 else if (SegmentName == "__OBJC")
208 total_objc += Sec.size;
210 total_others += Sec.size;
213 StringRef SegmentName = StringRef(Seg.segname);
214 if (SegmentName == "__TEXT")
215 total_text += Seg.vmsize;
216 else if (SegmentName == "__DATA")
217 total_data += Seg.vmsize;
218 else if (SegmentName == "__OBJC")
219 total_objc += Seg.vmsize;
221 total_others += Seg.vmsize;
223 } else if (Load.C.cmd == MachO::LC_SEGMENT) {
224 MachO::segment_command Seg = MachO->getSegmentLoadCommand(Load);
225 if (MachO->getHeader().filetype == MachO::MH_OBJECT) {
226 for (unsigned J = 0; J < Seg.nsects; ++J) {
227 MachO::section Sec = MachO->getSection(Load, J);
228 StringRef SegmentName = StringRef(Sec.segname);
229 if (SegmentName == "__TEXT")
230 total_text += Sec.size;
231 else if (SegmentName == "__DATA")
232 total_data += Sec.size;
233 else if (SegmentName == "__OBJC")
234 total_objc += Sec.size;
236 total_others += Sec.size;
239 StringRef SegmentName = StringRef(Seg.segname);
240 if (SegmentName == "__TEXT")
241 total_text += Seg.vmsize;
242 else if (SegmentName == "__DATA")
243 total_data += Seg.vmsize;
244 else if (SegmentName == "__OBJC")
245 total_objc += Seg.vmsize;
247 total_others += Seg.vmsize;
251 uint64_t total = total_text + total_data + total_objc + total_others;
253 if (!berkeleyHeaderPrinted) {
254 outs() << "__TEXT\t__DATA\t__OBJC\tothers\tdec\thex\n";
255 berkeleyHeaderPrinted = true;
257 outs() << total_text << "\t" << total_data << "\t" << total_objc << "\t"
258 << total_others << "\t" << total << "\t" << format("%" PRIx64, total)
262 /// @brief Print the size of each section in @p Obj.
264 /// The format used is determined by @c OutputFormat and @c Radix.
265 static void PrintObjectSectionSizes(ObjectFile *Obj) {
268 raw_string_ostream fmt(fmtbuf);
269 const char *radix_fmt = getRadixFmt();
271 // If OutputFormat is darwin and we have a MachOObjectFile print as darwin's
272 // size(1) -m output, else if OutputFormat is darwin and not a Mach-O object
273 // let it fall through to OutputFormat berkeley.
274 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj);
275 if (OutputFormat == darwin && MachO)
276 PrintDarwinSectionSizes(MachO);
277 // If we have a MachOObjectFile and the OutputFormat is berkeley print as
278 // darwin's default berkeley format for Mach-O files.
279 else if (MachO && OutputFormat == berkeley)
280 PrintDarwinSegmentSizes(MachO);
281 else if (OutputFormat == sysv) {
282 // Run two passes over all sections. The first gets the lengths needed for
283 // formatting the output. The second actually does the output.
284 std::size_t max_name_len = strlen("section");
285 std::size_t max_size_len = strlen("size");
286 std::size_t max_addr_len = strlen("addr");
287 for (const SectionRef &Section : Obj->sections()) {
288 uint64_t size = Section.getSize();
292 if (error(Section.getName(name)))
294 uint64_t addr = Section.getAddress();
295 max_name_len = std::max(max_name_len, name.size());
296 max_size_len = std::max(max_size_len, getNumLengthAsString(size));
297 max_addr_len = std::max(max_addr_len, getNumLengthAsString(addr));
300 // Add extra padding.
305 // Setup header format.
306 fmt << "%-" << max_name_len << "s "
307 << "%" << max_size_len << "s "
308 << "%" << max_addr_len << "s\n";
311 outs() << format(fmt.str().c_str(), static_cast<const char *>("section"),
312 static_cast<const char *>("size"),
313 static_cast<const char *>("addr"));
316 // Setup per section format.
317 fmt << "%-" << max_name_len << "s "
318 << "%#" << max_size_len << radix_fmt << " "
319 << "%#" << max_addr_len << radix_fmt << "\n";
321 // Print each section.
322 for (const SectionRef &Section : Obj->sections()) {
324 if (error(Section.getName(name)))
326 uint64_t size = Section.getSize();
327 uint64_t addr = Section.getAddress();
328 std::string namestr = name;
330 outs() << format(fmt.str().c_str(), namestr.c_str(), size, addr);
335 fmt << "%-" << max_name_len << "s "
336 << "%#" << max_size_len << radix_fmt << "\n";
337 outs() << format(fmt.str().c_str(), static_cast<const char *>("Total"),
340 // The Berkeley format does not display individual section sizes. It
341 // displays the cumulative size for each section type.
342 uint64_t total_text = 0;
343 uint64_t total_data = 0;
344 uint64_t total_bss = 0;
346 // Make one pass over the section table to calculate sizes.
347 for (const SectionRef &Section : Obj->sections()) {
348 uint64_t size = Section.getSize();
349 bool isText = Section.isText();
350 bool isData = Section.isData();
351 bool isBSS = Section.isBSS();
360 total = total_text + total_data + total_bss;
362 if (!berkeleyHeaderPrinted) {
363 outs() << " text data bss "
364 << (Radix == octal ? "oct" : "dec") << " hex filename\n";
365 berkeleyHeaderPrinted = true;
369 fmt << "%#7" << radix_fmt << " "
370 << "%#7" << radix_fmt << " "
371 << "%#7" << radix_fmt << " ";
372 outs() << format(fmt.str().c_str(), total_text, total_data, total_bss);
374 fmt << "%7" << (Radix == octal ? PRIo64 : PRIu64) << " "
376 outs() << format(fmt.str().c_str(), total, total);
380 /// @brief Checks to see if the @p o ObjectFile is a Mach-O file and if it is
381 /// and there is a list of architecture flags specified then check to
382 /// make sure this Mach-O file is one of those architectures or all
383 /// architectures was specificed. If not then an error is generated and
384 /// this routine returns false. Else it returns true.
385 static bool checkMachOAndArchFlags(ObjectFile *o, StringRef file) {
386 if (isa<MachOObjectFile>(o) && !ArchAll && ArchFlags.size() != 0) {
387 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
388 bool ArchFound = false;
389 MachO::mach_header H;
390 MachO::mach_header_64 H_64;
392 if (MachO->is64Bit()) {
393 H_64 = MachO->MachOObjectFile::getHeader64();
394 T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype);
396 H = MachO->MachOObjectFile::getHeader();
397 T = MachOObjectFile::getArch(H.cputype, H.cpusubtype);
400 for (i = 0; i < ArchFlags.size(); ++i) {
401 if (ArchFlags[i] == T.getArchName())
406 errs() << ToolName << ": file: " << file
407 << " does not contain architecture: " << ArchFlags[i] << ".\n";
414 /// @brief Print the section sizes for @p file. If @p file is an archive, print
415 /// the section sizes for each archive member.
416 static void PrintFileSectionSizes(StringRef file) {
418 // Attempt to open the binary.
419 ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
420 if (std::error_code EC = BinaryOrErr.getError()) {
421 errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
424 Binary &Bin = *BinaryOrErr.get().getBinary();
426 if (Archive *a = dyn_cast<Archive>(&Bin)) {
427 // This is an archive. Iterate over each member and display its sizes.
428 for (object::Archive::child_iterator i = a->child_begin(),
431 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
432 if (std::error_code EC = ChildOrErr.getError()) {
433 errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
436 if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
437 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
438 if (!checkMachOAndArchFlags(o, file))
440 if (OutputFormat == sysv)
441 outs() << o->getFileName() << " (ex " << a->getFileName() << "):\n";
442 else if (MachO && OutputFormat == darwin)
443 outs() << a->getFileName() << "(" << o->getFileName() << "):\n";
444 PrintObjectSectionSizes(o);
445 if (OutputFormat == berkeley) {
447 outs() << a->getFileName() << "(" << o->getFileName() << ")\n";
449 outs() << o->getFileName() << " (ex " << a->getFileName() << ")\n";
453 } else if (MachOUniversalBinary *UB =
454 dyn_cast<MachOUniversalBinary>(&Bin)) {
455 // If we have a list of architecture flags specified dump only those.
456 if (!ArchAll && ArchFlags.size() != 0) {
457 // Look for a slice in the universal binary that matches each ArchFlag.
459 for (unsigned i = 0; i < ArchFlags.size(); ++i) {
461 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
462 E = UB->end_objects();
464 if (ArchFlags[i] == I->getArchTypeName()) {
466 ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile();
468 if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
469 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
470 if (OutputFormat == sysv)
471 outs() << o->getFileName() << " :\n";
472 else if (MachO && OutputFormat == darwin) {
473 if (moreThanOneFile || ArchFlags.size() > 1)
474 outs() << o->getFileName() << " (for architecture "
475 << I->getArchTypeName() << "): \n";
477 PrintObjectSectionSizes(o);
478 if (OutputFormat == berkeley) {
479 if (!MachO || moreThanOneFile || ArchFlags.size() > 1)
480 outs() << o->getFileName() << " (for architecture "
481 << I->getArchTypeName() << ")";
485 } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
487 std::unique_ptr<Archive> &UA = *AOrErr;
488 // This is an archive. Iterate over each member and display its
490 for (object::Archive::child_iterator i = UA->child_begin(),
493 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
494 if (std::error_code EC = ChildOrErr.getError()) {
495 errs() << ToolName << ": " << file << ": " << EC.message()
499 if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
500 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
501 if (OutputFormat == sysv)
502 outs() << o->getFileName() << " (ex " << UA->getFileName()
504 else if (MachO && OutputFormat == darwin)
505 outs() << UA->getFileName() << "(" << o->getFileName()
507 << " (for architecture " << I->getArchTypeName()
509 PrintObjectSectionSizes(o);
510 if (OutputFormat == berkeley) {
512 outs() << UA->getFileName() << "(" << o->getFileName()
514 if (ArchFlags.size() > 1)
515 outs() << " (for architecture " << I->getArchTypeName()
519 outs() << o->getFileName() << " (ex " << UA->getFileName()
528 errs() << ToolName << ": file: " << file
529 << " does not contain architecture" << ArchFlags[i] << ".\n";
535 // No architecture flags were specified so if this contains a slice that
536 // matches the host architecture dump only that.
538 StringRef HostArchName = MachOObjectFile::getHostArch().getArchName();
539 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
540 E = UB->end_objects();
542 if (HostArchName == I->getArchTypeName()) {
543 ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile();
545 if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
546 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
547 if (OutputFormat == sysv)
548 outs() << o->getFileName() << " :\n";
549 else if (MachO && OutputFormat == darwin) {
551 outs() << o->getFileName() << " (for architecture "
552 << I->getArchTypeName() << "):\n";
554 PrintObjectSectionSizes(o);
555 if (OutputFormat == berkeley) {
556 if (!MachO || moreThanOneFile)
557 outs() << o->getFileName() << " (for architecture "
558 << I->getArchTypeName() << ")";
562 } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
564 std::unique_ptr<Archive> &UA = *AOrErr;
565 // This is an archive. Iterate over each member and display its
567 for (object::Archive::child_iterator i = UA->child_begin(),
570 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
571 if (std::error_code EC = ChildOrErr.getError()) {
572 errs() << ToolName << ": " << file << ": " << EC.message()
576 if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
577 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
578 if (OutputFormat == sysv)
579 outs() << o->getFileName() << " (ex " << UA->getFileName()
581 else if (MachO && OutputFormat == darwin)
582 outs() << UA->getFileName() << "(" << o->getFileName() << ")"
583 << " (for architecture " << I->getArchTypeName()
585 PrintObjectSectionSizes(o);
586 if (OutputFormat == berkeley) {
588 outs() << UA->getFileName() << "(" << o->getFileName()
591 outs() << o->getFileName() << " (ex " << UA->getFileName()
601 // Either all architectures have been specified or none have been specified
602 // and this does not contain the host architecture so dump all the slices.
603 bool moreThanOneArch = UB->getNumberOfObjects() > 1;
604 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
605 E = UB->end_objects();
607 ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile();
609 if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
610 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
611 if (OutputFormat == sysv)
612 outs() << o->getFileName() << " :\n";
613 else if (MachO && OutputFormat == darwin) {
614 if (moreThanOneFile || moreThanOneArch)
615 outs() << o->getFileName() << " (for architecture "
616 << I->getArchTypeName() << "):";
619 PrintObjectSectionSizes(o);
620 if (OutputFormat == berkeley) {
621 if (!MachO || moreThanOneFile || moreThanOneArch)
622 outs() << o->getFileName() << " (for architecture "
623 << I->getArchTypeName() << ")";
627 } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
629 std::unique_ptr<Archive> &UA = *AOrErr;
630 // This is an archive. Iterate over each member and display its sizes.
631 for (object::Archive::child_iterator i = UA->child_begin(),
634 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
635 if (std::error_code EC = ChildOrErr.getError()) {
636 errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
639 if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
640 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
641 if (OutputFormat == sysv)
642 outs() << o->getFileName() << " (ex " << UA->getFileName()
644 else if (MachO && OutputFormat == darwin)
645 outs() << UA->getFileName() << "(" << o->getFileName() << ")"
646 << " (for architecture " << I->getArchTypeName() << "):\n";
647 PrintObjectSectionSizes(o);
648 if (OutputFormat == berkeley) {
650 outs() << UA->getFileName() << "(" << o->getFileName() << ")"
651 << " (for architecture " << I->getArchTypeName()
654 outs() << o->getFileName() << " (ex " << UA->getFileName()
661 } else if (ObjectFile *o = dyn_cast<ObjectFile>(&Bin)) {
662 if (!checkMachOAndArchFlags(o, file))
664 if (OutputFormat == sysv)
665 outs() << o->getFileName() << " :\n";
666 PrintObjectSectionSizes(o);
667 if (OutputFormat == berkeley) {
668 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
669 if (!MachO || moreThanOneFile)
670 outs() << o->getFileName();
674 errs() << ToolName << ": " << file << ": "
675 << "Unrecognized file type.\n";
677 // System V adds an extra newline at the end of each file.
678 if (OutputFormat == sysv)
682 int main(int argc, char **argv) {
683 // Print a stack trace if we signal out.
684 sys::PrintStackTraceOnErrorSignal();
685 PrettyStackTraceProgram X(argc, argv);
687 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
688 cl::ParseCommandLineOptions(argc, argv, "llvm object size dumper\n");
691 if (OutputFormatShort.getNumOccurrences())
692 OutputFormat = static_cast<OutputFormatTy>(OutputFormatShort);
693 if (RadixShort.getNumOccurrences())
696 for (unsigned i = 0; i < ArchFlags.size(); ++i) {
697 if (ArchFlags[i] == "all") {
700 if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
701 outs() << ToolName << ": for the -arch option: Unknown architecture "
702 << "named '" << ArchFlags[i] << "'";
708 if (InputFilenames.size() == 0)
709 InputFilenames.push_back("a.out");
711 moreThanOneFile = InputFilenames.size() > 1;
712 std::for_each(InputFilenames.begin(), InputFilenames.end(),
713 PrintFileSectionSizes);