#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf-vxworks.h"
bfd_boolean
elf_vxworks_add_symbol_hook (bfd *abfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info,
Elf_Internal_Sym *sym,
const char **namep,
flagword *flagsp,
asection **secp ATTRIBUTE_UNUSED,
bfd_vma *valp ATTRIBUTE_UNUSED)
{
if ((info->shared || abfd->flags & DYNAMIC)
&& (strcmp (*namep, "__GOTT_INDEX__") == 0
|| strcmp (*namep, "__GOTT_BASE__") == 0))
{
sym->st_info = ELF_ST_INFO (STB_WEAK, ELF_ST_TYPE (sym->st_info));
*flagsp |= BSF_WEAK;
}
return TRUE;
}
bfd_boolean
elf_vxworks_link_output_symbol_hook (const char *name,
Elf_Internal_Sym *sym)
{
if (strcmp (name, "__GOTT_INDEX__") == 0
|| strcmp (name, "__GOTT_BASE__") == 0)
sym->st_info = ELF_ST_INFO (STB_GLOBAL, ELF_ST_TYPE (sym->st_info));
return TRUE;
}
bfd_boolean
elf_vxworks_emit_relocs (bfd *output_bfd,
asection *input_section,
Elf_Internal_Shdr *input_rel_hdr,
Elf_Internal_Rela *internal_relocs,
struct elf_link_hash_entry **rel_hash)
{
const struct elf_backend_data *bed;
Elf_Internal_Rela *irela;
Elf_Internal_Rela *irelaend;
int j;
bed = get_elf_backend_data (output_bfd);
irela = internal_relocs;
irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
* bed->s->int_rels_per_ext_rel);
while (irela < irelaend)
{
if ((output_bfd->flags & (DYNAMIC|EXEC_P))
&& *rel_hash
&& (*rel_hash)->def_dynamic
&& !(*rel_hash)->def_regular
&& (*rel_hash)->root.type == bfd_link_hash_defined
&& (*rel_hash)->root.u.def.section->output_section != NULL)
{
for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
{
asection *sec = (*rel_hash)->root.u.def.section;
int this_idx =
elf_section_data (sec->output_section)->this_idx;
irela[j].r_info = ELF32_R_INFO (this_idx,
ELF32_R_TYPE (irela[j].r_info));
irela[j].r_addend += (*rel_hash)->root.u.def.value;
irela[j].r_addend += sec->output_offset;
}
*rel_hash = NULL;
}
irela += bed->s->int_rels_per_ext_rel;
rel_hash++;
}
return _bfd_elf_link_output_relocs (output_bfd, input_section,
input_rel_hdr, internal_relocs,
rel_hash);
}
void
elf_vxworks_final_write_processing (bfd *abfd,
bfd_boolean linker ATTRIBUTE_UNUSED)
{
asection * sec;
struct bfd_elf_section_data *d;
sec = bfd_get_section_by_name (abfd, ".rel.plt.unloaded");
if (!sec)
sec = bfd_get_section_by_name (abfd, ".rela.plt.unloaded");
if (!sec)
return;
d = elf_section_data (sec);
d->this_hdr.sh_link = elf_tdata (abfd)->symtab_section;
sec = bfd_get_section_by_name (abfd, ".plt");
if (sec)
d->this_hdr.sh_info = elf_section_data (sec)->this_idx;
}