[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug gas/31567] New: gas/ld: Implicit addends for non-code sections
From: |
i at maskray dot me |
Subject: |
[Bug gas/31567] New: gas/ld: Implicit addends for non-code sections |
Date: |
Thu, 28 Mar 2024 07:00:19 +0000 |
https://sourceware.org/bugzilla/show_bug.cgi?id=31567
Bug ID: 31567
Summary: gas/ld: Implicit addends for non-code sections
Product: binutils
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: gas
Assignee: unassigned at sourceware dot org
Reporter: i at maskray dot me
Target Milestone: ---
ELF defines two relocation formats, REL and RELA. REL uses implicit addends,
saving space compared to RELA's explicit addend field.
However, REL is often inadequate for static code relocations because the
instruction to be modified (commonly 4 bytes on RISC architectures) limits the
available space for the addend.
GNU assembler generates RELA static relocations for most ports and generates
REL for very few ones (AArch32, BPF, M32R, MIPS o32).
However, using RELA can be unnecessarily bulky for data and debug sections
where the constraints on addend size don't apply.
I propose that we add an assembler option `-Wa,--implicit-addends-for-data` to
allow non-code sections to use implicit addends to save space.
In a clang -O0 -g -gpubnames build, using REL for non-code sections (sections
without the SHF_EXECINSTR flag) decreased relocation size by 27.1% and the .o
file size by 6.4%.
Using CREL (`clang -Wa,--crel,--implicit-addends-for-data`) decreased the .o
file size by 21.6%!
```
|reloc size | .o size
---------+-----------+------------
RELA | 550519056 | 2339938120
REL data | 401209104 | 2190607000 -Wa,--implicit-addends-for-data
CREL | 44865612 | 1834284744 -Wa,--crel,--implicit-addends-for-data
```
```
# https://github.com/MaskRay/llvm-project/tree/demo-crel
clang -fuse-ld=lld -Wa,--implicit-addends-for-data a.c -o a
```
The saving is less pronounced in a non-debug -O3 build (2.3% .o file size) due
to relatively fewer data relocations.
```
|reloc size | .o size
---------+-----------+-----------
RELA | 28235664 | 136014800
REL data | 25081480 | 132847952
CREL | 3812677 | 111591872 -Wa,--implicit-addends-for-data
CREL | 3482387 | 111261704 -Wa,--crel,--implicit-addends-for-data
```
---
Technically, data sections can have static code relocations because assemblers
don't reject `.data; call foo`.
Since we are adding an opt-in assembler option, we can rely on the user to do
the right thing and only use data directives.
For a custom section, `sec->use_rela_p` is at a location matching the following
stack trace.
```
perform_an_assembly_pass
read_a_source_file
obj_elf_section
change_section
subseg_force_new
subseg_get
bfd_make_section_anyway
bfd_make_section_anyway_with_flags
bfd_section_init
_bfd_elf_new_section_hook
```
_bfd_elf_new_section_hook sets `sec->use_rela_p = bed->default_use_rela_p;`
---
The GNU ld support for REL data relocations seems good, but .eh_frame needs to
be fixed.
```
# clang is patched with my user branch mentioned by
https://maskray.me/blog/2024-03-09-a-compact-relocation-format-for-elf#relleb-for-dynamic-relocations
% fclang -Wa,--implicit-addends-for-data a.c b.c -fuse-ld=bfd -o a
/usr/bin/ld.bfd: .eh_frame_hdr refers to overlapping FDEs
/usr/bin/ld.bfd: final link failed: bad value
clang: error: linker command failed with exit code 1 (use -v to see invocation)
% fclang -Wa,--implicit-addends-for-data a.c b.c -fuse-ld=bfd -o a
-fno-asynchronous-unwind-tables
% ./a
hello
h
0x5633b227e020 0x5633b227e028
% fclang -Wa,--implicit-addends-for-data a.c b.c -fuse-ld=bfd -o a
-fno-asynchronous-unwind-tables -static --target=aarch64-linux-gnu
% ./a
hello
h
0x490050 0x490058
```
--
You are receiving this mail because:
You are on the CC list for the bug.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Bug gas/31567] New: gas/ld: Implicit addends for non-code sections,
i at maskray dot me <=