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 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "bfdlink.h"
00029 #include "libbfd.h"
00030 #include "elf-bfd.h"
00031 #include "elf/vax.h"
00032
00033 static reloc_howto_type *reloc_type_lookup
00034 PARAMS ((bfd *, bfd_reloc_code_real_type));
00035 static void rtype_to_howto
00036 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00037 static struct bfd_hash_entry *elf_vax_link_hash_newfunc
00038 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
00039 static struct bfd_link_hash_table *elf_vax_link_hash_table_create
00040 PARAMS ((bfd *));
00041 static bfd_boolean elf_vax_check_relocs
00042 PARAMS ((bfd *, struct bfd_link_info *, asection *,
00043 const Elf_Internal_Rela *));
00044 static asection *elf_vax_gc_mark_hook
00045 PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
00046 struct elf_link_hash_entry *, Elf_Internal_Sym *));
00047 static bfd_boolean elf_vax_gc_sweep_hook
00048 PARAMS ((bfd *, struct bfd_link_info *, asection *,
00049 const Elf_Internal_Rela *));
00050 static bfd_boolean elf_vax_adjust_dynamic_symbol
00051 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
00052 static bfd_boolean elf_vax_size_dynamic_sections
00053 PARAMS ((bfd *, struct bfd_link_info *));
00054 static bfd_boolean elf_vax_relocate_section
00055 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00056 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
00057 static bfd_boolean elf_vax_finish_dynamic_symbol
00058 PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
00059 Elf_Internal_Sym *));
00060 static bfd_boolean elf_vax_finish_dynamic_sections
00061 PARAMS ((bfd *, struct bfd_link_info *));
00062
00063 static bfd_boolean elf32_vax_set_private_flags
00064 PARAMS ((bfd *, flagword));
00065 static bfd_boolean elf32_vax_merge_private_bfd_data
00066 PARAMS ((bfd *, bfd *));
00067 static bfd_boolean elf32_vax_print_private_bfd_data
00068 PARAMS ((bfd *, PTR));
00069
00070 static reloc_howto_type howto_table[] = {
00071 HOWTO (R_VAX_NONE,
00072 0,
00073 0,
00074 0,
00075 FALSE,
00076 0,
00077 complain_overflow_dont,
00078 bfd_elf_generic_reloc,
00079 "R_VAX_NONE",
00080 FALSE,
00081 0,
00082 0x00000000,
00083 FALSE),
00084
00085 HOWTO (R_VAX_32,
00086 0,
00087 2,
00088 32,
00089 FALSE,
00090 0,
00091 complain_overflow_bitfield,
00092 bfd_elf_generic_reloc,
00093 "R_VAX_32",
00094 FALSE,
00095 0,
00096 0xffffffff,
00097 FALSE),
00098
00099 HOWTO (R_VAX_16,
00100 0,
00101 1,
00102 16,
00103 FALSE,
00104 0,
00105 complain_overflow_bitfield,
00106 bfd_elf_generic_reloc,
00107 "R_VAX_16",
00108 FALSE,
00109 0,
00110 0x0000ffff,
00111 FALSE),
00112
00113 HOWTO (R_VAX_8,
00114 0,
00115 0,
00116 8,
00117 FALSE,
00118 0,
00119 complain_overflow_bitfield,
00120 bfd_elf_generic_reloc,
00121 "R_VAX_8",
00122 FALSE,
00123 0,
00124 0x000000ff,
00125 FALSE),
00126
00127 HOWTO (R_VAX_PC32,
00128 0,
00129 2,
00130 32,
00131 TRUE,
00132 0,
00133 complain_overflow_bitfield,
00134 bfd_elf_generic_reloc,
00135 "R_VAX_PC32",
00136 FALSE,
00137 0,
00138 0xffffffff,
00139 TRUE),
00140
00141 HOWTO (R_VAX_PC16,
00142 0,
00143 1,
00144 16,
00145 TRUE,
00146 0,
00147 complain_overflow_signed,
00148 bfd_elf_generic_reloc,
00149 "R_VAX_PC16",
00150 FALSE,
00151 0,
00152 0x0000ffff,
00153 TRUE),
00154
00155 HOWTO (R_VAX_PC8,
00156 0,
00157 0,
00158 8,
00159 TRUE,
00160 0,
00161 complain_overflow_signed,
00162 bfd_elf_generic_reloc,
00163 "R_VAX_PC8",
00164 FALSE,
00165 0,
00166 0x000000ff,
00167 TRUE),
00168
00169 HOWTO (R_VAX_GOT32,
00170 0,
00171 2,
00172 32,
00173 TRUE,
00174 0,
00175 complain_overflow_bitfield,
00176 bfd_elf_generic_reloc,
00177 "R_VAX_GOT32",
00178 FALSE,
00179 0,
00180 0xffffffff,
00181 TRUE),
00182
00183 EMPTY_HOWTO (-1),
00184 EMPTY_HOWTO (-1),
00185 EMPTY_HOWTO (-1),
00186 EMPTY_HOWTO (-1),
00187 EMPTY_HOWTO (-1),
00188
00189 HOWTO (R_VAX_PLT32,
00190 0,
00191 2,
00192 32,
00193 TRUE,
00194 0,
00195 complain_overflow_bitfield,
00196 bfd_elf_generic_reloc,
00197 "R_VAX_PLT32",
00198 FALSE,
00199 0,
00200 0xffffffff,
00201 TRUE),
00202
00203 EMPTY_HOWTO (-1),
00204 EMPTY_HOWTO (-1),
00205 EMPTY_HOWTO (-1),
00206 EMPTY_HOWTO (-1),
00207 EMPTY_HOWTO (-1),
00208
00209 HOWTO (R_VAX_COPY,
00210 0,
00211 0,
00212 0,
00213 FALSE,
00214 0,
00215 complain_overflow_dont,
00216 bfd_elf_generic_reloc,
00217 "R_VAX_COPY",
00218 FALSE,
00219 0,
00220 0xffffffff,
00221 FALSE),
00222
00223 HOWTO (R_VAX_GLOB_DAT,
00224 0,
00225 2,
00226 32,
00227 FALSE,
00228 0,
00229 complain_overflow_dont,
00230 bfd_elf_generic_reloc,
00231 "R_VAX_GLOB_DAT",
00232 FALSE,
00233 0,
00234 0xffffffff,
00235 FALSE),
00236
00237 HOWTO (R_VAX_JMP_SLOT,
00238 0,
00239 2,
00240 32,
00241 FALSE,
00242 0,
00243 complain_overflow_dont,
00244 bfd_elf_generic_reloc,
00245 "R_VAX_JMP_SLOT",
00246 FALSE,
00247 0,
00248 0xffffffff,
00249 FALSE),
00250
00251 HOWTO (R_VAX_RELATIVE,
00252 0,
00253 2,
00254 32,
00255 FALSE,
00256 0,
00257 complain_overflow_dont,
00258 bfd_elf_generic_reloc,
00259 "R_VAX_RELATIVE",
00260 FALSE,
00261 0,
00262 0xffffffff,
00263 FALSE),
00264
00265
00266 HOWTO (R_VAX_GNU_VTINHERIT,
00267 0,
00268 2,
00269 0,
00270 FALSE,
00271 0,
00272 complain_overflow_dont,
00273 NULL,
00274 "R_VAX_GNU_VTINHERIT",
00275 FALSE,
00276 0,
00277 0,
00278 FALSE),
00279
00280
00281 HOWTO (R_VAX_GNU_VTENTRY,
00282 0,
00283 2,
00284 0,
00285 FALSE,
00286 0,
00287 complain_overflow_dont,
00288 _bfd_elf_rel_vtable_reloc_fn,
00289 "R_VAX_GNU_VTENTRY",
00290 FALSE,
00291 0,
00292 0,
00293 FALSE),
00294 };
00295
00296 static void
00297 rtype_to_howto (abfd, cache_ptr, dst)
00298 bfd *abfd ATTRIBUTE_UNUSED;
00299 arelent *cache_ptr;
00300 Elf_Internal_Rela *dst;
00301 {
00302 BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_VAX_max);
00303 cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)];
00304 }
00305
00306 #define elf_info_to_howto rtype_to_howto
00307
00308 static const struct
00309 {
00310 bfd_reloc_code_real_type bfd_val;
00311 int elf_val;
00312 } reloc_map[] = {
00313 { BFD_RELOC_NONE, R_VAX_NONE },
00314 { BFD_RELOC_32, R_VAX_32 },
00315 { BFD_RELOC_16, R_VAX_16 },
00316 { BFD_RELOC_8, R_VAX_8 },
00317 { BFD_RELOC_32_PCREL, R_VAX_PC32 },
00318 { BFD_RELOC_16_PCREL, R_VAX_PC16 },
00319 { BFD_RELOC_8_PCREL, R_VAX_PC8 },
00320 { BFD_RELOC_32_GOT_PCREL, R_VAX_GOT32 },
00321 { BFD_RELOC_32_PLT_PCREL, R_VAX_PLT32 },
00322 { BFD_RELOC_NONE, R_VAX_COPY },
00323 { BFD_RELOC_VAX_GLOB_DAT, R_VAX_GLOB_DAT },
00324 { BFD_RELOC_VAX_JMP_SLOT, R_VAX_JMP_SLOT },
00325 { BFD_RELOC_VAX_RELATIVE, R_VAX_RELATIVE },
00326 { BFD_RELOC_CTOR, R_VAX_32 },
00327 { BFD_RELOC_VTABLE_INHERIT, R_VAX_GNU_VTINHERIT },
00328 { BFD_RELOC_VTABLE_ENTRY, R_VAX_GNU_VTENTRY },
00329 };
00330
00331 static reloc_howto_type *
00332 reloc_type_lookup (abfd, code)
00333 bfd *abfd ATTRIBUTE_UNUSED;
00334 bfd_reloc_code_real_type code;
00335 {
00336 unsigned int i;
00337 for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++)
00338 {
00339 if (reloc_map[i].bfd_val == code)
00340 return &howto_table[reloc_map[i].elf_val];
00341 }
00342 return 0;
00343 }
00344
00345 #define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
00346 #define ELF_ARCH bfd_arch_vax
00347
00348
00349
00350
00351
00352
00353
00354 #define ELF_DYNAMIC_INTERPRETER "/usr/libexec/ld.elf_so"
00355
00356
00357
00358 #define PLT_ENTRY_SIZE 12
00359
00360
00361
00362
00363 static const bfd_byte elf_vax_plt0_entry[PLT_ENTRY_SIZE] =
00364 {
00365 0xdd, 0xef,
00366 0, 0, 0, 0,
00367 0x17, 0xff,
00368 0, 0, 0, 0,
00369 };
00370
00371
00372
00373 static const bfd_byte elf_vax_plt_entry[PLT_ENTRY_SIZE] =
00374 {
00375 0x40, 0x00,
00376 0x16, 0xef,
00377 0, 0, 0, 0,
00378 0, 0, 0, 0,
00379 };
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 struct elf_vax_pcrel_relocs_copied
00391 {
00392
00393 struct elf_vax_pcrel_relocs_copied *next;
00394
00395 asection *section;
00396
00397 bfd_size_type count;
00398 };
00399
00400
00401
00402 struct elf_vax_link_hash_entry
00403 {
00404 struct elf_link_hash_entry root;
00405
00406
00407 struct elf_vax_pcrel_relocs_copied *pcrel_relocs_copied;
00408
00409 bfd_vma got_addend;
00410 };
00411
00412
00413
00414 struct elf_vax_link_hash_table
00415 {
00416 struct elf_link_hash_table root;
00417 };
00418
00419
00420
00421 static bfd_boolean elf_vax_discard_copies
00422 PARAMS ((struct elf_vax_link_hash_entry *, PTR));
00423
00424
00425
00426 static bfd_boolean elf_vax_instantiate_got_entries
00427 PARAMS ((struct elf_link_hash_entry *, PTR));
00428
00429
00430
00431 #define elf_vax_link_hash_traverse(table, func, info) \
00432 (elf_link_hash_traverse \
00433 (&(table)->root, \
00434 (bfd_boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
00435 (info)))
00436
00437
00438
00439 #define elf_vax_hash_table(p) \
00440 ((struct elf_vax_link_hash_table *) (p)->hash)
00441
00442
00443
00444 static struct bfd_hash_entry *
00445 elf_vax_link_hash_newfunc (entry, table, string)
00446 struct bfd_hash_entry *entry;
00447 struct bfd_hash_table *table;
00448 const char *string;
00449 {
00450 struct elf_vax_link_hash_entry *ret =
00451 (struct elf_vax_link_hash_entry *) entry;
00452
00453
00454
00455 if (ret == (struct elf_vax_link_hash_entry *) NULL)
00456 ret = ((struct elf_vax_link_hash_entry *)
00457 bfd_hash_allocate (table,
00458 sizeof (struct elf_vax_link_hash_entry)));
00459 if (ret == (struct elf_vax_link_hash_entry *) NULL)
00460 return (struct bfd_hash_entry *) ret;
00461
00462
00463 ret = ((struct elf_vax_link_hash_entry *)
00464 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
00465 table, string));
00466 if (ret != (struct elf_vax_link_hash_entry *) NULL)
00467 {
00468 ret->pcrel_relocs_copied = NULL;
00469 }
00470
00471 return (struct bfd_hash_entry *) ret;
00472 }
00473
00474
00475
00476 static struct bfd_link_hash_table *
00477 elf_vax_link_hash_table_create (abfd)
00478 bfd *abfd;
00479 {
00480 struct elf_vax_link_hash_table *ret;
00481 bfd_size_type amt = sizeof (struct elf_vax_link_hash_table);
00482
00483 ret = (struct elf_vax_link_hash_table *) bfd_malloc (amt);
00484 if (ret == (struct elf_vax_link_hash_table *) NULL)
00485 return NULL;
00486
00487 if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
00488 elf_vax_link_hash_newfunc))
00489 {
00490 free (ret);
00491 return NULL;
00492 }
00493
00494 return &ret->root.root;
00495 }
00496
00497
00498 static bfd_boolean
00499 elf32_vax_set_private_flags (abfd, flags)
00500 bfd *abfd;
00501 flagword flags;
00502 {
00503 elf_elfheader (abfd)->e_flags = flags;
00504 elf_flags_init (abfd) = TRUE;
00505 return TRUE;
00506 }
00507
00508
00509
00510 static bfd_boolean
00511 elf32_vax_merge_private_bfd_data (ibfd, obfd)
00512 bfd *ibfd;
00513 bfd *obfd;
00514 {
00515 flagword out_flags;
00516 flagword in_flags;
00517
00518 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
00519 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
00520 return TRUE;
00521
00522 in_flags = elf_elfheader (ibfd)->e_flags;
00523 out_flags = elf_elfheader (obfd)->e_flags;
00524
00525 if (!elf_flags_init (obfd))
00526 {
00527 elf_flags_init (obfd) = TRUE;
00528 elf_elfheader (obfd)->e_flags = in_flags;
00529 }
00530
00531 return TRUE;
00532 }
00533
00534
00535 static bfd_boolean
00536 elf32_vax_print_private_bfd_data (abfd, ptr)
00537 bfd *abfd;
00538 PTR ptr;
00539 {
00540 FILE *file = (FILE *) ptr;
00541
00542 BFD_ASSERT (abfd != NULL && ptr != NULL);
00543
00544
00545 _bfd_elf_print_private_bfd_data (abfd, ptr);
00546
00547
00548
00549
00550 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
00551
00552 if (elf_elfheader (abfd)->e_flags & EF_VAX_NONPIC)
00553 fprintf (file, _(" [nonpic]"));
00554
00555 if (elf_elfheader (abfd)->e_flags & EF_VAX_DFLOAT)
00556 fprintf (file, _(" [d-float]"));
00557
00558 if (elf_elfheader (abfd)->e_flags & EF_VAX_GFLOAT)
00559 fprintf (file, _(" [g-float]"));
00560
00561 fputc ('\n', file);
00562
00563 return TRUE;
00564 }
00565
00566
00567
00568
00569 static bfd_boolean
00570 elf_vax_check_relocs (abfd, info, sec, relocs)
00571 bfd *abfd;
00572 struct bfd_link_info *info;
00573 asection *sec;
00574 const Elf_Internal_Rela *relocs;
00575 {
00576 bfd *dynobj;
00577 Elf_Internal_Shdr *symtab_hdr;
00578 struct elf_link_hash_entry **sym_hashes;
00579 const Elf_Internal_Rela *rel;
00580 const Elf_Internal_Rela *rel_end;
00581 asection *sgot;
00582 asection *srelgot;
00583 asection *sreloc;
00584
00585 if (info->relocatable)
00586 return TRUE;
00587
00588 dynobj = elf_hash_table (info)->dynobj;
00589 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00590 sym_hashes = elf_sym_hashes (abfd);
00591
00592 sgot = NULL;
00593 srelgot = NULL;
00594 sreloc = NULL;
00595
00596 rel_end = relocs + sec->reloc_count;
00597 for (rel = relocs; rel < rel_end; rel++)
00598 {
00599 unsigned long r_symndx;
00600 struct elf_link_hash_entry *h;
00601
00602 r_symndx = ELF32_R_SYM (rel->r_info);
00603
00604 if (r_symndx < symtab_hdr->sh_info)
00605 h = NULL;
00606 else
00607 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
00608
00609 switch (ELF32_R_TYPE (rel->r_info))
00610 {
00611 case R_VAX_GOT32:
00612 if (h != NULL
00613 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
00614 break;
00615
00616
00617
00618 if (dynobj == NULL)
00619 {
00620
00621 elf_hash_table (info)->dynobj = dynobj = abfd;
00622 if (!_bfd_elf_create_got_section (dynobj, info))
00623 return FALSE;
00624 }
00625
00626 if (sgot == NULL)
00627 {
00628 sgot = bfd_get_section_by_name (dynobj, ".got");
00629 BFD_ASSERT (sgot != NULL);
00630 }
00631
00632 if (srelgot == NULL
00633 && (h != NULL || info->shared))
00634 {
00635 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
00636 if (srelgot == NULL)
00637 {
00638 srelgot = bfd_make_section (dynobj, ".rela.got");
00639 if (srelgot == NULL
00640 || !bfd_set_section_flags (dynobj, srelgot,
00641 (SEC_ALLOC
00642 | SEC_LOAD
00643 | SEC_HAS_CONTENTS
00644 | SEC_IN_MEMORY
00645 | SEC_LINKER_CREATED
00646 | SEC_READONLY))
00647 || !bfd_set_section_alignment (dynobj, srelgot, 2))
00648 return FALSE;
00649 }
00650 }
00651
00652 if (h != NULL)
00653 {
00654 struct elf_vax_link_hash_entry *eh;
00655
00656 eh = (struct elf_vax_link_hash_entry *) h;
00657 if (h->got.refcount == -1)
00658 {
00659 h->got.refcount = 1;
00660 eh->got_addend = rel->r_addend;
00661 }
00662 else
00663 {
00664 h->got.refcount++;
00665 if (eh->got_addend != (bfd_vma) rel->r_addend)
00666 (*_bfd_error_handler)
00667 (_("%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"),
00668 bfd_get_filename (abfd), rel->r_addend,
00669 h->root.root.string,
00670 eh->got_addend);
00671
00672 }
00673 }
00674 break;
00675
00676 case R_VAX_PLT32:
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 if (h == NULL)
00687 continue;
00688
00689 h->needs_plt = 1;
00690 if (h->plt.refcount == -1)
00691 h->plt.refcount = 1;
00692 else
00693 h->plt.refcount++;
00694 break;
00695
00696 case R_VAX_PC8:
00697 case R_VAX_PC16:
00698 case R_VAX_PC32:
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 if (!(info->shared
00710 && (sec->flags & SEC_ALLOC) != 0
00711 && h != NULL
00712 && (!info->symbolic
00713 || !h->def_regular)))
00714 {
00715 if (h != NULL)
00716 {
00717
00718
00719
00720 if (h->plt.refcount == -1)
00721 h->plt.refcount = 1;
00722 else
00723 h->plt.refcount++;
00724 }
00725 break;
00726 }
00727
00728 case R_VAX_8:
00729 case R_VAX_16:
00730 case R_VAX_32:
00731 if (h != NULL)
00732 {
00733
00734
00735 if (h->plt.refcount == -1)
00736 h->plt.refcount = 1;
00737 else
00738 h->plt.refcount++;
00739 }
00740
00741
00742
00743 if (info->shared
00744 && (sec->flags & SEC_ALLOC) != 0)
00745 {
00746
00747
00748
00749 if (sreloc == NULL)
00750 {
00751 const char *name;
00752
00753 name = (bfd_elf_string_from_elf_section
00754 (abfd,
00755 elf_elfheader (abfd)->e_shstrndx,
00756 elf_section_data (sec)->rel_hdr.sh_name));
00757 if (name == NULL)
00758 return FALSE;
00759
00760 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
00761 && strcmp (bfd_get_section_name (abfd, sec),
00762 name + 5) == 0);
00763
00764 sreloc = bfd_get_section_by_name (dynobj, name);
00765 if (sreloc == NULL)
00766 {
00767 sreloc = bfd_make_section (dynobj, name);
00768 if (sreloc == NULL
00769 || !bfd_set_section_flags (dynobj, sreloc,
00770 (SEC_ALLOC
00771 | SEC_LOAD
00772 | SEC_HAS_CONTENTS
00773 | SEC_IN_MEMORY
00774 | SEC_LINKER_CREATED
00775 | SEC_READONLY))
00776 || !bfd_set_section_alignment (dynobj, sreloc, 2))
00777 return FALSE;
00778 }
00779 if (sec->flags & SEC_READONLY)
00780 info->flags |= DF_TEXTREL;
00781 }
00782
00783 sreloc->size += sizeof (Elf32_External_Rela);
00784
00785
00786
00787
00788
00789
00790
00791
00792 if ((ELF32_R_TYPE (rel->r_info) == R_VAX_PC8
00793 || ELF32_R_TYPE (rel->r_info) == R_VAX_PC16
00794 || ELF32_R_TYPE (rel->r_info) == R_VAX_PC32)
00795 && info->symbolic)
00796 {
00797 struct elf_vax_link_hash_entry *eh;
00798 struct elf_vax_pcrel_relocs_copied *p;
00799
00800 eh = (struct elf_vax_link_hash_entry *) h;
00801
00802 for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
00803 if (p->section == sreloc)
00804 break;
00805
00806 if (p == NULL)
00807 {
00808 p = ((struct elf_vax_pcrel_relocs_copied *)
00809 bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
00810 if (p == NULL)
00811 return FALSE;
00812 p->next = eh->pcrel_relocs_copied;
00813 eh->pcrel_relocs_copied = p;
00814 p->section = sreloc;
00815 p->count = 0;
00816 }
00817
00818 ++p->count;
00819 }
00820 }
00821
00822 break;
00823
00824
00825
00826 case R_VAX_GNU_VTINHERIT:
00827 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
00828 return FALSE;
00829 break;
00830
00831
00832
00833 case R_VAX_GNU_VTENTRY:
00834 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
00835 return FALSE;
00836 break;
00837
00838 default:
00839 break;
00840 }
00841 }
00842
00843 return TRUE;
00844 }
00845
00846
00847
00848
00849 static asection *
00850 elf_vax_gc_mark_hook (sec, info, rel, h, sym)
00851 asection *sec;
00852 struct bfd_link_info *info ATTRIBUTE_UNUSED;
00853 Elf_Internal_Rela *rel;
00854 struct elf_link_hash_entry *h;
00855 Elf_Internal_Sym *sym;
00856 {
00857 if (h != NULL)
00858 {
00859 switch (ELF32_R_TYPE (rel->r_info))
00860 {
00861 case R_VAX_GNU_VTINHERIT:
00862 case R_VAX_GNU_VTENTRY:
00863 break;
00864
00865 default:
00866 switch (h->root.type)
00867 {
00868 default:
00869 break;
00870
00871 case bfd_link_hash_defined:
00872 case bfd_link_hash_defweak:
00873 return h->root.u.def.section;
00874
00875 case bfd_link_hash_common:
00876 return h->root.u.c.p->section;
00877 }
00878 }
00879 }
00880 else
00881 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
00882
00883 return NULL;
00884 }
00885
00886
00887
00888 static bfd_boolean
00889 elf_vax_gc_sweep_hook (abfd, info, sec, relocs)
00890 bfd *abfd;
00891 struct bfd_link_info *info;
00892 asection *sec;
00893 const Elf_Internal_Rela *relocs;
00894 {
00895 Elf_Internal_Shdr *symtab_hdr;
00896 struct elf_link_hash_entry **sym_hashes;
00897 const Elf_Internal_Rela *rel, *relend;
00898 bfd *dynobj;
00899
00900 dynobj = elf_hash_table (info)->dynobj;
00901 if (dynobj == NULL)
00902 return TRUE;
00903
00904 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00905 sym_hashes = elf_sym_hashes (abfd);
00906
00907 relend = relocs + sec->reloc_count;
00908 for (rel = relocs; rel < relend; rel++)
00909 {
00910 unsigned long r_symndx;
00911 struct elf_link_hash_entry *h = NULL;
00912
00913 r_symndx = ELF32_R_SYM (rel->r_info);
00914 if (r_symndx >= symtab_hdr->sh_info)
00915 {
00916 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
00917 while (h->root.type == bfd_link_hash_indirect
00918 || h->root.type == bfd_link_hash_warning)
00919 h = (struct elf_link_hash_entry *) h->root.u.i.link;
00920 }
00921
00922 switch (ELF32_R_TYPE (rel->r_info))
00923 {
00924 case R_VAX_GOT32:
00925 if (h != NULL && h->got.refcount > 0)
00926 --h->got.refcount;
00927 break;
00928
00929 case R_VAX_PLT32:
00930 case R_VAX_PC8:
00931 case R_VAX_PC16:
00932 case R_VAX_PC32:
00933 case R_VAX_8:
00934 case R_VAX_16:
00935 case R_VAX_32:
00936 if (h != NULL && h->plt.refcount > 0)
00937 --h->plt.refcount;
00938 break;
00939
00940 default:
00941 break;
00942 }
00943 }
00944
00945 return TRUE;
00946 }
00947
00948
00949
00950
00951
00952
00953
00954 static bfd_boolean
00955 elf_vax_adjust_dynamic_symbol (info, h)
00956 struct bfd_link_info *info;
00957 struct elf_link_hash_entry *h;
00958 {
00959 bfd *dynobj;
00960 asection *s;
00961 unsigned int power_of_two;
00962
00963 dynobj = elf_hash_table (info)->dynobj;
00964
00965
00966 BFD_ASSERT (dynobj != NULL
00967 && (h->needs_plt
00968 || h->u.weakdef != NULL
00969 || (h->def_dynamic
00970 && h->ref_regular
00971 && !h->def_regular)));
00972
00973
00974
00975
00976 if (h->type == STT_FUNC
00977 || h->needs_plt)
00978 {
00979 if (! info->shared
00980 && !h->def_dynamic
00981 && !h->ref_dynamic
00982
00983
00984
00985 && h->dynindx == -1)
00986 {
00987
00988
00989
00990
00991
00992 BFD_ASSERT (h->needs_plt);
00993 h->plt.offset = (bfd_vma) -1;
00994 return TRUE;
00995 }
00996
00997
00998 if (h->plt.refcount <= 0)
00999 {
01000 h->needs_plt = 0;
01001 h->plt.offset = (bfd_vma) -1;
01002 return TRUE;
01003 }
01004
01005
01006 if (h->dynindx == -1)
01007 {
01008 if (! bfd_elf_link_record_dynamic_symbol (info, h))
01009 return FALSE;
01010 }
01011
01012 s = bfd_get_section_by_name (dynobj, ".plt");
01013 BFD_ASSERT (s != NULL);
01014
01015
01016
01017 if (s->size == 0)
01018 {
01019 s->size += PLT_ENTRY_SIZE;
01020 }
01021
01022
01023
01024
01025
01026
01027 if (!info->shared
01028 && !h->def_regular)
01029 {
01030 h->root.u.def.section = s;
01031 h->root.u.def.value = s->size;
01032 }
01033
01034 h->plt.offset = s->size;
01035
01036
01037 s->size += PLT_ENTRY_SIZE;
01038
01039
01040
01041
01042 s = bfd_get_section_by_name (dynobj, ".got.plt");
01043 BFD_ASSERT (s != NULL);
01044 s->size += 4;
01045
01046
01047
01048 s = bfd_get_section_by_name (dynobj, ".rela.plt");
01049 BFD_ASSERT (s != NULL);
01050 s->size += sizeof (Elf32_External_Rela);
01051
01052 return TRUE;
01053 }
01054
01055
01056
01057 h->plt.offset = (bfd_vma) -1;
01058
01059
01060
01061
01062 if (h->u.weakdef != NULL)
01063 {
01064 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
01065 || h->u.weakdef->root.type == bfd_link_hash_defweak);
01066 h->root.u.def.section = h->u.weakdef->root.u.def.section;
01067 h->root.u.def.value = h->u.weakdef->root.u.def.value;
01068 return TRUE;
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078 if (info->shared)
01079 return TRUE;
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 s = bfd_get_section_by_name (dynobj, ".dynbss");
01092 BFD_ASSERT (s != NULL);
01093
01094
01095
01096
01097
01098 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
01099 {
01100 asection *srel;
01101
01102 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
01103 BFD_ASSERT (srel != NULL);
01104 srel->size += sizeof (Elf32_External_Rela);
01105 h->needs_copy = 1;
01106 }
01107
01108
01109
01110 power_of_two = bfd_log2 (h->size);
01111 if (power_of_two > 3)
01112 power_of_two = 3;
01113
01114
01115 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
01116 if (power_of_two > bfd_get_section_alignment (dynobj, s))
01117 {
01118 if (!bfd_set_section_alignment (dynobj, s, power_of_two))
01119 return FALSE;
01120 }
01121
01122
01123 h->root.u.def.section = s;
01124 h->root.u.def.value = s->size;
01125
01126
01127 s->size += h->size;
01128
01129 return TRUE;
01130 }
01131
01132
01133
01134 static bfd_boolean
01135 elf_vax_size_dynamic_sections (output_bfd, info)
01136 bfd *output_bfd;
01137 struct bfd_link_info *info;
01138 {
01139 bfd *dynobj;
01140 asection *s;
01141 bfd_boolean plt;
01142 bfd_boolean relocs;
01143 bfd_boolean reltext;
01144
01145 dynobj = elf_hash_table (info)->dynobj;
01146 BFD_ASSERT (dynobj != NULL);
01147
01148 if (elf_hash_table (info)->dynamic_sections_created)
01149 {
01150
01151 if (info->executable)
01152 {
01153 s = bfd_get_section_by_name (dynobj, ".interp");
01154 BFD_ASSERT (s != NULL);
01155 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
01156 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
01157 }
01158 }
01159 else
01160 {
01161
01162
01163
01164
01165
01166 s = bfd_get_section_by_name (dynobj, ".rela.got");
01167 if (s != NULL)
01168 s->size = 0;
01169 s = bfd_get_section_by_name (dynobj, ".got.plt");
01170 if (s != NULL)
01171 s->size = 0;
01172 s = bfd_get_section_by_name (dynobj, ".got");
01173 if (s != NULL)
01174 s->size = 0;
01175 }
01176
01177
01178
01179
01180
01181 if (info->shared && info->symbolic)
01182 elf_vax_link_hash_traverse (elf_vax_hash_table (info),
01183 elf_vax_discard_copies,
01184 (PTR) NULL);
01185
01186
01187
01188
01189 elf_link_hash_traverse (elf_hash_table (info),
01190 elf_vax_instantiate_got_entries,
01191 (PTR) info);
01192
01193
01194
01195
01196 plt = FALSE;
01197 relocs = FALSE;
01198 reltext = FALSE;
01199 for (s = dynobj->sections; s != NULL; s = s->next)
01200 {
01201 const char *name;
01202 bfd_boolean strip;
01203
01204 if ((s->flags & SEC_LINKER_CREATED) == 0)
01205 continue;
01206
01207
01208
01209 name = bfd_get_section_name (dynobj, s);
01210
01211 strip = FALSE;
01212
01213 if (strcmp (name, ".plt") == 0)
01214 {
01215 if (s->size == 0)
01216 {
01217
01218
01219 strip = TRUE;
01220 }
01221 else
01222 {
01223
01224 plt = TRUE;
01225 }
01226 }
01227 else if (strncmp (name, ".rela", 5) == 0)
01228 {
01229 if (s->size == 0)
01230 {
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240 strip = TRUE;
01241 }
01242 else
01243 {
01244 asection *target;
01245
01246
01247
01248 if (strcmp (name, ".rela.plt") != 0)
01249 {
01250 const char *outname;
01251
01252 relocs = TRUE;
01253
01254
01255
01256
01257
01258 outname = bfd_get_section_name (output_bfd,
01259 s->output_section);
01260 target = bfd_get_section_by_name (output_bfd, outname + 5);
01261 if (target != NULL
01262 && (target->flags & SEC_READONLY) != 0
01263 && (target->flags & SEC_ALLOC) != 0)
01264 reltext = TRUE;
01265 }
01266
01267
01268
01269 s->reloc_count = 0;
01270 }
01271 }
01272 else if (strncmp (name, ".got", 4) != 0)
01273 {
01274
01275 continue;
01276 }
01277
01278 if (strip)
01279 {
01280 _bfd_strip_section_from_output (info, s);
01281 continue;
01282 }
01283
01284
01285 s->contents = (bfd_byte *) bfd_alloc (dynobj, s->size);
01286 if (s->contents == NULL && s->size != 0)
01287 return FALSE;
01288 }
01289
01290 if (elf_hash_table (info)->dynamic_sections_created)
01291 {
01292
01293
01294
01295
01296
01297 #define add_dynamic_entry(TAG, VAL) \
01298 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
01299
01300 if (!info->shared)
01301 {
01302 if (!add_dynamic_entry (DT_DEBUG, 0))
01303 return FALSE;
01304 }
01305
01306 if (plt)
01307 {
01308 if (!add_dynamic_entry (DT_PLTGOT, 0)
01309 || !add_dynamic_entry (DT_PLTRELSZ, 0)
01310 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
01311 || !add_dynamic_entry (DT_JMPREL, 0))
01312 return FALSE;
01313 }
01314
01315 if (relocs)
01316 {
01317 if (!add_dynamic_entry (DT_RELA, 0)
01318 || !add_dynamic_entry (DT_RELASZ, 0)
01319 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
01320 return FALSE;
01321 }
01322
01323 if (reltext || (info->flags & DF_TEXTREL) != 0)
01324 {
01325 if (!add_dynamic_entry (DT_TEXTREL, 0))
01326 return FALSE;
01327 }
01328 }
01329 #undef add_dynamic_entry
01330
01331 return TRUE;
01332 }
01333
01334
01335
01336
01337
01338
01339
01340 static bfd_boolean
01341 elf_vax_discard_copies (h, ignore)
01342 struct elf_vax_link_hash_entry *h;
01343 PTR ignore ATTRIBUTE_UNUSED;
01344 {
01345 struct elf_vax_pcrel_relocs_copied *s;
01346
01347 if (h->root.root.type == bfd_link_hash_warning)
01348 h = (struct elf_vax_link_hash_entry *) h->root.root.u.i.link;
01349
01350
01351 if (!h->root.def_regular)
01352 return TRUE;
01353
01354 for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
01355 s->section->size -= s->count * sizeof (Elf32_External_Rela);
01356
01357 return TRUE;
01358 }
01359
01360
01361
01362
01363
01364
01365
01366
01367 static bfd_boolean
01368 elf_vax_instantiate_got_entries (h, infoptr)
01369 struct elf_link_hash_entry *h;
01370 PTR infoptr;
01371 {
01372 struct bfd_link_info *info = (struct bfd_link_info *) infoptr;
01373 bfd *dynobj;
01374 asection *sgot;
01375 asection *srelgot;
01376
01377
01378 if (h->got.refcount <= 0 && h->plt.refcount <= 0)
01379 return TRUE;
01380
01381 dynobj = elf_hash_table (info)->dynobj;
01382 if (dynobj == NULL)
01383 return TRUE;
01384
01385 sgot = bfd_get_section_by_name (dynobj, ".got");
01386 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
01387
01388 if (!elf_hash_table (info)->dynamic_sections_created
01389 || (info->shared && info->symbolic))
01390 {
01391 h->got.refcount = 0;
01392 h->got.offset = (bfd_vma) -1;
01393 h->plt.refcount = 0;
01394 h->plt.offset = (bfd_vma) -1;
01395 }
01396 else if (h->got.refcount > 0)
01397 {
01398
01399 if (h->dynindx == -1)
01400 {
01401 if (!bfd_elf_link_record_dynamic_symbol (info, h))
01402 return FALSE;
01403 }
01404
01405
01406 sgot->size += 4;
01407 srelgot->size += sizeof (Elf32_External_Rela);
01408 }
01409
01410 return TRUE;
01411 }
01412
01413
01414
01415 static bfd_boolean
01416 elf_vax_relocate_section (output_bfd, info, input_bfd, input_section,
01417 contents, relocs, local_syms, local_sections)
01418 bfd *output_bfd;
01419 struct bfd_link_info *info;
01420 bfd *input_bfd;
01421 asection *input_section;
01422 bfd_byte *contents;
01423 Elf_Internal_Rela *relocs;
01424 Elf_Internal_Sym *local_syms;
01425 asection **local_sections;
01426 {
01427 bfd *dynobj;
01428 Elf_Internal_Shdr *symtab_hdr;
01429 struct elf_link_hash_entry **sym_hashes;
01430 bfd_vma *local_got_offsets;
01431 bfd_vma plt_index;
01432 bfd_vma got_offset;
01433 asection *sgot;
01434 asection *splt;
01435 asection *sgotplt;
01436 asection *sreloc;
01437 Elf_Internal_Rela *rel;
01438 Elf_Internal_Rela *relend;
01439
01440 if (info->relocatable)
01441 return TRUE;
01442
01443 dynobj = elf_hash_table (info)->dynobj;
01444 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
01445 sym_hashes = elf_sym_hashes (input_bfd);
01446 local_got_offsets = elf_local_got_offsets (input_bfd);
01447
01448 sgot = NULL;
01449 splt = NULL;
01450 sgotplt = NULL;
01451 sreloc = NULL;
01452
01453 rel = relocs;
01454 relend = relocs + input_section->reloc_count;
01455 for (; rel < relend; rel++)
01456 {
01457 int r_type;
01458 reloc_howto_type *howto;
01459 unsigned long r_symndx;
01460 struct elf_link_hash_entry *h;
01461 Elf_Internal_Sym *sym;
01462 asection *sec;
01463 bfd_vma relocation;
01464 bfd_reloc_status_type r;
01465
01466 r_type = ELF32_R_TYPE (rel->r_info);
01467 if (r_type < 0 || r_type >= (int) R_VAX_max)
01468 {
01469 bfd_set_error (bfd_error_bad_value);
01470 return FALSE;
01471 }
01472 howto = howto_table + r_type;
01473
01474
01475 r_symndx = ELF32_R_SYM (rel->r_info);
01476 h = NULL;
01477 sym = NULL;
01478 sec = NULL;
01479 if (r_symndx < symtab_hdr->sh_info)
01480 {
01481 sym = local_syms + r_symndx;
01482 sec = local_sections[r_symndx];
01483 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
01484 }
01485 else
01486 {
01487 bfd_boolean unresolved_reloc;
01488 bfd_boolean warned;
01489
01490 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
01491 r_symndx, symtab_hdr, sym_hashes,
01492 h, sec, relocation,
01493 unresolved_reloc, warned);
01494
01495 if ((h->root.type == bfd_link_hash_defined
01496 || h->root.type == bfd_link_hash_defweak)
01497 && ((r_type == R_VAX_PLT32
01498 && h->plt.offset != (bfd_vma) -1
01499 && elf_hash_table (info)->dynamic_sections_created)
01500 || (r_type == R_VAX_GOT32
01501 && strcmp (h->root.root.string,
01502 "_GLOBAL_OFFSET_TABLE_") != 0
01503 && elf_hash_table (info)->dynamic_sections_created
01504 && (! info->shared
01505 || (! info->symbolic && h->dynindx != -1)
01506 || !h->def_regular))
01507 || (info->shared
01508 && ((! info->symbolic && h->dynindx != -1)
01509 || !h->def_regular)
01510 && ((input_section->flags & SEC_ALLOC) != 0
01511
01512
01513
01514
01515
01516 || ((input_section->flags & SEC_DEBUGGING) != 0
01517 && h->def_dynamic))
01518 && (r_type == R_VAX_8
01519 || r_type == R_VAX_16
01520 || r_type == R_VAX_32
01521 || r_type == R_VAX_PC8
01522 || r_type == R_VAX_PC16
01523 || r_type == R_VAX_PC32))))
01524
01525
01526
01527 relocation = 0;
01528 }
01529
01530 switch (r_type)
01531 {
01532 case R_VAX_GOT32:
01533
01534
01535 if (h == NULL || h->got.offset == (bfd_vma) -1)
01536 break;
01537
01538
01539
01540
01541 {
01542 bfd_vma off;
01543
01544 if (sgot == NULL)
01545 {
01546 sgot = bfd_get_section_by_name (dynobj, ".got");
01547 BFD_ASSERT (sgot != NULL);
01548 }
01549
01550 BFD_ASSERT (h != NULL);
01551 off = h->got.offset;
01552 BFD_ASSERT (off != (bfd_vma) -1);
01553 BFD_ASSERT (off < sgot->size);
01554
01555 if (info->shared
01556 && h->dynindx == -1
01557 && h->def_regular)
01558 {
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569 if ((off & 1) != 0)
01570 off &= ~1;
01571 else
01572 {
01573 bfd_put_32 (output_bfd, relocation + rel->r_addend,
01574 sgot->contents + off);
01575 h->got.offset |= 1;
01576 }
01577 } else {
01578 bfd_put_32 (output_bfd, rel->r_addend, sgot->contents + off);
01579 }
01580
01581 relocation = sgot->output_offset + off;
01582
01583 rel->r_addend = 0;
01584
01585
01586 contents[rel->r_offset - 1] |= 0x10;
01587 relocation += sgot->output_section->vma;
01588 }
01589 break;
01590
01591 case R_VAX_PLT32:
01592
01593
01594
01595
01596
01597 if (h == NULL)
01598 break;
01599
01600 if (h->plt.offset == (bfd_vma) -1
01601 || !elf_hash_table (info)->dynamic_sections_created)
01602 {
01603
01604
01605
01606 break;
01607 }
01608
01609 if (splt == NULL)
01610 {
01611 splt = bfd_get_section_by_name (dynobj, ".plt");
01612 BFD_ASSERT (splt != NULL);
01613 }
01614
01615 if (sgotplt == NULL)
01616 {
01617 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
01618 BFD_ASSERT (splt != NULL);
01619 }
01620
01621 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
01622
01623
01624
01625
01626 got_offset = (plt_index + 3) * 4;
01627
01628
01629
01630 relocation = (sgotplt->output_section->vma
01631 + sgotplt->output_offset
01632 + got_offset);
01633 contents[rel->r_offset-1] |= 0x10;
01634 if (rel->r_addend == 2)
01635 {
01636 h->plt.offset |= 1;
01637 }
01638 else if (rel->r_addend != 0)
01639 (*_bfd_error_handler)
01640 (_("%s: warning: PLT addend of %d to `%s' from %s section ignored"),
01641 bfd_get_filename (input_bfd), rel->r_addend,
01642 h->root.root.string,
01643 bfd_get_section_name (input_bfd, input_section));
01644 rel->r_addend = 0;
01645
01646 break;
01647
01648 case R_VAX_PC8:
01649 case R_VAX_PC16:
01650 case R_VAX_PC32:
01651 if (h == NULL)
01652 break;
01653
01654 case R_VAX_8:
01655 case R_VAX_16:
01656 case R_VAX_32:
01657 if (info->shared
01658 && r_symndx != 0
01659 && (input_section->flags & SEC_ALLOC) != 0
01660 && ((r_type != R_VAX_PC8
01661 && r_type != R_VAX_PC16
01662 && r_type != R_VAX_PC32)
01663 || (!info->symbolic
01664 || !h->def_regular)))
01665 {
01666 Elf_Internal_Rela outrel;
01667 bfd_byte *loc;
01668 bfd_boolean skip, relocate;
01669
01670
01671
01672
01673 if (sreloc == NULL)
01674 {
01675 const char *name;
01676
01677 name = (bfd_elf_string_from_elf_section
01678 (input_bfd,
01679 elf_elfheader (input_bfd)->e_shstrndx,
01680 elf_section_data (input_section)->rel_hdr.sh_name));
01681 if (name == NULL)
01682 return FALSE;
01683
01684 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
01685 && strcmp (bfd_get_section_name (input_bfd,
01686 input_section),
01687 name + 5) == 0);
01688
01689 sreloc = bfd_get_section_by_name (dynobj, name);
01690 BFD_ASSERT (sreloc != NULL);
01691 }
01692
01693 skip = FALSE;
01694 relocate = FALSE;
01695
01696 outrel.r_offset =
01697 _bfd_elf_section_offset (output_bfd, info, input_section,
01698 rel->r_offset);
01699 if (outrel.r_offset == (bfd_vma) -1)
01700 skip = TRUE;
01701 if (outrel.r_offset == (bfd_vma) -2)
01702 skip = TRUE, relocate = TRUE;
01703 outrel.r_offset += (input_section->output_section->vma
01704 + input_section->output_offset);
01705
01706 if (skip)
01707 memset (&outrel, 0, sizeof outrel);
01708
01709
01710 else if (h != NULL
01711 && ((! info->symbolic && h->dynindx != -1)
01712 || !h->def_regular))
01713 {
01714 BFD_ASSERT (h->dynindx != -1);
01715 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
01716 outrel.r_addend = relocation + rel->r_addend;
01717 }
01718 else
01719 {
01720 if (r_type == R_VAX_32)
01721 {
01722 relocate = TRUE;
01723 outrel.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE);
01724 BFD_ASSERT (bfd_get_signed_32 (input_bfd,
01725 &contents[rel->r_offset]) == 0);
01726 outrel.r_addend = relocation + rel->r_addend;
01727 }
01728 else
01729 {
01730 long indx;
01731
01732 if (bfd_is_abs_section (sec))
01733 indx = 0;
01734 else if (sec == NULL || sec->owner == NULL)
01735 {
01736 bfd_set_error (bfd_error_bad_value);
01737 return FALSE;
01738 }
01739 else
01740 {
01741 asection *osec;
01742
01743 osec = sec->output_section;
01744 indx = elf_section_data (osec)->dynindx;
01745 BFD_ASSERT (indx > 0);
01746 }
01747
01748 outrel.r_info = ELF32_R_INFO (indx, r_type);
01749 outrel.r_addend = relocation + rel->r_addend;
01750 }
01751 }
01752
01753 if (!strcmp (bfd_get_section_name (input_bfd, input_section),
01754 ".text") != 0 ||
01755 (info->shared
01756 && ELF32_R_TYPE(outrel.r_info) != R_VAX_32
01757 && ELF32_R_TYPE(outrel.r_info) != R_VAX_RELATIVE
01758 && ELF32_R_TYPE(outrel.r_info) != R_VAX_COPY
01759 && ELF32_R_TYPE(outrel.r_info) != R_VAX_JMP_SLOT
01760 && ELF32_R_TYPE(outrel.r_info) != R_VAX_GLOB_DAT))
01761 {
01762 if (h != NULL)
01763 (*_bfd_error_handler)
01764 (_("%s: warning: %s relocation against symbol `%s' from %s section"),
01765 bfd_get_filename (input_bfd), howto->name,
01766 h->root.root.string,
01767 bfd_get_section_name (input_bfd, input_section));
01768 else
01769 (*_bfd_error_handler)
01770 (_("%s: warning: %s relocation to 0x%x from %s section"),
01771 bfd_get_filename (input_bfd), howto->name,
01772 outrel.r_addend,
01773 bfd_get_section_name (input_bfd, input_section));
01774 }
01775 loc = sreloc->contents;
01776 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
01777 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
01778
01779
01780
01781
01782
01783 if (!relocate)
01784 continue;
01785 }
01786
01787 break;
01788
01789 case R_VAX_GNU_VTINHERIT:
01790 case R_VAX_GNU_VTENTRY:
01791
01792 continue;
01793
01794 default:
01795 break;
01796 }
01797
01798
01799
01800
01801 if (howto->pc_relative && howto->pcrel_offset)
01802 relocation -= bfd_get_reloc_size(howto);
01803
01804 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
01805 contents, rel->r_offset,
01806 relocation, rel->r_addend);
01807
01808 if (r != bfd_reloc_ok)
01809 {
01810 switch (r)
01811 {
01812 default:
01813 case bfd_reloc_outofrange:
01814 abort ();
01815 case bfd_reloc_overflow:
01816 {
01817 const char *name;
01818
01819 if (h != NULL)
01820 name = NULL;
01821 else
01822 {
01823 name = bfd_elf_string_from_elf_section (input_bfd,
01824 symtab_hdr->sh_link,
01825 sym->st_name);
01826 if (name == NULL)
01827 return FALSE;
01828 if (*name == '\0')
01829 name = bfd_section_name (input_bfd, sec);
01830 }
01831 if (!(info->callbacks->reloc_overflow
01832 (info, (h ? &h->root : NULL), name, howto->name,
01833 (bfd_vma) 0, input_bfd, input_section,
01834 rel->r_offset)))
01835 return FALSE;
01836 }
01837 break;
01838 }
01839 }
01840 }
01841
01842 return TRUE;
01843 }
01844
01845
01846
01847
01848 static bfd_boolean
01849 elf_vax_finish_dynamic_symbol (output_bfd, info, h, sym)
01850 bfd *output_bfd;
01851 struct bfd_link_info *info;
01852 struct elf_link_hash_entry *h;
01853 Elf_Internal_Sym *sym;
01854 {
01855 bfd *dynobj;
01856
01857 dynobj = elf_hash_table (info)->dynobj;
01858
01859 if (h->plt.offset != (bfd_vma) -1)
01860 {
01861 asection *splt;
01862 asection *sgot;
01863 asection *srela;
01864 bfd_vma plt_index;
01865 bfd_vma got_offset;
01866 bfd_vma addend;
01867 Elf_Internal_Rela rela;
01868 bfd_byte *loc;
01869
01870
01871
01872 BFD_ASSERT (h->dynindx != -1);
01873
01874 splt = bfd_get_section_by_name (dynobj, ".plt");
01875 sgot = bfd_get_section_by_name (dynobj, ".got.plt");
01876 srela = bfd_get_section_by_name (dynobj, ".rela.plt");
01877 BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
01878
01879 addend = 2 * (h->plt.offset & 1);
01880 h->plt.offset &= ~1;
01881
01882
01883
01884
01885
01886 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
01887
01888
01889
01890
01891 got_offset = (plt_index + 3) * 4;
01892
01893
01894 memcpy (splt->contents + h->plt.offset, elf_vax_plt_entry,
01895 PLT_ENTRY_SIZE);
01896
01897
01898 bfd_put_32 (output_bfd,
01899 -(h->plt.offset + 8),
01900 splt->contents + h->plt.offset + 4);
01901
01902 bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
01903 splt->contents + h->plt.offset + 8);
01904
01905
01906 bfd_put_32 (output_bfd,
01907 (splt->output_section->vma
01908 + splt->output_offset
01909 + h->plt.offset) + addend,
01910 sgot->contents + got_offset);
01911
01912
01913 rela.r_offset = (sgot->output_section->vma
01914 + sgot->output_offset
01915 + got_offset);
01916 rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_JMP_SLOT);
01917 rela.r_addend = addend;
01918 loc = srela->contents + plt_index * sizeof (Elf32_External_Rela);
01919 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
01920
01921 if (!h->def_regular)
01922 {
01923
01924
01925 sym->st_shndx = SHN_UNDEF;
01926 }
01927 }
01928
01929 if (h->got.offset != (bfd_vma) -1)
01930 {
01931 asection *sgot;
01932 asection *srela;
01933 Elf_Internal_Rela rela;
01934 bfd_byte *loc;
01935
01936
01937
01938 sgot = bfd_get_section_by_name (dynobj, ".got");
01939 srela = bfd_get_section_by_name (dynobj, ".rela.got");
01940 BFD_ASSERT (sgot != NULL && srela != NULL);
01941
01942 rela.r_offset = (sgot->output_section->vma
01943 + sgot->output_offset
01944 + (h->got.offset &~ 1));
01945
01946
01947
01948
01949
01950 if (info->shared
01951 && h->dynindx == -1
01952 && h->def_regular)
01953 {
01954 rela.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE);
01955 }
01956 else
01957 {
01958 rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_GLOB_DAT);
01959 }
01960 rela.r_addend = bfd_get_signed_32 (output_bfd,
01961 (sgot->contents
01962 + (h->got.offset & ~1)));
01963
01964 loc = srela->contents;
01965 loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
01966 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
01967 }
01968
01969 if (h->needs_copy)
01970 {
01971 asection *s;
01972 Elf_Internal_Rela rela;
01973 bfd_byte *loc;
01974
01975
01976 BFD_ASSERT (h->dynindx != -1
01977 && (h->root.type == bfd_link_hash_defined
01978 || h->root.type == bfd_link_hash_defweak));
01979
01980 s = bfd_get_section_by_name (h->root.u.def.section->owner,
01981 ".rela.bss");
01982 BFD_ASSERT (s != NULL);
01983
01984 rela.r_offset = (h->root.u.def.value
01985 + h->root.u.def.section->output_section->vma
01986 + h->root.u.def.section->output_offset);
01987 rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_COPY);
01988 rela.r_addend = 0;
01989 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
01990 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
01991 }
01992
01993
01994 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
01995 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
01996 sym->st_shndx = SHN_ABS;
01997
01998 return TRUE;
01999 }
02000
02001
02002
02003 static bfd_boolean
02004 elf_vax_finish_dynamic_sections (output_bfd, info)
02005 bfd *output_bfd;
02006 struct bfd_link_info *info;
02007 {
02008 bfd *dynobj;
02009 asection *sgot;
02010 asection *sdyn;
02011
02012 dynobj = elf_hash_table (info)->dynobj;
02013
02014 sgot = bfd_get_section_by_name (dynobj, ".got.plt");
02015 BFD_ASSERT (sgot != NULL);
02016 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
02017
02018 if (elf_hash_table (info)->dynamic_sections_created)
02019 {
02020 asection *splt;
02021 Elf32_External_Dyn *dyncon, *dynconend;
02022
02023 splt = bfd_get_section_by_name (dynobj, ".plt");
02024 BFD_ASSERT (splt != NULL && sdyn != NULL);
02025
02026 dyncon = (Elf32_External_Dyn *) sdyn->contents;
02027 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
02028 for (; dyncon < dynconend; dyncon++)
02029 {
02030 Elf_Internal_Dyn dyn;
02031 const char *name;
02032 asection *s;
02033
02034 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
02035
02036 switch (dyn.d_tag)
02037 {
02038 default:
02039 break;
02040
02041 case DT_PLTGOT:
02042 name = ".got";
02043 goto get_vma;
02044 case DT_JMPREL:
02045 name = ".rela.plt";
02046 get_vma:
02047 s = bfd_get_section_by_name (output_bfd, name);
02048 BFD_ASSERT (s != NULL);
02049 dyn.d_un.d_ptr = s->vma;
02050 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
02051 break;
02052
02053 case DT_PLTRELSZ:
02054 s = bfd_get_section_by_name (output_bfd, ".rela.plt");
02055 BFD_ASSERT (s != NULL);
02056 dyn.d_un.d_val = s->size;
02057 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
02058 break;
02059
02060 case DT_RELASZ:
02061
02062
02063
02064
02065
02066
02067
02068 s = bfd_get_section_by_name (output_bfd, ".rela.plt");
02069 if (s != NULL)
02070 dyn.d_un.d_val -= s->size;
02071 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
02072 break;
02073 }
02074 }
02075
02076
02077 if (splt->size > 0)
02078 {
02079 memcpy (splt->contents, elf_vax_plt0_entry, PLT_ENTRY_SIZE);
02080 bfd_put_32 (output_bfd,
02081 (sgot->output_section->vma
02082 + sgot->output_offset + 4
02083 - (splt->output_section->vma + 6)),
02084 splt->contents + 2);
02085 bfd_put_32 (output_bfd,
02086 (sgot->output_section->vma
02087 + sgot->output_offset + 8
02088 - (splt->output_section->vma + 12)),
02089 splt->contents + 8);
02090 elf_section_data (splt->output_section)->this_hdr.sh_entsize
02091 = PLT_ENTRY_SIZE;
02092 }
02093 }
02094
02095
02096 if (sgot->size > 0)
02097 {
02098 if (sdyn == NULL)
02099 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
02100 else
02101 bfd_put_32 (output_bfd,
02102 sdyn->output_section->vma + sdyn->output_offset,
02103 sgot->contents);
02104 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
02105 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
02106 }
02107
02108 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
02109
02110 return TRUE;
02111 }
02112
02113 #define TARGET_LITTLE_SYM bfd_elf32_vax_vec
02114 #define TARGET_LITTLE_NAME "elf32-vax"
02115 #define ELF_MACHINE_CODE EM_VAX
02116 #define ELF_MAXPAGESIZE 0x1000
02117
02118 #define elf_backend_create_dynamic_sections \
02119 _bfd_elf_create_dynamic_sections
02120 #define bfd_elf32_bfd_link_hash_table_create \
02121 elf_vax_link_hash_table_create
02122 #define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
02123
02124 #define elf_backend_check_relocs elf_vax_check_relocs
02125 #define elf_backend_adjust_dynamic_symbol \
02126 elf_vax_adjust_dynamic_symbol
02127 #define elf_backend_size_dynamic_sections \
02128 elf_vax_size_dynamic_sections
02129 #define elf_backend_relocate_section elf_vax_relocate_section
02130 #define elf_backend_finish_dynamic_symbol \
02131 elf_vax_finish_dynamic_symbol
02132 #define elf_backend_finish_dynamic_sections \
02133 elf_vax_finish_dynamic_sections
02134 #define elf_backend_gc_mark_hook elf_vax_gc_mark_hook
02135 #define elf_backend_gc_sweep_hook elf_vax_gc_sweep_hook
02136 #define bfd_elf32_bfd_merge_private_bfd_data \
02137 elf32_vax_merge_private_bfd_data
02138 #define bfd_elf32_bfd_set_private_flags \
02139 elf32_vax_set_private_flags
02140 #define bfd_elf32_bfd_print_private_bfd_data \
02141 elf32_vax_print_private_bfd_data
02142
02143 #define elf_backend_can_gc_sections 1
02144 #define elf_backend_want_got_plt 1
02145 #define elf_backend_plt_readonly 1
02146 #define elf_backend_want_plt_sym 0
02147 #define elf_backend_got_header_size 16
02148 #define elf_backend_rela_normal 1
02149
02150 #include "elf32-target.h"