1 |
/* BFD back-end for Motorola 68000 COFF binaries. |
/* BFD back-end for Motorola 68000 COFF binaries. |
2 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, |
3 |
2000, 2001 |
2000, 2001, 2002, 2003, 2005 |
4 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
5 |
Written by Cygnus Support. |
Written by Cygnus Support. |
6 |
|
|
67 |
#define RELOC_SPECIAL_FN m68kcoff_common_addend_special_fn |
#define RELOC_SPECIAL_FN m68kcoff_common_addend_special_fn |
68 |
#endif |
#endif |
69 |
|
|
70 |
static boolean m68k_coff_is_local_label_name PARAMS ((bfd *, const char *)); |
static bfd_boolean m68k_coff_is_local_label_name |
71 |
|
PARAMS ((bfd *, const char *)); |
72 |
|
|
73 |
/* On the delta, a symbol starting with L% is local. We won't see |
/* On the delta, a symbol starting with L% is local. We won't see |
74 |
such a symbol on other platforms, so it should be safe to always |
such a symbol on other platforms, so it should be safe to always |
75 |
consider it local here. */ |
consider it local here. */ |
76 |
|
|
77 |
static boolean |
static bfd_boolean |
78 |
m68k_coff_is_local_label_name (abfd, name) |
m68k_coff_is_local_label_name (abfd, name) |
79 |
bfd *abfd; |
bfd *abfd; |
80 |
const char *name; |
const char *name; |
81 |
{ |
{ |
82 |
if (name[0] == 'L' && name[1] == '%') |
if (name[0] == 'L' && name[1] == '%') |
83 |
return true; |
return TRUE; |
84 |
|
|
85 |
return _bfd_coff_is_local_label_name (abfd, name); |
return _bfd_coff_is_local_label_name (abfd, name); |
86 |
} |
} |
101 |
#endif |
#endif |
102 |
reloc_howto_type m68kcoff_howto_table[] = |
reloc_howto_type m68kcoff_howto_table[] = |
103 |
{ |
{ |
104 |
HOWTO (R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "8", true, 0x000000ff,0x000000ff, false), |
HOWTO (R_RELBYTE, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "8", TRUE, 0x000000ff,0x000000ff, FALSE), |
105 |
HOWTO (R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "16", true, 0x0000ffff,0x0000ffff, false), |
HOWTO (R_RELWORD, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "16", TRUE, 0x0000ffff,0x0000ffff, FALSE), |
106 |
HOWTO (R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "32", true, 0xffffffff,0xffffffff, false), |
HOWTO (R_RELLONG, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "32", TRUE, 0xffffffff,0xffffffff, FALSE), |
107 |
HOWTO (R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP8", true, 0x000000ff,0x000000ff, false), |
HOWTO (R_PCRBYTE, 0, 0, 8, TRUE, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP8", TRUE, 0x000000ff,0x000000ff, FALSE), |
108 |
HOWTO (R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP16", true, 0x0000ffff,0x0000ffff, false), |
HOWTO (R_PCRWORD, 0, 1, 16, TRUE, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP16", TRUE, 0x0000ffff,0x0000ffff, FALSE), |
109 |
HOWTO (R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP32", true, 0xffffffff,0xffffffff, false), |
HOWTO (R_PCRLONG, 0, 2, 32, TRUE, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP32", TRUE, 0xffffffff,0xffffffff, FALSE), |
110 |
HOWTO (R_RELLONG_NEG, 0, -2, 32, false, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "-32", true, 0xffffffff,0xffffffff, false), |
HOWTO (R_RELLONG_NEG, 0, -2, 32, FALSE, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "-32", TRUE, 0xffffffff,0xffffffff, FALSE), |
111 |
}; |
}; |
112 |
#endif /* not ONLY_DECLARE_RELOCS */ |
#endif /* not ONLY_DECLARE_RELOCS */ |
113 |
|
|
250 |
symbol is the value itself plus any desired offset. (taken from |
symbol is the value itself plus any desired offset. (taken from |
251 |
work done by Ian Taylor, Cygnus Support, for I386 COFF). */ |
work done by Ian Taylor, Cygnus Support, for I386 COFF). */ |
252 |
|
|
253 |
/* If we are producing relocateable output, we need to do some |
/* If we are producing relocatable output, we need to do some |
254 |
adjustments to the object file that are not done by the |
adjustments to the object file that are not done by the |
255 |
bfd_perform_relocation function. This function is called by every |
bfd_perform_relocation function. This function is called by every |
256 |
reloc type to make any required adjustments. */ |
reloc type to make any required adjustments. */ |
290 |
{ |
{ |
291 |
/* For some reason bfd_perform_relocation always effectively |
/* For some reason bfd_perform_relocation always effectively |
292 |
ignores the addend for a COFF target when producing |
ignores the addend for a COFF target when producing |
293 |
relocateable output. This seems to be always wrong for 386 |
relocatable output. This seems to be always wrong for 386 |
294 |
COFF, so we handle the addend here instead. */ |
COFF, so we handle the addend here instead. */ |
295 |
diff = reloc_entry->addend; |
diff = reloc_entry->addend; |
296 |
} |
} |
409 |
} |
} |
410 |
|
|
411 |
/* If the output symbol is common (in which case this must be a |
/* If the output symbol is common (in which case this must be a |
412 |
relocateable link), we need to add in the final size of the |
relocatable link), we need to add in the final size of the |
413 |
common symbol. */ |
common symbol. */ |
414 |
if (h != NULL && h->root.type == bfd_link_hash_common) |
if (h != NULL && h->root.type == bfd_link_hash_common) |
415 |
*addendp += h->root.u.c.size; |
*addendp += h->root.u.c.size; |
431 |
after the add_symbols entry point has been called for all the |
after the add_symbols entry point has been called for all the |
432 |
objects, and before the final_link entry point is called. */ |
objects, and before the final_link entry point is called. */ |
433 |
|
|
434 |
boolean |
bfd_boolean |
435 |
bfd_m68k_coff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) |
bfd_m68k_coff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) |
436 |
bfd *abfd; |
bfd *abfd; |
437 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
445 |
bfd_byte *p; |
bfd_byte *p; |
446 |
bfd_size_type amt; |
bfd_size_type amt; |
447 |
|
|
448 |
BFD_ASSERT (! info->relocateable); |
BFD_ASSERT (! info->relocatable); |
449 |
|
|
450 |
*errmsg = NULL; |
*errmsg = NULL; |
451 |
|
|
452 |
if (datasec->reloc_count == 0) |
if (datasec->reloc_count == 0) |
453 |
return true; |
return TRUE; |
454 |
|
|
455 |
extsyms = obj_coff_external_syms (abfd); |
extsyms = obj_coff_external_syms (abfd); |
456 |
symesz = bfd_coff_symesz (abfd); |
symesz = bfd_coff_symesz (abfd); |
457 |
|
|
458 |
irel = _bfd_coff_read_internal_relocs (abfd, datasec, true, NULL, false, |
irel = _bfd_coff_read_internal_relocs (abfd, datasec, TRUE, NULL, FALSE, |
459 |
NULL); |
NULL); |
460 |
irelend = irel + datasec->reloc_count; |
irelend = irel + datasec->reloc_count; |
461 |
|
|
462 |
amt = (bfd_size_type) datasec->reloc_count * 12; |
amt = (bfd_size_type) datasec->reloc_count * 12; |
463 |
relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt); |
relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt); |
464 |
if (relsec->contents == NULL) |
if (relsec->contents == NULL) |
465 |
return false; |
return FALSE; |
466 |
|
|
467 |
p = relsec->contents; |
p = relsec->contents; |
468 |
|
|
481 |
{ |
{ |
482 |
*errmsg = _("unsupported reloc type"); |
*errmsg = _("unsupported reloc type"); |
483 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
484 |
return false; |
return FALSE; |
485 |
} |
} |
486 |
|
|
487 |
if (irel->r_symndx == -1) |
if (irel->r_symndx == -1) |
510 |
(irel->r_vaddr - datasec->vma + datasec->output_offset), p); |
(irel->r_vaddr - datasec->vma + datasec->output_offset), p); |
511 |
memset (p + 4, 0, 8); |
memset (p + 4, 0, 8); |
512 |
if (targetsec != NULL) |
if (targetsec != NULL) |
513 |
strncpy (p + 4, targetsec->output_section->name, 8); |
strncpy ((char *) p + 4, targetsec->output_section->name, 8); |
514 |
} |
} |
515 |
|
|
516 |
return true; |
return TRUE; |
517 |
} |
} |
518 |
#endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS */ |
#endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS */ |
519 |
|
|
532 |
#endif |
#endif |
533 |
|
|
534 |
#ifdef NAMES_HAVE_UNDERSCORE |
#ifdef NAMES_HAVE_UNDERSCORE |
535 |
CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL) |
CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE) |
536 |
#else |
#else |
537 |
CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, 0, NULL) |
CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, 0, NULL, COFF_SWAP_TABLE) |
538 |
#endif |
#endif |