public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] gold: Handle R_X86_64_CODE_4_GOTPCRELX
@ 2023-12-28 18:02 H.J. Lu
  0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 2023-12-28 18:02 UTC (permalink / raw)
  To: bfd-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4a54cb06585f568031dfd291d0fe45979ad75e98

commit 4a54cb06585f568031dfd291d0fe45979ad75e98
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Jun 8 12:12:48 2023 -0700

    gold: Handle R_X86_64_CODE_4_GOTPCRELX
    
    Handle R_X86_64_CODE_4_GOTPCRELX and convert
    
            mov     name@GOTPCREL(%rip), %r31
    
    to
    
            lea     name@GOTPCREL(%rip), %r31
    
    if the instruction is encoded with the REX2 prefix when possible.
    
    elfcpp/
    
            * x86_64.h (R_X86_64_CODE_4_GOTPCRELX): New.
    
    gold/
    
            * x86_64.cc (Target_x86_64::can_convert_mov_to_lea): Handle
            R_X86_64_CODE_4_GOTPCRELX.
            (Target_x86_64::Scan::get_reference_flags): Likewise.
            (Target_x86_64::Scan::local): Likewise.
            (Target_x86_64::Scan::possible_function_pointer_reloc): Likewise.
            (Target_x86_64::Scan::global): Likewise.
            (Target_x86_64::Relocate::relocate): Likewise.
            * testsuite/x86_64_mov_to_lea1.s: Add a test for
            R_X86_64_CODE_4_GOTPCRELX.
            * testsuite/x86_64_mov_to_lea2.s: Likewise.
            * testsuite/x86_64_mov_to_lea3.s: Likewise.
            * testsuite/x86_64_mov_to_lea4.s: Likewise.
            * testsuite/x86_64_mov_to_lea5.s: Likewise.
            * testsuite/x86_64_mov_to_lea.sh: Updated.

Diff:
---
 elfcpp/x86_64.h                     |  6 +++++-
 gold/testsuite/x86_64_mov_to_lea.sh | 16 ++++++++++++++++
 gold/testsuite/x86_64_mov_to_lea1.s |  1 +
 gold/testsuite/x86_64_mov_to_lea2.s |  1 +
 gold/testsuite/x86_64_mov_to_lea3.s |  1 +
 gold/testsuite/x86_64_mov_to_lea4.s |  1 +
 gold/testsuite/x86_64_mov_to_lea5.s |  1 +
 gold/x86_64.cc                      | 37 ++++++++++++++++++++++++++++---------
 8 files changed, 54 insertions(+), 10 deletions(-)

diff --git a/elfcpp/x86_64.h b/elfcpp/x86_64.h
index 0377e773071..97a87ae424d 100644
--- a/elfcpp/x86_64.h
+++ b/elfcpp/x86_64.h
@@ -95,9 +95,13 @@ enum
   R_X86_64_PC32_BND = 39,  // PC relative 32 bit signed with BND prefix
   R_X86_64_PLT32_BND = 40, // 32 bit PLT address with BND prefix
   R_X86_64_GOTPCRELX = 41, // 32 bit signed PC relative offset to GOT
-			   // without REX prefix, relaxable.
+			   // without REX nor REX2 prefixes, relaxable.
   R_X86_64_REX_GOTPCRELX = 42, // 32 bit signed PC relative offset to GOT
 			       // with REX prefix, relaxable.
+  R_X86_64_CODE_4_GOTPCRELX = 43, // 32 bit signed PC relative offset to
+				  // GOT if the instruction starts at 4
+				  // bytes before the relocation offset,
+				  // relaxable.
   // GNU vtable garbage collection extensions.
   R_X86_64_GNU_VTINHERIT = 250,
   R_X86_64_GNU_VTENTRY = 251
diff --git a/gold/testsuite/x86_64_mov_to_lea.sh b/gold/testsuite/x86_64_mov_to_lea.sh
index 1b30e1aa048..3e248ebec3c 100755
--- a/gold/testsuite/x86_64_mov_to_lea.sh
+++ b/gold/testsuite/x86_64_mov_to_lea.sh
@@ -25,20 +25,36 @@
 set -e
 
 grep -q "lea    -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea1.stdout
+grep -q "lea    -0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea1.stdout
 grep -q "lea    -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea2.stdout
+grep -q "lea    -0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea2.stdout
 grep -q "lea    -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea3.stdout
+grep -q "lea    -0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea3.stdout
 grep -q "lea    -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea4.stdout
+grep -q "lea    -0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea4.stdout
 grep -q "lea    -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea5.stdout
+grep -q "lea    -0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea5.stdout
 grep -q "lea    -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea6.stdout
+grep -q "lea    -0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea6.stdout
 grep -q "mov    0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea7.stdout
