* elf-bfd.h (struct elf_backend_data):

elf_backend_emit_relocs: New field: Function for emitting
        relocs.
        elf_backend_count_relocs: New field: Function for determining
        the number of relocs to be emitted.
        * elfxx-target.h: Provide default (NULL) values for
        elf_backend_emit_relocs and elf_backend_count_relocs.
        * elflink.h (elf_link_size_reloc_section): Make the hash table
        big enough to hold the relocs counted by either reloc_count or
        o->reloc_count.
        (elf_bfd_final_link) emit_relocs: New boolean, set if relocs
        should be emitted, either because of a command line option
        stored in the info structure or because the target provides a
        special reloc emitting function.
        If the target provides a reloc counting function use it,
        unless performing a relocatable link or emitting all relocs.
        Also set the SEC_RELOC flag on any output section which will
        contain relocs.
        (elf_link_input_bfd): emit_relocs: New boolean, set if relocs
        should be emitted, either because of a command line option
        stored in the info structure or because the target provides a
        special reloc emitting function.
        If the target provides a reloc emitting function, use it,
        unless performing a relocatable link or emitting all relocs.
This commit is contained in:
Catherine Moore 2001-06-20 20:34:10 +00:00
parent 161d71a639
commit 9317eaccac
4 changed files with 104 additions and 17 deletions

View File

@ -1,3 +1,30 @@
2001-06-20 Catherine Moore <clm@redhat.com>
* elf-bfd.h (struct elf_backend_data):
elf_backend_emit_relocs: New field: Function for emitting
relocs.
elf_backend_count_relocs: New field: Function for determining
the number of relocs to be emitted.
* elfxx-target.h: Provide default (NULL) values for
elf_backend_emit_relocs and elf_backend_count_relocs.
* elflink.h (elf_link_size_reloc_section): Make the hash table
big enough to hold the relocs counted by either reloc_count or
o->reloc_count.
(elf_bfd_final_link) emit_relocs: New boolean, set if relocs
should be emitted, either because of a command line option
stored in the info structure or because the target provides a
special reloc emitting function.
If the target provides a reloc counting function use it,
unless performing a relocatable link or emitting all relocs.
Also set the SEC_RELOC flag on any output section which will
contain relocs.
(elf_link_input_bfd): emit_relocs: New boolean, set if relocs
should be emitted, either because of a command line option
stored in the info structure or because the target provides a
special reloc emitting function.
If the target provides a reloc emitting function, use it,
unless performing a relocatable link or emitting all relocs.
2001-06-20 H.J. Lu <hjl@gnu.org>
* elf32-i386.c (elf_i386_size_dynamic_sections): Always

View File

@ -618,6 +618,16 @@ struct elf_backend_data
void (*elf_backend_hide_symbol)
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
/* Emit relocations. Overrides default routine for emitting relocs,
except during a relocatable link, or if all relocs are being emitted. */
void (*elf_backend_emit_relocs)
PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *));
/* Count relocations. Not called for relocatable links
or if all relocs are being preserved in the output. */
unsigned int (*elf_backend_count_relocs)
PARAMS ((asection *, Elf_Internal_Rela *));
/* The swapping table to use when dealing with ECOFF information.
Used for the MIPS ELF .mdebug section. */
const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;

View File

