[01/11] alpha: initialize every field of a new got entry

Message ID 20260901023318.3503991-2-mattst88@gmail.com
State New
Headers
Series alpha: support STT_GNU_IFUNC |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply

Commit Message

Matt Turner Sept. 1, 2026, 2:33 a.m. UTC
  get_got_entry allocates a got entry with bfd_alloc and then assigns the
fields one by one, but never assigns flags. elf64_alpha_merge_gots reads
it, so two got subsections that merge OR uninitialized memory into the
surviving entry. A literal always has flags assigned by check_relocs
before then, from its LITUSEs or from the fallback that marks it as an
address use, but an entry created for a TLS relocation has no such
assignment.

elf64_alpha_relax_tls_get_addr allocates one the same way when it
switches a general dynamic sequence to initial exec and the object has
no GOTTPREL entry yet. That one leaves both flags and plt_offset
uninitialized, and a stray plt_offset is not a value the rest of the
code expects to see.

Allocate both with bfd_zalloc and assign only the fields whose initial
value is not zero. A new field then needs no assignment at either site,
rather than one that is easy to forget at the second.

Found with valgrind.
---
 bfd/elf64-alpha.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
  

Patch

diff --git ./bfd/elf64-alpha.c ./bfd/elf64-alpha.c
index 8b8a97a4b05..4fc1a542704 100644
--- ./bfd/elf64-alpha.c
+++ ./bfd/elf64-alpha.c
@@ -1718,7 +1718,7 @@  get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h,
       size_t amt;
 
       amt = sizeof (struct alpha_elf_got_entry);
-      gotent = (struct alpha_elf_got_entry *) bfd_alloc (abfd, amt);
+      gotent = (struct alpha_elf_got_entry *) bfd_zalloc (abfd, amt);
       if (!gotent)
 	return NULL;
 
@@ -1728,8 +1728,6 @@  get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h,
       gotent->plt_offset = -1;
       gotent->use_count = 1;
       gotent->reloc_type = r_type;
-      gotent->reloc_done = 0;
-      gotent->reloc_xlated = 0;
 
       gotent->next = *slot;
       *slot = gotent;
@@ -3655,7 +3653,7 @@  elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval,
 	  else
 	    {
 	      tprel_gotent = (struct alpha_elf_got_entry *)
-		bfd_alloc (info->abfd, sizeof (struct alpha_elf_got_entry));
+		bfd_zalloc (info->abfd, sizeof (struct alpha_elf_got_entry));
 	      if (!tprel_gotent)
 		return false;
 
@@ -3665,8 +3663,7 @@  elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval,
 	      tprel_gotent->gotobj = info->gotobj;
 	      tprel_gotent->addend = irel->r_addend;
 	      tprel_gotent->got_offset = -1;
-	      tprel_gotent->reloc_done = 0;
-	      tprel_gotent->reloc_xlated = 0;
+	      tprel_gotent->plt_offset = -1;
 	    }
 
 	  tprel_gotent->use_count = 1;