A binary got bigger for no obvious reason, and GNU size tells you whether the bloat sits in code, data, or uninitialised storage. You will read section sizes, compare several files, and inspect an archive without changing any input. Allow about ten minutes. You need a shell, GNU Binutils, and a readable ELF executable or object file; no elevated privileges are normally needed.
Tip: By the end, you should know which output format you used and what its total actually includes: that matters more than the raw numbers.
This machine has GNU Binutils 2.42 in the installed binutils-common, binutils-aarch64-linux-gnu and binutils-x86-64-linux-gnu packages. The command found first in this shell is GNU Binutils 2.47.20260726, so record your own path and version before comparing numbers with another host.
$ command -v size
/home/linuxbrew/.linuxbrew/bin/size
$ size --version | head -n 2
GNU size (GNU Binutils) 2.47.20260726
Copyright (C) 2026 Free Software Foundation, Inc.
The architecture-prefixed aliases, such as aarch64-linux-gnu-size and x86_64-linux-gnu-size, use the same documented interface. Prefer the alias that matches the target toolchain when you need to make that choice explicit.
Give size one or more object files. The default is a one-line Berkeley-style report, with columns in bytes: text for code and read-only data as counted by this format, data for initialised writable data, and bss for zero-initialised storage. dec and hex are the sum of those three columns.
$ size /bin/true
text data bss dec hex filename
18383 900 16 19299 4b63 /bin/true
The exact numbers depend on the binary and build. This command only reads the file: it does not measure the executable's on-disk file length, memory mapping, shared-library footprint or peak runtime memory.
Checkpoint: Confirm that dec equals text + data + bss. If you need file length, use a separate command such as stat; do not treat dec as a disk-usage figure.
GNU size supports Berkeley, GNU and System V layouts, and the difference is more than presentation. Berkeley places read-only data in text; GNU places it in data and calls the sum total. Use one format consistently in a report.
$ size --format=gnu /bin/true
text data bss total filename
11946 7337 16 19299 /bin/true
$ size --format=sysv /bin/true | sed -n '1,8p'
/bin/true :
section size addr
.interp 28 792
.note.gnu.property 48 824
.note.gnu.build-id 36 872
.note.ABI-tag 32 908
.gnu.hash 36 944
.dynsym 1104 984
The short forms are -B for Berkeley, -G for GNU and -A for System V; the long forms are easier to audit in scripts. System V output lists individual sections and addresses, while Berkeley and GNU output are compact summaries.
Use --radix=10, --radix=8 or --radix=16, also available as -d, -o and -x. Only 8, 10 and 16 are accepted. With decimal or hexadecimal section output, the total stays available in decimal and hexadecimal; octal output uses octal and hexadecimal totals.
$ size --radix=16 /bin/true
text data bss dec hex filename
0x47cf 0x384 0x10 19299 4b63 /bin/true
Do not compare a hexadecimal section column with a decimal one by eye. Keep the selected radix in the command or report heading, and convert values when doing arithmetic outside the tool.
List several files to get one row per file. Add --totals when you also need their combined section totals; this applies to Berkeley and GNU output modes, not to the System V section listing.
$ size --totals /bin/true /bin/false
text data bss dec hex filename
18383 900 16 19299 4b63 /bin/true
18383 900 16 19299 4b63 /bin/false
36766 1800 32 38598 96c6 (TOTALS)
Totals are a report over the files you named, not a prediction of the memory used when they run together. Shared libraries, loader behaviour and runtime allocations sit outside this calculation.
If the input is an archive, size reports each module in it, which is handy for spotting a large object before linking. The archive members below are copied from system binaries only to make a disposable test archive; this does not modify /bin/true or /bin/false.
$ workdir=$(mktemp -d /tmp/size-example.XXXXXX)
$ cp /bin/true "$workdir/true.o"
$ cp /bin/false "$workdir/false.o"
$ ar rcs "$workdir/sample.a" "$workdir/true.o" "$workdir/false.o"
$ size "$workdir/sample.a"
text data bss dec hex filename
18383 900 16 19299 4b63 true.o (ex /tmp/size-example.XXXXXX/sample.a)
18383 900 16 19299 4b63 false.o (ex /tmp/size-example.XXXXXX/sample.a)
The random directory suffix in the displayed archive path will differ. When finished, remove only the disposable directory you created, for example with rm -rf -- "$workdir". Check the variable first: a mistaken destructive command can remove more than the test files. No sudo is needed for this example.
size falls back to a.out, which often produces a confusing error on a modern project. Name the file explicitly.--target=BFDNAME can force a BFD object format, but guessing a target can produce misleading results.--common reports their total size; in Berkeley and GNU formats it is already included in the bss value. Use it when common symbols matter to your build comparison.-f is accepted but ignored by GNU Binutils. Do not add it assuming it changes the report.@file arguments are expanded recursively. Treat them as executable configuration: inspect their contents before use, especially in automated builds.If a report looks wrong, first run command -v size, size --version and file /path/to/binary. Compare the tool path, version, target format and selected output mode before comparing numbers. Reading a binary needs no elevated privilege; only use an administrator account if ordinary file permissions genuinely require it.
size executable and version.dec is the section sum.