Measure ELF Object Sections with llvm-size-18

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.

Before you start

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.

1. Create a harmless ELF object

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.

2. Read the default Berkeley summary

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.

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.

3. Inspect every section with SysV format

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

4. Change the numeric base

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.

5. Compare several objects and request totals

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.

6. Use the result without damaging a build

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.

Done means