summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@linux-m68k.org>2003-05-17 19:40:36 +0000
committerAndreas Schwab <schwab@linux-m68k.org>2003-05-17 19:40:36 +0000
commit985cc86a9bf14b081fc1677eb6bfbca1c5a03496 (patch)
tree1e065f91730f1866f026de64b01115fd1de2d5c5
parent41acc81524606d0d40273b73ce5c06796512eeb2 (diff)
downloadbinutils-redhat-985cc86a9bf14b081fc1677eb6bfbca1c5a03496.tar.gz
* elf32-m68k.c (elf_m68k_check_relocs): Cache reloc section in
elf_section_data during processing of pc-relative and absolute relocations. (elf_m68k_relocate_section): Use the cached reloc section instead of computing it again. Fix handling of visibility. Don't modify addend when copying over a relocation into the output.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf32-m68k.c49
2 files changed, 30 insertions, 28 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3df4fc8ed3..b5a6a899b8 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2003-05-17 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_check_relocs): Cache reloc section in
+ elf_section_data during processing of pc-relative and absolute
+ relocations.
+ (elf_m68k_relocate_section): Use the cached reloc section instead
+ of computing it again. Fix handling of visibility. Don't modify
+ addend when copying over a relocation into the output.
+
2003-05-17 Alan Modra <amodra@bigpond.net.au>
* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Use SYMBOL_CALLS_LOCAL
diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
index fc3a2af744..1cf23d6abb 100644
--- a/bfd/elf32-m68k.c
+++ b/bfd/elf32-m68k.c
@@ -673,6 +673,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
|| !bfd_set_section_alignment (dynobj, sreloc, 2))
return FALSE;
}
+ elf_section_data (sec)->sreloc = sreloc;
}
if (sec->flags & SEC_READONLY
@@ -1627,12 +1628,17 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
if (info->shared
&& r_symndx != 0
&& (input_section->flags & SEC_ALLOC) != 0
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
&& ((r_type != R_68K_PC8
&& r_type != R_68K_PC16
&& r_type != R_68K_PC32)
- || (!info->symbolic
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+ || (h != NULL
+ && h->dynindx != -1
+ && (!info->symbolic
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))))
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
@@ -1642,26 +1648,6 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
are copied into the output file to be resolved at run
time. */
- if (sreloc == NULL)
- {
- const char *name;
-
- name = (bfd_elf_string_from_elf_section
- (input_bfd,
- elf_elfheader (input_bfd)->e_shstrndx,
- elf_section_data (input_section)->rel_hdr.sh_name));
- if (name == NULL)
- return FALSE;
-
- BFD_ASSERT (strncmp (name, ".rela", 5) == 0
- && strcmp (bfd_get_section_name (input_bfd,
- input_section),
- name + 5) == 0);
-
- sreloc = bfd_get_section_by_name (dynobj, name);
- BFD_ASSERT (sreloc != NULL);
- }
-
skip = FALSE;
relocate = FALSE;
@@ -1677,19 +1663,22 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
if (skip)
memset (&outrel, 0, sizeof outrel);
- /* h->dynindx may be -1 if the symbol was marked to
- become local. */
else if (h != NULL
- && ((! info->symbolic && h->dynindx != -1)
+ && h->dynindx != -1
+ && (r_type == R_68K_PC8
+ || r_type == R_68K_PC16
+ || r_type == R_68K_PC32
+ || !info->shared
+ || !info->symbolic
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0))
{
- BFD_ASSERT (h->dynindx != -1);
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
- outrel.r_addend = relocation + rel->r_addend;
+ outrel.r_addend = rel->r_addend;
}
else
{
+ /* This symbol is local, or marked to become local. */
if (r_type == R_68K_32)
{
relocate = TRUE;
@@ -1730,6 +1719,10 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
}
}
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+
loc = sreloc->contents;
loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);