* elf32-frv.c (FRV_SYM_LOCAL): Weak undefined doesn't imply local.

(_frv_emit_got_relocs_plt_entries): Decay relocation to protected
function's descriptor to symbol+offset, and map local undefweak
symbol to NULL function descriptor.
(elf32_frv_relocate_section): Likewise.
This commit is contained in:
Alexandre Oliva
2004-02-24 16:39:01 +00:00
parent 74aee4eb9f
commit 072c89031a
2 changed files with 148 additions and 112 deletions

@ -1,3 +1,11 @@
2004-02-24 Alexandre Oliva <aoliva@redhat.com>
* elf32-frv.c (FRV_SYM_LOCAL): Weak undefined doesn't imply local.
(_frv_emit_got_relocs_plt_entries): Decay relocation to protected
function's descriptor to symbol+offset, and map local undefweak
symbol to NULL function descriptor.
(elf32_frv_relocate_section): Likewise.
2004-02-23 Mark Kettenis <kettenis@gnu.org>
* libaout.h (enum machine_type): Add M_SPARC64_NETBSD and

@ -659,7 +659,6 @@ frv_elf_link_hash_table_create (bfd *abfd)
#define FRV_SYM_LOCAL(INFO, H) \
(_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
|| ! elf_hash_table (INFO)->dynamic_sections_created \
|| (H)->root.type == bfd_link_hash_undefweak \
|| (/* The condition below is an ugly hack to get .scommon data to
be regarded as local. For some reason the
ELF_LINK_HASH_DEF_REGULAR bit is not set on such common
@ -1029,13 +1028,31 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
if (entry->fdgot_entry)
{
int reloc, idx;
bfd_vma ad;
bfd_vma ad = 0;
if (! (entry->symndx == -1
&& entry->d.h->root.type == bfd_link_hash_undefweak
&& FRV_SYM_LOCAL (info, entry->d.h)))
{
/* If the symbol is dynamic and there may be dynamic symbol
resolution because we are or are linked with a shared
resolution because we are, or are linked with, a shared
library, emit a FUNCDESC relocation such that the dynamic
linker will allocate the function descriptor. */
if (entry->symndx == -1 && ! FRV_FUNCDESC_LOCAL (info, entry->d.h))
linker will allocate the function descriptor. If the
symbol needs a non-local function descriptor but binds
locally (e.g., its visibility is protected, emit a
dynamic relocation decayed to section+offset. */
if (entry->symndx == -1 && ! FRV_FUNCDESC_LOCAL (info, entry->d.h)
&& FRV_SYM_LOCAL (info, entry->d.h)
&& !(info->executable && !info->pie))
{
reloc = R_FRV_FUNCDESC;
idx = elf_section_data (entry->d.h->root.u.def.section
->output_section)->dynindx;
ad = entry->d.h->root.u.def.section->output_offset
+ entry->d.h->root.u.def.value;
}
else if (entry->symndx == -1
&& ! FRV_FUNCDESC_LOCAL (info, entry->d.h))
{
reloc = R_FRV_FUNCDESC;
idx = dynindx;
@ -1050,25 +1067,21 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
if (elf_hash_table (info)->dynamic_sections_created)
BFD_ASSERT (entry->privfd);
reloc = R_FRV_32;
idx = elf_section_data (frv_got_section (info)->output_section)
->dynindx;
ad = frv_got_section (info)->output_offset +
frv_got_initial_offset (info) + entry->fd_entry;
idx = elf_section_data (frv_got_section (info)
->output_section)->dynindx;
ad = frv_got_section (info)->output_offset
+ frv_got_initial_offset (info) + entry->fd_entry;
}
/* If there is room for dynamic symbol resolution, emit the
dynamic relocation. However, if we're linking an executable
at a fixed location, we won't have emitted a dynamic symbol
entry for the got section, so idx will be zero, which means
we can and should compute the address of the private
descriptor ourselves. */
dynamic relocation. However, if we're linking an
executable at a fixed location, we won't have emitted a
dynamic symbol entry for the got section, so idx will be
zero, which means we can and should compute the address
of the private descriptor ourselves. */
if (info->executable && !info->pie
&& (entry->symndx != -1 || FRV_FUNCDESC_LOCAL (info, entry->d.h)))
{
if (entry->symndx == -1
&& entry->d.h->root.type == bfd_link_hash_undefweak)
ad = 0;
else
&& (entry->symndx != -1
|| FRV_FUNCDESC_LOCAL (info, entry->d.h)))
{
ad += frv_got_section (info)->output_section->vma;
_frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
@ -1077,7 +1090,6 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
+ frv_got_initial_offset (info)
+ entry->fdgot_entry);
}
}
else
_frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
_bfd_elf_section_offset
@ -1088,6 +1100,7 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
+ frv_got_section (info)->output_section->vma
+ frv_got_section (info)->output_offset,
reloc, idx, ad);
}
bfd_put_32 (output_bfd, ad,
frv_got_section (info)->contents
@ -2005,12 +2018,27 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
int dynindx;
bfd_vma addend = rel->r_addend;
if (! (h && h->root.type == bfd_link_hash_undefweak
&& FRV_SYM_LOCAL (info, h)))
{
/* If the symbol is dynamic and there may be dynamic
symbol resolution because we are or are linked with a
shared library, emit a FUNCDESC relocation such that
the dynamic linker will allocate the function
descriptor. */
if (h && ! FRV_FUNCDESC_LOCAL (info, h))
descriptor. If the symbol needs a non-local function
descriptor but binds locally (e.g., its visibility is
protected, emit a dynamic relocation decayed to
section+offset. */
if (h && ! FRV_FUNCDESC_LOCAL (info, h)
&& FRV_SYM_LOCAL (info, h)
&& !(info->executable && !info->pie))
{
dynindx = elf_section_data (h->root.u.def.section
->output_section)->dynindx;
addend += h->root.u.def.section->output_offset
+ h->root.u.def.value;
}
else if (h && ! FRV_FUNCDESC_LOCAL (info, h))
{
if (addend)
{
@ -2027,8 +2055,8 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
descriptor, so reference it directly. */
BFD_ASSERT (picrel->privfd);
r_type = R_FRV_32;
dynindx = elf_section_data (frv_got_section
(info)->output_section)->dynindx;
dynindx = elf_section_data (frv_got_section (info)
->output_section)->dynindx;
addend = frv_got_section (info)->output_offset
+ frv_got_initial_offset (info)
+ picrel->fd_entry;
@ -2057,7 +2085,6 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
name, input_bfd, input_section, rel->r_offset);
return FALSE;
}
if (! h || h->root.type != bfd_link_hash_undefweak)
_frv_add_rofixup (output_bfd,
frv_gotfixup_section (info),
_bfd_elf_section_offset
@ -2088,6 +2115,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
+ input_section->output_offset,
r_type, dynindx, addend);
}
}
/* We want the addend in-place because dynamic
relocations are REL. Setting relocation to it should