aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-microblaze.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf32-microblaze.c')
-rw-r--r--bfd/elf32-microblaze.c228
1 files changed, 95 insertions, 133 deletions
diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
index 5c66808..c700bcb 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
@@ -731,11 +731,6 @@ struct elf32_mb_link_hash_table
struct elf_link_hash_table elf;
/* Short-cuts to get to dynamic linker sections. */
- asection *sgot;
- asection *sgotplt;
- asection *srelgot;
- asection *splt;
- asection *srelplt;
asection *sdynbss;
asection *srelbss;
@@ -1152,8 +1147,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
break; /* Do nothing. */
case (int) R_MICROBLAZE_GOTPC_64:
- relocation = htab->sgotplt->output_section->vma
- + htab->sgotplt->output_offset;
+ relocation = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset);
relocation -= (input_section->output_section->vma
+ input_section->output_offset
+ offset + INST_WORD_SIZE);
@@ -1167,11 +1162,11 @@ microblaze_elf_relocate_section (bfd *output_bfd,
case (int) R_MICROBLAZE_PLT_64:
{
bfd_vma immediate;
- if (htab->splt != NULL && h != NULL
+ if (htab->elf.splt != NULL && h != NULL
&& h->plt.offset != (bfd_vma) -1)
{
- relocation = (htab->splt->output_section->vma
- + htab->splt->output_offset
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ h->plt.offset);
unresolved_reloc = FALSE;
immediate = relocation - (input_section->output_section->vma
@@ -1211,7 +1206,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
bfd_vma static_value;
bfd_boolean need_relocs = FALSE;
- if (htab->sgot == NULL)
+ if (htab->elf.sgot == NULL)
abort ();
indx = 0;
@@ -1227,10 +1222,11 @@ microblaze_elf_relocate_section (bfd *output_bfd,
offp = &htab->tlsld_got.offset;
else if (h != NULL)
{
- if (htab->sgotplt != NULL && h->got.offset != (bfd_vma) -1)
- offp = &h->got.offset;
+ if (htab->elf.sgotplt != NULL
+ && h->got.offset != (bfd_vma) -1)
+ offp = &h->got.offset;
else
- abort ();
+ abort ();
}
else
{
@@ -1277,97 +1273,95 @@ microblaze_elf_relocate_section (bfd *output_bfd,
{
bfd_vma got_offset;
- got_offset = (htab->sgot->output_section->vma
- + htab->sgot->output_offset
+ got_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ off);
/* Process module-id */
if (IS_TLS_LD(tls_type))
{
if (! bfd_link_pic (info))
- {
- bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
- }
+ bfd_put_32 (output_bfd, 1,
+ htab->elf.sgot->contents + off);
else
- {
- microblaze_elf_output_dynamic_relocation (output_bfd,
- htab->srelgot, htab->srelgot->reloc_count++,
- /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
- got_offset, 0);
- }
+ microblaze_elf_output_dynamic_relocation
+ (output_bfd,
+ htab->elf.srelgot,
+ htab->elf.srelgot->reloc_count++,
+ /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
+ got_offset, 0);
}
else if (IS_TLS_GD(tls_type))
{
if (! need_relocs)
- {
- bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
- }
+ bfd_put_32 (output_bfd, 1,
+ htab->elf.sgot->contents + off);
else
- {
- microblaze_elf_output_dynamic_relocation (output_bfd,
- htab->srelgot,
- htab->srelgot->reloc_count++,
- /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
- got_offset, indx ? 0 : static_value);
- }
+ microblaze_elf_output_dynamic_relocation
+ (output_bfd,
+ htab->elf.srelgot,
+ htab->elf.srelgot->reloc_count++,
+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
+ got_offset, indx ? 0 : static_value);
}
/* Process Offset */
- if (htab->srelgot == NULL)
+ if (htab->elf.srelgot == NULL)
abort ();
- got_offset = (htab->sgot->output_section->vma
- + htab->sgot->output_offset
+ got_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ off2);
if (IS_TLS_LD(tls_type))
{
/* For LD, offset should be 0 */
*offp |= 1;
- bfd_put_32 (output_bfd, 0, htab->sgot->contents + off2);
+ bfd_put_32 (output_bfd, 0,
+ htab->elf.sgot->contents + off2);
}
else if (IS_TLS_GD(tls_type))
{
*offp |= 1;
static_value -= dtprel_base(info);
if (need_relocs)
- {
- microblaze_elf_output_dynamic_relocation (output_bfd,
- htab->srelgot, htab->srelgot->reloc_count++,
- /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
- got_offset, indx ? 0 : static_value);
- }
+ microblaze_elf_output_dynamic_relocation
+ (output_bfd,
+ htab->elf.srelgot,
+ htab->elf.srelgot->reloc_count++,
+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
+ got_offset, indx ? 0 : static_value);
else
- {
- bfd_put_32 (output_bfd, static_value,
- htab->sgot->contents + off2);
- }
+ bfd_put_32 (output_bfd, static_value,
+ htab->elf.sgot->contents + off2);
}
else
{
- bfd_put_32 (output_bfd, static_value,
- htab->sgot->contents + off2);
+ bfd_put_32 (output_bfd, static_value,
+ htab->elf.sgot->contents + off2);
- /* Relocs for dyn symbols generated by
- finish_dynamic_symbols */
- if (bfd_link_pic (info) && h == NULL)
- {
- *offp |= 1;
- microblaze_elf_output_dynamic_relocation (output_bfd,
- htab->srelgot, htab->srelgot->reloc_count++,
- /* symindex= */ indx, R_MICROBLAZE_REL,
- got_offset, static_value);
- }
+ /* Relocs for dyn symbols generated by
+ finish_dynamic_symbols */
+ if (bfd_link_pic (info) && h == NULL)
+ {
+ *offp |= 1;
+ microblaze_elf_output_dynamic_relocation
+ (output_bfd,
+ htab->elf.srelgot,
+ htab->elf.srelgot->reloc_count++,
+ /* symindex= */ indx, R_MICROBLAZE_REL,
+ got_offset, static_value);
+ }
}
}
/* 4. Fixup Relocation with GOT offset value
Compute relative address of GOT entry for applying
the current relocation */
- relocation = htab->sgot->output_section->vma
- + htab->sgot->output_offset
+ relocation = htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ off
- - htab->sgotplt->output_section->vma
- - htab->sgotplt->output_offset;
+ - htab->elf.sgotplt->output_section->vma
+ - htab->elf.sgotplt->output_offset;
/* Apply Current Relocation */
bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
@@ -1384,22 +1378,23 @@ microblaze_elf_relocate_section (bfd *output_bfd,
bfd_vma immediate;
unsigned short lo, high;
relocation += addend;
- relocation -= htab->sgotplt->output_section->vma
- + htab->sgotplt->output_offset;
+ relocation -= (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset);
/* Write this value into correct location. */
immediate = relocation;
lo = immediate & 0x0000ffff;
high = (immediate >> 16) & 0x0000ffff;
bfd_put_16 (input_bfd, high, contents + offset + endian);
- bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian);
+ bfd_put_16 (input_bfd, lo,
+ contents + offset + INST_WORD_SIZE + endian);
break;
}
case (int) R_MICROBLAZE_GOTOFF_32:
{
relocation += addend;
- relocation -= htab->sgotplt->output_section->vma
- + htab->sgotplt->output_offset;
+ relocation -= (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset);
/* Write this value into correct location. */
bfd_put_32 (input_bfd, relocation, contents + offset);
break;
@@ -2248,39 +2243,6 @@ microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
#define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
#define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
-/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
- shortcuts to them in our hash table. */
-
-static bfd_boolean
-create_got_section (bfd *dynobj, struct bfd_link_info *info)
-{
- struct elf32_mb_link_hash_table *htab;
-
- if (! _bfd_elf_create_got_section (dynobj, info))
- return FALSE;
- htab = elf32_mb_hash_table (info);
- if (htab == NULL)
- return FALSE;
-
- htab->sgot = bfd_get_linker_section (dynobj, ".got");
- htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
- if (!htab->sgot || !htab->sgotplt)
- return FALSE;
-
- if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL)
- htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got");
- if (htab->srelgot == NULL
- || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY)
- || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
- return FALSE;
- return TRUE;
-}
-
static bfd_boolean
update_local_sym_info (bfd *abfd,
Elf_Internal_Shdr *symtab_hdr,
@@ -2396,11 +2358,11 @@ microblaze_elf_check_relocs (bfd * abfd,
sec->has_tls_reloc = 1;
/* Fall through. */
case R_MICROBLAZE_GOT_64:
- if (htab->sgot == NULL)
+ if (htab->elf.sgot == NULL)
{
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
- if (!create_got_section (htab->elf.dynobj, info))
+ if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
return FALSE;
}
if (h != NULL)
@@ -2550,19 +2512,17 @@ microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
if (htab == NULL)
return FALSE;
- if (!htab->sgot && !create_got_section (dynobj, info))
+ if (!htab->elf.sgot && !_bfd_elf_create_got_section (dynobj, info))
return FALSE;
if (!_bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE;
- htab->splt = bfd_get_linker_section (dynobj, ".plt");
- htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
if (!bfd_link_pic (info))
htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
- if (!htab->splt || !htab->srelplt || !htab->sdynbss
+ if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
|| (!bfd_link_pic (info) && !htab->srelbss))
abort ();
@@ -2793,7 +2753,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
{
- asection *s = htab->splt;
+ asection *s = htab->elf.splt;
/* The first entry in .plt is reserved. */
if (s->size == 0)
@@ -2818,10 +2778,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
- htab->sgotplt->size += 4;
+ htab->elf.sgotplt->size += 4;
/* We also need to make an entry in the .rel.plt section. */
- htab->srelplt->size += sizeof (Elf32_External_Rela);
+ htab->elf.srelplt->size += sizeof (Elf32_External_Rela);
}
else
{
@@ -2878,10 +2838,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
}
else
{
- s = htab->sgot;
+ s = htab->elf.sgot;
h->got.offset = s->size;
s->size += need;
- htab->srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
+ htab->elf.srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
}
}
else
@@ -3025,8 +2985,8 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
locsymcount = symtab_hdr->sh_info;
end_local_got = local_got + locsymcount;
lgot_masks = (unsigned char *) end_local_got;
- s = htab->sgot;
- srel = htab->srelgot;
+ s = htab->elf.sgot;
+ srel = htab->elf.srelgot;
for (; local_got < end_local_got; ++local_got, ++lgot_masks)
{
@@ -3066,10 +3026,10 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if (htab->tlsld_got.refcount > 0)
{
- htab->tlsld_got.offset = htab->sgot->size;
- htab->sgot->size += 8;
+ htab->tlsld_got.offset = htab->elf.sgot->size;
+ htab->elf.sgot->size += 8;
if (bfd_link_pic (info))
- htab->srelgot->size += sizeof (Elf32_External_Rela);
+ htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
}
else
htab->tlsld_got.offset = (bfd_vma) -1;
@@ -3077,8 +3037,8 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Make space for the trailing nop in .plt. */
- if (htab->splt->size > 0)
- htab->splt->size += 4;
+ if (htab->elf.splt->size > 0)
+ htab->elf.splt->size += 4;
}
/* The check_relocs and adjust_dynamic_symbol entry points have
@@ -3118,7 +3078,9 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
s->reloc_count = 0;
}
}
- else if (s != htab->splt && s != htab->sgot && s != htab->sgotplt)
+ else if (s != htab->elf.splt
+ && s != htab->elf.sgot
+ && s != htab->elf.sgotplt)
{
/* It's not one of our sections, so don't allocate space. */
continue;
@@ -3162,7 +3124,7 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
return FALSE;
- if (htab->splt->size != 0)
+ if (htab->elf.splt->size != 0)
{
if (!add_dynamic_entry (DT_PLTGOT, 0)
|| !add_dynamic_entry (DT_PLTRELSZ, 0)
@@ -3213,9 +3175,9 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
it up. */
BFD_ASSERT (h->dynindx != -1);
- splt = htab->splt;
- srela = htab->srelplt;
- sgotplt = htab->sgotplt;
+ splt = htab->elf.splt;
+ srela = htab->elf.srelplt;
+ sgotplt = htab->elf.sgotplt;
BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
@@ -3224,7 +3186,7 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
/* For non-PIC objects we need absolute address of the GOT entry. */
if (!bfd_link_pic (info))
- got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset;
+ got_addr += sgotplt->output_section->vma + sgotplt->output_offset;
/* Fill in the entry in the procedure linkage table. */
bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
@@ -3276,8 +3238,8 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
/* This symbol has an entry in the global offset table. Set it
up. */
- sgot = htab->sgot;
- srela = htab->srelgot;
+ sgot = htab->elf.sgot;
+ srela = htab->elf.srelgot;
BFD_ASSERT (sgot != NULL && srela != NULL);
offset = (sgot->output_section->vma + sgot->output_offset
@@ -3369,7 +3331,7 @@ microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
asection *splt;
Elf32_External_Dyn *dyncon, *dynconend;
- splt = bfd_get_linker_section (dynobj, ".plt");
+ splt = htab->elf.splt;
BFD_ASSERT (splt != NULL && sdyn != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
@@ -3424,7 +3386,7 @@ microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
/* Set the first entry in the global offset table to the address of
the dynamic section. */
- sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ sgot = htab->elf.sgotplt;
if (sgot && sgot->size > 0)
{
if (sdyn == NULL)
@@ -3436,8 +3398,8 @@ microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
}
- if (htab->sgot && htab->sgot->size > 0)
- elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
+ if (htab->elf.sgot && htab->elf.sgot->size > 0)
+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
return TRUE;
}