diff options
59 files changed, 200 insertions, 73 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2705feb1673..7eedaae66cd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,71 @@ +2012-05-07 Maciej W. Rozycki <macro@linux-mips.org> + + * 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. + 2012-05-05 Alan Modra <amodra@gmail.com> PR ld/14052 diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 5af924c4c60..a016d473c26 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2408,10 +2408,11 @@ extern asection _bfd_elf_large_com_section; 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_section; 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; \ } diff --git a/bfd/elf-m10200.c b/bfd/elf-m10200.c index 4c6564b4214..a46c86dcb21 100644 --- a/bfd/elf-m10200.c +++ b/bfd/elf-m10200.c @@ -403,7 +403,7 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (sec != NULL && 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; diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index adbb0091924..8b5afa56d7d 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -2117,7 +2117,7 @@ mn10300_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index f5bad392dae..bc600c22a38 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -10483,7 +10483,7 @@ elf32_arm_relocate_section (bfd * output_bfd, if (sec != NULL && 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) { diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 41ab3f62b56..9fb72f583f5 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -1192,7 +1192,7 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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; diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c index e5d94018076..c7f634b774e 100644 --- a/bfd/elf32-bfin.c +++ b/bfd/elf32-bfin.c @@ -1446,7 +1446,7 @@ bfin_relocate_section (bfd * output_bfd, if (sec != NULL && 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_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c index a162191c8bd..56d1c542789 100644 --- a/bfd/elf32-cr16.c +++ b/bfd/elf32-cr16.c @@ -1433,7 +1433,7 @@ elf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (sec != NULL && 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; diff --git a/bfd/elf32-cr16c.c b/bfd/elf32-cr16c.c index 9dcbddebb16..ea227016aee 100644 --- a/bfd/elf32-cr16c.c +++ b/bfd/elf32-cr16c.c @@ -725,7 +725,7 @@ elf32_cr16c_relocate_section (bfd *output_bfd, if (sec != NULL && 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) { diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index 370bf1abf85..1f7d20d44c6 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -1186,7 +1186,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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; diff --git a/bfd/elf32-crx.c b/bfd/elf32-crx.c index d36c0ea95fd..b4cbd77c682 100644 --- a/bfd/elf32-crx.c +++ b/bfd/elf32-crx.c @@ -875,7 +875,7 @@ elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (sec != NULL && 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; diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c index e0e93c8470f..246e5f51650 100644 --- a/bfd/elf32-d10v.c +++ b/bfd/elf32-d10v.c @@ -465,7 +465,7 @@ elf32_d10v_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-epiphany.c b/bfd/elf32-epiphany.c index 7330204a17f..b427ef33e09 100644 --- a/bfd/elf32-epiphany.c +++ b/bfd/elf32-epiphany.c @@ -526,7 +526,7 @@ epiphany_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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; diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c index 462e51bcf57..89aab8870c4 100644 --- a/bfd/elf32-fr30.c +++ b/bfd/elf32-fr30.c @@ -580,7 +580,7 @@ fr30_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (sec != NULL && 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; diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c index 57de3c02f21..05e9c58b4af 100644 --- a/bfd/elf32-frv.c +++ b/bfd/elf32-frv.c @@ -2814,7 +2814,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section, if (sec != NULL && 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; diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c index 28fab3269ee..758dc75c1a1 100644 --- a/bfd/elf32-h8300.c +++ b/bfd/elf32-h8300.c @@ -462,7 +462,7 @@ elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (sec != NULL && 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; diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 82a0db611d1..8d86cb85f85 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -3736,8 +3736,8 @@ elf32_hppa_relocate_section (bfd *output_bfd, if (sym_sec != NULL && 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) diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c index 2022aaffcaf..4d1d037e509 100644 --- a/bfd/elf32-i370.c +++ b/bfd/elf32-i370.c @@ -1133,7 +1133,7 @@ i370_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 832ad899805..270a7c7ee8a 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -3192,7 +3192,7 @@ elf_i386_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-i860.c b/bfd/elf32-i860.c index b890384bc86..f50e51b24f7 100644 --- a/bfd/elf32-i860.c +++ b/bfd/elf32-i860.c @@ -1131,7 +1131,7 @@ elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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; diff --git a/bfd/elf32-ip2k.c b/bfd/elf32-ip2k.c index fe9461543d5..d696a27e299 100644 --- a/bfd/elf32-ip2k.c +++ b/bfd/elf32-ip2k.c @@ -1438,7 +1438,7 @@ ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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; diff --git a/bfd/elf32-iq2000.c b/bfd/elf32-iq2000.c index fd3b2639488..079a9621943 100644 --- a/bfd/elf32-iq2000.c +++ b/bfd/elf32-iq2000.c @@ -635,7 +635,7 @@ iq2000_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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; diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c index bd560e1ba32..b18f08f459f 100644 --- a/bfd/elf32-lm32.c +++ b/bfd/elf32-lm32.c @@ -895,7 +895,7 @@ lm32_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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) { diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c index 84cd6d37a70..e11a2e579de 100644 --- a/bfd/elf32-m32c.c +++ b/bfd/elf32-m32c.c @@ -436,7 +436,7 @@ m32c_elf_relocate_section if (sec != NULL && 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) { diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index 7ab7b601816..763c90d5c64 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -2615,7 +2615,7 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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) { diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c index f1d45860da6..f5762a481aa 100644 --- a/bfd/elf32-m68hc1x.c +++ b/bfd/elf32-m68hc1x.c @@ -986,7 +986,7 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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) { diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 78d7464f427..bba4c791b27 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -3724,7 +3724,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, if (sec != NULL && 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; diff --git a/bfd/elf32-mcore.c b/bfd/elf32-mcore.c index c0769a89dd0..727969728ed 100644 --- a/bfd/elf32-mcore.c +++ b/bfd/elf32-mcore.c @@ -468,7 +468,7 @@ mcore_elf_relocate_section (bfd * output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-mep.c b/bfd/elf32-mep.c index 9c53f3dfbd1..f356fd06ffe 100644 --- a/bfd/elf32-mep.c +++ b/bfd/elf32-mep.c @@ -502,7 +502,7 @@ mep_elf_relocate_section if (sec != NULL && 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; diff --git a/bfd/elf32-moxie.c b/bfd/elf32-moxie.c index bc1d4c7ae59..c1a793e50f2 100644 --- a/bfd/elf32-moxie.c +++ b/bfd/elf32-moxie.c @@ -252,7 +252,7 @@ moxie_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c index c79c4745251..c0459f43945 100644 --- a/bfd/elf32-msp430.c +++ b/bfd/elf32-msp430.c @@ -456,7 +456,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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; diff --git a/bfd/elf32-mt.c b/bfd/elf32-mt.c index 7d187747a5c..c03d8f429d4 100644 --- a/bfd/elf32-mt.c +++ b/bfd/elf32-mt.c @@ -356,7 +356,7 @@ mt_elf_relocate_section if (sec != NULL && 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; diff --git a/bfd/elf32-openrisc.c b/bfd/elf32-openrisc.c index 1c9e14ad3c7..2b002abcc73 100644 --- a/bfd/elf32-openrisc.c +++ b/bfd/elf32-openrisc.c @@ -375,7 +375,7 @@ openrisc_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index ca6df26e59e..5716b8247f8 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -6888,7 +6888,7 @@ ppc_elf_relocate_section (bfd *output_bfd, 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) diff --git a/bfd/elf32-rl78.c b/bfd/elf32-rl78.c index 2806cd3c82d..c454e5f8412 100644 --- a/bfd/elf32-rl78.c +++ b/bfd/elf32-rl78.c @@ -473,7 +473,7 @@ rl78_elf_relocate_section if (sec != NULL && 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) { diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c index 942d4e09d0c..e74f5465d91 100644 --- a/bfd/elf32-rx.c +++ b/bfd/elf32-rx.c @@ -523,7 +523,7 @@ rx_elf_relocate_section if (sec != NULL && 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) { diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 4b2b38001e7..8b90c8cb71c 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -2302,7 +2302,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, if (sec != NULL && 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; diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c index bb945410614..eb3002e9526 100644 --- a/bfd/elf32-score.c +++ b/bfd/elf32-score.c @@ -2674,7 +2674,7 @@ s3_bfd_score_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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) { diff --git a/bfd/elf32-score7.c b/bfd/elf32-score7.c index b0eb56cf878..b18991b4129 100644 --- a/bfd/elf32-score7.c +++ b/bfd/elf32-score7.c @@ -2445,7 +2445,7 @@ s7_bfd_score_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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) { diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 2ce0875e69e..c7a8b2b6985 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -4242,7 +4242,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (sec != NULL && 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; diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index f5bc3ecdf49..28628f83add 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -4898,7 +4898,7 @@ spu_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c index 4d7f9237cec..1aec02883e5 100644 --- a/bfd/elf32-tic6x.c +++ b/bfd/elf32-tic6x.c @@ -2329,7 +2329,7 @@ elf32_tic6x_relocate_section (bfd *output_bfd, if (sec != NULL && 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) { diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c index 23073c1e522..88c1326fdd5 100644 --- a/bfd/elf32-tilepro.c +++ b/bfd/elf32-tilepro.c @@ -2876,7 +2876,7 @@ tilepro_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (sec != NULL && 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; diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index 236a0b28bc1..11fbbb4cbc3 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -2096,7 +2096,7 @@ v850_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index f1b5d760da0..d55cdc5ef63 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -1445,7 +1445,7 @@ elf_vax_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf32-xc16x.c b/bfd/elf32-xc16x.c index dc8cab562bc..b7e0d412d50 100644 --- a/bfd/elf32-xc16x.c +++ b/bfd/elf32-xc16x.c @@ -389,7 +389,7 @@ elf32_xc16x_relocate_section (bfd *output_bfd, 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) diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c index 57445ba6f89..d6a48bf7bbe 100644 --- a/bfd/elf32-xstormy16.c +++ b/bfd/elf32-xstormy16.c @@ -827,7 +827,7 @@ xstormy16_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNU if (sec != NULL && 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; diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index cfbdff0bd89..c6c9c12ccf1 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -2658,7 +2658,7 @@ elf_xtensa_relocate_section (bfd *output_bfd, if (sec != NULL && 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) { diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 495b6014949..c8d76a0be66 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -4110,8 +4110,8 @@ elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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) @@ -4319,7 +4319,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (sec != NULL && 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; diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index b3a5e24ff08..e3de2a6c60c 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -3922,7 +3922,7 @@ elf64_hppa_relocate_section (bfd *output_bfd, if (sym_sec != NULL && 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; diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index fd5921a6608..5366df4f6fe 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -1478,7 +1478,7 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (sec != NULL && 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) { diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 0d6dd99e543..433fabf4432 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -12275,8 +12275,8 @@ ppc64_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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) diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index c3ec24c264d..cc0e473119a 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -2246,7 +2246,7 @@ elf_s390_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index 60f13cdf42a..e041bdae418 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -1663,7 +1663,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec != NULL && 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; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index e91324639fe..de7fd6f957f 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -3145,7 +3145,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c index a1294ff297e..fdefb03ca07 100644 --- a/bfd/elfnn-ia64.c +++ b/bfd/elfnn-ia64.c @@ -3913,7 +3913,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd, if (sym_sec != NULL && 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; diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 35109381ab0..6dd0592917d 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -9324,6 +9324,55 @@ mips_elf_adjust_addend (bfd *output_bfd, struct bfd_link_info *info, } } +/* 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 *output_bfd, struct bfd_link_info *info, } if (sec != NULL && 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)) { diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 9a0a1a4e68a..06f02bfff4c 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -3013,7 +3013,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, if (sec != NULL && 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; diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c index d87edf504a3..9939228fbce 100644 --- a/bfd/elfxx-tilegx.c +++ b/bfd/elfxx-tilegx.c @@ -3142,7 +3142,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (sec != NULL && 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; |