From 117ac71069d0651e8f4f0b1df9373f85b791816b Mon Sep 17 00:00:00 2001 From: Ryan Mansfield Date: Wed, 10 Sep 2025 12:55:14 -0400 Subject: [PATCH 1/3] [llvm-size] Fix --totals option for Mach-O files The --totals option was not working for Mach-O files because the Darwin segment size calculation skipped the totals accumulation. --- llvm/test/tools/llvm-size/totals.test | 148 ++++++++++++++++++++++++++ llvm/tools/llvm-size/llvm-size.cpp | 43 ++++++-- 2 files changed, 181 insertions(+), 10 deletions(-) diff --git a/llvm/test/tools/llvm-size/totals.test b/llvm/test/tools/llvm-size/totals.test index 6f97dc18fee78..b4ca1f6f2f77f 100644 --- a/llvm/test/tools/llvm-size/totals.test +++ b/llvm/test/tools/llvm-size/totals.test @@ -16,6 +16,16 @@ # 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 --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 +65,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 diff --git a/llvm/tools/llvm-size/llvm-size.cpp b/llvm/tools/llvm-size/llvm-size.cpp index afb6b2386218e..acc7843ffac8b 100644 --- a/llvm/tools/llvm-size/llvm-size.cpp +++ b/llvm/tools/llvm-size/llvm-size.cpp @@ -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 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 &) { From c30e9b9eb4b5b0eaf28d0b2a9e0e2106d3bc4791 Mon Sep 17 00:00:00 2001 From: Ryan Mansfield Date: Tue, 16 Sep 2025 08:18:46 -0400 Subject: [PATCH 2/3] Fix FileCheck line wrapping. --- llvm/test/tools/llvm-size/totals.test | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/test/tools/llvm-size/totals.test b/llvm/test/tools/llvm-size/totals.test index b4ca1f6f2f77f..23de40a4b7ea8 100644 --- a/llvm/test/tools/llvm-size/totals.test +++ b/llvm/test/tools/llvm-size/totals.test @@ -19,7 +19,8 @@ # 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 --match-full-lines --implicit-check-not={{.}} -DFILE1=%t-macho.o -DFILE2=%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]] From f6f8fd00d957dc30e863cfd2824f8e6a33c78979 Mon Sep 17 00:00:00 2001 From: Ryan Mansfield Date: Thu, 18 Sep 2025 08:23:44 -0400 Subject: [PATCH 3/3] Update llvm/test/tools/llvm-size/totals.test Co-authored-by: James Henderson --- llvm/test/tools/llvm-size/totals.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/tools/llvm-size/totals.test b/llvm/test/tools/llvm-size/totals.test index 23de40a4b7ea8..c1a312ef89cda 100644 --- a/llvm/test/tools/llvm-size/totals.test +++ b/llvm/test/tools/llvm-size/totals.test @@ -18,8 +18,8 @@ # 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: 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