@ -4135,6 +4135,7 @@ elf_link_size_reloc_section (abfd, rel_hdr, o)
asection *o;
{
unsigned reloc_count;
unsigned num_rel_hashes;
/* Figure out how many relocations there will be. */
if (rel_hdr == &elf_section_data (o)->rel_hdr)
@ -4142,6 +4143,10 @@ elf_link_size_reloc_section (abfd, rel_hdr, o)
else
reloc_count = elf_section_data (o)->rel_count2;
num_rel_hashes = o->reloc_count;
if (num_rel_hashes < reloc_count)
num_rel_hashes = reloc_count;
/* That allows us to calculate the size of the section. */
rel_hdr->sh_size = rel_hdr->sh_entsize * reloc_count;
@ -4155,14 +4160,15 @@ elf_link_size_reloc_section (abfd, rel_hdr, o)
/* We only allocate one set of hash entries, so we only do it the
first time we are called. */
if (elf_section_data (o)->rel_hashes == NULL)
if (elf_section_data (o)->rel_hashes == NULL
&& num_rel_hashes)
{
struct elf_link_hash_entry **p;
p = ((struct elf_link_hash_entry **)
bfd_zmalloc (o->reloc_count
bfd_zmalloc (num_rel_hashes
* sizeof (struct elf_link_hash_entry *)));
if (p == NULL && o->reloc_count != 0)
if (p == NULL)
return false;
elf_section_data (o)->rel_hashes = p;
@ -4268,6 +4274,7 @@ elf_bfd_final_link (abfd, info)
struct bfd_link_info *info;
{
boolean dynamic;
boolean emit_relocs;
bfd *dynobj;
struct elf_final_link_info finfo;
register asection *o;
@ -4292,6 +4299,10 @@ elf_bfd_final_link (abfd, info)
dynamic = elf_hash_table (info)->dynamic_sections_created;
dynobj = elf_hash_table (info)->dynobj;
emit_relocs = (info->relocateable
|| info->emitrelocations
|| bed->elf_backend_emit_relocs);
finfo.info = info;
finfo.output_bfd = abfd;
finfo.symstrtab = elf_stringtab_init ();
@ -4357,6 +4368,20 @@ elf_bfd_final_link (abfd, info)
if (info->relocateable || info->emitrelocations)
o->reloc_count += sec->reloc_count;
else if (bed->elf_backend_count_relocs)
{
Elf_Internal_Rela * relocs;
relocs = (NAME(_bfd_elf,link_read_relocs)
(abfd, sec, (PTR) NULL,
(Elf_Internal_Rela *) NULL, info->keep_memory));
o->reloc_count += (*bed->elf_backend_count_relocs)
(sec, relocs);
if (!info->keep_memory)
free (relocs);
}
if (sec->_raw_size > max_contents_size)
max_contents_size = sec->_raw_size;
@ -4427,7 +4452,7 @@ elf_bfd_final_link (abfd, info)
/* Figure out how many relocations we will have in each section.
Just using RELOC_COUNT isn't good enough since that doesn't
maintain a separate value for REL vs. RELA relocations. */
if (info->relocateable || info->emitrelocations)
if (emit_relocs)
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
for (o = sub->sections; o != NULL; o = o->next)
{
@ -4467,6 +4492,7 @@ elf_bfd_final_link (abfd, info)
*rel_count += NUM_SHDR_ENTRIES (& esdi->rel_hdr);
if (esdi->rel_hdr2)
*rel_count2 += NUM_SHDR_ENTRIES (esdi->rel_hdr2);
output_section->flags |= SEC_RELOC;
}
}
@ -4533,7 +4559,8 @@ elf_bfd_final_link (abfd, info)
/* Start writing out the symbol table. The first symbol is always a
dummy symbol. */
if (info->strip != strip_all || info->relocateable || info->emitrelocations)
if (info->strip != strip_all
|| emit_relocs)
{
elfsym.st_value = 0;
elfsym.st_size = 0;
@ -4566,7 +4593,8 @@ elf_bfd_final_link (abfd, info)
symbols have no names. We store the index of each one in the
index field of the section, so that we can find it again when
outputting relocs. */
if (info->strip != strip_all || info->relocateable || info->emitrelocations)
if (info->strip != strip_all
|| emit_relocs)
{
elfsym.st_size = 0;
elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
@ -5018,7 +5046,7 @@ elf_bfd_final_link (abfd, info)
{
if ((o->flags & SEC_RELOC) != 0
&& elf_section_data (o)->rel_hashes != NULL)
free (elf_section_data (o)->rel_hashes);
free (elf_section_data (o)->rel_hashes);
}
elf_tdata (abfd)->linker = true;
@ -5572,6 +5600,7 @@ elf_link_input_bfd (finfo, input_bfd)
asection **ppsection;
asection *o;
struct elf_backend_data *bed;
boolean emit_relocs;
output_bfd = finfo->output_bfd;
bed = get_elf_backend_data (output_bfd);
@ -5583,6 +5612,10 @@ elf_link_input_bfd (finfo, input_bfd)
if ((input_bfd->flags & DYNAMIC) != 0)
return true;
emit_relocs = (finfo->info->relocateable
|| finfo->info->emitrelocations
|| bed->elf_backend_emit_relocs);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (elf_bad_symtab (input_bfd))
{
@ -5860,13 +5893,16 @@ elf_link_input_bfd (finfo, input_bfd)
finfo->sections))
return false;
if (finfo->info->relocateable || finfo->info->emitrelocations)
if (emit_relocs)
{
Elf_Internal_Rela *irela;
Elf_Internal_Rela *irelaend;
struct elf_link_hash_entry **rel_hash;
Elf_Internal_Shdr *input_rel_hdr;
unsigned int next_erel;
void (* reloc_emitter) PARAMS ((bfd *, asection *,
Elf_Internal_Shdr *,
Elf_Internal_Rela *));
/* Adjust the reloc addresses and symbol indices. */
@ -6008,17 +6044,23 @@ elf_link_input_bfd (finfo, input_bfd)
}
/* Swap out the relocs. */
if (bed->elf_backend_emit_relocs
&& ! (finfo->info->relocateable || finfo->info->emitrelocations))
reloc_emitter = bed->elf_backend_emit_relocs;
else
reloc_emitter = elf_link_output_relocs;
input_rel_hdr = &elf_section_data (o)->rel_hdr;
elf_link_output_relocs (output_bfd, o,
input_rel_hdr,
internal_relocs);
internal_relocs += NUM_SHDR_ENTRIES (input_rel_hdr)
* bed->s->int_rels_per_ext_rel;
(*reloc_emitter) (output_bfd, o, input_rel_hdr, internal_relocs);
input_rel_hdr = elf_section_data (o)->rel_hdr2;
if (input_rel_hdr)
elf_link_output_relocs (output_bfd, o,
input_rel_hdr,
internal_relocs);
if (input_rel_hdr)
{
internal_relocs += NUM_SHDR_ENTRIES (input_rel_hdr)
* bed->s->int_rels_per_ext_rel;
reloc_emitter (output_bfd, o, input_rel_hdr, internal_relocs);
}
}
}

View File

@ -323,6 +323,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef elf_backend_hide_symbol
#define elf_backend_hide_symbol _bfd_elf_link_hash_hide_symbol
#endif
#ifndef elf_backend_emit_relocs
#define elf_backend_emit_relocs NULL
#endif
#ifndef elf_backend_count_relocs
#define elf_backend_count_relocs NULL
#endif
/* Previously, backends could only use SHT_REL or SHT_RELA relocation
sections, but not both. They defined USE_REL to indicate SHT_REL
@ -404,6 +410,8 @@ static CONST struct elf_backend_data elfNN_bed =
elf_backend_output_arch_syms,
elf_backend_copy_indirect_symbol,
elf_backend_hide_symbol,
elf_backend_emit_relocs,
elf_backend_count_relocs,
elf_backend_ecoff_debug_swap,
ELF_MACHINE_ALT1,
ELF_MACHINE_ALT2,