aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-08-04 17:37:12 +0930
committerAlan Modra <amodra@gmail.com>2023-08-04 17:59:01 +0930
commit066c738ec5d803a080e3da3b0936484a10c8f31b (patch)
treef3d9ca479fb81e84da8e3fdcc060fc3d3be50d2b /bfd/elf32-ppc.c
parentae33771224660dac25e64c3f70943a17bfab7681 (diff)
downloadgdb-066c738ec5d803a080e3da3b0936484a10c8f31b.zip
gdb-066c738ec5d803a080e3da3b0936484a10c8f31b.tar.gz
gdb-066c738ec5d803a080e3da3b0936484a10c8f31b.tar.bz2
ppc: sanity check writing relocs
Check for output buffer overruns. * elf32-ppc.c (swap_reloc_out, count_and_swap_reloc_out): New functions. Use throughout file. * elf64-ppc.c (swap_reloc_out, count_and_swap_reloc_out): Likewise.
Diffstat (limited to 'bfd/elf32-ppc.c')
-rw-r--r--bfd/elf32-ppc.c63
1 files changed, 37 insertions, 26 deletions
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 37bfbcf..ccee076 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -6935,6 +6935,23 @@ is_insn_dq_form (unsigned int insn)
&& (insn & 3) == 1));
}
+static bool
+swap_reloc_out (bfd *obfd, Elf_Internal_Rela *rel, bfd_byte *loc, asection *s)
+{
+ if ((size_t) (loc - s->contents) >= s->size)
+ return false;
+ bfd_elf32_swap_reloca_out (obfd, rel, loc);
+ return true;
+}
+
+static bool
+count_and_swap_reloc_out (bfd *obfd, Elf_Internal_Rela *rel, asection *s)
+{
+ bfd_byte *loc = s->contents;
+ loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
+ return swap_reloc_out (obfd, rel, loc, s);
+}
+
/* The RELOCATE_SECTION function is called by the ELF backend linker
to handle the relocations for a section.
@@ -7806,7 +7823,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
: sym->st_shndx != SHN_ABS)))
{
asection *rsec = htab->elf.srelgot;
- bfd_byte * loc;
if (ifunc != NULL)
{
@@ -7825,11 +7841,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
outrel.r_info = ELF32_R_INFO (indx, R_PPC_DTPMOD32);
if (tls_ty == (TLS_TLS | TLS_GD))
{
- loc = rsec->contents;
- loc += (rsec->reloc_count++
- * sizeof (Elf32_External_Rela));
- bfd_elf32_swap_reloca_out (output_bfd,
- &outrel, loc);
+ BFD_ASSERT (count_and_swap_reloc_out (output_bfd,
+ &outrel,
+ rsec));
outrel.r_offset += 4;
outrel.r_info
= ELF32_R_INFO (indx, R_PPC_DTPREL32);
@@ -7856,10 +7870,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
outrel.r_addend -= htab->elf.tls_sec->vma;
}
}
- loc = rsec->contents;
- loc += (rsec->reloc_count++
- * sizeof (Elf32_External_Rela));
- bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ BFD_ASSERT (count_and_swap_reloc_out (output_bfd,
+ &outrel, rsec));
}
/* Init the .got section contents if we're not
@@ -8089,7 +8101,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
&& h->dyn_relocs != NULL))
{
int skip;
- bfd_byte *loc;
asection *sreloc;
long indx = 0;
@@ -8221,9 +8232,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
if (sreloc == NULL)
return false;
- loc = sreloc->contents;
- loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
- bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ BFD_ASSERT (count_and_swap_reloc_out (output_bfd, &outrel,
+ sreloc));
if (skip == -1)
goto copy_reloc;
@@ -9573,7 +9583,8 @@ write_global_sym_plt (struct elf_link_hash_entry *h, void *inf)
rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
R_PPC_ADDR16_HA);
rela.r_addend = got_offset;
- bfd_elf32_swap_reloca_out (info->output_bfd, &rela, loc);
+ BFD_ASSERT (swap_reloc_out (info->output_bfd, &rela, loc,
+ htab->srelplt2));
loc += sizeof (Elf32_External_Rela);
/* Provide the @l relocation for the second instruction. */
@@ -9583,7 +9594,8 @@ write_global_sym_plt (struct elf_link_hash_entry *h, void *inf)
rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
R_PPC_ADDR16_LO);
rela.r_addend = got_offset;
- bfd_elf32_swap_reloca_out (info->output_bfd, &rela, loc);
+ BFD_ASSERT (swap_reloc_out (info->output_bfd, &rela, loc,
+ htab->srelplt2));
loc += sizeof (Elf32_External_Rela);
/* Provide a relocation for the GOT entry corresponding to this
@@ -9594,7 +9606,8 @@ write_global_sym_plt (struct elf_link_hash_entry *h, void *inf)
rela.r_info = ELF32_R_INFO (htab->elf.hplt->indx,
R_PPC_ADDR32);
rela.r_addend = ent->plt.offset + 16;
- bfd_elf32_swap_reloca_out (info->output_bfd, &rela, loc);
+ BFD_ASSERT (swap_reloc_out (info->output_bfd, &rela, loc,
+ htab->srelplt2));
}
/* VxWorks uses non-standard semantics for R_PPC_JMP_SLOT.
@@ -9676,7 +9689,8 @@ write_global_sym_plt (struct elf_link_hash_entry *h, void *inf)
if (h->type == STT_GNU_IFUNC && is_static_defined (h))
htab->maybe_local_ifunc_resolver = 1;
}
- bfd_elf32_swap_reloca_out (info->output_bfd, &rela, loc);
+ BFD_ASSERT (swap_reloc_out (info->output_bfd, &rela,
+ loc, relplt));
}
doneone = true;
}
@@ -9793,9 +9807,8 @@ ppc_finish_symbols (struct bfd_link_info *info)
+ plt->output_offset
+ plt->output_section->vma);
rela.r_addend = val;
- loc = relplt->contents + (relplt->reloc_count++
- * sizeof (Elf32_External_Rela));
- bfd_elf32_swap_reloca_out (info->output_bfd, &rela, loc);
+ BFD_ASSERT (count_and_swap_reloc_out (info->output_bfd, &rela,
+ relplt));
p = (unsigned char *) htab->glink->contents + ent->glink_offset;
write_glink_stub (NULL, ent, htab->elf.iplt, p, info);
@@ -9879,7 +9892,6 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
{
asection *s;
Elf_Internal_Rela rela;
- bfd_byte *loc;
/* This symbols needs a copy reloc. Set it up. */
@@ -9900,8 +9912,7 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
rela.r_offset = SYM_VAL (h);
rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_COPY);
rela.r_addend = 0;
- loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
- bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ BFD_ASSERT (count_and_swap_reloc_out (output_bfd, &rela, s));
}
#ifdef DEBUG
@@ -10105,7 +10116,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
+ 2);
rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_HA);
rela.r_addend = 0;
- bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ BFD_ASSERT (swap_reloc_out (output_bfd, &rela, loc, htab->srelplt2));
loc += sizeof (Elf32_External_Rela);
/* Output the @l relocation for the second instruction. */
@@ -10114,7 +10125,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
+ 6);
rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_LO);
rela.r_addend = 0;
- bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ BFD_ASSERT (swap_reloc_out (output_bfd, &rela, loc, htab->srelplt2));
loc += sizeof (Elf32_External_Rela);
/* Fix up the remaining relocations. They may have the wrong