reloc caching

Alan Modra amodra@gmail.com
Fri Jan 17 09:37:31 GMT 2025


This arranges to free section relocs cached in elf_section_data.  To
do that, some relocs stored there need to use bfd_malloc buffers
rather than bfd_alloc ones.

I'll leave this one until after the branch.

	* elf.c (_bfd_elf_free_cached_info): Free relocs.
	* elf32-ppc.c (ppc_elf_relax_section): Realloc relocs rather
	than malloc, copy, free old.
	* elf64-ppc.c (get_relocs): bfd_malloc relocs.
	* elflink.c (_bfd_elf_link_info_read_relocs): Always
	bfd_malloc relocs.

diff --git a/bfd/elf.c b/bfd/elf.c
index bce2a18c961..37b87ee13da 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -10134,6 +10134,8 @@ _bfd_elf_free_cached_info (bfd *abfd)
 	      free (elf_section_data (sec)->this_hdr.contents);
 	      elf_section_data (sec)->this_hdr.contents = NULL;
 	    }
+	  free (elf_section_data (sec)->relocs);
+	  elf_section_data (sec)->relocs = NULL;
 	}
       free (tdata->symtab_hdr.contents);
       tdata->symtab_hdr.contents = NULL;
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 25cb31b8f3b..f17effdf176 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -6629,26 +6629,15 @@ ppc_elf_relax_section (bfd *abfd,
     {
       /* Append sufficient NOP relocs so we can write out relocation
 	 information for the trampolines.  */
-      Elf_Internal_Shdr *rel_hdr;
-      Elf_Internal_Rela *new_relocs = bfd_malloc ((changes + isec->reloc_count)
-						  * sizeof (*new_relocs));
-      unsigned ix;
-
-      if (!new_relocs)
+      size_t old_size = isec->reloc_count * sizeof (*internal_relocs);
+      size_t extra_size = changes * sizeof (*internal_relocs);
+      internal_relocs = bfd_realloc (internal_relocs, old_size + extra_size);
+      elf_section_data (isec)->relocs = internal_relocs;
+      if (!internal_relocs)
 	goto error_return;
-      memcpy (new_relocs, internal_relocs,
-	      isec->reloc_count * sizeof (*new_relocs));
-      for (ix = changes; ix--;)
-	{
-	  irel = new_relocs + ix + isec->reloc_count;
-
-	  irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
-	}
-      if (internal_relocs != elf_section_data (isec)->relocs)
-	free (internal_relocs);
-      elf_section_data (isec)->relocs = new_relocs;
+      memset ((char *) internal_relocs + old_size, 0, extra_size);
       isec->reloc_count += changes;
-      rel_hdr = _bfd_elf_single_rel_hdr (isec);
+      Elf_Internal_Shdr *rel_hdr = _bfd_elf_single_rel_hdr (isec);
       rel_hdr->sh_size += changes * rel_hdr->sh_entsize;
     }
   else if (elf_section_data (isec)->relocs != internal_relocs)
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index fa28a536378..65415bd39c7 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -11575,7 +11575,7 @@ get_relocs (asection *sec, int count)
     {
       bfd_size_type relsize;
       relsize = sec->reloc_count * sizeof (*relocs);
-      relocs = bfd_alloc (sec->owner, relsize);
+      relocs = bfd_malloc (relsize);
       if (relocs == NULL)
 	return NULL;
       elfsec_data->relocs = relocs;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index d4e890df734..8974015728d 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -2841,14 +2841,9 @@ _bfd_elf_link_info_read_relocs (bfd *abfd,
       bfd_size_type size;
 
       size = (bfd_size_type) o->reloc_count * sizeof (Elf_Internal_Rela);
-      if (keep_memory)
-	{
-	  internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_alloc (abfd, size);
-	  if (info)
-	    info->cache_size += size;
-	}
-      else
-	internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size);
+      if (keep_memory && info)
+	info->cache_size += size;
+      internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size);
       if (internal_relocs == NULL)
 	return NULL;
     }
@@ -2886,13 +2881,7 @@ _bfd_elf_link_info_read_relocs (bfd *abfd,
 
  error_return:
   _bfd_munmap_temporary (alloc1, alloc1_size);
-  if (alloc2 != NULL)
-    {
-      if (keep_memory)
-	bfd_release (abfd, alloc2);
-      else
-	free (alloc2);
-    }
+  free (alloc2);
   return NULL;
 }
 

-- 
Alan Modra


More information about the Binutils mailing list