* 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:
parent
161d71a639
commit
9317eaccac
4 changed files with 104 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue