From 568cbddc710f6cb6be752f390a1521cd5556ad9b Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Sun, 29 Nov 2020 06:00:37 -0800 Subject: [PATCH] gold: Convert x86-64 GOTPCRELX only if addend == -4 Convert x86-64 GOTPCRELX relocations only if addend == -4. PR gold/26939 * x86_64.cc (Target_x86_64::Scan::local): Check get_r_addend() == -4 for GOTPCRELX conversion. (Target_x86_64::Scan::global): Likewise. (Target_x86_64::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/ChangeLog | 21 +++++ 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 ++++++++++++++++------------ 6 files changed, 135 insertions(+), 52 deletions(-) create mode 100644 gold/testsuite/x86_64_mov_to_lea5.s diff --git a/gold/ChangeLog b/gold/ChangeLog index 1e90cbdda63..53bb030821c 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,24 @@ +2020-11-29 H.J. Lu + + PR gold/26939 + * x86_64.cc (Target_x86_64::Scan::local): Check + get_r_addend() == -4 for GOTPCRELX conversion. + (Target_x86_64::Scan::global): Likewise. + (Target_x86_64::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. + 2020-11-29 H.J. Lu PR gold/26937 diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index ae962a817e8..3ba2a30ed85 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 695eeb1f337..cad5af6bf57 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -314,6 +314,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 \ @@ -336,6 +338,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 \ @@ -8356,6 +8360,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 @@ -8384,6 +8392,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 @@ -8412,6 +8424,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 ad59ac05021..4e5c1434bf6 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 00000000000..e793a2b9b73 --- /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 378bac16f78..ddf4722160b 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -3730,6 +3730,7 @@ Target_x86_64::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) { @@ -4200,6 +4201,7 @@ Target_x86_64::Scan::global(Symbol_table* symtab, Lazy_view 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::can_convert_mov_to_lea(gsym, r_type, r_offset, &view)) @@ -4890,63 +4892,78 @@ Target_x86_64::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::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::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::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::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.30.2