diff options
author | Alan Modra <amodra@gmail.com> | 2023-03-07 22:21:28 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2023-03-08 11:24:50 +1030 |
commit | d64c8f7181fd21f90983f8d55369f6f9a2960c43 (patch) | |
tree | 2121d1b6c59faefb19dd040ebe4eb57929782f76 /bfd/coff-z80.c | |
parent | b9ee26d9ca29b5f598772de9f78c3da21cfa6c1b (diff) | |
download | gdb-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.c | 118 |
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 |