summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Object/MachOUniversal.cpp2
-rw-r--r--test/Object/size-trivial-macho.test12
-rw-r--r--tools/llvm-size/llvm-size.cpp52
3 files changed, 65 insertions, 1 deletions
diff --git a/lib/Object/MachOUniversal.cpp b/lib/Object/MachOUniversal.cpp
index e414de8bcf..05729ef746 100644
--- a/lib/Object/MachOUniversal.cpp
+++ b/lib/Object/MachOUniversal.cpp
@@ -53,7 +53,7 @@ static T getUniversalBinaryStruct(const char *Ptr) {
MachOUniversalBinary::ObjectForArch::ObjectForArch(
const MachOUniversalBinary *Parent, uint32_t Index)
: Parent(Parent), Index(Index) {
- if (!Parent || Index > Parent->getNumberOfObjects()) {
+ if (!Parent || Index >= Parent->getNumberOfObjects()) {
clear();
} else {
// Parse object header.
diff --git a/test/Object/size-trivial-macho.test b/test/Object/size-trivial-macho.test
index 960fb25fbe..1ed611b0de 100644
--- a/test/Object/size-trivial-macho.test
+++ b/test/Object/size-trivial-macho.test
@@ -10,6 +10,10 @@ RUN: llvm-size -format darwin %p/Inputs/macho-archive-x86_64.a \
RUN: | FileCheck %s -check-prefix mAR
RUN: llvm-size -format darwin -x -l %p/Inputs/hello-world.macho-x86_64 \
RUN: | FileCheck %s -check-prefix mxl
+RUN: llvm-size %p/Inputs/macho-universal.x86_64.i386 \
+RUN: | FileCheck %s -check-prefix u
+RUN: llvm-size %p/Inputs/macho-universal-archive.x86_64.i386 \
+RUN: | FileCheck %s -check-prefix uAR
A: section size addr
A: __text 12 0
@@ -65,3 +69,11 @@ mxl: Section __la_symbol_ptr: 0x8 (addr 0x100001010 offset 4112)
mxl: total 0x18
mxl: Segment __LINKEDIT: 0x1000 (vmaddr 0x100002000 fileoff 8192)
mxl: total 0x100003000
+
+u: __TEXT __DATA __OBJC others dec hex
+u: 4096 0 0 4294971392 4294975488 100002000 {{.*}}/macho-universal.x86_64.i386:x86_64
+u: 4096 0 0 8192 12288 3000 {{.*}}/macho-universal.x86_64.i386:i386
+
+uAR: __TEXT __DATA __OBJC others dec hex
+uAR: 136 0 0 32 168 a8 {{.*}}/macho-universal-archive.x86_64.i386:x86_64(hello.o)
+uAR: 5 4 0 0 9 9 {{.*}}/macho-universal-archive.x86_64.i386:i386(foo.o)
diff --git a/tools/llvm-size/llvm-size.cpp b/tools/llvm-size/llvm-size.cpp
index 5e4e4aa932..b3aaac8d27 100644
--- a/tools/llvm-size/llvm-size.cpp
+++ b/tools/llvm-size/llvm-size.cpp
@@ -17,6 +17,7 @@
#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/MachO.h"
+#include "llvm/Object/MachOUniversal.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
@@ -456,6 +457,57 @@ static void PrintFileSectionSizes(StringRef file) {
}
}
}
+ } else if (MachOUniversalBinary *UB =
+ dyn_cast<MachOUniversalBinary>(binary.get())) {
+ // This is a Mach-O universal binary. Iterate over each object and
+ // display its sizes.
+ bool moreThanOneArch = UB->getNumberOfObjects() > 1;
+ for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
+ E = UB->end_objects();
+ I != E; ++I) {
+ std::unique_ptr<ObjectFile> UO;
+ std::unique_ptr<Archive> UA;
+ if (!I->getAsObjectFile(UO)) {
+ if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
+ if (OutputFormat == sysv)
+ outs() << o->getFileName() << " :\n";
+ PrintObjectSectionSizes(o);
+ if (OutputFormat == berkeley) {
+ MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
+ if (!MachO || moreThanOneFile || moreThanOneArch)
+ outs() << o->getFileName();
+ outs() << "\n";
+ }
+ }
+ }
+ else if (!I->getAsArchive(UA)) {
+ // 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 = ChildOrErr.getError()) {
+ errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
+ continue;
+ }
+ if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
+ MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
+ if (OutputFormat == sysv)
+ outs() << o->getFileName() << " (ex " << UA->getFileName()
+ << "):\n";
+ else if(MachO && OutputFormat == darwin)
+ outs() << UA->getFileName() << "(" << o->getFileName() << "):\n";
+ PrintObjectSectionSizes(o);
+ if (OutputFormat == berkeley) {
+ if (MachO)
+ outs() << UA->getFileName() << "(" << o->getFileName() << ")\n";
+ else
+ outs() << o->getFileName() << " (ex " << UA->getFileName()
+ << ")\n";
+ }
+ }
+ }
+ }
+ }
} else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) {
if (OutputFormat == sysv)
outs() << o->getFileName() << " :\n";