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:
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
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;
+ 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;
+ }
switch (reloc->howto->type)
{
bfd_put_8 (in_abfd,
bfd_coff_reloc16_get_value (reloc, link_info, input_section),
data + *dst_ptr);
- (*dst_ptr) += 1;
- (*src_ptr) += 1;
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
case R_IMM32:
dst = (dst & 0xffff) | ((dst & 0xff0000) << 8) | 0x80000000;
bfd_put_32 (in_abfd, dst, data + *dst_ptr);
}
- (*dst_ptr) += 4;
- (*src_ptr) += 4;
+ *dst_ptr += 4;
+ *src_ptr += 4;
break;
case R_IMM4L:
bfd_put_8 (in_abfd,
((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0)
- | (0x0f
- & bfd_coff_reloc16_get_value (reloc, link_info,
- input_section))),
+ | (0x0f & bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section))),
data + *dst_ptr);
- (*dst_ptr) += 1;
- (*src_ptr) += 1;
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
case R_IMM16:
bfd_put_16 (in_abfd,
bfd_coff_reloc16_get_value (reloc, link_info, input_section),
data + *dst_ptr);
- (*dst_ptr) += 2;
- (*src_ptr) += 2;
+ *dst_ptr += 2;
+ *src_ptr += 2;
break;
case R_JR:
bfd_vma dot = (*dst_ptr
+ input_section->output_offset
+ input_section->output_section->vma);
- int gap = dst - dot - 1; /* -1, since we're in the odd byte of the
- word and the pc's been incremented. */
-
- if (gap & 1)
- abort ();
- gap /= 2;
- if (gap > 127 || 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);
-
- bfd_put_8 (in_abfd, gap, data + *dst_ptr);
- (*dst_ptr)++;
- (*src_ptr)++;
+ /* -1, since we're in the odd byte of the word and the pc has
+ been incremented. */
+ bfd_signed_vma gap = dst - dot - 1;
+
+ if ((gap & 1) != 0 || gap > 254 || gap < -256)
+ {
+ 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 / 2, data + *dst_ptr);
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
}
bfd_vma dot = (*dst_ptr
+ input_section->output_offset
+ input_section->output_section->vma);
- int gap = dst - dot - 1; /* -1, since we're in the odd byte of the
- word and the pc's been incremented. */
-
- if (gap & 1)
- abort ();
- gap /= 2;
+ bfd_signed_vma gap = dst - dot - 1;
- if (gap > 0 || gap < -127)
- (*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);
+ if ((gap & 1) != 0 || gap > 0 || gap < -254)
+ {
+ 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,
- (bfd_get_8 ( in_abfd, data + *dst_ptr) & 0x80) + (-gap & 0x7f),
+ ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0x80)
+ + (-gap / 2 & 0x7f)),
data + *dst_ptr);
- (*dst_ptr)++;
- (*src_ptr)++;
+ *dst_ptr += 1;
+ *src_ptr += 1;
break;
}
bfd_vma dot = (*dst_ptr
+ input_section->output_offset
+ input_section->output_section->vma);
- int gap = dst - dot - 2;
+ bfd_signed_vma gap = dst - dot - 2;
- if (gap & 1)
- abort ();
- if (gap > 4096 || gap < -4095)
- (*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);
+ if ((gap & 1) != 0 || gap > 4096 || gap < -4095)
+ {
+ 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;
+ }
- gap /= 2;
bfd_put_16 (in_abfd,
- (bfd_get_16 ( in_abfd, data + *dst_ptr) & 0xf000) | (-gap & 0x0fff),
+ ((bfd_get_16 (in_abfd, data + *dst_ptr) & 0xf000)
+ | (-gap / 2 & 0x0fff)),
data + *dst_ptr);
- (*dst_ptr) += 2;
- (*src_ptr) += 2;
+ *dst_ptr += 2;
+ *src_ptr += 2;
break;
}
bfd_vma dot = (*dst_ptr
+ input_section->output_offset
+ input_section->output_section->vma);
- int gap = dst - dot - 2;
+ bfd_signed_vma gap = dst - dot - 2;
if (gap > 32767 || gap < -32768)
- (*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);
-
- bfd_put_16 (in_abfd, (bfd_vma) gap, data + *dst_ptr);
- (*dst_ptr) += 2;
- (*src_ptr) += 2;
+ {
+ 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_16 (in_abfd, gap, data + *dst_ptr);
+ *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;
}
#define coff_reloc16_extra_cases extra_case
. (bfd *, FILE *, combined_entry_type *, combined_entry_type *,
. combined_entry_type *, unsigned int);
.
-. void (*_bfd_coff_reloc16_extra_cases)
+. bool (*_bfd_coff_reloc16_extra_cases)
. (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
-. bfd_byte *, unsigned int *, unsigned int *);
+. bfd_byte *, size_t *, size_t *);
.
. int (*_bfd_coff_reloc16_estimate)
. (bfd *, asection *, arelent *, unsigned int,
#define coff_reloc16_extra_cases dummy_reloc16_extra_cases
-/* This works even if abort is not declared in any header file. */
-
-static void
+static bool
dummy_reloc16_extra_cases (bfd *abfd ATTRIBUTE_UNUSED,
struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
struct bfd_link_order *link_order ATTRIBUTE_UNUSED,
arelent *reloc ATTRIBUTE_UNUSED,
bfd_byte *data ATTRIBUTE_UNUSED,
- unsigned int *src_ptr ATTRIBUTE_UNUSED,
- unsigned int *dst_ptr ATTRIBUTE_UNUSED)
+ size_t *src_ptr ATTRIBUTE_UNUSED,
+ size_t *dst_ptr ATTRIBUTE_UNUSED)
{
- abort ();
+ return false;
}
#endif
(bfd *, FILE *, combined_entry_type *, combined_entry_type *,
combined_entry_type *, unsigned int);
- void (*_bfd_coff_reloc16_extra_cases)
+ bool (*_bfd_coff_reloc16_extra_cases)
(bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
- bfd_byte *, unsigned int *, unsigned int *);
+ bfd_byte *, size_t *, size_t *);
int (*_bfd_coff_reloc16_estimate)
(bfd *, asection *, arelent *, unsigned int,
{
arelent **parent = reloc_vector;
arelent *reloc;
- unsigned int dst_address = 0;
- unsigned int src_address = 0;
- unsigned int run;
- unsigned int idx;
+ size_t dst_address = 0;
+ size_t src_address = 0;
+ size_t run;
+ size_t idx;
/* Find how long a run we can do. */
while (dst_address < link_order->size)
/* Note that the relaxing didn't tie up the addresses in the
relocation, so we use the original address to work out the
run of non-relocated data. */
+ if (reloc->address > link_order->size
+ || reloc->address < src_address)
+ {
+ link_info->callbacks->einfo
+ /* xgettext:c-format */
+ (_("%X%P: %pB(%pA): relocation \"%pR\" goes out of range\n"),
+ input_bfd, input_section, reloc);
+ goto error_return;
+ }
run = reloc->address - src_address;
parent++;
}
data[dst_address++] = data[src_address++];
/* Now do the relocation. */
- if (reloc)
- {
- bfd_coff_reloc16_extra_cases (input_bfd, link_info, link_order,
- reloc, data, &src_address,
- &dst_address);
- }
+ if (reloc
+ && !bfd_coff_reloc16_extra_cases (input_bfd, link_info,
+ link_order, reloc, data,
+ &src_address, &dst_address))
+ goto error_return;
}
}
free (reloc_vector);