aboutsummaryrefslogtreecommitdiff
path: root/bfd/coff-z80.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-03-07 22:21:28 +1030
committerAlan Modra <amodra@gmail.com>2023-03-08 11:24:50 +1030
commitd64c8f7181fd21f90983f8d55369f6f9a2960c43 (patch)
tree2121d1b6c59faefb19dd040ebe4eb57929782f76 /bfd/coff-z80.c
parentb9ee26d9ca29b5f598772de9f78c3da21cfa6c1b (diff)
downloadgdb-d64c8f7181fd21f90983f8d55369f6f9a2960c43.zip
gdb-d64c8f7181fd21f90983f8d55369f6f9a2960c43.tar.gz
gdb-d64c8f7181fd21f90983f8d55369f6f9a2960c43.tar.bz2
z8 and z80 coff_reloc16_extra_cases sanity checks
* reloc16.c (bfd_coff_reloc16_get_relocated_section_contents): Use size_t variables. Sanity check reloc address. Handle errors from bfd_coff_reloc16_extra_cases. * coffcode.h (_bfd_coff_reloc16_extra_cases): Return bool, take size_t* args. (dummy_reloc16_extra_cases): Adjust to suit. Don't abort. * coff-z80.c (extra_case): Sanity check reloc address. Return errors. Tidy formatting. Use bfd_signed_vma temp var to check for reloc overflow. Don't abort on unexpected reloc type, instead print an error and return false. * coff-z8k.c (extra_case): Likewise. * libcoff.h: Regenerate.
Diffstat (limited to 'bfd/coff-z80.c')
-rw-r--r--bfd/coff-z80.c118
1 files changed, 71 insertions, 47 deletions
diff --git a/bfd/coff-z80.c b/bfd/coff-z80.c
index c782e32..702fe65 100644
--- a/bfd/coff-z80.c
+++ b/bfd/coff-z80.c
@@ -330,77 +330,92 @@ reloc_processing (arelent *relent,
relent->address -= section->vma;
}
-static void
+static bool
extra_case (bfd *in_abfd,
struct bfd_link_info *link_info,
struct bfd_link_order *link_order,
arelent *reloc,
bfd_byte *data,
- unsigned int *src_ptr,
- unsigned int *dst_ptr)
+ size_t *src_ptr,
+ size_t *dst_ptr)
{
asection * input_section = link_order->u.indirect.section;
- int val = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ bfd_size_type end = bfd_get_section_limit_octets (in_abfd, input_section);
+ bfd_size_type reloc_size = bfd_get_reloc_size (reloc->howto);
+
+ if (*src_ptr > end
+ || reloc_size > end - *src_ptr)
+ {
+ link_info->callbacks->einfo
+ /* xgettext:c-format */
+ (_("%X%P: %pB(%pA): relocation \"%pR\" goes out of range\n"),
+ in_abfd, input_section, reloc);
+ return false;
+ }
+ int val = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
switch (reloc->howto->type)
{
case R_OFF8:
if (reloc->howto->partial_inplace)
- val += (signed char)(bfd_get_8 ( in_abfd, data+*src_ptr)
- & reloc->howto->src_mask);
- if (val>127 || val<-128) /* Test for overflow. */
- (*link_info->callbacks->reloc_overflow)
+ val += (signed char) (bfd_get_8 (in_abfd, data + *src_ptr)
+ & reloc->howto->src_mask);
+ if (val > 127 || val < -128)
+ {
+ link_info->callbacks->reloc_overflow
(link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
reloc->howto->name, reloc->addend, input_section->owner,
input_section, reloc->address);
+ return false;
+ }
- bfd_put_8 (in_abfd, val, data + *dst_ptr);
- (*dst_ptr) += 1;
- (*src_ptr) += 1;
+ bfd_put_8 (in_abfd, val, data + *dst_ptr);
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
case R_BYTE3:
bfd_put_8 (in_abfd, val >> 24, data + *dst_ptr);
- (*dst_ptr) += 1;
- (*src_ptr) += 1;
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
case R_BYTE2:
bfd_put_8 (in_abfd, val >> 16, data + *dst_ptr);
- (*dst_ptr) += 1;
- (*src_ptr) += 1;
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
case R_BYTE1:
bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr);
- (*dst_ptr) += 1;
- (*src_ptr) += 1;
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
case R_IMM8:
if (reloc->howto->partial_inplace)
- val += bfd_get_8 ( in_abfd, data+*src_ptr) & reloc->howto->src_mask;
+ val += bfd_get_8 (in_abfd, data + *src_ptr) & reloc->howto->src_mask;
/* Fall through. */
case R_BYTE0:
bfd_put_8 (in_abfd, val, data + *dst_ptr);
- (*dst_ptr) += 1;
- (*src_ptr) += 1;
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
case R_WORD1:
bfd_put_16 (in_abfd, val >> 16, data + *dst_ptr);
- (*dst_ptr) += 2;
- (*src_ptr) += 2;
+ *dst_ptr += 2;
+ *src_ptr += 2;
break;
case R_IMM16:
if (reloc->howto->partial_inplace)
- val += bfd_get_16 ( in_abfd, data+*src_ptr) & reloc->howto->src_mask;
+ val += bfd_get_16 (in_abfd, data + *src_ptr) & reloc->howto->src_mask;
/* Fall through. */
case R_WORD0:
bfd_put_16 (in_abfd, val, data + *dst_ptr);
- (*dst_ptr) += 2;
- (*src_ptr) += 2;
+ *dst_ptr += 2;
+ *src_ptr += 2;
break;
case R_IMM24:
@@ -408,53 +423,62 @@ extra_case (bfd *in_abfd,
val += (bfd_get_24 (in_abfd, data + *src_ptr)
& reloc->howto->src_mask);
bfd_put_24 (in_abfd, val, data + *dst_ptr);
- (*dst_ptr) += 3;
- (*src_ptr) += 3;
+ *dst_ptr += 3;
+ *src_ptr += 3;
break;
case R_IMM32:
if (reloc->howto->partial_inplace)
- val += bfd_get_32 ( in_abfd, data+*src_ptr) & reloc->howto->src_mask;
+ val += bfd_get_32 (in_abfd, data + *src_ptr) & reloc->howto->src_mask;
bfd_put_32 (in_abfd, val, data + *dst_ptr);
- (*dst_ptr) += 4;
- (*src_ptr) += 4;
+ *dst_ptr += 4;
+ *src_ptr += 4;
break;
case R_JR:
{
- if (reloc->howto->partial_inplace)
- val += (signed char)(bfd_get_8 ( in_abfd, data+*src_ptr)
- & reloc->howto->src_mask);
+ if (reloc->howto->partial_inplace)
+ val += (signed char) (bfd_get_8 (in_abfd, data + *src_ptr)
+ & reloc->howto->src_mask);
bfd_vma dot = (*dst_ptr
+ input_section->output_offset
+ input_section->output_section->vma);
- int gap = val - dot;
+ bfd_signed_vma gap = val - dot;
if (gap >= 128 || gap < -128)
- (*link_info->callbacks->reloc_overflow)
- (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
- reloc->howto->name, reloc->addend, input_section->owner,
- input_section, reloc->address);
+ {
+ link_info->callbacks->reloc_overflow
+ (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address);
+ return false;
+ }
bfd_put_8 (in_abfd, gap, data + *dst_ptr);
- (*dst_ptr)++;
- (*src_ptr)++;
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
}
case R_IMM16BE:
if (reloc->howto->partial_inplace)
- val += (bfd_get_8 ( in_abfd, data+*src_ptr+0) * 0x100 +
- bfd_get_8 ( in_abfd, data+*src_ptr+1)) & reloc->howto->src_mask;
+ val += ((bfd_get_8 (in_abfd, data + *src_ptr + 0) * 0x100
+ + bfd_get_8 (in_abfd, data + *src_ptr + 1))
+ & reloc->howto->src_mask);
- bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr+0);
- bfd_put_8 (in_abfd, val, data + *dst_ptr+1);
- (*dst_ptr) += 2;
- (*src_ptr) += 2;
+ bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr + 0);
+ bfd_put_8 (in_abfd, val, data + *dst_ptr + 1);
+ *dst_ptr += 2;
+ *src_ptr += 2;
break;
default:
- abort ();
+ link_info->callbacks->einfo
+ /* xgettext:c-format */
+ (_("%X%P: %pB(%pA): relocation \"%pR\" is not supported\n"),
+ in_abfd, input_section, reloc);
+ return false;
}
+ return true;
}
static bool