This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Commit: MSP430: Fix computing SYM_DIFF relocs in very small sections.
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Fri, 05 Jun 2015 16:40:25 +0100
- Subject: Commit: MSP430: Fix computing SYM_DIFF relocs in very small sections.
- Authentication-results: sourceware.org; auth=none
Hi Guys,
I am checking in the patch below to fix a minor problem with the
MSP430 linker, when it tries to compute the value for a SYM_DIFF reloc
in a very small section. if the section is small enough the generic
reloc handler will complain about the reloc being too big, even though
it does not actually matter. So the patch adds a special handler just
for this reloc.
Cheers
Nick
bfd/ChangeLog
2015-06-05 Nick Clifton <nickc@redhat.com>
* elf32-msp430.c (rl78_sym_diff_handler): New function.
(msp430_howto_table): Use the new function for the SYM_DIFF reloc.
(msp430x_howto_table): Likewise.
diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c
index fdab3d3..bc54b22 100644
--- a/bfd/elf32-msp430.c
+++ b/bfd/elf32-msp430.c
@@ -26,6 +26,31 @@
#include "elf-bfd.h"
#include "elf/msp430.h"
+static bfd_reloc_status_type
+rl78_sym_diff_handler (bfd * abfd,
+ arelent * reloc,
+ asymbol * sym ATTRIBUTE_UNUSED,
+ void * addr ATTRIBUTE_UNUSED,
+ asection * input_sec,
+ bfd * out_bfd ATTRIBUTE_UNUSED,
+ char ** error_message ATTRIBUTE_UNUSED)
+{
+ bfd_size_type octets;
+ octets = reloc->address * bfd_octets_per_byte (abfd);
+
+ /* Catch the case where bfd_install_relocation would return
+ bfd_reloc_outofrange because the SYM_DIFF reloc is being used in a very
+ small section. It does not actually matter if this happens because all
+ that SYM_DIFF is compute a (4-byte) value. A second reloc then uses
+ this value, and it is that reloc that must fit into the section.
+
+ This happens in eg, gcc/testsuite/gcc.c-torture/compile/labels-3.c. */
+ if ((octets + bfd_get_reloc_size (reloc->howto))
+ > bfd_get_section_limit_octets (abfd, input_sec))
+ return bfd_reloc_ok;
+ return bfd_reloc_continue;
+}
+
static reloc_howto_type elf_msp430_howto_table[] =
{
HOWTO (R_MSP430_NONE, /* type */
@@ -185,7 +210,7 @@ static reloc_howto_type elf_msp430_howto_table[] =
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
- NULL, /* special handler. */
+ rl78_sym_diff_handler, /* special handler. */
"R_MSP430_SYM_DIFF", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
@@ -488,7 +513,7 @@ static reloc_howto_type elf_msp430x_howto_table[] =
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
- NULL, /* special handler. */
+ rl78_sym_diff_handler, /* special handler. */
"R_MSP430X_SYM_DIFF", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */