aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elf32-sh.c34
-rw-r--r--bfd/elf32-sh64.c22
-rw-r--r--bfd/elf64-sh64.c24
4 files changed, 89 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d41c0a6..635c6ae 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2003-10-15 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_relocate_section): Handle R_SH_IMM_*_PCREL
+ relocations.
+ (sh_elf_check_relocs): Likewise.
+
+ * elf32-sh64.c (elf_backend_merge_symbol_attribute): Define.
+ (sh64_elf_merge_symbol_attribute): New.
+ * elf64-sh64.c (elf_backend_merge_symbol_attribute): Define.
+ (sh64_elf64_merge_symbol_attribute): New.
+
2003-10-14 Kaz Kojima <kkojima@rr.iij4u.or.jp>
* elf-bfd.h (struct elf_backend_data): New function pointer member
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index a3b2133..836b34b 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -5081,13 +5081,19 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_SH_DIR32:
case R_SH_REL32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_IMM_LOW16_PCREL:
+ case R_SH_IMM_MEDLOW16_PCREL:
+ case R_SH_IMM_MEDHI16_PCREL:
+ case R_SH_IMM_HI16_PCREL:
+#endif
if (info->shared
&& (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
&& r_symndx != 0
&& (input_section->flags & SEC_ALLOC) != 0
- && (r_type != R_SH_REL32
+ && (r_type == R_SH_DIR32
|| !SYMBOL_CALLS_LOCAL (info, h)))
{
Elf_Internal_Rela outrel;
@@ -5140,6 +5146,17 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
outrel.r_addend
= bfd_get_32 (input_bfd, contents + rel->r_offset);
}
+#ifdef INCLUDE_SHMEDIA
+ else if (r_type == R_SH_IMM_LOW16_PCREL
+ || r_type == R_SH_IMM_MEDLOW16_PCREL
+ || r_type == R_SH_IMM_MEDHI16_PCREL
+ || r_type == R_SH_IMM_HI16_PCREL)
+ {
+ BFD_ASSERT (h != NULL && h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = addend;
+ }
+#endif
else
{
/* h->dynindx may be -1 if this symbol was marked to
@@ -6655,6 +6672,12 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
case R_SH_DIR32:
case R_SH_REL32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_IMM_LOW16_PCREL:
+ case R_SH_IMM_MEDLOW16_PCREL:
+ case R_SH_IMM_MEDHI16_PCREL:
+ case R_SH_IMM_HI16_PCREL:
+#endif
if (h != NULL && ! info->shared)
{
h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
@@ -6772,7 +6795,14 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
}
p->count += 1;
- if (r_type == R_SH_REL32)
+ if (r_type == R_SH_REL32
+#ifdef INCLUDE_SHMEDIA
+ || r_type == R_SH_IMM_LOW16_PCREL
+ || r_type == R_SH_IMM_MEDLOW16_PCREL
+ || r_type == R_SH_IMM_MEDHI16_PCREL
+ || r_type == R_SH_IMM_HI16_PCREL
+#endif
+ )
p->pc_count += 1;
}
diff --git a/bfd/elf32-sh64.c b/bfd/elf32-sh64.c
index 288003e..c3be09f 100644
--- a/bfd/elf32-sh64.c
+++ b/bfd/elf32-sh64.c
@@ -85,6 +85,7 @@ static void sh64_find_section_for_address
#define elf_backend_add_symbol_hook sh64_elf_add_symbol_hook
#define elf_backend_link_output_symbol_hook \
sh64_elf_link_output_symbol_hook
+#define elf_backend_merge_symbol_attribute sh64_elf_merge_symbol_attribute
#define elf_backend_final_write_processing sh64_elf_final_write_processing
#define elf_backend_section_from_shdr sh64_backend_section_from_shdr
#define elf_backend_special_sections sh64_elf_special_sections
@@ -735,6 +736,27 @@ sh64_elf_final_write_processing (bfd *abfd,
}
}
+/* Merge non visibility st_other attribute when the symbol comes from
+ a dynamic object. */
+static void
+sh64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *isym,
+ bfd_boolean definition,
+ bfd_boolean dynamic)
+{
+ if (isym->st_other != 0 && dynamic)
+ {
+ unsigned char other;
+
+ /* Take the balance of OTHER from the definition. */
+ other = (definition ? isym->st_other : h->other);
+ other &= ~ ELF_ST_VISIBILITY (-1);
+ h->other = other | ELF_ST_VISIBILITY (h->other);
+ }
+
+ return;
+}
+
static struct bfd_elf_special_section const sh64_elf_special_sections[]=
{
{ ".cranges", 8, 0, SHT_PROGBITS, 0 },
diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c
index e05145e..1a679d3 100644
--- a/bfd/elf64-sh64.c
+++ b/bfd/elf64-sh64.c
@@ -4118,6 +4118,27 @@ sh64_elf64_finish_dynamic_sections (bfd *output_bfd,
return TRUE;
}
+/* Merge non visibility st_other attribute when the symbol comes from
+ a dynamic object. */
+static void
+sh64_elf64_merge_symbol_attribute (struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *isym,
+ bfd_boolean definition,
+ bfd_boolean dynamic)
+{
+ if (isym->st_other != 0 && dynamic)
+ {
+ unsigned char other;
+
+ /* Take the balance of OTHER from the definition. */
+ other = (definition ? isym->st_other : h->other);
+ other &= ~ ELF_ST_VISIBILITY (-1);
+ h->other = other | ELF_ST_VISIBILITY (h->other);
+ }
+
+ return;
+}
+
static struct bfd_elf_special_section const sh64_elf64_special_sections[]=
{
{ ".cranges", 8, 0, SHT_PROGBITS, 0 },
@@ -4164,6 +4185,9 @@ static struct bfd_elf_special_section const sh64_elf64_special_sections[]=
#define elf_backend_link_output_symbol_hook \
sh64_elf64_link_output_symbol_hook
+#define elf_backend_merge_symbol_attribute \
+ sh64_elf64_merge_symbol_attribute
+
#define elf_backend_final_write_processing \
sh64_elf64_final_write_processing