You compile a small ELF object, measure its text, data and bss sections with llvm-size-18, and compare the Berkeley and SysV views of the same file. Allow about ten minutes if LLVM 18 is already installed. The commands only create files under /tmp; they do not change a service or install anything.
This guide uses Ubuntu's llvm-18 package. On the machine used for these examples, llvm-size-18 --version reports LLVM 18.1.3 and the executable is /usr/bin/llvm-size-18. The local manual page is for llvm-size 18 and lists the options covered here.
$ command -v llvm-size-18
/usr/bin/llvm-size-18
$ llvm-size-18 --version
llvm-size-18
Ubuntu LLVM version 18.1.3
Optimized build.
You also need a C compiler for the reproducible object-file example. Check it without elevating privileges:
$ command -v cc
/usr/bin/cc
If your package uses a different executable name, substitute it in the compile step. Do not use sudo for measuring a readable object file: root access does not make an invalid object valid, and it can make it easier to write unwanted files in the wrong directory.
Put the source and object in /tmp so the experiment stays separate from a project checkout. The initialised global contributes to data, while the uninitialised static contributes to bss:
$ printf '%s\n' \
'int global_data = 42;' \
'static int local_bss;' \
'int main(void) { return global_data + local_bss; }' \
> /tmp/llvm-size-demo.c
$ cc -c /tmp/llvm-size-demo.c -o /tmp/llvm-size-demo.o
$ file /tmp/llvm-size-demo.o
/tmp/llvm-size-demo.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), ...
Checkpoint: the architecture wording from file varies by host, but it should say ELF and relocatable. If the file is missing, stop and check the compiler error before running the size command.
Pass one or more object files as operands:
$ llvm-size-18 /tmp/llvm-size-demo.o
text data bss dec hex filename
112 4 4 120 78 /tmp/llvm-size-demo.o
In this installed build, the default is the compact Berkeley layout.
text, data and bss are decimal section sizes.dec is their decimal total.hex is that same total in hexadecimal.None of those columns total every section in the object, such as comments or unwind metadata. Use the exit status as a quick scriptable check:
$ llvm-size-18 /tmp/llvm-size-demo.o > /tmp/llvm-size-report.txt
$ test $? -eq 0 && test -s /tmp/llvm-size-report.txt && echo "size report written"
size report written
Redirection creates or truncates the report. Choose a new path if an existing report matters, or copy it first. The object file itself is read, not modified.
Use the long option when section-level detail matters:
$ llvm-size-18 --format=sysv /tmp/llvm-size-demo.o
/tmp/llvm-size-demo.o :
section size addr
.text 24 0
.data 4 0
.bss 4 0
.comment 46 0
.note.GNU-stack 0 0
.note.gnu.property 32 0
.eh_frame 56 0
Total 166
SysV output lists sections and their addresses, then a per-file total. That total includes sections which Berkeley leaves out of its text, data and bss summary, so do not compare 166 against Berkeley's 120 as though they were two spellings of the same number. Relocatable objects commonly show zero section addresses; that is not evidence the section has no size.
The format names accepted by this installed command are berkeley, sysv and darwin. The Darwin view is for Mach-O input and is not a useful choice for this ELF object. An invalid value produces an error and a non-zero exit status:
$ llvm-size-18 --format=SysV /tmp/llvm-size-demo.o
llvm-size-18: error: --format value should be one of: 'berkeley', 'darwin', 'sysv'
$ printf 'exit status: %s\n' "$?"
exit status: 1
The default radix is decimal for the size columns. Select octal, decimal or hexadecimal explicitly with --radix=8, --radix=10 or --radix=16. The short forms are -o, -d and -x:
$ llvm-size-18 --format=berkeley --radix=16 /tmp/llvm-size-demo.o
text data bss dec hex filename
0x70 0x4 0x4 120 78 /tmp/llvm-size-demo.o
Only the section-size columns change base here. The total columns stay labelled dec and hex, giving you both forms for the combined Berkeley total. If a script consumes this output, pick one format and radix rather than relying on the display default.
Berkeley format can list multiple inputs. Add --totals, or its short form -t, when you want an extra aggregate row:
$ cp /tmp/llvm-size-demo.o /tmp/llvm-size-demo-copy.o
$ llvm-size-18 --format=berkeley --radix=10 --totals \
/tmp/llvm-size-demo.o /tmp/llvm-size-demo-copy.o
text data bss dec hex filename
112 4 4 120 78 /tmp/llvm-size-demo.o
112 4 4 120 78 /tmp/llvm-size-demo-copy.o
224 8 8 240 f0 (TOTALS)
--totals applies to Berkeley format only. It is not a request to total the individual section rows SysV prints. The copied object is only a convenient second input for the test; it is not a meaningful build comparison.
For a real build, point the command at the exact object or executable you want to compare. Run it after the build has finished, and save a report under a deliberate output path:
$ llvm-size-18 --format=berkeley --radix=10 \
/path/to/build/app.o \
> /path/to/reports/app-size.txt
$ test -s /path/to/reports/app-size.txt && sed -n '1,3p' /path/to/reports/app-size.txt
Warning: shell redirection does not create missing parent directories and will truncate an existing report. To preserve an old report, use a new filename such as app-size-$(date +%Y%m%d-%H%M%S).txt, or make an explicit backup before redirecting. If the command fails, inspect the diagnostic and exit status; do not treat a partially written report as a valid measurement.
Recovery: keep the input file in place until the report has been checked. If you created the temporary demonstration files, they can be removed later with rm -- /tmp/llvm-size-demo.c /tmp/llvm-size-demo.o /tmp/llvm-size-demo-copy.o /tmp/llvm-size-report.txt. That deletion is irreversible, so do it only once you no longer need the example or its report.
llvm-size-18 --version identified the installed LLVM 18.1.3 tool.--totals only with Berkeley output and checked the command status.