[llvm-size] Fix --totals option for Mach-O files (#157904)

The --totals option was not working for Mach-O files because the Darwin
segment size calculation skipped the totals accumulation.

---------

Co-authored-by: James Henderson <James.Henderson@sony.com>
This commit is contained in:
Ryan Mansfield
2025-09-18 09:07:33 -04:00
committed by GitHub
parent 01b4b2a5b8
commit dcd0a2eecc
2 changed files with 182 additions and 10 deletions

View File

@@ -16,6 +16,17 @@
# CHECK-NEXT: [[FILE2]]
# CHECK-NEXT: 18 36 72 126 7e (TOTALS)
# RUN: yaml2obj %s --docnum=3 -o %t-macho.o
# RUN: yaml2obj %s --docnum=4 -o %t-macho2.o
# RUN: llvm-size --totals %t-macho.o %t-macho2.o | \
# RUN: FileCheck %s --check-prefix=MACHO-CHECK --strict-whitespace \
# RUN: --match-full-lines --implicit-check-not={{.}} -DFILE1=%t-macho.o -DFILE2=%t-macho2.o
# MACHO-CHECK:__TEXT __DATA __OBJC others dec hex
# MACHO-CHECK-NEXT:20 100 0 32 152 98 [[FILE1]]
# MACHO-CHECK-NEXT:20 200 0 32 252 fc [[FILE2]]
# MACHO-CHECK-NEXT:40 300 0 64 404 194 (TOTALS)
--- !ELF
FileHeader:
Class: ELFCLASS64
@@ -55,3 +66,141 @@ Sections:
Type: SHT_NOBITS
Flags: [SHF_ALLOC, SHF_WRITE]
Size: 32
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x100000C
cpusubtype: 0x0
filetype: 0x1
ncmds: 2
sizeofcmds: 352
flags: 0x2000
reserved: 0x0
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 312
segname: ''
vmaddr: 0
vmsize: 152
fileoff: 384
filesize: 152
maxprot: 7
initprot: 7
nsects: 3
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0
size: 20
offset: 0x180
align: 2
reloff: 0x0
nreloc: 0
flags: 0x80000400
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
- sectname: __data
segname: __DATA
addr: 0x18
size: 100
offset: 0x198
align: 2
reloff: 0x0
nreloc: 0
flags: 0x0
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
- sectname: __compact_unwind
segname: __LD
addr: 0x20
size: 32
offset: 0x200
align: 3
reloff: 0x0
nreloc: 0
flags: 0x2000000
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
- cmd: LC_BUILD_VERSION
cmdsize: 32
platform: 1
minos: 851968
sdk: 983040
ntools: 1
Tools:
- tool: 3
version: 68157696
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x100000C
cpusubtype: 0x0
filetype: 0x1
ncmds: 2
sizeofcmds: 352
flags: 0x2000
reserved: 0x0
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 312
segname: ''
vmaddr: 0
vmsize: 252
fileoff: 384
filesize: 252
maxprot: 7
initprot: 7
nsects: 3
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0
size: 20
offset: 0x180
align: 2
reloff: 0x0
nreloc: 0
flags: 0x80000400
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
- sectname: __data
segname: __DATA
addr: 0x18
size: 200
offset: 0x198
align: 2
reloff: 0x0
nreloc: 0
flags: 0x0
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
- sectname: __compact_unwind
segname: __LD
addr: 0x20
size: 32
offset: 0x260
align: 3
reloff: 0x0
nreloc: 0
flags: 0x2000000
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
- cmd: LC_BUILD_VERSION
cmdsize: 32
platform: 1
minos: 851968
sdk: 983040
ntools: 1
Tools:
- tool: 3
version: 68157696

View File

@@ -78,6 +78,7 @@ static OutputFormatTy OutputFormat;
static bool DarwinLongFormat;
static RadixTy Radix = RadixTy::decimal;
static bool TotalSizes;
static bool HasMachOFiles = false;
static std::vector<std::string> InputFilenames;
@@ -92,6 +93,10 @@ static uint64_t TotalObjectData = 0;
static uint64_t TotalObjectBss = 0;
static uint64_t TotalObjectTotal = 0;
// Darwin-specific totals
static uint64_t TotalObjectObjc = 0;
static uint64_t TotalObjectOthers = 0;
static void error(const Twine &Message, StringRef File = "") {
HadError = true;
if (File.empty())
@@ -283,6 +288,7 @@ static void printDarwinSegmentSizes(MachOObjectFile *MachO) {
uint64_t total_data = 0;
uint64_t total_objc = 0;
uint64_t total_others = 0;
HasMachOFiles = true;
for (const auto &Load : MachO->load_commands()) {
if (Load.C.cmd == MachO::LC_SEGMENT_64) {
MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Load);
@@ -340,6 +346,14 @@ static void printDarwinSegmentSizes(MachOObjectFile *MachO) {
}
uint64_t total = total_text + total_data + total_objc + total_others;
if (TotalSizes) {
TotalObjectText += total_text;
TotalObjectData += total_data;
TotalObjectObjc += total_objc;
TotalObjectOthers += total_others;
TotalObjectTotal += total;
}
if (!BerkeleyHeaderPrinted) {
outs() << "__TEXT\t__DATA\t__OBJC\tothers\tdec\thex\n";
BerkeleyHeaderPrinted = true;
@@ -852,16 +866,25 @@ static void printBerkeleyTotals() {
std::string fmtbuf;
raw_string_ostream fmt(fmtbuf);
const char *radix_fmt = getRadixFmt();
fmt << "%#7" << radix_fmt << "\t"
<< "%#7" << radix_fmt << "\t"
<< "%#7" << radix_fmt << "\t";
outs() << format(fmtbuf.c_str(), TotalObjectText, TotalObjectData,
TotalObjectBss);
fmtbuf.clear();
fmt << "%7" << (Radix == octal ? PRIo64 : PRIu64) << "\t"
<< "%7" PRIx64 "\t";
outs() << format(fmtbuf.c_str(), TotalObjectTotal, TotalObjectTotal)
<< "(TOTALS)\n";
if (HasMachOFiles) {
// Darwin format totals: __TEXT __DATA __OBJC others dec hex
outs() << TotalObjectText << "\t" << TotalObjectData << "\t"
<< TotalObjectObjc << "\t" << TotalObjectOthers << "\t"
<< TotalObjectTotal << "\t" << format("%" PRIx64, TotalObjectTotal)
<< "\t(TOTALS)\n";
} else {
fmt << "%#7" << radix_fmt << "\t"
<< "%#7" << radix_fmt << "\t"
<< "%#7" << radix_fmt << "\t";
outs() << format(fmtbuf.c_str(), TotalObjectText, TotalObjectData,
TotalObjectBss);
fmtbuf.clear();
fmt << "%7" << (Radix == octal ? PRIo64 : PRIu64) << "\t"
<< "%7" PRIx64 "\t";
outs() << format(fmtbuf.c_str(), TotalObjectTotal, TotalObjectTotal)
<< "(TOTALS)\n";
}
}
int llvm_size_main(int argc, char **argv, const llvm::ToolContext &) {