+grep -q "mov    0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea7.stdout
 grep -q "mov    0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea8.stdout
+grep -q "mov    0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea8.stdout
 grep -q "lea    -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea9.stdout
+grep -q "lea    -0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea9.stdout
 grep -q "lea    -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea10.stdout
+grep -q "lea    -0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea10.stdout
 grep -q "mov    0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea11.stdout
+grep -q "mov    0x[a-f0-9]\+(%rip),%r26" x86_64_mov_to_lea11.stdout
 grep -q "mov    0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea12.stdout
+grep -q "mov    0x[a-f0-9]\+(%rip),%r26" 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),%r26" x86_64_mov_to_lea13.stdout
 grep -q "lea    -0x[a-f0-9]\+(%rip),%rax" x86_64_mov_to_lea14.stdout
+grep -q "lea    -0x[a-f0-9]\+(%rip),%r26" 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),%r26d" x86_64_mov_to_lea15.stdout
 grep -q "mov    0x[a-f0-9]\+(%rip),%eax" x86_64_mov_to_lea16.stdout
+grep -q "mov    0x[a-f0-9]\+(%rip),%r26d" x86_64_mov_to_lea16.stdout
 
 exit 0
diff --git a/gold/testsuite/x86_64_mov_to_lea1.s b/gold/testsuite/x86_64_mov_to_lea1.s
index 4dce487c3fc..298ede12f80 100644
--- a/gold/testsuite/x86_64_mov_to_lea1.s
+++ b/gold/testsuite/x86_64_mov_to_lea1.s
@@ -8,4 +8,5 @@ foo:
 	.type	_start, @function
 _start:
 	movq	foo@GOTPCREL(%rip), %rax
+	movq	foo@GOTPCREL(%rip), %r26
 	.size	_start, .-_start
diff --git a/gold/testsuite/x86_64_mov_to_lea2.s b/gold/testsuite/x86_64_mov_to_lea2.s
index 2a11b7a19f4..404f4c1dd48 100644
--- a/gold/testsuite/x86_64_mov_to_lea2.s
+++ b/gold/testsuite/x86_64_mov_to_lea2.s
@@ -3,4 +3,5 @@
 	.type	_start, @function
 _start:
 	movq	_DYNAMIC@GOTPCREL(%rip), %rax
+	movq	_DYNAMIC@GOTPCREL(%rip), %r26
 	.size	_start, .-_start
diff --git a/gold/testsuite/x86_64_mov_to_lea3.s b/gold/testsuite/x86_64_mov_to_lea3.s
index ac43b783758..838c33edae0 100644
--- a/gold/testsuite/x86_64_mov_to_lea3.s
+++ b/gold/testsuite/x86_64_mov_to_lea3.s
@@ -7,4 +7,5 @@ foo:
 	.type	_start, @function
 _start:
 	movq	foo@GOTPCREL(%rip), %rax
+	movq	foo@GOTPCREL(%rip), %r26
 	.size	_start, .-_start
diff --git a/gold/testsuite/x86_64_mov_to_lea4.s b/gold/testsuite/x86_64_mov_to_lea4.s
index 37bee32bb4e..a68a4cf0d19 100644
--- a/gold/testsuite/x86_64_mov_to_lea4.s
+++ b/gold/testsuite/x86_64_mov_to_lea4.s
@@ -9,4 +9,5 @@ foo:
 	.type	_start, @function
 _start:
 	movq	foo@GOTPCREL(%rip), %rax
+	movq	foo@GOTPCREL(%rip), %r26
 	.size	_start, .-_start
diff --git a/gold/testsuite/x86_64_mov_to_lea5.s b/gold/testsuite/x86_64_mov_to_lea5.s
index e793a2b9b73..e818989deb7 100644
--- a/gold/testsuite/x86_64_mov_to_lea5.s
+++ b/gold/testsuite/x86_64_mov_to_lea5.s
@@ -9,4 +9,5 @@ foo:
 	.type	_start, @function
 _start:
 	movl	foo@GOTPCREL+4(%rip), %eax
+	movl	foo@GOTPCREL+4(%rip), %r26d
 	.size	_start, .-_start
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 928dfa8ea34..b7be9bf0d48 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -1053,8 +1053,9 @@ class Target_x86_64 : public Sized_target<size, false>
     gold_assert(gsym != NULL);
     // We cannot do the conversion unless it's one of these relocations.
     if (r_type != elfcpp::R_X86_64_GOTPCREL
-        && r_type != elfcpp::R_X86_64_GOTPCRELX
-        && r_type != elfcpp::R_X86_64_REX_GOTPCRELX)
+	&& r_type != elfcpp::R_X86_64_GOTPCRELX
+	&& r_type != elfcpp::R_X86_64_REX_GOTPCRELX
+	&& r_type != elfcpp::R_X86_64_CODE_4_GOTPCRELX)
       return false;
     // We cannot convert references to IFUNC symbols, or to symbols that
     // are not local to the current module.
