Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define BYTES_IN_WORD 4
-#define ARCH 32
/* #define ENTRY_CAN_BE_ZERO */
#define N_HEADER_IN_TEXT(x) 1
#define N_SHARED_LIB(x) 0
#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define MY_final_link_callback unused
#define MY_bfd_final_link _bfd_generic_final_link
#define MY_backend_data &MY(backend_data)
#define MIPS_RELOC_HI16_S 4
#define MIPS_RELOC_LO16 5
+/*
+ * This is only called when performing a BFD_RELOC_MIPS_JMP relocation.
+ * The jump destination address is formed from the upper 4 bits of the
+ * "current" program counter concatenated with the jump instruction's
+ * 26 bit field and two trailing zeros.
+ * If the destination address is not in the same segment as the "current"
+ * program counter, then we need to signal an error.
+ */
+static bfd_reloc_status_type
+mips_fix_jmp_addr (abfd,reloc_entry,symbol,data,input_section,output_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+{
+ bfd_vma relocation, pc;
+
+ /* If this is a partial relocation, just continue. */
+ if (output_bfd != (bfd *)NULL)
+ return bfd_reloc_continue;
+
+ /* If this is an undefined symbol, return error */
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0)
+ return bfd_reloc_undefined;
+
+ /*
+ * Work out which section the relocation is targetted at and the
+ * initial relocation command value.
+ */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+
+ pc = input_section->output_section->vma + input_section->output_offset +
+ reloc_entry->address + 4;
+
+ if ((relocation & 0xF0000000) != (pc & 0xF0000000))
+ return bfd_reloc_overflow;
+
+ return bfd_reloc_continue;
+}
+
/*
* This is only called when performing a BFD_RELOC_HI16_S relocation.
* We need to see if bit 15 is set in the result. If it is, we add
if (output_bfd != (bfd *)NULL)
return bfd_reloc_continue;
+ /* If this is an undefined symbol, return error */
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0)
+ return bfd_reloc_undefined;
+
/*
* Work out which section the relocation is targetted at and the
* initial relocation command value.
*/
- if (symbol->section == &bfd_com_section)
+ if (bfd_is_com_section (symbol->section))
relocation = 0;
else
relocation = symbol->value;
static reloc_howto_type mips_howto_table_ext[] = {
{MIPS_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield, 0,
"32", false, 0, 0xffffffff, false},
- {MIPS_RELOC_JMP, 2, 2, 26, false, 0, complain_overflow_bitfield, 0,
+ {MIPS_RELOC_JMP, 2, 2, 26, false, 0, complain_overflow_dont,
+ mips_fix_jmp_addr,
"MIPS_JMP", false, 0, 0x03ffffff, false},
- {MIPS_RELOC_WDISP16, 2, 1, 16, true, 0, complain_overflow_signed, 0,
+ {MIPS_RELOC_WDISP16, 2, 2, 16, true, 0, complain_overflow_signed, 0,
"WDISP16", false, 0, 0x0000ffff, false},
- {MIPS_RELOC_HI16, 16, 1, 16, false, 0, complain_overflow_bitfield, 0,
+ {MIPS_RELOC_HI16, 16, 2, 16, false, 0, complain_overflow_bitfield, 0,
"HI16", false, 0, 0x0000ffff, false},
- {MIPS_RELOC_HI16_S, 16, 1, 16, false, 0, complain_overflow_bitfield,
+ {MIPS_RELOC_HI16_S, 16, 2, 16, false, 0, complain_overflow_bitfield,
mips_fix_hi16_s,
"HI16_S", false, 0, 0x0000ffff, false},
- {MIPS_RELOC_LO16, 0, 1, 16, false, 0, complain_overflow_dont, 0,
+ {MIPS_RELOC_LO16, 0, 2, 16, false, 0, complain_overflow_dont, 0,
"LO16", false, 0, 0x0000ffff, false},
};
switch (code)
{
+ case BFD_RELOC_CTOR:
case BFD_RELOC_32:
return (&mips_howto_table_ext[MIPS_RELOC_32]);
case BFD_RELOC_MIPS_JMP:
PAGE_SIZE, /* text vma */
MY_set_sizes,
0, /* text size includes exec header */
+ 0, /* add_dynamic_symbols */
+ 0, /* add_one_symbol */
+ 0, /* link_dynamic_object */
+ 0, /* write_dynamic_symbol */
+ 0, /* check_dynamic_reloc */
+ 0 /* finish_dynamic_link */
};
-bfd_target aout_mips_little_vec =
+const bfd_target aout_mips_little_vec =
{
"a.out-mips-little", /* name */
bfd_target_aout_flavour,
(PTR) MY_backend_data,
};
-bfd_target aout_mips_big_vec =
+const bfd_target aout_mips_big_vec =
{
"a.out-mips-big", /* name */
bfd_target_aout_flavour,