/* MMIX-specific support for 64-bit ELF.
- Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
Contributed by Hans-Peter Nilsson <hp@bitrange.com>
This file is part of BFD, the Binary File Descriptor library.
/* Only intended to be called from a debugger. */
extern void mmix_dump_bpo_gregs
- (struct bfd_link_info *, bfd_error_handler_type);
+ (struct bfd_link_info *, void (*) (const char *, ...));
static void
mmix_set_relaxable_size (bfd *, asection *, void *);
/* This reloc does nothing. */
HOWTO (R_MMIX_NONE, /* type */
0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
+ 3, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_MMIX_NONE", /* name */
FALSE, /* partial_inplace */
doesn't cost much, so can be left in at all times. */
if (value != gregdata->reloc_request[bpo_index].value)
{
- (*_bfd_error_handler)
- (_("%s: Internal inconsistency error for value for\n\
- linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"),
- bfd_get_filename (isec->owner),
- (unsigned long) (value >> 32), (unsigned long) value,
- (unsigned long) (gregdata->reloc_request[bpo_index].value
- >> 32),
- (unsigned long) gregdata->reloc_request[bpo_index].value);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: Internal inconsistency error for value for\n\
+ linker-allocated global register: linked: %#Lx != relaxed: %#Lx"),
+ isec->owner,
+ value,
+ gregdata->reloc_request[bpo_index].value);
bfd_set_error (bfd_error_bad_value);
return bfd_reloc_overflow;
}
unsigned int r_type;
r_type = ELF64_R_TYPE (dst->r_info);
- BFD_ASSERT (r_type < (unsigned int) R_MMIX_max);
+ if (r_type >= (unsigned int) R_MMIX_max)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B: invalid MMIX reloc number: %d"), abfd, r_type);
+ r_type = 0;
+ }
cache_ptr->howto = &elf_mmix_howto_table[r_type];
}
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
rel, 1, relend, howto, 0, contents);
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
{
/* This is a relocatable link. For most relocs we don't have to
change anything, unless the reloc is against a section
if (r != bfd_reloc_ok)
{
- bfd_boolean check_ok = TRUE;
const char * msg = (const char *) NULL;
switch (r)
{
case bfd_reloc_overflow:
- check_ok = info->callbacks->reloc_overflow
+ info->callbacks->reloc_overflow
(info, (h ? &h->root : NULL), name, howto->name,
(bfd_vma) 0, input_bfd, input_section, rel->r_offset);
break;
case bfd_reloc_undefined:
/* We may have sent this message above. */
if (! undefined_signalled)
- check_ok = info->callbacks->undefined_symbol
- (info, name, input_bfd, input_section, rel->r_offset,
- TRUE);
+ info->callbacks->undefined_symbol
+ (info, name, input_bfd, input_section, rel->r_offset, TRUE);
undefined_signalled = TRUE;
break;
}
if (msg)
- check_ok = info->callbacks->warning
- (info, msg, name, input_bfd, input_section, rel->r_offset);
-
- if (! check_ok)
- return FALSE;
+ (*info->callbacks->warning) (info, msg, name, input_bfd,
+ input_section, rel->r_offset);
}
}
/* Note: This is separated out into two messages in order
to ease the translation into other languages. */
if (symname == NULL || *symname == 0)
- (*_bfd_error_handler)
- (_("%s: base-plus-offset relocation against register symbol: (unknown) in %s"),
- bfd_get_filename (input_section->owner),
- bfd_get_section_name (symsec->owner, symsec));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: base-plus-offset relocation against register symbol:"
+ " (unknown) in %A"),
+ input_section->owner, symsec);
else
- (*_bfd_error_handler)
- (_("%s: base-plus-offset relocation against register symbol: %s in %s"),
- bfd_get_filename (input_section->owner), symname,
- bfd_get_section_name (symsec->owner, symsec));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: base-plus-offset relocation against register symbol:"
+ " %s in %A"),
+ input_section->owner, symname, symsec);
return bfd_reloc_overflow;
}
goto do_mmix_reloc;
/* Note: This is separated out into two messages in order
to ease the translation into other languages. */
if (symname == NULL || *symname == 0)
- (*_bfd_error_handler)
- (_("%s: register relocation against non-register symbol: (unknown) in %s"),
- bfd_get_filename (input_section->owner),
- bfd_get_section_name (symsec->owner, symsec));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: register relocation against non-register symbol:"
+ " (unknown) in %A"),
+ input_section->owner, symsec);
else
- (*_bfd_error_handler)
- (_("%s: register relocation against non-register symbol: %s in %s"),
- bfd_get_filename (input_section->owner), symname,
- bfd_get_section_name (symsec->owner, symsec));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: register relocation against non-register symbol:"
+ " %s in %A"),
+ input_section->owner, symname, symsec);
/* The bfd_reloc_outofrange return value, though intuitively a
better value, will not get us an error. */
&& strcmp (bfd_get_section_name (symsec->owner, symsec),
MMIX_REG_SECTION_NAME) != 0)
{
- (*_bfd_error_handler)
- (_("%s: directive LOCAL valid only with a register or absolute value"),
- bfd_get_filename (input_section->owner));
+ _bfd_error_handler
+ (_("%B: directive LOCAL valid only with a register or absolute value"),
+ input_section->owner);
return bfd_reloc_overflow;
}
if ((bfd_vma) srel >= first_global)
{
/* FIXME: Better error message. */
- (*_bfd_error_handler)
- (_("%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."),
- bfd_get_filename (input_section->owner), (long) srel, (long) first_global);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: LOCAL directive: Register $%Ld is not a local register."
+ " First global register is $%Ld."),
+ input_section->owner, srel, first_global);
return bfd_reloc_overflow;
}
DSO-related stuff if that member is non-NULL. */
case R_MMIX_BASE_PLUS_OFFSET:
/* We don't do anything with this reloc for a relocatable link. */
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
break;
if (bpo_greg_owner == NULL)
if (!mmix_elf_check_common_relocs (abfd, info, sec, relocs))
return FALSE;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
rel_end = relocs + sec->reloc_count;
/* PR15323, ref flags aren't set for references in the same
object. */
- h->root.non_ir_ref = 1;
+ h->root.non_ir_ref_regular = 1;
}
switch (ELF64_R_TYPE (rel->r_info))
/* Handle the special section numbers that a symbol may use. */
void
-mmix_elf_symbol_processing (abfd, asym)
- bfd *abfd ATTRIBUTE_UNUSED;
- asymbol *asym;
+mmix_elf_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym)
{
elf_symbol_type *elfsym;
{
/* How do we get the asymbol (or really: the filename) from h?
h->u.def.section->owner is NULL. */
- ((*_bfd_error_handler)
- (_("%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"),
- bfd_get_filename (abfd), *namep,
- *namep + strlen (MMIX_LOC_SECTION_START_SYMBOL_PREFIX)));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: Error: multiple definition of `%s'; start of %s "
+ "is set in a earlier linked file\n"),
+ abfd, *namep,
+ *namep + strlen (MMIX_LOC_SECTION_START_SYMBOL_PREFIX));
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
/* For use in relocatable link, we start with a max stubs size. See
mmix_elf_relax_section. */
- if (info->relocatable && sec->output_section)
+ if (bfd_link_relocatable (info) && sec->output_section)
mmix_elf_section_data (sec->output_section)->pjs.stubs_size_sum
+= (mmix_elf_section_data (sec)->pjs.n_pushj_relocs
* MAX_PUSHJ_STUB_SIZE);
bfd *ibfd;
/* Set the initial size of sections. */
- for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
bfd_map_over_sections (ibfd, mmix_set_relaxable_size, info);
/* The bpo_greg_owner bfd is supposed to have been set by
if (gregdata->n_remaining_bpo_relocs_this_relaxation_round
!= gregdata->n_bpo_relocs)
{
- (*_bfd_error_handler)
- (_("Internal inconsistency: remaining %u != max %u.\n\
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("Internal inconsistency: remaining %lu != max %lu.\n\
Please report this bug."),
- gregdata->n_remaining_bpo_relocs_this_relaxation_round,
- gregdata->n_bpo_relocs);
+ (unsigned long) gregdata->n_remaining_bpo_relocs_this_relaxation_round,
+ (unsigned long) gregdata->n_bpo_relocs);
return FALSE;
}
from base-plus-offset relocs. */
void
-mmix_dump_bpo_gregs (link_info, pf)
- struct bfd_link_info *link_info;
- bfd_error_handler_type pf;
+mmix_dump_bpo_gregs (struct bfd_link_info *link_info,
+ void (*pf) (const char *fmt, ...))
{
bfd *bpo_greg_owner;
asection *bpo_gregs_section;
/* We process relocs in a distinctly different way when this is a
relocatable link (for one, we don't look at symbols), so we avoid
mixing its code with that for the "normal" relaxation. */
- if (link_info->relocatable)
+ if (bfd_link_relocatable (link_info))
{
/* The only transformation in a relocatable link is to generate
a full stub at the location of the stub calculated for the
indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
h = elf_sym_hashes (abfd)[indx];
BFD_ASSERT (h != NULL);
- if (h->root.type != bfd_link_hash_defined
- && h->root.type != bfd_link_hash_defweak)
+ if (h->root.type == bfd_link_hash_undefweak)
+ /* FIXME: for R_MMIX_PUSHJ_STUBBABLE, there are alternatives to
+ the canonical value 0 for an unresolved weak symbol to
+ consider: as the debug-friendly approach, resolve to "abort"
+ (or a port-specific function), or as the space-friendly
+ approach resolve to the next instruction (like some other
+ ports, notably ARM and AArch64). These alternatives require
+ matching code in mmix_elf_perform_relocation or its caller. */
+ symval = 0;
+ else if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ else
{
/* This appears to be a reference to an undefined symbol. Just
ignore it--it will be caught by the regular reloc processing.
}
continue;
}
-
- symval = (h->root.u.def.value
- + h->root.u.def.section->output_section->vma
- + h->root.u.def.section->output_offset);
}
if (ELF64_R_TYPE (irel->r_info) == (int) R_MMIX_PUSHJ_STUBBABLE)
}
}
+ BFD_ASSERT(pjsno == mmix_elf_section_data (sec)->pjs.n_pushj_relocs);
+
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);