@@ -2971,6 +2972,7 @@ Target_x86_64<size>::Scan::get_reference_flags(unsigned int r_type)
     case elfcpp::R_X86_64_GOTPCREL:
     case elfcpp::R_X86_64_GOTPCRELX:
     case elfcpp::R_X86_64_REX_GOTPCRELX:
+    case elfcpp::R_X86_64_CODE_4_GOTPCRELX:
     case elfcpp::R_X86_64_GOTPLT64:
       // Absolute in GOT.
       return Symbol::ABSOLUTE_REF;
@@ -3251,6 +3253,7 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
     case elfcpp::R_X86_64_GOTPCREL:
     case elfcpp::R_X86_64_GOTPCRELX:
     case elfcpp::R_X86_64_REX_GOTPCRELX:
+    case elfcpp::R_X86_64_CODE_4_GOTPCRELX:
     case elfcpp::R_X86_64_GOTPLT64:
       {
 	// The symbol requires a GOT section.
@@ -3261,21 +3264,30 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
 	// mov foo@GOTPCREL(%rip), %reg
 	// to lea foo(%rip), %reg.
 	// in Relocate::relocate.
+	size_t r_offset = reloc.get_r_offset();
 	if (!parameters->incremental()
-	    && (r_type == elfcpp::R_X86_64_GOTPCREL
-		|| r_type == elfcpp::R_X86_64_GOTPCRELX
-		|| r_type == elfcpp::R_X86_64_REX_GOTPCRELX)
+	    && (((r_type == elfcpp::R_X86_64_GOTPCREL
+		  || r_type == elfcpp::R_X86_64_GOTPCRELX
+		  || r_type == elfcpp::R_X86_64_REX_GOTPCRELX)
+		 && r_offset >= 2)
+		|| (r_type == elfcpp::R_X86_64_CODE_4_GOTPCRELX
+		    && r_offset >= 4))
 	    && reloc.get_r_addend() == -4
-	    && reloc.get_r_offset() >= 2
 	    && !is_ifunc)
 	  {
 	    section_size_type stype;
 	    const unsigned char* view = object->section_contents(data_shndx,
 								 &stype, true);
-	    if (view[reloc.get_r_offset() - 2] == 0x8b)
+	    if (r_type == elfcpp::R_X86_64_CODE_4_GOTPCRELX
+		&& view[r_offset - 4] != 0xd5)
+	      goto need_got;
+
+	    if (view[r_offset - 2] == 0x8b)
 	      break;
 	  }
 
+need_got:
+
 	// The symbol requires a GOT entry.
 	unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
 
@@ -3498,6 +3510,7 @@ Target_x86_64<size>::Scan::possible_function_pointer_reloc(
     case elfcpp::R_X86_64_GOTPCREL:
     case elfcpp::R_X86_64_GOTPCRELX:
     case elfcpp::R_X86_64_REX_GOTPCRELX:
+    case elfcpp::R_X86_64_CODE_4_GOTPCRELX:
     case elfcpp::R_X86_64_GOTPLT64:
       {
 	return true;
@@ -3714,6 +3727,7 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
     case elfcpp::R_X86_64_GOTPCREL:
     case elfcpp::R_X86_64_GOTPCRELX:
     case elfcpp::R_X86_64_REX_GOTPCRELX:
+    case elfcpp::R_X86_64_CODE_4_GOTPCRELX:
     case elfcpp::R_X86_64_GOTPLT64:
       {
 	// The symbol requires a GOT entry.
@@ -3736,8 +3750,12 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
         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_type != elfcpp::R_X86_64_CODE_4_GOTPCRELX
+		 && r_offset >= 2)
+		|| (r_type == elfcpp::R_X86_64_CODE_4_GOTPCRELX
+		    && r_offset >= 4
+		    && view[r_offset - 4] == 0xd5))
+	    && Target_x86_64<size>::can_convert_mov_to_lea(gsym, r_type,
                                                            r_offset, &view))
           break;
 
@@ -4420,6 +4438,7 @@ Target_x86_64<size>::Relocate::relocate(
     case elfcpp::R_X86_64_GOTPCREL:
     case elfcpp::R_X86_64_GOTPCRELX:
     case elfcpp::R_X86_64_REX_GOTPCRELX:
+    case elfcpp::R_X86_64_CODE_4_GOTPCRELX:
       {
       bool converted_p = false;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-12-28 18:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-28 18:02 [binutils-gdb] gold: Handle R_X86_64_CODE_4_GOTPCRELX H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).