Use RELR relative relocations to reduce file sizes (-z pack-relative-relocs) #134

Closed
opened 2022-08-04 23:26:05 +02:00 by BertalanD · 9 comments
Contributor

In binutils 2.38 and the recently released glibc 2.36, support has been added for the DT_RELR relative relocation format. This format can significantly reduce the size of shared libraries and position-independent executables. Measurements show a 5% decrease in size for libraries, and 8% for executables in total.

One particular measurement, taken from MaskRay's Arch feature request (https://bugs.archlinux.org/task/72433):

 % ~/projects/bloaty/Release/bloaty clang.pie.relr -- clang.pie
   FILE SIZE        VM SIZE    
 --------------  -------------- 
  [NEW]  +163Ki  [NEW]  +163Ki    .relr.dyn
  +4.9%     +32  +5.4%     +32    .dynamic
  +2.5%      +8  [ = ]       0    .shstrtab
 -99.5% -13.8Mi -99.5% -13.8Mi    .rela.dyn
  -8.3% -13.6Mi  -8.2% -13.6Mi    TOTAL

This great blog post explains the technical details: https://maskray.me/blog/2021-10-31-relative-relocations-and-relr. It highlights that RELR been used (with patched binutils+libc) in ChromeOS/Android for a long time without any issues. User applications don't need to adapt to the new format.

To enable RELR, the -z pack-relative-relocs flag must be passed to GNU ld. With LLD/mold, the --pack-dyn-relocs=relr spelling should be used instead.

In binutils 2.38 and the recently released glibc 2.36, support has been added for the `DT_RELR` relative relocation format. This format can significantly reduce the size of shared libraries and position-independent executables. Measurements show a 5% decrease in size for libraries, and 8% for executables in total. One particular measurement, taken from MaskRay's Arch feature request (https://bugs.archlinux.org/task/72433): > ``` > % ~/projects/bloaty/Release/bloaty clang.pie.relr -- clang.pie > FILE SIZE VM SIZE > -------------- -------------- > [NEW] +163Ki [NEW] +163Ki .relr.dyn > +4.9% +32 +5.4% +32 .dynamic > +2.5% +8 [ = ] 0 .shstrtab > -99.5% -13.8Mi -99.5% -13.8Mi .rela.dyn > -8.3% -13.6Mi -8.2% -13.6Mi TOTAL > ``` This great blog post explains the technical details: https://maskray.me/blog/2021-10-31-relative-relocations-and-relr. It highlights that RELR been used (with patched binutils+libc) in ChromeOS/Android for a long time without any issues. User applications don't need to adapt to the new format. To enable RELR, the `-z pack-relative-relocs` flag must be passed to GNU ld. With LLD/mold, the `--pack-dyn-relocs=relr` spelling should be used instead.
Owner

Sounds interesting. As far as I understand, ALHP would need to detect the compiler/linker used, so that the correct flags are added? If so, this is probably blocked by #124.

Sounds interesting. As far as I understand, ALHP would need to detect the compiler/linker used, so that the correct flags are added? If so, this is probably blocked by #124.
Author
Contributor

LLD will get support for the GNU argument name in 15.0.0, whose is planned to be released on September 6th. If I remember correctly, mold does not support that spelling as of now; we could open a feature request. The only package that lists mold as its build dependency is cardinal. The only remaining linker is GNU gold, but I hope there aren't any projects depending on it in 2022...

Sidenote: it's a bit infuriating that the binutils maintainers decided to go with a custom spelling instead of the one established by the original implementation in LLD.

Do you have any examples of packages that override the default linker?

LLD will get support for the GNU argument name in 15.0.0, whose is planned to be released on September 6th. If I remember correctly, `mold` does not support that spelling as of now; we could open a feature request. The only package that lists mold as its build dependency is `cardinal`. The only remaining linker is GNU gold, but I hope there aren't any projects depending on it in 2022... Sidenote: it's a bit infuriating that the binutils maintainers decided to go with a custom spelling instead of the one established by the original implementation in LLD. Do you have any examples of packages that override the default linker?
Owner

