This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] MIPS/BFD: Handle linker garbage collection with n64 relocs
On Tue, 10 Apr 2012, Richard Sandiford wrote:
> > The fix below removes the problem and causes no regressions with said
> > modified mips64-linux-gnu configuration nor a pristine mips-linux-gnu one.
> > The RELOC_AGAINST_DISCARDED_SECTION macro has a bit weird semantics, it's
> > not really intended to behave like a function call, and I think there's
> > little point in making it do (e.g. adding argument protection throughout),
> > if at all possible. Therefore some unusual syntactic sugar had to be
> > added around the macro reference, so that its expansion can be executed
> > three times consecutively over a relocation triplet. This is explained in
> > the comment included with the change itself. The new code also avoids a
> > duplicate call to MIPS_ELF_RTYPE_TO_HOWTO, hence a bit unusual form of the
> > loop introduced.
>
> I think it'd be better (and cleaner) to handle
> bed->s->int_rels_per_ext_rel in RELOC_AGAINST_DISCARDED_SECTION
> instead.
Hmm, good point, really.
> The patch as posted isn't quite correct, because the "middle"
> relocation in a triple doesn't define a relocation field.
> E.g. for the common %hi(%neg(%gp_rel(...))) case, the middle
> %neg is a 64-bit relocation, but we don't want R_A_D_S to clear
> a 64-bit field.
This is a good observation as well. I think this should be handled in a
general manner and given that it's the final relocation (outermost percent
operator) that determines the output field of the whole relocation
operation, it's that one that should be picked for this purpose -- which
is the last non-null one.
So here's the resulting change, but obviously because of the API change
of RELOC_AGAINST_DISCARDED_SECTION it now touches virtually everything.
As the selection of the correct relocation for output relocatable field
clearing is target-specific (I think; let me know it you have reasons to
believe otherwise), I have decided there is no feasible way to do it
within RELOC_AGAINST_DISCARDED_SECTION, and decided to pass the right
HOWTO and the REL-relative index of the relocation that HOWTO applies to
as extra arguments to RELOC_AGAINST_DISCARDED_SECTION.
Also I've decided to keep mips_reloc_against_discarded_section to avoid
stretching _bfd_mips_elf_relocate_section even further as it's IMHO
already beyond a reasonable size for a function, but I can fold it back if
you preferred it that way.
This fixes the original problem just as the previous version did. OK in
this form?
2012-04-28 Maciej W. Rozycki <macro@linux-mips.org>
bfd/
* elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Handle compound
relocations.
* elfxx-mips.c (mips_reloc_against_discarded_section): New
function.
(_bfd_mips_elf_relocate_section): Call it, in place of
RELOC_AGAINST_DISCARDED_SECTION.
* elf-m10200.c (mn10200_elf_relocate_section): Update arguments
to RELOC_AGAINST_DISCARDED_SECTION.
* elf-m10300.c (mn10300_elf_relocate_section): Likewise.
* elf32-arm.c (elf32_arm_relocate_section): Likewise.
* elf32-avr.c (elf32_avr_relocate_section): Likewise.
* elf32-bfin.c (bfin_relocate_section): Likewise.
(bfinfdpic_relocate_section): Likewise.
* elf32-cr16.c (elf32_cr16_relocate_section): Likewise.
* elf32-cr16c.c (elf32_cr16c_relocate_section): Likewise.
* elf32-cris.c (cris_elf_relocate_section): Likewise.
* elf32-crx.c (elf32_crx_relocate_section): Likewise.
* elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
* elf32-epiphany.c (epiphany_elf_relocate_section): Likewise.
* elf32-fr30.c (fr30_elf_relocate_section): Likewise.
* elf32-frv.c (elf32_frv_relocate_section): Likewise.
* elf32-h8300.c (elf32_h8_relocate_section): Likewise.
* elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
* elf32-i370.c (i370_elf_relocate_section): Likewise.
* elf32-i386.c (elf_i386_relocate_section): Likewise.
* elf32-i860.c (elf32_i860_relocate_section): Likewise.
* elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
* elf32-iq2000.c (iq2000_elf_relocate_section): Likewise.
* elf32-lm32.c (lm32_elf_relocate_section): Likewise.
* elf32-m32c.c (m32c_elf_relocate_section): Likewise.
* elf32-m32r.c (m32r_elf_relocate_section): Likewise.
* elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Likewise.
* elf32-m68k.c (elf_m68k_relocate_section): Likewise.
* elf32-mcore.c (mcore_elf_relocate_section): Likewise.
* elf32-mep.c (mep_elf_relocate_section): Likewise.
* elf32-moxie.c (moxie_elf_relocate_section): Likewise.
* elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
* elf32-mt.c (mt_elf_relocate_section): Likewise.
* elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
* elf32-rl78.c (rl78_elf_relocate_section): Likewise.
* elf32-rx.c (rx_elf_relocate_section): Likewise.
* elf32-s390.c (elf_s390_relocate_section): Likewise.
* elf32-score.c (s3_bfd_score_elf_relocate_section): Likewise.
* elf32-score7.c (s7_bfd_score_elf_relocate_section): Likewise.
* elf32-sh.c (sh_elf_relocate_section): Likewise.
* elf32-spu.c (spu_elf_relocate_section): Likewise.
* elf32-tic6x.c (elf32_tic6x_relocate_section): Likewise.
* elf32-tilepro.c (tilepro_elf_relocate_section): Likewise.
* elf32-v850.c (v850_elf_relocate_section): Likewise.
* elf32-vax.c (elf_vax_relocate_section): Likewise.
* elf32-xc16x.c (elf32_xc16x_relocate_section): Likewise.
* elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
* elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
* elf64-alpha.c (elf64_alpha_relocate_section_r): Likewise.
(elf64_alpha_relocate_section): Likewise.
* elf64-hppa.c (elf64_hppa_relocate_section): Likewise.
* elf64-mmix.c (mmix_elf_relocate_section): Likewise.
* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
* elf64-s390.c (elf_s390_relocate_section): Likewise.
* elf64-sh64.c (sh_elf64_relocate_section): Likewise.
* elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
* elfnn-ia64.c (elfNN_ia64_relocate_section): Likewise.
* elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
* elfxx-tilegx.c (tilegx_elf_relocate_section): Likewise.
Maciej
binutils-mips64-reloc-discard.patch
Index: binutils/bfd/elf-bfd.h
===================================================================
--- binutils.orig/bfd/elf-bfd.h
+++ binutils/bfd/elf-bfd.h
@@ -2408,10 +2408,11 @@ extern asection _bfd_elf_large_com_secti
link, we remove such relocations. Otherwise, we just want the
section contents zeroed and avoid any special processing. */
#define RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd, input_section, \
- rel, relend, howto, contents) \
+ rel, count, relend, \
+ howto, index, contents) \
{ \
_bfd_clear_contents (howto, input_bfd, input_section, \
- contents + rel->r_offset); \
+ contents + rel[index].r_offset); \
\
if (info->relocatable \
&& (input_section->flags & SEC_DEBUGGING)) \
@@ -2423,23 +2424,28 @@ extern asection _bfd_elf_large_com_secti
rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \
\
/* Avoid empty output section. */ \
- if (rel_hdr->sh_size > rel_hdr->sh_entsize) \
+ if (rel_hdr->sh_size > count * rel_hdr->sh_entsize) \
{ \
- rel_hdr->sh_size -= rel_hdr->sh_entsize; \
+ rel_hdr->sh_size -= count * rel_hdr->sh_entsize; \
rel_hdr = _bfd_elf_single_rel_hdr (input_section); \
- rel_hdr->sh_size -= rel_hdr->sh_entsize; \
+ rel_hdr->sh_size -= count * rel_hdr->sh_entsize; \
\
- memmove (rel, rel + 1, (relend - rel - 1) * sizeof (*rel)); \
+ memmove (rel, rel + count, \
+ (relend - rel - count) * sizeof (*rel)); \
\
- input_section->reloc_count--; \
- relend--; \
+ input_section->reloc_count -= count; \
+ relend -= count; \
rel--; \
continue; \
} \
} \
\
- rel->r_info = 0; \
- rel->r_addend = 0; \
+ for (i = 0; i < count; i++) \
+ { \
+ rel[i].r_info = 0; \
+ rel[i].r_addend = 0; \
+ } \
+ rel += count - 1; \
continue; \
}
Index: binutils/bfd/elf-m10200.c
===================================================================
--- binutils.orig/bfd/elf-m10200.c
+++ binutils/bfd/elf-m10200.c
@@ -403,7 +403,7 @@ mn10200_elf_relocate_section (output_bfd
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf-m10300.c
===================================================================
--- binutils.orig/bfd/elf-m10300.c
+++ binutils/bfd/elf-m10300.c
@@ -2117,7 +2117,7 @@ mn10300_elf_relocate_section (bfd *outpu
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-arm.c
===================================================================
--- binutils.orig/bfd/elf32-arm.c
+++ binutils/bfd/elf32-arm.c
@@ -10382,7 +10382,7 @@ elf32_arm_relocate_section (bfd *
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-avr.c
===================================================================
--- binutils.orig/bfd/elf32-avr.c
+++ binutils/bfd/elf32-avr.c
@@ -1191,7 +1191,7 @@ elf32_avr_relocate_section (bfd *output_
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-bfin.c
===================================================================
--- binutils.orig/bfd/elf32-bfin.c
+++ binutils/bfd/elf32-bfin.c
@@ -1446,7 +1446,7 @@ bfin_relocate_section (bfd * output_bfd,
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
@@ -2667,7 +2667,7 @@ bfinfdpic_relocate_section (bfd * output
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-cr16.c
===================================================================
--- binutils.orig/bfd/elf32-cr16.c
+++ binutils/bfd/elf32-cr16.c
@@ -1433,7 +1433,7 @@ elf32_cr16_relocate_section (bfd *output
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-cr16c.c
===================================================================
--- binutils.orig/bfd/elf32-cr16c.c
+++ binutils/bfd/elf32-cr16c.c
@@ -725,7 +725,7 @@ elf32_cr16c_relocate_section (bfd *outpu
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-cris.c
===================================================================
--- binutils.orig/bfd/elf32-cris.c
+++ binutils/bfd/elf32-cris.c
@@ -1186,7 +1186,7 @@ cris_elf_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-crx.c
===================================================================
--- binutils.orig/bfd/elf32-crx.c
+++ binutils/bfd/elf32-crx.c
@@ -875,7 +875,7 @@ elf32_crx_relocate_section (bfd *output_
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-d10v.c
===================================================================
--- binutils.orig/bfd/elf32-d10v.c
+++ binutils/bfd/elf32-d10v.c
@@ -465,7 +465,7 @@ elf32_d10v_relocate_section (bfd *output
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-epiphany.c
===================================================================
--- binutils.orig/bfd/elf32-epiphany.c
+++ binutils/bfd/elf32-epiphany.c
@@ -526,7 +526,7 @@ epiphany_elf_relocate_section (bfd *outp
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-fr30.c
===================================================================
--- binutils.orig/bfd/elf32-fr30.c
+++ binutils/bfd/elf32-fr30.c
@@ -579,7 +579,7 @@ fr30_elf_relocate_section (output_bfd, i
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-frv.c
===================================================================
--- binutils.orig/bfd/elf32-frv.c
+++ binutils/bfd/elf32-frv.c
@@ -2814,7 +2814,7 @@ elf32_frv_relocate_section (output_bfd,
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-h8300.c
===================================================================
--- binutils.orig/bfd/elf32-h8300.c
+++ binutils/bfd/elf32-h8300.c
@@ -462,7 +462,7 @@ elf32_h8_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-hppa.c
===================================================================
--- binutils.orig/bfd/elf32-hppa.c
+++ binutils/bfd/elf32-hppa.c
@@ -3736,8 +3736,8 @@ elf32_hppa_relocate_section (bfd *output
if (sym_sec != NULL && elf_discarded_section (sym_sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rela, relend,
- elf_hppa_howto_table + r_type,
+ rela, 1, relend,
+ elf_hppa_howto_table + r_type, 0,
contents);
if (info->relocatable)
Index: binutils/bfd/elf32-i370.c
===================================================================
--- binutils.orig/bfd/elf32-i370.c
+++ binutils/bfd/elf32-i370.c
@@ -1133,7 +1133,7 @@ i370_elf_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-i386.c
===================================================================
--- binutils.orig/bfd/elf32-i386.c
+++ binutils/bfd/elf32-i386.c
@@ -3192,7 +3192,7 @@ elf_i386_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-i860.c
===================================================================
--- binutils.orig/bfd/elf32-i860.c
+++ binutils/bfd/elf32-i860.c
@@ -1130,7 +1130,7 @@ elf32_i860_relocate_section (bfd *output
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-ip2k.c
===================================================================
--- binutils.orig/bfd/elf32-ip2k.c
+++ binutils/bfd/elf32-ip2k.c
@@ -1438,7 +1438,7 @@ ip2k_elf_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-iq2000.c
===================================================================
--- binutils.orig/bfd/elf32-iq2000.c
+++ binutils/bfd/elf32-iq2000.c
@@ -635,7 +635,7 @@ iq2000_elf_relocate_section (bfd *
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-lm32.c
===================================================================
--- binutils.orig/bfd/elf32-lm32.c
+++ binutils/bfd/elf32-lm32.c
@@ -895,7 +895,7 @@ lm32_elf_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-m32c.c
===================================================================
--- binutils.orig/bfd/elf32-m32c.c
+++ binutils/bfd/elf32-m32c.c
@@ -436,7 +436,7 @@ m32c_elf_relocate_section
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-m32r.c
===================================================================
--- binutils.orig/bfd/elf32-m32r.c
+++ binutils/bfd/elf32-m32r.c
@@ -2615,7 +2615,7 @@ m32r_elf_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable && !use_rel)
{
Index: binutils/bfd/elf32-m68hc1x.c
===================================================================
--- binutils.orig/bfd/elf32-m68hc1x.c
+++ binutils/bfd/elf32-m68hc1x.c
@@ -986,7 +986,7 @@ elf32_m68hc11_relocate_section (bfd *out
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-m68k.c
===================================================================
--- binutils.orig/bfd/elf32-m68k.c
+++ binutils/bfd/elf32-m68k.c
@@ -3712,7 +3712,7 @@ elf_m68k_relocate_section (output_bfd, i
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-mcore.c
===================================================================
--- binutils.orig/bfd/elf32-mcore.c
+++ binutils/bfd/elf32-mcore.c
@@ -468,7 +468,7 @@ mcore_elf_relocate_section (bfd * output
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-mep.c
===================================================================
--- binutils.orig/bfd/elf32-mep.c
+++ binutils/bfd/elf32-mep.c
@@ -502,7 +502,7 @@ mep_elf_relocate_section
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-moxie.c
===================================================================
--- binutils.orig/bfd/elf32-moxie.c
+++ binutils/bfd/elf32-moxie.c
@@ -252,7 +252,7 @@ moxie_elf_relocate_section (bfd *output_
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-msp430.c
===================================================================
--- binutils.orig/bfd/elf32-msp430.c
+++ binutils/bfd/elf32-msp430.c
@@ -456,7 +456,7 @@ elf32_msp430_relocate_section (bfd * out
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-mt.c
===================================================================
--- binutils.orig/bfd/elf32-mt.c
+++ binutils/bfd/elf32-mt.c
@@ -356,7 +356,7 @@ mt_elf_relocate_section
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-openrisc.c
===================================================================
--- binutils.orig/bfd/elf32-openrisc.c
+++ binutils/bfd/elf32-openrisc.c
@@ -375,7 +375,7 @@ openrisc_elf_relocate_section (bfd *outp
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-ppc.c
===================================================================
--- binutils.orig/bfd/elf32-ppc.c
+++ binutils/bfd/elf32-ppc.c
@@ -6888,7 +6888,7 @@ ppc_elf_relocate_section (bfd *output_bf
if (r_type < R_PPC_max)
howto = ppc_elf_howto_table[r_type];
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
}
if (info->relocatable)
Index: binutils/bfd/elf32-rl78.c
===================================================================
--- binutils.orig/bfd/elf32-rl78.c
+++ binutils/bfd/elf32-rl78.c
@@ -473,7 +473,7 @@ rl78_elf_relocate_section
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-rx.c
===================================================================
--- binutils.orig/bfd/elf32-rx.c
+++ binutils/bfd/elf32-rx.c
@@ -523,7 +523,7 @@ rx_elf_relocate_section
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-s390.c
===================================================================
--- binutils.orig/bfd/elf32-s390.c
+++ binutils/bfd/elf32-s390.c
@@ -2302,7 +2302,7 @@ elf_s390_relocate_section (output_bfd, i
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-score.c
===================================================================
--- binutils.orig/bfd/elf32-score.c
+++ binutils/bfd/elf32-score.c
@@ -2674,7 +2674,7 @@ s3_bfd_score_elf_relocate_section (bfd *
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-score7.c
===================================================================
--- binutils.orig/bfd/elf32-score7.c
+++ binutils/bfd/elf32-score7.c
@@ -2445,7 +2445,7 @@ s7_bfd_score_elf_relocate_section (bfd *
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-sh.c
===================================================================
--- binutils.orig/bfd/elf32-sh.c
+++ binutils/bfd/elf32-sh.c
@@ -4239,7 +4239,7 @@ sh_elf_relocate_section (bfd *output_bfd
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-spu.c
===================================================================
--- binutils.orig/bfd/elf32-spu.c
+++ binutils/bfd/elf32-spu.c
@@ -4898,7 +4898,7 @@ spu_elf_relocate_section (bfd *output_bf
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-tic6x.c
===================================================================
--- binutils.orig/bfd/elf32-tic6x.c
+++ binutils/bfd/elf32-tic6x.c
@@ -2329,7 +2329,7 @@ elf32_tic6x_relocate_section (bfd *outpu
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf32-tilepro.c
===================================================================
--- binutils.orig/bfd/elf32-tilepro.c
+++ binutils/bfd/elf32-tilepro.c
@@ -2876,7 +2876,7 @@ tilepro_elf_relocate_section (bfd *outpu
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-v850.c
===================================================================
--- binutils.orig/bfd/elf32-v850.c
+++ binutils/bfd/elf32-v850.c
@@ -2095,7 +2095,7 @@ v850_elf_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-vax.c
===================================================================
--- binutils.orig/bfd/elf32-vax.c
+++ binutils/bfd/elf32-vax.c
@@ -1445,7 +1445,7 @@ elf_vax_relocate_section (bfd *output_bf
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-xc16x.c
===================================================================
--- binutils.orig/bfd/elf32-xc16x.c
+++ binutils/bfd/elf32-xc16x.c
@@ -389,7 +389,7 @@ elf32_xc16x_relocate_section (bfd *outpu
reloc_howto_type *howto;
howto = xc16x_reloc_type_lookup (input_bfd, r_type);
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
}
if (info->relocatable)
Index: binutils/bfd/elf32-xstormy16.c
===================================================================
--- binutils.orig/bfd/elf32-xstormy16.c
+++ binutils/bfd/elf32-xstormy16.c
@@ -827,7 +827,7 @@ xstormy16_elf_relocate_section (bfd *
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf32-xtensa.c
===================================================================
--- binutils.orig/bfd/elf32-xtensa.c
+++ binutils/bfd/elf32-xtensa.c
@@ -2658,7 +2658,7 @@ elf_xtensa_relocate_section (bfd *output
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf64-alpha.c
===================================================================
--- binutils.orig/bfd/elf64-alpha.c
+++ binutils/bfd/elf64-alpha.c
@@ -4109,8 +4109,8 @@ elf64_alpha_relocate_section_r (bfd *out
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend,
- elf64_alpha_howto_table + r_type,
+ rel, 1, relend,
+ elf64_alpha_howto_table + r_type, 0,
contents);
if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
@@ -4318,7 +4318,7 @@ elf64_alpha_relocate_section (bfd *outpu
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
addend = rel->r_addend;
value += addend;
Index: binutils/bfd/elf64-hppa.c
===================================================================
--- binutils.orig/bfd/elf64-hppa.c
+++ binutils/bfd/elf64-hppa.c
@@ -3921,7 +3921,7 @@ elf64_hppa_relocate_section (bfd *output
if (sym_sec != NULL && elf_discarded_section (sym_sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf64-mmix.c
===================================================================
--- binutils.orig/bfd/elf64-mmix.c
+++ binutils/bfd/elf64-mmix.c
@@ -1477,7 +1477,7 @@ mmix_elf_relocate_section (output_bfd, i
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
{
Index: binutils/bfd/elf64-ppc.c
===================================================================
--- binutils.orig/bfd/elf64-ppc.c
+++ binutils/bfd/elf64-ppc.c
@@ -12257,8 +12257,8 @@ ppc64_elf_relocate_section (bfd *output_
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend,
- ppc64_elf_howto_table[r_type],
+ rel, 1, relend,
+ ppc64_elf_howto_table[r_type], 0,
contents);
if (info->relocatable)
Index: binutils/bfd/elf64-s390.c
===================================================================
--- binutils.orig/bfd/elf64-s390.c
+++ binutils/bfd/elf64-s390.c
@@ -2246,7 +2246,7 @@ elf_s390_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf64-sh64.c
===================================================================
--- binutils.orig/bfd/elf64-sh64.c
+++ binutils/bfd/elf64-sh64.c
@@ -1663,7 +1663,7 @@ sh_elf64_relocate_section (bfd *output_b
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elf64-x86-64.c
===================================================================
--- binutils.orig/bfd/elf64-x86-64.c
+++ binutils/bfd/elf64-x86-64.c
@@ -3145,7 +3145,7 @@ elf_x86_64_relocate_section (bfd *output
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elfnn-ia64.c
===================================================================
--- binutils.orig/bfd/elfnn-ia64.c
+++ binutils/bfd/elfnn-ia64.c
@@ -3921,7 +3921,7 @@ elfNN_ia64_relocate_section (bfd *output
if (sym_sec != NULL && elf_discarded_section (sym_sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elfxx-mips.c
===================================================================
--- binutils.orig/bfd/elfxx-mips.c
+++ binutils/bfd/elfxx-mips.c
@@ -9324,6 +9324,55 @@ mips_elf_adjust_addend (bfd *output_bfd,
}
}
+/* Handle relocations against symbols from removed linkonce sections,
+ or sections discarded by a linker script. We use this wrapper around
+ RELOC_AGAINST_DISCARDED_SECTION to handle triplets of compound relocs
+ on 64-bit ELF targets. In this case for any relocation handled, which
+ always be the first in a triplet, the remaining two have to be processed
+ together with the first, even if they are R_MIPS_NONE. It is the symbol
+ index referred by the first reloc that applies to all the three and the
+ remaining two never refer to an object symbol. And it is the final
+ relocation (the last non-null one) that determines the output field of
+ the whole relocation so retrieve the corresponding howto structure for
+ the relocatable field to be cleared by RELOC_AGAINST_DISCARDED_SECTION.
+
+ Note that RELOC_AGAINST_DISCARDED_SECTION is a macro that uses "continue"
+ and therefore requires to be pasted in a loop. It also defines a block
+ and does not protect any of its arguments, hence the extra brackets. */
+
+static void
+mips_reloc_against_discarded_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd, asection *input_section,
+ Elf_Internal_Rela **rel,
+ const Elf_Internal_Rela **relend,
+ bfd_boolean rel_reloc,
+ reloc_howto_type *howto,
+ bfd_byte *contents)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+ int count = bed->s->int_rels_per_ext_rel;
+ unsigned int r_type;
+ int i;
+
+ for (i = count - 1; i > 0; i--)
+ {
+ r_type = ELF_R_TYPE (output_bfd, (*rel)[i].r_info);
+ if (r_type != R_MIPS_NONE)
+ {
+ howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type, !rel_reloc);
+ break;
+ }
+ }
+ do
+ {
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ (*rel), count, (*relend),
+ howto, i, contents);
+ }
+ while (0);
+}
+
/* Relocate a MIPS ELF section. */
bfd_boolean
@@ -9390,8 +9439,12 @@ _bfd_mips_elf_relocate_section (bfd *out
}
if (sec != NULL && elf_discarded_section (sec))
- RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ {
+ mips_reloc_against_discarded_section (output_bfd, info, input_bfd,
+ input_section, &rel, &relend,
+ rel_reloc, howto, contents);
+ continue;
+ }
if (r_type == R_MIPS_64 && ! NEWABI_P (input_bfd))
{
Index: binutils/bfd/elfxx-sparc.c
===================================================================
--- binutils.orig/bfd/elfxx-sparc.c
+++ binutils/bfd/elfxx-sparc.c
@@ -2965,7 +2965,7 @@ _bfd_sparc_elf_relocate_section (bfd *ou
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
Index: binutils/bfd/elfxx-tilegx.c
===================================================================
--- binutils.orig/bfd/elfxx-tilegx.c
+++ binutils/bfd/elfxx-tilegx.c
@@ -3142,7 +3142,7 @@ tilegx_elf_relocate_section (bfd *output
if (sec != NULL && elf_discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;