bug-binutils
[Top][All Lists]
Advanced

[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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]