Message ID | 20220108183838.1920397-1-hjl.tools@gmail.com |
---|---|
Headers | show |
Series | ld: Implement DT_RELR for x86 | expand |
On 2022-01-08, H.J. Lu via Binutils wrote: >Hi Nick, > >I'd like to enable DT_RELR for x86 in binutils 2.38. > > >H.J. >--- >Changes in v2: > >1. Drop the _bfd_elf_link_iterate_on_relocs patch, which has been checked >into master branch. >2. Also pack R_*_RELATIVE relocations against dynamic symbols. >3. Skip relocation against IFUNC symbol earlier. >4. Don't require the --relax option enabled. >5. Add more DT_RELR tests: > a. Add a test with relative relocation in section with 1-byte > alignment. > b. Add a test with -z pack-relative-relocs --no-relax. > c. Add tests for packing R_*_RELATIVE relocations against dynamic > symbols. > >DT_RELR encodes consecutive R_*_RELATIVE relocations in GOT (the global >offset table) and data sections in a compact format: > >https://groups.google.com/g/generic-abi/c/bX460iggiKg > >On some targets, R_*_RELATIVE relocations are counted and the GOT offsets >are allocated when setting the dynamic section sizes after seeing all >relocations. R_*_RELATIVE relocations are generated while relocating >sections after section layout has been finalized. > >For x86 targets, the old check_relocs is renamed to scan_relocs and a >new check_relocs is added to chek input sections and create dynamic >relocation sections so that they will be mapped to output sections. >scan_relocs is now called from elf_backend_always_size_sections. > >On some targets, the DT_RELR section size can be computed only after all >symbols addresses can be determined: > >1. Update ldelf_map_segments to pass need_layout to >_bfd_elf_map_sections_to_segments which will size DT_RELR section and >set need_layout to true if the DT_RELR section size is changed. >2. Set the preliminary DT_RELR section size before mapping sections to >segments and set the final DT_RELR section size after regular symbol >processing is done. > >On x86, DT_RELR is implemented with linker relaxation: > >1. During linker relaxation, we scan input relocations with the same >logic in relocate_section to determine if a relative relocation should >be generated and save the relative relocation candidate information for >sizing the DT_RELR section later after all symbols addresses can be >determined. For these relative relocations which can't be placed in >the DT_RELR section, they will be placed in the rela.dyn/rel.dyn >section. >2. When DT_RELR is enabled, _bfd_elf_map_sections_to_segments calls a >backend function to size the DT_RELR section which will compute the >DT_RELR section size and tell ldelf_map_segments to layout sections >again when the DT_RELR section size has been increased. >3. After regular symbol processing is finished, bfd_elf_final_link calls >a backend function to finish the DT_RELR section. > >When DT_RELR is enabled, to avoid random run-time crash with older glibc >binaries without DT_RELR support, add a GLIBC_ABI_DT_RELR symbol version, >which is provided by glibc with DT_RELR support, dependency on the shared >C library if it provides a GLIBC_2.XX symbol version. > >It can build DT_RELR enabled glibc successfully on x86-64, x32 and >i686. > >H.J. Lu (9): > elf: Add .relr.dyn to special_sections_r > elf: Extract _bfd_elf_process_reverse_copy > elf: Pass need_layout to _bfd_elf_map_sections_to_segments > ld: Initial DT_RELR support > elf: Add size_relative_relocs and finish_relative_relocs > elf: Support DT_RELR in linker tests > x86: Add DT_RELR support > ld: Add simple DT_RELR tests > ld: Add glibc dependency for DT_RELR Thank you so much for the heroic work. I cannot think of other items. When linking clang, there is no longer RELA R_X86_64_RELATIVE. Nice! clang -fsanitize=memory built ld passed. gcc -fsanitize=address built ld passed (ld has pre-existing leaks. This patch series does not add more leaks.) Reviewed-by: Fangrui Song <i@maskray.me> (perhaps binutils doesn't use this...)
On Sat, 8 Jan 2022, Fangrui Song wrote: > Thank you so much for the heroic work. > I cannot think of other items. I am bummed that Rich Felker's solution for compatibility (sane diagnostic for loading a new PIE/DSO with old ld.so) was not accepted: https://sourceware.org/pipermail/libc-alpha/2021-November/133313.html (add just one new relocation to indicate presence of SHT_RELR) It would have been a nice solution that works the same across all OS'es, without requiring changes in ld.so. Was there something wrong with it? Alexander
Hi H.J. The patch set looks good to me, but there is one problem. With the set applied there is a new linker testsuite regression for non x86 ELF based targets (eg: s390-linux, xtensa-elf, aarch64-linux-gnu to mention just a few): Executing on host: sh -c {./ld-new -o tmpdir/symbolic-func.so -z norelro -L/ld/testsuite/ld-elf -shared -Bsymbolic-functions -z nopack-relative-relocs tmpdir/symbolic-func.o 2>&1} /dev/null ld.tmp (timeout = 300) spawn [open ...] ./ld-new: warning: -z nopack-relative-relocs ignored ./ld-new: warning: -z nopack-relative-relocs ignored FAIL: -Bsymbolic-functions Please could you investigate and fix this issue ? Cheers Nick
On Tue, Jan 11, 2022 at 2:13 AM Nick Clifton <nickc@redhat.com> wrote: > > Hi H.J. > > The patch set looks good to me, but there is one problem. With the > set applied there is a new linker testsuite regression for non x86 > ELF based targets (eg: s390-linux, xtensa-elf, aarch64-linux-gnu to > mention just a few): > > Executing on host: sh -c {./ld-new -o tmpdir/symbolic-func.so > -z norelro -L/ld/testsuite/ld-elf -shared -Bsymbolic-functions > -z nopack-relative-relocs tmpdir/symbolic-func.o 2>&1} > /dev/null ld.tmp (timeout = 300) > spawn [open ...] > > ./ld-new: warning: -z nopack-relative-relocs ignored > ./ld-new: warning: -z nopack-relative-relocs ignored > FAIL: -Bsymbolic-functions > > Please could you investigate and fix this issue ? > Fixed in the v3 patch: https://sourceware.org/pipermail/binutils/2022-January/119292.html by Changes in v3: 1. Set DT_RELR_LDFLAGS, DT_RELR_CC_LDFLAGS, NO_DT_RELR_LDFLAGS and NO_DT_RELR_CC_LDFLAGS to empty for non-Linux/x86 targets. 2. Run x86 DT_RELR tests only for Linux/x86 targets. Thanks.
Hi H.J. > Fixed in the v3 patch: > > https://sourceware.org/pipermail/binutils/2022-January/119292.html > > by > > Changes in v3: > > 1. Set DT_RELR_LDFLAGS, DT_RELR_CC_LDFLAGS, NO_DT_RELR_LDFLAGS and > NO_DT_RELR_CC_LDFLAGS to empty for non-Linux/x86 targets. > 2. Run x86 DT_RELR tests only for Linux/x86 targets. Patch series approved - please apply. Cheers Nick
On 2022-01-09, Alexander Monakov wrote: >On Sat, 8 Jan 2022, Fangrui Song wrote: > >> Thank you so much for the heroic work. >> I cannot think of other items. > >I am bummed that Rich Felker's solution for compatibility (sane diagnostic >for loading a new PIE/DSO with old ld.so) was not accepted: >https://sourceware.org/pipermail/libc-alpha/2021-November/133313.html > >(add just one new relocation to indicate presence of SHT_RELR) > >It would have been a nice solution that works the same across all OS'es, >without requiring changes in ld.so. Was there something wrong with it? > >Alexander Hi Alexander, I think the .gnu.version_r approach is better. For FreeBSD/musl/etc, there is no version node called GLIBC_2*, ld.bfd -z pack-relative-relocs will not add anything. For a relocation approach, every psABI needs to define which relocation type is used as the available indicator (something like R_*_GNU_VTENTRY). It's too much work for something only glibc needs. Now that the ld patch series has landed on https://sourceware.org/git/?p=binutils-gdb.git, what's the next step for the glibc patch? The current diff I have is https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/relr I think making ld.so/libc.so themselves compatible with DT_RELR can be separate changes (I personally do not know enough ld.so to contribute it...)
On Wed, Jan 12, 2022 at 6:54 PM Fangrui Song <i@maskray.me> wrote: > > On 2022-01-09, Alexander Monakov wrote: > >On Sat, 8 Jan 2022, Fangrui Song wrote: > > > >> Thank you so much for the heroic work. > >> I cannot think of other items. > > > >I am bummed that Rich Felker's solution for compatibility (sane diagnostic > >for loading a new PIE/DSO with old ld.so) was not accepted: > >https://sourceware.org/pipermail/libc-alpha/2021-November/133313.html > > > >(add just one new relocation to indicate presence of SHT_RELR) > > > >It would have been a nice solution that works the same across all OS'es, > >without requiring changes in ld.so. Was there something wrong with it? > > > >Alexander > > Hi Alexander, I think the .gnu.version_r approach is better. > For FreeBSD/musl/etc, there is no version node called GLIBC_2*, > ld.bfd -z pack-relative-relocs will not add anything. > > For a relocation approach, every psABI needs to define which relocation > type is used as the available indicator (something like > R_*_GNU_VTENTRY). It's too much work for something only glibc needs. > > > > Now that the ld patch series has landed on > https://sourceware.org/git/?p=binutils-gdb.git, what's the next step for the > glibc patch? The current diff I have is > https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/relr > I think making ld.so/libc.so themselves compatible with DT_RELR can > be separate changes (I personally do not know enough ld.so to contribute > it...) It is too late for glibc 2.35. It should go in after 2.35 is branched. My DT_RELR branch is based on your patch: https://gitlab.com/x86-glibc/glibc/-/commits/users/hjl/relr/master My branch requires -z pack-relative-relocs to enable DT_RELR and supports zero DT_RELA/DT_REL values generated by ld.