* elf32-m68k.c (struct elf_m68k_link_hash_table): Add sym_sec

member.
	(elf_m68k_link_hash_table_create): Initialize it.
	(elf_m68k_check_relocs): Handle symbols that are forced to be
	local due to visibility changes.
	(elf_m68k_adjust_dynamic_symbol): Likewise.
	(elf_m68k_size_dynamic_sections): Likewise.
	(elf_m68k_discard_copies): Likewise.
	(elf_m68k_relocate_section): Likewise.
This commit is contained in:
Andreas Schwab 2002-12-04 15:07:13 +00:00
parent 73374ef17b
commit b6152c3461
2 changed files with 80 additions and 33 deletions

View file

@ -1,3 +1,15 @@
2002-12-04 Andreas Schwab <schwab@suse.de>
* elf32-m68k.c (struct elf_m68k_link_hash_table): Add sym_sec
member.
(elf_m68k_link_hash_table_create): Initialize it.
(elf_m68k_check_relocs): Handle symbols that are forced to be
local due to visibility changes.
(elf_m68k_adjust_dynamic_symbol): Likewise.
(elf_m68k_size_dynamic_sections): Likewise.
(elf_m68k_discard_copies): Likewise.
(elf_m68k_relocate_section): Likewise.
2002-12-04 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (ppc64_elf_edit_opd): Correct typo.

View file

@ -277,6 +277,9 @@ struct elf_m68k_link_hash_entry
struct elf_m68k_link_hash_table
{
struct elf_link_hash_table root;
/* Small local sym to section mapping cache. */
struct sym_sec_cache sym_sec;
};
/* Declare this now that the above structures are defined. */
@ -349,6 +352,8 @@ elf_m68k_link_hash_table_create (abfd)
return NULL;
}
ret->sym_sec.abfd = NULL;
return &ret->root.root;
}
@ -516,7 +521,8 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
if (h->got.refcount == 0)
{
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
if (h->dynindx == -1
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
{
if (!bfd_elf32_link_record_dynamic_symbol (info, h))
return FALSE;
@ -593,7 +599,8 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
}
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
if (h->dynindx == -1
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
{
if (!bfd_elf32_link_record_dynamic_symbol (info, h))
return FALSE;
@ -620,6 +627,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
&& (sec->flags & SEC_ALLOC) != 0
&& h != NULL
&& (!info->symbolic
|| h->root.type == bfd_link_hash_defweak
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0)))
{
@ -687,24 +695,41 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
sreloc->_raw_size += sizeof (Elf32_External_Rela);
/* If we are linking with -Bsymbolic, we count the number of
PC relative relocations we have entered for this symbol,
so that we can discard them again if the symbol is later
defined by a regular object. Note that this function is
only called if we are using an m68kelf linker hash table,
which means that h is really a pointer to an
/* We count the number of PC relative relocations we have
entered for this symbol, so that we can discard them
again if, in the -Bsymbolic case, the symbol is later
defined by a regular object, or, in the normal shared
case, the symbol is forced to be local. Note that this
function is only called if we are using an m68kelf linker
hash table, which means that h is really a pointer to an
elf_m68k_link_hash_entry. */
if ((ELF32_R_TYPE (rel->r_info) == R_68K_PC8
if (ELF32_R_TYPE (rel->r_info) == R_68K_PC8
|| ELF32_R_TYPE (rel->r_info) == R_68K_PC16
|| ELF32_R_TYPE (rel->r_info) == R_68K_PC32)
&& info->symbolic)
{
struct elf_m68k_link_hash_entry *eh;
struct elf_m68k_pcrel_relocs_copied *p;
struct elf_m68k_pcrel_relocs_copied **head;
eh = (struct elf_m68k_link_hash_entry *) h;
if (h != NULL)
{
struct elf_m68k_link_hash_entry *eh
= (struct elf_m68k_link_hash_entry *) h;
head = &eh->pcrel_relocs_copied;
}
else
{
asection *s;
s = (bfd_section_from_r_symndx
(abfd, &elf_m68k_hash_table (info)->sym_sec,
sec, r_symndx));
if (s == NULL)
return FALSE;
for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
head = ((struct elf_m68k_pcrel_relocs_copied **)
&elf_section_data (s)->local_dynrel);
}
for (p = *head; p != NULL; p = p->next)
if (p->section == sreloc)
break;
@ -714,8 +739,8 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
if (p == NULL)
return FALSE;
p->next = eh->pcrel_relocs_copied;
eh->pcrel_relocs_copied = p;
p->next = *head;
*head = p;
p->section = sreloc;
p->count = 0;
}
@ -950,7 +975,8 @@ elf_m68k_adjust_dynamic_symbol (info, h)
}
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
if (h->dynindx == -1
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
{
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
return FALSE;
@ -1121,14 +1147,16 @@ elf_m68k_size_dynamic_sections (output_bfd, info)
s->_raw_size = 0;
}
/* If this is a -Bsymbolic shared link, then we need to discard all PC
relative relocs against symbols defined in a regular object. We
allocated space for them in the check_relocs routine, but we will not
fill them in in the relocate_section routine. */
if (info->shared && info->symbolic)
/* If this is a -Bsymbolic shared link, then we need to discard all
PC relative relocs against symbols defined in a regular object.
For the normal shared case we discard the PC relative relocs
against symbols that have become local due to visibility changes.
We allocated space for them in the check_relocs routine, but we
will not fill them in in the relocate_section routine. */
if (info->shared)
elf_m68k_link_hash_traverse (elf_m68k_hash_table (info),
elf_m68k_discard_copies,
(PTR) NULL);
(PTR) info);
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
@ -1255,23 +1283,28 @@ elf_m68k_size_dynamic_sections (output_bfd, info)
}
/* This function is called via elf_m68k_link_hash_traverse if we are
creating a shared object with -Bsymbolic. It discards the space
allocated to copy PC relative relocs against symbols which are defined
in regular objects. We allocated space for them in the check_relocs
routine, but we won't fill them in in the relocate_section routine. */
creating a shared object. In the -Bsymbolic case it discards the
space allocated to copy PC relative relocs against symbols which
are defined in regular objects. For the normal shared case, if
discards space for pc-relative relocs that have become local due to
symbol visibility changes. We allocated space for them in the
check_relocs routine, but we won't fill them in in the
relocate_section routine. */
static bfd_boolean
elf_m68k_discard_copies (h, ignore)
elf_m68k_discard_copies (h, inf)
struct elf_m68k_link_hash_entry *h;
PTR ignore ATTRIBUTE_UNUSED;
PTR inf;
{
struct bfd_link_info *info = (struct bfd_link_info *) inf;
struct elf_m68k_pcrel_relocs_copied *s;
if (h->root.root.type == bfd_link_hash_warning)
h = (struct elf_m68k_link_hash_entry *) h->root.root.u.i.link;
/* We only discard relocs for symbols defined in a regular object. */
if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
|| (!info->symbolic
&& (h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0))
return TRUE;
for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
@ -1591,7 +1624,9 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
case R_68K_PC8:
case R_68K_PC16:
case R_68K_PC32:
if (h == NULL)
if (h == NULL
|| (info->shared
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0))
break;
/* Fall through. */
case R_68K_8: