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 #include "elf-bfd.h"
00031 #include "elf/i860.h"
00032
00033
00034 static bfd_reloc_status_type
00035 i860_howto_pc26_reloc (bfd *abfd ATTRIBUTE_UNUSED,
00036 arelent *reloc_entry,
00037 asymbol *symbol,
00038 void *data ATTRIBUTE_UNUSED,
00039 asection *input_section,
00040 bfd *output_bfd,
00041 char **error_message ATTRIBUTE_UNUSED)
00042 {
00043 bfd_vma insn;
00044 bfd_vma relocation;
00045 bfd_byte *addr;
00046
00047 if (output_bfd != NULL
00048 && (symbol->flags & BSF_SECTION_SYM) == 0
00049 && (! reloc_entry->howto->partial_inplace
00050 || reloc_entry->addend == 0))
00051 {
00052 reloc_entry->address += input_section->output_offset;
00053 return bfd_reloc_ok;
00054 }
00055
00056
00057 if (bfd_is_und_section (symbol->section)
00058 && output_bfd == (bfd *) NULL)
00059 return bfd_reloc_undefined;
00060
00061 if (bfd_is_com_section (symbol->section))
00062 relocation = 0;
00063 else
00064 relocation = symbol->value;
00065
00066 relocation += symbol->section->output_section->vma;
00067 relocation += symbol->section->output_offset;
00068 relocation += reloc_entry->addend;
00069
00070 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00071 return bfd_reloc_outofrange;
00072
00073
00074 relocation -= (input_section->output_section->vma
00075 + input_section->output_offset
00076 + reloc_entry->address
00077 + 4);
00078
00079
00080 if ((bfd_signed_vma)relocation > (0x3ffffff << 2)
00081 || (bfd_signed_vma)relocation < (-0x4000000 << 2))
00082 return bfd_reloc_outofrange;
00083
00084 addr = (bfd_byte *) data + reloc_entry->address;
00085 insn = bfd_get_32 (abfd, addr);
00086
00087 relocation >>= reloc_entry->howto->rightshift;
00088 insn = (insn & ~reloc_entry->howto->dst_mask)
00089 | (relocation & reloc_entry->howto->dst_mask);
00090
00091 bfd_put_32 (abfd, (bfd_vma) insn, addr);
00092
00093 return bfd_reloc_ok;
00094 }
00095
00096
00097 static bfd_reloc_status_type
00098 i860_howto_pc16_reloc (bfd *abfd,
00099 arelent *reloc_entry,
00100 asymbol *symbol,
00101 void *data,
00102 asection *input_section,
00103 bfd *output_bfd,
00104 char **error_message ATTRIBUTE_UNUSED)
00105 {
00106 bfd_vma insn;
00107 bfd_vma relocation;
00108 bfd_byte *addr;
00109
00110 if (output_bfd != NULL
00111 && (symbol->flags & BSF_SECTION_SYM) == 0
00112 && (! reloc_entry->howto->partial_inplace
00113 || reloc_entry->addend == 0))
00114 {
00115 reloc_entry->address += input_section->output_offset;
00116 return bfd_reloc_ok;
00117 }
00118
00119
00120 if (bfd_is_und_section (symbol->section)
00121 && output_bfd == (bfd *) NULL)
00122 return bfd_reloc_undefined;
00123
00124 if (bfd_is_com_section (symbol->section))
00125 relocation = 0;
00126 else
00127 relocation = symbol->value;
00128
00129 relocation += symbol->section->output_section->vma;
00130 relocation += symbol->section->output_offset;
00131 relocation += reloc_entry->addend;
00132
00133 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00134 return bfd_reloc_outofrange;
00135
00136
00137 relocation -= (input_section->output_section->vma
00138 + input_section->output_offset
00139 + reloc_entry->address
00140 + 4);
00141
00142
00143 if ((bfd_signed_vma)relocation > (0x7fff << 2)
00144 || (bfd_signed_vma)relocation < (-0x8000 << 2))
00145 return bfd_reloc_outofrange;
00146
00147 addr = (bfd_byte *) data + reloc_entry->address;
00148 insn = bfd_get_32 (abfd, addr);
00149
00150 relocation >>= reloc_entry->howto->rightshift;
00151 relocation = (((relocation & 0xf800) << 5) | (relocation & 0x7ff))
00152 & reloc_entry->howto->dst_mask;
00153 insn = (insn & ~reloc_entry->howto->dst_mask) | relocation;
00154
00155 bfd_put_32 (abfd, (bfd_vma) insn, addr);
00156
00157 return bfd_reloc_ok;
00158 }
00159
00160
00161 static bfd_reloc_status_type
00162 i860_howto_highadj_reloc (bfd *abfd,
00163 arelent *reloc_entry,
00164 asymbol *symbol,
00165 void *data,
00166 asection *input_section,
00167 bfd *output_bfd,
00168 char **error_message ATTRIBUTE_UNUSED)
00169 {
00170 bfd_vma insn;
00171 bfd_vma relocation;
00172 bfd_byte *addr;
00173
00174 if (output_bfd != NULL
00175 && (symbol->flags & BSF_SECTION_SYM) == 0
00176 && (! reloc_entry->howto->partial_inplace
00177 || reloc_entry->addend == 0))
00178 {
00179 reloc_entry->address += input_section->output_offset;
00180 return bfd_reloc_ok;
00181 }
00182
00183
00184 if (bfd_is_und_section (symbol->section)
00185 && output_bfd == (bfd *) NULL)
00186 return bfd_reloc_undefined;
00187
00188 if (bfd_is_com_section (symbol->section))
00189 relocation = 0;
00190 else
00191 relocation = symbol->value;
00192
00193 relocation += symbol->section->output_section->vma;
00194 relocation += symbol->section->output_offset;
00195 relocation += reloc_entry->addend;
00196 relocation += 0x8000;
00197
00198 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00199 return bfd_reloc_outofrange;
00200
00201 addr = (bfd_byte *) data + reloc_entry->address;
00202 insn = bfd_get_32 (abfd, addr);
00203
00204 relocation = ((relocation >> 16) & 0xffff);
00205
00206 insn = (insn & 0xffff0000) | relocation;
00207
00208 bfd_put_32 (abfd, (bfd_vma) insn, addr);
00209
00210 return bfd_reloc_ok;
00211 }
00212
00213
00214 static bfd_reloc_status_type
00215 i860_howto_splitn_reloc (bfd *abfd,
00216 arelent *reloc_entry,
00217 asymbol *symbol,
00218 void *data,
00219 asection *input_section,
00220 bfd *output_bfd,
00221 char **error_message ATTRIBUTE_UNUSED)
00222 {
00223 bfd_vma insn;
00224 bfd_vma relocation;
00225 bfd_byte *addr;
00226
00227 if (output_bfd != NULL
00228 && (symbol->flags & BSF_SECTION_SYM) == 0
00229 && (! reloc_entry->howto->partial_inplace
00230 || reloc_entry->addend == 0))
00231 {
00232 reloc_entry->address += input_section->output_offset;
00233 return bfd_reloc_ok;
00234 }
00235
00236
00237 if (bfd_is_und_section (symbol->section)
00238 && output_bfd == (bfd *) NULL)
00239 return bfd_reloc_undefined;
00240
00241 if (bfd_is_com_section (symbol->section))
00242 relocation = 0;
00243 else
00244 relocation = symbol->value;
00245
00246 relocation += symbol->section->output_section->vma;
00247 relocation += symbol->section->output_offset;
00248 relocation += reloc_entry->addend;
00249
00250 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00251 return bfd_reloc_outofrange;
00252
00253 addr = (bfd_byte *) data + reloc_entry->address;
00254 insn = bfd_get_32 (abfd, addr);
00255
00256 relocation = (((relocation & 0xf800) << 5) | (relocation & 0x7ff))
00257 & reloc_entry->howto->dst_mask;
00258 insn = (insn & ~reloc_entry->howto->dst_mask) | relocation;
00259
00260 bfd_put_32 (abfd, (bfd_vma) insn, addr);
00261
00262 return bfd_reloc_ok;
00263 }
00264
00265
00266 static reloc_howto_type elf32_i860_howto_table [] =
00267 {
00268
00269 HOWTO (R_860_NONE,
00270 0,
00271 2,
00272 32,
00273 FALSE,
00274 0,
00275 complain_overflow_bitfield,
00276 bfd_elf_generic_reloc,
00277 "R_860_NONE",
00278 FALSE,
00279 0,
00280 0,
00281 FALSE),
00282
00283
00284 HOWTO (R_860_32,
00285 0,
00286 2,
00287 32,
00288 FALSE,
00289 0,
00290 complain_overflow_bitfield,
00291 bfd_elf_generic_reloc,
00292 "R_860_32",
00293 FALSE,
00294 0xffffffff,
00295 0xffffffff,
00296 FALSE),
00297
00298 HOWTO (R_860_COPY,
00299 0,
00300 2,
00301 32,
00302 FALSE,
00303 0,
00304 complain_overflow_bitfield,
00305 bfd_elf_generic_reloc,
00306 "R_860_COPY",
00307 TRUE,
00308 0xffffffff,
00309 0xffffffff,
00310 FALSE),
00311
00312 HOWTO (R_860_GLOB_DAT,
00313 0,
00314 2,
00315 32,
00316 FALSE,
00317 0,
00318 complain_overflow_bitfield,
00319 bfd_elf_generic_reloc,
00320 "R_860_GLOB_DAT",
00321 TRUE,
00322 0xffffffff,
00323 0xffffffff,
00324 FALSE),
00325
00326 HOWTO (R_860_JUMP_SLOT,
00327 0,
00328 2,
00329 32,
00330 FALSE,
00331 0,
00332 complain_overflow_bitfield,
00333 bfd_elf_generic_reloc,
00334 "R_860_JUMP_SLOT",
00335 TRUE,
00336 0xffffffff,
00337 0xffffffff,
00338 FALSE),
00339
00340 HOWTO (R_860_RELATIVE,
00341 0,
00342 2,
00343 32,
00344 FALSE,
00345 0,
00346 complain_overflow_bitfield,
00347 bfd_elf_generic_reloc,
00348 "R_860_RELATIVE",
00349 TRUE,
00350 0xffffffff,
00351 0xffffffff,
00352 FALSE),
00353
00354
00355 HOWTO (R_860_PC26,
00356 2,
00357 2,
00358 26,
00359 TRUE,
00360 0,
00361 complain_overflow_bitfield,
00362 i860_howto_pc26_reloc,
00363 "R_860_PC26",
00364 FALSE,
00365 0x3ffffff,
00366 0x3ffffff,
00367 TRUE),
00368
00369 HOWTO (R_860_PLT26,
00370 0,
00371 2,
00372 26,
00373 TRUE,
00374 0,
00375 complain_overflow_bitfield,
00376 bfd_elf_generic_reloc,
00377 "R_860_PLT26",
00378 TRUE,
00379 0xffffffff,
00380 0xffffffff,
00381 TRUE),
00382
00383
00384 HOWTO (R_860_PC16,
00385 2,
00386 2,
00387 16,
00388 TRUE,
00389 0,
00390 complain_overflow_bitfield,
00391 i860_howto_pc16_reloc,
00392 "R_860_PC16",
00393 FALSE,
00394 0x1f07ff,
00395 0x1f07ff,
00396 TRUE),
00397
00398 HOWTO (R_860_LOW0,
00399 0,
00400 2,
00401 16,
00402 FALSE,
00403 0,
00404 complain_overflow_dont,
00405 bfd_elf_generic_reloc,
00406 "R_860_LOW0",
00407 FALSE,
00408 0xffff,
00409 0xffff,
00410 FALSE),
00411
00412 HOWTO (R_860_SPLIT0,
00413 0,
00414 2,
00415 16,
00416 FALSE,
00417 0,
00418 complain_overflow_dont,
00419 i860_howto_splitn_reloc,
00420 "R_860_SPLIT0",
00421 FALSE,
00422 0x1f07ff,
00423 0x1f07ff,
00424 FALSE),
00425
00426 HOWTO (R_860_LOW1,
00427 0,
00428 2,
00429 16,
00430 FALSE,
00431 0,
00432 complain_overflow_dont,
00433 bfd_elf_generic_reloc,
00434 "R_860_LOW1",
00435 FALSE,
00436 0xfffe,
00437 0xfffe,
00438 FALSE),
00439
00440 HOWTO (R_860_SPLIT1,
00441 0,
00442 2,
00443 16,
00444 FALSE,
00445 0,
00446 complain_overflow_dont,
00447 i860_howto_splitn_reloc,
00448 "R_860_SPLIT1",
00449 FALSE,
00450 0x1f07fe,
00451 0x1f07fe,
00452 FALSE),
00453
00454 HOWTO (R_860_LOW2,
00455 0,
00456 2,
00457 16,
00458 FALSE,
00459 0,
00460 complain_overflow_dont,
00461 bfd_elf_generic_reloc,
00462 "R_860_LOW2",
00463 FALSE,
00464 0xfffc,
00465 0xfffc,
00466 FALSE),
00467
00468 HOWTO (R_860_SPLIT2,
00469 0,
00470 2,
00471 16,
00472 FALSE,
00473 0,
00474 complain_overflow_dont,
00475 i860_howto_splitn_reloc,
00476 "R_860_SPLIT2",
00477 FALSE,
00478 0x1f07fc,
00479 0x1f07fc,
00480 FALSE),
00481
00482 HOWTO (R_860_LOW3,
00483 0,
00484 2,
00485 16,
00486 FALSE,
00487 0,
00488 complain_overflow_dont,
00489 bfd_elf_generic_reloc,
00490 "R_860_LOW3",
00491 FALSE,
00492 0xfff8,
00493 0xfff8,
00494 FALSE),
00495
00496 HOWTO (R_860_LOGOT0,
00497 0,
00498 2,
00499 16,
00500 FALSE,
00501 0,
00502 complain_overflow_dont,
00503 bfd_elf_generic_reloc,
00504 "R_860_LOGOT0",
00505 FALSE,
00506 0,
00507 0xffff,
00508 TRUE),
00509
00510 HOWTO (R_860_SPGOT0,
00511 0,
00512 2,
00513 16,
00514 FALSE,
00515 0,
00516 complain_overflow_dont,
00517 bfd_elf_generic_reloc,
00518 "R_860_SPGOT0",
00519 FALSE,
00520 0,
00521 0xffff,
00522 TRUE),
00523
00524 HOWTO (R_860_LOGOT1,
00525 0,
00526 2,
00527 16,
00528 FALSE,
00529 0,
00530 complain_overflow_dont,
00531 bfd_elf_generic_reloc,
00532 "R_860_LOGOT1",
00533 FALSE,
00534 0,
00535 0xffff,
00536 TRUE),
00537
00538 HOWTO (R_860_SPGOT1,
00539 0,
00540 2,
00541 16,
00542 FALSE,
00543 0,
00544 complain_overflow_dont,
00545 bfd_elf_generic_reloc,
00546 "R_860_SPGOT1",
00547 FALSE,
00548 0,
00549 0xffff,
00550 TRUE),
00551
00552 HOWTO (R_860_LOGOTOFF0,
00553 0,
00554 2,
00555 32,
00556 FALSE,
00557 0,
00558 complain_overflow_dont,
00559 bfd_elf_generic_reloc,
00560 "R_860_LOGOTOFF0",
00561 TRUE,
00562 0xffffffff,
00563 0xffffffff,
00564 FALSE),
00565
00566 HOWTO (R_860_SPGOTOFF0,
00567 0,
00568 2,
00569 32,
00570 FALSE,
00571 0,
00572 complain_overflow_dont,
00573 bfd_elf_generic_reloc,
00574 "R_860_SPGOTOFF0",
00575 TRUE,
00576 0xffffffff,
00577 0xffffffff,
00578 FALSE),
00579
00580 HOWTO (R_860_LOGOTOFF1,
00581 0,
00582 2,
00583 32,
00584 FALSE,
00585 0,
00586 complain_overflow_dont,
00587 bfd_elf_generic_reloc,
00588 "R_860_LOGOTOFF1",
00589 TRUE,
00590 0xffffffff,
00591 0xffffffff,
00592 FALSE),
00593
00594 HOWTO (R_860_SPGOTOFF1,
00595 0,
00596 2,
00597 32,
00598 FALSE,
00599 0,
00600 complain_overflow_dont,
00601 bfd_elf_generic_reloc,
00602 "R_860_SPGOTOFF1",
00603 TRUE,
00604 0xffffffff,
00605 0xffffffff,
00606 FALSE),
00607
00608 HOWTO (R_860_LOGOTOFF2,
00609 0,
00610 2,
00611 32,
00612 FALSE,
00613 0,
00614 complain_overflow_dont,
00615 bfd_elf_generic_reloc,
00616 "R_860_LOGOTOFF2",
00617 TRUE,
00618 0xffffffff,
00619 0xffffffff,
00620 FALSE),
00621
00622 HOWTO (R_860_LOGOTOFF3,
00623 0,
00624 2,
00625 32,
00626 FALSE,
00627 0,
00628 complain_overflow_dont,
00629 bfd_elf_generic_reloc,
00630 "R_860_LOGOTOFF3",
00631 TRUE,
00632 0xffffffff,
00633 0xffffffff,
00634 FALSE),
00635
00636 HOWTO (R_860_LOPC,
00637 0,
00638 2,
00639 16,
00640 TRUE,
00641 0,
00642 complain_overflow_bitfield,
00643 bfd_elf_generic_reloc,
00644 "R_860_LOPC",
00645 FALSE,
00646 0xffff,
00647 0xffff,
00648 TRUE),
00649
00650 HOWTO (R_860_HIGHADJ,
00651 0,
00652 2,
00653 16,
00654 FALSE,
00655 0,
00656 complain_overflow_dont,
00657 i860_howto_highadj_reloc,
00658 "R_860_HIGHADJ",
00659 FALSE,
00660 0xffff,
00661 0xffff,
00662 FALSE),
00663
00664 HOWTO (R_860_HAGOT,
00665 0,
00666 2,
00667 16,
00668 FALSE,
00669 0,
00670 complain_overflow_dont,
00671 bfd_elf_generic_reloc,
00672 "R_860_HAGOT",
00673 FALSE,
00674 0,
00675 0xffff,
00676 TRUE),
00677
00678 HOWTO (R_860_HAGOTOFF,
00679 0,
00680 2,
00681 32,
00682 FALSE,
00683 0,
00684 complain_overflow_dont,
00685 bfd_elf_generic_reloc,
00686 "R_860_HAGOTOFF",
00687 TRUE,
00688 0xffffffff,
00689 0xffffffff,
00690 FALSE),
00691
00692 HOWTO (R_860_HAPC,
00693 0,
00694 2,
00695 16,
00696 TRUE,
00697 0,
00698 complain_overflow_bitfield,
00699 bfd_elf_generic_reloc,
00700 "R_860_HAPC",
00701 FALSE,
00702 0xffff,
00703 0xffff,
00704 TRUE),
00705
00706 HOWTO (R_860_HIGH,
00707 16,
00708 2,
00709 16,
00710 FALSE,
00711 0,
00712 complain_overflow_dont,
00713 bfd_elf_generic_reloc,
00714 "R_860_HIGH",
00715 FALSE,
00716 0xffff,
00717 0xffff,
00718 FALSE),
00719
00720 HOWTO (R_860_HIGOT,
00721 0,
00722 2,
00723 16,
00724 FALSE,
00725 0,
00726 complain_overflow_dont,
00727 bfd_elf_generic_reloc,
00728 "R_860_HIGOT",
00729 FALSE,
00730 0,
00731 0xffff,
00732 TRUE),
00733
00734 HOWTO (R_860_HIGOTOFF,
00735 0,
00736 2,
00737 32,
00738 FALSE,
00739 0,
00740 complain_overflow_dont,
00741 bfd_elf_generic_reloc,
00742 "R_860_HIGOTOFF",
00743 TRUE,
00744 0xffffffff,
00745 0xffffffff,
00746 FALSE),
00747 };
00748
00749 static unsigned char elf_code_to_howto_index[R_860_max + 1];
00750
00751 static reloc_howto_type *
00752 lookup_howto (unsigned int rtype)
00753 {
00754 static int initialized = 0;
00755 int i;
00756 int howto_tbl_size = (int) (sizeof (elf32_i860_howto_table)
00757 / sizeof (elf32_i860_howto_table[0]));
00758
00759 if (! initialized)
00760 {
00761 initialized = 1;
00762 memset (elf_code_to_howto_index, 0xff,
00763 sizeof (elf_code_to_howto_index));
00764 for (i = 0; i < howto_tbl_size; i++)
00765 elf_code_to_howto_index[elf32_i860_howto_table[i].type] = i;
00766 }
00767
00768 BFD_ASSERT (rtype <= R_860_max);
00769 i = elf_code_to_howto_index[rtype];
00770 if (i >= howto_tbl_size)
00771 return 0;
00772 return elf32_i860_howto_table + i;
00773 }
00774
00775
00776 static reloc_howto_type *
00777 elf32_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00778 bfd_reloc_code_real_type code)
00779 {
00780 unsigned int rtype;
00781
00782 switch (code)
00783 {
00784 case BFD_RELOC_NONE:
00785 rtype = R_860_NONE;
00786 break;
00787 case BFD_RELOC_32:
00788 rtype = R_860_32;
00789 break;
00790 case BFD_RELOC_860_COPY:
00791 rtype = R_860_COPY;
00792 break;
00793 case BFD_RELOC_860_GLOB_DAT:
00794 rtype = R_860_GLOB_DAT;
00795 break;
00796 case BFD_RELOC_860_JUMP_SLOT:
00797 rtype = R_860_JUMP_SLOT;
00798 break;
00799 case BFD_RELOC_860_RELATIVE:
00800 rtype = R_860_RELATIVE;
00801 break;
00802 case BFD_RELOC_860_PC26:
00803 rtype = R_860_PC26;
00804 break;
00805 case BFD_RELOC_860_PLT26:
00806 rtype = R_860_PLT26;
00807 break;
00808 case BFD_RELOC_860_PC16:
00809 rtype = R_860_PC16;
00810 break;
00811 case BFD_RELOC_860_LOW0:
00812 rtype = R_860_LOW0;
00813 break;
00814 case BFD_RELOC_860_SPLIT0:
00815 rtype = R_860_SPLIT0;
00816 break;
00817 case BFD_RELOC_860_LOW1:
00818 rtype = R_860_LOW1;
00819 break;
00820 case BFD_RELOC_860_SPLIT1:
00821 rtype = R_860_SPLIT1;
00822 break;
00823 case BFD_RELOC_860_LOW2:
00824 rtype = R_860_LOW2;
00825 break;
00826 case BFD_RELOC_860_SPLIT2:
00827 rtype = R_860_SPLIT2;
00828 break;
00829 case BFD_RELOC_860_LOW3:
00830 rtype = R_860_LOW3;
00831 break;
00832 case BFD_RELOC_860_LOGOT0:
00833 rtype = R_860_LOGOT0;
00834 break;
00835 case BFD_RELOC_860_SPGOT0:
00836 rtype = R_860_SPGOT0;
00837 break;
00838 case BFD_RELOC_860_LOGOT1:
00839 rtype = R_860_LOGOT1;
00840 break;
00841 case BFD_RELOC_860_SPGOT1:
00842 rtype = R_860_SPGOT1;
00843 break;
00844 case BFD_RELOC_860_LOGOTOFF0:
00845 rtype = R_860_LOGOTOFF0;
00846 break;
00847 case BFD_RELOC_860_SPGOTOFF0:
00848 rtype = R_860_SPGOTOFF0;
00849 break;
00850 case BFD_RELOC_860_LOGOTOFF1:
00851 rtype = R_860_LOGOTOFF1;
00852 break;
00853 case BFD_RELOC_860_SPGOTOFF1:
00854 rtype = R_860_SPGOTOFF1;
00855 break;
00856 case BFD_RELOC_860_LOGOTOFF2:
00857 rtype = R_860_LOGOTOFF2;
00858 break;
00859 case BFD_RELOC_860_LOGOTOFF3:
00860 rtype = R_860_LOGOTOFF3;
00861 break;
00862 case BFD_RELOC_860_LOPC:
00863 rtype = R_860_LOPC;
00864 break;
00865 case BFD_RELOC_860_HIGHADJ:
00866 rtype = R_860_HIGHADJ;
00867 break;
00868 case BFD_RELOC_860_HAGOT:
00869 rtype = R_860_HAGOT;
00870 break;
00871 case BFD_RELOC_860_HAGOTOFF:
00872 rtype = R_860_HAGOTOFF;
00873 break;
00874 case BFD_RELOC_860_HAPC:
00875 rtype = R_860_HAPC;
00876 break;
00877 case BFD_RELOC_860_HIGH:
00878 rtype = R_860_HIGH;
00879 break;
00880 case BFD_RELOC_860_HIGOT:
00881 rtype = R_860_HIGOT;
00882 break;
00883 case BFD_RELOC_860_HIGOTOFF:
00884 rtype = R_860_HIGOTOFF;
00885 break;
00886 default:
00887 rtype = 0;
00888 break;
00889 }
00890 return lookup_howto (rtype);
00891 }
00892
00893
00894 static void
00895 elf32_i860_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
00896 arelent *bfd_reloc,
00897 Elf_Internal_Rela *elf_reloc)
00898 {
00899 bfd_reloc->howto
00900 = lookup_howto ((unsigned) ELF32_R_TYPE (elf_reloc->r_info));
00901 }
00902
00903
00904
00905 static bfd_reloc_status_type
00906 elf32_i860_relocate_splitn (bfd *input_bfd,
00907 Elf_Internal_Rela *rello,
00908 bfd_byte *contents,
00909 bfd_vma value)
00910 {
00911 bfd_vma insn;
00912 reloc_howto_type *howto;
00913 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
00914 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
00915
00916
00917 value += rello->r_addend;
00918
00919
00920 value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
00921 insn = (insn & ~howto->dst_mask) | value;
00922
00923 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
00924 return bfd_reloc_ok;
00925 }
00926
00927
00928
00929
00930 static bfd_reloc_status_type
00931 elf32_i860_relocate_pc16 (bfd *input_bfd,
00932 asection *input_section,
00933 Elf_Internal_Rela *rello,
00934 bfd_byte *contents,
00935 bfd_vma value)
00936 {
00937 bfd_vma insn;
00938 reloc_howto_type *howto;
00939 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
00940 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
00941
00942
00943 value -= (input_section->output_section->vma
00944 + input_section->output_offset);
00945 value -= rello->r_offset;
00946
00947
00948 value += rello->r_addend;
00949
00950
00951 value = (value - 4) >> howto->rightshift;
00952 value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
00953 insn = (insn & ~howto->dst_mask) | value;
00954
00955 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
00956 return bfd_reloc_ok;
00957
00958 }
00959
00960
00961
00962 static bfd_reloc_status_type
00963 elf32_i860_relocate_pc26 (bfd *input_bfd,
00964 asection *input_section,
00965 Elf_Internal_Rela *rello,
00966 bfd_byte *contents,
00967 bfd_vma value)
00968 {
00969 bfd_vma insn;
00970 reloc_howto_type *howto;
00971 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
00972 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
00973
00974
00975 value -= (input_section->output_section->vma
00976 + input_section->output_offset);
00977 value -= rello->r_offset;
00978
00979
00980 value += rello->r_addend;
00981
00982
00983 value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
00984 insn = (insn & ~howto->dst_mask) | value;
00985
00986 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
00987 return bfd_reloc_ok;
00988
00989 }
00990
00991
00992 static bfd_reloc_status_type
00993 elf32_i860_relocate_highadj (bfd *input_bfd,
00994 Elf_Internal_Rela *rel,
00995 bfd_byte *contents,
00996 bfd_vma value)
00997 {
00998 bfd_vma insn;
00999
01000 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
01001
01002 value += rel->r_addend;
01003 value += 0x8000;
01004 value = ((value >> 16) & 0xffff);
01005
01006 insn = (insn & 0xffff0000) | value;
01007
01008 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
01009 return bfd_reloc_ok;
01010 }
01011
01012
01013
01014 static bfd_reloc_status_type
01015 i860_final_link_relocate (reloc_howto_type *howto,
01016 bfd *input_bfd,
01017 asection *input_section,
01018 bfd_byte *contents,
01019 Elf_Internal_Rela *rel,
01020 bfd_vma relocation)
01021 {
01022 return _bfd_final_link_relocate (howto, input_bfd, input_section,
01023 contents, rel->r_offset, relocation,
01024 rel->r_addend);
01025 }
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 static bfd_boolean
01059 elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
01060 struct bfd_link_info *info,
01061 bfd *input_bfd,
01062 asection *input_section,
01063 bfd_byte *contents,
01064 Elf_Internal_Rela *relocs,
01065 Elf_Internal_Sym *local_syms,
01066 asection **local_sections)
01067 {
01068 Elf_Internal_Shdr *symtab_hdr;
01069 struct elf_link_hash_entry **sym_hashes;
01070 Elf_Internal_Rela *rel;
01071 Elf_Internal_Rela *relend;
01072
01073 if (info->relocatable)
01074 return TRUE;
01075
01076 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
01077 sym_hashes = elf_sym_hashes (input_bfd);
01078 relend = relocs + input_section->reloc_count;
01079
01080 for (rel = relocs; rel < relend; rel ++)
01081 {
01082 reloc_howto_type * howto;
01083 unsigned long r_symndx;
01084 Elf_Internal_Sym * sym;
01085 asection * sec;
01086 struct elf_link_hash_entry * h;
01087 bfd_vma relocation;
01088 bfd_reloc_status_type r;
01089 const char * name = NULL;
01090 int r_type;
01091
01092 r_type = ELF32_R_TYPE (rel->r_info);
01093 r_symndx = ELF32_R_SYM (rel->r_info);
01094
01095 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
01096 h = NULL;
01097 sym = NULL;
01098 sec = NULL;
01099
01100 if (r_symndx < symtab_hdr->sh_info)
01101 {
01102 sym = local_syms + r_symndx;
01103 sec = local_sections [r_symndx];
01104 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
01105
01106 name = bfd_elf_string_from_elf_section
01107 (input_bfd, symtab_hdr->sh_link, sym->st_name);
01108 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
01109 }
01110 else
01111 {
01112 bfd_boolean unresolved_reloc, warned;
01113
01114 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
01115 r_symndx, symtab_hdr, sym_hashes,
01116 h, sec, relocation,
01117 unresolved_reloc, warned);
01118 }
01119
01120 switch (r_type)
01121 {
01122 default:
01123 r = i860_final_link_relocate (howto, input_bfd, input_section,
01124 contents, rel, relocation);
01125 break;
01126
01127 case R_860_HIGHADJ:
01128 r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
01129 relocation);
01130 break;
01131
01132 case R_860_PC16:
01133 r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
01134 contents, relocation);
01135 break;
01136
01137 case R_860_PC26:
01138 r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
01139 contents, relocation);
01140 break;
01141
01142 case R_860_SPLIT0:
01143 case R_860_SPLIT1:
01144 case R_860_SPLIT2:
01145 r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
01146 relocation);
01147 break;
01148
01149
01150 case R_860_COPY:
01151 case R_860_GLOB_DAT:
01152 case R_860_JUMP_SLOT:
01153 case R_860_RELATIVE:
01154 case R_860_PLT26:
01155 case R_860_LOGOT0:
01156 case R_860_SPGOT0:
01157 case R_860_LOGOT1:
01158 case R_860_SPGOT1:
01159 case R_860_LOGOTOFF0:
01160 case R_860_SPGOTOFF0:
01161 case R_860_LOGOTOFF1:
01162 case R_860_SPGOTOFF1:
01163 case R_860_LOGOTOFF2:
01164 case R_860_LOGOTOFF3:
01165 case R_860_LOPC:
01166 case R_860_HAGOT:
01167 case R_860_HAGOTOFF:
01168 case R_860_HAPC:
01169 case R_860_HIGOT:
01170 case R_860_HIGOTOFF:
01171 r = bfd_reloc_notsupported;
01172 break;
01173 }
01174
01175 if (r != bfd_reloc_ok)
01176 {
01177 const char * msg = (const char *) NULL;
01178
01179 switch (r)
01180 {
01181 case bfd_reloc_overflow:
01182 r = info->callbacks->reloc_overflow
01183 (info, (h ? &h->root : NULL), name, howto->name,
01184 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
01185 break;
01186
01187 case bfd_reloc_undefined:
01188 r = info->callbacks->undefined_symbol
01189 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
01190 break;
01191
01192 case bfd_reloc_outofrange:
01193 msg = _("internal error: out of range error");
01194 break;
01195
01196 case bfd_reloc_notsupported:
01197 msg = _("internal error: unsupported relocation error");
01198 break;
01199
01200 case bfd_reloc_dangerous:
01201 msg = _("internal error: dangerous relocation");
01202 break;
01203
01204 default:
01205 msg = _("internal error: unknown error");
01206 break;
01207 }
01208
01209 if (msg)
01210 r = info->callbacks->warning
01211 (info, msg, name, input_bfd, input_section, rel->r_offset);
01212
01213 if (! r)
01214 return FALSE;
01215 }
01216 }
01217
01218 return TRUE;
01219 }
01220
01221
01222
01223
01224
01225
01226 static bfd_boolean
01227 elf32_i860_is_local_label_name (bfd *abfd, const char *name)
01228 {
01229 if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
01230 return TRUE;
01231
01232 return _bfd_elf_is_local_label_name (abfd, name);
01233 }
01234
01235 #define TARGET_BIG_SYM bfd_elf32_i860_vec
01236 #define TARGET_BIG_NAME "elf32-i860"
01237 #define TARGET_LITTLE_SYM bfd_elf32_i860_little_vec
01238 #define TARGET_LITTLE_NAME "elf32-i860-little"
01239 #define ELF_ARCH bfd_arch_i860
01240 #define ELF_MACHINE_CODE EM_860
01241 #define ELF_MAXPAGESIZE 4096
01242
01243 #define elf_backend_rela_normal 1
01244 #define elf_info_to_howto_rel NULL
01245 #define elf_info_to_howto elf32_i860_info_to_howto_rela
01246 #define elf_backend_relocate_section elf32_i860_relocate_section
01247 #define bfd_elf32_bfd_reloc_type_lookup elf32_i860_reloc_type_lookup
01248 #define bfd_elf32_bfd_is_local_label_name elf32_i860_is_local_label_name
01249
01250 #include "elf32-target.h"