00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "bfd.h"
00028 #include "sysdep.h"
00029 #include "libbfd.h"
00030
00031 #include "coff/i860.h"
00032
00033 #include "coff/internal.h"
00034
00035 #include "libcoff.h"
00036
00037
00038 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
00039
00040
00041 #define COFF_PAGE_SIZE 0x1000
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 static bfd_reloc_status_type
00053 coff_i860_reloc (bfd *abfd,
00054 arelent *reloc_entry,
00055 asymbol *symbol,
00056 void *data,
00057 asection *input_section ATTRIBUTE_UNUSED,
00058 bfd *output_bfd,
00059 char **error_message ATTRIBUTE_UNUSED)
00060 {
00061 symvalue diff;
00062
00063 if (output_bfd == (bfd *) NULL)
00064 return bfd_reloc_continue;
00065
00066 if (bfd_is_com_section (symbol->section))
00067 {
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 diff = symbol->value + reloc_entry->addend;
00080 }
00081 else
00082 {
00083
00084
00085
00086
00087 diff = reloc_entry->addend;
00088 }
00089
00090 #define DOIT(x) \
00091 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
00092
00093 if (diff != 0)
00094 {
00095 reloc_howto_type *howto = reloc_entry->howto;
00096 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
00097
00098 switch (howto->size)
00099 {
00100 case 0:
00101 {
00102 char x = bfd_get_8 (abfd, addr);
00103 DOIT (x);
00104 bfd_put_8 (abfd, x, addr);
00105 }
00106 break;
00107
00108 case 1:
00109 {
00110 short x = bfd_get_16 (abfd, addr);
00111 DOIT (x);
00112 bfd_put_16 (abfd, (bfd_vma) x, addr);
00113 }
00114 break;
00115
00116 case 2:
00117 {
00118 long x = bfd_get_32 (abfd, addr);
00119 DOIT (x);
00120 bfd_put_32 (abfd, (bfd_vma) x, addr);
00121 }
00122 break;
00123
00124 default:
00125 abort ();
00126 }
00127 }
00128
00129
00130 return bfd_reloc_continue;
00131 }
00132
00133
00134
00135
00136 static bfd_reloc_status_type
00137 coff_i860_reloc_nyi (bfd *abfd ATTRIBUTE_UNUSED,
00138 arelent *reloc_entry,
00139 asymbol *symbol ATTRIBUTE_UNUSED,
00140 void *data ATTRIBUTE_UNUSED,
00141 asection *input_section ATTRIBUTE_UNUSED,
00142 bfd *output_bfd ATTRIBUTE_UNUSED,
00143 char **error_message ATTRIBUTE_UNUSED)
00144 {
00145 reloc_howto_type *howto = reloc_entry->howto;
00146 fprintf (stderr, _("Relocation `%s' not yet implemented\n"), howto->name);
00147 return bfd_reloc_notsupported;
00148 }
00149
00150 #ifndef PCRELOFFSET
00151 #define PCRELOFFSET FALSE
00152 #endif
00153
00154 static reloc_howto_type howto_table[] =
00155 {
00156 EMPTY_HOWTO (0),
00157 EMPTY_HOWTO (1),
00158 EMPTY_HOWTO (2),
00159 EMPTY_HOWTO (3),
00160 EMPTY_HOWTO (4),
00161 EMPTY_HOWTO (5),
00162 HOWTO (R_DIR32,
00163 0,
00164 2,
00165 32,
00166 FALSE,
00167 0,
00168 complain_overflow_bitfield,
00169 coff_i860_reloc,
00170 "dir32",
00171 TRUE,
00172 0xffffffff,
00173 0xffffffff,
00174 TRUE),
00175
00176 HOWTO (R_IMAGEBASE,
00177 0,
00178 2,
00179 32,
00180 FALSE,
00181 0,
00182 complain_overflow_bitfield,
00183 coff_i860_reloc,
00184 "rva32",
00185 TRUE,
00186 0xffffffff,
00187 0xffffffff,
00188 FALSE),
00189 EMPTY_HOWTO (010),
00190 EMPTY_HOWTO (011),
00191 EMPTY_HOWTO (012),
00192 EMPTY_HOWTO (013),
00193 EMPTY_HOWTO (014),
00194 EMPTY_HOWTO (015),
00195 EMPTY_HOWTO (016),
00196 HOWTO (R_RELBYTE,
00197 0,
00198 0,
00199 8,
00200 FALSE,
00201 0,
00202 complain_overflow_bitfield,
00203 coff_i860_reloc,
00204 "8",
00205 TRUE,
00206 0x000000ff,
00207 0x000000ff,
00208 PCRELOFFSET),
00209 HOWTO (R_RELWORD,
00210 0,
00211 1,
00212 16,
00213 FALSE,
00214 0,
00215 complain_overflow_bitfield,
00216 coff_i860_reloc,
00217 "16",
00218 TRUE,
00219 0x0000ffff,
00220 0x0000ffff,
00221 PCRELOFFSET),
00222 HOWTO (R_RELLONG,
00223 0,
00224 2,
00225 32,
00226 FALSE,
00227 0,
00228 complain_overflow_bitfield,
00229 coff_i860_reloc,
00230 "32",
00231 TRUE,
00232 0xffffffff,
00233 0xffffffff,
00234 PCRELOFFSET),
00235 HOWTO (R_PCRBYTE,
00236 0,
00237 0,
00238 8,
00239 TRUE,
00240 0,
00241 complain_overflow_signed,
00242 coff_i860_reloc,
00243 "DISP8",
00244 TRUE,
00245 0x000000ff,
00246 0x000000ff,
00247 PCRELOFFSET),
00248 HOWTO (R_PCRWORD,
00249 0,
00250 1,
00251 16,
00252 TRUE,
00253 0,
00254 complain_overflow_signed,
00255 coff_i860_reloc,
00256 "DISP16",
00257 TRUE,
00258 0x0000ffff,
00259 0x0000ffff,
00260 PCRELOFFSET),
00261 HOWTO (R_PCRLONG,
00262 0,
00263 2,
00264 32,
00265 TRUE,
00266 0,
00267 complain_overflow_signed,
00268 coff_i860_reloc,
00269 "DISP32",
00270 TRUE,
00271 0xffffffff,
00272 0xffffffff,
00273 PCRELOFFSET),
00274 EMPTY_HOWTO (0x15),
00275 EMPTY_HOWTO (0x16),
00276 EMPTY_HOWTO (0x17),
00277 EMPTY_HOWTO (0x18),
00278 EMPTY_HOWTO (0x19),
00279 EMPTY_HOWTO (0x1a),
00280 EMPTY_HOWTO (0x1b),
00281 HOWTO (COFF860_R_PAIR,
00282 0,
00283 2,
00284 16,
00285 FALSE,
00286 0,
00287 complain_overflow_dont,
00288 coff_i860_reloc_nyi,
00289 "PAIR",
00290 FALSE,
00291 0xffff,
00292 0xffff,
00293 FALSE),
00294 EMPTY_HOWTO (0x1d),
00295 HOWTO (COFF860_R_HIGH,
00296 16,
00297 2,
00298 16,
00299 FALSE,
00300 0,
00301 complain_overflow_dont,
00302 coff_i860_reloc,
00303 "HIGH",
00304 FALSE,
00305 0xffff,
00306 0xffff,
00307 FALSE),
00308 HOWTO (COFF860_R_LOW0,
00309 0,
00310 2,
00311 16,
00312 FALSE,
00313 0,
00314 complain_overflow_dont,
00315 coff_i860_reloc,
00316 "LOW0",
00317 FALSE,
00318 0xffff,
00319 0xffff,
00320 FALSE),
00321 HOWTO (COFF860_R_LOW1,
00322 0,
00323 2,
00324 16,
00325 FALSE,
00326 0,
00327 complain_overflow_dont,
00328 coff_i860_reloc,
00329 "LOW1",
00330 FALSE,
00331 0xfffe,
00332 0xfffe,
00333 FALSE),
00334 HOWTO (COFF860_R_LOW2,
00335 0,
00336 2,
00337 16,
00338 FALSE,
00339 0,
00340 complain_overflow_dont,
00341 coff_i860_reloc,
00342 "LOW2",
00343 FALSE,
00344 0xfffc,
00345 0xfffc,
00346 FALSE),
00347 HOWTO (COFF860_R_LOW3,
00348 0,
00349 2,
00350 16,
00351 FALSE,
00352 0,
00353 complain_overflow_dont,
00354 coff_i860_reloc,
00355 "LOW3",
00356 FALSE,
00357 0xfff8,
00358 0xfff8,
00359 FALSE),
00360 HOWTO (COFF860_R_LOW4,
00361 0,
00362 2,
00363 16,
00364 FALSE,
00365 0,
00366 complain_overflow_dont,
00367 coff_i860_reloc,
00368 "LOW4",
00369 FALSE,
00370 0xfff0,
00371 0xfff0,
00372 FALSE),
00373 HOWTO (COFF860_R_SPLIT0,
00374 0,
00375 2,
00376 16,
00377 FALSE,
00378 0,
00379 complain_overflow_dont,
00380 coff_i860_reloc_nyi,
00381 "SPLIT0",
00382 FALSE,
00383 0x1f07ff,
00384 0x1f07ff,
00385 FALSE),
00386 HOWTO (COFF860_R_SPLIT1,
00387 0,
00388 2,
00389 16,
00390 FALSE,
00391 0,
00392 complain_overflow_dont,
00393 coff_i860_reloc_nyi,
00394 "SPLIT1",
00395 FALSE,
00396 0x1f07fe,
00397 0x1f07fe,
00398 FALSE),
00399 HOWTO (COFF860_R_SPLIT2,
00400 0,
00401 2,
00402 16,
00403 FALSE,
00404 0,
00405 complain_overflow_dont,
00406 coff_i860_reloc_nyi,
00407 "SPLIT2",
00408 FALSE,
00409 0x1f07fc,
00410 0x1f07fc,
00411 FALSE),
00412 HOWTO (COFF860_R_HIGHADJ,
00413 0,
00414 2,
00415 16,
00416 FALSE,
00417 0,
00418 complain_overflow_dont,
00419 coff_i860_reloc_nyi,
00420 "HIGHADJ",
00421 FALSE,
00422 0xffff,
00423 0xffff,
00424 FALSE),
00425 HOWTO (COFF860_R_BRADDR,
00426 2,
00427 2,
00428 26,
00429 TRUE,
00430 0,
00431 complain_overflow_bitfield,
00432 coff_i860_reloc_nyi,
00433 "BRADDR",
00434 FALSE,
00435 0x3ffffff,
00436 0x3ffffff,
00437 TRUE)
00438 };
00439
00440
00441
00442 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
00443 #define BADMAG(x) I860BADMAG(x)
00444 #define I860 1
00445
00446 #define RTYPE2HOWTO(cache_ptr, dst) \
00447 ((cache_ptr)->howto = \
00448 ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0]) \
00449 ? howto_table + (dst)->r_type \
00450 : NULL))
00451
00452
00453
00454
00455 #define BSS_NOLOAD_IS_SHARED_LIBRARY
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)
00471
00472
00473 #define coff_relocate_section _bfd_coff_generic_relocate_section
00474
00475 static reloc_howto_type *
00476 coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
00477 asection *sec,
00478 struct internal_reloc *rel,
00479 struct coff_link_hash_entry *h,
00480 struct internal_syment *sym,
00481 bfd_vma *addendp)
00482 {
00483
00484 reloc_howto_type *howto;
00485
00486 if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
00487 {
00488 bfd_set_error (bfd_error_bad_value);
00489 return NULL;
00490 }
00491
00492 howto = howto_table + rel->r_type;
00493
00494 if (howto->pc_relative)
00495 *addendp += sec->vma;
00496
00497 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
00498 {
00499
00500
00501
00502
00503
00504
00505 BFD_ASSERT (h != NULL);
00506
00507
00508
00509
00510
00511
00512
00513 *addendp -= sym->n_value;
00514 }
00515
00516
00517
00518
00519 if (h != NULL && h->root.type == bfd_link_hash_common)
00520 *addendp += h->root.u.c.size;
00521
00522 return howto;
00523 }
00524
00525 static reloc_howto_type *
00526 coff_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00527 bfd_reloc_code_real_type code)
00528 {
00529 switch (code)
00530 {
00531 case BFD_RELOC_32:
00532 return howto_table + R_DIR32;
00533 case BFD_RELOC_860_PC26:
00534 return howto_table + COFF860_R_BRADDR;
00535 case BFD_RELOC_860_PC16:
00536
00537 return howto_table + COFF860_R_SPLIT0;
00538 case BFD_RELOC_860_LOW0:
00539 return howto_table + COFF860_R_LOW0;
00540 case BFD_RELOC_860_SPLIT0:
00541 return howto_table + COFF860_R_SPLIT0;
00542 case BFD_RELOC_860_LOW1:
00543 return howto_table + COFF860_R_LOW1;
00544 case BFD_RELOC_860_SPLIT1:
00545 return howto_table + COFF860_R_SPLIT1;
00546 case BFD_RELOC_860_LOW2:
00547 return howto_table + COFF860_R_LOW2;
00548 case BFD_RELOC_860_SPLIT2:
00549 return howto_table + COFF860_R_SPLIT2;
00550 case BFD_RELOC_860_LOW3:
00551 return howto_table + COFF860_R_LOW3;
00552 case BFD_RELOC_860_HIGHADJ:
00553 return howto_table + COFF860_R_HIGHADJ;
00554 case BFD_RELOC_860_HIGH:
00555 return howto_table + COFF860_R_HIGH;
00556 default:
00557 BFD_FAIL ();
00558 return 0;
00559 }
00560 }
00561
00562
00563
00564
00565
00566 static void
00567 i860_reloc_processing (arelent *cache_ptr, struct internal_reloc *dst,
00568 asymbol **symbols, bfd *abfd, asection *asect)
00569 {
00570 if (dst->r_type == COFF860_R_PAIR)
00571 {
00572
00573 cache_ptr->howto = howto_table + dst->r_type;
00574 cache_ptr->address = dst->r_vaddr;
00575 cache_ptr->addend = dst->r_symndx;
00576 cache_ptr->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr;
00577 }
00578 else
00579 {
00580
00581
00582 asymbol *ptr = NULL;
00583 cache_ptr->address = dst->r_vaddr;
00584
00585 if (dst->r_symndx != -1)
00586 {
00587 if (dst->r_symndx < 0 || dst->r_symndx >= obj_conv_table_size (abfd))
00588 {
00589 (*_bfd_error_handler)
00590 (_("%B: warning: illegal symbol index %ld in relocs"),
00591 abfd, dst->r_symndx);
00592 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00593 ptr = NULL;
00594 }
00595 else
00596 {
00597 cache_ptr->sym_ptr_ptr = (symbols
00598 + obj_convert (abfd)[dst->r_symndx]);
00599 ptr = *(cache_ptr->sym_ptr_ptr);
00600 }
00601 }
00602 else
00603 {
00604 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00605 ptr = NULL;
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 CALC_ADDEND (abfd, ptr, (*dst), cache_ptr);
00617
00618 cache_ptr->address -= asect->vma;
00619
00620
00621 RTYPE2HOWTO (cache_ptr, dst);
00622 }
00623 }
00624
00625 #define coff_rtype_to_howto coff_i860_rtype_to_howto
00626 #define coff_bfd_reloc_type_lookup coff_i860_reloc_type_lookup
00627
00628 #define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
00629 i860_reloc_processing (relent, reloc, symbols, abfd, section)
00630
00631 #include "coffcode.h"
00632
00633 static const bfd_target *
00634 i3coff_object_p(bfd *a)
00635 {
00636 return coff_object_p (a);
00637 }
00638
00639 const bfd_target
00640 #ifdef TARGET_SYM
00641 TARGET_SYM =
00642 #else
00643 i860coff_vec =
00644 #endif
00645 {
00646 #ifdef TARGET_NAME
00647 TARGET_NAME,
00648 #else
00649 "coff-i860",
00650 #endif
00651 bfd_target_coff_flavour,
00652 BFD_ENDIAN_LITTLE,
00653 BFD_ENDIAN_LITTLE,
00654
00655 (HAS_RELOC | EXEC_P |
00656 HAS_LINENO | HAS_DEBUG |
00657 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
00658
00659 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
00660 '_',
00661 '/',
00662 15,
00663
00664 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00665 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
00666 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
00667 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00668 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
00669 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
00670
00671
00672 {_bfd_dummy_target, i3coff_object_p,
00673 bfd_generic_archive_p, i3coff_object_p},
00674 {bfd_false, coff_mkobject, _bfd_generic_mkarchive,
00675 bfd_false},
00676 {bfd_false, coff_write_object_contents,
00677 _bfd_write_archive_contents, bfd_false},
00678
00679 BFD_JUMP_TABLE_GENERIC (coff),
00680 BFD_JUMP_TABLE_COPY (coff),
00681 BFD_JUMP_TABLE_CORE (_bfd_nocore),
00682 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
00683 BFD_JUMP_TABLE_SYMBOLS (coff),
00684 BFD_JUMP_TABLE_RELOCS (coff),
00685 BFD_JUMP_TABLE_WRITE (coff),
00686 BFD_JUMP_TABLE_LINK (coff),
00687 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00688
00689 NULL,
00690
00691 COFF_SWAP_TABLE
00692 };