LLD will get support for the GNU argument name in 15.0.0, whose is planned to be released on September 6th. If I remember correctly, mold does not support that spelling as of now; we could open a feature request. The only package that lists mold as its build dependency is cardinal. The only remaining linker is GNU gold, but I hope there aren't any projects depending on it in 2022...

Gold is most likely not worth talking about, no. So, best case scenario would be to wait until that new LLD release, then add -z pack-relative-relocs, since this should be supported by LLD and ld by then.

Sidenote: it's a bit infuriating that the binutils maintainers decided to go with a custom spelling instead of the one established by the original implementation in LLD.

Do you have any examples of packages that override the default linker?

I quickly grep'd the PKGBUILD tree, and besides already mentioned cardinal, there appear to be none. cardinal, using mold, will most likely fail after adding that above mentioned flag, but adding one more package to the ignore list would not be that detrimental. Maybe we can, as you said, convince the mold devs to also accept the GNU flag.

> LLD will get support for the GNU argument name in 15.0.0, whose is planned to be released on September 6th. If I remember correctly, `mold` does not support that spelling as of now; we could open a feature request. The only package that lists mold as its build dependency is `cardinal`. The only remaining linker is GNU gold, but I hope there aren't any projects depending on it in 2022... Gold is most likely not worth talking about, no. So, best case scenario would be to wait until that new LLD release, then add `-z pack-relative-relocs`, since this should be supported by LLD and ld by then. > > Sidenote: it's a bit infuriating that the binutils maintainers decided to go with a custom spelling instead of the one established by the original implementation in LLD. > > Do you have any examples of packages that override the default linker? I quickly grep'd the PKGBUILD tree, and besides already mentioned `cardinal`, there appear to be none. `cardinal`, using mold, will most likely fail after adding that above mentioned flag, but adding one more package to the ignore list would not be that detrimental. Maybe we can, as you said, convince the mold devs to also accept the GNU flag.
anonfunc added the
enhancement
blocked upstream
labels 2022-08-05 20:10:40 +02:00
Owner

@BertalanD How is the status here? Are we still waiting for upstream? I see some of the versions you mentioned are already released now.

@BertalanD How is the status here? Are we still waiting for upstream? I see some of the versions you mentioned are already released now.
Author
Contributor

It looks like we should be good to go.

  • Mold supports the GNU-style -z pack-relative-relocs as of 1.7.0
  • LLVM 15 has shipped a long time ago, it also supports the GNU-style spelling now
  • Relocation support is available in musl since version 1.2.4
  • Support in the GNU BFD linker and glibc was already available when I opened this issue
It looks like we should be good to go. - Mold [supports](https://github.com/rui314/mold/commit/b365d6ba1aade2e99d636892e4a21b8d7988a01c) the GNU-style `-z pack-relative-relocs` as of 1.7.0 - LLVM 15 has shipped a long time ago, it also [supports](https://github.com/llvm/llvm-project/commit/4a8de2832a2a730f63b71bdf1c1b446285ec5b6f) the GNU-style spelling now - Relocation support is [available](https://github.com/bminor/musl/commit/d32dadd60efb9d3b255351a3b532f8e4c3dd0db1) in musl since version 1.2.4 - Support in the GNU BFD linker and glibc was already available when I opened this issue
anonfunc removed the
blocked upstream
label 2023-06-03 14:14:16 +02:00
Owner

Very nice. If I understood correctly -z,pack-relative-relocs has to be added to LDFLAGS?

Very nice. If I understood correctly `-z,pack-relative-relocs` has to be added to `LDFLAGS`?
Author
Contributor

It also needs the -Wl, prefix if the flag is separated by a space from the other linker flags.

It also needs the `-Wl,` prefix if the flag is separated by a space from the other linker flags.
Owner

I'll try to add it without space, but I think I need to adjust the flag parsing logic for LDFLAGS, because of the different separation.

I'll try to add it without space, but I think I need to adjust the flag parsing logic for `LDFLAGS`, because of the different separation.
Owner

I made the necessary changes. Should be active from now on 👍

I made the necessary changes. Should be active from now on 👍
Sign in to join this conversation.
No description provided.