/* Alpha specific support for 64-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@tamu.edu>.
static bfd_boolean elf64_alpha_section_from_shdr
PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
static bfd_boolean elf64_alpha_section_flags
- PARAMS ((flagword *, Elf_Internal_Shdr *));
+ PARAMS ((flagword *, const Elf_Internal_Shdr *));
static bfd_boolean elf64_alpha_fake_sections
PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
static bfd_boolean elf64_alpha_create_got_section
static bfd_boolean elf64_alpha_size_rela_got_1
PARAMS ((struct alpha_elf_link_hash_entry *, struct bfd_link_info *));
static bfd_boolean elf64_alpha_add_symbol_hook
- PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
static struct alpha_elf_got_entry *get_got_entry
PARAMS ((bfd *, struct alpha_elf_link_hash_entry *, unsigned long,
elf64_alpha_object_p (abfd)
bfd *abfd;
{
- /* Allocate our special target data. */
- struct alpha_elf_obj_tdata *new_tdata;
- bfd_size_type amt = sizeof (struct alpha_elf_obj_tdata);
- new_tdata = bfd_zalloc (abfd, amt);
- if (new_tdata == NULL)
- return FALSE;
- new_tdata->root = *abfd->tdata.elf_obj_data;
- abfd->tdata.any = new_tdata;
-
/* Set the right machine number for an Alpha ELF file. */
return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
}
{
bfd_reloc_status_type ret;
bfd_vma gp, relocation;
+ bfd_vma high_address;
bfd_byte *p_ldah, *p_lda;
/* Don't do anything if we're not doing a final link. */
return bfd_reloc_ok;
}
- if (reloc_entry->address > input_section->_cooked_size ||
- reloc_entry->address + reloc_entry->addend > input_section->_cooked_size)
+ high_address = bfd_get_section_limit (abfd, input_section);
+ if (reloc_entry->address > high_address
+ || reloc_entry->address + reloc_entry->addend > high_address)
return bfd_reloc_outofrange;
/* The gp used in the portion of the output object to which this
|| sec->reloc_count == 0)
return TRUE;
- /* If this is the first time we have been called for this section,
- initialize the cooked size. */
- if (sec->_cooked_size == 0)
- sec->_cooked_size = sec->_raw_size;
-
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
info.contents = elf_section_data (sec)->this_hdr.contents;
else
{
- info.contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
- if (info.contents == NULL)
- goto error_return;
-
- if (! bfd_get_section_contents (abfd, sec, info.contents,
- (file_ptr) 0, sec->_raw_size))
+ if (!bfd_malloc_and_get_section (abfd, sec, &info.contents))
goto error_return;
}
static bfd_boolean
elf64_alpha_section_flags (flags, hdr)
flagword *flags;
- Elf_Internal_Shdr *hdr;
+ const Elf_Internal_Shdr *hdr;
{
if (hdr->sh_flags & SHF_ALPHA_GPREL)
*flags |= SEC_SMALL_DATA;
elf64_alpha_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
bfd *abfd;
struct bfd_link_info *info;
- const Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *sym;
const char **namep ATTRIBUTE_UNUSED;
flagword *flagsp ATTRIBUTE_UNUSED;
asection **secp;
h->type = STT_OBJECT;
if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
s = bfd_make_section (abfd, ".rela.plt");
h->type = STT_OBJECT;
if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
elf_hash_table (info)->hgot = h;
#undef READ
debug->fdr = NULL;
- debug->adjust = NULL;
return TRUE;
{
/* If this is a shared library, and the section is to be
loaded into memory, we need a RELATIVE reloc. */
- sreloc->_raw_size += sizeof (Elf64_External_Rela);
+ sreloc->size += sizeof (Elf64_External_Rela);
if ((sec->flags & (SEC_READONLY | SEC_ALLOC))
== (SEC_READONLY | SEC_ALLOC))
info->flags |= DF_TEXTREL;
return FALSE;
/* The first bit of the .plt is reserved. */
- if (s->_raw_size == 0)
- s->_raw_size = PLT_HEADER_SIZE;
+ if (s->size == 0)
+ s->size = PLT_HEADER_SIZE;
- h->plt.offset = s->_raw_size;
- s->_raw_size += PLT_ENTRY_SIZE;
+ h->plt.offset = s->size;
+ s->size += PLT_ENTRY_SIZE;
/* If this symbol is not defined in a regular file, and we are not
generating a shared library, then set the symbol to the location
/* We also need a JMP_SLOT entry in the .rela.plt section. */
s = bfd_get_section_by_name (dynobj, ".rela.plt");
BFD_ASSERT (s != NULL);
- s->_raw_size += sizeof (Elf64_External_Rela);
+ s->size += sizeof (Elf64_External_Rela);
return TRUE;
}
struct alpha_elf_link_hash_entry *h;
PTR arg ATTRIBUTE_UNUSED;
{
+ bfd_boolean result = TRUE;
struct alpha_elf_got_entry *gotent;
if (h->root.root.type == bfd_link_hash_warning)
for (gotent = h->got_entries; gotent; gotent = gotent->next)
if (gotent->use_count > 0)
{
- bfd_size_type *plge
- = &alpha_elf_tdata (gotent->gotobj)->got->_raw_size;
+ struct alpha_elf_obj_tdata *td;
+ bfd_size_type *plge;
+ td = alpha_elf_tdata (gotent->gotobj);
+ if (td == NULL)
+ {
+ _bfd_error_handler (_("Symbol %s has no GOT subsection for offset 0x%x"),
+ h->root.root.root.string, gotent->got_offset);
+ result = FALSE;
+ continue;
+ }
+ plge = &td->got->size;
gotent->got_offset = *plge;
*plge += alpha_got_entry_size (gotent->reloc_type);
}
- return TRUE;
+ return result;
}
static void
/* First, zero out the .got sizes, as we may be recalculating the
.got after optimizing it. */
for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
- alpha_elf_tdata(i)->got->_raw_size = 0;
+ alpha_elf_tdata(i)->got->size = 0;
/* Next, fill in the offsets for all the global entries. */
alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
/* Finally, fill in the offsets for the local entries. */
for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
{
- bfd_size_type got_offset = alpha_elf_tdata(i)->got->_raw_size;
+ bfd_size_type got_offset = alpha_elf_tdata(i)->got->size;
bfd *j;
for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
}
}
- alpha_elf_tdata(i)->got->_raw_size = got_offset;
- alpha_elf_tdata(i)->got->_cooked_size = got_offset;
+ alpha_elf_tdata(i)->got->size = got_offset;
}
}
if (splt == NULL)
return TRUE;
- splt->_raw_size = 0;
+ splt->size = 0;
alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
elf64_alpha_size_plt_section_1, splt);
- splt->_cooked_size = splt->_raw_size;
-
/* Every plt entry requires a JMP_SLOT relocation. */
spltrel = bfd_get_section_by_name (dynobj, ".rela.plt");
- if (splt->_raw_size)
- entries = (splt->_raw_size - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
+ if (splt->size)
+ entries = (splt->size - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
else
entries = 0;
- spltrel->_raw_size = entries * sizeof (Elf64_External_Rela);
- spltrel->_cooked_size = spltrel->_raw_size;
+ spltrel->size = entries * sizeof (Elf64_External_Rela);
return TRUE;
}
a need for the PLT entry. */
if (gotent)
{
- if (splt->_raw_size == 0)
- splt->_raw_size = PLT_HEADER_SIZE;
- h->root.plt.offset = splt->_raw_size;
- splt->_raw_size += PLT_ENTRY_SIZE;
+ if (splt->size == 0)
+ splt->size = PLT_HEADER_SIZE;
+ h->root.plt.offset = splt->size;
+ splt->size += PLT_ENTRY_SIZE;
}
else
{
for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
{
asection *s = alpha_elf_tdata(i)->got;
- if (s->_raw_size > 0)
+ if (s->size > 0)
{
- s->contents = (bfd_byte *) bfd_zalloc (i, s->_raw_size);
+ s->contents = (bfd_byte *) bfd_zalloc (i, s->size);
if (s->contents == NULL)
return FALSE;
}
info->shared);
if (entries)
{
- relent->srel->_raw_size +=
+ relent->srel->size +=
entries * sizeof (Elf64_External_Rela) * relent->count;
if (relent->reltext)
info->flags |= DT_TEXTREL;
BFD_ASSERT (entries == 0);
return TRUE;
}
- srel->_raw_size = sizeof (Elf64_External_Rela) * entries;
+ srel->size = sizeof (Elf64_External_Rela) * entries;
/* Now do the non-local symbols. */
alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
elf64_alpha_size_rela_got_1, info);
- srel->_cooked_size = srel->_raw_size;
-
return TRUE;
}
bfd *dynobj = elf_hash_table(info)->dynobj;
asection *srel = bfd_get_section_by_name (dynobj, ".rela.got");
BFD_ASSERT (srel != NULL);
- srel->_raw_size += sizeof (Elf64_External_Rela) * entries;
+ srel->size += sizeof (Elf64_External_Rela) * entries;
}
return TRUE;
{
s = bfd_get_section_by_name (dynobj, ".interp");
BFD_ASSERT (s != NULL);
- s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
}
if (strncmp (name, ".rela", 5) == 0)
{
- strip = (s->_raw_size == 0);
+ strip = (s->size == 0);
if (!strip)
{
else
{
/* Allocate memory for the section contents. */
- s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
- if (s->contents == NULL && s->_raw_size != 0)
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL && s->size != 0)
return FALSE;
}
}
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
loc = srel->contents;
loc += srel->reloc_count++ * sizeof (Elf64_External_Rela);
bfd_elf64_swap_reloca_out (abfd, &outrel, loc);
- BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
- <= srel->_cooked_size);
+ BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count <= srel->size);
}
/* Relocate an Alpha ELF section for a relocatable link.
_bfd_merged_section_offset (output_bfd, &msec,
elf_section_data (sec)->
sec_info,
- sym->st_value + ent->addend,
- (bfd_vma) 0);
+ sym->st_value + ent->addend);
ent->addend -= sym->st_value;
ent->addend += msec->output_section->vma
+ msec->output_offset
bfd_boolean warned;
bfd_boolean unresolved_reloc;
struct elf_link_hash_entry *hh;
-
- RELOC_FOR_GLOBAL_SYMBOL (hh,
- (struct elf_link_hash_entry *) alpha_elf_sym_hashes (input_bfd),
- r_symndx, symtab_hdr, value,
- sec, unresolved_reloc, info,
- warned);
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ hh, sec, value,
+ unresolved_reloc, warned);
if (warned)
continue;
BFD_ASSERT (splt != NULL && sdyn != NULL);
dyncon = (Elf64_External_Dyn *) sdyn->contents;
- dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
out who is right. */
s = bfd_get_section_by_name (output_bfd, ".rela.plt");
if (s)
- {
- dyn.d_un.d_val -=
- (s->_cooked_size ? s->_cooked_size : s->_raw_size);
- }
+ dyn.d_un.d_val -= s->size;
break;
get_vma:
get_size:
s = bfd_get_section_by_name (output_bfd, name);
- dyn.d_un.d_val =
- (s->_cooked_size ? s->_cooked_size : s->_raw_size);
+ dyn.d_un.d_val = s->size;
break;
}
}
/* Initialize the PLT0 entry. */
- if (splt->_raw_size > 0)
+ if (splt->size > 0)
{
bfd_put_32 (output_bfd, PLT_HEADER_WORD1, splt->contents);
bfd_put_32 (output_bfd, PLT_HEADER_WORD2, splt->contents + 4);
if (s != NULL)
{
esym.asym.value = s->vma;
- last = s->vma + s->_raw_size;
+ last = s->vma + s->size;
}
else
esym.asym.value = last;
input_swap = (get_elf_backend_data (input_bfd)
->elf_backend_ecoff_debug_swap);
- BFD_ASSERT (p->size == input_section->_raw_size);
+ BFD_ASSERT (p->size == input_section->size);
/* The ECOFF linking code expects that we have already
read in the debugging information and set up an
return FALSE;
/* Set the size of the .mdebug section. */
- o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap);
+ o->size = bfd_ecoff_debug_size (abfd, &debug, swap);
/* Skip this section later on (I don't think this currently
matters, but someday it might). */
}
/* Invoke the regular ELF backend linker to do all the work. */
- if (! bfd_elf64_bfd_final_link (abfd, info))
+ if (! bfd_elf_final_link (abfd, info))
return FALSE;
/* Now write out the computed sections. */
if (! bfd_set_section_contents (abfd, sgot->output_section,
sgot->contents,
(file_ptr) sgot->output_offset,
- sgot->_raw_size))
+ sgot->size))
return FALSE;
}
}