/* MMIX-specific support for 64-bit ELF.
- Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
Contributed by Hans-Peter Nilsson <hp@bitrange.com>
This file is part of BFD, the Binary File Descriptor library.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/* No specific ABI or "processor-specific supplement" defined. */
mmix_set_relaxable_size
PARAMS ((bfd *, asection *, void *));
-static bfd_boolean
-mmix_elf_get_section_contents
- PARAMS ((bfd *, sec_ptr, void *, file_ptr, bfd_size_type));
-
/* Watch out: this currently needs to have elements with the same index as
their R_MMIX_ number. */
bfd *abfd;
asection *sec;
{
- struct _mmix_elf_section_data *sdata;
- bfd_size_type amt = sizeof (*sdata);
+ if (!sec->used_by_bfd)
+ {
+ struct _mmix_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
- sdata = (struct _mmix_elf_section_data *) bfd_zalloc (abfd, amt);
- if (sdata == NULL)
- return FALSE;
- sec->used_by_bfd = (PTR) sdata;
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
return _bfd_elf_new_section_hook (abfd, sec);
}
position for the stub. There's supposed to be room allocated
for the stub. */
bfd_byte *stubcontents
- = ((char *) datap
+ = ((bfd_byte *) datap
- (addr - (isec->output_section->vma + isec->output_offset))
+ size
+ mmix_elf_section_data (isec)->pjs.stub_offset);
{
case bfd_reloc_overflow:
check_ok = info->callbacks->reloc_overflow
- (info, name, howto->name, (bfd_vma) 0,
- input_bfd, input_section, rel->r_offset);
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
break;
case bfd_reloc_undefined:
if (allocated_gregs_section == NULL)
{
allocated_gregs_section
- = bfd_make_section (bpo_greg_owner,
- MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
+ = bfd_make_section_with_flags (bpo_greg_owner,
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME,
+ (SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
/* Setting both SEC_ALLOC and SEC_LOAD means the section is
treated like any other section, and we'd get errors for
address overlap with the text section. Let's set none of
those flags, as that is what currently happens for usual
GREG allocations, and that works. */
if (allocated_gregs_section == NULL
- || !bfd_set_section_flags (bpo_greg_owner,
- allocated_gregs_section,
- (SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED))
|| !bfd_set_section_alignment (bpo_greg_owner,
allocated_gregs_section,
3))
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
switch (ELF64_R_TYPE (rel->r_info))
{
bfd_vma *valp ATTRIBUTE_UNUSED;
{
if (sym->st_shndx == SHN_REGISTER)
- *secp = bfd_make_section_old_way (abfd, MMIX_REG_SECTION_NAME);
+ {
+ *secp = bfd_make_section_old_way (abfd, MMIX_REG_SECTION_NAME);
+ (*secp)->flags |= SEC_LINKER_CREATED;
+ }
else if ((*namep)[0] == '_' && (*namep)[1] == '_' && (*namep)[2] == '.'
&& strncmp (*namep, MMIX_LOC_SECTION_START_SYMBOL_PREFIX,
strlen (MMIX_LOC_SECTION_START_SYMBOL_PREFIX)) == 0)
/* We never output a register section, though we create one for
temporary measures. Check that nobody entered contents into it. */
asection *reg_section;
- asection **secpp;
reg_section = bfd_get_section_by_name (abfd, MMIX_REG_SECTION_NAME);
if (bfd_get_section_flags (abfd, reg_section) & SEC_HAS_CONTENTS)
_bfd_abort (__FILE__, __LINE__, _("Register section has contents\n"));
- /* Really remove the section. */
- for (secpp = &abfd->sections;
- *secpp != reg_section;
- secpp = &(*secpp)->next)
- ;
- bfd_section_list_remove (abfd, secpp);
- --abfd->section_count;
+ /* Really remove the section, if it hasn't already been done. */
+ if (!bfd_section_removed_from_list (abfd, reg_section))
+ {
+ bfd_section_list_remove (abfd, reg_section);
+ --abfd->section_count;
+ }
}
if (! bfd_elf_final_link (abfd, info))