[TOC]
char[]
.REL
, RELA
, APS2
, or
RELR
..rel.dyn
, .rel.plt
,
.rela.dyn
, or .rela.plt
.REL
and RELA
, each relocation is stored using either 2 or 3 words,
based on the architecture.RELR
and APS2
, relative relocations are compressed.
APS2
: Somewhat involved compression which trades off runtime
performance for smaller file size.RELR
: Supported in Android P+. Smaller and simpler than APS2
.
RELR
is used by default on Chrome OS..reloc
sections..reloc
section has a small
overhead as well..rela.dyn
section of more than 14MiB!APS2
] to compress these down to ~300kb.RELR
] would require only 60kb, but is
not yet enabled..relocs
sections that sum to 620KiB..data.rel.ro
, which as
of Oct 2019 is ~6.5MiB on Linux and ~2MiB on Android. .data.rel.ro
is data
that would have been put into .rodata
and mapped read-only if not for the
required relocations. The memory does not get written to after it’s
relocated, so the linker makes it read-only once relocations are applied (but
by that point the damage is done and we have the dirty pages).
mremap
onto shared memory to dedupe after-the-fact.# For ELF files:
third_party/llvm-build/Release+Asserts/bin/llvm-readelf --relocs out/Release/libmonochrome.so
# For PE files:
python tools\win\pe_summarize.py out\Release\chrome.dll
It’s not practical to avoid them altogether, but there are times when you can be smart about them.
For Example:
// The following uses 2 bytes of padding for each smaller string but creates no relocations.
// Total size overhead: 4 * 5 = 20 bytes.
const char kArr[][5] = {"as", "ab", "asdf", "fi"};
// The following requires no string padding, but uses 4 relocatable pointers.
// Total size overhead:
// Linux 64-bit: (8 bytes per pointer + 24 bytes per relocation) * 4 entries + 14 bytes of char = 142 bytes
// Windows 64-bit: (8 bytes per pointer + 2 bytes per relocation) * 4 entries + 14 bytes of char = 54 bytes
// CrOS 64-bit: (8 bytes per pointer + ~0 bytes per relocation) * 4 entries + 14 bytes of char = ~46 bytes
// Android 32-bit: (4 bytes per pointer + ~0 bytes per relocation) * 4 entries + 14 bytes of char = ~30 bytes
const char * const kArr2[] = {"as", "ab", "asdf", "fi"};
Notes:
Here’s a simpler example:
// No pointer, no relocation. Just 5 bytes of character data.
const char kText[] = "asdf";
// Requires pointer, relocation, and character data.
// In most cases there is no advantage to pointers for strings.
const char* const kText = "asdf";
Another thing to look out for: