-//===-- llvm-size.cpp - Print the size of each object section -------------===//
+//===-- llvm-size.cpp - Print the size of each object section ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#include "llvm/ADT/APInt.h"
#include "llvm/Object/Archive.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include <algorithm>
#include <string>
#include <system_error>
+
using namespace llvm;
using namespace object;
return result.size();
}
-/// @brief Return the the printing format for the Radix.
-static const char *getRadixFmt(void) {
+/// @brief Return the printing format for the Radix.
+static const char *getRadixFmt() {
switch (Radix) {
case octal:
return PRIo64;
fmt << "0x";
fmt << "%" << radix_fmt;
- uint32_t LoadCommandCount = MachO->getHeader().ncmds;
uint32_t Filetype = MachO->getHeader().filetype;
- MachOObjectFile::LoadCommandInfo Load = MachO->getFirstLoadCommandInfo();
uint64_t total = 0;
- for (unsigned I = 0;; ++I) {
+ for (const auto &Load : MachO->load_commands()) {
if (Load.C.cmd == MachO::LC_SEGMENT_64) {
MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Load);
outs() << "Segment " << Seg.segname << ": "
if (Seg.nsects != 0)
outs() << "\ttotal " << format(fmt.str().c_str(), sec_total) << "\n";
}
- if (I == LoadCommandCount - 1)
- break;
- else
- Load = MachO->getNextLoadCommandInfo(Load);
}
outs() << "total " << format(fmt.str().c_str(), total) << "\n";
}
/// This is when used when @c OutputFormat is berkeley with a Mach-O file and
/// produces the same output as darwin's size(1) default output.
static void PrintDarwinSegmentSizes(MachOObjectFile *MachO) {
- uint32_t LoadCommandCount = MachO->getHeader().ncmds;
- MachOObjectFile::LoadCommandInfo Load = MachO->getFirstLoadCommandInfo();
-
uint64_t total_text = 0;
uint64_t total_data = 0;
uint64_t total_objc = 0;
uint64_t total_others = 0;
- for (unsigned I = 0;; ++I) {
+ for (const auto &Load : MachO->load_commands()) {
if (Load.C.cmd == MachO::LC_SEGMENT_64) {
MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Load);
if (MachO->getHeader().filetype == MachO::MH_OBJECT) {
total_others += Seg.vmsize;
}
}
- if (I == LoadCommandCount - 1)
- break;
- else
- Load = MachO->getNextLoadCommandInfo(Load);
}
uint64_t total = total_text + total_data + total_objc + total_others;
std::size_t max_size_len = strlen("size");
std::size_t max_addr_len = strlen("addr");
for (const SectionRef &Section : Obj->sections()) {
- uint64_t size = 0;
- if (error(Section.getSize(size)))
- return;
+ uint64_t size = Section.getSize();
total += size;
StringRef name;
- uint64_t addr = 0;
if (error(Section.getName(name)))
return;
- if (error(Section.getAddress(addr)))
- return;
+ uint64_t addr = Section.getAddress();
max_name_len = std::max(max_name_len, name.size());
max_size_len = std::max(max_size_len, getNumLengthAsString(size));
max_addr_len = std::max(max_addr_len, getNumLengthAsString(addr));
// Print each section.
for (const SectionRef &Section : Obj->sections()) {
StringRef name;
- uint64_t size = 0;
- uint64_t addr = 0;
if (error(Section.getName(name)))
return;
- if (error(Section.getSize(size)))
- return;
- if (error(Section.getAddress(addr)))
- return;
+ uint64_t size = Section.getSize();
+ uint64_t addr = Section.getAddress();
std::string namestr = name;
outs() << format(fmt.str().c_str(), namestr.c_str(), size, addr);
// Make one pass over the section table to calculate sizes.
for (const SectionRef &Section : Obj->sections()) {
- uint64_t size = 0;
- bool isText = false;
- bool isData = false;
- bool isBSS = false;
- if (error(Section.getSize(size)))
- return;
- if (error(Section.isText(isText)))
- return;
- if (error(Section.isData(isData)))
- return;
- if (error(Section.isBSS(isBSS)))
- return;
+ uint64_t size = Section.getSize();
+ bool isText = Section.isText();
+ bool isData = Section.isData();
+ bool isBSS = Section.isBSS();
if (isText)
total_text += size;
else if (isData)
/// @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 != "-") {
- bool exists;
- if (sys::fs::exists(file, exists) || !exists) {
- errs() << ToolName << ": '" << file << "': "
- << "No such file\n";
- return;
- }
- }
// Attempt to open the binary.
- ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(file);
+ ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
if (std::error_code EC = BinaryOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
return;
}
- Binary &Bin = *BinaryOrErr.get();
+ Binary &Bin = *BinaryOrErr.get().getBinary();
if (Archive *a = dyn_cast<Archive>(&Bin)) {
// This is an archive. Iterate over each member and display its sizes.
for (object::Archive::child_iterator i = a->child_begin(),
e = a->child_end();
i != e; ++i) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
+ if (i->getError()) {
+ errs() << ToolName << ": " << file << ": " << i->getError().message()
+ << ".\n";
+ exit(1);
+ }
+ auto &c = i->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = c.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
continue;
if (ArchFlags[i] == I->getArchTypeName()) {
ArchFound = true;
ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile();
- std::unique_ptr<Archive> UA;
if (UO) {
if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
outs() << "\n";
}
}
- } else if (!I->getAsArchive(UA)) {
+ } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
+ I->getAsArchive()) {
+ std::unique_ptr<Archive> &UA = *AOrErr;
// This is an archive. Iterate over each member and display its
// sizes.
for (object::Archive::child_iterator i = UA->child_begin(),
e = UA->child_end();
i != e; ++i) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
+ if (std::error_code EC = i->getError()) {
+ errs() << ToolName << ": " << file << ": " << EC.message()
+ << ".\n";
+ exit(1);
+ }
+ auto &c = i->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = c.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message()
<< ".\n";
I != E; ++I) {
if (HostArchName == I->getArchTypeName()) {
ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile();
- std::unique_ptr<Archive> UA;
if (UO) {
if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
outs() << "\n";
}
}
- } else if (!I->getAsArchive(UA)) {
+ } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
+ I->getAsArchive()) {
+ std::unique_ptr<Archive> &UA = *AOrErr;
// This is an archive. Iterate over each member and display its
// sizes.
for (object::Archive::child_iterator i = UA->child_begin(),
e = UA->child_end();
i != e; ++i) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
+ if (std::error_code EC = i->getError()) {
+ errs() << ToolName << ": " << file << ": " << EC.message()
+ << ".\n";
+ exit(1);
+ }
+ auto &c = i->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = c.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message()
<< ".\n";
E = UB->end_objects();
I != E; ++I) {
ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile();
- std::unique_ptr<Archive> UA;
if (UO) {
if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
outs() << "\n";
}
}
- } else if (!I->getAsArchive(UA)) {
+ } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
+ I->getAsArchive()) {
+ std::unique_ptr<Archive> &UA = *AOrErr;
// This is an archive. Iterate over each member and display its sizes.
for (object::Archive::child_iterator i = UA->child_begin(),
e = UA->child_end();
i != e; ++i) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
+ if (std::error_code EC = i->getError()) {
+ errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
+ exit(1);
+ }
+ auto &c = i->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = c.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
continue;
ToolName = argv[0];
if (OutputFormatShort.getNumOccurrences())
- OutputFormat = OutputFormatShort;
+ OutputFormat = static_cast<OutputFormatTy>(OutputFormatShort);
if (RadixShort.getNumOccurrences())
Radix = RadixShort;