[binutils-gdb/binutils-2_44-branch] aarch64: Fix PLT fixups when BTI is used [PR32572]

Richard Earnshaw rearnsha@sourceware.org
Fri Jan 24 14:59:21 GMT 2025


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

commit a4e996833fe5d770a9efc95d35567b51025cf23f
Author: Richard Earnshaw <rearnsha@arm.com>
Date:   Thu Jan 23 10:53:54 2025 +0000

    aarch64: Fix PLT fixups when BTI is used [PR32572]
    
    PR ld/32572
    
    There are two problems addressed in this PR.  Firstly, the choice of
    whether or not a PLT stub needs a BTI on entry was too strict,
    resulting in non-pie executables not having a BTI on their stub.  But
    secondly, the logic to handle each stub types did not agree across the
    various places where this information is used.
    
    The first issue is fixed by using bfd_link_executable rather than
    bfd_link_pde.  The second is addressed by recording a delta for PLT
    stub alongside the stub itself.  This is then used without needing
    additional logic later on since it has been pre-calculated.
    
    A more comprehensive fix would involve creating a data structure to
    describe each fixup, including a call-back function to apply any
    relocations.  But that's a fairly large change and not appropriate for
    backporting.

Diff:
---
 bfd/elfnn-aarch64.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index f327b7a8a36..65182f49070 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -2631,6 +2631,11 @@ struct elf_aarch64_link_hash_table
   /* The bytes of the subsequent PLT entry.  */
   const bfd_byte *plt_entry;
 
+  /* PLT entries have a common shape, but may have some pre-amble
+     instructions (such as BTI).  This delta is used to factor this
+     out of the common code.  */
+  int plt_entry_delta;
+
   /* For convenience in allocate_dynrelocs.  */
   bfd *obfd;
 
@@ -2924,6 +2929,7 @@ elfNN_aarch64_link_hash_table_create (bfd *abfd)
   ret->plt_header_size = PLT_ENTRY_SIZE;
   ret->plt0_entry = elfNN_aarch64_small_plt0_entry;
   ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
+  ret->plt_entry_delta = 0;
   ret->plt_entry = elfNN_aarch64_small_plt_entry;
   ret->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE;
   ret->obfd = abfd;
@@ -4958,15 +4964,17 @@ setup_plt_values (struct bfd_link_info *link_info,
       globals->plt0_entry = elfNN_aarch64_small_plt0_bti_entry;
 
       /* Only in ET_EXEC we need PLTn with BTI.  */
-      if (bfd_link_pde (link_info))
+      if (bfd_link_executable (link_info))
 	{
 	  globals->plt_entry_size = PLT_BTI_PAC_SMALL_ENTRY_SIZE;
 	  globals->plt_entry = elfNN_aarch64_small_plt_bti_pac_entry;
+	  globals->plt_entry_delta = 4;
 	}
       else
 	{
 	  globals->plt_entry_size = PLT_PAC_SMALL_ENTRY_SIZE;
 	  globals->plt_entry = elfNN_aarch64_small_plt_pac_entry;
+	  globals->plt_entry_delta = 0;
 	}
     }
   else if (plt_type == PLT_BTI)
@@ -4974,10 +4982,11 @@ setup_plt_values (struct bfd_link_info *link_info,
       globals->plt0_entry = elfNN_aarch64_small_plt0_bti_entry;
 
       /* Only in ET_EXEC we need PLTn with BTI.  */
-      if (bfd_link_pde (link_info))
+      if (bfd_link_executable (link_info))
 	{
 	  globals->plt_entry_size = PLT_BTI_SMALL_ENTRY_SIZE;
 	  globals->plt_entry = elfNN_aarch64_small_plt_bti_entry;
+	  globals->plt_entry_delta = 4;
 	}
     }
   else if (plt_type == PLT_PAC)
@@ -9837,11 +9846,9 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
   /* Copy in the boiler-plate for the PLTn entry.  */
   memcpy (plt_entry, htab->plt_entry, htab->plt_entry_size);
 
-  /* First instruction in BTI enabled PLT stub is a BTI
-     instruction so skip it.  */
-  if (elf_aarch64_tdata (output_bfd)->sw_protections.plt_type & PLT_BTI
-      && elf_elfheader (output_bfd)->e_type == ET_EXEC)
-    plt_entry = plt_entry + 4;
+  /* Allow for any delta (such as a BTI instruction) before the common
+     sequence.  */
+  plt_entry += htab->plt_entry_delta;
 
   /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
      ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */


More information about the Binutils-cvs mailing list