From f8df10f4f595488c4b6a8e49ffc99721d5aefdba Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 23 Nov 2001 12:17:21 +0000 Subject: [PATCH] * elf.c (_bfd_elf_rela_local_sym): New. * elflink.h (elf_link_input_bfd): Don't consider empty merged sections as removed in relocation tests. * elf-bfd.h (_bfd_elf_rela_local_sym): Add prototype. * elf32-i386.c (elf_i386_relocate_section): Handle relocs against STT_SECTION symbol of SHF_MERGE section. * elf32-arm.h (elf32_arm_relocate_section): Likewise. * elf32-avr.c (elf32_avr_relocate_section): Call _bfd_elf_rela_local_sym. * elf32-cris.c (cris_elf_relocate_section): Likewise. * elf32-d10v.c (elf32_d10v_relocate_section): Likewise. * elf32-fr30.c (fr30_final_link_relocate): 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-i860.c (elf32_i860_relocate_section): Likewise. * elf32-m32r.c (m32r_elf_relocate_section): Likewise. * elf32-m68k.c (elf_m68k_relocate_section): Likewise. * elf32-mcore.c (mcore_elf_relocate_section): Likewise. * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. * elf32-s390.c (elf_s390_relocate_section): Likewise. * elf32-sparc.c (elf32_sparc_relocate_section): Likewise. * elf32-v850.c (v850_elf_relocate_section): Likewise. * elf64-alpha.c (elf64_alpha_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-sparc.c (sparc64_elf_relocate_section): Likewise. * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. * elf-hppa.h (elf_hppa_relocate_section): Likewise. * elf-m10200.c (mn10200_elf_relocate_section): Likewise. * elf-m10300.c (mn10300_elf_relocate_section): Likewise. * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise. * elf32-sh.c (sh_elf_relocate_section): Likewise for !partial_inplace relocs. Handle relocs against STT_SECTION symbol of SHF_MERGE for partial_inplace relocs. * config/tc-alpha.c (tc_gen_reloc): Remove SEC_MERGE test. * write.c (adjust_reloc_syms): Don't handle relocs against SEC_MERGE section symbols specially. (fixup_segment): Likewise. --- bfd/ChangeLog | 40 ++++++++++++++++++++++++++++++++++++++++ bfd/elf-bfd.h | 2 ++ bfd/elf-hppa.h | 5 +---- bfd/elf-m10200.c | 4 +--- bfd/elf-m10300.c | 4 +--- bfd/elf.c | 32 ++++++++++++++++++++++++++++++++ bfd/elf32-arm.h | 42 ++++++++++++++++++++++++++++++++++++++++++ bfd/elf32-avr.c | 4 +--- bfd/elf32-cris.c | 4 +--- bfd/elf32-d10v.c | 6 ++---- bfd/elf32-fr30.c | 6 ++---- bfd/elf32-h8300.c | 4 +--- bfd/elf32-hppa.c | 5 +---- bfd/elf32-i370.c | 5 ++--- bfd/elf32-i386.c | 26 ++++++++++++++++++++++++++ bfd/elf32-i860.c | 4 +--- bfd/elf32-m32r.c | 7 +++++++ bfd/elf32-m68k.c | 4 +--- bfd/elf32-mcore.c | 7 +++---- bfd/elf32-openrisc.c | 5 ++--- bfd/elf32-ppc.c | 5 ++--- bfd/elf32-s390.c | 4 +--- bfd/elf32-sh.c | 34 ++++++++++++++++++++++++++++++++-- bfd/elf32-sparc.c | 4 +--- bfd/elf32-v850.c | 4 +--- bfd/elf64-alpha.c | 4 +--- bfd/elf64-mmix.c | 4 +--- bfd/elf64-ppc.c | 5 ++--- bfd/elf64-s390.c | 4 +--- bfd/elf64-sparc.c | 4 +--- bfd/elf64-x86-64.c | 4 +--- bfd/elflink.h | 7 +++++-- bfd/elfxx-ia64.c | 4 +--- gas/ChangeLog | 7 +++++++ gas/config/tc-alpha.c | 3 +-- gas/write.c | 10 ---------- 36 files changed, 227 insertions(+), 96 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5759b1b..0b3cd62 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,43 @@ +2001-11-23 Jakub Jelinek + + * elf.c (_bfd_elf_rela_local_sym): New. + * elflink.h (elf_link_input_bfd): Don't consider empty + merged sections as removed in relocation tests. + * elf-bfd.h (_bfd_elf_rela_local_sym): Add prototype. + * elf32-i386.c (elf_i386_relocate_section): Handle relocs + against STT_SECTION symbol of SHF_MERGE section. + * elf32-arm.h (elf32_arm_relocate_section): Likewise. + * elf32-avr.c (elf32_avr_relocate_section): Call + _bfd_elf_rela_local_sym. + * elf32-cris.c (cris_elf_relocate_section): Likewise. + * elf32-d10v.c (elf32_d10v_relocate_section): Likewise. + * elf32-fr30.c (fr30_final_link_relocate): 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-i860.c (elf32_i860_relocate_section): Likewise. + * elf32-m32r.c (m32r_elf_relocate_section): Likewise. + * elf32-m68k.c (elf_m68k_relocate_section): Likewise. + * elf32-mcore.c (mcore_elf_relocate_section): Likewise. + * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise. + * elf32-ppc.c (ppc_elf_relocate_section): Likewise. + * elf32-s390.c (elf_s390_relocate_section): Likewise. + * elf32-sparc.c (elf32_sparc_relocate_section): Likewise. + * elf32-v850.c (v850_elf_relocate_section): Likewise. + * elf64-alpha.c (elf64_alpha_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-sparc.c (sparc64_elf_relocate_section): Likewise. + * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. + * elf-hppa.h (elf_hppa_relocate_section): Likewise. + * elf-m10200.c (mn10200_elf_relocate_section): Likewise. + * elf-m10300.c (mn10300_elf_relocate_section): Likewise. + * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise. + * elf32-sh.c (sh_elf_relocate_section): Likewise for + !partial_inplace relocs. Handle relocs against STT_SECTION + symbol of SHF_MERGE for partial_inplace relocs. + 2001-11-21 Nick Clifton * po/Make-in (distclean): Move SRC-POTFILES.in and diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index b621327..026d8cf 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1140,6 +1140,8 @@ extern void _bfd_elf_fprintf_vma extern enum elf_reloc_type_class _bfd_elf_reloc_type_class PARAMS ((const Elf_Internal_Rela *)); +extern bfd_vma _bfd_elf_rela_local_sym + PARAMS ((bfd *, Elf_Internal_Sym *, asection *, Elf_Internal_Rela *)); extern unsigned long bfd_elf_hash PARAMS ((const char *)); diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h index e584bb9..cca760d 100644 --- a/bfd/elf-hppa.h +++ b/bfd/elf-hppa.h @@ -1325,10 +1325,7 @@ elf_hppa_relocate_section (output_bfd, info, input_bfd, input_section, /* This is a local symbol. */ sym = local_syms + r_symndx; sym_sec = local_sections[r_symndx]; - relocation = ((ELF_ST_TYPE (sym->st_info) == STT_SECTION - ? 0 : sym->st_value) - + sym_sec->output_offset - + sym_sec->output_section->vma); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel); /* If this symbol has an entry in the PA64 dynamic hash table, then get it. */ diff --git a/bfd/elf-m10200.c b/bfd/elf-m10200.c index b73ebec..aebae33 100644 --- a/bfd/elf-m10200.c +++ b/bfd/elf-m10200.c @@ -394,9 +394,7 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index ff88350..9bec736 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -610,9 +610,7 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf.c b/bfd/elf.c index 7bffecd..51ae3db 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -6370,3 +6370,35 @@ _bfd_elf_reloc_type_class (rela) { return reloc_class_normal; } + +/* For RELA architectures, return what the relocation value for + relocation against a local symbol. */ + +bfd_vma +_bfd_elf_rela_local_sym (abfd, sym, sec, rel) + bfd *abfd; + Elf_Internal_Sym *sym; + asection *sec; + Elf_Internal_Rela *rel; +{ + bfd_vma relocation; + + relocation = (sec->output_section->vma + + sec->output_offset + + sym->st_value); + if ((sec->flags & SEC_MERGE) + && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + { + asection *msec; + + msec = sec; + rel->r_addend = + _bfd_merged_section_offset (abfd, &msec, + elf_section_data (sec)->merge_info, + sym->st_value + rel->r_addend, + (bfd_vma) 0) + - relocation; + rel->r_addend += msec->output_section->vma + msec->output_offset; + } + return relocation; +} diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 83a2d6d..6bd1fbb 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -1858,9 +1858,51 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; +#ifdef USE_REL relocation = (sec->output_section->vma + sec->output_offset + sym->st_value); + if ((sec->flags & SEC_MERGE) + && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + { + asection *msec; + bfd_vma addend, value; + + if (howto->rightshift) + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): %s relocation against SEC_MERGE section"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, howto->name); + return false; + } + + value = bfd_get_32 (input_bfd, contents + rel->r_offset); + + /* Get the (signed) value from the instruction. */ + addend = value & howto->src_mask; + if (addend & ((howto->src_mask + 1) >> 1)) + { + bfd_signed_vma mask; + + mask = -1; + mask &= ~ howto->src_mask; + addend |= mask; + } + msec = sec; + addend = + _bfd_merged_section_offset (output_bfd, &msec, + elf_section_data (sec)->merge_info, + sym->st_value + addend, (bfd_vma) 0) + - relocation; + addend += msec->output_section->vma + msec->output_offset; + value = (value & ~ howto->dst_mask) | (addend & howto->dst_mask); + bfd_put_32 (input_bfd, value, contents + rel->r_offset); + } +#else + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); +#endif } else { diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 1081b51..3efd248 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -778,9 +778,7 @@ elf32_avr_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections [r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index f8f0725..674a7b1 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -870,9 +870,7 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections [r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); symname = (bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name)); diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c index 5b6ed27..9ec0aa5 100644 --- a/bfd/elf32-d10v.c +++ b/bfd/elf32-d10v.c @@ -356,7 +356,7 @@ elf32_d10v_check_relocs (abfd, info, sec, relocs) static boolean elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, local_syms, local_sections) - bfd *output_bfd ATTRIBUTE_UNUSED; + bfd *output_bfd; struct bfd_link_info *info; bfd *input_bfd; asection *input_section; @@ -422,9 +422,7 @@ elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c index 320a3c1..86f70ef 100644 --- a/bfd/elf32-fr30.c +++ b/bfd/elf32-fr30.c @@ -503,7 +503,7 @@ fr30_final_link_relocate (howto, input_bfd, input_section, contents, rel, reloca static boolean fr30_elf_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, local_syms, local_sections) - bfd * output_bfd ATTRIBUTE_UNUSED; + bfd * output_bfd; struct bfd_link_info * info; bfd * input_bfd; asection * input_section; @@ -571,9 +571,7 @@ fr30_elf_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections [r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c index 0c37002..5ca6955 100644 --- a/bfd/elf32-h8300.c +++ b/bfd/elf32-h8300.c @@ -473,9 +473,7 @@ elf32_h8_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 481bde7..9f13576 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -3650,10 +3650,7 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, /* This is a local symbol, h defaults to NULL. */ sym = local_syms + r_symndx; sym_sec = local_sections[r_symndx]; - relocation = ((ELF_ST_TYPE (sym->st_info) == STT_SECTION - ? 0 : sym->st_value) - + sym_sec->output_offset - + sym_sec->output_section->vma); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel); } else { diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c index 3f9c9c1..3b9ad34 100644 --- a/bfd/elf32-i370.c +++ b/bfd/elf32-i370.c @@ -1367,9 +1367,8 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, sec = local_sections[r_symndx]; sym_name = ""; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + addend = rel->r_addend; } else { diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 238772e..9299b1c 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1770,6 +1770,32 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, relocation = (sec->output_section->vma + sec->output_offset + sym->st_value); + if ((sec->flags & SEC_MERGE) + && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + { + asection *msec; + bfd_vma addend; + + if (howto->src_mask != 0xffffffff) + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): %s relocation against SEC_MERGE section"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, howto->name); + return false; + } + + addend = bfd_get_32 (input_bfd, contents + rel->r_offset); + msec = sec; + addend = + _bfd_merged_section_offset (output_bfd, &msec, + elf_section_data (sec)->merge_info, + sym->st_value + addend, (bfd_vma) 0) + - relocation; + addend += msec->output_section->vma + msec->output_offset; + bfd_put_32 (input_bfd, addend, contents + rel->r_offset); + } } else { diff --git a/bfd/elf32-i860.c b/bfd/elf32-i860.c index 142d138..7b5d052 100644 --- a/bfd/elf32-i860.c +++ b/bfd/elf32-i860.c @@ -934,9 +934,7 @@ elf32_i860_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections [r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index eb2237f..214fed1 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -1106,9 +1106,16 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, sym = local_syms + r_symndx; sec = local_sections[r_symndx]; sym_name = ""; +#ifndef USE_REL + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + addend = rel->r_addend; +#else + /* FIXME: This won't handle local relocations against SEC_MERGE + symbols. See elf32-i386.c for how to do this. */ relocation = (sec->output_section->vma + sec->output_offset + sym->st_value); +#endif } else { diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index a613024..68f4a23 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -1389,9 +1389,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf32-mcore.c b/bfd/elf32-mcore.c index 669ba51..8275965 100644 --- a/bfd/elf32-mcore.c +++ b/bfd/elf32-mcore.c @@ -410,7 +410,7 @@ mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section, static boolean mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, local_syms, local_sections) - bfd * output_bfd ATTRIBUTE_UNUSED; + bfd * output_bfd; struct bfd_link_info * info; bfd * input_bfd; asection * input_section; @@ -510,9 +510,8 @@ mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections [r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + addend = rel->r_addend; } else { diff --git a/bfd/elf32-openrisc.c b/bfd/elf32-openrisc.c index 20358e0..5a7b42f 100644 --- a/bfd/elf32-openrisc.c +++ b/bfd/elf32-openrisc.c @@ -324,7 +324,7 @@ openrisc_final_link_relocate (howto, input_bfd, input_section, contents, rel, static boolean openrisc_elf_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, local_syms, local_sections) - bfd *output_bfd ATTRIBUTE_UNUSED; + bfd *output_bfd; struct bfd_link_info *info; bfd *input_bfd; asection *input_section; @@ -394,8 +394,7 @@ openrisc_elf_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index cd6bd95..2af8400 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -2998,9 +2998,8 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, sec = local_sections[r_symndx]; sym_name = ""; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + addend = rel->r_addend; /* Relocs to local symbols are always resolved. */ will_become_local = 1; } diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 2153a4c..f608fb0 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -1664,9 +1664,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 35ebf1a..74b725a 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -2960,7 +2960,7 @@ sh_elf_discard_copies (h, ignore) static boolean sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, local_syms, local_sections) - bfd *output_bfd ATTRIBUTE_UNUSED; + bfd *output_bfd; struct bfd_link_info *info; bfd *input_bfd; asection *input_section; @@ -3041,7 +3041,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, relocation = (sec->output_section->vma + sec->output_offset + sym->st_value); - if (info->relocateable) { /* This is a relocateable link. We don't have to change @@ -3079,6 +3078,37 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, continue; } + else if (! howto->partial_inplace) + { + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + addend = rel->r_addend; + } + else if ((sec->flags & SEC_MERGE) + && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + { + asection *msec; + + if (howto->rightshift || howto->src_mask != 0xffffffff) + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): %s relocation against SEC_MERGE section"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, howto->name); + return false; + } + + addend = bfd_get_32 (input_bfd, contents + rel->r_offset); + msec = sec; + addend = + _bfd_merged_section_offset (output_bfd, &msec, + elf_section_data (sec)->merge_info, + sym->st_value + addend, (bfd_vma) 0) + - relocation; + addend += msec->output_section->vma + msec->output_offset; + bfd_put_32 (input_bfd, addend, contents + rel->r_offset); + addend = 0; + } } else { diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index 96fc3e9..9458061 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -1176,9 +1176,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index b657020..c873ed9 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -1597,9 +1597,7 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); #if 0 { char * name; diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 69cfef9..783f010 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -3318,9 +3318,7 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index 68dc96a..95cbd76 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -1091,9 +1091,7 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections [r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 97aa485..02d2913 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -3140,9 +3140,8 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, sec = local_sections[r_symndx]; sym_name = ""; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + addend = rel->r_addend; } else { diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index f4c1075..222e1e4 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -1643,9 +1643,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c index 9e06d60..6af2b15 100644 --- a/bfd/elf64-sparc.c +++ b/bfd/elf64-sparc.c @@ -1969,9 +1969,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index df303e7..349540f 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1229,9 +1229,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rela); } else { diff --git a/bfd/elflink.h b/bfd/elflink.h index 6b06bd0..26b28f2 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -6317,7 +6317,9 @@ elf_link_input_bfd (finfo, input_bfd) || h->root.type == bfd_link_hash_defweak) && ! bfd_is_abs_section (h->root.u.def.section) && bfd_is_abs_section (h->root.u.def.section - ->output_section)) + ->output_section) + && elf_section_data (h->root.u.def.section)->merge_info + == NULL) { #if BFD_VERSION_DATE < 20031005 if ((o->flags & SEC_DEBUGGING) != 0) @@ -6348,7 +6350,8 @@ elf_link_input_bfd (finfo, input_bfd) if (sec != NULL && ! bfd_is_abs_section (sec) - && bfd_is_abs_section (sec->output_section)) + && bfd_is_abs_section (sec->output_section) + && elf_section_data (sec)->merge_info == NULL) { #if BFD_VERSION_DATE < 20031005 if ((o->flags & SEC_DEBUGGING) != 0 diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 05ae668..ed06f54 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -3481,9 +3481,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, /* Reloc against local symbol. */ sym = local_syms + r_symndx; sym_sec = local_sections[r_symndx]; - value = (sym_sec->output_section->vma - + sym_sec->output_offset - + sym->st_value); + value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel); } else { diff --git a/gas/ChangeLog b/gas/ChangeLog index 9440e14..b2caa0b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2001-11-23 Jakub Jelinek + + * config/tc-alpha.c (tc_gen_reloc): Remove SEC_MERGE test. + * write.c (adjust_reloc_syms): Don't handle relocs against + SEC_MERGE section symbols specially. + (fixup_segment): Likewise. + 2001-11-21 Richard Sandiford * config/tc-mips.c (mips_need_elf_addend_fixup): New, extracted from... diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c index f73c862..f9908e7 100644 --- a/gas/config/tc-alpha.c +++ b/gas/config/tc-alpha.c @@ -1507,8 +1507,7 @@ tc_gen_reloc (sec, fixp) * at assembly time. bfd_perform_reloc doesn't know about this sort * of thing, and as a result we need to fake it out here. */ - if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy) - || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)) + if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)) && !S_IS_COMMON (fixp->fx_addsy)) reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value; #endif diff --git a/gas/write.c b/gas/write.c index 8176335..5397aa0 100644 --- a/gas/write.c +++ b/gas/write.c @@ -873,13 +873,6 @@ adjust_reloc_syms (abfd, sec, xxx) symbol_mark_used_in_reloc (fixp->fx_addsy); goto done; } - - /* Never adjust a reloc against local symbol in a merge section. */ - if (symsec->flags & SEC_MERGE) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); - goto done; - } #endif /* Is there some other reason we can't adjust this one? (E.g., @@ -2815,9 +2808,6 @@ fixup_segment (fixP, this_segment_type) else if (add_symbol_segment == undefined_section #ifdef BFD_ASSEMBLER || bfd_is_com_section (add_symbol_segment) - || (bfd_get_section_flags (stdoutput, - add_symbol_segment) - & SEC_MERGE) != 0 #endif ) { -- 2.7.4