|
|
|
@ -42,7 +42,7 @@ extern boolean mcore_bfd_coff_final_link |
|
|
|
|
|
|
|
static struct bfd_link_hash_table * coff_mcore_link_hash_table_create |
|
|
|
PARAMS ((bfd *)); |
|
|
|
static bfd_reloc_status_type mcore_coff_unsupported_reloc |
|
|
|
static bfd_reloc_status_type mcore_coff_unsupported_reloc |
|
|
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
|
|
|
static boolean coff_mcore_relocate_section |
|
|
|
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
|
|
|
@ -70,36 +70,36 @@ static reloc_howto_type * coff_mcore_rtype_to_howto |
|
|
|
static reloc_howto_type mcore_coff_howto_table[] = |
|
|
|
{ |
|
|
|
/* Unused: */ |
|
|
|
HOWTO (IMAGE_REL_MCORE_ABSOLUTE,/* type */ |
|
|
|
0, /* rightshift */ |
|
|
|
0, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
0, /* bitsize */ |
|
|
|
false, /* pc_relative */ |
|
|
|
0, /* bitpos */ |
|
|
|
HOWTO (IMAGE_REL_MCORE_ABSOLUTE,/* type */ |
|
|
|
0, /* rightshift */ |
|
|
|
0, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
0, /* bitsize */ |
|
|
|
false, /* pc_relative */ |
|
|
|
0, /* bitpos */ |
|
|
|
complain_overflow_dont, /* dont complain_on_overflow */ |
|
|
|
NULL, /* special_function */ |
|
|
|
NULL, /* special_function */ |
|
|
|
"ABSOLUTE", /* name */ |
|
|
|
false, /* partial_inplace */ |
|
|
|
0x00, /* src_mask */ |
|
|
|
0x00, /* dst_mask */ |
|
|
|
false, /* partial_inplace */ |
|
|
|
0x00, /* src_mask */ |
|
|
|
0x00, /* dst_mask */ |
|
|
|
false), /* pcrel_offset */ |
|
|
|
|
|
|
|
|
|
|
|
HOWTO (IMAGE_REL_MCORE_ADDR32,/* type */ |
|
|
|
0, /* rightshift */ |
|
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
32, /* bitsize */ |
|
|
|
false, /* pc_relative */ |
|
|
|
0, /* bitpos */ |
|
|
|
0, /* rightshift */ |
|
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
32, /* bitsize */ |
|
|
|
false, /* pc_relative */ |
|
|
|
0, /* bitpos */ |
|
|
|
complain_overflow_bitfield, /* complain_on_overflow */ |
|
|
|
NULL, /* special_function */ |
|
|
|
NULL, /* special_function */ |
|
|
|
"ADDR32", /* name */ |
|
|
|
true, /* partial_inplace */ |
|
|
|
0xffffffff, /* src_mask */ |
|
|
|
0xffffffff, /* dst_mask */ |
|
|
|
true, /* partial_inplace */ |
|
|
|
0xffffffff, /* src_mask */ |
|
|
|
0xffffffff, /* dst_mask */ |
|
|
|
false), /* pcrel_offset */ |
|
|
|
|
|
|
|
|
|
|
|
/* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
|
|
|
|
Should not appear in object files. */ |
|
|
|
Should not appear in object files. */ |
|
|
|
HOWTO (IMAGE_REL_MCORE_PCREL_IMM8BY4, /* type */ |
|
|
|
2, /* rightshift */ |
|
|
|
1, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
@ -114,7 +114,7 @@ static reloc_howto_type mcore_coff_howto_table[] = |
|
|
|
0, /* dst_mask */ |
|
|
|
true), /* pcrel_offset */ |
|
|
|
|
|
|
|
/* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
|
|
|
|
/* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
|
|
|
|
Span 2k instructions == 4k bytes. |
|
|
|
Only useful pieces at the relocated address are the opcode (5 bits) */ |
|
|
|
HOWTO (IMAGE_REL_MCORE_PCREL_IMM11BY2,/* type */ |
|
|
|
@ -131,7 +131,7 @@ static reloc_howto_type mcore_coff_howto_table[] = |
|
|
|
0x7ff, /* dst_mask */ |
|
|
|
true), /* pcrel_offset */ |
|
|
|
|
|
|
|
/* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */ |
|
|
|
/* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */ |
|
|
|
HOWTO (IMAGE_REL_MCORE_PCREL_IMM4BY2, /* type */ |
|
|
|
1, /* rightshift */ |
|
|
|
1, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
@ -146,7 +146,7 @@ static reloc_howto_type mcore_coff_howto_table[] = |
|
|
|
0, /* dst_mask */ |
|
|
|
true), /* pcrel_offset */ |
|
|
|
|
|
|
|
/* 32-bit pc-relative. Eventually this will help support PIC code. */ |
|
|
|
/* 32-bit pc-relative. Eventually this will help support PIC code. */ |
|
|
|
HOWTO (IMAGE_REL_MCORE_PCREL_32,/* type */ |
|
|
|
0, /* rightshift */ |
|
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
@ -163,11 +163,11 @@ static reloc_howto_type mcore_coff_howto_table[] = |
|
|
|
|
|
|
|
/* Like PCREL_IMM11BY2, this relocation indicates that there is a
|
|
|
|
'jsri' at the specified address. There is a separate relocation |
|
|
|
entry for the literal pool entry that it references, but we |
|
|
|
entry for the literal pool entry that it references, but we |
|
|
|
might be able to change the jsri to a bsr if the target turns out |
|
|
|
to be close enough [even though we won't reclaim the literal pool |
|
|
|
entry, we'll get some runtime efficiency back]. Note that this |
|
|
|
is a relocation that we are allowed to safely ignore. */ |
|
|
|
is a relocation that we are allowed to safely ignore. */ |
|
|
|
HOWTO (IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2,/* type */ |
|
|
|
1, /* rightshift */ |
|
|
|
1, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
@ -181,7 +181,7 @@ static reloc_howto_type mcore_coff_howto_table[] = |
|
|
|
0x0, /* src_mask */ |
|
|
|
0x7ff, /* dst_mask */ |
|
|
|
true), /* pcrel_offset */ |
|
|
|
|
|
|
|
|
|
|
|
HOWTO (IMAGE_REL_MCORE_RVA, /* type */ |
|
|
|
0, /* rightshift */ |
|
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
@ -259,11 +259,10 @@ mcore_emit_base_file_entry (info, output_bfd, input_section, reloc_offset) |
|
|
|
|
|
|
|
if (coff_data (output_bfd)->pe) |
|
|
|
addr -= pe_data (output_bfd)->pe_opthdr.ImageBase; |
|
|
|
|
|
|
|
|
|
|
|
fwrite (&addr, 1, sizeof (addr), (FILE *) info->base_file); |
|
|
|
} |
|
|
|
|
|
|
|
/*ARGSUSED*/ |
|
|
|
static bfd_reloc_status_type |
|
|
|
mcore_coff_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section, |
|
|
|
output_bfd, error_message) |
|
|
|
@ -276,17 +275,17 @@ mcore_coff_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section, |
|
|
|
char ** error_message ATTRIBUTE_UNUSED; |
|
|
|
{ |
|
|
|
BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0); |
|
|
|
|
|
|
|
|
|
|
|
_bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"), |
|
|
|
bfd_get_filename (abfd), |
|
|
|
reloc_entry->howto->name, |
|
|
|
reloc_entry->howto->type); |
|
|
|
|
|
|
|
|
|
|
|
return bfd_reloc_notsupported; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* A cheesy little macro to make the code a little more readable. */ |
|
|
|
/* A cheesy little macro to make the code a little more readable. */ |
|
|
|
#define HOW2MAP(bfd_rtype, mcore_rtype) \ |
|
|
|
case bfd_rtype: return & mcore_coff_howto_table [mcore_rtype] |
|
|
|
|
|
|
|
@ -296,7 +295,7 @@ mcore_coff_reloc_type_lookup (abfd, code) |
|
|
|
bfd_reloc_code_real_type code; |
|
|
|
{ |
|
|
|
switch (code) |
|
|
|
{ |
|
|
|
{ |
|
|
|
HOW2MAP (BFD_RELOC_32, IMAGE_REL_MCORE_ADDR32); |
|
|
|
HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM8BY4, IMAGE_REL_MCORE_PCREL_IMM8BY4); |
|
|
|
HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM11BY2, IMAGE_REL_MCORE_PCREL_IMM11BY2); |
|
|
|
@ -304,7 +303,7 @@ mcore_coff_reloc_type_lookup (abfd, code) |
|
|
|
HOW2MAP (BFD_RELOC_32_PCREL, IMAGE_REL_MCORE_PCREL_32); |
|
|
|
HOW2MAP (BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2); |
|
|
|
HOW2MAP (BFD_RELOC_RVA, IMAGE_REL_MCORE_RVA); |
|
|
|
default: |
|
|
|
default: |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
/*NOTREACHED*/ |
|
|
|
@ -326,19 +325,18 @@ coff_mcore_rtype_to_howto (abfd, sec, rel, h, sym, addendp) |
|
|
|
{ |
|
|
|
reloc_howto_type * howto; |
|
|
|
|
|
|
|
|
|
|
|
if (rel->r_type >= NUM_ELEM (mcore_coff_howto_table)) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
|
|
howto = mcore_coff_howto_table + rel->r_type; |
|
|
|
|
|
|
|
if (rel->r_type == IMAGE_REL_MCORE_RVA) |
|
|
|
* addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase; |
|
|
|
|
|
|
|
|
|
|
|
else if (howto->pc_relative) |
|
|
|
{ |
|
|
|
* addendp = sec->vma - 2; /* XXX guess - is this right ? */ |
|
|
|
|
|
|
|
|
|
|
|
/* If the symbol is defined, then the generic code is going to
|
|
|
|
add back the symbol value in order to cancel out an |
|
|
|
adjustment it made to the addend. However, we set the addend |
|
|
|
@ -350,7 +348,7 @@ coff_mcore_rtype_to_howto (abfd, sec, rel, h, sym, addendp) |
|
|
|
} |
|
|
|
else |
|
|
|
* addendp = 0; |
|
|
|
|
|
|
|
|
|
|
|
return howto; |
|
|
|
} |
|
|
|
|
|
|
|
@ -362,7 +360,7 @@ in_reloc_p (abfd, howto) |
|
|
|
reloc_howto_type * howto; |
|
|
|
{ |
|
|
|
return ! howto->pc_relative && howto->type != IMAGE_REL_MCORE_RVA; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* The reloc processing routine for the optimized COFF linker. */ |
|
|
|
@ -382,13 +380,13 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
struct internal_reloc * relend; |
|
|
|
boolean hihalf; |
|
|
|
bfd_vma hihalf_val; |
|
|
|
|
|
|
|
|
|
|
|
/* If we are performing a relocateable link, we don't need to do a
|
|
|
|
thing. The caller will take care of adjusting the reloc |
|
|
|
addresses and symbol indices. */ |
|
|
|
if (info->relocateable) |
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
/* Check if we have the same endianess */ |
|
|
|
if ( input_bfd->xvec->byteorder != output_bfd->xvec->byteorder |
|
|
|
&& output_bfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) |
|
|
|
@ -408,7 +406,7 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
|
|
|
|
rel = relocs; |
|
|
|
relend = rel + input_section->reloc_count; |
|
|
|
|
|
|
|
|
|
|
|
for (; rel < relend; rel++) |
|
|
|
{ |
|
|
|
long symndx; |
|
|
|
@ -421,7 +419,7 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
reloc_howto_type * howto = NULL; |
|
|
|
struct coff_link_hash_entry * h; |
|
|
|
const char * my_name; |
|
|
|
|
|
|
|
|
|
|
|
symndx = rel->r_symndx; |
|
|
|
loc = contents + rel->r_vaddr - input_section->vma; |
|
|
|
|
|
|
|
@ -437,7 +435,7 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
} |
|
|
|
|
|
|
|
addend = 0; |
|
|
|
|
|
|
|
|
|
|
|
/* Get the howto and initialise the addend. */ |
|
|
|
howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h, |
|
|
|
sym, & addend); |
|
|
|
@ -445,7 +443,7 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
return false; |
|
|
|
|
|
|
|
val = 0; |
|
|
|
|
|
|
|
|
|
|
|
if (h == NULL) |
|
|
|
{ |
|
|
|
if (symndx == -1) |
|
|
|
@ -453,8 +451,8 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
else |
|
|
|
{ |
|
|
|
asection * sec = sections[symndx]; |
|
|
|
|
|
|
|
val = (sym->n_value |
|
|
|
|
|
|
|
val = (sym->n_value |
|
|
|
+ sec->output_section->vma |
|
|
|
+ sec->output_offset); |
|
|
|
|
|
|
|
@ -463,10 +461,10 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
else if ( sym->_n._n_n._n_zeroes == 0 |
|
|
|
&& sym->_n._n_n._n_offset != 0) |
|
|
|
my_name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset; |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
static char buf [SYMNMLEN + 1]; |
|
|
|
|
|
|
|
|
|
|
|
strncpy (buf, sym->_n._n_name, SYMNMLEN); |
|
|
|
buf[SYMNMLEN] = '\0'; |
|
|
|
my_name = buf; |
|
|
|
@ -479,7 +477,7 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
|| h->root.type == bfd_link_hash_defweak) |
|
|
|
{ |
|
|
|
asection * sec = h->root.u.def.section; |
|
|
|
|
|
|
|
|
|
|
|
val = (h->root.u.def.value |
|
|
|
+ sec->output_section->vma |
|
|
|
+ sec->output_offset); |
|
|
|
@ -491,12 +489,12 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
rel->r_vaddr - input_section->vma, true))) |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
my_name = h->root.root.string; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
rstat = bfd_reloc_ok; |
|
|
|
|
|
|
|
|
|
|
|
/* Each case must do its own relocation, setting rstat appropriately. */ |
|
|
|
switch (r_type) |
|
|
|
{ |
|
|
|
@ -505,19 +503,19 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
bfd_get_filename (input_bfd), r_type); |
|
|
|
bfd_set_error (bfd_error_bad_value); |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
case IMAGE_REL_MCORE_ABSOLUTE: |
|
|
|
fprintf (stderr, |
|
|
|
_("Warning: unsupported reloc %s <file %s, section %s>\n"), |
|
|
|
fprintf (stderr, |
|
|
|
_("Warning: unsupported reloc %s <file %s, section %s>\n"), |
|
|
|
howto->name, |
|
|
|
bfd_get_filename (input_bfd), |
|
|
|
input_section->name); |
|
|
|
|
|
|
|
fprintf (stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n", |
|
|
|
|
|
|
|
fprintf (stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n", |
|
|
|
rel->r_symndx, my_name, (long) rel->r_vaddr, |
|
|
|
(unsigned long) rel->r_vaddr); |
|
|
|
(unsigned long) rel->r_vaddr); |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case IMAGE_REL_MCORE_PCREL_IMM8BY4: |
|
|
|
case IMAGE_REL_MCORE_PCREL_IMM11BY2: |
|
|
|
case IMAGE_REL_MCORE_PCREL_IMM4BY2: |
|
|
|
@ -527,7 +525,7 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
/* XXX fixme - shouldn't this be like the code for the RVA reloc ? */ |
|
|
|
rstat = _bfd_relocate_contents (howto, input_bfd, val, loc); |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case IMAGE_REL_MCORE_RVA: |
|
|
|
rstat = _bfd_final_link_relocate |
|
|
|
(howto, input_bfd, |
|
|
|
@ -535,36 +533,36 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
val, addend); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (info->base_file) |
|
|
|
{ |
|
|
|
/* Emit a reloc if the backend thinks it needs it. */ |
|
|
|
if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto)) |
|
|
|
mcore_emit_base_file_entry (info, output_bfd, input_section, rel->r_vaddr); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
switch (rstat) |
|
|
|
{ |
|
|
|
default: |
|
|
|
abort (); |
|
|
|
|
|
|
|
|
|
|
|
case bfd_reloc_ok: |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case bfd_reloc_overflow: |
|
|
|
if (! ((*info->callbacks->reloc_overflow) |
|
|
|
(info, my_name, howto->name, |
|
|
|
(info, my_name, howto->name, |
|
|
|
(bfd_vma) 0, input_bfd, |
|
|
|
input_section, rel->r_vaddr - input_section->vma))) |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Tailor coffcode.h -- macro heaven. */ |
|
|
|
/* Tailor coffcode.h -- macro heaven. */ |
|
|
|
|
|
|
|
/* We use the special COFF backend linker, with our own special touch. */ |
|
|
|
|
|
|
|
@ -581,7 +579,7 @@ coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
/* Forward declaration to initialise alterbative_target field. */ |
|
|
|
extern const bfd_target TARGET_LITTLE_SYM; |
|
|
|
|
|
|
|
/* The transfer vectors that lead the outside world to all of the above. */ |
|
|
|
/* The transfer vectors that lead the outside world to all of the above. */ |
|
|
|
CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, |
|
|
|
(SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_READONLY | SEC_LINK_ONCE | SEC_LINK_DUPLICATES), |
|
|
|
0, & TARGET_LITTLE_SYM) |
|
|
|
|