x86: traverse loc_hash_table only if used

Message ID CAMe9rOphrnO0iQXu19uEeDztwH1KuW8XVRr9mXsiDn3wWceGfw@mail.gmail.com
State New
Headers
Series x86: traverse loc_hash_table only if used |

Commit Message

H.J. Lu Nov. 29, 2025, 12:52 a.m. UTC
  Traverse x86 loc_hash_table only if it is used.

* elf32-i386.c (elf_i386_output_arch_local_syms): Traverse
loc_hash_table only if has_loc_hash_table is set.
* elf64-x86-64.c (elf_x86_64_output_arch_local_syms): Likewise.
* elfxx-x86.c (_bfd_elf_x86_get_local_sym_hash): Set
has_loc_hash_table.
(_bfd_x86_elf_late_size_sections): Traverse loc_hash_table only
if has_loc_hash_table is set.
* elfxx-x86.h (elf_x86_link_hash_table): Move plt0_pad_byte and
add has_loc_hash_table.
  

Comments

H.J. Lu Dec. 2, 2025, 1:03 a.m. UTC | #1
On Sat, Nov 29, 2025 at 8:52 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> Traverse x86 loc_hash_table only if it is used.
>
> * elf32-i386.c (elf_i386_output_arch_local_syms): Traverse
> loc_hash_table only if has_loc_hash_table is set.
> * elf64-x86-64.c (elf_x86_64_output_arch_local_syms): Likewise.
> * elfxx-x86.c (_bfd_elf_x86_get_local_sym_hash): Set
> has_loc_hash_table.
> (_bfd_x86_elf_late_size_sections): Traverse loc_hash_table only
> if has_loc_hash_table is set.
> * elfxx-x86.h (elf_x86_link_hash_table): Move plt0_pad_byte and
> add has_loc_hash_table.
>
>
> --
> H.J.

I am checking it in.
  

Patch

From e3a9a6162101813437f6a136808866b3e0a4927d Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sat, 29 Nov 2025 08:47:46 +0800
Subject: [PATCH] x86: traverse loc_hash_table only if used

Traverse x86 loc_hash_table only if it is used.

	* elf32-i386.c (elf_i386_output_arch_local_syms): Traverse
	loc_hash_table only if has_loc_hash_table is set.
	* elf64-x86-64.c (elf_x86_64_output_arch_local_syms): Likewise.
	* elfxx-x86.c (_bfd_elf_x86_get_local_sym_hash): Set
	has_loc_hash_table.
	(_bfd_x86_elf_late_size_sections): Traverse loc_hash_table only
	if has_loc_hash_table is set.
	* elfxx-x86.h (elf_x86_link_hash_table): Move plt0_pad_byte and
	add has_loc_hash_table.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 bfd/elf32-i386.c   | 10 ++++++----
 bfd/elf64-x86-64.c | 10 ++++++----
 bfd/elfxx-x86.c    |  9 ++++++---
 bfd/elfxx-x86.h    |  9 ++++++---
 4 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index abb361be993..755c2176fd2 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -4271,10 +4271,12 @@  elf_i386_output_arch_local_syms
   if (htab == NULL)
     return false;
 
-  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
-  htab_traverse (htab->loc_hash_table,
-		 elf_i386_finish_local_dynamic_symbol,
-		 info);
+  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols if
+     needed.  */
+  if (htab->has_loc_hash_table)
+    htab_traverse (htab->loc_hash_table,
+		   elf_i386_finish_local_dynamic_symbol,
+		   info);
 
   return true;
 }
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 337394fc478..1bffced9a30 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -5777,10 +5777,12 @@  elf_x86_64_output_arch_local_syms
   if (htab == NULL)
     return false;
 
-  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
-  htab_traverse (htab->loc_hash_table,
-		 elf_x86_64_finish_local_dynamic_symbol,
-		 info);
+  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols if
+     needed.  */
+  if (htab->has_loc_hash_table)
+    htab_traverse (htab->loc_hash_table,
+		   elf_x86_64_finish_local_dynamic_symbol,
+		   info);
 
   return true;
 }
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 215a1569e9d..9f425e9bb9b 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -613,6 +613,7 @@  _bfd_elf_x86_get_local_sym_hash (struct elf_x86_link_hash_table *htab,
       ret->elf.dynindx = -1;
       ret->plt_got.offset = (bfd_vma) -1;
       *slot = ret;
+      htab->has_loc_hash_table = 1;
     }
   return &ret->elf;
 }
@@ -2425,9 +2426,11 @@  _bfd_x86_elf_late_size_sections (bfd *output_bfd,
   elf_link_hash_traverse (&htab->elf, elf_x86_allocate_dynrelocs,
 			  info);
 
-  /* Allocate .plt and .got entries, and space for local symbols.  */
-  htab_traverse (htab->loc_hash_table, elf_x86_allocate_local_dynreloc,
-		 info);
+  /* Allocate .plt and .got entries, and space for local symbols if
+     needed.  */
+  if (htab->has_loc_hash_table)
+    htab_traverse (htab->loc_hash_table, elf_x86_allocate_local_dynreloc,
+		   info);
 
   /* For every jump slot reserved in the sgotplt, reloc_count is
      incremented.  However, when we reserve space for TLS descriptors,
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 7e196cd0475..99ef9341563 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -673,9 +673,8 @@  struct elf_x86_link_hash_table
   /* TRUE if inputs call ___tls_get_addr.  This is only used for i386.  */
   unsigned int has_tls_get_addr_call : 1;
 
-   /* Value used to fill the unused bytes of the first PLT entry.  This
-      is only used for i386.  */
-  bfd_byte plt0_pad_byte;
+  /* TRUE if loc_hash_table is used.  */
+  unsigned int has_loc_hash_table : 1;
 
   /* TRUE if GOT is referenced.  */
   unsigned int got_referenced : 1;
@@ -688,6 +687,10 @@  struct elf_x86_link_hash_table
      function address.  */
   unsigned int pcrel_plt : 1;
 
+   /* Value used to fill the unused bytes of the first PLT entry.  This
+      is only used for i386.  */
+  bfd_byte plt0_pad_byte;
+
   bfd_vma (*r_info) (bfd_vma, bfd_vma);
   bfd_vma (*r_sym) (bfd_vma);
   bool (*is_reloc_section) (const char *);
-- 
2.52.0