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 #include "bfd.h"
00026 #include "sysdep.h"
00027 #include "libiberty.h"
00028 #include "libbfd.h"
00029 #include "elf-bfd.h"
00030 #include "elf/msp430.h"
00031
00032
00033 #undef USE_REL
00034
00035 static reloc_howto_type elf_msp430_howto_table[] =
00036 {
00037 HOWTO (R_MSP430_NONE,
00038 0,
00039 2,
00040 32,
00041 FALSE,
00042 0,
00043 complain_overflow_bitfield,
00044 bfd_elf_generic_reloc,
00045 "R_MSP430_NONE",
00046 FALSE,
00047 0,
00048 0,
00049 FALSE),
00050
00051 HOWTO (R_MSP430_32,
00052 0,
00053 2,
00054 32,
00055 FALSE,
00056 0,
00057 complain_overflow_bitfield,
00058 bfd_elf_generic_reloc,
00059 "R_MSP430_32",
00060 FALSE,
00061 0xffffffff,
00062 0xffffffff,
00063 FALSE),
00064
00065
00066 HOWTO (R_MSP430_10_PCREL,
00067 1,
00068 1,
00069 10,
00070 TRUE,
00071 0,
00072 complain_overflow_bitfield,
00073 bfd_elf_generic_reloc,
00074 "R_MSP430_13_PCREL",
00075 FALSE,
00076 0xfff,
00077 0xfff,
00078 TRUE),
00079
00080
00081 HOWTO (R_MSP430_16,
00082 0,
00083 1,
00084 16,
00085 FALSE,
00086 0,
00087 complain_overflow_dont,
00088 bfd_elf_generic_reloc,
00089 "R_MSP430_16",
00090 FALSE,
00091 0,
00092 0xffff,
00093 FALSE),
00094
00095
00096 HOWTO (R_MSP430_16_PCREL,
00097 1,
00098 1,
00099 16,
00100 TRUE,
00101 0,
00102 complain_overflow_dont,
00103 bfd_elf_generic_reloc,
00104 "R_MSP430_16_PCREL",
00105 FALSE,
00106 0,
00107 0xffff,
00108 TRUE),
00109
00110
00111 HOWTO (R_MSP430_16_BYTE,
00112 0,
00113 1,
00114 16,
00115 FALSE,
00116 0,
00117 complain_overflow_dont,
00118 bfd_elf_generic_reloc,
00119 "R_MSP430_16_BYTE",
00120 FALSE,
00121 0xffff,
00122 0xffff,
00123 FALSE),
00124
00125
00126 HOWTO (R_MSP430_16_PCREL_BYTE,
00127 1,
00128 1,
00129 16,
00130 TRUE,
00131 0,
00132 complain_overflow_dont,
00133 bfd_elf_generic_reloc,
00134 "R_MSP430_16_PCREL_BYTE",
00135 FALSE,
00136 0xffff,
00137 0xffff,
00138 TRUE),
00139
00140
00141 HOWTO (R_MSP430_2X_PCREL,
00142 1,
00143 2,
00144 10,
00145 TRUE,
00146 0,
00147 complain_overflow_bitfield,
00148 bfd_elf_generic_reloc,
00149 "R_MSP430_2X_PCREL",
00150 FALSE,
00151 0xfff,
00152 0xfff,
00153 TRUE),
00154
00155
00156 HOWTO (R_MSP430_RL_PCREL,
00157 1,
00158 1,
00159 16,
00160 TRUE,
00161 0,
00162 complain_overflow_dont,
00163 bfd_elf_generic_reloc,
00164 "R_MSP430_RL_PCREL",
00165 FALSE,
00166 0,
00167 0xffff,
00168 TRUE)
00169 };
00170
00171
00172
00173 struct msp430_reloc_map
00174 {
00175 bfd_reloc_code_real_type bfd_reloc_val;
00176 unsigned int elf_reloc_val;
00177 };
00178
00179 static const struct msp430_reloc_map msp430_reloc_map[] =
00180 {
00181 {BFD_RELOC_NONE, R_MSP430_NONE},
00182 {BFD_RELOC_32, R_MSP430_32},
00183 {BFD_RELOC_MSP430_10_PCREL, R_MSP430_10_PCREL},
00184 {BFD_RELOC_16, R_MSP430_16_BYTE},
00185 {BFD_RELOC_MSP430_16_PCREL, R_MSP430_16_PCREL},
00186 {BFD_RELOC_MSP430_16, R_MSP430_16},
00187 {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
00188 {BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE},
00189 {BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL},
00190 {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL}
00191 };
00192
00193 static reloc_howto_type *
00194 bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
00195 bfd_reloc_code_real_type code)
00196 {
00197 unsigned int i;
00198
00199 for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++)
00200 if (msp430_reloc_map[i].bfd_reloc_val == code)
00201 return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val];
00202
00203 return NULL;
00204 }
00205
00206
00207
00208 static void
00209 msp430_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
00210 arelent * cache_ptr,
00211 Elf_Internal_Rela * dst)
00212 {
00213 unsigned int r_type;
00214
00215 r_type = ELF32_R_TYPE (dst->r_info);
00216 BFD_ASSERT (r_type < (unsigned int) R_MSP430_max);
00217 cache_ptr->howto = &elf_msp430_howto_table[r_type];
00218 }
00219
00220 static asection *
00221 elf32_msp430_gc_mark_hook (asection * sec,
00222 struct bfd_link_info * info ATTRIBUTE_UNUSED,
00223 Elf_Internal_Rela * rel,
00224 struct elf_link_hash_entry * h,
00225 Elf_Internal_Sym * sym)
00226 {
00227 if (h != NULL)
00228 {
00229 switch (ELF32_R_TYPE (rel->r_info))
00230 {
00231 default:
00232 switch (h->root.type)
00233 {
00234 case bfd_link_hash_defined:
00235 case bfd_link_hash_defweak:
00236 return h->root.u.def.section;
00237
00238 case bfd_link_hash_common:
00239 return h->root.u.c.p->section;
00240
00241 default:
00242 break;
00243 }
00244 }
00245 }
00246 else
00247 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
00248
00249 return NULL;
00250 }
00251
00252 static bfd_boolean
00253 elf32_msp430_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
00254 struct bfd_link_info * info ATTRIBUTE_UNUSED,
00255 asection * sec ATTRIBUTE_UNUSED,
00256 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
00257 {
00258
00259 return TRUE;
00260 }
00261
00262
00263
00264
00265
00266 static bfd_boolean
00267 elf32_msp430_check_relocs (bfd * abfd, struct bfd_link_info * info,
00268 asection * sec, const Elf_Internal_Rela * relocs)
00269 {
00270 Elf_Internal_Shdr *symtab_hdr;
00271 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
00272 const Elf_Internal_Rela *rel;
00273 const Elf_Internal_Rela *rel_end;
00274
00275 if (info->relocatable)
00276 return TRUE;
00277
00278 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00279 sym_hashes = elf_sym_hashes (abfd);
00280 sym_hashes_end =
00281 sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
00282 if (!elf_bad_symtab (abfd))
00283 sym_hashes_end -= symtab_hdr->sh_info;
00284
00285 rel_end = relocs + sec->reloc_count;
00286 for (rel = relocs; rel < rel_end; rel++)
00287 {
00288 struct elf_link_hash_entry *h;
00289 unsigned long r_symndx;
00290
00291 r_symndx = ELF32_R_SYM (rel->r_info);
00292 if (r_symndx < symtab_hdr->sh_info)
00293 h = NULL;
00294 else
00295 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
00296 }
00297
00298 return TRUE;
00299 }
00300
00301
00302
00303
00304 static bfd_reloc_status_type
00305 msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
00306 asection * input_section, bfd_byte * contents,
00307 Elf_Internal_Rela * rel, bfd_vma relocation)
00308 {
00309 bfd_reloc_status_type r = bfd_reloc_ok;
00310 bfd_vma x;
00311 bfd_signed_vma srel;
00312
00313 switch (howto->type)
00314 {
00315 case R_MSP430_10_PCREL:
00316 contents += rel->r_offset;
00317 srel = (bfd_signed_vma) relocation;
00318 srel += rel->r_addend;
00319 srel -= rel->r_offset;
00320 srel -= 2;
00321 srel -= (input_section->output_section->vma +
00322 input_section->output_offset);
00323
00324 if (srel & 1)
00325 return bfd_reloc_outofrange;
00326
00327
00328 srel >>= 1;
00329
00330
00331 if (srel < -512 || srel > 511)
00332 return bfd_reloc_overflow;
00333
00334 x = bfd_get_16 (input_bfd, contents);
00335 x = (x & 0xfc00) | (srel & 0x3ff);
00336 bfd_put_16 (input_bfd, x, contents);
00337 break;
00338
00339 case R_MSP430_2X_PCREL:
00340 contents += rel->r_offset;
00341 srel = (bfd_signed_vma) relocation;
00342 srel += rel->r_addend;
00343 srel -= rel->r_offset;
00344 srel -= 2;
00345 srel -= (input_section->output_section->vma +
00346 input_section->output_offset);
00347
00348 if (srel & 1)
00349 return bfd_reloc_outofrange;
00350
00351
00352 srel >>= 1;
00353
00354
00355 if (srel < -512 || srel > 511)
00356 return bfd_reloc_overflow;
00357
00358 x = bfd_get_16 (input_bfd, contents);
00359 x = (x & 0xfc00) | (srel & 0x3ff);
00360 bfd_put_16 (input_bfd, x, contents);
00361
00362 x = bfd_get_16 (input_bfd, contents - 2);
00363 srel += 1;
00364 x = (x & 0xfc00) | (srel & 0x3ff);
00365 bfd_put_16 (input_bfd, x, contents - 2);
00366 break;
00367
00368 case R_MSP430_16_PCREL:
00369 case R_MSP430_RL_PCREL:
00370 contents += rel->r_offset;
00371 srel = (bfd_signed_vma) relocation;
00372 srel += rel->r_addend;
00373 srel -= rel->r_offset;
00374
00375 srel -= (input_section->output_section->vma +
00376 input_section->output_offset);
00377
00378 if (srel & 1)
00379 return bfd_reloc_outofrange;
00380
00381 bfd_put_16 (input_bfd, srel & 0xffff, contents);
00382 break;
00383
00384 case R_MSP430_16_PCREL_BYTE:
00385 contents += rel->r_offset;
00386 srel = (bfd_signed_vma) relocation;
00387 srel += rel->r_addend;
00388 srel -= rel->r_offset;
00389
00390 srel -= (input_section->output_section->vma +
00391 input_section->output_offset);
00392
00393 bfd_put_16 (input_bfd, srel & 0xffff, contents);
00394 break;
00395
00396 case R_MSP430_16_BYTE:
00397 contents += rel->r_offset;
00398 srel = (bfd_signed_vma) relocation;
00399 srel += rel->r_addend;
00400 bfd_put_16 (input_bfd, srel & 0xffff, contents);
00401 break;
00402
00403 case R_MSP430_16:
00404 contents += rel->r_offset;
00405 srel = (bfd_signed_vma) relocation;
00406 srel += rel->r_addend;
00407
00408 if (srel & 1)
00409 return bfd_reloc_notsupported;
00410
00411 bfd_put_16 (input_bfd, srel & 0xffff, contents);
00412 break;
00413
00414 default:
00415 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
00416 contents, rel->r_offset,
00417 relocation, rel->r_addend);
00418 }
00419
00420 return r;
00421 }
00422
00423
00424
00425 static bfd_boolean
00426 elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
00427 struct bfd_link_info * info,
00428 bfd * input_bfd,
00429 asection * input_section,
00430 bfd_byte * contents,
00431 Elf_Internal_Rela * relocs,
00432 Elf_Internal_Sym * local_syms,
00433 asection ** local_sections)
00434 {
00435 Elf_Internal_Shdr *symtab_hdr;
00436 struct elf_link_hash_entry **sym_hashes;
00437 Elf_Internal_Rela *rel;
00438 Elf_Internal_Rela *relend;
00439
00440 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
00441 sym_hashes = elf_sym_hashes (input_bfd);
00442 relend = relocs + input_section->reloc_count;
00443
00444 for (rel = relocs; rel < relend; rel++)
00445 {
00446 reloc_howto_type *howto;
00447 unsigned long r_symndx;
00448 Elf_Internal_Sym *sym;
00449 asection *sec;
00450 struct elf_link_hash_entry *h;
00451 bfd_vma relocation;
00452 bfd_reloc_status_type r;
00453 const char *name = NULL;
00454 int r_type;
00455
00456
00457
00458 r_type = ELF32_R_TYPE (rel->r_info);
00459 r_symndx = ELF32_R_SYM (rel->r_info);
00460 howto = elf_msp430_howto_table + ELF32_R_TYPE (rel->r_info);
00461 h = NULL;
00462 sym = NULL;
00463 sec = NULL;
00464
00465 if (r_symndx < symtab_hdr->sh_info)
00466 {
00467 sym = local_syms + r_symndx;
00468 sec = local_sections[r_symndx];
00469 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
00470
00471 name = bfd_elf_string_from_elf_section
00472 (input_bfd, symtab_hdr->sh_link, sym->st_name);
00473 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
00474 }
00475 else
00476 {
00477 bfd_boolean unresolved_reloc, warned;
00478
00479 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
00480 r_symndx, symtab_hdr, sym_hashes,
00481 h, sec, relocation,
00482 unresolved_reloc, warned);
00483 }
00484
00485 r = msp430_final_link_relocate (howto, input_bfd, input_section,
00486 contents, rel, relocation);
00487
00488 if (r != bfd_reloc_ok)
00489 {
00490 const char *msg = (const char *) NULL;
00491
00492 switch (r)
00493 {
00494 case bfd_reloc_overflow:
00495 r = info->callbacks->reloc_overflow
00496 (info, (h ? &h->root : NULL), name, howto->name,
00497 (bfd_vma) 0, input_bfd, input_section,
00498 rel->r_offset);
00499 break;
00500
00501 case bfd_reloc_undefined:
00502 r = info->callbacks->undefined_symbol
00503 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
00504 break;
00505
00506 case bfd_reloc_outofrange:
00507 msg = _("internal error: out of range error");
00508 break;
00509
00510 case bfd_reloc_notsupported:
00511 msg = _("internal error: unsupported relocation error");
00512 break;
00513
00514 case bfd_reloc_dangerous:
00515 msg = _("internal error: dangerous relocation");
00516 break;
00517
00518 default:
00519 msg = _("internal error: unknown error");
00520 break;
00521 }
00522
00523 if (msg)
00524 r = info->callbacks->warning
00525 (info, msg, name, input_bfd, input_section, rel->r_offset);
00526
00527 if (!r)
00528 return FALSE;
00529 }
00530
00531 }
00532
00533 return TRUE;
00534 }
00535
00536
00537
00538
00539
00540 static void
00541 bfd_elf_msp430_final_write_processing (bfd * abfd,
00542 bfd_boolean linker ATTRIBUTE_UNUSED)
00543 {
00544 unsigned long val;
00545
00546 switch (bfd_get_mach (abfd))
00547 {
00548 default:
00549 case bfd_mach_msp110:
00550 val = E_MSP430_MACH_MSP430x11x1;
00551 break;
00552
00553 case bfd_mach_msp11:
00554 val = E_MSP430_MACH_MSP430x11;
00555 break;
00556
00557 case bfd_mach_msp12:
00558 val = E_MSP430_MACH_MSP430x12;
00559 break;
00560
00561 case bfd_mach_msp13:
00562 val = E_MSP430_MACH_MSP430x13;
00563 break;
00564
00565 case bfd_mach_msp14:
00566 val = E_MSP430_MACH_MSP430x14;
00567 break;
00568
00569 case bfd_mach_msp15:
00570 val = E_MSP430_MACH_MSP430x15;
00571 break;
00572
00573 case bfd_mach_msp16:
00574 val = E_MSP430_MACH_MSP430x16;
00575 break;
00576
00577 case bfd_mach_msp31:
00578 val = E_MSP430_MACH_MSP430x31;
00579 break;
00580
00581 case bfd_mach_msp32:
00582 val = E_MSP430_MACH_MSP430x32;
00583 break;
00584
00585 case bfd_mach_msp33:
00586 val = E_MSP430_MACH_MSP430x33;
00587 break;
00588
00589 case bfd_mach_msp41:
00590 val = E_MSP430_MACH_MSP430x41;
00591 break;
00592
00593 case bfd_mach_msp42:
00594 val = E_MSP430_MACH_MSP430x42;
00595 break;
00596
00597 case bfd_mach_msp43:
00598 val = E_MSP430_MACH_MSP430x43;
00599 break;
00600
00601 case bfd_mach_msp44:
00602 val = E_MSP430_MACH_MSP430x44;
00603 break;
00604 }
00605
00606 elf_elfheader (abfd)->e_machine = EM_MSP430;
00607 elf_elfheader (abfd)->e_flags &= ~EF_MSP430_MACH;
00608 elf_elfheader (abfd)->e_flags |= val;
00609 }
00610
00611
00612
00613 static bfd_boolean
00614 elf32_msp430_object_p (bfd * abfd)
00615 {
00616 int e_set = bfd_mach_msp14;
00617
00618 if (elf_elfheader (abfd)->e_machine == EM_MSP430
00619 || elf_elfheader (abfd)->e_machine == EM_MSP430_OLD)
00620 {
00621 int e_mach = elf_elfheader (abfd)->e_flags & EF_MSP430_MACH;
00622
00623 switch (e_mach)
00624 {
00625 default:
00626 case E_MSP430_MACH_MSP430x11:
00627 e_set = bfd_mach_msp11;
00628 break;
00629
00630 case E_MSP430_MACH_MSP430x11x1:
00631 e_set = bfd_mach_msp110;
00632 break;
00633
00634 case E_MSP430_MACH_MSP430x12:
00635 e_set = bfd_mach_msp12;
00636 break;
00637
00638 case E_MSP430_MACH_MSP430x13:
00639 e_set = bfd_mach_msp13;
00640 break;
00641
00642 case E_MSP430_MACH_MSP430x14:
00643 e_set = bfd_mach_msp14;
00644 break;
00645
00646 case E_MSP430_MACH_MSP430x15:
00647 e_set = bfd_mach_msp15;
00648 break;
00649
00650 case E_MSP430_MACH_MSP430x16:
00651 e_set = bfd_mach_msp16;
00652 break;
00653
00654 case E_MSP430_MACH_MSP430x31:
00655 e_set = bfd_mach_msp31;
00656 break;
00657
00658 case E_MSP430_MACH_MSP430x32:
00659 e_set = bfd_mach_msp32;
00660 break;
00661
00662 case E_MSP430_MACH_MSP430x33:
00663 e_set = bfd_mach_msp33;
00664 break;
00665
00666 case E_MSP430_MACH_MSP430x41:
00667 e_set = bfd_mach_msp41;
00668 break;
00669
00670 case E_MSP430_MACH_MSP430x42:
00671 e_set = bfd_mach_msp42;
00672 break;
00673
00674 case E_MSP430_MACH_MSP430x43:
00675 e_set = bfd_mach_msp43;
00676 break;
00677
00678 case E_MSP430_MACH_MSP430x44:
00679 e_set = bfd_mach_msp44;
00680 break;
00681 }
00682 }
00683
00684 return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set);
00685 }
00686
00687 static void
00688 elf32_msp430_post_process_headers (bfd * abfd,
00689 struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
00690 {
00691 Elf_Internal_Ehdr * i_ehdrp;
00692
00693 i_ehdrp = elf_elfheader (abfd);
00694
00695 #ifndef ELFOSABI_STANDALONE
00696 #define ELFOSABI_STANDALONE 255
00697 #endif
00698
00699 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_STANDALONE;
00700 }
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 #define NUMB_RELAX_CODES 12
00763 static struct rcodes_s
00764 {
00765 int f0, f1;
00766 int t0, t1;
00767 int labels;
00768
00769
00770 int cdx;
00771 int bs;
00772 int off;
00773 int ncl;
00774 } rcode[] =
00775 {
00776 { 0x0000, 0x0000, 0x3c00, 0x0000, 1, 0, 2, 2, 2},
00777 { 0x0000, 0x2002, 0x2400, 0x0000, 1, 1, 4, 4, 2},
00778 { 0x0000, 0x2402, 0x2000, 0x0000, 1, 1, 4, 4, 2},
00779 { 0x0000, 0x3402, 0x3800, 0x0000, 1, 1, 4, 4, 2},
00780 { 0x0000, 0x2c02, 0x2800, 0x0000, 1, 1, 4, 4, 2},
00781 { 0x0000, 0x3802, 0x3400, 0x0000, 1, 1, 4, 4, 2},
00782 { 0x0000, 0x2802, 0x2c00, 0x0000, 1, 1, 4, 4, 2},
00783 { 0x3001, 0x3c02, 0x3000, 0x0000, 1, 2, 6, 6, 2},
00784 { 0x2403, 0x3802, 0x2401, 0x3400, 2, 2, 4, 6, 4},
00785 { 0x2403, 0x2802, 0x2401, 0x2c00, 2, 2, 4, 6, 4},
00786 { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4},
00787 { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4},
00788 { 0, 0, 0, 0, 0, 0, 0, 0, 0}
00789 };
00790
00791
00792
00793 static bfd_boolean
00794 msp430_elf_symbol_address_p (bfd * abfd,
00795 asection * sec,
00796 Elf_Internal_Sym * isym,
00797 bfd_vma addr)
00798 {
00799 Elf_Internal_Shdr *symtab_hdr;
00800 unsigned int sec_shndx;
00801 Elf_Internal_Sym *isymend;
00802 struct elf_link_hash_entry **sym_hashes;
00803 struct elf_link_hash_entry **end_hashes;
00804 unsigned int symcount;
00805
00806 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
00807
00808
00809 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00810 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
00811 if (isym->st_shndx == sec_shndx && isym->st_value == addr)
00812 return TRUE;
00813
00814 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
00815 - symtab_hdr->sh_info);
00816 sym_hashes = elf_sym_hashes (abfd);
00817 end_hashes = sym_hashes + symcount;
00818 for (; sym_hashes < end_hashes; sym_hashes++)
00819 {
00820 struct elf_link_hash_entry *sym_hash = *sym_hashes;
00821
00822 if ((sym_hash->root.type == bfd_link_hash_defined
00823 || sym_hash->root.type == bfd_link_hash_defweak)
00824 && sym_hash->root.u.def.section == sec
00825 && sym_hash->root.u.def.value == addr)
00826 return TRUE;
00827 }
00828
00829 return FALSE;
00830 }
00831
00832
00833
00834 static bfd_boolean
00835 msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr,
00836 int count)
00837 {
00838 Elf_Internal_Shdr *symtab_hdr;
00839 unsigned int sec_shndx;
00840 bfd_byte *contents;
00841 Elf_Internal_Rela *irel;
00842 Elf_Internal_Rela *irelend;
00843 Elf_Internal_Rela *irelalign;
00844 bfd_vma toaddr;
00845 Elf_Internal_Sym *isym;
00846 Elf_Internal_Sym *isymend;
00847 struct elf_link_hash_entry **sym_hashes;
00848 struct elf_link_hash_entry **end_hashes;
00849 unsigned int symcount;
00850
00851 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
00852
00853 contents = elf_section_data (sec)->this_hdr.contents;
00854
00855
00856
00857
00858 irelalign = NULL;
00859 toaddr = sec->size;
00860
00861 irel = elf_section_data (sec)->relocs;
00862 irelend = irel + sec->reloc_count;
00863
00864
00865 memmove (contents + addr, contents + addr + count,
00866 (size_t) (toaddr - addr - count));
00867 sec->size -= count;
00868
00869
00870 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
00871
00872 if ((irel->r_offset > addr && irel->r_offset < toaddr))
00873 irel->r_offset -= count;
00874
00875
00876 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
00877 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
00878 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
00879 if (isym->st_shndx == sec_shndx
00880 && isym->st_value > addr && isym->st_value < toaddr)
00881 isym->st_value -= count;
00882
00883
00884 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
00885 - symtab_hdr->sh_info);
00886 sym_hashes = elf_sym_hashes (abfd);
00887 end_hashes = sym_hashes + symcount;
00888 for (; sym_hashes < end_hashes; sym_hashes++)
00889 {
00890 struct elf_link_hash_entry *sym_hash = *sym_hashes;
00891
00892 if ((sym_hash->root.type == bfd_link_hash_defined
00893 || sym_hash->root.type == bfd_link_hash_defweak)
00894 && sym_hash->root.u.def.section == sec
00895 && sym_hash->root.u.def.value > addr
00896 && sym_hash->root.u.def.value < toaddr)
00897 sym_hash->root.u.def.value -= count;
00898 }
00899
00900 return TRUE;
00901 }
00902
00903
00904 static bfd_boolean
00905 msp430_elf_relax_section (bfd * abfd, asection * sec,
00906 struct bfd_link_info * link_info,
00907 bfd_boolean * again)
00908 {
00909 Elf_Internal_Shdr * symtab_hdr;
00910 Elf_Internal_Rela * internal_relocs;
00911 Elf_Internal_Rela * irel;
00912 Elf_Internal_Rela * irelend;
00913 bfd_byte * contents = NULL;
00914 Elf_Internal_Sym * isymbuf = NULL;
00915
00916
00917 *again = FALSE;
00918
00919
00920
00921
00922 if (link_info->relocatable
00923 || (sec->flags & SEC_RELOC) == 0
00924 || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
00925 return TRUE;
00926
00927 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
00928
00929
00930 internal_relocs =
00931 _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
00932 if (internal_relocs == NULL)
00933 goto error_return;
00934
00935
00936 irelend = internal_relocs + sec->reloc_count;
00937 for (irel = internal_relocs; irel < irelend; irel++)
00938 {
00939 bfd_vma symval;
00940
00941
00942
00943 if (ELF32_R_TYPE (irel->r_info) != (int) R_MSP430_RL_PCREL)
00944 continue;
00945
00946
00947 if (contents == NULL)
00948 {
00949
00950 if (elf_section_data (sec)->this_hdr.contents != NULL)
00951 contents = elf_section_data (sec)->this_hdr.contents;
00952 else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
00953 goto error_return;
00954 }
00955
00956
00957 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
00958 {
00959 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
00960 if (isymbuf == NULL)
00961 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
00962 symtab_hdr->sh_info, 0,
00963 NULL, NULL, NULL);
00964 if (isymbuf == NULL)
00965 goto error_return;
00966 }
00967
00968
00969 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
00970 {
00971
00972 Elf_Internal_Sym *isym;
00973 asection *sym_sec;
00974
00975 isym = isymbuf + ELF32_R_SYM (irel->r_info);
00976 if (isym->st_shndx == SHN_UNDEF)
00977 sym_sec = bfd_und_section_ptr;
00978 else if (isym->st_shndx == SHN_ABS)
00979 sym_sec = bfd_abs_section_ptr;
00980 else if (isym->st_shndx == SHN_COMMON)
00981 sym_sec = bfd_com_section_ptr;
00982 else
00983 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
00984 symval = (isym->st_value
00985 + sym_sec->output_section->vma + sym_sec->output_offset);
00986 }
00987 else
00988 {
00989 unsigned long indx;
00990 struct elf_link_hash_entry *h;
00991
00992
00993 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
00994 h = elf_sym_hashes (abfd)[indx];
00995 BFD_ASSERT (h != NULL);
00996
00997 if (h->root.type != bfd_link_hash_defined
00998 && h->root.type != bfd_link_hash_defweak)
00999
01000
01001
01002 continue;
01003
01004 symval = (h->root.u.def.value
01005 + h->root.u.def.section->output_section->vma
01006 + h->root.u.def.section->output_offset);
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 if (ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL)
01021 {
01022 bfd_vma value = symval;
01023
01024
01025 value -= (sec->output_section->vma + sec->output_offset);
01026 value -= irel->r_offset;
01027 value += irel->r_addend;
01028
01029
01030
01031
01032 if ((long) value < 1016 && (long) value > -1016)
01033 {
01034 int code0 = 0, code1 = 0, code2 = 0;
01035 int i;
01036 struct rcodes_s *rx;
01037
01038
01039 if (irel->r_offset >= 6)
01040 code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6);
01041
01042 if (irel->r_offset >= 4)
01043 code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4);
01044
01045 code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
01046
01047 if (code2 != 0x4010)
01048 continue;
01049
01050
01051 for (i = NUMB_RELAX_CODES - 1; i >= 0; i--)
01052 {
01053 rx = &rcode[i];
01054 if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1)
01055 break;
01056 else if (rx->cdx == 1 && rx->f1 == code1)
01057 break;
01058 else if (rx->cdx == 0)
01059 break;
01060 }
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 if (rx->cdx > 0
01076 && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
01077 irel->r_offset - 2))
01078 continue;
01079 if (rx->cdx > 1
01080 && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
01081 irel->r_offset - 4))
01082 continue;
01083
01084
01085 elf_section_data (sec)->relocs = internal_relocs;
01086 elf_section_data (sec)->this_hdr.contents = contents;
01087 symtab_hdr->contents = (unsigned char *) isymbuf;
01088
01089
01090 if (rx->labels == 3)
01091 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01092 R_MSP430_2X_PCREL);
01093 else
01094 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01095 R_MSP430_10_PCREL);
01096
01097
01098 bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off);
01099 if (rx->t1)
01100 bfd_put_16 (abfd, rx->t1,
01101 contents + irel->r_offset - rx->off + 2);
01102
01103
01104 if (!msp430_elf_relax_delete_bytes (abfd, sec,
01105 irel->r_offset - rx->off +
01106 rx->ncl, rx->bs))
01107 goto error_return;
01108
01109
01110 if (rx->cdx == 0)
01111 irel->r_offset -= 2;
01112
01113
01114
01115 *again = TRUE;
01116 }
01117 }
01118 }
01119
01120 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
01121 {
01122 if (!link_info->keep_memory)
01123 free (isymbuf);
01124 else
01125 {
01126
01127 symtab_hdr->contents = (unsigned char *) isymbuf;
01128 }
01129 }
01130
01131 if (contents != NULL
01132 && elf_section_data (sec)->this_hdr.contents != contents)
01133 {
01134 if (!link_info->keep_memory)
01135 free (contents);
01136 else
01137 {
01138
01139 elf_section_data (sec)->this_hdr.contents = contents;
01140 }
01141 }
01142
01143 if (internal_relocs != NULL
01144 && elf_section_data (sec)->relocs != internal_relocs)
01145 free (internal_relocs);
01146
01147 return TRUE;
01148
01149 error_return:
01150 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
01151 free (isymbuf);
01152 if (contents != NULL
01153 && elf_section_data (sec)->this_hdr.contents != contents)
01154 free (contents);
01155 if (internal_relocs != NULL
01156 && elf_section_data (sec)->relocs != internal_relocs)
01157 free (internal_relocs);
01158
01159 return FALSE;
01160 }
01161
01162
01163 #define ELF_ARCH bfd_arch_msp430
01164 #define ELF_MACHINE_CODE EM_MSP430
01165 #define ELF_MACHINE_ALT1 EM_MSP430_OLD
01166 #define ELF_MAXPAGESIZE 1
01167
01168 #define TARGET_LITTLE_SYM bfd_elf32_msp430_vec
01169 #define TARGET_LITTLE_NAME "elf32-msp430"
01170
01171 #define elf_info_to_howto msp430_info_to_howto_rela
01172 #define elf_info_to_howto_rel NULL
01173 #define elf_backend_relocate_section elf32_msp430_relocate_section
01174 #define elf_backend_gc_mark_hook elf32_msp430_gc_mark_hook
01175 #define elf_backend_gc_sweep_hook elf32_msp430_gc_sweep_hook
01176 #define elf_backend_check_relocs elf32_msp430_check_relocs
01177 #define elf_backend_can_gc_sections 1
01178 #define elf_backend_final_write_processing bfd_elf_msp430_final_write_processing
01179 #define elf_backend_object_p elf32_msp430_object_p
01180 #define elf_backend_post_process_headers elf32_msp430_post_process_headers
01181 #define bfd_elf32_bfd_relax_section msp430_elf_relax_section
01182
01183 #include "elf32-target.h"