Skip to content

Commit 30b0215

Browse files
authored
[llvm-size] Add --exclude-pagezero option for Mach-O to exclude __PAGEZERO size. (#159574)
Do not include the ``__PAGEZERO`` segment when calculating size information for Mach-O files when `--exclude-pagezero` is used. The ``__PAGEZERO`` segment is a virtual memory region used for memory protection that does not contribute to actual size, and excluding can provide a better representation of actual size. Fixes #86644
1 parent 3b299af commit 30b0215

File tree

4 files changed

+122
-2
lines changed

4 files changed

+122
-2
lines changed

llvm/docs/CommandGuide/llvm-size.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ OPTIONS
4141
as a separate section entry for ``sysv`` output. If not specified, these
4242
symbols are ignored.
4343

44+
.. option:: --exclude-pagezero
45+
46+
Do not include the ``__PAGEZERO`` segment when calculating size information
47+
for Mach-O files. The ``__PAGEZERO`` segment is a virtual memory region used
48+
for memory protection that does not contribute to actual size, and excluding
49+
can provide a better representation of actual size.
50+
4451
.. option:: -d
4552

4653
Equivalent to :option:`--radix` with a value of ``10``.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
## Test the --exclude-pagezero option to skip __PAGEZERO segment in Mach-O files.
2+
3+
# RUN: yaml2obj %s --docnum=1 -o %t-pagezero.o
4+
# RUN: llvm-size %t-pagezero.o | \
5+
# RUN: FileCheck %s --check-prefix=NORMAL --match-full-lines
6+
# RUN: llvm-size --exclude-pagezero %t-pagezero.o | \
7+
# RUN: FileCheck %s --check-prefix=SKIP --match-full-lines
8+
9+
# RUN: yaml2obj %s --docnum=2 -o %t-pagezero32.o
10+
# RUN: llvm-size %t-pagezero32.o | \
11+
# RUN: FileCheck %s --check-prefix=NORMAL --match-full-lines
12+
# RUN: llvm-size --exclude-pagezero %t-pagezero32.o | \
13+
# RUN: FileCheck %s --check-prefix=SKIP --match-full-lines
14+
15+
# NORMAL:__TEXT __DATA __OBJC others dec hex
16+
# NORMAL-NEXT:20 100 0 4096 4216 1078
17+
18+
# SKIP:__TEXT __DATA __OBJC others dec hex
19+
# SKIP-NEXT:20 100 0 0 120 78
20+
21+
--- !mach-o
22+
FileHeader:
23+
magic: 0xFEEDFACF
24+
cputype: 0x100000C
25+
cpusubtype: 0x0
26+
filetype: 0x2
27+
ncmds: 3
28+
sizeofcmds: 216
29+
flags: 0x2000
30+
reserved: 0x0
31+
LoadCommands:
32+
- cmd: LC_SEGMENT_64
33+
cmdsize: 72
34+
segname: __PAGEZERO
35+
vmaddr: 0x0
36+
vmsize: 4096
37+
fileoff: 0
38+
filesize: 0
39+
maxprot: 0
40+
initprot: 0
41+
nsects: 0
42+
flags: 0
43+
- cmd: LC_SEGMENT_64
44+
cmdsize: 72
45+
segname: __TEXT
46+
vmaddr: 0x100000000
47+
vmsize: 20
48+
fileoff: 248
49+
filesize: 20
50+
maxprot: 7
51+
initprot: 5
52+
nsects: 0
53+
flags: 0
54+
- cmd: LC_SEGMENT_64
55+
cmdsize: 72
56+
segname: __DATA
57+
vmaddr: 0x100001000
58+
vmsize: 100
59+
fileoff: 268
60+
filesize: 100
61+
maxprot: 7
62+
initprot: 3
63+
nsects: 0
64+
flags: 0
65+
66+
--- !mach-o
67+
FileHeader:
68+
magic: 0xFEEDFACE
69+
cputype: 0x7
70+
cpusubtype: 0x3
71+
filetype: 0x2
72+
ncmds: 3
73+
sizeofcmds: 168
74+
flags: 0x2000
75+
LoadCommands:
76+
- cmd: LC_SEGMENT
77+
cmdsize: 56
78+
segname: __PAGEZERO
79+
vmaddr: 0x0
80+
vmsize: 4096
81+
fileoff: 0
82+
filesize: 0
83+
maxprot: 0
84+
initprot: 0
85+
nsects: 0
86+
flags: 0
87+
- cmd: LC_SEGMENT
88+
cmdsize: 56
89+
segname: __TEXT
90+
vmaddr: 0x1000
91+
vmsize: 20
92+
fileoff: 196
93+
filesize: 20
94+
maxprot: 7
95+
initprot: 5
96+
nsects: 0
97+
flags: 0
98+
- cmd: LC_SEGMENT
99+
cmdsize: 56
100+
segname: __DATA
101+
vmaddr: 0x2000
102+
vmsize: 100
103+
fileoff: 216
104+
filesize: 100
105+
maxprot: 7
106+
initprot: 3
107+
nsects: 0
108+
flags: 0

llvm/tools/llvm-size/Opts.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ def grp_mach_o : OptionGroup<"kind">, HelpText<"OPTIONS (Mach-O specific)">;
2121
def arch_EQ : Joined<["--"], "arch=">, HelpText<"architecture(s) from a Mach-O file to dump">, Group<grp_mach_o>;
2222
def : Separate<["--", "-"], "arch">, Alias<arch_EQ>;
2323
def l : F<"l", "When format is darwin, use long format to include addresses and offsets">, Group<grp_mach_o>;
24+
def exclude_pagezero
25+
: FF<"exclude-pagezero", "Do not include __PAGEZERO segment in totals">,
26+
Group<grp_mach_o>;
2427

2528
def : F<"A", "Alias for --format">, Alias<format_EQ>, AliasArgs<["sysv"]>;
2629
def : F<"B", "Alias for --format">, Alias<format_EQ>, AliasArgs<["berkeley"]>;

llvm/tools/llvm-size/llvm-size.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ static bool DarwinLongFormat;
7979
static RadixTy Radix = RadixTy::decimal;
8080
static bool TotalSizes;
8181
static bool HasMachOFiles = false;
82+
static bool ExcludePageZero = false;
8283

8384
static std::vector<std::string> InputFilenames;
8485

@@ -313,7 +314,7 @@ static void printDarwinSegmentSizes(MachOObjectFile *MachO) {
313314
total_data += Seg.vmsize;
314315
else if (SegmentName == "__OBJC")
315316
total_objc += Seg.vmsize;
316-
else
317+
else if (!ExcludePageZero || SegmentName != "__PAGEZERO")
317318
total_others += Seg.vmsize;
318319
}
319320
} else if (Load.C.cmd == MachO::LC_SEGMENT) {
@@ -339,7 +340,7 @@ static void printDarwinSegmentSizes(MachOObjectFile *MachO) {
339340
total_data += Seg.vmsize;
340341
else if (SegmentName == "__OBJC")
341342
total_objc += Seg.vmsize;
342-
else
343+
else if (!ExcludePageZero || SegmentName != "__PAGEZERO")
343344
total_others += Seg.vmsize;
344345
}
345346
}
@@ -914,6 +915,7 @@ int llvm_size_main(int argc, char **argv, const llvm::ToolContext &) {
914915

915916
ELFCommons = Args.hasArg(OPT_common);
916917
DarwinLongFormat = Args.hasArg(OPT_l);
918+
ExcludePageZero = Args.hasArg(OPT_exclude_pagezero);
917919
TotalSizes = Args.hasArg(OPT_totals);
918920
StringRef V = Args.getLastArgValue(OPT_format_EQ, "berkeley");
919921
if (V == "berkeley")

0 commit comments

Comments
 (0)