aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2025-01-13 20:33:54 +1030
committerAlan Modra <amodra@gmail.com>2025-01-20 07:13:46 +1030
commit3a8864b3aa87330412f956a6ce233209eba133c8 (patch)
tree07c3dcea730b90f3852ff1453c6ccdb7f2fd4e42
parentcb6326b5ceb7cfc784003c05b90b351d78c755fd (diff)
downloadbinutils-3a8864b3aa87330412f956a6ce233209eba133c8.zip
binutils-3a8864b3aa87330412f956a6ce233209eba133c8.tar.gz
binutils-3a8864b3aa87330412f956a6ce233209eba133c8.tar.bz2
reloc caching
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. * 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.
-rw-r--r--bfd/elf.c2
-rw-r--r--bfd/elf32-ppc.c25
-rw-r--r--bfd/elf64-ppc.c2
-rw-r--r--bfd/elflink.c19
4 files changed, 14 insertions, 34 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index bce2a18..37b87ee 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 25cb31b..f17effd 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 fa28a53..65415bd 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 d4e890d..8974015 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;
}