mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
* elf32-sparc.c (WILL_CALL_FINISH_DYNAMIC_SYMBOL): New.
(elf32_sparc_relocate_section): Use it to figure out when to initialize .got entries. * elf64-sparc.c: Similarly.
This commit is contained in:
parent
2fccf04a44
commit
e36f7d5326
@ -1,3 +1,10 @@
|
||||
2002-04-01 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* elf32-sparc.c (WILL_CALL_FINISH_DYNAMIC_SYMBOL): New.
|
||||
(elf32_sparc_relocate_section): Use it to figure out when to
|
||||
initialize .got entries.
|
||||
* elf64-sparc.c: Similarly.
|
||||
|
||||
2002-03-28 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* linker.c (link_action): Ignore duplicate warning syms.
|
||||
|
@ -1084,6 +1084,17 @@ elf32_sparc_relax_section (abfd, section, link_info, again)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This is the condition under which finish_dynamic_symbol will be called
|
||||
from elflink.h. If elflink.h doesn't call our finish_dynamic_symbol
|
||||
routine, we'll need to do something about initializing any .plt and .got
|
||||
entries in relocate_section. */
|
||||
#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \
|
||||
((DYN) \
|
||||
&& ((INFO)->shared \
|
||||
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \
|
||||
&& ((H)->dynindx != -1 \
|
||||
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0))
|
||||
|
||||
/* Relocate a SPARC ELF section. */
|
||||
|
||||
static boolean
|
||||
@ -1133,9 +1144,10 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
struct elf_link_hash_entry *h;
|
||||
Elf_Internal_Sym *sym;
|
||||
asection *sec;
|
||||
bfd_vma relocation;
|
||||
bfd_vma relocation, off;
|
||||
bfd_reloc_status_type r;
|
||||
boolean is_plt = false;
|
||||
boolean unresolved_reloc;
|
||||
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
|
||||
@ -1175,6 +1187,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
h = NULL;
|
||||
sym = NULL;
|
||||
sec = NULL;
|
||||
unresolved_reloc = false;
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
{
|
||||
sym = local_syms + r_symndx;
|
||||
@ -1187,71 +1200,30 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
relocation = 0;
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
sec = h->root.u.def.section;
|
||||
if (((r_type == R_SPARC_WPLT30
|
||||
|| r_type == R_SPARC_PLT32)
|
||||
&& h->plt.offset != (bfd_vma) -1)
|
||||
|| ((r_type == R_SPARC_GOT10
|
||||
|| r_type == R_SPARC_GOT13
|
||||
|| r_type == R_SPARC_GOT22)
|
||||
&& elf_hash_table (info)->dynamic_sections_created
|
||||
&& (! info->shared
|
||||
|| (! info->symbolic && h->dynindx != -1)
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
||||
|| (info->shared
|
||||
&& ((! info->symbolic && h->dynindx != -1)
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0)
|
||||
&& (r_type == R_SPARC_8
|
||||
|| r_type == R_SPARC_16
|
||||
|| r_type == R_SPARC_32
|
||||
|| r_type == R_SPARC_DISP8
|
||||
|| r_type == R_SPARC_DISP16
|
||||
|| r_type == R_SPARC_DISP32
|
||||
|| r_type == R_SPARC_WDISP30
|
||||
|| r_type == R_SPARC_WDISP22
|
||||
|| r_type == R_SPARC_WDISP19
|
||||
|| r_type == R_SPARC_WDISP16
|
||||
|| r_type == R_SPARC_HI22
|
||||
|| r_type == R_SPARC_22
|
||||
|| r_type == R_SPARC_13
|
||||
|| r_type == R_SPARC_LO10
|
||||
|| r_type == R_SPARC_UA16
|
||||
|| r_type == R_SPARC_UA32
|
||||
|| ((r_type == R_SPARC_PC10
|
||||
|| r_type == R_SPARC_PC22)
|
||||
&& strcmp (h->root.root.string,
|
||||
"_GLOBAL_OFFSET_TABLE_") != 0))
|
||||
&& ((input_section->flags & SEC_ALLOC) != 0
|
||||
/* DWARF will emit R_SPARC_32 relocations in its
|
||||
sections against symbols defined externally
|
||||
in shared libraries. We can't do anything
|
||||
with them here. */
|
||||
|| ((input_section->flags & SEC_DEBUGGING) != 0
|
||||
&& (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_DYNAMIC) != 0))))
|
||||
{
|
||||
/* In these cases, we don't need the relocation
|
||||
value. We check specially because in some
|
||||
obscure cases sec->output_section will be NULL. */
|
||||
relocation = 0;
|
||||
}
|
||||
if (sec->output_section == NULL)
|
||||
/* Set a flag that will be cleared later if we find a
|
||||
relocation value for this symbol. output_section
|
||||
is typically NULL for symbols satisfied by a shared
|
||||
library. */
|
||||
unresolved_reloc = true;
|
||||
else
|
||||
relocation = (h->root.u.def.value
|
||||
+ sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
else if (h->root.type == bfd_link_hash_undefweak)
|
||||
relocation = 0;
|
||||
;
|
||||
else if (info->shared
|
||||
&& (!info->symbolic || info->allow_shlib_undefined)
|
||||
&& !info->no_undefined
|
||||
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
|
||||
relocation = 0;
|
||||
;
|
||||
else
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
@ -1260,7 +1232,6 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
(!info->shared || info->no_undefined
|
||||
|| ELF_ST_VISIBILITY (h->other)))))
|
||||
return false;
|
||||
relocation = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1279,14 +1250,17 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
bfd_vma off;
|
||||
boolean dyn;
|
||||
|
||||
off = h->got.offset;
|
||||
BFD_ASSERT (off != (bfd_vma) -1);
|
||||
dyn = elf_hash_table (info)->dynamic_sections_created;
|
||||
|
||||
if (! elf_hash_table (info)->dynamic_sections_created
|
||||
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
|
||||
|| (info->shared
|
||||
&& (info->symbolic || h->dynindx == -1)
|
||||
&& (info->symbolic
|
||||
|| h->dynindx == -1
|
||||
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
|
||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
|
||||
{
|
||||
/* This is actually a static link, or it is a
|
||||
@ -1310,13 +1284,11 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
h->got.offset |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
relocation = sgot->output_offset + off - got_base;
|
||||
else
|
||||
unresolved_reloc = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_vma off;
|
||||
|
||||
BFD_ASSERT (local_got_offsets != NULL
|
||||
&& local_got_offsets[r_symndx] != (bfd_vma) -1);
|
||||
|
||||
@ -1355,10 +1327,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|
||||
local_got_offsets[r_symndx] |= 1;
|
||||
}
|
||||
|
||||
relocation = sgot->output_offset + off - got_base;
|
||||
}
|
||||
|
||||
relocation = sgot->output_offset + off - got_base;
|
||||
break;
|
||||
|
||||
case R_SPARC_PLT32:
|
||||
@ -1396,6 +1366,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
relocation = (splt->output_section->vma
|
||||
+ splt->output_offset
|
||||
+ h->plt.offset);
|
||||
unresolved_reloc = false;
|
||||
if (r_type == R_SPARC_PLT32)
|
||||
{
|
||||
r_type = R_SPARC_32;
|
||||
@ -1582,6 +1553,18 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
break;
|
||||
}
|
||||
|
||||
/* ??? Copied from elf32-i386.c, debugging section check and all. */
|
||||
if (unresolved_reloc
|
||||
&& !(info->shared
|
||||
&& (input_section->flags & SEC_DEBUGGING) != 0
|
||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
|
||||
(*_bfd_error_handler)
|
||||
(_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"),
|
||||
bfd_archive_filename (input_bfd),
|
||||
bfd_get_section_name (input_bfd, input_section),
|
||||
(long) rel->r_offset,
|
||||
h->root.root.string);
|
||||
|
||||
r = bfd_reloc_continue;
|
||||
if (r_type == R_SPARC_WDISP16)
|
||||
{
|
||||
|
@ -1881,6 +1881,17 @@ sparc64_elf_relax_section (abfd, section, link_info, again)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This is the condition under which finish_dynamic_symbol will be called
|
||||
from elflink.h. If elflink.h doesn't call our finish_dynamic_symbol
|
||||
routine, we'll need to do something about initializing any .plt and
|
||||
.got entries in relocate_section. */
|
||||
#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \
|
||||
((DYN) \
|
||||
&& ((INFO)->shared \
|
||||
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \
|
||||
&& ((H)->dynindx != -1 \
|
||||
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0))
|
||||
|
||||
/* Relocate a SPARC64 ELF section. */
|
||||
|
||||
static boolean
|
||||
@ -1928,9 +1939,10 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
struct elf_link_hash_entry *h;
|
||||
Elf_Internal_Sym *sym;
|
||||
asection *sec;
|
||||
bfd_vma relocation;
|
||||
bfd_vma relocation, off;
|
||||
bfd_reloc_status_type r;
|
||||
boolean is_plt = false;
|
||||
boolean unresolved_reloc;
|
||||
|
||||
r_type = ELF64_R_TYPE_ID (rel->r_info);
|
||||
if (r_type < 0 || r_type >= (int) R_SPARC_max_std)
|
||||
@ -1965,6 +1977,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
h = NULL;
|
||||
sym = NULL;
|
||||
sec = NULL;
|
||||
unresolved_reloc = false;
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
{
|
||||
sym = local_syms + r_symndx;
|
||||
@ -1977,116 +1990,30 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
relocation = 0;
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
boolean skip_it = false;
|
||||
sec = h->root.u.def.section;
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_SPARC_WPLT30:
|
||||
case R_SPARC_PLT32:
|
||||
case R_SPARC_HIPLT22:
|
||||
case R_SPARC_LOPLT10:
|
||||
case R_SPARC_PCPLT32:
|
||||
case R_SPARC_PCPLT22:
|
||||
case R_SPARC_PCPLT10:
|
||||
case R_SPARC_PLT64:
|
||||
if (h->plt.offset != (bfd_vma) -1)
|
||||
skip_it = true;
|
||||
break;
|
||||
|
||||
case R_SPARC_GOT10:
|
||||
case R_SPARC_GOT13:
|
||||
case R_SPARC_GOT22:
|
||||
if (elf_hash_table(info)->dynamic_sections_created
|
||||
&& (!info->shared
|
||||
|| (!info->symbolic && h->dynindx != -1)
|
||||
|| !(h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR)))
|
||||
skip_it = true;
|
||||
break;
|
||||
|
||||
case R_SPARC_PC10:
|
||||
case R_SPARC_PC22:
|
||||
case R_SPARC_PC_HH22:
|
||||
case R_SPARC_PC_HM10:
|
||||
case R_SPARC_PC_LM22:
|
||||
if (!strcmp(h->root.root.string, "_GLOBAL_OFFSET_TABLE_"))
|
||||
break;
|
||||
/* FALLTHRU */
|
||||
|
||||
case R_SPARC_8:
|
||||
case R_SPARC_16:
|
||||
case R_SPARC_32:
|
||||
case R_SPARC_DISP8:
|
||||
case R_SPARC_DISP16:
|
||||
case R_SPARC_DISP32:
|
||||
case R_SPARC_WDISP30:
|
||||
case R_SPARC_WDISP22:
|
||||
case R_SPARC_HI22:
|
||||
case R_SPARC_22:
|
||||
case R_SPARC_13:
|
||||
case R_SPARC_LO10:
|
||||
case R_SPARC_UA32:
|
||||
case R_SPARC_10:
|
||||
case R_SPARC_11:
|
||||
case R_SPARC_64:
|
||||
case R_SPARC_OLO10:
|
||||
case R_SPARC_HH22:
|
||||
case R_SPARC_HM10:
|
||||
case R_SPARC_LM22:
|
||||
case R_SPARC_WDISP19:
|
||||
case R_SPARC_WDISP16:
|
||||
case R_SPARC_7:
|
||||
case R_SPARC_5:
|
||||
case R_SPARC_6:
|
||||
case R_SPARC_DISP64:
|
||||
case R_SPARC_HIX22:
|
||||
case R_SPARC_LOX10:
|
||||
case R_SPARC_H44:
|
||||
case R_SPARC_M44:
|
||||
case R_SPARC_L44:
|
||||
case R_SPARC_UA64:
|
||||
case R_SPARC_UA16:
|
||||
if (info->shared
|
||||
&& ((!info->symbolic && h->dynindx != -1)
|
||||
|| !(h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR))
|
||||
&& ((input_section->flags & SEC_ALLOC) != 0
|
||||
/* DWARF will emit R_SPARC_{32,64} relocations in
|
||||
its sections against symbols defined externally
|
||||
in shared libraries. We can't do anything
|
||||
with them here. */
|
||||
|| ((input_section->flags & SEC_DEBUGGING) != 0
|
||||
&& (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_DYNAMIC) != 0)))
|
||||
skip_it = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (skip_it)
|
||||
{
|
||||
/* In these cases, we don't need the relocation
|
||||
value. We check specially because in some
|
||||
obscure cases sec->output_section will be NULL. */
|
||||
relocation = 0;
|
||||
}
|
||||
if (sec->output_section == NULL)
|
||||
/* Set a flag that will be cleared later if we find a
|
||||
relocation value for this symbol. output_section
|
||||
is typically NULL for symbols satisfied by a shared
|
||||
library. */
|
||||
unresolved_reloc = true;
|
||||
else
|
||||
{
|
||||
relocation = (h->root.u.def.value
|
||||
+ sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
relocation = (h->root.u.def.value
|
||||
+ sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
else if (h->root.type == bfd_link_hash_undefweak)
|
||||
relocation = 0;
|
||||
;
|
||||
else if (info->shared
|
||||
&& (!info->symbolic || info->allow_shlib_undefined)
|
||||
&& !info->no_undefined
|
||||
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
|
||||
relocation = 0;
|
||||
;
|
||||
else
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
@ -2107,7 +2034,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
}
|
||||
}
|
||||
|
||||
do_dynreloc:
|
||||
do_dynreloc:
|
||||
/* When generating a shared object, these relocations are copied
|
||||
into the output file to be resolved at run time. */
|
||||
if (info->shared && r_symndx != 0 && (input_section->flags & SEC_ALLOC))
|
||||
@ -2326,14 +2253,18 @@ do_dynreloc:
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
bfd_vma off = h->got.offset;
|
||||
BFD_ASSERT (off != (bfd_vma) -1);
|
||||
boolean dyn;
|
||||
|
||||
if (! elf_hash_table (info)->dynamic_sections_created
|
||||
off = h->got.offset;
|
||||
BFD_ASSERT (off != (bfd_vma) -1);
|
||||
dyn = elf_hash_table (info)->dynamic_sections_created;
|
||||
|
||||
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
|
||||
|| (info->shared
|
||||
&& (info->symbolic || h->dynindx == -1)
|
||||
&& (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR)))
|
||||
&& (info->symbolic
|
||||
|| h->dynindx == -1
|
||||
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
|
||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
|
||||
{
|
||||
/* This is actually a static link, or it is a -Bsymbolic
|
||||
link and the symbol is defined locally, or the symbol
|
||||
@ -2356,12 +2287,11 @@ do_dynreloc:
|
||||
h->got.offset |= 1;
|
||||
}
|
||||
}
|
||||
relocation = sgot->output_offset + off - got_base;
|
||||
else
|
||||
unresolved_reloc = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_vma off;
|
||||
|
||||
BFD_ASSERT (local_got_offsets != NULL);
|
||||
off = local_got_offsets[r_symndx];
|
||||
BFD_ASSERT (off != (bfd_vma) -1);
|
||||
@ -2407,8 +2337,8 @@ do_dynreloc:
|
||||
else
|
||||
bfd_put_64 (output_bfd, relocation, sgot->contents + off);
|
||||
}
|
||||
relocation = sgot->output_offset + off - got_base;
|
||||
}
|
||||
relocation = sgot->output_offset + off - got_base;
|
||||
goto do_default;
|
||||
|
||||
case R_SPARC_WPLT30:
|
||||
@ -2440,6 +2370,7 @@ do_dynreloc:
|
||||
relocation = (splt->output_section->vma
|
||||
+ splt->output_offset
|
||||
+ sparc64_elf_plt_entry_offset (h->plt.offset));
|
||||
unresolved_reloc = false;
|
||||
if (r_type == R_SPARC_WPLT30)
|
||||
goto do_wplt30;
|
||||
if (r_type == R_SPARC_PLT32 || r_type == R_SPARC_PLT64)
|
||||
@ -2623,6 +2554,17 @@ do_dynreloc:
|
||||
break;
|
||||
}
|
||||
|
||||
if (unresolved_reloc
|
||||
&& !(info->shared
|
||||
&& (input_section->flags & SEC_DEBUGGING) != 0
|
||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
|
||||
(*_bfd_error_handler)
|
||||
(_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"),
|
||||
bfd_archive_filename (input_bfd),
|
||||
bfd_get_section_name (input_bfd, input_section),
|
||||
(long) rel->r_offset,
|
||||
h->root.root.string);
|
||||
|
||||
switch (r)
|
||||
{
|
||||
case bfd_reloc_ok:
|
||||
|
Loading…
Reference in New Issue
Block a user