[PATCH] gold: Convert x86-64 GOTPCRELX only if addend == -4
H.J. Lu
hjl.tools@gmail.com
Thu Nov 26 14:16:04 GMT 2020
On Tue, Nov 24, 2020 at 2:37 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> Convert x86-64 GOTPCRELX relocations only if addend == -4.
>
> PR gold/26939
> * x86_64.cc (Target_x86_64<size>::Scan::local): Check
> get_r_addend() == -4 for GOTPCRELX conversion.
> (Target_x86_64<size>::Scan::global): Likewise.
> (Target_x86_64<size>::Relocate::relocate): Likewise.
> * testsuite/Makefile.am (check_DATA): Add
> x86_64_mov_to_lea15.stdout and x86_64_mov_to_lea16.stdout.
> (MOSTLYCLEANFILES): Add x86_64_mov_to_lea15 and
> x86_64_mov_to_lea16.
> (x86_64_mov_to_lea9.o): New target.
> (x86_64_mov_to_lea10.o): Likewise.
> (x86_64_mov_to_lea15): Likewise.
> (x86_64_mov_to_lea16): Likewise.
> (x86_64_mov_to_lea15.stdout): Likewise.
> (x86_64_mov_to_lea16.stdout): Likewise.
> * testsuite/Makefile.in: Regenerated.
> * testsuite/x86_64_mov_to_lea.sh: Updated.
> * testsuite/x86_64_mov_to_lea5.s: New file.
> ---
> gold/testsuite/Makefile.am | 19 ++++-
> gold/testsuite/Makefile.in | 16 ++++
> gold/testsuite/x86_64_mov_to_lea.sh | 2 +
> gold/testsuite/x86_64_mov_to_lea5.s | 12 +++
> gold/x86_64.cc | 117 ++++++++++++++++------------
> 5 files changed, 114 insertions(+), 52 deletions(-)
> create mode 100644 gold/testsuite/x86_64_mov_to_lea5.s
>
> diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
> index db5212d358..9bc7f02970 100644
> --- a/gold/testsuite/Makefile.am
> +++ b/gold/testsuite/Makefile.am
> @@ -1119,12 +1119,15 @@ check_DATA += x86_64_mov_to_lea1.stdout x86_64_mov_to_lea2.stdout \
> x86_64_mov_to_lea7.stdout x86_64_mov_to_lea8.stdout \
> x86_64_mov_to_lea9.stdout x86_64_mov_to_lea10.stdout \
> x86_64_mov_to_lea11.stdout x86_64_mov_to_lea12.stdout \
> - x86_64_mov_to_lea13.stdout x86_64_mov_to_lea14.stdout
> + x86_64_mov_to_lea13.stdout x86_64_mov_to_lea14.stdout \
> + x86_64_mov_to_lea15.stdout x86_64_mov_to_lea16.stdout
> +
> MOSTLYCLEANFILES += x86_64_mov_to_lea1 x86_64_mov_to_lea2 \
> x86_64_mov_to_lea3 x86_64_mov_to_lea4 x86_64_mov_to_lea5 \
> x86_64_mov_to_lea6 x86_64_mov_to_lea7 x86_64_mov_to_lea8 \
> x86_64_mov_to_lea9 x86_64_mov_to_lea10 x86_64_mov_to_lea11 \
> - x86_64_mov_to_lea12 x86_64_mov_to_lea13 x86_64_mov_to_lea14
> + x86_64_mov_to_lea12 x86_64_mov_to_lea13 x86_64_mov_to_lea14 \
> + x86_64_mov_to_lea15 x86_64_mov_to_lea16
>
> x86_64_mov_to_lea1.o: x86_64_mov_to_lea1.s
> $(TEST_AS) --64 -o $@ $<
> @@ -1142,6 +1145,10 @@ x86_64_mov_to_lea7.o: x86_64_mov_to_lea4.s
> $(TEST_AS) --x32 -o $@ $<
> x86_64_mov_to_lea8.o: x86_64_mov_to_lea4.s
> $(TEST_AS) --64 -o $@ $<
> +x86_64_mov_to_lea9.o: x86_64_mov_to_lea5.s
> + $(TEST_AS) --x32 -mrelax-relocations=yes -o $@ $<
> +x86_64_mov_to_lea10.o: x86_64_mov_to_lea5.s
> + $(TEST_AS) --64 -mrelax-relocations=yes -o $@ $<
> x86_64_mov_to_lea1: x86_64_mov_to_lea1.o ../ld-new
> ../ld-new -Bsymbolic -shared -melf_x86_64 -o $@ $<
> x86_64_mov_to_lea2: x86_64_mov_to_lea1.o ../ld-new
> @@ -1170,6 +1177,10 @@ x86_64_mov_to_lea13: x86_64_mov_to_lea7.o ../ld-new
> ../ld-new -melf32_x86_64 -shared -o $@ $<
> x86_64_mov_to_lea14: x86_64_mov_to_lea8.o ../ld-new
> ../ld-new -melf_x86_64 -shared -o $@ $<
> +x86_64_mov_to_lea15: x86_64_mov_to_lea9.o ../ld-new
> + ../ld-new -melf32_x86_64 -shared -o $@ $<
> +x86_64_mov_to_lea16: x86_64_mov_to_lea10.o ../ld-new
> + ../ld-new -melf_x86_64 -shared -o $@ $<
> x86_64_mov_to_lea1.stdout: x86_64_mov_to_lea1
> $(TEST_OBJDUMP) -dw $< > $@
> x86_64_mov_to_lea2.stdout: x86_64_mov_to_lea2
> @@ -1198,6 +1209,10 @@ x86_64_mov_to_lea13.stdout: x86_64_mov_to_lea13
> $(TEST_OBJDUMP) -dw $< > $@
> x86_64_mov_to_lea14.stdout: x86_64_mov_to_lea14
> $(TEST_OBJDUMP) -dw $< > $@
> +x86_64_mov_to_lea15.stdout: x86_64_mov_to_lea15
> + $(TEST_OBJDUMP) -dw $< > $@
> +x86_64_mov_to_lea16.stdout: x86_64_mov_to_lea16
> + $(TEST_OBJDUMP) -dw $< > $@
>
> check_SCRIPTS += x86_64_indirect_call_to_direct.sh
> check_DATA += x86_64_indirect_call_to_direct1.stdout \
> diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
> index 6be1c4e046..8bb97ee4ac 100644
> --- a/gold/testsuite/Makefile.in
> +++ b/gold/testsuite/Makefile.in
> @@ -318,6 +318,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea12.stdout \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea13.stdout \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea14.stdout \
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea15.stdout \
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea16.stdout \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_indirect_call_to_direct1.stdout \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_indirect_jump_to_direct1.stdout \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_gd_to_le.stdout \
> @@ -344,6 +346,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea12 \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea13 \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea14 \
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea15 \
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea16 \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_indirect_call_to_direct1 \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_indirect_jump_to_direct1 \
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_gd_to_le \
> @@ -8387,6 +8391,10 @@ uninstall-am:
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) --x32 -o $@ $<
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea8.o: x86_64_mov_to_lea4.s
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) --64 -o $@ $<
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea9.o: x86_64_mov_to_lea5.s
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) --x32 -mrelax-relocations=yes -o $@ $<
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea10.o: x86_64_mov_to_lea5.s
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) --64 -mrelax-relocations=yes -o $@ $<
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea1: x86_64_mov_to_lea1.o ../ld-new
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ ../ld-new -Bsymbolic -shared -melf_x86_64 -o $@ $<
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea2: x86_64_mov_to_lea1.o ../ld-new
> @@ -8415,6 +8423,10 @@ uninstall-am:
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ ../ld-new -melf32_x86_64 -shared -o $@ $<
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea14: x86_64_mov_to_lea8.o ../ld-new
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ ../ld-new -melf_x86_64 -shared -o $@ $<
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea15: x86_64_mov_to_lea9.o ../ld-new
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ ../ld-new -melf32_x86_64 -shared -o $@ $<
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea16: x86_64_mov_to_lea10.o ../ld-new
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ ../ld-new -melf_x86_64 -shared -o $@ $<
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea1.stdout: x86_64_mov_to_lea1
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -dw $< > $@
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea2.stdout: x86_64_mov_to_lea2
> @@ -8443,6 +8455,10 @@ uninstall-am:
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -dw $< > $@
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea14.stdout: x86_64_mov_to_lea14
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -dw $< > $@
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea15.stdout: x86_64_mov_to_lea15
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -dw $< > $@
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_mov_to_lea16.stdout: x86_64_mov_to_lea16
> +@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -dw $< > $@
>
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@x86_64_indirect_call_to_direct1.o: x86_64_indirect_call_to_direct1.s
> @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) --64 -mrelax-relocations=yes -o $@ $<
> diff --git a/gold/testsuite/x86_64_mov_to_lea.sh b/gold/testsuite/x86_64_mov_to_lea.sh
> index ad59ac0502..4e5c1434bf 100755
> --- a/gold/testsuite/x86_64_mov_to_lea.sh
> +++ b/gold/testsuite/x86_64_mov_to_lea.sh
> @@ -38,5 +38,7 @@ grep -q "mov 0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea11.stdout
> grep -q "mov 0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea12.stdout
> grep -q "lea -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea13.stdout
> grep -q "lea -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea14.stdout
> +grep -q "mov 0x[a-f0-9]\+(%rip),%eax" x86_64_mov_to_lea15.stdout
> +grep -q "mov 0x[a-f0-9]\+(%rip),%eax" x86_64_mov_to_lea16.stdout
>
> exit 0
> diff --git a/gold/testsuite/x86_64_mov_to_lea5.s b/gold/testsuite/x86_64_mov_to_lea5.s
> new file mode 100644
> index 0000000000..e793a2b9b7
> --- /dev/null
> +++ b/gold/testsuite/x86_64_mov_to_lea5.s
> @@ -0,0 +1,12 @@
> + .text
> + .globl foo
> + .hidden foo
> + .type foo, @function
> +foo:
> + ret
> + .size foo, .-foo
> + .globl _start
> + .type _start, @function
> +_start:
> + movl foo@GOTPCREL+4(%rip), %eax
> + .size _start, .-_start
> diff --git a/gold/x86_64.cc b/gold/x86_64.cc
> index 6c3e39c030..ab97cf95e6 100644
> --- a/gold/x86_64.cc
> +++ b/gold/x86_64.cc
> @@ -3737,6 +3737,7 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
> && (r_type == elfcpp::R_X86_64_GOTPCREL
> || r_type == elfcpp::R_X86_64_GOTPCRELX
> || r_type == elfcpp::R_X86_64_REX_GOTPCRELX)
> + && reloc.get_r_addend() == -4
> && reloc.get_r_offset() >= 2
> && !is_ifunc)
> {
> @@ -4207,6 +4208,7 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
> Lazy_view<size> view(object, data_shndx);
> size_t r_offset = reloc.get_r_offset();
> if (!parameters->incremental()
> + && reloc.get_r_addend() == -4
> && r_offset >= 2
> && Target_x86_64<size>::can_convert_mov_to_lea(gsym, r_type,
> r_offset, &view))
> @@ -4897,63 +4899,78 @@ Target_x86_64<size>::Relocate::relocate(
> case elfcpp::R_X86_64_GOTPCRELX:
> case elfcpp::R_X86_64_REX_GOTPCRELX:
> {
> - // Convert
> - // mov foo@GOTPCREL(%rip), %reg
> - // to lea foo(%rip), %reg.
> - // if possible.
> - if (!parameters->incremental()
> - && ((gsym == NULL
> - && rela.get_r_offset() >= 2
> - && view[-2] == 0x8b
> - && !psymval->is_ifunc_symbol())
> - || (gsym != NULL
> - && rela.get_r_offset() >= 2
> - && Target_x86_64<size>::can_convert_mov_to_lea(gsym, r_type,
> - 0, &view))))
> - {
> - view[-2] = 0x8d;
> - Reloc_funcs::pcrela32(view, object, psymval, addend, address);
> - }
> - // Convert
> - // callq *foo@GOTPCRELX(%rip) to
> - // addr32 callq foo
> - // and jmpq *foo@GOTPCRELX(%rip) to
> - // jmpq foo
> - // nop
> - else if (!parameters->incremental()
> - && gsym != NULL
> - && rela.get_r_offset() >= 2
> - && Target_x86_64<size>::can_convert_callq_to_direct(gsym,
> - r_type,
> - 0, &view))
> + bool converted_p = false;
> +
> + if (rela.get_r_addend() == -4)
> {
> - if (view[-1] == 0x15)
> + // Convert
> + // mov foo@GOTPCREL(%rip), %reg
> + // to lea foo(%rip), %reg.
> + // if possible.
> + if (!parameters->incremental()
> + && ((gsym == NULL
> + && rela.get_r_offset() >= 2
> + && view[-2] == 0x8b
> + && !psymval->is_ifunc_symbol())
> + || (gsym != NULL
> + && rela.get_r_offset() >= 2
> + && Target_x86_64<size>::can_convert_mov_to_lea(gsym,
> + r_type,
> + 0,
> + &view))))
> {
> - // Convert callq *foo@GOTPCRELX(%rip) to addr32 callq.
> - // Opcode of addr32 is 0x67 and opcode of direct callq is 0xe8.
> - view[-2] = 0x67;
> - view[-1] = 0xe8;
> - // Convert GOTPCRELX to 32-bit pc relative reloc.
> + view[-2] = 0x8d;
> Reloc_funcs::pcrela32(view, object, psymval, addend, address);
> + converted_p = true;
> }
> - else
> + // Convert
> + // callq *foo@GOTPCRELX(%rip) to
> + // addr32 callq foo
> + // and jmpq *foo@GOTPCRELX(%rip) to
> + // jmpq foo
> + // nop
> + else if (!parameters->incremental()
> + && gsym != NULL
> + && rela.get_r_offset() >= 2
> + && Target_x86_64<size>::can_convert_callq_to_direct(gsym,
> + r_type,
> + 0,
> + &view))
> {
> - // Convert jmpq *foo@GOTPCRELX(%rip) to
> - // jmpq foo
> - // nop
> - // The opcode of direct jmpq is 0xe9.
> - view[-2] = 0xe9;
> - // The opcode of nop is 0x90.
> - view[3] = 0x90;
> - // Convert GOTPCRELX to 32-bit pc relative reloc. jmpq is rip
> - // relative and since the instruction following the jmpq is now
> - // the nop, offset the address by 1 byte. The start of the
> - // relocation also moves ahead by 1 byte.
> - Reloc_funcs::pcrela32(&view[-1], object, psymval, addend,
> - address - 1);
> + if (view[-1] == 0x15)
> + {
> + // Convert callq *foo@GOTPCRELX(%rip) to addr32 callq.
> + // Opcode of addr32 is 0x67 and opcode of direct callq
> + // is 0xe8.
> + view[-2] = 0x67;
> + view[-1] = 0xe8;
> + // Convert GOTPCRELX to 32-bit pc relative reloc.
> + Reloc_funcs::pcrela32(view, object, psymval, addend,
> + address);
> + converted_p = true;
> + }
> + else
> + {
> + // Convert jmpq *foo@GOTPCRELX(%rip) to
> + // jmpq foo
> + // nop
> + // The opcode of direct jmpq is 0xe9.
> + view[-2] = 0xe9;
> + // The opcode of nop is 0x90.
> + view[3] = 0x90;
> + // Convert GOTPCRELX to 32-bit pc relative reloc. jmpq
> + // is rip relative and since the instruction following
> + // the jmpq is now the nop, offset the address by 1
> + // byte. The start of the relocation also moves ahead
> + // by 1 byte.
> + Reloc_funcs::pcrela32(&view[-1], object, psymval, addend,
> + address - 1);
> + converted_p = true;
> + }
> }
> }
> - else
> +
> + if (!converted_p)
> {
> if (gsym != NULL)
> {
> --
> 2.28.0
>
I will check it in next Monday if there are no objections.
--
H.J.
More information about the Binutils
mailing list