[binutils-gdb] sanity check score reloc functions
Alan Modra
amodra@sourceware.org
Tue Jan 27 05:26:47 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ba89097403add5d68424fe542a18ea00d72240df
commit ba89097403add5d68424fe542a18ea00d72240df
Author: Alan Modra <amodra@gmail.com>
Date: Tue Jan 27 15:30:14 2026 +1030
sanity check score reloc functions
Some of these already did some sanity checking, but
bfd_reloc_offset_in_range is better since it takes into account the
relocation field size too.
* elf32-score.c (score_elf_hi16_reloc, score_elf_lo16_reloc),
(score_elf_gprel15_with_gp, gprel32_with_gp),
(score_elf_got_lo16_reloc): Use bfd_reloc_offset_in_range to
sanity check reloc addresses.
* elf32-score7.c (score_elf_hi16_reloc, score_elf_lo16_reloc),
(score_elf_gprel15_with_gp, gprel32_with_gp),
(score_elf_got_lo16_reloc): Likewise.
Diff:
---
bfd/elf32-score.c | 34 ++++++++++++++++++++++------------
bfd/elf32-score7.c | 36 ++++++++++++++++++++++++------------
2 files changed, 46 insertions(+), 24 deletions(-)
diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c
index 706732768e5..125b2cc804b 100644
--- a/bfd/elf32-score.c
+++ b/bfd/elf32-score.c
@@ -312,6 +312,10 @@ score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
bfd *output_bfd ATTRIBUTE_UNUSED,
char **error_message ATTRIBUTE_UNUSED)
{
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
+ return bfd_reloc_outofrange;
+
score_elf_section_data (input_section)->hi16_rel_addr
= (bfd_byte *) data + reloc_entry->address;
return bfd_reloc_ok;
@@ -331,14 +335,16 @@ score_elf_lo16_reloc (bfd *abfd,
unsigned long hi16_offset, hi16_value, uvalue;
bfd_byte *hi16_rel_addr;
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
+ return bfd_reloc_outofrange;
+
hi16_rel_addr = score_elf_section_data (input_section)->hi16_rel_addr;
hi16_value = hi16_rel_addr ? score_bfd_get_32 (abfd, hi16_rel_addr) : 0;
hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
val = reloc_entry->addend;
- if (reloc_entry->address > input_section->size)
- return bfd_reloc_outofrange;
uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
if (hi16_rel_addr)
{
@@ -411,7 +417,7 @@ static bfd_reloc_status_type
score_elf_final_gp (bfd *output_bfd,
asymbol *symbol,
bool relocatable,
- char **error_message,
+ char **error_message,
bfd_vma *pgp)
{
if (bfd_is_und_section (symbol->section)
@@ -448,12 +454,13 @@ score_elf_gprel15_with_gp (bfd *abfd,
arelent *reloc_entry,
asection *input_section,
bool relocateable,
- void * data,
+ void *data,
bfd_vma gp ATTRIBUTE_UNUSED)
{
unsigned long insn;
- if (reloc_entry->address > input_section->size)
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
return bfd_reloc_outofrange;
insn = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
@@ -477,6 +484,10 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
bfd_vma relocation;
bfd_vma val;
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
+ return bfd_reloc_outofrange;
+
if (bfd_is_com_section (symbol->section))
relocation = 0;
else
@@ -485,9 +496,6 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
relocation += symbol->section->output_section->vma;
relocation += symbol->section->output_offset;
- if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
- return bfd_reloc_outofrange;
-
/* Set val to the offset into the section or symbol. */
val = reloc_entry->addend;
@@ -516,7 +524,7 @@ static bfd_reloc_status_type
score_elf_gprel15_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol,
- void * data,
+ void *data,
asection *input_section,
bfd *output_bfd,
char **error_message)
@@ -610,7 +618,7 @@ static bfd_reloc_status_type
score_elf_got_lo16_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol ATTRIBUTE_UNUSED,
- void * data,
+ void *data,
asection *input_section,
bfd *output_bfd ATTRIBUTE_UNUSED,
char **error_message ATTRIBUTE_UNUSED)
@@ -620,14 +628,16 @@ score_elf_got_lo16_reloc (bfd *abfd,
signed long hi16_offset, hi16_value, uvalue;
bfd_byte *hi16_rel_addr;
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
+ return bfd_reloc_outofrange;
+
hi16_rel_addr = score_elf_section_data (input_section)->hi16_rel_addr;
hi16_value = hi16_rel_addr ? score_bfd_get_32 (abfd, hi16_rel_addr) : 0;
hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
val = reloc_entry->addend;
- if (reloc_entry->address > input_section->size)
- return bfd_reloc_outofrange;
uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
if (hi16_rel_addr)
{
diff --git a/bfd/elf32-score7.c b/bfd/elf32-score7.c
index 91610240462..387421f18ff 100644
--- a/bfd/elf32-score7.c
+++ b/bfd/elf32-score7.c
@@ -206,11 +206,15 @@ static bfd_reloc_status_type
score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
arelent *reloc_entry,
asymbol *symbol ATTRIBUTE_UNUSED,
- void * data,
- asection *input_section ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section,
bfd *output_bfd ATTRIBUTE_UNUSED,
char **error_message ATTRIBUTE_UNUSED)
{
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
+ return bfd_reloc_outofrange;
+
score_elf_section_data (input_section)->hi16_rel_addr
= (bfd_byte *) data + reloc_entry->address;
return bfd_reloc_ok;
@@ -220,7 +224,7 @@ static bfd_reloc_status_type
score_elf_lo16_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol ATTRIBUTE_UNUSED,
- void * data,
+ void *data,
asection *input_section,
bfd *output_bfd ATTRIBUTE_UNUSED,
char **error_message ATTRIBUTE_UNUSED)
@@ -230,14 +234,16 @@ score_elf_lo16_reloc (bfd *abfd,
unsigned long hi16_offset, hi16_value, uvalue;
bfd_byte *hi16_rel_addr;
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
+ return bfd_reloc_outofrange;
+
hi16_rel_addr = score_elf_section_data (input_section)->hi16_rel_addr;
hi16_value = hi16_rel_addr ? bfd_get_32 (abfd, hi16_rel_addr) : 0;
hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
val = reloc_entry->addend;
- if (reloc_entry->address > input_section->size)
- return bfd_reloc_outofrange;
uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
if (hi16_rel_addr)
{
@@ -348,12 +354,13 @@ score_elf_gprel15_with_gp (bfd *abfd,
arelent *reloc_entry,
asection *input_section,
bool relocateable,
- void * data,
+ void *data,
bfd_vma gp ATTRIBUTE_UNUSED)
{
unsigned long insn;
- if (reloc_entry->address > input_section->size)
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
return bfd_reloc_outofrange;
insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
@@ -377,6 +384,10 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
bfd_vma relocation;
bfd_vma val;
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
+ return bfd_reloc_outofrange;
+
if (bfd_is_com_section (symbol->section))
relocation = 0;
else
@@ -385,9 +396,6 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
relocation += symbol->section->output_section->vma;
relocation += symbol->section->output_offset;
- if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
- return bfd_reloc_outofrange;
-
/* Set val to the offset into the section or symbol. */
val = reloc_entry->addend;
@@ -416,7 +424,7 @@ static bfd_reloc_status_type
score_elf_gprel15_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol,
- void * data,
+ void *data,
asection *input_section,
bfd *output_bfd,
char **error_message)
@@ -513,7 +521,7 @@ static bfd_reloc_status_type
score_elf_got_lo16_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol ATTRIBUTE_UNUSED,
- void * data,
+ void *data,
asection *input_section,
bfd *output_bfd ATTRIBUTE_UNUSED,
char **error_message ATTRIBUTE_UNUSED)
@@ -523,6 +531,10 @@ score_elf_got_lo16_reloc (bfd *abfd,
signed long hi16_offset, hi16_value, uvalue;
bfd_byte *hi16_rel_addr;
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section,
+ reloc_entry->address))
+ return bfd_reloc_outofrange;
+
hi16_rel_addr = score_elf_section_data (input_section)->hi16_rel_addr;
hi16_value = hi16_rel_addr ? bfd_get_32 (abfd, hi16_rel_addr) : 0;
hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
More information about the Binutils-cvs
mailing list