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
00028
00029
00030
00031
00032
00033
00034 #include "bfd.h"
00035 #include "sysdep.h"
00036 #include "bfdlink.h"
00037 #include "libbfd.h"
00038 #include "elf-bfd.h"
00039 #include "elf/i370.h"
00040
00041 static reloc_howto_type *i370_elf_howto_table[ (int)R_I370_max ];
00042
00043 static reloc_howto_type i370_elf_howto_raw[] =
00044 {
00045
00046 HOWTO (R_I370_NONE,
00047 0,
00048 2,
00049 32,
00050 FALSE,
00051 0,
00052 complain_overflow_bitfield,
00053 bfd_elf_generic_reloc,
00054 "R_I370_NONE",
00055 FALSE,
00056 0,
00057 0,
00058 FALSE),
00059
00060
00061 HOWTO (R_I370_ADDR31,
00062 0,
00063 2,
00064 31,
00065 FALSE,
00066 0,
00067 complain_overflow_bitfield,
00068 bfd_elf_generic_reloc,
00069 "R_I370_ADDR31",
00070 FALSE,
00071 0,
00072 0x7fffffff,
00073 FALSE),
00074
00075
00076 HOWTO (R_I370_ADDR32,
00077 0,
00078 2,
00079 32,
00080 FALSE,
00081 0,
00082 complain_overflow_bitfield,
00083 bfd_elf_generic_reloc,
00084 "R_I370_ADDR32",
00085 FALSE,
00086 0,
00087 0xffffffff,
00088 FALSE),
00089
00090
00091 HOWTO (R_I370_ADDR16,
00092 0,
00093 1,
00094 16,
00095 FALSE,
00096 0,
00097 complain_overflow_bitfield,
00098 bfd_elf_generic_reloc,
00099 "R_I370_ADDR16",
00100 FALSE,
00101 0,
00102 0xffff,
00103 FALSE),
00104
00105
00106 HOWTO (R_I370_REL31,
00107 0,
00108 2,
00109 31,
00110 TRUE,
00111 0,
00112 complain_overflow_bitfield,
00113 bfd_elf_generic_reloc,
00114 "R_I370_REL31",
00115 FALSE,
00116 0,
00117 0x7fffffff,
00118 TRUE),
00119
00120
00121 HOWTO (R_I370_REL32,
00122 0,
00123 2,
00124 32,
00125 TRUE,
00126 0,
00127 complain_overflow_bitfield,
00128 bfd_elf_generic_reloc,
00129 "R_I370_REL32",
00130 FALSE,
00131 0,
00132 0xffffffff,
00133 TRUE),
00134
00135
00136 HOWTO (R_I370_ADDR12,
00137 0,
00138 1,
00139 12,
00140 FALSE,
00141 0,
00142 complain_overflow_bitfield,
00143 bfd_elf_generic_reloc,
00144 "R_I370_ADDR12",
00145 FALSE,
00146 0,
00147 0xfff,
00148 FALSE),
00149
00150
00151 HOWTO (R_I370_REL12,
00152 0,
00153 1,
00154 12,
00155 TRUE,
00156 0,
00157 complain_overflow_bitfield,
00158 bfd_elf_generic_reloc,
00159 "R_I370_REL12",
00160 FALSE,
00161 0,
00162 0xfff,
00163 TRUE),
00164
00165
00166 HOWTO (R_I370_ADDR8,
00167 0,
00168 0,
00169 8,
00170 FALSE,
00171 0,
00172 complain_overflow_bitfield,
00173 bfd_elf_generic_reloc,
00174 "R_I370_ADDR8",
00175 FALSE,
00176 0,
00177 0xff,
00178 FALSE),
00179
00180
00181 HOWTO (R_I370_REL8,
00182 0,
00183 0,
00184 8,
00185 TRUE,
00186 0,
00187 complain_overflow_bitfield,
00188 bfd_elf_generic_reloc,
00189 "R_I370_REL8",
00190 FALSE,
00191 0,
00192 0xff,
00193 TRUE),
00194
00195
00196
00197
00198
00199
00200 HOWTO (R_I370_COPY,
00201 0,
00202 2,
00203 32,
00204 FALSE,
00205 0,
00206 complain_overflow_bitfield,
00207 bfd_elf_generic_reloc,
00208 "R_I370_COPY",
00209 FALSE,
00210 0,
00211 0,
00212 FALSE),
00213
00214
00215
00216
00217 HOWTO (R_I370_RELATIVE,
00218 0,
00219 2,
00220 32,
00221 FALSE,
00222 0,
00223 complain_overflow_bitfield,
00224 bfd_elf_generic_reloc,
00225 "R_I370_RELATIVE",
00226 FALSE,
00227 0,
00228 0xffffffff,
00229 FALSE),
00230
00231 };
00232
00233 static void i370_elf_howto_init
00234 PARAMS ((void));
00235 static reloc_howto_type *i370_elf_reloc_type_lookup
00236 PARAMS ((bfd *, bfd_reloc_code_real_type));
00237 static void i370_elf_info_to_howto
00238 PARAMS ((bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst));
00239 static bfd_boolean i370_elf_set_private_flags
00240 PARAMS ((bfd *, flagword));
00241
00242
00243
00244 static void
00245 i370_elf_howto_init ()
00246 {
00247 unsigned int i, type;
00248
00249 for (i = 0; i < sizeof (i370_elf_howto_raw) / sizeof (i370_elf_howto_raw[0]); i++)
00250 {
00251 type = i370_elf_howto_raw[i].type;
00252 BFD_ASSERT (type < sizeof (i370_elf_howto_table) / sizeof (i370_elf_howto_table[0]));
00253 i370_elf_howto_table[type] = &i370_elf_howto_raw[i];
00254 }
00255 }
00256
00257 static reloc_howto_type *
00258 i370_elf_reloc_type_lookup (abfd, code)
00259 bfd *abfd ATTRIBUTE_UNUSED;
00260 bfd_reloc_code_real_type code;
00261 {
00262 enum i370_reloc_type i370_reloc = R_I370_NONE;
00263
00264 if (!i370_elf_howto_table[ R_I370_ADDR31 ])
00265 i370_elf_howto_init ();
00266
00267 switch ((int)code)
00268 {
00269 default:
00270 return (reloc_howto_type *)NULL;
00271
00272 case BFD_RELOC_NONE: i370_reloc = R_I370_NONE; break;
00273 case BFD_RELOC_32: i370_reloc = R_I370_ADDR31; break;
00274 case BFD_RELOC_16: i370_reloc = R_I370_ADDR16; break;
00275 case BFD_RELOC_32_PCREL: i370_reloc = R_I370_REL31; break;
00276 case BFD_RELOC_CTOR: i370_reloc = R_I370_ADDR31; break;
00277 case BFD_RELOC_I370_D12: i370_reloc = R_I370_ADDR12; break;
00278 }
00279
00280 return i370_elf_howto_table[ (int)i370_reloc ];
00281 };
00282
00283 static bfd_boolean i370_elf_merge_private_bfd_data
00284 PARAMS ((bfd *, bfd *));
00285 static bfd_boolean i370_elf_relocate_section
00286 PARAMS ((bfd *, struct bfd_link_info *info, bfd *, asection *, bfd_byte *,
00287 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
00288 asection **));
00289 static void i370_elf_post_process_headers
00290 PARAMS ((bfd *, struct bfd_link_info *));
00291 static bfd_boolean i370_elf_create_dynamic_sections
00292 PARAMS ((bfd *, struct bfd_link_info *));
00293 static bfd_boolean i370_elf_section_from_shdr
00294 PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
00295 static bfd_boolean i370_elf_fake_sections
00296 PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
00297 static bfd_boolean i370_elf_check_relocs
00298 PARAMS ((bfd *, struct bfd_link_info *, asection *,
00299 const Elf_Internal_Rela *));
00300 static bfd_boolean i370_elf_adjust_dynamic_symbol
00301 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
00302 static bfd_boolean i370_elf_adjust_dynindx
00303 PARAMS ((struct elf_link_hash_entry *, PTR));
00304 static bfd_boolean i370_elf_size_dynamic_sections
00305 PARAMS ((bfd *, struct bfd_link_info *));
00306 static bfd_boolean i370_elf_finish_dynamic_sections
00307 PARAMS ((bfd *, struct bfd_link_info *));
00308
00309
00310
00311
00312 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so"
00313
00314
00315
00316 static void
00317 i370_elf_info_to_howto (abfd, cache_ptr, dst)
00318 bfd *abfd ATTRIBUTE_UNUSED;
00319 arelent *cache_ptr;
00320 Elf_Internal_Rela *dst;
00321 {
00322 if (!i370_elf_howto_table[ R_I370_ADDR31 ])
00323 i370_elf_howto_init ();
00324
00325 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_I370_max);
00326 cache_ptr->howto = i370_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
00327 }
00328
00329
00330
00331
00332
00333 static bfd_boolean
00334 i370_elf_set_private_flags (abfd, flags)
00335 bfd *abfd;
00336 flagword flags;
00337 {
00338 BFD_ASSERT (!elf_flags_init (abfd)
00339 || elf_elfheader (abfd)->e_flags == flags);
00340
00341 elf_elfheader (abfd)->e_flags = flags;
00342 elf_flags_init (abfd) = TRUE;
00343 return TRUE;
00344 }
00345
00346
00347
00348 static bfd_boolean
00349 i370_elf_merge_private_bfd_data (ibfd, obfd)
00350 bfd *ibfd;
00351 bfd *obfd;
00352 {
00353 flagword old_flags;
00354 flagword new_flags;
00355
00356 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
00357 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
00358 return TRUE;
00359
00360 new_flags = elf_elfheader (ibfd)->e_flags;
00361 old_flags = elf_elfheader (obfd)->e_flags;
00362 if (!elf_flags_init (obfd))
00363 {
00364 elf_flags_init (obfd) = TRUE;
00365 elf_elfheader (obfd)->e_flags = new_flags;
00366 }
00367
00368 else if (new_flags == old_flags)
00369 ;
00370
00371 else
00372 {
00373 (*_bfd_error_handler)
00374 ("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)",
00375 ibfd, (long) new_flags, (long) old_flags);
00376
00377 bfd_set_error (bfd_error_bad_value);
00378 return FALSE;
00379 }
00380
00381 return TRUE;
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391 static bfd_boolean
00392 i370_elf_section_from_shdr (abfd, hdr, name)
00393 bfd *abfd;
00394 Elf_Internal_Shdr *hdr;
00395 const char *name;
00396 {
00397 asection *newsect;
00398 flagword flags;
00399
00400 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
00401 return FALSE;
00402
00403 newsect = hdr->bfd_section;
00404 flags = bfd_get_section_flags (abfd, newsect);
00405 if (hdr->sh_flags & SHF_EXCLUDE)
00406 flags |= SEC_EXCLUDE;
00407
00408 if (hdr->sh_type == SHT_ORDERED)
00409 flags |= SEC_SORT_ENTRIES;
00410
00411 bfd_set_section_flags (abfd, newsect, flags);
00412 return TRUE;
00413 }
00414
00415
00416
00417
00418
00419
00420
00421 static bfd_boolean
00422 i370_elf_fake_sections (abfd, shdr, asect)
00423 bfd *abfd ATTRIBUTE_UNUSED;
00424 Elf_Internal_Shdr *shdr;
00425 asection *asect;
00426 {
00427 if ((asect->flags & SEC_EXCLUDE) != 0)
00428 shdr->sh_flags |= SHF_EXCLUDE;
00429
00430 if ((asect->flags & SEC_SORT_ENTRIES) != 0)
00431 shdr->sh_type = SHT_ORDERED;
00432
00433 return TRUE;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 static bfd_boolean
00445 i370_elf_create_dynamic_sections (abfd, info)
00446 bfd *abfd;
00447 struct bfd_link_info *info;
00448 {
00449 register asection *s;
00450 flagword flags;
00451
00452 if (!_bfd_elf_create_dynamic_sections(abfd, info))
00453 return FALSE;
00454
00455 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
00456 | SEC_LINKER_CREATED);
00457
00458 s = bfd_make_section (abfd, ".dynsbss");
00459 if (s == NULL
00460 || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
00461 return FALSE;
00462
00463 if (! info->shared)
00464 {
00465 s = bfd_make_section (abfd, ".rela.sbss");
00466 if (s == NULL
00467 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
00468 || ! bfd_set_section_alignment (abfd, s, 2))
00469 return FALSE;
00470 }
00471
00472
00473 s = bfd_make_section (abfd, ".rela.text");
00474 if (s == NULL
00475 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
00476 || ! bfd_set_section_alignment (abfd, s, 2))
00477 return FALSE;
00478 return TRUE;
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 static bfd_boolean
00492 i370_elf_adjust_dynamic_symbol (info, h)
00493 struct bfd_link_info *info;
00494 struct elf_link_hash_entry *h;
00495 {
00496 bfd *dynobj = elf_hash_table (info)->dynobj;
00497 asection *s;
00498 unsigned int power_of_two;
00499
00500 #ifdef DEBUG
00501 fprintf (stderr, "i370_elf_adjust_dynamic_symbol called for %s\n",
00502 h->root.root.string);
00503 #endif
00504
00505
00506 BFD_ASSERT (dynobj != NULL
00507 && (h->needs_plt
00508 || h->u.weakdef != NULL
00509 || (h->def_dynamic
00510 && h->ref_regular
00511 && !h->def_regular)));
00512
00513 s = bfd_get_section_by_name (dynobj, ".rela.text");
00514 BFD_ASSERT (s != NULL);
00515 s->size += sizeof (Elf32_External_Rela);
00516
00517
00518
00519
00520 if (h->u.weakdef != NULL)
00521 {
00522 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
00523 || h->u.weakdef->root.type == bfd_link_hash_defweak);
00524 h->root.u.def.section = h->u.weakdef->root.u.def.section;
00525 h->root.u.def.value = h->u.weakdef->root.u.def.value;
00526 return TRUE;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536 if (info->shared)
00537 return TRUE;
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 if (h->size <= elf_gp_size (dynobj))
00554 s = bfd_get_section_by_name (dynobj, ".dynsbss");
00555 else
00556 s = bfd_get_section_by_name (dynobj, ".dynbss");
00557 BFD_ASSERT (s != NULL);
00558
00559
00560
00561
00562
00563 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
00564 {
00565 asection *srel;
00566
00567 if (h->size <= elf_gp_size (dynobj))
00568 srel = bfd_get_section_by_name (dynobj, ".rela.sbss");
00569 else
00570 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
00571 BFD_ASSERT (srel != NULL);
00572 srel->size += sizeof (Elf32_External_Rela);
00573 h->needs_copy = 1;
00574 }
00575
00576
00577
00578 power_of_two = bfd_log2 (h->size);
00579 if (power_of_two > 4)
00580 power_of_two = 4;
00581
00582
00583 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
00584 if (power_of_two > bfd_get_section_alignment (dynobj, s))
00585 {
00586 if (! bfd_set_section_alignment (dynobj, s, power_of_two))
00587 return FALSE;
00588 }
00589
00590
00591 h->root.u.def.section = s;
00592 h->root.u.def.value = s->size;
00593
00594
00595 s->size += h->size;
00596
00597 return TRUE;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607 static bfd_boolean
00608 i370_elf_adjust_dynindx (h, cparg)
00609 struct elf_link_hash_entry *h;
00610 PTR cparg;
00611 {
00612 int *cp = (int *) cparg;
00613
00614 #ifdef DEBUG
00615 fprintf (stderr,
00616 "i370_elf_adjust_dynindx called, h->dynindx = %d, *cp = %d\n",
00617 h->dynindx, *cp);
00618 #endif
00619
00620 if (h->root.type == bfd_link_hash_warning)
00621 h = (struct elf_link_hash_entry *) h->root.u.i.link;
00622
00623 if (h->dynindx != -1)
00624 h->dynindx += *cp;
00625
00626 return TRUE;
00627 }
00628
00629
00630
00631
00632
00633
00634
00635 static bfd_boolean
00636 i370_elf_size_dynamic_sections (output_bfd, info)
00637 bfd *output_bfd;
00638 struct bfd_link_info *info;
00639 {
00640 bfd *dynobj;
00641 asection *s;
00642 bfd_boolean plt;
00643 bfd_boolean relocs;
00644 bfd_boolean reltext;
00645
00646 #ifdef DEBUG
00647 fprintf (stderr, "i370_elf_size_dynamic_sections called\n");
00648 #endif
00649
00650 dynobj = elf_hash_table (info)->dynobj;
00651 BFD_ASSERT (dynobj != NULL);
00652
00653 if (elf_hash_table (info)->dynamic_sections_created)
00654 {
00655
00656 if (info->executable)
00657 {
00658 s = bfd_get_section_by_name (dynobj, ".interp");
00659 BFD_ASSERT (s != NULL);
00660 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
00661 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
00662 }
00663 }
00664 else
00665 {
00666
00667
00668
00669
00670
00671 static char *rela_sections[] = { ".rela.got", ".rela.sdata",
00672 ".rela.sdata2", ".rela.sbss",
00673 (char *)0 };
00674 char **p;
00675
00676 for (p = rela_sections; *p != (char *)0; p++)
00677 {
00678 s = bfd_get_section_by_name (dynobj, *p);
00679 if (s != NULL)
00680 s->size = 0;
00681 }
00682 }
00683
00684
00685
00686
00687 plt = FALSE;
00688 relocs = FALSE;
00689 reltext = FALSE;
00690 for (s = dynobj->sections; s != NULL; s = s->next)
00691 {
00692 const char *name;
00693 bfd_boolean strip;
00694
00695 if ((s->flags & SEC_LINKER_CREATED) == 0)
00696 continue;
00697
00698
00699
00700 name = bfd_get_section_name (dynobj, s);
00701 strip = FALSE;
00702
00703 if (strcmp (name, ".plt") == 0)
00704 {
00705 if (s->size == 0)
00706 {
00707
00708
00709 strip = TRUE;
00710 }
00711 else
00712 {
00713
00714 plt = TRUE;
00715 }
00716 }
00717 else if (strncmp (name, ".rela", 5) == 0)
00718 {
00719 if (s->size == 0)
00720 {
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 strip = TRUE;
00731 }
00732 else
00733 {
00734 asection *target;
00735 const char *outname;
00736
00737
00738 relocs = TRUE;
00739
00740
00741
00742 outname = bfd_get_section_name (output_bfd,
00743 s->output_section);
00744 target = bfd_get_section_by_name (output_bfd, outname + 5);
00745 if (target != NULL
00746 && (target->flags & SEC_READONLY) != 0
00747 && (target->flags & SEC_ALLOC) != 0)
00748 reltext = TRUE;
00749
00750
00751
00752 s->reloc_count = 0;
00753 }
00754 }
00755 else if (strcmp (name, ".got") != 0
00756 && strcmp (name, ".sdata") != 0
00757 && strcmp (name, ".sdata2") != 0)
00758 {
00759
00760 continue;
00761 }
00762
00763 if (strip)
00764 {
00765 asection **spp;
00766
00767 for (spp = &s->output_section->owner->sections;
00768 *spp != NULL;
00769 spp = &(*spp)->next)
00770 {
00771 if (*spp == s->output_section)
00772 {
00773 bfd_section_list_remove (s->output_section->owner, spp);
00774 --s->output_section->owner->section_count;
00775 break;
00776 }
00777 }
00778 continue;
00779 }
00780
00781 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
00782 if (s->contents == NULL && s->size != 0)
00783 return FALSE;
00784 }
00785
00786 if (elf_hash_table (info)->dynamic_sections_created)
00787 {
00788
00789
00790
00791
00792
00793 #define add_dynamic_entry(TAG, VAL) \
00794 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
00795
00796 if (!info->shared)
00797 {
00798 if (!add_dynamic_entry (DT_DEBUG, 0))
00799 return FALSE;
00800 }
00801
00802 if (plt)
00803 {
00804 if (!add_dynamic_entry (DT_PLTGOT, 0)
00805 || !add_dynamic_entry (DT_PLTRELSZ, 0)
00806 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
00807 || !add_dynamic_entry (DT_JMPREL, 0))
00808 return FALSE;
00809 }
00810
00811 if (relocs)
00812 {
00813 if (!add_dynamic_entry (DT_RELA, 0)
00814 || !add_dynamic_entry (DT_RELASZ, 0)
00815 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
00816 return FALSE;
00817 }
00818
00819 if (reltext)
00820 {
00821 if (!add_dynamic_entry (DT_TEXTREL, 0))
00822 return FALSE;
00823 info->flags |= DF_TEXTREL;
00824 }
00825 }
00826 #undef add_dynamic_entry
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 if (info->shared)
00839 {
00840 int c;
00841
00842 for (c = 0, s = output_bfd->sections; s != NULL; s = s->next)
00843 {
00844 if ((s->flags & SEC_LINKER_CREATED) != 0
00845 || (s->flags & SEC_ALLOC) == 0)
00846 {
00847 elf_section_data (s)->dynindx = -1;
00848 continue;
00849 }
00850
00851
00852
00853
00854 elf_section_data (s)->dynindx = c + 1;
00855
00856 c++;
00857 }
00858
00859 elf_link_hash_traverse (elf_hash_table (info),
00860 i370_elf_adjust_dynindx,
00861 (PTR) &c);
00862 elf_hash_table (info)->dynsymcount += c;
00863 }
00864
00865 return TRUE;
00866 }
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876 static bfd_boolean
00877 i370_elf_check_relocs (abfd, info, sec, relocs)
00878 bfd *abfd;
00879 struct bfd_link_info *info;
00880 asection *sec;
00881 const Elf_Internal_Rela *relocs;
00882 {
00883 bfd *dynobj;
00884 Elf_Internal_Shdr *symtab_hdr;
00885 struct elf_link_hash_entry **sym_hashes;
00886 const Elf_Internal_Rela *rel;
00887 const Elf_Internal_Rela *rel_end;
00888 bfd_vma *local_got_offsets;
00889 asection *sreloc;
00890
00891 if (info->relocatable)
00892 return TRUE;
00893
00894 #ifdef DEBUG
00895 _bfd_error_handler ("i370_elf_check_relocs called for section %A in %B",
00896 sec, abfd);
00897 #endif
00898
00899 dynobj = elf_hash_table (info)->dynobj;
00900 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00901 sym_hashes = elf_sym_hashes (abfd);
00902 local_got_offsets = elf_local_got_offsets (abfd);
00903
00904 sreloc = NULL;
00905
00906 rel_end = relocs + sec->reloc_count;
00907 for (rel = relocs; rel < rel_end; rel++)
00908 {
00909 unsigned long r_symndx;
00910 struct elf_link_hash_entry *h;
00911
00912 r_symndx = ELF32_R_SYM (rel->r_info);
00913 if (r_symndx < symtab_hdr->sh_info)
00914 h = NULL;
00915 else
00916 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
00917
00918 if (info->shared)
00919 {
00920 #ifdef DEBUG
00921 fprintf (stderr,
00922 "i370_elf_check_relocs needs to create relocation for %s\n",
00923 (h && h->root.root.string)
00924 ? h->root.root.string : "<unknown>");
00925 #endif
00926 if (sreloc == NULL)
00927 {
00928 const char *name;
00929
00930 name = (bfd_elf_string_from_elf_section
00931 (abfd,
00932 elf_elfheader (abfd)->e_shstrndx,
00933 elf_section_data (sec)->rel_hdr.sh_name));
00934 if (name == NULL)
00935 return FALSE;
00936
00937 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
00938 && strcmp (bfd_get_section_name (abfd, sec), name + 5) == 0);
00939
00940 sreloc = bfd_get_section_by_name (dynobj, name);
00941 if (sreloc == NULL)
00942 {
00943 flagword flags;
00944
00945 sreloc = bfd_make_section (dynobj, name);
00946 flags = (SEC_HAS_CONTENTS | SEC_READONLY
00947 | SEC_IN_MEMORY | SEC_LINKER_CREATED);
00948 if ((sec->flags & SEC_ALLOC) != 0)
00949 flags |= SEC_ALLOC | SEC_LOAD;
00950 if (sreloc == NULL
00951 || ! bfd_set_section_flags (dynobj, sreloc, flags)
00952 || ! bfd_set_section_alignment (dynobj, sreloc, 2))
00953 return FALSE;
00954 }
00955 }
00956
00957 sreloc->size += sizeof (Elf32_External_Rela);
00958
00959
00960
00961
00962
00963
00964
00965 }
00966 }
00967
00968 return TRUE;
00969 }
00970
00971
00972
00973
00974
00975
00976
00977 static bfd_boolean
00978 i370_elf_finish_dynamic_sections (output_bfd, info)
00979 bfd *output_bfd;
00980 struct bfd_link_info *info;
00981 {
00982 asection *sdyn;
00983 bfd *dynobj = elf_hash_table (info)->dynobj;
00984 asection *sgot = bfd_get_section_by_name (dynobj, ".got");
00985
00986 #ifdef DEBUG
00987 fprintf (stderr, "i370_elf_finish_dynamic_sections called\n");
00988 #endif
00989
00990 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
00991
00992 if (elf_hash_table (info)->dynamic_sections_created)
00993 {
00994 asection *splt;
00995 Elf32_External_Dyn *dyncon, *dynconend;
00996
00997 splt = bfd_get_section_by_name (dynobj, ".plt");
00998 BFD_ASSERT (splt != NULL && sdyn != NULL);
00999
01000 dyncon = (Elf32_External_Dyn *) sdyn->contents;
01001 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
01002 for (; dyncon < dynconend; dyncon++)
01003 {
01004 Elf_Internal_Dyn dyn;
01005 const char *name;
01006 bfd_boolean size;
01007
01008 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
01009
01010 switch (dyn.d_tag)
01011 {
01012 case DT_PLTGOT: name = ".plt"; size = FALSE; break;
01013 case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
01014 case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
01015 default: name = NULL; size = FALSE; break;
01016 }
01017
01018 if (name != NULL)
01019 {
01020 asection *s;
01021
01022 s = bfd_get_section_by_name (output_bfd, name);
01023 if (s == NULL)
01024 dyn.d_un.d_val = 0;
01025 else
01026 {
01027 if (! size)
01028 dyn.d_un.d_ptr = s->vma;
01029 else
01030 dyn.d_un.d_val = s->size;
01031 }
01032 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
01033 }
01034 }
01035 }
01036
01037
01038
01039
01040 if (sgot)
01041 {
01042 unsigned char *contents = sgot->contents;
01043 bfd_put_32 (output_bfd, (bfd_vma) 0x4e800021 , contents);
01044
01045 if (sdyn == NULL)
01046 bfd_put_32 (output_bfd, (bfd_vma) 0, contents+4);
01047 else
01048 bfd_put_32 (output_bfd,
01049 sdyn->output_section->vma + sdyn->output_offset,
01050 contents+4);
01051
01052 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
01053 }
01054
01055 if (info->shared)
01056 {
01057 asection *sdynsym;
01058 asection *s;
01059 Elf_Internal_Sym sym;
01060 int maxdindx = 0;
01061
01062
01063
01064 sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
01065 BFD_ASSERT (sdynsym != NULL);
01066
01067 sym.st_size = 0;
01068 sym.st_name = 0;
01069 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
01070 sym.st_other = 0;
01071
01072 for (s = output_bfd->sections; s != NULL; s = s->next)
01073 {
01074 int indx, dindx;
01075 Elf32_External_Sym *esym;
01076
01077 sym.st_value = s->vma;
01078
01079 indx = elf_section_data (s)->this_idx;
01080 dindx = elf_section_data (s)->dynindx;
01081 if (dindx != -1)
01082 {
01083 BFD_ASSERT(indx > 0);
01084 BFD_ASSERT(dindx > 0);
01085
01086 if (dindx > maxdindx)
01087 maxdindx = dindx;
01088
01089 sym.st_shndx = indx;
01090
01091 esym = (Elf32_External_Sym *) sdynsym->contents + dindx;
01092 bfd_elf32_swap_symbol_out (output_bfd, &sym, (PTR) esym, (PTR) 0);
01093 }
01094 }
01095
01096
01097
01098 elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
01099 maxdindx + 1;
01100 }
01101
01102 return TRUE;
01103 }
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134 static bfd_boolean
01135 i370_elf_relocate_section (output_bfd, info, input_bfd, input_section,
01136 contents, relocs, local_syms, local_sections)
01137 bfd *output_bfd;
01138 struct bfd_link_info *info;
01139 bfd *input_bfd;
01140 asection *input_section;
01141 bfd_byte *contents;
01142 Elf_Internal_Rela *relocs;
01143 Elf_Internal_Sym *local_syms;
01144 asection **local_sections;
01145 {
01146 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
01147 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
01148 bfd *dynobj = elf_hash_table (info)->dynobj;
01149 Elf_Internal_Rela *rel = relocs;
01150 Elf_Internal_Rela *relend = relocs + input_section->reloc_count;
01151 asection *sreloc = NULL;
01152 bfd_vma *local_got_offsets;
01153 bfd_boolean ret = TRUE;
01154
01155 if (info->relocatable)
01156 return TRUE;
01157
01158 #ifdef DEBUG
01159 _bfd_error_handler ("i370_elf_relocate_section called for %B section %A, %ld relocations%s",
01160 input_bfd, input_section,
01161 (long) input_section->reloc_count,
01162 (info->relocatable) ? " (relocatable)" : "");
01163 #endif
01164
01165 if (!i370_elf_howto_table[ R_I370_ADDR31 ])
01166 i370_elf_howto_init ();
01167
01168 local_got_offsets = elf_local_got_offsets (input_bfd);
01169
01170 for (; rel < relend; rel++)
01171 {
01172 enum i370_reloc_type r_type = (enum i370_reloc_type)ELF32_R_TYPE (rel->r_info);
01173 bfd_vma offset = rel->r_offset;
01174 bfd_vma addend = rel->r_addend;
01175 bfd_reloc_status_type r = bfd_reloc_other;
01176 Elf_Internal_Sym *sym = (Elf_Internal_Sym *)0;
01177 asection *sec = (asection *)0;
01178 struct elf_link_hash_entry *h = (struct elf_link_hash_entry *)0;
01179 const char *sym_name = (const char *)0;
01180 reloc_howto_type *howto;
01181 unsigned long r_symndx;
01182 bfd_vma relocation;
01183
01184
01185 if ((unsigned)r_type >= (unsigned)R_I370_max
01186 || !i370_elf_howto_table[(int)r_type])
01187 {
01188 (*_bfd_error_handler) ("%B: unknown relocation type %d",
01189 input_bfd,
01190 (int) r_type);
01191
01192 bfd_set_error (bfd_error_bad_value);
01193 ret = FALSE;
01194 continue;
01195 }
01196
01197 howto = i370_elf_howto_table[(int)r_type];
01198 r_symndx = ELF32_R_SYM (rel->r_info);
01199
01200 if (r_symndx < symtab_hdr->sh_info)
01201 {
01202 sym = local_syms + r_symndx;
01203 sec = local_sections[r_symndx];
01204 sym_name = "<local symbol>";
01205
01206 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
01207 addend = rel->r_addend;
01208 }
01209 else
01210 {
01211 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
01212 while (h->root.type == bfd_link_hash_indirect
01213 || h->root.type == bfd_link_hash_warning)
01214 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01215 sym_name = h->root.root.string;
01216 if (h->root.type == bfd_link_hash_defined
01217 || h->root.type == bfd_link_hash_defweak)
01218 {
01219 sec = h->root.u.def.section;
01220 if (info->shared
01221 && ((! info->symbolic && h->dynindx != -1)
01222 || !h->def_regular)
01223 && (input_section->flags & SEC_ALLOC) != 0
01224 && (r_type == R_I370_ADDR31
01225 || r_type == R_I370_COPY
01226 || r_type == R_I370_ADDR16
01227 || r_type == R_I370_RELATIVE))
01228 {
01229
01230
01231
01232 relocation = 0;
01233 }
01234 else
01235 relocation = (h->root.u.def.value
01236 + sec->output_section->vma
01237 + sec->output_offset);
01238 }
01239 else if (h->root.type == bfd_link_hash_undefweak)
01240 relocation = 0;
01241 else if (info->unresolved_syms_in_objects == RM_IGNORE
01242 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
01243 relocation = 0;
01244 else
01245 {
01246 if ((*info->callbacks->undefined_symbol)
01247 (info, h->root.root.string, input_bfd,
01248 input_section, rel->r_offset,
01249 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
01250 || ELF_ST_VISIBILITY (h->other))))
01251 {
01252 ret = FALSE;
01253 continue;
01254 }
01255 relocation = 0;
01256 }
01257 }
01258
01259 switch ((int) r_type)
01260 {
01261 default:
01262 (*_bfd_error_handler)
01263 ("%B: unknown relocation type %d for symbol %s",
01264 input_bfd, (int) r_type, sym_name);
01265
01266 bfd_set_error (bfd_error_bad_value);
01267 ret = FALSE;
01268 continue;
01269
01270 case (int)R_I370_NONE:
01271 continue;
01272
01273
01274
01275 case (int)R_I370_REL31:
01276
01277
01278 if (h == NULL
01279 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
01280 break;
01281
01282
01283
01284
01285 case (int)R_I370_ADDR31:
01286 case (int)R_I370_ADDR16:
01287 if (info->shared
01288 && r_symndx != 0)
01289 {
01290 Elf_Internal_Rela outrel;
01291 bfd_byte *loc;
01292 int skip;
01293
01294 #ifdef DEBUG
01295 fprintf (stderr,
01296 "i370_elf_relocate_section needs to create relocation for %s\n",
01297 (h && h->root.root.string) ? h->root.root.string : "<unknown>");
01298 #endif
01299
01300
01301
01302
01303
01304 if (sreloc == NULL)
01305 {
01306 const char *name;
01307
01308 name = (bfd_elf_string_from_elf_section
01309 (input_bfd,
01310 elf_elfheader (input_bfd)->e_shstrndx,
01311 elf_section_data (input_section)->rel_hdr.sh_name));
01312 if (name == NULL)
01313 return FALSE;
01314
01315 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
01316 && strcmp (bfd_get_section_name (input_bfd,
01317 input_section),
01318 name + 5) == 0);
01319
01320 sreloc = bfd_get_section_by_name (dynobj, name);
01321 BFD_ASSERT (sreloc != NULL);
01322 }
01323
01324 skip = 0;
01325
01326 outrel.r_offset =
01327 _bfd_elf_section_offset (output_bfd, info, input_section,
01328 rel->r_offset);
01329 if (outrel.r_offset == (bfd_vma) -1
01330 || outrel.r_offset == (bfd_vma) -2)
01331 skip = (int) outrel.r_offset;
01332 outrel.r_offset += (input_section->output_section->vma
01333 + input_section->output_offset);
01334
01335 if (skip)
01336 memset (&outrel, 0, sizeof outrel);
01337
01338
01339 else if (h != NULL
01340 && ((! info->symbolic && h->dynindx != -1)
01341 || !h->def_regular))
01342 {
01343 BFD_ASSERT (h->dynindx != -1);
01344 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
01345 outrel.r_addend = rel->r_addend;
01346 }
01347 else
01348 {
01349 if (r_type == R_I370_ADDR31)
01350 {
01351 outrel.r_info = ELF32_R_INFO (0, R_I370_RELATIVE);
01352 outrel.r_addend = relocation + rel->r_addend;
01353 }
01354 else
01355 {
01356 long indx;
01357
01358 if (bfd_is_abs_section (sec))
01359 indx = 0;
01360 else if (sec == NULL || sec->owner == NULL)
01361 {
01362 bfd_set_error (bfd_error_bad_value);
01363 return FALSE;
01364 }
01365 else
01366 {
01367 asection *osec;
01368
01369 osec = sec->output_section;
01370 indx = elf_section_data (osec)->dynindx;
01371 BFD_ASSERT(indx > 0);
01372 #ifdef DEBUG
01373 if (indx <= 0)
01374 {
01375 printf ("indx=%d section=%s flags=%08x name=%s\n",
01376 indx, osec->name, osec->flags,
01377 h->root.root.string);
01378 }
01379 #endif
01380 }
01381
01382 outrel.r_info = ELF32_R_INFO (indx, r_type);
01383 outrel.r_addend = relocation + rel->r_addend;
01384 }
01385 }
01386
01387 loc = sreloc->contents;
01388 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
01389 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
01390
01391
01392
01393
01394 if (skip == -1
01395 || (input_section->flags & SEC_ALLOC) != 0
01396 || ELF32_R_TYPE (outrel.r_info) != R_I370_RELATIVE)
01397 continue;
01398 }
01399 break;
01400
01401 case (int)R_I370_COPY:
01402 case (int)R_I370_RELATIVE:
01403 (*_bfd_error_handler)
01404 ("%B: Relocation %s is not yet supported for symbol %s.",
01405 input_bfd,
01406 i370_elf_howto_table[(int) r_type]->name,
01407 sym_name);
01408
01409 bfd_set_error (bfd_error_invalid_operation);
01410 ret = FALSE;
01411 continue;
01412 }
01413
01414 #ifdef DEBUG
01415 fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, offset = %ld, addend = %ld\n",
01416 howto->name,
01417 (int)r_type,
01418 sym_name,
01419 r_symndx,
01420 (long)offset,
01421 (long)addend);
01422 #endif
01423
01424 r = _bfd_final_link_relocate (howto,
01425 input_bfd,
01426 input_section,
01427 contents,
01428 offset,
01429 relocation,
01430 addend);
01431
01432 if (r != bfd_reloc_ok)
01433 {
01434 ret = FALSE;
01435 switch (r)
01436 {
01437 default:
01438 break;
01439
01440 case bfd_reloc_overflow:
01441 {
01442 const char *name;
01443
01444 if (h != NULL)
01445 name = NULL;
01446 else
01447 {
01448 name = bfd_elf_string_from_elf_section (input_bfd,
01449 symtab_hdr->sh_link,
01450 sym->st_name);
01451 if (name == NULL)
01452 break;
01453
01454 if (*name == '\0')
01455 name = bfd_section_name (input_bfd, sec);
01456 }
01457
01458 (*info->callbacks->reloc_overflow) (info,
01459 (h ? &h->root : NULL),
01460 name,
01461 howto->name,
01462 (bfd_vma) 0,
01463 input_bfd,
01464 input_section,
01465 offset);
01466 }
01467 break;
01468
01469 }
01470 }
01471 }
01472
01473 #ifdef DEBUG
01474 fprintf (stderr, "\n");
01475 #endif
01476
01477 return ret;
01478 }
01479
01480 static void
01481 i370_elf_post_process_headers (abfd, link_info)
01482 bfd * abfd;
01483 struct bfd_link_info * link_info ATTRIBUTE_UNUSED;
01484 {
01485 Elf_Internal_Ehdr * i_ehdrp;
01486
01487 i_ehdrp = elf_elfheader (abfd);
01488 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX;
01489 }
01490
01491 #define TARGET_BIG_SYM bfd_elf32_i370_vec
01492 #define TARGET_BIG_NAME "elf32-i370"
01493 #define ELF_ARCH bfd_arch_i370
01494 #define ELF_MACHINE_CODE EM_S370
01495 #ifdef EM_I370_OLD
01496 #define ELF_MACHINE_ALT1 EM_I370_OLD
01497 #endif
01498 #define ELF_MAXPAGESIZE 0x1000
01499 #define elf_info_to_howto i370_elf_info_to_howto
01500
01501 #define elf_backend_plt_not_loaded 1
01502 #define elf_backend_got_symbol_offset 4
01503 #define elf_backend_rela_normal 1
01504
01505 #define bfd_elf32_bfd_reloc_type_lookup i370_elf_reloc_type_lookup
01506 #define bfd_elf32_bfd_set_private_flags i370_elf_set_private_flags
01507 #define bfd_elf32_bfd_merge_private_bfd_data i370_elf_merge_private_bfd_data
01508 #define elf_backend_relocate_section i370_elf_relocate_section
01509
01510
01511
01512
01513 #define elf_backend_create_dynamic_sections i370_elf_create_dynamic_sections
01514 #define elf_backend_size_dynamic_sections i370_elf_size_dynamic_sections
01515 #define elf_backend_finish_dynamic_sections i370_elf_finish_dynamic_sections
01516 #define elf_backend_fake_sections i370_elf_fake_sections
01517 #define elf_backend_section_from_shdr i370_elf_section_from_shdr
01518 #define elf_backend_adjust_dynamic_symbol i370_elf_adjust_dynamic_symbol
01519 #define elf_backend_check_relocs i370_elf_check_relocs
01520
01521
01522
01523
01524
01525
01526
01527
01528 #define elf_backend_post_process_headers i370_elf_post_process_headers
01529
01530 static int i370_noop
01531 PARAMS ((void));
01532
01533 static int i370_noop ()
01534 {
01535 return 1;
01536 }
01537
01538
01539
01540 #define elf_backend_add_symbol_hook \
01541 (bfd_boolean (*) \
01542 PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *, \
01543 const char **, flagword *, asection **, bfd_vma *))) i370_noop
01544 #define elf_backend_finish_dynamic_symbol \
01545 (bfd_boolean (*) \
01546 PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, \
01547 Elf_Internal_Sym *))) i370_noop
01548 #define elf_backend_additional_program_headers \
01549 (int (*) PARAMS ((bfd *))) i370_noop
01550 #define elf_backend_modify_segment_map \
01551 (bfd_boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) i370_noop
01552
01553 #include "elf32-target.h"