aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog40
-rw-r--r--bfd/elf-bfd.h2
-rw-r--r--bfd/elf-hppa.h5
-rw-r--r--bfd/elf-m10200.c4
-rw-r--r--bfd/elf-m10300.c4
-rw-r--r--bfd/elf.c32
-rw-r--r--bfd/elf32-arm.h42
-rw-r--r--bfd/elf32-avr.c4
-rw-r--r--bfd/elf32-cris.c4
-rw-r--r--bfd/elf32-d10v.c6
-rw-r--r--bfd/elf32-fr30.c6
-rw-r--r--bfd/elf32-h8300.c4
-rw-r--r--bfd/elf32-hppa.c5
-rw-r--r--bfd/elf32-i370.c5
-rw-r--r--bfd/elf32-i386.c26
-rw-r--r--bfd/elf32-i860.c4
-rw-r--r--bfd/elf32-m32r.c7
-rw-r--r--bfd/elf32-m68k.c4
-rw-r--r--bfd/elf32-mcore.c7
-rw-r--r--bfd/elf32-openrisc.c5
-rw-r--r--bfd/elf32-ppc.c5
-rw-r--r--bfd/elf32-s390.c4
-rw-r--r--bfd/elf32-sh.c34
-rw-r--r--bfd/elf32-sparc.c4
-rw-r--r--bfd/elf32-v850.c4
-rw-r--r--bfd/elf64-alpha.c4
-rw-r--r--bfd/elf64-mmix.c4
-rw-r--r--bfd/elf64-ppc.c5
-rw-r--r--bfd/elf64-s390.c4
-rw-r--r--bfd/elf64-sparc.c4
-rw-r--r--bfd/elf64-x86-64.c4
-rw-r--r--bfd/elflink.h7
-rw-r--r--bfd/elfxx-ia64.c4
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-alpha.c3
-rw-r--r--gas/write.c10
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 <jakub@redhat.com>
+
+ * 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 <nickc@cambridge.redhat.com>
* 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 = "<local symbol>";
- 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 = "<local symbol>";
+#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 = "<local symbol>";
- 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 = "<local symbol>";
- 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 <jakub@redhat.com>
+
+ * 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 <rsandifo@redhat.com>
* 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
)
{