* 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:
parent
73374ef17b
commit
b6152c3461
2 changed files with 80 additions and 33 deletions
|
@ -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>
|
2002-12-04 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* elf64-ppc.c (ppc64_elf_edit_opd): Correct typo.
|
* elf64-ppc.c (ppc64_elf_edit_opd): Correct typo.
|
||||||
|
|
|
@ -277,6 +277,9 @@ struct elf_m68k_link_hash_entry
|
||||||
struct elf_m68k_link_hash_table
|
struct elf_m68k_link_hash_table
|
||||||
{
|
{
|
||||||
struct elf_link_hash_table root;
|
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. */
|
/* Declare this now that the above structures are defined. */
|
||||||
|
@ -349,6 +352,8 @@ elf_m68k_link_hash_table_create (abfd)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret->sym_sec.abfd = NULL;
|
||||||
|
|
||||||
return &ret->root.root;
|
return &ret->root.root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +521,8 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
|
||||||
if (h->got.refcount == 0)
|
if (h->got.refcount == 0)
|
||||||
{
|
{
|
||||||
/* Make sure this symbol is output as a dynamic symbol. */
|
/* 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))
|
if (!bfd_elf32_link_record_dynamic_symbol (info, h))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -593,7 +599,8 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure this symbol is output as a dynamic symbol. */
|
/* 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))
|
if (!bfd_elf32_link_record_dynamic_symbol (info, h))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -620,6 +627,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
|
||||||
&& (sec->flags & SEC_ALLOC) != 0
|
&& (sec->flags & SEC_ALLOC) != 0
|
||||||
&& h != NULL
|
&& h != NULL
|
||||||
&& (!info->symbolic
|
&& (!info->symbolic
|
||||||
|
|| h->root.type == bfd_link_hash_defweak
|
||||||
|| (h->elf_link_hash_flags
|
|| (h->elf_link_hash_flags
|
||||||
& ELF_LINK_HASH_DEF_REGULAR) == 0)))
|
& 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);
|
sreloc->_raw_size += sizeof (Elf32_External_Rela);
|
||||||
|
|
||||||
/* If we are linking with -Bsymbolic, we count the number of
|
/* We count the number of PC relative relocations we have
|
||||||
PC relative relocations we have entered for this symbol,
|
entered for this symbol, so that we can discard them
|
||||||
so that we can discard them again if the symbol is later
|
again if, in the -Bsymbolic case, the symbol is later
|
||||||
defined by a regular object. Note that this function is
|
defined by a regular object, or, in the normal shared
|
||||||
only called if we are using an m68kelf linker hash table,
|
case, the symbol is forced to be local. Note that this
|
||||||
which means that h is really a pointer to an
|
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. */
|
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_PC16
|
||||||
|| ELF32_R_TYPE (rel->r_info) == R_68K_PC32)
|
|| 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 *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)
|
if (p->section == sreloc)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -714,8 +739,8 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
|
||||||
bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
|
bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
p->next = eh->pcrel_relocs_copied;
|
p->next = *head;
|
||||||
eh->pcrel_relocs_copied = p;
|
*head = p;
|
||||||
p->section = sreloc;
|
p->section = sreloc;
|
||||||
p->count = 0;
|
p->count = 0;
|
||||||
}
|
}
|
||||||
|
@ -950,7 +975,8 @@ elf_m68k_adjust_dynamic_symbol (info, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure this symbol is output as a dynamic symbol. */
|
/* 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))
|
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1121,14 +1147,16 @@ elf_m68k_size_dynamic_sections (output_bfd, info)
|
||||||
s->_raw_size = 0;
|
s->_raw_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a -Bsymbolic shared link, then we need to discard all PC
|
/* If this is a -Bsymbolic shared link, then we need to discard all
|
||||||
relative relocs against symbols defined in a regular object. We
|
PC relative relocs against symbols defined in a regular object.
|
||||||
allocated space for them in the check_relocs routine, but we will not
|
For the normal shared case we discard the PC relative relocs
|
||||||
fill them in in the relocate_section routine. */
|
against symbols that have become local due to visibility changes.
|
||||||
if (info->shared && info->symbolic)
|
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_link_hash_traverse (elf_m68k_hash_table (info),
|
||||||
elf_m68k_discard_copies,
|
elf_m68k_discard_copies,
|
||||||
(PTR) NULL);
|
(PTR) info);
|
||||||
|
|
||||||
/* The check_relocs and adjust_dynamic_symbol entry points have
|
/* The check_relocs and adjust_dynamic_symbol entry points have
|
||||||
determined the sizes of the various dynamic sections. Allocate
|
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
|
/* This function is called via elf_m68k_link_hash_traverse if we are
|
||||||
creating a shared object with -Bsymbolic. It discards the space
|
creating a shared object. In the -Bsymbolic case it discards the
|
||||||
allocated to copy PC relative relocs against symbols which are defined
|
space allocated to copy PC relative relocs against symbols which
|
||||||
in regular objects. We allocated space for them in the check_relocs
|
are defined in regular objects. For the normal shared case, if
|
||||||
routine, but we won't fill them in in the relocate_section routine. */
|
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
|
static bfd_boolean
|
||||||
elf_m68k_discard_copies (h, ignore)
|
elf_m68k_discard_copies (h, inf)
|
||||||
struct elf_m68k_link_hash_entry *h;
|
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;
|
struct elf_m68k_pcrel_relocs_copied *s;
|
||||||
|
|
||||||
if (h->root.root.type == bfd_link_hash_warning)
|
if (h->root.root.type == bfd_link_hash_warning)
|
||||||
h = (struct elf_m68k_link_hash_entry *) h->root.root.u.i.link;
|
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;
|
return TRUE;
|
||||||
|
|
||||||
for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
|
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_PC8:
|
||||||
case R_68K_PC16:
|
case R_68K_PC16:
|
||||||
case R_68K_PC32:
|
case R_68K_PC32:
|
||||||
if (h == NULL)
|
if (h == NULL
|
||||||
|
|| (info->shared
|
||||||
|
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0))
|
||||||
break;
|
break;
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
case R_68K_8:
|
case R_68K_8:
|
||||||
|
|
Loading…
Reference in a new issue