This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
refcounts ought to start from zero
- To: binutils at sourceware dot cygnus dot com
- Subject: refcounts ought to start from zero
- From: Alan Modra <amodra at bigpond dot net dot au>
- Date: Fri, 28 Sep 2001 22:41:36 +0930
This patch is about turning code in check_relocs like the following
if (h->got.refcount == -1)
h->got.refcount = 1;
else
h->got.refcount += 1;
into the simpler
h->got.refcount += 1;
by starting refcounts at zero.
Sounds easy, but it's complicated by a number of factors. Firstly, h->got
(and h->plt) are unions; The fields are initially used as refcounts, then
later as offsets, and zero happens to be a valid offset. Depending on the
back-end, one or more of adjust_dynamic_relocs, elf_gc_common_final_link,
and size_dynamic_sections turn the refcounts into offsets. The problem
here being that should the linker need to create a symbol when the fields
are used as offsets, we need to initialise the offset to -1 as opposed to
initialising the refcount to zero. Otherwise finish_dynamic_symbol might
think the symbol has a valid got and plt offset. Problem solved by
init_refcount. Secondly, some of the ELF back-ends, eg. elf32-sparc, claim
to support garbage collection but don't implement reference counting.
These back-ends use got.offset and plt.offset as offsets right from the
beginning, and so need the fields initialised to -1. That's why it's
necessary to have elf_backend_can_refcount.
bfd/ChangeLog
* 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.
(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.
* 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.
I'll check this in soon unless someone finds fatal flaws. HP in
particular, could you verify that this doesn't break cris? elf32-cris
has a few unusual features...
--
Alan Modra
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.46
diff -u -p -r1.46 elf-bfd.h
--- elf-bfd.h 2001/09/25 04:34:50 1.46
+++ elf-bfd.h 2001/09/28 05:55:49
@@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suit
#include "bfdlink.h"
/* The number of entries in a section is its size divided by the size
- of a single entry. This is normally only applicaable to reloc and
+ of a single entry. This is normally only applicable to reloc and
symbol table sections. */
#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_size / (shdr)->sh_entsize)
@@ -223,33 +223,50 @@ struct elf_link_local_dynamic_entry
struct elf_link_hash_table
{
struct bfd_link_hash_table root;
+
/* Whether we have created the special dynamic sections required
when linking against or generating a shared object. */
boolean dynamic_sections_created;
+
/* The BFD used to hold special sections created by the linker.
This will be the first BFD found which requires these sections to
be created. */
bfd *dynobj;
+
+ /* The value to use when initialising got.refcount/offset and
+ plt.refcount/offset in an elf_link_hash_entry. Set to zero when
+ the values are refcounts. Set to -1 in size_dynamic_sections
+ when the values may be offsets. */
+ bfd_signed_vma init_refcount;
+
/* The number of symbols found in the link which must be put into
the .dynsym section. */
bfd_size_type dynsymcount;
+
/* The string table of dynamic symbols, which becomes the .dynstr
section. */
struct bfd_strtab_hash *dynstr;
+
/* The number of buckets in the hash table in the .hash section.
This is based on the number of dynamic symbols. */
bfd_size_type bucketcount;
+
/* A linked list of DT_NEEDED names found in dynamic objects
included in the link. */
struct bfd_link_needed_list *needed;
+
/* The _GLOBAL_OFFSET_TABLE_ symbol. */
struct elf_link_hash_entry *hgot;
+
/* A pointer to information used to link stabs in sections. */
PTR stab_info;
+
/* A pointer to information used to merge SEC_MERGE sections. */
PTR merge_info;
+
/* A linked list of local symbols to be added to .dynsym. */
struct elf_link_local_dynamic_entry *dynlocal;
+
/* A linked list of DT_RPATH/DT_RUNPATH names found in dynamic
objects included in the link. */
struct bfd_link_needed_list *runpath;
@@ -726,6 +743,7 @@ struct elf_backend_data
unsigned plt_not_loaded : 1;
unsigned plt_alignment : 4;
unsigned can_gc_sections : 1;
+ unsigned can_refcount : 1;
unsigned want_got_sym : 1;
unsigned want_dynbss : 1;
};
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.94
diff -u -p -r1.94 elf.c
--- elf.c 2001/09/24 01:38:31 1.94
+++ elf.c 2001/09/28 06:09:40
@@ -944,31 +944,31 @@ _bfd_elf_link_hash_newfunc (entry, table
struct bfd_hash_table *table;
const char *string;
{
- struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
-
/* Allocate the structure if it has not already been allocated by a
subclass. */
- if (ret == (struct elf_link_hash_entry *) NULL)
- ret = ((struct elf_link_hash_entry *)
- bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)));
- if (ret == (struct elf_link_hash_entry *) NULL)
- return (struct bfd_hash_entry *) ret;
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
/* Call the allocation method of the superclass. */
- ret = ((struct elf_link_hash_entry *)
- _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
- table, string));
- if (ret != (struct elf_link_hash_entry *) NULL)
+ entry = _bfd_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
{
+ struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
+ struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table;
+
/* Set local fields. */
ret->indx = -1;
ret->size = 0;
ret->dynindx = -1;
ret->dynstr_index = 0;
ret->weakdef = NULL;
- ret->got.offset = (bfd_vma) -1;
- ret->plt.offset = (bfd_vma) -1;
- ret->linker_section_pointer = (elf_linker_section_pointers_t *)0;
+ ret->got.refcount = htab->init_refcount;
+ ret->plt.refcount = htab->init_refcount;
+ ret->linker_section_pointer = NULL;
ret->verinfo.verdef = NULL;
ret->vtable_entries_used = NULL;
ret->vtable_entries_size = 0;
@@ -982,7 +982,7 @@ _bfd_elf_link_hash_newfunc (entry, table
ret->elf_link_hash_flags = ELF_LINK_NON_ELF;
}
- return (struct bfd_hash_entry *) ret;
+ return entry;
}
/* Copy data from an indirect symbol to its direct symbol, hiding the
@@ -1002,21 +1002,21 @@ _bfd_elf_link_hash_copy_indirect (dir, i
| ELF_LINK_HASH_REF_REGULAR_NONWEAK
| ELF_LINK_NON_GOT_REF));
- /* Copy over the global and procedure linkage table offset entries.
+ /* Copy over the global and procedure linkage table refcount entries.
These may have been already set up by a check_relocs routine. */
- if (dir->got.offset == (bfd_vma) -1)
+ if (dir->got.refcount <= 0)
{
- dir->got.offset = ind->got.offset;
- ind->got.offset = (bfd_vma) -1;
+ dir->got.refcount = ind->got.refcount;
+ ind->got.refcount = 0;
}
- BFD_ASSERT (ind->got.offset == (bfd_vma) -1);
+ BFD_ASSERT (ind->got.refcount <= 0);
- if (dir->plt.offset == (bfd_vma) -1)
+ if (dir->plt.refcount <= 0)
{
- dir->plt.offset = ind->plt.offset;
- ind->plt.offset = (bfd_vma) -1;
+ dir->plt.refcount = ind->plt.refcount;
+ ind->plt.refcount = 0;
}
- BFD_ASSERT (ind->plt.offset == (bfd_vma) -1);
+ BFD_ASSERT (ind->plt.refcount <= 0);
if (dir->dynindx == -1)
{
@@ -1053,6 +1053,7 @@ _bfd_elf_link_hash_table_init (table, ab
table->dynamic_sections_created = false;
table->dynobj = NULL;
+ table->init_refcount = get_elf_backend_data (abfd)->can_refcount - 1;
/* The first dynamic symbol is a dummy. */
table->dynsymcount = 1;
table->dynstr = NULL;
Index: bfd/elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.12
diff -u -p -r1.12 elf32-cris.c
--- elf32-cris.c 2001/09/24 01:38:31 1.12
+++ elf32-cris.c 2001/09/28 05:55:56
@@ -2315,10 +2315,9 @@ cris_elf_check_relocs (abfd, info, sec,
GOT entries. */
amt = symtab_hdr->sh_info + 1;
amt *= sizeof (bfd_signed_vma);
- local_got_refcounts = ((bfd_signed_vma *) bfd_alloc (abfd, amt));
+ local_got_refcounts = ((bfd_signed_vma *) bfd_zalloc (abfd, amt));
if (local_got_refcounts == NULL)
return false;
- memset (local_got_refcounts, -1, (size_t) amt);
local_got_refcounts++;
elf_local_got_refcounts (abfd) = local_got_refcounts;
@@ -2371,10 +2370,8 @@ cris_elf_check_relocs (abfd, info, sec,
if (h != NULL)
{
- if (h->got.refcount == -1)
+ if (h->got.refcount == 0)
{
- h->got.refcount = 1;
-
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
@@ -2387,16 +2384,13 @@ cris_elf_check_relocs (abfd, info, sec,
/* Allocate relocation space. */
srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
- else
- h->got.refcount++;
+ h->got.refcount++;
}
else
{
/* This is a global offset table entry for a local symbol. */
- if (local_got_refcounts[r_symndx] == -1)
+ if (local_got_refcounts[r_symndx] == 0)
{
- local_got_refcounts[r_symndx] = 1;
-
sgot->_raw_size += 4;
if (info->shared)
{
@@ -2406,8 +2400,7 @@ cris_elf_check_relocs (abfd, info, sec,
srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
}
- else
- local_got_refcounts[r_symndx]++;
+ local_got_refcounts[r_symndx]++;
}
break;
@@ -2440,10 +2433,7 @@ cris_elf_check_relocs (abfd, info, sec,
continue;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- if (h->plt.refcount == -1)
- h->plt.refcount = 1;
- else
- h->plt.refcount++;
+ h->plt.refcount++;
break;
case R_CRIS_8:
@@ -2478,10 +2468,7 @@ cris_elf_check_relocs (abfd, info, sec,
/* Make sure a plt entry is created for this symbol if it
turns out to be a function defined by a dynamic object. */
- if (h->plt.refcount == -1)
- h->plt.refcount = 1;
- else
- h->plt.refcount++;
+ h->plt.refcount++;
}
/* If we are creating a shared library and this is not a local
@@ -3013,6 +3000,7 @@ elf_cris_reloc_type_class (rela)
#define elf_backend_check_relocs cris_elf_check_relocs
#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
#define elf_backend_object_p cris_elf_object_p
#define elf_backend_final_write_processing \
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.50
diff -u -p -r1.50 elf32-hppa.c
--- elf32-hppa.c 2001/09/28 08:56:51 1.50
+++ elf32-hppa.c 2001/09/28 09:00:52
@@ -1359,10 +1359,7 @@ elf32_hppa_check_relocs (abfd, info, sec
if (h != NULL)
{
- if (h->elf.got.refcount == -1)
- h->elf.got.refcount = 1;
- else
- h->elf.got.refcount += 1;
+ h->elf.got.refcount += 1;
}
else
{
@@ -1404,13 +1401,8 @@ elf32_hppa_check_relocs (abfd, info, sec
{
if (h != NULL)
{
- if (h->elf.plt.refcount == -1)
- {
- h->elf.plt.refcount = 1;
- h->elf.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- }
- else
- h->elf.plt.refcount += 1;
+ h->elf.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->elf.plt.refcount += 1;
/* If this .plt entry is for a plabel, mark it so
that adjust_dynamic_symbol will keep the entry
@@ -4375,6 +4367,7 @@ elf32_hppa_elf_get_symbol_type (elf_sym,
#define elf_backend_reloc_type_class elf32_hppa_reloc_type_class
#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
#define elf_backend_plt_alignment 2
#define elf_backend_want_got_plt 0
#define elf_backend_plt_readonly 0
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.51
diff -u -p -r1.51 elf32-i386.c
--- elf32-i386.c 2001/09/27 16:18:42 1.51
+++ elf32-i386.c 2001/09/28 09:00:50
@@ -703,10 +703,7 @@ elf_i386_check_relocs (abfd, info, sec,
/* 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 +751,8 @@ elf_i386_check_relocs (abfd, info, sec,
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 +769,7 @@ elf_i386_check_relocs (abfd, info, sec,
/* 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 +1267,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 +1299,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)
@@ -2141,7 +2130,10 @@ elf_i386_finish_dynamic_symbol (output_b
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 +2257,7 @@ elf_i386_finish_dynamic_sections (output
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
+ asection *s;
bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
@@ -2282,10 +2275,11 @@ elf_i386_finish_dynamic_sections (output
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 +2294,11 @@ elf_i386_finish_dynamic_sections (output
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 +2360,7 @@ elf_i386_finish_dynamic_sections (output
#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
Index: bfd/elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.27
diff -u -p -r1.27 elf32-m68k.c
--- elf32-m68k.c 2001/09/24 01:38:31 1.27
+++ elf32-m68k.c 2001/09/28 05:56:06
@@ -534,10 +534,8 @@ elf_m68k_check_relocs (abfd, info, sec,
if (h != NULL)
{
- if (h->got.refcount == -1)
+ if (h->got.refcount == 0)
{
- h->got.refcount = 1;
-
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
@@ -550,8 +548,7 @@ elf_m68k_check_relocs (abfd, info, sec,
/* Allocate relocation space. */
srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
- else
- h->got.refcount++;
+ h->got.refcount++;
}
else
{
@@ -563,16 +560,13 @@ elf_m68k_check_relocs (abfd, info, sec,
size = symtab_hdr->sh_info;
size *= sizeof (bfd_signed_vma);
local_got_refcounts = ((bfd_signed_vma *)
- bfd_alloc (abfd, size));
+ bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
return false;
elf_local_got_refcounts (abfd) = local_got_refcounts;
- memset (local_got_refcounts, -1, (size_t) size);
}
- if (local_got_refcounts[r_symndx] == -1)
+ if (local_got_refcounts[r_symndx] == 0)
{
- local_got_refcounts[r_symndx] = 1;
-
sgot->_raw_size += 4;
if (info->shared)
{
@@ -582,8 +576,7 @@ elf_m68k_check_relocs (abfd, info, sec,
srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
}
- else
- local_got_refcounts[r_symndx]++;
+ local_got_refcounts[r_symndx]++;
}
break;
@@ -603,10 +596,7 @@ elf_m68k_check_relocs (abfd, info, sec,
continue;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- if (h->plt.refcount == -1)
- h->plt.refcount = 1;
- else
- h->plt.refcount++;
+ h->plt.refcount++;
break;
case R_68K_PLT8O:
@@ -631,10 +621,7 @@ elf_m68k_check_relocs (abfd, info, sec,
}
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- if (h->plt.refcount == -1)
- h->plt.refcount = 1;
- else
- h->plt.refcount++;
+ h->plt.refcount++;
break;
case R_68K_PC8:
@@ -662,10 +649,7 @@ elf_m68k_check_relocs (abfd, info, sec,
/* Make sure a plt entry is created for this symbol if
it turns out to be a function defined by a dynamic
object. */
- if (h->plt.refcount == -1)
- h->plt.refcount = 1;
- else
- h->plt.refcount++;
+ h->plt.refcount++;
}
break;
}
@@ -677,10 +661,7 @@ elf_m68k_check_relocs (abfd, info, sec,
{
/* Make sure a plt entry is created for this symbol if it
turns out to be a function defined by a dynamic object. */
- if (h->plt.refcount == -1)
- h->plt.refcount = 1;
- else
- h->plt.refcount++;
+ h->plt.refcount++;
}
/* If we are creating a shared library, we need to copy the
@@ -2357,6 +2338,7 @@ elf32_m68k_reloc_type_class (rela)
#define elf_backend_reloc_type_class elf32_m68k_reloc_type_class
#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
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.31
diff -u -p -r1.31 elf32-ppc.c
--- elf32-ppc.c 2001/09/24 01:38:31 1.31
+++ elf32-ppc.c 2001/09/28 05:56:08
@@ -2184,7 +2184,7 @@ ppc_elf_check_relocs (abfd, info, sec, r
if (h != NULL)
{
- if (h->got.refcount == -1)
+ if (h->got.refcount == 0)
{
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
@@ -2195,11 +2195,8 @@ ppc_elf_check_relocs (abfd, info, sec, r
sgot->_raw_size += 4;
/* Allocate relocation space. */
srelgot->_raw_size += sizeof (Elf32_External_Rela);
-
- h->got.refcount = 1;
}
- else
- h->got.refcount++;
+ h->got.refcount++;
}
else
{
@@ -2211,13 +2208,12 @@ ppc_elf_check_relocs (abfd, info, sec, r
size = symtab_hdr->sh_info;
size *= sizeof (bfd_signed_vma);
local_got_refcounts
- = (bfd_signed_vma *) bfd_alloc (abfd, size);
+ = (bfd_signed_vma *) bfd_zalloc (abfd, size);
if (local_got_refcounts == NULL)
return false;
elf_local_got_refcounts (abfd) = local_got_refcounts;
- memset (local_got_refcounts, -1, (size_t) size);
}
- if (local_got_refcounts[r_symndx] == -1)
+ if (local_got_refcounts[r_symndx] == 0)
{
sgot->_raw_size += 4;
@@ -2226,11 +2222,8 @@ ppc_elf_check_relocs (abfd, info, sec, r
dynamic linker can adjust this GOT entry. */
if (info->shared)
srelgot->_raw_size += sizeof (Elf32_External_Rela);
-
- local_got_refcounts[r_symndx] = 1;
}
- else
- local_got_refcounts[r_symndx]++;
+ local_got_refcounts[r_symndx]++;
}
break;
@@ -2343,13 +2336,8 @@ ppc_elf_check_relocs (abfd, info, sec, r
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
return false;
}
- if (h->plt.refcount == -1)
- {
- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- h->plt.refcount = 1;
- }
- else
- h->plt.refcount++;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->plt.refcount++;
break;
/* The following relocations don't need to propagate the
@@ -3821,6 +3809,7 @@ ppc_elf_grok_psinfo (abfd, note)
#define elf_backend_plt_not_loaded 1
#define elf_backend_got_symbol_offset 4
#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
#define elf_backend_got_header_size 12
#define elf_backend_plt_header_size PLT_INITIAL_ENTRY_SIZE
Index: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.8
diff -u -p -r1.8 elf32-s390.c
--- elf32-s390.c 2001/09/24 01:38:31 1.8
+++ elf32-s390.c 2001/09/28 05:56:10
@@ -577,10 +577,8 @@ elf_s390_check_relocs (abfd, info, sec,
if (h != NULL)
{
- if (h->got.refcount == -1)
+ if (h->got.refcount == 0)
{
- h->got.refcount = 1;
-
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
@@ -591,8 +589,7 @@ elf_s390_check_relocs (abfd, info, sec,
sgot->_raw_size += 4;
srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
- else
- h->got.refcount += 1;
+ h->got.refcount += 1;
}
else
{
@@ -604,16 +601,13 @@ elf_s390_check_relocs (abfd, info, sec,
size = symtab_hdr->sh_info;
size *= sizeof (bfd_signed_vma);
local_got_refcounts = (bfd_signed_vma *)
- bfd_alloc (abfd, size);
+ bfd_zalloc (abfd, size);
if (local_got_refcounts == NULL)
return false;
elf_local_got_refcounts (abfd) = local_got_refcounts;
- memset (local_got_refcounts, -1, (size_t) size);
}
- if (local_got_refcounts[r_symndx] == -1)
+ if (local_got_refcounts[r_symndx] == 0)
{
- local_got_refcounts[r_symndx] = 1;
-
sgot->_raw_size += 4;
if (info->shared)
{
@@ -623,8 +617,7 @@ elf_s390_check_relocs (abfd, info, sec,
srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
}
- else
- local_got_refcounts[r_symndx] += 1;
+ local_got_refcounts[r_symndx] += 1;
}
break;
@@ -642,13 +635,8 @@ elf_s390_check_relocs (abfd, info, sec,
if (h == NULL)
continue;
- if (h->plt.refcount == -1)
- {
- h->plt.refcount = 1;
- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- }
- else
- h->plt.refcount += 1;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->plt.refcount += 1;
break;
case R_390_8:
@@ -2164,6 +2152,7 @@ elf_s390_reloc_type_class (rela)
#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
Index: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.8
diff -u -p -r1.8 elf64-s390.c
--- elf64-s390.c 2001/09/24 01:38:31 1.8
+++ elf64-s390.c 2001/09/28 05:56:16
@@ -541,10 +541,8 @@ elf_s390_check_relocs (abfd, info, sec,
if (h != NULL)
{
- if (h->got.refcount == -1)
+ if (h->got.refcount == 0)
{
- h->got.refcount = 1;
-
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
@@ -555,8 +553,7 @@ elf_s390_check_relocs (abfd, info, sec,
sgot->_raw_size += 8;
srelgot->_raw_size += sizeof (Elf64_External_Rela);
}
- else
- h->got.refcount += 1;
+ h->got.refcount += 1;
}
else
{
@@ -567,16 +564,13 @@ elf_s390_check_relocs (abfd, info, sec,
size = symtab_hdr->sh_info * sizeof (bfd_vma);
local_got_refcounts = ((bfd_signed_vma *)
- bfd_alloc (abfd, size));
+ bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
return false;
elf_local_got_refcounts (abfd) = local_got_refcounts;
- memset (local_got_refcounts, -1, (size_t) size);
}
- if (local_got_refcounts[r_symndx] == -1)
+ if (local_got_refcounts[r_symndx] == 0)
{
- local_got_refcounts[r_symndx] = 1;
-
sgot->_raw_size += 8;
if (info->shared)
{
@@ -586,9 +580,7 @@ elf_s390_check_relocs (abfd, info, sec,
srelgot->_raw_size += sizeof (Elf64_External_Rela);
}
}
- else
- local_got_refcounts[r_symndx] += 1;
-
+ local_got_refcounts[r_symndx] += 1;
}
break;
@@ -608,13 +600,8 @@ elf_s390_check_relocs (abfd, info, sec,
if (h == NULL)
continue;
- if (h->plt.refcount == -1)
- {
- h->plt.refcount = 1;
- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- }
- else
- h->plt.refcount += 1;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->plt.refcount += 1;
break;
case R_390_8:
@@ -2162,6 +2149,7 @@ const struct elf_size_info s390_elf64_si
#define elf_backend_size_info s390_elf64_size_info
#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
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.27
diff -u -p -r1.27 elf64-x86-64.c
--- elf64-x86-64.c 2001/09/24 01:38:31 1.27
+++ elf64-x86-64.c 2001/09/28 05:56:17
@@ -442,10 +442,8 @@ elf64_x86_64_check_relocs (abfd, info, s
if (h != NULL)
{
- if (h->got.refcount == -1)
+ if (h->got.refcount == 0)
{
- h->got.refcount = 1;
-
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
@@ -456,8 +454,7 @@ elf64_x86_64_check_relocs (abfd, info, s
sgot->_raw_size += GOT_ENTRY_SIZE;
srelgot->_raw_size += sizeof (Elf64_External_Rela);
}
- else
- h->got.refcount += 1;
+ h->got.refcount += 1;
}
else
{
@@ -469,16 +466,13 @@ elf64_x86_64_check_relocs (abfd, info, s
size = symtab_hdr->sh_info;
size *= sizeof (bfd_signed_vma);
local_got_refcounts = ((bfd_signed_vma *)
- bfd_alloc (abfd, size));
+ bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
return false;
elf_local_got_refcounts (abfd) = local_got_refcounts;
- memset (local_got_refcounts, -1, (size_t) size);
}
- if (local_got_refcounts[r_symndx] == -1)
+ if (local_got_refcounts[r_symndx] == 0)
{
- local_got_refcounts[r_symndx] = 1;
-
sgot->_raw_size += GOT_ENTRY_SIZE;
if (info->shared)
{
@@ -488,8 +482,7 @@ elf64_x86_64_check_relocs (abfd, info, s
srelgot->_raw_size += sizeof (Elf64_External_Rela);
}
}
- else
- local_got_refcounts[r_symndx] += 1;
+ local_got_refcounts[r_symndx] += 1;
}
break;
@@ -507,10 +500,7 @@ elf64_x86_64_check_relocs (abfd, info, s
continue;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
- if (h->plt.refcount == -1)
- h->plt.refcount = 1;
- else
- h->plt.refcount += 1;
+ h->plt.refcount += 1;
break;
case R_X86_64_8:
@@ -1960,6 +1950,7 @@ elf64_x86_64_reloc_type_class (rela)
#define ELF_MAXPAGESIZE 0x100000
#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
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.108
diff -u -p -r1.108 elflink.h
--- elflink.h 2001/09/24 01:38:31 1.108
+++ elflink.h 2001/09/28 05:56:25
@@ -2920,6 +2920,10 @@ NAME(bfd_elf,size_dynamic_sections) (out
if (! is_elf_hash_table (info))
return false;
+ /* Any syms created from now on start with -1 in
+ got.refcount/offset and plt.refcount/offset. */
+ elf_hash_table (info)->init_refcount = -1;
+
/* The backend may have to create some sections regardless of whether
we're dynamic or not. */
bed = get_elf_backend_data (output_bfd);
Index: bfd/elfxx-target.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-target.h,v
retrieving revision 1.29
diff -u -p -r1.29 elfxx-target.h
--- elfxx-target.h 2001/09/18 09:57:24 1.29
+++ elfxx-target.h 2001/09/28 05:56:28
@@ -102,6 +102,9 @@ Foundation, Inc., 59 Temple Place - Suit
#ifndef elf_backend_can_gc_sections
#define elf_backend_can_gc_sections 0
#endif
+#ifndef elf_backend_can_refcount
+#define elf_backend_can_refcount 0
+#endif
#ifndef elf_backend_want_got_sym
#define elf_backend_want_got_sym 1
#endif
@@ -459,6 +462,7 @@ static const struct elf_backend_data elf
elf_backend_plt_not_loaded,
elf_backend_plt_alignment,
elf_backend_can_gc_sections,
+ elf_backend_can_refcount,
elf_backend_want_dynbss,
elf_backend_want_got_sym
};
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.17
diff -u -p -r1.17 linker.c
--- linker.c 2001/09/21 02:12:28 1.17
+++ linker.c 2001/09/28 05:56:30
@@ -445,28 +445,27 @@ _bfd_link_hash_newfunc (entry, table, st
struct bfd_hash_table *table;
const char *string;
{
- struct bfd_link_hash_entry *ret = (struct bfd_link_hash_entry *) entry;
-
/* Allocate the structure if it has not already been allocated by a
subclass. */
- if (ret == (struct bfd_link_hash_entry *) NULL)
- ret = ((struct bfd_link_hash_entry *)
- bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry)));
- if (ret == (struct bfd_link_hash_entry *) NULL)
- return NULL;
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
/* Call the allocation method of the superclass. */
- ret = ((struct bfd_link_hash_entry *)
- bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
-
- if (ret)
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry)
{
+ struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) entry;
+
/* Initialize the local fields. */
- ret->type = bfd_link_hash_new;
- ret->next = NULL;
+ h->type = bfd_link_hash_new;
+ h->next = NULL;
}
- return (struct bfd_hash_entry *) ret;
+ return entry;
}
/* Initialize a link hash table. The BFD argument is the one
@@ -642,30 +641,29 @@ _bfd_generic_link_hash_newfunc (entry, t
struct bfd_hash_table *table;
const char *string;
{
- struct generic_link_hash_entry *ret =
- (struct generic_link_hash_entry *) entry;
-
/* Allocate the structure if it has not already been allocated by a
subclass. */
- if (ret == (struct generic_link_hash_entry *) NULL)
- ret = ((struct generic_link_hash_entry *)
- bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry)));
- if (ret == (struct generic_link_hash_entry *) NULL)
- return NULL;
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct generic_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
/* Call the allocation method of the superclass. */
- ret = ((struct generic_link_hash_entry *)
- _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
- table, string));
-
- if (ret)
+ entry = _bfd_link_hash_newfunc (entry, table, string);
+ if (entry)
{
+ struct generic_link_hash_entry *ret;
+
/* Set local fields. */
+ ret = (struct generic_link_hash_entry *) entry;
ret->written = false;
ret->sym = NULL;
}
- return (struct bfd_hash_entry *) ret;
+ return entry;
}
/* Create an generic link hash table. */