aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-i386.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2001-09-29 06:21:59 +0000
committerAlan Modra <amodra@gmail.com>2001-09-29 06:21:59 +0000
commit51b64d56a7c65e6a30649cf9aade57b56c321c0e (patch)
tree92f1f675368a87f2f181589c5df4a599575e54fb /bfd/elf32-i386.c
parent21d17a588f70a57acf7d97def74a550e2925600e (diff)
downloadfsf-binutils-gdb-51b64d56a7c65e6a30649cf9aade57b56c321c0e.zip
fsf-binutils-gdb-51b64d56a7c65e6a30649cf9aade57b56c321c0e.tar.gz
fsf-binutils-gdb-51b64d56a7c65e6a30649cf9aade57b56c321c0e.tar.bz2
* elf-bfd.h (struct elf_link_local_dynamic_entry): Add init_refcount.
(struct elf_backend_data): Add can_refcount. * elf.c (_bfd_elf_link_hash_newfunc): Get rid of a few casts. Set got.refcount and plt.refcount from init_refcount. (_bfd_elf_link_hash_table_init): Set up init_refcount. (_bfd_elf_link_hash_copy_indirect): Reference got/plt.refcount rather than got/plt.offset, and test for <= 0 rather than -1. * elflink.h (size_dynamic_sections): Set init_refcount to -1. * elfxx-target.h (elf_backend_can_refcount): Define. (elfNN_bed): Init can_refcount. * linker.c (_bfd_link_hash_newfunc): Get rid of a few casts. (_bfd_generic_link_hash_newfunc): Likewise. * elf32-cris.c (cris_elf_check_relocs): Modify for refcounts starting from zero. (elf_backend_can_refcount): Define. * elf32-hppa.c (elf32_hppa_check_relocs): Modify for refcounts starting from zero. (elf32_hppa_copy_indirect_symbol): Make static to agree with prototype. (elf_backend_can_refcount): Define. * elf32-i386.c (elf_i386_check_relocs): Modify for refcounts starting from zero. (allocate_dynrelocs): Set plt/got.offset rather than *.refcount. (elf_i386_finish_dynamic_symbol): Expand SHN_UNDEF comment. (elf_i386_finish_dynamic_sections): Use local var so line < 80 chars. (elf_backend_can_refcount): Define. (elf_i386_copy_indirect_symbol): Make static to agree with prototype. Formatting fix. * elf32-m68k.c (elf_m68k_check_relocs): Modify for refcounts starting from zero. (elf_backend_can_refcount): Define. * elf32-ppc.c (ppc_elf_check_relocs): Modify for refcounts starting from zero. (elf_backend_can_refcount): Define. * elf32-s390.c (elf_s390_check_relocs): Modify for refcounts starting from zero. (elf_backend_can_refcount): Define. * elf64-s390.c (elf_s390_check_relocs): Modify for refcounts starting from zero. (elf_backend_can_refcount): Define. * elf64-x86-64.c (elf64_x86_64_check_relocs): Modify for refcounts starting from zero. (elf_backend_can_refcount): Define.
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r--bfd/elf32-i386.c55
1 files changed, 23 insertions, 32 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index dbd137f..192aa4e 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -44,8 +44,7 @@ static boolean create_got_section
PARAMS((bfd *, struct bfd_link_info *));
static boolean elf_i386_create_dynamic_sections
PARAMS((bfd *, struct bfd_link_info *));
-static void
-elf_i386_copy_indirect_symbol
+static void elf_i386_copy_indirect_symbol
PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
static boolean elf_i386_check_relocs
PARAMS ((bfd *, struct bfd_link_info *, asection *,
@@ -629,7 +628,7 @@ elf_i386_create_dynamic_sections (dynobj, info)
/* Copy the extra info we tack onto an elf_link_hash_entry. */
-void
+static void
elf_i386_copy_indirect_symbol (dir, ind)
struct elf_link_hash_entry *dir, *ind;
{
@@ -703,10 +702,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
/* This symbol requires a global offset table entry. */
if (h != NULL)
{
- if (h->got.refcount == -1)
- h->got.refcount = 1;
- else
- h->got.refcount += 1;
+ h->got.refcount += 1;
}
else
{
@@ -754,13 +750,8 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
if (h == NULL)
continue;
- if (h->plt.refcount == -1)
- {
- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- h->plt.refcount = 1;
- }
- else
- h->plt.refcount += 1;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->plt.refcount += 1;
break;
case R_386_32:
@@ -777,10 +768,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
/* We may need a .plt entry if the function this reloc
refers to is in a shared lib. */
- if (h->plt.refcount == -1)
- h->plt.refcount = 1;
- else
- h->plt.refcount += 1;
+ h->plt.refcount += 1;
}
/* If we are creating a shared library, and this is a reloc
@@ -1278,13 +1266,13 @@ allocate_dynrelocs (h, inf)
}
else
{
- h->plt.refcount = -1;
+ h->plt.offset = (bfd_vma) -1;
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
}
}
else
{
- h->plt.refcount = -1;
+ h->plt.offset = (bfd_vma) -1;
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
}
@@ -1310,7 +1298,7 @@ allocate_dynrelocs (h, inf)
htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
}
else
- h->got.refcount = -1;
+ h->got.offset = (bfd_vma) -1;
eh = (struct elf_i386_link_hash_entry *) h;
if (eh->dyn_relocs == NULL)
@@ -1648,7 +1636,6 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
asection **local_sections;
{
struct elf_i386_link_hash_table *htab;
- bfd *dynobj;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
bfd_vma *local_got_offsets;
@@ -1656,7 +1643,6 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
Elf_Internal_Rela *relend;
htab = elf_i386_hash_table (info);
- dynobj = htab->elf.dynobj;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
local_got_offsets = elf_local_got_offsets (input_bfd);
@@ -2066,10 +2052,8 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
Elf_Internal_Sym *sym;
{
struct elf_i386_link_hash_table *htab;
- bfd *dynobj;
htab = elf_i386_hash_table (info);
- dynobj = htab->elf.dynobj;
if (h->plt.offset != (bfd_vma) -1)
{
@@ -2141,7 +2125,10 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
{
/* Mark the symbol as undefined, rather than as defined in
- the .plt section. Leave the value alone. */
+ the .plt section. Leave the value alone. This is a clue
+ for the dynamic linker, to make function pointer
+ comparisons work between an application and shared
+ library. */
sym->st_shndx = SHN_UNDEF;
}
}
@@ -2265,6 +2252,7 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
+ asection *s;
bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
@@ -2282,10 +2270,11 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
break;
case DT_PLTRELSZ:
- if (htab->srelplt->output_section->_cooked_size != 0)
- dyn.d_un.d_val = htab->srelplt->output_section->_cooked_size;
+ s = htab->srelplt->output_section;
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val = s->_cooked_size;
else
- dyn.d_un.d_val = htab->srelplt->output_section->_raw_size;
+ dyn.d_un.d_val = s->_raw_size;
break;
case DT_RELSZ:
@@ -2300,10 +2289,11 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
about changing the DT_REL entry. */
if (htab->srelplt != NULL)
{
- if (htab->srelplt->output_section->_cooked_size != 0)
- dyn.d_un.d_val -= htab->srelplt->output_section->_cooked_size;
+ s = htab->srelplt->output_section;
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val -= s->_cooked_size;
else
- dyn.d_un.d_val -= htab->srelplt->output_section->_raw_size;
+ dyn.d_un.d_val -= s->_raw_size;
}
break;
}
@@ -2365,6 +2355,7 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
#define ELF_MAXPAGESIZE 0x1000
#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
#define elf_backend_want_got_plt 1
#define elf_backend_plt_readonly 1
#define elf_backend_want_plt_sym 0