/* MMIX-specific support for 64-bit ELF.
- Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004, 2005 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. */
goto pcrel_mmix_reloc_fits;
else
{
- bfd_size_type size
- = (isec->size
- - (mmix_elf_section_data (isec)->pjs.n_pushj_relocs
- * MAX_PUSHJ_STUB_SIZE));
+ bfd_size_type size = isec->rawsize ? isec->rawsize : isec->size;
/* We have the bytes at the PUSHJ insn and need to get the
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);
bfd_reloc_status_type flag = bfd_reloc_ok;
bfd_vma output_base = 0;
bfd_vma addr;
- bfd_size_type sz;
r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
return bfd_reloc_undefined;
/* Is the address of the relocation really within the section? */
- sz = input_section->rawsize ? input_section->rawsize : input_section->size;
- if (reloc_entry->address > sz)
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
return bfd_reloc_outofrange;
/* Work out which section the relocation is targeted at and the
struct elf_link_hash_entry **sym_hashes;
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
- bfd_size_type size
- = (input_section->size
- - (mmix_elf_section_data (input_section)->pjs.n_pushj_relocs
- * MAX_PUSHJ_STUB_SIZE));
+ bfd_size_type size;
size_t pjsno = 0;
+ size = input_section->rawsize ? input_section->rawsize : input_section->size;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
relend = relocs + input_section->reloc_count;
+ /* Zero the stub area before we start. */
+ if (input_section->rawsize != 0
+ && input_section->size > input_section->rawsize)
+ memset (contents + input_section->rawsize, 0,
+ input_section->size - input_section->rawsize);
+
for (rel = relocs; rel < relend; rel ++)
{
reloc_howto_type *howto;
{
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))
if (mmix_elf_section_data (sec)->pjs.n_pushj_relocs == 0)
return;
+ sec->rawsize = sec->size;
sec->size += (mmix_elf_section_data (sec)->pjs.n_pushj_relocs
* MAX_PUSHJ_STUB_SIZE);
size_t pjsno = 0;
bfd *bpo_greg_owner;
Elf_Internal_Sym *isymbuf = NULL;
- bfd_size_type size = (sec->size
- - (mmix_elf_section_data (sec)->pjs.n_pushj_relocs
- * MAX_PUSHJ_STUB_SIZE));
+ bfd_size_type size = sec->rawsize ? sec->rawsize : sec->size;
mmix_elf_section_data (sec)->pjs.stubs_size_sum = 0;
0,
bfd_arch_bits_per_address (abfd),
/* Output-stub location. */
- sec->output_section->size
+ sec->output_section->rawsize
+ (mmix_elf_section_data (sec
->output_section)
->pjs.stubs_size_sum)
free (internal_relocs);
return FALSE;
}
-
-/* Because we set size to include the max size of pushj stubs,
- i.e. larger than the actual section input size (see
- mmix_set_relaxablesize), we have to take care of that when reading
- the section. */
-
-static bfd_boolean
-mmix_elf_get_section_contents (abfd, section, location, offset, count)
- bfd *abfd;
- sec_ptr section;
- void *location;
- file_ptr offset;
- bfd_size_type count;
-{
- bfd_size_type size = (section->size
- - (mmix_elf_section_data (section)->pjs.n_pushj_relocs
- * MAX_PUSHJ_STUB_SIZE));
-
- if (offset + count > section->size)
- {
- abort();
- bfd_set_error (bfd_error_invalid_operation);
- return FALSE;
- }
-
- /* Check bounds against the faked size. */
- if (offset + count > size)
- {
- /* Clear the part in the faked area. */
- memset (location + size - offset, 0, count - (size - offset));
-
- /* If there's no initial part within the "real" contents, we're
- done. */
- if ((bfd_size_type) offset >= size)
- return TRUE;
-
- /* Else adjust the count and fall through to call the generic
- function. */
- count = size - offset;
- }
-
- return
- _bfd_generic_get_section_contents (abfd, section, location, offset,
- count);
-}
-
\f
#define ELF_ARCH bfd_arch_mmix
#define ELF_MACHINE_CODE EM_MMIX
#define bfd_elf64_new_section_hook mmix_elf_new_section_hook
#define bfd_elf64_bfd_final_link mmix_elf_final_link
#define bfd_elf64_bfd_relax_section mmix_elf_relax_section
-#define bfd_elf64_get_section_contents mmix_elf_get_section_contents
#include "elf64-target.h"