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 #include "bfd.h"
00032 #include "sysdep.h"
00033 #include "libbfd.h"
00034 #include "elf-bfd.h"
00035 #include "elf/hppa.h"
00036 #include "libhppa.h"
00037 #include "elf32-hppa.h"
00038 #define ARCH_SIZE 32
00039 #include "elf32-hppa.h"
00040 #include "elf-hppa.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 #define PLT_ENTRY_SIZE 8
00121 #define GOT_ENTRY_SIZE 4
00122 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
00123
00124 static const bfd_byte plt_stub[] =
00125 {
00126 0x0e, 0x80, 0x10, 0x96,
00127 0xea, 0xc0, 0xc0, 0x00,
00128 0x0e, 0x88, 0x10, 0x95,
00129 #define PLT_STUB_ENTRY (3*4)
00130 0xea, 0x9f, 0x1f, 0xdd,
00131 0xd6, 0x80, 0x1c, 0x1e,
00132 0x00, 0xc0, 0xff, 0xee,
00133 0xde, 0xad, 0xbe, 0xef
00134 };
00135
00136
00137
00138 #define STUB_SUFFIX ".stub"
00139
00140
00141
00142
00143 #ifndef RELATIVE_DYNRELOCS
00144 #define RELATIVE_DYNRELOCS 0
00145 #define IS_ABSOLUTE_RELOC(r_type) 1
00146 #endif
00147
00148
00149
00150
00151
00152 #define ELIMINATE_COPY_RELOCS 1
00153
00154 enum elf32_hppa_stub_type {
00155 hppa_stub_long_branch,
00156 hppa_stub_long_branch_shared,
00157 hppa_stub_import,
00158 hppa_stub_import_shared,
00159 hppa_stub_export,
00160 hppa_stub_none
00161 };
00162
00163 struct elf32_hppa_stub_hash_entry {
00164
00165
00166 struct bfd_hash_entry root;
00167
00168
00169 asection *stub_sec;
00170
00171
00172 bfd_vma stub_offset;
00173
00174
00175
00176 bfd_vma target_value;
00177 asection *target_section;
00178
00179 enum elf32_hppa_stub_type stub_type;
00180
00181
00182 struct elf32_hppa_link_hash_entry *h;
00183
00184
00185
00186 asection *id_sec;
00187 };
00188
00189 struct elf32_hppa_link_hash_entry {
00190
00191 struct elf_link_hash_entry elf;
00192
00193
00194
00195 struct elf32_hppa_stub_hash_entry *stub_cache;
00196
00197
00198
00199 struct elf32_hppa_dyn_reloc_entry {
00200
00201
00202 struct elf32_hppa_dyn_reloc_entry *next;
00203
00204
00205 asection *sec;
00206
00207
00208 bfd_size_type count;
00209
00210 #if RELATIVE_DYNRELOCS
00211
00212 bfd_size_type relative_count;
00213 #endif
00214 } *dyn_relocs;
00215
00216
00217 unsigned int plabel:1;
00218 };
00219
00220 struct elf32_hppa_link_hash_table {
00221
00222
00223 struct elf_link_hash_table elf;
00224
00225
00226 struct bfd_hash_table stub_hash_table;
00227
00228
00229 bfd *stub_bfd;
00230
00231
00232 asection * (*add_stub_section) (const char *, asection *);
00233 void (*layout_sections_again) (void);
00234
00235
00236
00237 struct map_stub {
00238
00239
00240 asection *link_sec;
00241
00242 asection *stub_sec;
00243 } *stub_group;
00244
00245
00246 unsigned int bfd_count;
00247 int top_index;
00248 asection **input_list;
00249 Elf_Internal_Sym **all_local_syms;
00250
00251
00252 asection *sgot;
00253 asection *srelgot;
00254 asection *splt;
00255 asection *srelplt;
00256 asection *sdynbss;
00257 asection *srelbss;
00258
00259
00260
00261 bfd_vma text_segment_base;
00262 bfd_vma data_segment_base;
00263
00264
00265 unsigned int multi_subspace:1;
00266
00267
00268
00269 unsigned int has_12bit_branch:1;
00270 unsigned int has_17bit_branch:1;
00271 unsigned int has_22bit_branch:1;
00272
00273
00274 unsigned int need_plt_stub:1;
00275
00276
00277 struct sym_sec_cache sym_sec;
00278 };
00279
00280
00281 #define hppa_link_hash_table(p) \
00282 ((struct elf32_hppa_link_hash_table *) ((p)->hash))
00283
00284 #define hppa_stub_hash_lookup(table, string, create, copy) \
00285 ((struct elf32_hppa_stub_hash_entry *) \
00286 bfd_hash_lookup ((table), (string), (create), (copy)))
00287
00288
00289
00290
00291
00292 static struct bfd_hash_entry *
00293 stub_hash_newfunc (struct bfd_hash_entry *entry,
00294 struct bfd_hash_table *table,
00295 const char *string)
00296 {
00297
00298
00299 if (entry == NULL)
00300 {
00301 entry = bfd_hash_allocate (table,
00302 sizeof (struct elf32_hppa_stub_hash_entry));
00303 if (entry == NULL)
00304 return entry;
00305 }
00306
00307
00308 entry = bfd_hash_newfunc (entry, table, string);
00309 if (entry != NULL)
00310 {
00311 struct elf32_hppa_stub_hash_entry *eh;
00312
00313
00314 eh = (struct elf32_hppa_stub_hash_entry *) entry;
00315 eh->stub_sec = NULL;
00316 eh->stub_offset = 0;
00317 eh->target_value = 0;
00318 eh->target_section = NULL;
00319 eh->stub_type = hppa_stub_long_branch;
00320 eh->h = NULL;
00321 eh->id_sec = NULL;
00322 }
00323
00324 return entry;
00325 }
00326
00327
00328
00329 static struct bfd_hash_entry *
00330 hppa_link_hash_newfunc (struct bfd_hash_entry *entry,
00331 struct bfd_hash_table *table,
00332 const char *string)
00333 {
00334
00335
00336 if (entry == NULL)
00337 {
00338 entry = bfd_hash_allocate (table,
00339 sizeof (struct elf32_hppa_link_hash_entry));
00340 if (entry == NULL)
00341 return entry;
00342 }
00343
00344
00345 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
00346 if (entry != NULL)
00347 {
00348 struct elf32_hppa_link_hash_entry *eh;
00349
00350
00351 eh = (struct elf32_hppa_link_hash_entry *) entry;
00352 eh->stub_cache = NULL;
00353 eh->dyn_relocs = NULL;
00354 eh->plabel = 0;
00355 }
00356
00357 return entry;
00358 }
00359
00360
00361
00362
00363
00364 static struct bfd_link_hash_table *
00365 elf32_hppa_link_hash_table_create (bfd *abfd)
00366 {
00367 struct elf32_hppa_link_hash_table *ret;
00368 bfd_size_type amt = sizeof (*ret);
00369
00370 ret = bfd_malloc (amt);
00371 if (ret == NULL)
00372 return NULL;
00373
00374 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, hppa_link_hash_newfunc))
00375 {
00376 free (ret);
00377 return NULL;
00378 }
00379
00380
00381 if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc))
00382 return NULL;
00383
00384 ret->stub_bfd = NULL;
00385 ret->add_stub_section = NULL;
00386 ret->layout_sections_again = NULL;
00387 ret->stub_group = NULL;
00388 ret->sgot = NULL;
00389 ret->srelgot = NULL;
00390 ret->splt = NULL;
00391 ret->srelplt = NULL;
00392 ret->sdynbss = NULL;
00393 ret->srelbss = NULL;
00394 ret->text_segment_base = (bfd_vma) -1;
00395 ret->data_segment_base = (bfd_vma) -1;
00396 ret->multi_subspace = 0;
00397 ret->has_12bit_branch = 0;
00398 ret->has_17bit_branch = 0;
00399 ret->has_22bit_branch = 0;
00400 ret->need_plt_stub = 0;
00401 ret->sym_sec.abfd = NULL;
00402
00403 return &ret->elf.root;
00404 }
00405
00406
00407
00408 static void
00409 elf32_hppa_link_hash_table_free (struct bfd_link_hash_table *hash)
00410 {
00411 struct elf32_hppa_link_hash_table *ret
00412 = (struct elf32_hppa_link_hash_table *) hash;
00413
00414 bfd_hash_table_free (&ret->stub_hash_table);
00415 _bfd_generic_link_hash_table_free (hash);
00416 }
00417
00418
00419
00420 static char *
00421 hppa_stub_name (const asection *input_section,
00422 const asection *sym_sec,
00423 const struct elf32_hppa_link_hash_entry *hash,
00424 const Elf_Internal_Rela *rel)
00425 {
00426 char *stub_name;
00427 bfd_size_type len;
00428
00429 if (hash)
00430 {
00431 len = 8 + 1 + strlen (hash->elf.root.root.string) + 1 + 8 + 1;
00432 stub_name = bfd_malloc (len);
00433 if (stub_name != NULL)
00434 {
00435 sprintf (stub_name, "%08x_%s+%x",
00436 input_section->id & 0xffffffff,
00437 hash->elf.root.root.string,
00438 (int) rel->r_addend & 0xffffffff);
00439 }
00440 }
00441 else
00442 {
00443 len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
00444 stub_name = bfd_malloc (len);
00445 if (stub_name != NULL)
00446 {
00447 sprintf (stub_name, "%08x_%x:%x+%x",
00448 input_section->id & 0xffffffff,
00449 sym_sec->id & 0xffffffff,
00450 (int) ELF32_R_SYM (rel->r_info) & 0xffffffff,
00451 (int) rel->r_addend & 0xffffffff);
00452 }
00453 }
00454 return stub_name;
00455 }
00456
00457
00458
00459
00460 static struct elf32_hppa_stub_hash_entry *
00461 hppa_get_stub_entry (const asection *input_section,
00462 const asection *sym_sec,
00463 struct elf32_hppa_link_hash_entry *hash,
00464 const Elf_Internal_Rela *rel,
00465 struct elf32_hppa_link_hash_table *htab)
00466 {
00467 struct elf32_hppa_stub_hash_entry *stub_entry;
00468 const asection *id_sec;
00469
00470
00471
00472
00473
00474
00475 id_sec = htab->stub_group[input_section->id].link_sec;
00476
00477 if (hash != NULL && hash->stub_cache != NULL
00478 && hash->stub_cache->h == hash
00479 && hash->stub_cache->id_sec == id_sec)
00480 {
00481 stub_entry = hash->stub_cache;
00482 }
00483 else
00484 {
00485 char *stub_name;
00486
00487 stub_name = hppa_stub_name (id_sec, sym_sec, hash, rel);
00488 if (stub_name == NULL)
00489 return NULL;
00490
00491 stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table,
00492 stub_name, FALSE, FALSE);
00493 if (hash != NULL)
00494 hash->stub_cache = stub_entry;
00495
00496 free (stub_name);
00497 }
00498
00499 return stub_entry;
00500 }
00501
00502
00503
00504
00505 static struct elf32_hppa_stub_hash_entry *
00506 hppa_add_stub (const char *stub_name,
00507 asection *section,
00508 struct elf32_hppa_link_hash_table *htab)
00509 {
00510 asection *link_sec;
00511 asection *stub_sec;
00512 struct elf32_hppa_stub_hash_entry *stub_entry;
00513
00514 link_sec = htab->stub_group[section->id].link_sec;
00515 stub_sec = htab->stub_group[section->id].stub_sec;
00516 if (stub_sec == NULL)
00517 {
00518 stub_sec = htab->stub_group[link_sec->id].stub_sec;
00519 if (stub_sec == NULL)
00520 {
00521 size_t namelen;
00522 bfd_size_type len;
00523 char *s_name;
00524
00525 namelen = strlen (link_sec->name);
00526 len = namelen + sizeof (STUB_SUFFIX);
00527 s_name = bfd_alloc (htab->stub_bfd, len);
00528 if (s_name == NULL)
00529 return NULL;
00530
00531 memcpy (s_name, link_sec->name, namelen);
00532 memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
00533 stub_sec = (*htab->add_stub_section) (s_name, link_sec);
00534 if (stub_sec == NULL)
00535 return NULL;
00536 htab->stub_group[link_sec->id].stub_sec = stub_sec;
00537 }
00538 htab->stub_group[section->id].stub_sec = stub_sec;
00539 }
00540
00541
00542 stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, stub_name,
00543 TRUE, FALSE);
00544 if (stub_entry == NULL)
00545 {
00546 (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
00547 section->owner,
00548 stub_name);
00549 return NULL;
00550 }
00551
00552 stub_entry->stub_sec = stub_sec;
00553 stub_entry->stub_offset = 0;
00554 stub_entry->id_sec = link_sec;
00555 return stub_entry;
00556 }
00557
00558
00559
00560 static enum elf32_hppa_stub_type
00561 hppa_type_of_stub (asection *input_sec,
00562 const Elf_Internal_Rela *rel,
00563 struct elf32_hppa_link_hash_entry *hash,
00564 bfd_vma destination,
00565 struct bfd_link_info *info)
00566 {
00567 bfd_vma location;
00568 bfd_vma branch_offset;
00569 bfd_vma max_branch_offset;
00570 unsigned int r_type;
00571
00572 if (hash != NULL
00573 && hash->elf.plt.offset != (bfd_vma) -1
00574 && hash->elf.dynindx != -1
00575 && !hash->plabel
00576 && (info->shared
00577 || !hash->elf.def_regular
00578 || hash->elf.root.type == bfd_link_hash_defweak))
00579 {
00580
00581
00582 return hppa_stub_import;
00583 }
00584
00585
00586 location = (input_sec->output_offset
00587 + input_sec->output_section->vma
00588 + rel->r_offset);
00589
00590 branch_offset = destination - location - 8;
00591 r_type = ELF32_R_TYPE (rel->r_info);
00592
00593
00594
00595
00596
00597 if (r_type == (unsigned int) R_PARISC_PCREL17F)
00598 {
00599 max_branch_offset = (1 << (17-1)) << 2;
00600 }
00601 else if (r_type == (unsigned int) R_PARISC_PCREL12F)
00602 {
00603 max_branch_offset = (1 << (12-1)) << 2;
00604 }
00605 else
00606 {
00607 max_branch_offset = (1 << (22-1)) << 2;
00608 }
00609
00610 if (branch_offset + max_branch_offset >= 2*max_branch_offset)
00611 return hppa_stub_long_branch;
00612
00613 return hppa_stub_none;
00614 }
00615
00616
00617
00618
00619 #define LDIL_R1 0x20200000
00620 #define BE_SR4_R1 0xe0202002
00621
00622 #define BL_R1 0xe8200000
00623 #define ADDIL_R1 0x28200000
00624 #define DEPI_R1 0xd4201c1e
00625
00626 #define ADDIL_DP 0x2b600000
00627 #define LDW_R1_R21 0x48350000
00628 #define BV_R0_R21 0xeaa0c000
00629 #define LDW_R1_R19 0x48330000
00630
00631 #define ADDIL_R19 0x2a600000
00632 #define LDW_R1_DP 0x483b0000
00633
00634 #define LDSID_R21_R1 0x02a010a1
00635 #define MTSP_R1 0x00011820
00636 #define BE_SR0_R21 0xe2a00000
00637 #define STW_RP 0x6bc23fd1
00638
00639 #define BL22_RP 0xe800a002
00640 #define BL_RP 0xe8400002
00641 #define NOP 0x08000240
00642 #define LDW_RP 0x4bc23fd1
00643 #define LDSID_RP_R1 0x004010a1
00644 #define BE_SR0_RP 0xe0400002
00645
00646 #ifndef R19_STUBS
00647 #define R19_STUBS 1
00648 #endif
00649
00650 #if R19_STUBS
00651 #define LDW_R1_DLT LDW_R1_R19
00652 #else
00653 #define LDW_R1_DLT LDW_R1_DP
00654 #endif
00655
00656 static bfd_boolean
00657 hppa_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
00658 {
00659 struct elf32_hppa_stub_hash_entry *stub_entry;
00660 struct bfd_link_info *info;
00661 struct elf32_hppa_link_hash_table *htab;
00662 asection *stub_sec;
00663 bfd *stub_bfd;
00664 bfd_byte *loc;
00665 bfd_vma sym_value;
00666 bfd_vma insn;
00667 bfd_vma off;
00668 int val;
00669 int size;
00670
00671
00672 stub_entry = (struct elf32_hppa_stub_hash_entry *) gen_entry;
00673 info = in_arg;
00674
00675 htab = hppa_link_hash_table (info);
00676 stub_sec = stub_entry->stub_sec;
00677
00678
00679 stub_entry->stub_offset = stub_sec->size;
00680 loc = stub_sec->contents + stub_entry->stub_offset;
00681
00682 stub_bfd = stub_sec->owner;
00683
00684 switch (stub_entry->stub_type)
00685 {
00686 case hppa_stub_long_branch:
00687
00688
00689
00690
00691 sym_value = (stub_entry->target_value
00692 + stub_entry->target_section->output_offset
00693 + stub_entry->target_section->output_section->vma);
00694
00695 val = hppa_field_adjust (sym_value, 0, e_lrsel);
00696 insn = hppa_rebuild_insn ((int) LDIL_R1, val, 21);
00697 bfd_put_32 (stub_bfd, insn, loc);
00698
00699 val = hppa_field_adjust (sym_value, 0, e_rrsel) >> 2;
00700 insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17);
00701 bfd_put_32 (stub_bfd, insn, loc + 4);
00702
00703 size = 8;
00704 break;
00705
00706 case hppa_stub_long_branch_shared:
00707
00708 sym_value = (stub_entry->target_value
00709 + stub_entry->target_section->output_offset
00710 + stub_entry->target_section->output_section->vma);
00711
00712
00713 sym_value -= (stub_entry->stub_offset
00714 + stub_sec->output_offset
00715 + stub_sec->output_section->vma);
00716
00717 bfd_put_32 (stub_bfd, (bfd_vma) BL_R1, loc);
00718 val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_lrsel);
00719 insn = hppa_rebuild_insn ((int) ADDIL_R1, val, 21);
00720 bfd_put_32 (stub_bfd, insn, loc + 4);
00721
00722 val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_rrsel) >> 2;
00723 insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17);
00724 bfd_put_32 (stub_bfd, insn, loc + 8);
00725 size = 12;
00726 break;
00727
00728 case hppa_stub_import:
00729 case hppa_stub_import_shared:
00730 off = stub_entry->h->elf.plt.offset;
00731 if (off >= (bfd_vma) -2)
00732 abort ();
00733
00734 off &= ~ (bfd_vma) 1;
00735 sym_value = (off
00736 + htab->splt->output_offset
00737 + htab->splt->output_section->vma
00738 - elf_gp (htab->splt->output_section->owner));
00739
00740 insn = ADDIL_DP;
00741 #if R19_STUBS
00742 if (stub_entry->stub_type == hppa_stub_import_shared)
00743 insn = ADDIL_R19;
00744 #endif
00745 val = hppa_field_adjust (sym_value, 0, e_lrsel),
00746 insn = hppa_rebuild_insn ((int) insn, val, 21);
00747 bfd_put_32 (stub_bfd, insn, loc);
00748
00749
00750
00751
00752
00753
00754 val = hppa_field_adjust (sym_value, 0, e_rrsel);
00755 insn = hppa_rebuild_insn ((int) LDW_R1_R21, val, 14);
00756 bfd_put_32 (stub_bfd, insn, loc + 4);
00757
00758 if (htab->multi_subspace)
00759 {
00760 val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel);
00761 insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
00762 bfd_put_32 (stub_bfd, insn, loc + 8);
00763
00764 bfd_put_32 (stub_bfd, (bfd_vma) LDSID_R21_R1, loc + 12);
00765 bfd_put_32 (stub_bfd, (bfd_vma) MTSP_R1, loc + 16);
00766 bfd_put_32 (stub_bfd, (bfd_vma) BE_SR0_R21, loc + 20);
00767 bfd_put_32 (stub_bfd, (bfd_vma) STW_RP, loc + 24);
00768
00769 size = 28;
00770 }
00771 else
00772 {
00773 bfd_put_32 (stub_bfd, (bfd_vma) BV_R0_R21, loc + 8);
00774 val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel);
00775 insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
00776 bfd_put_32 (stub_bfd, insn, loc + 12);
00777
00778 size = 16;
00779 }
00780
00781 break;
00782
00783 case hppa_stub_export:
00784
00785 sym_value = (stub_entry->target_value
00786 + stub_entry->target_section->output_offset
00787 + stub_entry->target_section->output_section->vma);
00788
00789
00790 sym_value -= (stub_entry->stub_offset
00791 + stub_sec->output_offset
00792 + stub_sec->output_section->vma);
00793
00794 if (sym_value - 8 + (1 << (17 + 1)) >= (1 << (17 + 2))
00795 && (!htab->has_22bit_branch
00796 || sym_value - 8 + (1 << (22 + 1)) >= (1 << (22 + 2))))
00797 {
00798 (*_bfd_error_handler)
00799 (_("%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"),
00800 stub_entry->target_section->owner,
00801 stub_sec,
00802 (long) stub_entry->stub_offset,
00803 stub_entry->root.string);
00804 bfd_set_error (bfd_error_bad_value);
00805 return FALSE;
00806 }
00807
00808 val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_fsel) >> 2;
00809 if (!htab->has_22bit_branch)
00810 insn = hppa_rebuild_insn ((int) BL_RP, val, 17);
00811 else
00812 insn = hppa_rebuild_insn ((int) BL22_RP, val, 22);
00813 bfd_put_32 (stub_bfd, insn, loc);
00814
00815 bfd_put_32 (stub_bfd, (bfd_vma) NOP, loc + 4);
00816 bfd_put_32 (stub_bfd, (bfd_vma) LDW_RP, loc + 8);
00817 bfd_put_32 (stub_bfd, (bfd_vma) LDSID_RP_R1, loc + 12);
00818 bfd_put_32 (stub_bfd, (bfd_vma) MTSP_R1, loc + 16);
00819 bfd_put_32 (stub_bfd, (bfd_vma) BE_SR0_RP, loc + 20);
00820
00821
00822 stub_entry->h->elf.root.u.def.section = stub_sec;
00823 stub_entry->h->elf.root.u.def.value = stub_sec->size;
00824
00825 size = 24;
00826 break;
00827
00828 default:
00829 BFD_FAIL ();
00830 return FALSE;
00831 }
00832
00833 stub_sec->size += size;
00834 return TRUE;
00835 }
00836
00837 #undef LDIL_R1
00838 #undef BE_SR4_R1
00839 #undef BL_R1
00840 #undef ADDIL_R1
00841 #undef DEPI_R1
00842 #undef LDW_R1_R21
00843 #undef LDW_R1_DLT
00844 #undef LDW_R1_R19
00845 #undef ADDIL_R19
00846 #undef LDW_R1_DP
00847 #undef LDSID_R21_R1
00848 #undef MTSP_R1
00849 #undef BE_SR0_R21
00850 #undef STW_RP
00851 #undef BV_R0_R21
00852 #undef BL_RP
00853 #undef NOP
00854 #undef LDW_RP
00855 #undef LDSID_RP_R1
00856 #undef BE_SR0_RP
00857
00858
00859
00860
00861 static bfd_boolean
00862 hppa_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
00863 {
00864 struct elf32_hppa_stub_hash_entry *stub_entry;
00865 struct elf32_hppa_link_hash_table *htab;
00866 int size;
00867
00868
00869 stub_entry = (struct elf32_hppa_stub_hash_entry *) gen_entry;
00870 htab = in_arg;
00871
00872 if (stub_entry->stub_type == hppa_stub_long_branch)
00873 size = 8;
00874 else if (stub_entry->stub_type == hppa_stub_long_branch_shared)
00875 size = 12;
00876 else if (stub_entry->stub_type == hppa_stub_export)
00877 size = 24;
00878 else
00879 {
00880 if (htab->multi_subspace)
00881 size = 28;
00882 else
00883 size = 16;
00884 }
00885
00886 stub_entry->stub_sec->size += size;
00887 return TRUE;
00888 }
00889
00890
00891
00892
00893 static bfd_boolean
00894 elf32_hppa_object_p (bfd *abfd)
00895 {
00896 Elf_Internal_Ehdr * i_ehdrp;
00897 unsigned int flags;
00898
00899 i_ehdrp = elf_elfheader (abfd);
00900 if (strcmp (bfd_get_target (abfd), "elf32-hppa-linux") == 0)
00901 {
00902
00903
00904 if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX &&
00905 i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE)
00906 return FALSE;
00907 }
00908 else if (strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") == 0)
00909 {
00910
00911
00912 if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NETBSD &&
00913 i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE)
00914 return FALSE;
00915 }
00916 else
00917 {
00918 if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX)
00919 return FALSE;
00920 }
00921
00922 flags = i_ehdrp->e_flags;
00923 switch (flags & (EF_PARISC_ARCH | EF_PARISC_WIDE))
00924 {
00925 case EFA_PARISC_1_0:
00926 return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 10);
00927 case EFA_PARISC_1_1:
00928 return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 11);
00929 case EFA_PARISC_2_0:
00930 return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20);
00931 case EFA_PARISC_2_0 | EF_PARISC_WIDE:
00932 return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
00933 }
00934 return TRUE;
00935 }
00936
00937
00938
00939
00940 static bfd_boolean
00941 elf32_hppa_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
00942 {
00943 struct elf32_hppa_link_hash_table *htab;
00944 struct elf_link_hash_entry *h;
00945
00946
00947 htab = hppa_link_hash_table (info);
00948 if (htab->splt != NULL)
00949 return TRUE;
00950
00951
00952 if (! _bfd_elf_create_dynamic_sections (abfd, info))
00953 return FALSE;
00954
00955 htab->splt = bfd_get_section_by_name (abfd, ".plt");
00956 htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt");
00957
00958 htab->sgot = bfd_get_section_by_name (abfd, ".got");
00959 htab->srelgot = bfd_make_section (abfd, ".rela.got");
00960 if (htab->srelgot == NULL
00961 || ! bfd_set_section_flags (abfd, htab->srelgot,
00962 (SEC_ALLOC
00963 | SEC_LOAD
00964 | SEC_HAS_CONTENTS
00965 | SEC_IN_MEMORY
00966 | SEC_LINKER_CREATED
00967 | SEC_READONLY))
00968 || ! bfd_set_section_alignment (abfd, htab->srelgot, 2))
00969 return FALSE;
00970
00971 htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss");
00972 htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss");
00973
00974
00975
00976 h = elf_hash_table (info)->hgot;
00977 h->forced_local = 0;
00978 h->other = STV_DEFAULT;
00979 return bfd_elf_link_record_dynamic_symbol (info, h);
00980 }
00981
00982
00983
00984 static void
00985 elf32_hppa_copy_indirect_symbol (const struct elf_backend_data *bed,
00986 struct elf_link_hash_entry *dir,
00987 struct elf_link_hash_entry *ind)
00988 {
00989 struct elf32_hppa_link_hash_entry *edir, *eind;
00990
00991 edir = (struct elf32_hppa_link_hash_entry *) dir;
00992 eind = (struct elf32_hppa_link_hash_entry *) ind;
00993
00994 if (eind->dyn_relocs != NULL)
00995 {
00996 if (edir->dyn_relocs != NULL)
00997 {
00998 struct elf32_hppa_dyn_reloc_entry **pp;
00999 struct elf32_hppa_dyn_reloc_entry *p;
01000
01001 if (ind->root.type == bfd_link_hash_indirect)
01002 abort ();
01003
01004
01005
01006 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
01007 {
01008 struct elf32_hppa_dyn_reloc_entry *q;
01009
01010 for (q = edir->dyn_relocs; q != NULL; q = q->next)
01011 if (q->sec == p->sec)
01012 {
01013 #if RELATIVE_DYNRELOCS
01014 q->relative_count += p->relative_count;
01015 #endif
01016 q->count += p->count;
01017 *pp = p->next;
01018 break;
01019 }
01020 if (q == NULL)
01021 pp = &p->next;
01022 }
01023 *pp = edir->dyn_relocs;
01024 }
01025
01026 edir->dyn_relocs = eind->dyn_relocs;
01027 eind->dyn_relocs = NULL;
01028 }
01029
01030 if (ELIMINATE_COPY_RELOCS
01031 && ind->root.type != bfd_link_hash_indirect
01032 && dir->dynamic_adjusted)
01033 {
01034
01035
01036
01037 dir->ref_dynamic |= ind->ref_dynamic;
01038 dir->ref_regular |= ind->ref_regular;
01039 dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
01040 dir->needs_plt |= ind->needs_plt;
01041 }
01042 else
01043 _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
01044 }
01045
01046
01047
01048
01049
01050
01051 static bfd_boolean
01052 elf32_hppa_check_relocs (bfd *abfd,
01053 struct bfd_link_info *info,
01054 asection *sec,
01055 const Elf_Internal_Rela *relocs)
01056 {
01057 Elf_Internal_Shdr *symtab_hdr;
01058 struct elf_link_hash_entry **sym_hashes;
01059 const Elf_Internal_Rela *rel;
01060 const Elf_Internal_Rela *rel_end;
01061 struct elf32_hppa_link_hash_table *htab;
01062 asection *sreloc;
01063 asection *stubreloc;
01064
01065 if (info->relocatable)
01066 return TRUE;
01067
01068 htab = hppa_link_hash_table (info);
01069 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01070 sym_hashes = elf_sym_hashes (abfd);
01071 sreloc = NULL;
01072 stubreloc = NULL;
01073
01074 rel_end = relocs + sec->reloc_count;
01075 for (rel = relocs; rel < rel_end; rel++)
01076 {
01077 enum {
01078 NEED_GOT = 1,
01079 NEED_PLT = 2,
01080 NEED_DYNREL = 4,
01081 PLT_PLABEL = 8
01082 };
01083
01084 unsigned int r_symndx, r_type;
01085 struct elf32_hppa_link_hash_entry *h;
01086 int need_entry;
01087
01088 r_symndx = ELF32_R_SYM (rel->r_info);
01089
01090 if (r_symndx < symtab_hdr->sh_info)
01091 h = NULL;
01092 else
01093 h = ((struct elf32_hppa_link_hash_entry *)
01094 sym_hashes[r_symndx - symtab_hdr->sh_info]);
01095
01096 r_type = ELF32_R_TYPE (rel->r_info);
01097
01098 switch (r_type)
01099 {
01100 case R_PARISC_DLTIND14F:
01101 case R_PARISC_DLTIND14R:
01102 case R_PARISC_DLTIND21L:
01103
01104 need_entry = NEED_GOT;
01105 break;
01106
01107 case R_PARISC_PLABEL14R:
01108 case R_PARISC_PLABEL21L:
01109 case R_PARISC_PLABEL32:
01110
01111 if (rel->r_addend != 0)
01112 abort ();
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 need_entry = PLT_PLABEL | NEED_PLT | NEED_DYNREL;
01131 break;
01132
01133 case R_PARISC_PCREL12F:
01134 htab->has_12bit_branch = 1;
01135 goto branch_common;
01136
01137 case R_PARISC_PCREL17C:
01138 case R_PARISC_PCREL17F:
01139 htab->has_17bit_branch = 1;
01140 goto branch_common;
01141
01142 case R_PARISC_PCREL22F:
01143 htab->has_22bit_branch = 1;
01144 branch_common:
01145
01146
01147 if (h == NULL)
01148 {
01149
01150
01151
01152
01153
01154 continue;
01155 }
01156 else
01157 {
01158
01159
01160
01161
01162
01163 need_entry = NEED_PLT;
01164 if (h->elf.type == STT_PARISC_MILLI)
01165 need_entry = 0;
01166 }
01167 break;
01168
01169 case R_PARISC_SEGBASE:
01170 case R_PARISC_SEGREL32:
01171 case R_PARISC_PCREL14F:
01172 case R_PARISC_PCREL14R:
01173 case R_PARISC_PCREL17R:
01174 case R_PARISC_PCREL21L:
01175 case R_PARISC_PCREL32:
01176
01177
01178 continue;
01179
01180 case R_PARISC_DPREL14F:
01181 case R_PARISC_DPREL14R:
01182 case R_PARISC_DPREL21L:
01183 if (info->shared)
01184 {
01185 (*_bfd_error_handler)
01186 (_("%B: relocation %s can not be used when making a shared object; recompile with -fPIC"),
01187 abfd,
01188 elf_hppa_howto_table[r_type].name);
01189 bfd_set_error (bfd_error_bad_value);
01190 return FALSE;
01191 }
01192
01193
01194 case R_PARISC_DIR17F:
01195 case R_PARISC_DIR17R:
01196 case R_PARISC_DIR14F:
01197 case R_PARISC_DIR14R:
01198 case R_PARISC_DIR21L:
01199 case R_PARISC_DIR32:
01200
01201 need_entry = NEED_DYNREL;
01202 break;
01203
01204
01205
01206 case R_PARISC_GNU_VTINHERIT:
01207 if (!bfd_elf_gc_record_vtinherit (abfd, sec, &h->elf, rel->r_offset))
01208 return FALSE;
01209 continue;
01210
01211
01212
01213 case R_PARISC_GNU_VTENTRY:
01214 if (!bfd_elf_gc_record_vtentry (abfd, sec, &h->elf, rel->r_addend))
01215 return FALSE;
01216 continue;
01217
01218 default:
01219 continue;
01220 }
01221
01222
01223 if (need_entry & NEED_GOT)
01224 {
01225
01226
01227 if (htab->sgot == NULL)
01228 {
01229 if (htab->elf.dynobj == NULL)
01230 htab->elf.dynobj = abfd;
01231 if (!elf32_hppa_create_dynamic_sections (htab->elf.dynobj, info))
01232 return FALSE;
01233 }
01234
01235 if (h != NULL)
01236 {
01237 h->elf.got.refcount += 1;
01238 }
01239 else
01240 {
01241 bfd_signed_vma *local_got_refcounts;
01242
01243
01244 local_got_refcounts = elf_local_got_refcounts (abfd);
01245 if (local_got_refcounts == NULL)
01246 {
01247 bfd_size_type size;
01248
01249
01250
01251
01252
01253 size = symtab_hdr->sh_info;
01254 size *= 2 * sizeof (bfd_signed_vma);
01255 local_got_refcounts = bfd_zalloc (abfd, size);
01256 if (local_got_refcounts == NULL)
01257 return FALSE;
01258 elf_local_got_refcounts (abfd) = local_got_refcounts;
01259 }
01260 local_got_refcounts[r_symndx] += 1;
01261 }
01262 }
01263
01264 if (need_entry & NEED_PLT)
01265 {
01266
01267
01268
01269
01270
01271
01272
01273
01274 if ((sec->flags & SEC_ALLOC) != 0)
01275 {
01276 if (h != NULL)
01277 {
01278 h->elf.needs_plt = 1;
01279 h->elf.plt.refcount += 1;
01280
01281
01282
01283
01284 if (need_entry & PLT_PLABEL)
01285 h->plabel = 1;
01286 }
01287 else if (need_entry & PLT_PLABEL)
01288 {
01289 bfd_signed_vma *local_got_refcounts;
01290 bfd_signed_vma *local_plt_refcounts;
01291
01292 local_got_refcounts = elf_local_got_refcounts (abfd);
01293 if (local_got_refcounts == NULL)
01294 {
01295 bfd_size_type size;
01296
01297
01298
01299 size = symtab_hdr->sh_info;
01300 size *= 2 * sizeof (bfd_signed_vma);
01301 local_got_refcounts = bfd_zalloc (abfd, size);
01302 if (local_got_refcounts == NULL)
01303 return FALSE;
01304 elf_local_got_refcounts (abfd) = local_got_refcounts;
01305 }
01306 local_plt_refcounts = (local_got_refcounts
01307 + symtab_hdr->sh_info);
01308 local_plt_refcounts[r_symndx] += 1;
01309 }
01310 }
01311 }
01312
01313 if (need_entry & NEED_DYNREL)
01314 {
01315
01316
01317
01318 if (h != NULL && !info->shared)
01319 h->elf.non_got_ref = 1;
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349 if ((info->shared
01350 && (sec->flags & SEC_ALLOC) != 0
01351 && (IS_ABSOLUTE_RELOC (r_type)
01352 || (h != NULL
01353 && (!info->symbolic
01354 || h->elf.root.type == bfd_link_hash_defweak
01355 || !h->elf.def_regular))))
01356 || (ELIMINATE_COPY_RELOCS
01357 && !info->shared
01358 && (sec->flags & SEC_ALLOC) != 0
01359 && h != NULL
01360 && (h->elf.root.type == bfd_link_hash_defweak
01361 || !h->elf.def_regular)))
01362 {
01363 struct elf32_hppa_dyn_reloc_entry *p;
01364 struct elf32_hppa_dyn_reloc_entry **head;
01365
01366
01367
01368 if (sreloc == NULL)
01369 {
01370 char *name;
01371 bfd *dynobj;
01372
01373 name = (bfd_elf_string_from_elf_section
01374 (abfd,
01375 elf_elfheader (abfd)->e_shstrndx,
01376 elf_section_data (sec)->rel_hdr.sh_name));
01377 if (name == NULL)
01378 {
01379 (*_bfd_error_handler)
01380 (_("Could not find relocation section for %s"),
01381 sec->name);
01382 bfd_set_error (bfd_error_bad_value);
01383 return FALSE;
01384 }
01385
01386 if (htab->elf.dynobj == NULL)
01387 htab->elf.dynobj = abfd;
01388
01389 dynobj = htab->elf.dynobj;
01390 sreloc = bfd_get_section_by_name (dynobj, name);
01391 if (sreloc == NULL)
01392 {
01393 flagword flags;
01394
01395 sreloc = bfd_make_section (dynobj, name);
01396 flags = (SEC_HAS_CONTENTS | SEC_READONLY
01397 | SEC_IN_MEMORY | SEC_LINKER_CREATED);
01398 if ((sec->flags & SEC_ALLOC) != 0)
01399 flags |= SEC_ALLOC | SEC_LOAD;
01400 if (sreloc == NULL
01401 || !bfd_set_section_flags (dynobj, sreloc, flags)
01402 || !bfd_set_section_alignment (dynobj, sreloc, 2))
01403 return FALSE;
01404 }
01405
01406 elf_section_data (sec)->sreloc = sreloc;
01407 }
01408
01409
01410
01411 if (h != NULL)
01412 {
01413 head = &h->dyn_relocs;
01414 }
01415 else
01416 {
01417
01418
01419
01420
01421 asection *s;
01422 s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
01423 sec, r_symndx);
01424 if (s == NULL)
01425 return FALSE;
01426
01427 head = ((struct elf32_hppa_dyn_reloc_entry **)
01428 &elf_section_data (s)->local_dynrel);
01429 }
01430
01431 p = *head;
01432 if (p == NULL || p->sec != sec)
01433 {
01434 p = bfd_alloc (htab->elf.dynobj, sizeof *p);
01435 if (p == NULL)
01436 return FALSE;
01437 p->next = *head;
01438 *head = p;
01439 p->sec = sec;
01440 p->count = 0;
01441 #if RELATIVE_DYNRELOCS
01442 p->relative_count = 0;
01443 #endif
01444 }
01445
01446 p->count += 1;
01447 #if RELATIVE_DYNRELOCS
01448 if (!IS_ABSOLUTE_RELOC (rtype))
01449 p->relative_count += 1;
01450 #endif
01451 }
01452 }
01453 }
01454
01455 return TRUE;
01456 }
01457
01458
01459
01460
01461 static asection *
01462 elf32_hppa_gc_mark_hook (asection *sec,
01463 struct bfd_link_info *info ATTRIBUTE_UNUSED,
01464 Elf_Internal_Rela *rel,
01465 struct elf_link_hash_entry *h,
01466 Elf_Internal_Sym *sym)
01467 {
01468 if (h != NULL)
01469 {
01470 switch ((unsigned int) ELF32_R_TYPE (rel->r_info))
01471 {
01472 case R_PARISC_GNU_VTINHERIT:
01473 case R_PARISC_GNU_VTENTRY:
01474 break;
01475
01476 default:
01477 switch (h->root.type)
01478 {
01479 case bfd_link_hash_defined:
01480 case bfd_link_hash_defweak:
01481 return h->root.u.def.section;
01482
01483 case bfd_link_hash_common:
01484 return h->root.u.c.p->section;
01485
01486 default:
01487 break;
01488 }
01489 }
01490 }
01491 else
01492 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
01493
01494 return NULL;
01495 }
01496
01497
01498
01499
01500 static bfd_boolean
01501 elf32_hppa_gc_sweep_hook (bfd *abfd,
01502 struct bfd_link_info *info ATTRIBUTE_UNUSED,
01503 asection *sec,
01504 const Elf_Internal_Rela *relocs)
01505 {
01506 Elf_Internal_Shdr *symtab_hdr;
01507 struct elf_link_hash_entry **sym_hashes;
01508 bfd_signed_vma *local_got_refcounts;
01509 bfd_signed_vma *local_plt_refcounts;
01510 const Elf_Internal_Rela *rel, *relend;
01511
01512 elf_section_data (sec)->local_dynrel = NULL;
01513
01514 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01515 sym_hashes = elf_sym_hashes (abfd);
01516 local_got_refcounts = elf_local_got_refcounts (abfd);
01517 local_plt_refcounts = local_got_refcounts;
01518 if (local_plt_refcounts != NULL)
01519 local_plt_refcounts += symtab_hdr->sh_info;
01520
01521 relend = relocs + sec->reloc_count;
01522 for (rel = relocs; rel < relend; rel++)
01523 {
01524 unsigned long r_symndx;
01525 unsigned int r_type;
01526 struct elf_link_hash_entry *h = NULL;
01527
01528 r_symndx = ELF32_R_SYM (rel->r_info);
01529 if (r_symndx >= symtab_hdr->sh_info)
01530 {
01531 struct elf32_hppa_link_hash_entry *eh;
01532 struct elf32_hppa_dyn_reloc_entry **pp;
01533 struct elf32_hppa_dyn_reloc_entry *p;
01534
01535 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
01536 while (h->root.type == bfd_link_hash_indirect
01537 || h->root.type == bfd_link_hash_warning)
01538 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01539 eh = (struct elf32_hppa_link_hash_entry *) h;
01540
01541 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
01542 if (p->sec == sec)
01543 {
01544
01545 *pp = p->next;
01546 break;
01547 }
01548 }
01549
01550 r_type = ELF32_R_TYPE (rel->r_info);
01551 switch (r_type)
01552 {
01553 case R_PARISC_DLTIND14F:
01554 case R_PARISC_DLTIND14R:
01555 case R_PARISC_DLTIND21L:
01556 if (h != NULL)
01557 {
01558 if (h->got.refcount > 0)
01559 h->got.refcount -= 1;
01560 }
01561 else if (local_got_refcounts != NULL)
01562 {
01563 if (local_got_refcounts[r_symndx] > 0)
01564 local_got_refcounts[r_symndx] -= 1;
01565 }
01566 break;
01567
01568 case R_PARISC_PCREL12F:
01569 case R_PARISC_PCREL17C:
01570 case R_PARISC_PCREL17F:
01571 case R_PARISC_PCREL22F:
01572 if (h != NULL)
01573 {
01574 if (h->plt.refcount > 0)
01575 h->plt.refcount -= 1;
01576 }
01577 break;
01578
01579 case R_PARISC_PLABEL14R:
01580 case R_PARISC_PLABEL21L:
01581 case R_PARISC_PLABEL32:
01582 if (h != NULL)
01583 {
01584 if (h->plt.refcount > 0)
01585 h->plt.refcount -= 1;
01586 }
01587 else if (local_plt_refcounts != NULL)
01588 {
01589 if (local_plt_refcounts[r_symndx] > 0)
01590 local_plt_refcounts[r_symndx] -= 1;
01591 }
01592 break;
01593
01594 default:
01595 break;
01596 }
01597 }
01598
01599 return TRUE;
01600 }
01601
01602
01603
01604 static bfd_boolean
01605 elf32_hppa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
01606 {
01607 int offset;
01608 size_t size;
01609
01610 switch (note->descsz)
01611 {
01612 default:
01613 return FALSE;
01614
01615 case 396:
01616
01617 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
01618
01619
01620 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
01621
01622
01623 offset = 72;
01624 size = 320;
01625
01626 break;
01627 }
01628
01629
01630 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
01631 size, note->descpos + offset);
01632 }
01633
01634 static bfd_boolean
01635 elf32_hppa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
01636 {
01637 switch (note->descsz)
01638 {
01639 default:
01640 return FALSE;
01641
01642 case 124:
01643 elf_tdata (abfd)->core_program
01644 = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
01645 elf_tdata (abfd)->core_command
01646 = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
01647 }
01648
01649
01650
01651
01652 {
01653 char *command = elf_tdata (abfd)->core_command;
01654 int n = strlen (command);
01655
01656 if (0 < n && command[n - 1] == ' ')
01657 command[n - 1] = '\0';
01658 }
01659
01660 return TRUE;
01661 }
01662
01663
01664
01665
01666 static void
01667 elf32_hppa_hide_symbol (struct bfd_link_info *info,
01668 struct elf_link_hash_entry *h,
01669 bfd_boolean force_local)
01670 {
01671 if (force_local)
01672 {
01673 h->forced_local = 1;
01674 if (h->dynindx != -1)
01675 {
01676 h->dynindx = -1;
01677 _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
01678 h->dynstr_index);
01679 }
01680 }
01681
01682 if (! ((struct elf32_hppa_link_hash_entry *) h)->plabel)
01683 {
01684 h->needs_plt = 0;
01685 h->plt = elf_hash_table (info)->init_refcount;
01686 }
01687 }
01688
01689
01690
01691
01692
01693
01694
01695 static bfd_boolean
01696 elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
01697 struct elf_link_hash_entry *h)
01698 {
01699 struct elf32_hppa_link_hash_table *htab;
01700 asection *s;
01701 unsigned int power_of_two;
01702
01703
01704
01705 if (h->type == STT_FUNC
01706 || h->needs_plt)
01707 {
01708 if (h->plt.refcount <= 0
01709 || (h->def_regular
01710 && h->root.type != bfd_link_hash_defweak
01711 && ! ((struct elf32_hppa_link_hash_entry *) h)->plabel
01712 && (!info->shared || info->symbolic)))
01713 {
01714
01715
01716
01717
01718
01719
01720
01721
01722 h->plt.offset = (bfd_vma) -1;
01723 h->needs_plt = 0;
01724 }
01725
01726 return TRUE;
01727 }
01728 else
01729 h->plt.offset = (bfd_vma) -1;
01730
01731
01732
01733
01734 if (h->u.weakdef != NULL)
01735 {
01736 if (h->u.weakdef->root.type != bfd_link_hash_defined
01737 && h->u.weakdef->root.type != bfd_link_hash_defweak)
01738 abort ();
01739 h->root.u.def.section = h->u.weakdef->root.u.def.section;
01740 h->root.u.def.value = h->u.weakdef->root.u.def.value;
01741 if (ELIMINATE_COPY_RELOCS)
01742 h->non_got_ref = h->u.weakdef->non_got_ref;
01743 return TRUE;
01744 }
01745
01746
01747
01748
01749
01750
01751
01752
01753 if (info->shared)
01754 return TRUE;
01755
01756
01757
01758 if (!h->non_got_ref)
01759 return TRUE;
01760
01761 if (ELIMINATE_COPY_RELOCS)
01762 {
01763 struct elf32_hppa_link_hash_entry *eh;
01764 struct elf32_hppa_dyn_reloc_entry *p;
01765
01766 eh = (struct elf32_hppa_link_hash_entry *) h;
01767 for (p = eh->dyn_relocs; p != NULL; p = p->next)
01768 {
01769 s = p->sec->output_section;
01770 if (s != NULL && (s->flags & SEC_READONLY) != 0)
01771 break;
01772 }
01773
01774
01775
01776 if (p == NULL)
01777 {
01778 h->non_got_ref = 0;
01779 return TRUE;
01780 }
01781 }
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793 htab = hppa_link_hash_table (info);
01794
01795
01796
01797
01798 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
01799 {
01800 htab->srelbss->size += sizeof (Elf32_External_Rela);
01801 h->needs_copy = 1;
01802 }
01803
01804
01805
01806
01807 power_of_two = bfd_log2 (h->size);
01808 if (power_of_two > 3)
01809 power_of_two = 3;
01810
01811
01812 s = htab->sdynbss;
01813 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
01814 if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
01815 {
01816 if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
01817 return FALSE;
01818 }
01819
01820
01821 h->root.u.def.section = s;
01822 h->root.u.def.value = s->size;
01823
01824
01825 s->size += h->size;
01826
01827 return TRUE;
01828 }
01829
01830
01831
01832
01833 static bfd_boolean
01834 allocate_plt_static (struct elf_link_hash_entry *h, void *inf)
01835 {
01836 struct bfd_link_info *info;
01837 struct elf32_hppa_link_hash_table *htab;
01838 asection *s;
01839
01840 if (h->root.type == bfd_link_hash_indirect)
01841 return TRUE;
01842
01843 if (h->root.type == bfd_link_hash_warning)
01844 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01845
01846 info = inf;
01847 htab = hppa_link_hash_table (info);
01848 if (htab->elf.dynamic_sections_created
01849 && h->plt.refcount > 0)
01850 {
01851
01852
01853 if (h->dynindx == -1
01854 && !h->forced_local
01855 && h->type != STT_PARISC_MILLI)
01856 {
01857 if (! bfd_elf_link_record_dynamic_symbol (info, h))
01858 return FALSE;
01859 }
01860
01861 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
01862 {
01863
01864
01865
01866
01867 ((struct elf32_hppa_link_hash_entry *) h)->plabel = 0;
01868 }
01869 else if (((struct elf32_hppa_link_hash_entry *) h)->plabel)
01870 {
01871
01872
01873 s = htab->splt;
01874 h->plt.offset = s->size;
01875 s->size += PLT_ENTRY_SIZE;
01876 }
01877 else
01878 {
01879
01880 h->plt.offset = (bfd_vma) -1;
01881 h->needs_plt = 0;
01882 }
01883 }
01884 else
01885 {
01886 h->plt.offset = (bfd_vma) -1;
01887 h->needs_plt = 0;
01888 }
01889
01890 return TRUE;
01891 }
01892
01893
01894
01895
01896 static bfd_boolean
01897 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
01898 {
01899 struct bfd_link_info *info;
01900 struct elf32_hppa_link_hash_table *htab;
01901 asection *s;
01902 struct elf32_hppa_link_hash_entry *eh;
01903 struct elf32_hppa_dyn_reloc_entry *p;
01904
01905 if (h->root.type == bfd_link_hash_indirect)
01906 return TRUE;
01907
01908 if (h->root.type == bfd_link_hash_warning)
01909 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01910
01911 info = inf;
01912 htab = hppa_link_hash_table (info);
01913 if (htab->elf.dynamic_sections_created
01914 && h->plt.offset != (bfd_vma) -1
01915 && !((struct elf32_hppa_link_hash_entry *) h)->plabel)
01916 {
01917
01918 s = htab->splt;
01919 h->plt.offset = s->size;
01920 s->size += PLT_ENTRY_SIZE;
01921
01922
01923 htab->srelplt->size += sizeof (Elf32_External_Rela);
01924 htab->need_plt_stub = 1;
01925 }
01926
01927 if (h->got.refcount > 0)
01928 {
01929
01930
01931 if (h->dynindx == -1
01932 && !h->forced_local
01933 && h->type != STT_PARISC_MILLI)
01934 {
01935 if (! bfd_elf_link_record_dynamic_symbol (info, h))
01936 return FALSE;
01937 }
01938
01939 s = htab->sgot;
01940 h->got.offset = s->size;
01941 s->size += GOT_ENTRY_SIZE;
01942 if (htab->elf.dynamic_sections_created
01943 && (info->shared
01944 || (h->dynindx != -1
01945 && !h->forced_local)))
01946 {
01947 htab->srelgot->size += sizeof (Elf32_External_Rela);
01948 }
01949 }
01950 else
01951 h->got.offset = (bfd_vma) -1;
01952
01953 eh = (struct elf32_hppa_link_hash_entry *) h;
01954 if (eh->dyn_relocs == NULL)
01955 return TRUE;
01956
01957
01958
01959
01960
01961
01962 if (info->shared)
01963 {
01964 #if RELATIVE_DYNRELOCS
01965 if (SYMBOL_CALLS_LOCAL (info, h))
01966 {
01967 struct elf32_hppa_dyn_reloc_entry **pp;
01968
01969 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
01970 {
01971 p->count -= p->relative_count;
01972 p->relative_count = 0;
01973 if (p->count == 0)
01974 *pp = p->next;
01975 else
01976 pp = &p->next;
01977 }
01978 }
01979 #endif
01980
01981
01982
01983 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
01984 && h->root.type == bfd_link_hash_undefweak)
01985 eh->dyn_relocs = NULL;
01986 }
01987 else
01988 {
01989
01990
01991
01992 if (!h->non_got_ref
01993 && ((ELIMINATE_COPY_RELOCS
01994 && h->def_dynamic
01995 && !h->def_regular)
01996 || (htab->elf.dynamic_sections_created
01997 && (h->root.type == bfd_link_hash_undefweak
01998 || h->root.type == bfd_link_hash_undefined))))
01999 {
02000
02001
02002 if (h->dynindx == -1
02003 && !h->forced_local
02004 && h->type != STT_PARISC_MILLI)
02005 {
02006 if (! bfd_elf_link_record_dynamic_symbol (info, h))
02007 return FALSE;
02008 }
02009
02010
02011
02012 if (h->dynindx != -1)
02013 goto keep;
02014 }
02015
02016 eh->dyn_relocs = NULL;
02017 return TRUE;
02018
02019 keep: ;
02020 }
02021
02022
02023 for (p = eh->dyn_relocs; p != NULL; p = p->next)
02024 {
02025 asection *sreloc = elf_section_data (p->sec)->sreloc;
02026 sreloc->size += p->count * sizeof (Elf32_External_Rela);
02027 }
02028
02029 return TRUE;
02030 }
02031
02032
02033
02034
02035
02036
02037
02038
02039 static bfd_boolean
02040 clobber_millicode_symbols (struct elf_link_hash_entry *h,
02041 struct bfd_link_info *info)
02042 {
02043 if (h->root.type == bfd_link_hash_warning)
02044 h = (struct elf_link_hash_entry *) h->root.u.i.link;
02045
02046 if (h->type == STT_PARISC_MILLI
02047 && !h->forced_local)
02048 {
02049 elf32_hppa_hide_symbol (info, h, TRUE);
02050 }
02051 return TRUE;
02052 }
02053
02054
02055
02056 static bfd_boolean
02057 readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
02058 {
02059 struct elf32_hppa_link_hash_entry *eh;
02060 struct elf32_hppa_dyn_reloc_entry *p;
02061
02062 if (h->root.type == bfd_link_hash_warning)
02063 h = (struct elf_link_hash_entry *) h->root.u.i.link;
02064
02065 eh = (struct elf32_hppa_link_hash_entry *) h;
02066 for (p = eh->dyn_relocs; p != NULL; p = p->next)
02067 {
02068 asection *s = p->sec->output_section;
02069
02070 if (s != NULL && (s->flags & SEC_READONLY) != 0)
02071 {
02072 struct bfd_link_info *info = inf;
02073
02074 info->flags |= DF_TEXTREL;
02075
02076
02077 return FALSE;
02078 }
02079 }
02080 return TRUE;
02081 }
02082
02083
02084
02085 static bfd_boolean
02086 elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
02087 struct bfd_link_info *info)
02088 {
02089 struct elf32_hppa_link_hash_table *htab;
02090 bfd *dynobj;
02091 bfd *ibfd;
02092 asection *s;
02093 bfd_boolean relocs;
02094
02095 htab = hppa_link_hash_table (info);
02096 dynobj = htab->elf.dynobj;
02097 if (dynobj == NULL)
02098 abort ();
02099
02100 if (htab->elf.dynamic_sections_created)
02101 {
02102
02103 if (info->executable)
02104 {
02105 s = bfd_get_section_by_name (dynobj, ".interp");
02106 if (s == NULL)
02107 abort ();
02108 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
02109 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
02110 }
02111
02112
02113 elf_link_hash_traverse (&htab->elf,
02114 clobber_millicode_symbols,
02115 info);
02116 }
02117
02118
02119
02120 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
02121 {
02122 bfd_signed_vma *local_got;
02123 bfd_signed_vma *end_local_got;
02124 bfd_signed_vma *local_plt;
02125 bfd_signed_vma *end_local_plt;
02126 bfd_size_type locsymcount;
02127 Elf_Internal_Shdr *symtab_hdr;
02128 asection *srel;
02129
02130 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
02131 continue;
02132
02133 for (s = ibfd->sections; s != NULL; s = s->next)
02134 {
02135 struct elf32_hppa_dyn_reloc_entry *p;
02136
02137 for (p = ((struct elf32_hppa_dyn_reloc_entry *)
02138 elf_section_data (s)->local_dynrel);
02139 p != NULL;
02140 p = p->next)
02141 {
02142 if (!bfd_is_abs_section (p->sec)
02143 && bfd_is_abs_section (p->sec->output_section))
02144 {
02145
02146
02147
02148
02149 }
02150 else if (p->count != 0)
02151 {
02152 srel = elf_section_data (p->sec)->sreloc;
02153 srel->size += p->count * sizeof (Elf32_External_Rela);
02154 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
02155 info->flags |= DF_TEXTREL;
02156 }
02157 }
02158 }
02159
02160 local_got = elf_local_got_refcounts (ibfd);
02161 if (!local_got)
02162 continue;
02163
02164 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
02165 locsymcount = symtab_hdr->sh_info;
02166 end_local_got = local_got + locsymcount;
02167 s = htab->sgot;
02168 srel = htab->srelgot;
02169 for (; local_got < end_local_got; ++local_got)
02170 {
02171 if (*local_got > 0)
02172 {
02173 *local_got = s->size;
02174 s->size += GOT_ENTRY_SIZE;
02175 if (info->shared)
02176 srel->size += sizeof (Elf32_External_Rela);
02177 }
02178 else
02179 *local_got = (bfd_vma) -1;
02180 }
02181
02182 local_plt = end_local_got;
02183 end_local_plt = local_plt + locsymcount;
02184 if (! htab->elf.dynamic_sections_created)
02185 {
02186
02187 for (; local_plt < end_local_plt; ++local_plt)
02188 *local_plt = (bfd_vma) -1;
02189 }
02190 else
02191 {
02192 s = htab->splt;
02193 srel = htab->srelplt;
02194 for (; local_plt < end_local_plt; ++local_plt)
02195 {
02196 if (*local_plt > 0)
02197 {
02198 *local_plt = s->size;
02199 s->size += PLT_ENTRY_SIZE;
02200 if (info->shared)
02201 srel->size += sizeof (Elf32_External_Rela);
02202 }
02203 else
02204 *local_plt = (bfd_vma) -1;
02205 }
02206 }
02207 }
02208
02209
02210
02211
02212 elf_link_hash_traverse (&htab->elf, allocate_plt_static, info);
02213
02214
02215
02216 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
02217
02218
02219
02220
02221 relocs = FALSE;
02222 for (s = dynobj->sections; s != NULL; s = s->next)
02223 {
02224 if ((s->flags & SEC_LINKER_CREATED) == 0)
02225 continue;
02226
02227 if (s == htab->splt)
02228 {
02229 if (htab->need_plt_stub)
02230 {
02231
02232
02233
02234 int gotalign = bfd_section_alignment (dynobj, htab->sgot);
02235 int pltalign = bfd_section_alignment (dynobj, s);
02236 bfd_size_type mask;
02237
02238 if (gotalign > pltalign)
02239 bfd_set_section_alignment (dynobj, s, gotalign);
02240 mask = ((bfd_size_type) 1 << gotalign) - 1;
02241 s->size = (s->size + sizeof (plt_stub) + mask) & ~mask;
02242 }
02243 }
02244 else if (s == htab->sgot)
02245 ;
02246 else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
02247 {
02248 if (s->size != 0)
02249 {
02250
02251
02252 if (s != htab->srelplt)
02253 relocs = TRUE;
02254
02255
02256
02257 s->reloc_count = 0;
02258 }
02259 }
02260 else
02261 {
02262
02263 continue;
02264 }
02265
02266 if (s->size == 0)
02267 {
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277 _bfd_strip_section_from_output (info, s);
02278 continue;
02279 }
02280
02281
02282
02283 s->contents = bfd_zalloc (dynobj, s->size);
02284 if (s->contents == NULL && s->size != 0)
02285 return FALSE;
02286 }
02287
02288 if (htab->elf.dynamic_sections_created)
02289 {
02290
02291
02292
02293
02294 #define add_dynamic_entry(TAG, VAL) \
02295 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
02296
02297 if (!add_dynamic_entry (DT_PLTGOT, 0))
02298 return FALSE;
02299
02300
02301
02302
02303
02304
02305 if (!info->shared)
02306 {
02307 if (!add_dynamic_entry (DT_DEBUG, 0))
02308 return FALSE;
02309 }
02310
02311 if (htab->srelplt->size != 0)
02312 {
02313 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
02314 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
02315 || !add_dynamic_entry (DT_JMPREL, 0))
02316 return FALSE;
02317 }
02318
02319 if (relocs)
02320 {
02321 if (!add_dynamic_entry (DT_RELA, 0)
02322 || !add_dynamic_entry (DT_RELASZ, 0)
02323 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
02324 return FALSE;
02325
02326
02327
02328 if ((info->flags & DF_TEXTREL) == 0)
02329 elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
02330
02331 if ((info->flags & DF_TEXTREL) != 0)
02332 {
02333 if (!add_dynamic_entry (DT_TEXTREL, 0))
02334 return FALSE;
02335 }
02336 }
02337 }
02338 #undef add_dynamic_entry
02339
02340 return TRUE;
02341 }
02342
02343
02344
02345
02346
02347
02348
02349 int
02350 elf32_hppa_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
02351 {
02352 bfd *input_bfd;
02353 unsigned int bfd_count;
02354 int top_id, top_index;
02355 asection *section;
02356 asection **input_list, **list;
02357 bfd_size_type amt;
02358 struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
02359
02360
02361 for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
02362 input_bfd != NULL;
02363 input_bfd = input_bfd->link_next)
02364 {
02365 bfd_count += 1;
02366 for (section = input_bfd->sections;
02367 section != NULL;
02368 section = section->next)
02369 {
02370 if (top_id < section->id)
02371 top_id = section->id;
02372 }
02373 }
02374 htab->bfd_count = bfd_count;
02375
02376 amt = sizeof (struct map_stub) * (top_id + 1);
02377 htab->stub_group = bfd_zmalloc (amt);
02378 if (htab->stub_group == NULL)
02379 return -1;
02380
02381
02382
02383
02384 for (section = output_bfd->sections, top_index = 0;
02385 section != NULL;
02386 section = section->next)
02387 {
02388 if (top_index < section->index)
02389 top_index = section->index;
02390 }
02391
02392 htab->top_index = top_index;
02393 amt = sizeof (asection *) * (top_index + 1);
02394 input_list = bfd_malloc (amt);
02395 htab->input_list = input_list;
02396 if (input_list == NULL)
02397 return -1;
02398
02399
02400
02401 list = input_list + top_index;
02402 do
02403 *list = bfd_abs_section_ptr;
02404 while (list-- != input_list);
02405
02406 for (section = output_bfd->sections;
02407 section != NULL;
02408 section = section->next)
02409 {
02410 if ((section->flags & SEC_CODE) != 0)
02411 input_list[section->index] = NULL;
02412 }
02413
02414 return 1;
02415 }
02416
02417
02418
02419
02420
02421
02422 void
02423 elf32_hppa_next_input_section (struct bfd_link_info *info, asection *isec)
02424 {
02425 struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
02426
02427 if (isec->output_section->index <= htab->top_index)
02428 {
02429 asection **list = htab->input_list + isec->output_section->index;
02430 if (*list != bfd_abs_section_ptr)
02431 {
02432
02433 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
02434
02435
02436 PREV_SEC (isec) = *list;
02437 *list = isec;
02438 }
02439 }
02440 }
02441
02442
02443
02444
02445
02446
02447
02448
02449 static void
02450 group_sections (struct elf32_hppa_link_hash_table *htab,
02451 bfd_size_type stub_group_size,
02452 bfd_boolean stubs_always_before_branch)
02453 {
02454 asection **list = htab->input_list + htab->top_index;
02455 do
02456 {
02457 asection *tail = *list;
02458 if (tail == bfd_abs_section_ptr)
02459 continue;
02460 while (tail != NULL)
02461 {
02462 asection *curr;
02463 asection *prev;
02464 bfd_size_type total;
02465 bfd_boolean big_sec;
02466
02467 curr = tail;
02468 total = tail->size;
02469 big_sec = total >= stub_group_size;
02470
02471 while ((prev = PREV_SEC (curr)) != NULL
02472 && ((total += curr->output_offset - prev->output_offset)
02473 < stub_group_size))
02474 curr = prev;
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489 do
02490 {
02491 prev = PREV_SEC (tail);
02492
02493 htab->stub_group[tail->id].link_sec = curr;
02494 }
02495 while (tail != curr && (tail = prev) != NULL);
02496
02497
02498
02499
02500
02501
02502 if (!stubs_always_before_branch && !big_sec)
02503 {
02504 total = 0;
02505 while (prev != NULL
02506 && ((total += tail->output_offset - prev->output_offset)
02507 < stub_group_size))
02508 {
02509 tail = prev;
02510 prev = PREV_SEC (tail);
02511 htab->stub_group[tail->id].link_sec = curr;
02512 }
02513 }
02514 tail = prev;
02515 }
02516 }
02517 while (list-- != htab->input_list);
02518 free (htab->input_list);
02519 #undef PREV_SEC
02520 }
02521
02522
02523
02524
02525
02526 static int
02527 get_local_syms (bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *info)
02528 {
02529 unsigned int bfd_indx;
02530 Elf_Internal_Sym *local_syms, **all_local_syms;
02531 int stub_changed = 0;
02532 struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
02533
02534
02535
02536
02537 bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
02538 all_local_syms = bfd_zmalloc (amt);
02539 htab->all_local_syms = all_local_syms;
02540 if (all_local_syms == NULL)
02541 return -1;
02542
02543
02544
02545
02546 for (bfd_indx = 0;
02547 input_bfd != NULL;
02548 input_bfd = input_bfd->link_next, bfd_indx++)
02549 {
02550 Elf_Internal_Shdr *symtab_hdr;
02551
02552
02553 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
02554 if (symtab_hdr->sh_info == 0)
02555 continue;
02556
02557
02558 local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
02559 if (local_syms == NULL)
02560 {
02561 local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
02562 symtab_hdr->sh_info, 0,
02563 NULL, NULL, NULL);
02564
02565 symtab_hdr->contents = (unsigned char *) local_syms;
02566 }
02567 if (local_syms == NULL)
02568 return -1;
02569
02570 all_local_syms[bfd_indx] = local_syms;
02571
02572 if (info->shared && htab->multi_subspace)
02573 {
02574 struct elf_link_hash_entry **sym_hashes;
02575 struct elf_link_hash_entry **end_hashes;
02576 unsigned int symcount;
02577
02578 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
02579 - symtab_hdr->sh_info);
02580 sym_hashes = elf_sym_hashes (input_bfd);
02581 end_hashes = sym_hashes + symcount;
02582
02583
02584
02585 for (; sym_hashes < end_hashes; sym_hashes++)
02586 {
02587 struct elf32_hppa_link_hash_entry *hash;
02588
02589 hash = (struct elf32_hppa_link_hash_entry *) *sym_hashes;
02590
02591 while (hash->elf.root.type == bfd_link_hash_indirect
02592 || hash->elf.root.type == bfd_link_hash_warning)
02593 hash = ((struct elf32_hppa_link_hash_entry *)
02594 hash->elf.root.u.i.link);
02595
02596
02597
02598
02599 if ((hash->elf.root.type == bfd_link_hash_defined
02600 || hash->elf.root.type == bfd_link_hash_defweak)
02601 && hash->elf.type == STT_FUNC
02602 && hash->elf.root.u.def.section->output_section != NULL
02603 && (hash->elf.root.u.def.section->output_section->owner
02604 == output_bfd)
02605 && hash->elf.root.u.def.section->owner == input_bfd
02606 && hash->elf.def_regular
02607 && !hash->elf.forced_local
02608 && ELF_ST_VISIBILITY (hash->elf.other) == STV_DEFAULT)
02609 {
02610 asection *sec;
02611 const char *stub_name;
02612 struct elf32_hppa_stub_hash_entry *stub_entry;
02613
02614 sec = hash->elf.root.u.def.section;
02615 stub_name = hash->elf.root.root.string;
02616 stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table,
02617 stub_name,
02618 FALSE, FALSE);
02619 if (stub_entry == NULL)
02620 {
02621 stub_entry = hppa_add_stub (stub_name, sec, htab);
02622 if (!stub_entry)
02623 return -1;
02624
02625 stub_entry->target_value = hash->elf.root.u.def.value;
02626 stub_entry->target_section = hash->elf.root.u.def.section;
02627 stub_entry->stub_type = hppa_stub_export;
02628 stub_entry->h = hash;
02629 stub_changed = 1;
02630 }
02631 else
02632 {
02633 (*_bfd_error_handler) (_("%B: duplicate export stub %s"),
02634 input_bfd,
02635 stub_name);
02636 }
02637 }
02638 }
02639 }
02640 }
02641
02642 return stub_changed;
02643 }
02644
02645
02646
02647
02648
02649
02650
02651 bfd_boolean
02652 elf32_hppa_size_stubs
02653 (bfd *output_bfd, bfd *stub_bfd, struct bfd_link_info *info,
02654 bfd_boolean multi_subspace, bfd_signed_vma group_size,
02655 asection * (*add_stub_section) (const char *, asection *),
02656 void (*layout_sections_again) (void))
02657 {
02658 bfd_size_type stub_group_size;
02659 bfd_boolean stubs_always_before_branch;
02660 bfd_boolean stub_changed;
02661 struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
02662
02663
02664 htab->stub_bfd = stub_bfd;
02665 htab->multi_subspace = multi_subspace;
02666 htab->add_stub_section = add_stub_section;
02667 htab->layout_sections_again = layout_sections_again;
02668 stubs_always_before_branch = group_size < 0;
02669 if (group_size < 0)
02670 stub_group_size = -group_size;
02671 else
02672 stub_group_size = group_size;
02673 if (stub_group_size == 1)
02674 {
02675
02676 if (stubs_always_before_branch)
02677 {
02678 stub_group_size = 7680000;
02679 if (htab->has_17bit_branch || htab->multi_subspace)
02680 stub_group_size = 240000;
02681 if (htab->has_12bit_branch)
02682 stub_group_size = 7500;
02683 }
02684 else
02685 {
02686 stub_group_size = 6971392;
02687 if (htab->has_17bit_branch || htab->multi_subspace)
02688 stub_group_size = 217856;
02689 if (htab->has_12bit_branch)
02690 stub_group_size = 6808;
02691 }
02692 }
02693
02694 group_sections (htab, stub_group_size, stubs_always_before_branch);
02695
02696 switch (get_local_syms (output_bfd, info->input_bfds, info))
02697 {
02698 default:
02699 if (htab->all_local_syms)
02700 goto error_ret_free_local;
02701 return FALSE;
02702
02703 case 0:
02704 stub_changed = FALSE;
02705 break;
02706
02707 case 1:
02708 stub_changed = TRUE;
02709 break;
02710 }
02711
02712 while (1)
02713 {
02714 bfd *input_bfd;
02715 unsigned int bfd_indx;
02716 asection *stub_sec;
02717
02718 for (input_bfd = info->input_bfds, bfd_indx = 0;
02719 input_bfd != NULL;
02720 input_bfd = input_bfd->link_next, bfd_indx++)
02721 {
02722 Elf_Internal_Shdr *symtab_hdr;
02723 asection *section;
02724 Elf_Internal_Sym *local_syms;
02725
02726
02727 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
02728 if (symtab_hdr->sh_info == 0)
02729 continue;
02730
02731 local_syms = htab->all_local_syms[bfd_indx];
02732
02733
02734 for (section = input_bfd->sections;
02735 section != NULL;
02736 section = section->next)
02737 {
02738 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
02739
02740
02741
02742 if ((section->flags & SEC_RELOC) == 0
02743 || section->reloc_count == 0)
02744 continue;
02745
02746
02747
02748 if (section->output_section == NULL
02749 || section->output_section->owner != output_bfd)
02750 continue;
02751
02752
02753 internal_relocs
02754 = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
02755 info->keep_memory);
02756 if (internal_relocs == NULL)
02757 goto error_ret_free_local;
02758
02759
02760 irela = internal_relocs;
02761 irelaend = irela + section->reloc_count;
02762 for (; irela < irelaend; irela++)
02763 {
02764 unsigned int r_type, r_indx;
02765 enum elf32_hppa_stub_type stub_type;
02766 struct elf32_hppa_stub_hash_entry *stub_entry;
02767 asection *sym_sec;
02768 bfd_vma sym_value;
02769 bfd_vma destination;
02770 struct elf32_hppa_link_hash_entry *hash;
02771 char *stub_name;
02772 const asection *id_sec;
02773
02774 r_type = ELF32_R_TYPE (irela->r_info);
02775 r_indx = ELF32_R_SYM (irela->r_info);
02776
02777 if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
02778 {
02779 bfd_set_error (bfd_error_bad_value);
02780 error_ret_free_internal:
02781 if (elf_section_data (section)->relocs == NULL)
02782 free (internal_relocs);
02783 goto error_ret_free_local;
02784 }
02785
02786
02787 if (r_type != (unsigned int) R_PARISC_PCREL12F
02788 && r_type != (unsigned int) R_PARISC_PCREL17F
02789 && r_type != (unsigned int) R_PARISC_PCREL22F)
02790 continue;
02791
02792
02793
02794 sym_sec = NULL;
02795 sym_value = 0;
02796 destination = 0;
02797 hash = NULL;
02798 if (r_indx < symtab_hdr->sh_info)
02799 {
02800
02801 Elf_Internal_Sym *sym;
02802 Elf_Internal_Shdr *hdr;
02803
02804 sym = local_syms + r_indx;
02805 hdr = elf_elfsections (input_bfd)[sym->st_shndx];
02806 sym_sec = hdr->bfd_section;
02807 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
02808 sym_value = sym->st_value;
02809 destination = (sym_value + irela->r_addend
02810 + sym_sec->output_offset
02811 + sym_sec->output_section->vma);
02812 }
02813 else
02814 {
02815
02816 int e_indx;
02817
02818 e_indx = r_indx - symtab_hdr->sh_info;
02819 hash = ((struct elf32_hppa_link_hash_entry *)
02820 elf_sym_hashes (input_bfd)[e_indx]);
02821
02822 while (hash->elf.root.type == bfd_link_hash_indirect
02823 || hash->elf.root.type == bfd_link_hash_warning)
02824 hash = ((struct elf32_hppa_link_hash_entry *)
02825 hash->elf.root.u.i.link);
02826
02827 if (hash->elf.root.type == bfd_link_hash_defined
02828 || hash->elf.root.type == bfd_link_hash_defweak)
02829 {
02830 sym_sec = hash->elf.root.u.def.section;
02831 sym_value = hash->elf.root.u.def.value;
02832 if (sym_sec->output_section != NULL)
02833 destination = (sym_value + irela->r_addend
02834 + sym_sec->output_offset
02835 + sym_sec->output_section->vma);
02836 }
02837 else if (hash->elf.root.type == bfd_link_hash_undefweak)
02838 {
02839 if (! info->shared)
02840 continue;
02841 }
02842 else if (hash->elf.root.type == bfd_link_hash_undefined)
02843 {
02844 if (! (info->unresolved_syms_in_objects == RM_IGNORE
02845 && (ELF_ST_VISIBILITY (hash->elf.other)
02846 == STV_DEFAULT)
02847 && hash->elf.type != STT_PARISC_MILLI))
02848 continue;
02849 }
02850 else
02851 {
02852 bfd_set_error (bfd_error_bad_value);
02853 goto error_ret_free_internal;
02854 }
02855 }
02856
02857
02858 stub_type = hppa_type_of_stub (section, irela, hash,
02859 destination, info);
02860 if (stub_type == hppa_stub_none)
02861 continue;
02862
02863
02864 id_sec = htab->stub_group[section->id].link_sec;
02865
02866
02867 stub_name = hppa_stub_name (id_sec, sym_sec, hash, irela);
02868 if (!stub_name)
02869 goto error_ret_free_internal;
02870
02871 stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table,
02872 stub_name,
02873 FALSE, FALSE);
02874 if (stub_entry != NULL)
02875 {
02876
02877 free (stub_name);
02878 continue;
02879 }
02880
02881 stub_entry = hppa_add_stub (stub_name, section, htab);
02882 if (stub_entry == NULL)
02883 {
02884 free (stub_name);
02885 goto error_ret_free_internal;
02886 }
02887
02888 stub_entry->target_value = sym_value;
02889 stub_entry->target_section = sym_sec;
02890 stub_entry->stub_type = stub_type;
02891 if (info->shared)
02892 {
02893 if (stub_type == hppa_stub_import)
02894 stub_entry->stub_type = hppa_stub_import_shared;
02895 else if (stub_type == hppa_stub_long_branch)
02896 stub_entry->stub_type = hppa_stub_long_branch_shared;
02897 }
02898 stub_entry->h = hash;
02899 stub_changed = TRUE;
02900 }
02901
02902
02903 if (elf_section_data (section)->relocs == NULL)
02904 free (internal_relocs);
02905 }
02906 }
02907
02908 if (!stub_changed)
02909 break;
02910
02911
02912
02913 for (stub_sec = htab->stub_bfd->sections;
02914 stub_sec != NULL;
02915 stub_sec = stub_sec->next)
02916 stub_sec->size = 0;
02917
02918 bfd_hash_traverse (&htab->stub_hash_table, hppa_size_one_stub, htab);
02919
02920
02921 (*htab->layout_sections_again) ();
02922 stub_changed = FALSE;
02923 }
02924
02925 free (htab->all_local_syms);
02926 return TRUE;
02927
02928 error_ret_free_local:
02929 free (htab->all_local_syms);
02930 return FALSE;
02931 }
02932
02933
02934
02935
02936 bfd_boolean
02937 elf32_hppa_set_gp (bfd *abfd, struct bfd_link_info *info)
02938 {
02939 struct bfd_link_hash_entry *h;
02940 asection *sec = NULL;
02941 bfd_vma gp_val = 0;
02942 struct elf32_hppa_link_hash_table *htab;
02943
02944 htab = hppa_link_hash_table (info);
02945 h = bfd_link_hash_lookup (&htab->elf.root, "$global$", FALSE, FALSE, FALSE);
02946
02947 if (h != NULL
02948 && (h->type == bfd_link_hash_defined
02949 || h->type == bfd_link_hash_defweak))
02950 {
02951 gp_val = h->u.def.value;
02952 sec = h->u.def.section;
02953 }
02954 else
02955 {
02956 asection *splt = bfd_get_section_by_name (abfd, ".plt");
02957 asection *sgot = bfd_get_section_by_name (abfd, ".got");
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967 sec = strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") == 0
02968 ? NULL : splt;
02969 if (sec != NULL)
02970 {
02971 gp_val = sec->size;
02972 if (gp_val > 0x2000 || (sgot && sgot->size > 0x2000))
02973 {
02974 gp_val = 0x2000;
02975 }
02976 }
02977 else
02978 {
02979 sec = sgot;
02980 if (sec != NULL)
02981 {
02982 if (strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") != 0)
02983 {
02984
02985
02986 if (sec->size > 0x2000)
02987 gp_val = 0x2000;
02988 }
02989 }
02990 else
02991 {
02992
02993 sec = bfd_get_section_by_name (abfd, ".data");
02994 }
02995 }
02996
02997 if (h != NULL)
02998 {
02999 h->type = bfd_link_hash_defined;
03000 h->u.def.value = gp_val;
03001 if (sec != NULL)
03002 h->u.def.section = sec;
03003 else
03004 h->u.def.section = bfd_abs_section_ptr;
03005 }
03006 }
03007
03008 if (sec != NULL && sec->output_section != NULL)
03009 gp_val += sec->output_section->vma + sec->output_offset;
03010
03011 elf_gp (abfd) = gp_val;
03012 return TRUE;
03013 }
03014
03015
03016
03017
03018
03019
03020
03021 bfd_boolean
03022 elf32_hppa_build_stubs (struct bfd_link_info *info)
03023 {
03024 asection *stub_sec;
03025 struct bfd_hash_table *table;
03026 struct elf32_hppa_link_hash_table *htab;
03027
03028 htab = hppa_link_hash_table (info);
03029
03030 for (stub_sec = htab->stub_bfd->sections;
03031 stub_sec != NULL;
03032 stub_sec = stub_sec->next)
03033 {
03034 bfd_size_type size;
03035
03036
03037 size = stub_sec->size;
03038 stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
03039 if (stub_sec->contents == NULL && size != 0)
03040 return FALSE;
03041 stub_sec->size = 0;
03042 }
03043
03044
03045 table = &htab->stub_hash_table;
03046 bfd_hash_traverse (table, hppa_build_one_stub, info);
03047
03048 return TRUE;
03049 }
03050
03051
03052
03053 static bfd_boolean
03054 elf32_hppa_final_link (bfd *abfd, struct bfd_link_info *info)
03055 {
03056
03057 if (!bfd_elf_final_link (abfd, info))
03058 return FALSE;
03059
03060
03061
03062 return elf_hppa_sort_unwind (abfd);
03063 }
03064
03065
03066
03067 static void
03068 hppa_record_segment_addr (bfd *abfd ATTRIBUTE_UNUSED,
03069 asection *section,
03070 void *data)
03071 {
03072 struct elf32_hppa_link_hash_table *htab;
03073
03074 htab = (struct elf32_hppa_link_hash_table *) data;
03075
03076 if ((section->flags & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
03077 {
03078 bfd_vma value = section->vma - section->filepos;
03079
03080 if ((section->flags & SEC_READONLY) != 0)
03081 {
03082 if (value < htab->text_segment_base)
03083 htab->text_segment_base = value;
03084 }
03085 else
03086 {
03087 if (value < htab->data_segment_base)
03088 htab->data_segment_base = value;
03089 }
03090 }
03091 }
03092
03093
03094
03095 static bfd_reloc_status_type
03096 final_link_relocate (asection *input_section,
03097 bfd_byte *contents,
03098 const Elf_Internal_Rela *rel,
03099 bfd_vma value,
03100 struct elf32_hppa_link_hash_table *htab,
03101 asection *sym_sec,
03102 struct elf32_hppa_link_hash_entry *h,
03103 struct bfd_link_info *info)
03104 {
03105 int insn;
03106 unsigned int r_type = ELF32_R_TYPE (rel->r_info);
03107 unsigned int orig_r_type = r_type;
03108 reloc_howto_type *howto = elf_hppa_howto_table + r_type;
03109 int r_format = howto->bitsize;
03110 enum hppa_reloc_field_selector_type_alt r_field;
03111 bfd *input_bfd = input_section->owner;
03112 bfd_vma offset = rel->r_offset;
03113 bfd_vma max_branch_offset = 0;
03114 bfd_byte *hit_data = contents + offset;
03115 bfd_signed_vma addend = rel->r_addend;
03116 bfd_vma location;
03117 struct elf32_hppa_stub_hash_entry *stub_entry = NULL;
03118 int val;
03119
03120 if (r_type == R_PARISC_NONE)
03121 return bfd_reloc_ok;
03122
03123 insn = bfd_get_32 (input_bfd, hit_data);
03124
03125
03126 location = (offset +
03127 input_section->output_offset +
03128 input_section->output_section->vma);
03129
03130
03131
03132 if (!info->shared)
03133 {
03134 switch (r_type)
03135 {
03136 case R_PARISC_DLTIND21L:
03137 r_type = R_PARISC_DPREL21L;
03138 break;
03139
03140 case R_PARISC_DLTIND14R:
03141 r_type = R_PARISC_DPREL14R;
03142 break;
03143
03144 case R_PARISC_DLTIND14F:
03145 r_type = R_PARISC_DPREL14F;
03146 break;
03147 }
03148 }
03149
03150 switch (r_type)
03151 {
03152 case R_PARISC_PCREL12F:
03153 case R_PARISC_PCREL17F:
03154 case R_PARISC_PCREL22F:
03155
03156
03157 if (sym_sec == NULL
03158 || sym_sec->output_section == NULL
03159 || (h != NULL
03160 && h->elf.plt.offset != (bfd_vma) -1
03161 && h->elf.dynindx != -1
03162 && !h->plabel
03163 && (info->shared
03164 || !h->elf.def_regular
03165 || h->elf.root.type == bfd_link_hash_defweak)))
03166 {
03167 stub_entry = hppa_get_stub_entry (input_section, sym_sec,
03168 h, rel, htab);
03169 if (stub_entry != NULL)
03170 {
03171 value = (stub_entry->stub_offset
03172 + stub_entry->stub_sec->output_offset
03173 + stub_entry->stub_sec->output_section->vma);
03174 addend = 0;
03175 }
03176 else if (sym_sec == NULL && h != NULL
03177 && h->elf.root.type == bfd_link_hash_undefweak)
03178 {
03179
03180
03181
03182
03183
03184 value = location;
03185 addend = 8;
03186 }
03187 else
03188 return bfd_reloc_undefined;
03189 }
03190
03191
03192 case R_PARISC_PCREL21L:
03193 case R_PARISC_PCREL17C:
03194 case R_PARISC_PCREL17R:
03195 case R_PARISC_PCREL14R:
03196 case R_PARISC_PCREL14F:
03197 case R_PARISC_PCREL32:
03198
03199 value -= location;
03200 addend -= 8;
03201 break;
03202
03203 case R_PARISC_DPREL21L:
03204 case R_PARISC_DPREL14R:
03205 case R_PARISC_DPREL14F:
03206
03207
03208
03209
03210
03211 if (orig_r_type == R_PARISC_DLTIND21L)
03212 {
03213
03214
03215
03216
03217 if ((insn & 0xfc000000) == ((int) OP_ADDIL << 26))
03218 insn = ADDIL_DP;
03219 else
03220
03221
03222
03223 (*_bfd_error_handler)
03224 (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"),
03225 input_bfd,
03226 input_section,
03227 (long) rel->r_offset,
03228 howto->name,
03229 insn);
03230 }
03231 else if (orig_r_type == R_PARISC_DLTIND14F)
03232 {
03233
03234
03235 insn = (insn & 0xfc1ffff) | (27 << 21);
03236 }
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246 if (sym_sec == NULL || (sym_sec->flags & SEC_CODE) != 0)
03247 {
03248 if ((insn & ((0x3f << 26) | (0x1f << 21)))
03249 == (((int) OP_ADDIL << 26) | (27 << 21)))
03250 {
03251 insn &= ~ (0x1f << 21);
03252 }
03253
03254
03255 break;
03256 }
03257
03258
03259 case R_PARISC_DLTIND21L:
03260 case R_PARISC_DLTIND14R:
03261 case R_PARISC_DLTIND14F:
03262 value -= elf_gp (input_section->output_section->owner);
03263 break;
03264
03265 case R_PARISC_SEGREL32:
03266 if ((sym_sec->flags & SEC_CODE) != 0)
03267 value -= htab->text_segment_base;
03268 else
03269 value -= htab->data_segment_base;
03270 break;
03271
03272 default:
03273 break;
03274 }
03275
03276 switch (r_type)
03277 {
03278 case R_PARISC_DIR32:
03279 case R_PARISC_DIR14F:
03280 case R_PARISC_DIR17F:
03281 case R_PARISC_PCREL17C:
03282 case R_PARISC_PCREL14F:
03283 case R_PARISC_PCREL32:
03284 case R_PARISC_DPREL14F:
03285 case R_PARISC_PLABEL32:
03286 case R_PARISC_DLTIND14F:
03287 case R_PARISC_SEGBASE:
03288 case R_PARISC_SEGREL32:
03289 r_field = e_fsel;
03290 break;
03291
03292 case R_PARISC_DLTIND21L:
03293 case R_PARISC_PCREL21L:
03294 case R_PARISC_PLABEL21L:
03295 r_field = e_lsel;
03296 break;
03297
03298 case R_PARISC_DIR21L:
03299 case R_PARISC_DPREL21L:
03300 r_field = e_lrsel;
03301 break;
03302
03303 case R_PARISC_PCREL17R:
03304 case R_PARISC_PCREL14R:
03305 case R_PARISC_PLABEL14R:
03306 case R_PARISC_DLTIND14R:
03307 r_field = e_rsel;
03308 break;
03309
03310 case R_PARISC_DIR17R:
03311 case R_PARISC_DIR14R:
03312 case R_PARISC_DPREL14R:
03313 r_field = e_rrsel;
03314 break;
03315
03316 case R_PARISC_PCREL12F:
03317 case R_PARISC_PCREL17F:
03318 case R_PARISC_PCREL22F:
03319 r_field = e_fsel;
03320
03321 if (r_type == (unsigned int) R_PARISC_PCREL17F)
03322 {
03323 max_branch_offset = (1 << (17-1)) << 2;
03324 }
03325 else if (r_type == (unsigned int) R_PARISC_PCREL12F)
03326 {
03327 max_branch_offset = (1 << (12-1)) << 2;
03328 }
03329 else
03330 {
03331 max_branch_offset = (1 << (22-1)) << 2;
03332 }
03333
03334
03335
03336
03337 if (sym_sec == NULL)
03338 break;
03339
03340
03341
03342 if (value + addend + max_branch_offset >= 2*max_branch_offset)
03343 {
03344 stub_entry = hppa_get_stub_entry (input_section, sym_sec,
03345 h, rel, htab);
03346 if (stub_entry == NULL)
03347 return bfd_reloc_undefined;
03348
03349
03350
03351 value = (stub_entry->stub_offset
03352 + stub_entry->stub_sec->output_offset
03353 + stub_entry->stub_sec->output_section->vma
03354 - location);
03355 addend = -8;
03356 }
03357 break;
03358
03359
03360 default:
03361 return bfd_reloc_notsupported;
03362 }
03363
03364
03365 if (max_branch_offset != 0
03366 && value + addend + max_branch_offset >= 2*max_branch_offset)
03367 {
03368 (*_bfd_error_handler)
03369 (_("%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"),
03370 input_bfd,
03371 input_section,
03372 (long) rel->r_offset,
03373 stub_entry->root.string);
03374 bfd_set_error (bfd_error_bad_value);
03375 return bfd_reloc_notsupported;
03376 }
03377
03378 val = hppa_field_adjust (value, addend, r_field);
03379
03380 switch (r_type)
03381 {
03382 case R_PARISC_PCREL12F:
03383 case R_PARISC_PCREL17C:
03384 case R_PARISC_PCREL17F:
03385 case R_PARISC_PCREL17R:
03386 case R_PARISC_PCREL22F:
03387 case R_PARISC_DIR17F:
03388 case R_PARISC_DIR17R:
03389
03390
03391
03392
03393 val >>= 2;
03394 break;
03395
03396 default:
03397 break;
03398 }
03399
03400 insn = hppa_rebuild_insn (insn, val, r_format);
03401
03402
03403 bfd_put_32 (input_bfd, (bfd_vma) insn, hit_data);
03404 return bfd_reloc_ok;
03405 }
03406
03407
03408
03409 static bfd_boolean
03410 elf32_hppa_relocate_section (bfd *output_bfd,
03411 struct bfd_link_info *info,
03412 bfd *input_bfd,
03413 asection *input_section,
03414 bfd_byte *contents,
03415 Elf_Internal_Rela *relocs,
03416 Elf_Internal_Sym *local_syms,
03417 asection **local_sections)
03418 {
03419 bfd_vma *local_got_offsets;
03420 struct elf32_hppa_link_hash_table *htab;
03421 Elf_Internal_Shdr *symtab_hdr;
03422 Elf_Internal_Rela *rel;
03423 Elf_Internal_Rela *relend;
03424
03425 if (info->relocatable)
03426 return TRUE;
03427
03428 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
03429
03430 htab = hppa_link_hash_table (info);
03431 local_got_offsets = elf_local_got_offsets (input_bfd);
03432
03433 rel = relocs;
03434 relend = relocs + input_section->reloc_count;
03435 for (; rel < relend; rel++)
03436 {
03437 unsigned int r_type;
03438 reloc_howto_type *howto;
03439 unsigned int r_symndx;
03440 struct elf32_hppa_link_hash_entry *h;
03441 Elf_Internal_Sym *sym;
03442 asection *sym_sec;
03443 bfd_vma relocation;
03444 bfd_reloc_status_type r;
03445 const char *sym_name;
03446 bfd_boolean plabel;
03447 bfd_boolean warned_undef;
03448
03449 r_type = ELF32_R_TYPE (rel->r_info);
03450 if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
03451 {
03452 bfd_set_error (bfd_error_bad_value);
03453 return FALSE;
03454 }
03455 if (r_type == (unsigned int) R_PARISC_GNU_VTENTRY
03456 || r_type == (unsigned int) R_PARISC_GNU_VTINHERIT)
03457 continue;
03458
03459
03460 r_symndx = ELF32_R_SYM (rel->r_info);
03461 h = NULL;
03462 sym = NULL;
03463 sym_sec = NULL;
03464 warned_undef = FALSE;
03465 if (r_symndx < symtab_hdr->sh_info)
03466 {
03467
03468 sym = local_syms + r_symndx;
03469 sym_sec = local_sections[r_symndx];
03470 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sym_sec, rel);
03471 }
03472 else
03473 {
03474 struct elf_link_hash_entry *hh;
03475 bfd_boolean unresolved_reloc;
03476 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
03477
03478 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
03479 r_symndx, symtab_hdr, sym_hashes,
03480 hh, sym_sec, relocation,
03481 unresolved_reloc, warned_undef);
03482
03483 if (relocation == 0
03484 && hh->root.type != bfd_link_hash_defined
03485 && hh->root.type != bfd_link_hash_defweak
03486 && hh->root.type != bfd_link_hash_undefweak)
03487 {
03488 if (info->unresolved_syms_in_objects == RM_IGNORE
03489 && ELF_ST_VISIBILITY (hh->other) == STV_DEFAULT
03490 && hh->type == STT_PARISC_MILLI)
03491 {
03492 if (! info->callbacks->undefined_symbol
03493 (info, hh->root.root.string, input_bfd,
03494 input_section, rel->r_offset, FALSE))
03495 return FALSE;
03496 warned_undef = TRUE;
03497 }
03498 }
03499 h = (struct elf32_hppa_link_hash_entry *) hh;
03500 }
03501
03502
03503
03504
03505 plabel = 0;
03506 switch (r_type)
03507 {
03508 case R_PARISC_DLTIND14F:
03509 case R_PARISC_DLTIND14R:
03510 case R_PARISC_DLTIND21L:
03511 {
03512 bfd_vma off;
03513 bfd_boolean do_got = 0;
03514
03515
03516
03517 if (h != NULL)
03518 {
03519 bfd_boolean dyn;
03520
03521 off = h->elf.got.offset;
03522 dyn = htab->elf.dynamic_sections_created;
03523 if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
03524 &h->elf))
03525 {
03526
03527
03528
03529
03530
03531
03532 if ((off & 1) != 0)
03533 off &= ~1;
03534 else
03535 {
03536 h->elf.got.offset |= 1;
03537 do_got = 1;
03538 }
03539 }
03540 }
03541 else
03542 {
03543
03544 if (local_got_offsets == NULL)
03545 abort ();
03546
03547 off = local_got_offsets[r_symndx];
03548
03549
03550
03551
03552 if ((off & 1) != 0)
03553 off &= ~1;
03554 else
03555 {
03556 local_got_offsets[r_symndx] |= 1;
03557 do_got = 1;
03558 }
03559 }
03560
03561 if (do_got)
03562 {
03563 if (info->shared)
03564 {
03565
03566
03567
03568 Elf_Internal_Rela outrel;
03569 bfd_byte *loc;
03570 asection *s = htab->srelgot;
03571
03572 outrel.r_offset = (off
03573 + htab->sgot->output_offset
03574 + htab->sgot->output_section->vma);
03575 outrel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
03576 outrel.r_addend = relocation;
03577 loc = s->contents;
03578 loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
03579 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
03580 }
03581 else
03582 bfd_put_32 (output_bfd, relocation,
03583 htab->sgot->contents + off);
03584 }
03585
03586 if (off >= (bfd_vma) -2)
03587 abort ();
03588
03589
03590 relocation = (off
03591 + htab->sgot->output_offset
03592 + htab->sgot->output_section->vma);
03593 }
03594 break;
03595
03596 case R_PARISC_SEGREL32:
03597
03598
03599 if (htab->text_segment_base == (bfd_vma) -1)
03600 bfd_map_over_sections (output_bfd, hppa_record_segment_addr, htab);
03601 break;
03602
03603 case R_PARISC_PLABEL14R:
03604 case R_PARISC_PLABEL21L:
03605 case R_PARISC_PLABEL32:
03606 if (htab->elf.dynamic_sections_created)
03607 {
03608 bfd_vma off;
03609 bfd_boolean do_plt = 0;
03610
03611
03612
03613 if (h != NULL)
03614 {
03615 off = h->elf.plt.offset;
03616 if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared,
03617 &h->elf))
03618 {
03619
03620
03621
03622 if ((off & 1) != 0)
03623 off &= ~1;
03624 else
03625 {
03626 h->elf.plt.offset |= 1;
03627 do_plt = 1;
03628 }
03629 }
03630 }
03631 else
03632 {
03633 bfd_vma *local_plt_offsets;
03634
03635 if (local_got_offsets == NULL)
03636 abort ();
03637
03638 local_plt_offsets = local_got_offsets + symtab_hdr->sh_info;
03639 off = local_plt_offsets[r_symndx];
03640
03641
03642
03643
03644 if ((off & 1) != 0)
03645 off &= ~1;
03646 else
03647 {
03648 local_plt_offsets[r_symndx] |= 1;
03649 do_plt = 1;
03650 }
03651 }
03652
03653 if (do_plt)
03654 {
03655 if (info->shared)
03656 {
03657
03658
03659 Elf_Internal_Rela outrel;
03660 bfd_byte *loc;
03661 asection *s = htab->srelplt;
03662
03663 outrel.r_offset = (off
03664 + htab->splt->output_offset
03665 + htab->splt->output_section->vma);
03666 outrel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT);
03667 outrel.r_addend = relocation;
03668 loc = s->contents;
03669 loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
03670 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
03671 }
03672 else
03673 {
03674 bfd_put_32 (output_bfd,
03675 relocation,
03676 htab->splt->contents + off);
03677 bfd_put_32 (output_bfd,
03678 elf_gp (htab->splt->output_section->owner),
03679 htab->splt->contents + off + 4);
03680 }
03681 }
03682
03683 if (off >= (bfd_vma) -2)
03684 abort ();
03685
03686
03687
03688
03689
03690
03691
03692 if (h == NULL
03693 || (h->elf.root.type != bfd_link_hash_undefweak
03694 && h->elf.root.type != bfd_link_hash_undefined))
03695 {
03696 relocation = (off
03697 + htab->splt->output_offset
03698 + htab->splt->output_section->vma
03699 + 2);
03700 }
03701 plabel = 1;
03702 }
03703
03704
03705 case R_PARISC_DIR17F:
03706 case R_PARISC_DIR17R:
03707 case R_PARISC_DIR14F:
03708 case R_PARISC_DIR14R:
03709 case R_PARISC_DIR21L:
03710 case R_PARISC_DPREL14F:
03711 case R_PARISC_DPREL14R:
03712 case R_PARISC_DPREL21L:
03713 case R_PARISC_DIR32:
03714
03715
03716
03717 if (r_symndx == 0
03718 || (input_section->flags & SEC_ALLOC) == 0)
03719 break;
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733 if ((info->shared
03734 && (h == NULL
03735 || ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT
03736 || h->elf.root.type != bfd_link_hash_undefweak)
03737 && (IS_ABSOLUTE_RELOC (r_type)
03738 || !SYMBOL_CALLS_LOCAL (info, &h->elf)))
03739 || (!info->shared
03740 && h != NULL
03741 && h->elf.dynindx != -1
03742 && !h->elf.non_got_ref
03743 && ((ELIMINATE_COPY_RELOCS
03744 && h->elf.def_dynamic
03745 && !h->elf.def_regular)
03746 || h->elf.root.type == bfd_link_hash_undefweak
03747 || h->elf.root.type == bfd_link_hash_undefined)))
03748 {
03749 Elf_Internal_Rela outrel;
03750 bfd_boolean skip;
03751 asection *sreloc;
03752 bfd_byte *loc;
03753
03754
03755
03756
03757
03758 outrel.r_addend = rel->r_addend;
03759 outrel.r_offset =
03760 _bfd_elf_section_offset (output_bfd, info, input_section,
03761 rel->r_offset);
03762 skip = (outrel.r_offset == (bfd_vma) -1
03763 || outrel.r_offset == (bfd_vma) -2);
03764 outrel.r_offset += (input_section->output_offset
03765 + input_section->output_section->vma);
03766
03767 if (skip)
03768 {
03769 memset (&outrel, 0, sizeof (outrel));
03770 }
03771 else if (h != NULL
03772 && h->elf.dynindx != -1
03773 && (plabel
03774 || !IS_ABSOLUTE_RELOC (r_type)
03775 || !info->shared
03776 || !info->symbolic
03777 || !h->elf.def_regular))
03778 {
03779 outrel.r_info = ELF32_R_INFO (h->elf.dynindx, r_type);
03780 }
03781 else
03782 {
03783 int indx = 0;
03784
03785
03786 outrel.r_addend += relocation;
03787
03788
03789
03790
03791
03792
03793
03794 if (! plabel
03795 && sym_sec != NULL
03796 && sym_sec->output_section != NULL
03797 && ! bfd_is_abs_section (sym_sec))
03798 {
03799
03800
03801 if (bfd_is_abs_section (sym_sec->output_section))
03802 break;
03803
03804 indx = elf_section_data (sym_sec->output_section)->dynindx;
03805
03806
03807
03808
03809 outrel.r_addend -= sym_sec->output_section->vma;
03810 }
03811
03812 outrel.r_info = ELF32_R_INFO (indx, r_type);
03813 }
03814 sreloc = elf_section_data (input_section)->sreloc;
03815 if (sreloc == NULL)
03816 abort ();
03817
03818 loc = sreloc->contents;
03819 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
03820 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
03821 }
03822 break;
03823
03824 default:
03825 break;
03826 }
03827
03828 r = final_link_relocate (input_section, contents, rel, relocation,
03829 htab, sym_sec, h, info);
03830
03831 if (r == bfd_reloc_ok)
03832 continue;
03833
03834 if (h != NULL)
03835 sym_name = h->elf.root.root.string;
03836 else
03837 {
03838 sym_name = bfd_elf_string_from_elf_section (input_bfd,
03839 symtab_hdr->sh_link,
03840 sym->st_name);
03841 if (sym_name == NULL)
03842 return FALSE;
03843 if (*sym_name == '\0')
03844 sym_name = bfd_section_name (input_bfd, sym_sec);
03845 }
03846
03847 howto = elf_hppa_howto_table + r_type;
03848
03849 if (r == bfd_reloc_undefined || r == bfd_reloc_notsupported)
03850 {
03851 if (r == bfd_reloc_notsupported || !warned_undef)
03852 {
03853 (*_bfd_error_handler)
03854 (_("%B(%A+0x%lx): cannot handle %s for %s"),
03855 input_bfd,
03856 input_section,
03857 (long) rel->r_offset,
03858 howto->name,
03859 sym_name);
03860 bfd_set_error (bfd_error_bad_value);
03861 return FALSE;
03862 }
03863 }
03864 else
03865 {
03866 if (!((*info->callbacks->reloc_overflow)
03867 (info, (h ? &h->elf.root : NULL), sym_name, howto->name,
03868 (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
03869 return FALSE;
03870 }
03871 }
03872
03873 return TRUE;
03874 }
03875
03876
03877
03878
03879 static bfd_boolean
03880 elf32_hppa_finish_dynamic_symbol (bfd *output_bfd,
03881 struct bfd_link_info *info,
03882 struct elf_link_hash_entry *h,
03883 Elf_Internal_Sym *sym)
03884 {
03885 struct elf32_hppa_link_hash_table *htab;
03886 Elf_Internal_Rela rel;
03887 bfd_byte *loc;
03888
03889 htab = hppa_link_hash_table (info);
03890
03891 if (h->plt.offset != (bfd_vma) -1)
03892 {
03893 bfd_vma value;
03894
03895 if (h->plt.offset & 1)
03896 abort ();
03897
03898
03899
03900
03901
03902
03903
03904
03905 value = 0;
03906 if (h->root.type == bfd_link_hash_defined
03907 || h->root.type == bfd_link_hash_defweak)
03908 {
03909 value = h->root.u.def.value;
03910 if (h->root.u.def.section->output_section != NULL)
03911 value += (h->root.u.def.section->output_offset
03912 + h->root.u.def.section->output_section->vma);
03913 }
03914
03915
03916 rel.r_offset = (h->plt.offset
03917 + htab->splt->output_offset
03918 + htab->splt->output_section->vma);
03919 if (h->dynindx != -1)
03920 {
03921 rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_IPLT);
03922 rel.r_addend = 0;
03923 }
03924 else
03925 {
03926
03927
03928 rel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT);
03929 rel.r_addend = value;
03930 }
03931
03932 loc = htab->srelplt->contents;
03933 loc += htab->srelplt->reloc_count++ * sizeof (Elf32_External_Rela);
03934 bfd_elf32_swap_reloca_out (htab->splt->output_section->owner, &rel, loc);
03935
03936 if (!h->def_regular)
03937 {
03938
03939
03940 sym->st_shndx = SHN_UNDEF;
03941 }
03942 }
03943
03944 if (h->got.offset != (bfd_vma) -1)
03945 {
03946
03947
03948
03949 rel.r_offset = ((h->got.offset &~ (bfd_vma) 1)
03950 + htab->sgot->output_offset
03951 + htab->sgot->output_section->vma);
03952
03953
03954
03955
03956
03957
03958 if (info->shared
03959 && (info->symbolic || h->dynindx == -1)
03960 && h->def_regular)
03961 {
03962 rel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
03963 rel.r_addend = (h->root.u.def.value
03964 + h->root.u.def.section->output_offset
03965 + h->root.u.def.section->output_section->vma);
03966 }
03967 else
03968 {
03969 if ((h->got.offset & 1) != 0)
03970 abort ();
03971 bfd_put_32 (output_bfd, 0, htab->sgot->contents + h->got.offset);
03972 rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_DIR32);
03973 rel.r_addend = 0;
03974 }
03975
03976 loc = htab->srelgot->contents;
03977 loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
03978 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
03979 }
03980
03981 if (h->needs_copy)
03982 {
03983 asection *s;
03984
03985
03986
03987 if (! (h->dynindx != -1
03988 && (h->root.type == bfd_link_hash_defined
03989 || h->root.type == bfd_link_hash_defweak)))
03990 abort ();
03991
03992 s = htab->srelbss;
03993
03994 rel.r_offset = (h->root.u.def.value
03995 + h->root.u.def.section->output_offset
03996 + h->root.u.def.section->output_section->vma);
03997 rel.r_addend = 0;
03998 rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_COPY);
03999 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
04000 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
04001 }
04002
04003
04004 if (h->root.root.string[0] == '_'
04005 && (strcmp (h->root.root.string, "_DYNAMIC") == 0
04006 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0))
04007 {
04008 sym->st_shndx = SHN_ABS;
04009 }
04010
04011 return TRUE;
04012 }
04013
04014
04015
04016
04017 static enum elf_reloc_type_class
04018 elf32_hppa_reloc_type_class (const Elf_Internal_Rela *rela)
04019 {
04020 if (ELF32_R_SYM (rela->r_info) == 0)
04021 return reloc_class_relative;
04022
04023 switch ((int) ELF32_R_TYPE (rela->r_info))
04024 {
04025 case R_PARISC_IPLT:
04026 return reloc_class_plt;
04027 case R_PARISC_COPY:
04028 return reloc_class_copy;
04029 default:
04030 return reloc_class_normal;
04031 }
04032 }
04033
04034
04035
04036 static bfd_boolean
04037 elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
04038 struct bfd_link_info *info)
04039 {
04040 bfd *dynobj;
04041 struct elf32_hppa_link_hash_table *htab;
04042 asection *sdyn;
04043
04044 htab = hppa_link_hash_table (info);
04045 dynobj = htab->elf.dynobj;
04046
04047 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
04048
04049 if (htab->elf.dynamic_sections_created)
04050 {
04051 Elf32_External_Dyn *dyncon, *dynconend;
04052
04053 if (sdyn == NULL)
04054 abort ();
04055
04056 dyncon = (Elf32_External_Dyn *) sdyn->contents;
04057 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
04058 for (; dyncon < dynconend; dyncon++)
04059 {
04060 Elf_Internal_Dyn dyn;
04061 asection *s;
04062
04063 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
04064
04065 switch (dyn.d_tag)
04066 {
04067 default:
04068 continue;
04069
04070 case DT_PLTGOT:
04071
04072 dyn.d_un.d_ptr = elf_gp (output_bfd);
04073 break;
04074
04075 case DT_JMPREL:
04076 s = htab->srelplt;
04077 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
04078 break;
04079
04080 case DT_PLTRELSZ:
04081 s = htab->srelplt;
04082 dyn.d_un.d_val = s->size;
04083 break;
04084
04085 case DT_RELASZ:
04086
04087
04088 s = htab->srelplt;
04089 if (s == NULL)
04090 continue;
04091 dyn.d_un.d_val -= s->size;
04092 break;
04093
04094 case DT_RELA:
04095
04096
04097
04098 s = htab->srelplt;
04099 if (s == NULL)
04100 continue;
04101 if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
04102 continue;
04103 dyn.d_un.d_ptr += s->size;
04104 break;
04105 }
04106
04107 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
04108 }
04109 }
04110
04111 if (htab->sgot != NULL && htab->sgot->size != 0)
04112 {
04113
04114
04115 bfd_put_32 (output_bfd,
04116 sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0,
04117 htab->sgot->contents);
04118
04119
04120 memset (htab->sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
04121
04122
04123 elf_section_data (htab->sgot->output_section)
04124 ->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
04125 }
04126
04127 if (htab->splt != NULL && htab->splt->size != 0)
04128 {
04129
04130 elf_section_data (htab->splt->output_section)
04131 ->this_hdr.sh_entsize = PLT_ENTRY_SIZE;
04132
04133 if (htab->need_plt_stub)
04134 {
04135
04136 memcpy (htab->splt->contents
04137 + htab->splt->size - sizeof (plt_stub),
04138 plt_stub, sizeof (plt_stub));
04139
04140 if ((htab->splt->output_offset
04141 + htab->splt->output_section->vma
04142 + htab->splt->size)
04143 != (htab->sgot->output_offset
04144 + htab->sgot->output_section->vma))
04145 {
04146 (*_bfd_error_handler)
04147 (_(".got section not immediately after .plt section"));
04148 return FALSE;
04149 }
04150 }
04151 }
04152
04153 return TRUE;
04154 }
04155
04156
04157
04158 static void
04159 elf32_hppa_post_process_headers (bfd *abfd,
04160 struct bfd_link_info *info ATTRIBUTE_UNUSED)
04161 {
04162 Elf_Internal_Ehdr * i_ehdrp;
04163
04164 i_ehdrp = elf_elfheader (abfd);
04165
04166 if (strcmp (bfd_get_target (abfd), "elf32-hppa-linux") == 0)
04167 {
04168 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX;
04169 }
04170 else if (strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") == 0)
04171 {
04172 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_NETBSD;
04173 }
04174 else
04175 {
04176 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
04177 }
04178 }
04179
04180
04181
04182 static int
04183 elf32_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
04184 {
04185 if (ELF_ST_TYPE (elf_sym->st_info) == STT_PARISC_MILLI)
04186 return STT_PARISC_MILLI;
04187 else
04188 return type;
04189 }
04190
04191
04192 #define bfd_elf32_bfd_is_local_label_name elf_hppa_is_local_label_name
04193 #define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
04194 #define elf_info_to_howto elf_hppa_info_to_howto
04195 #define elf_info_to_howto_rel elf_hppa_info_to_howto_rel
04196
04197
04198 #define bfd_elf32_bfd_final_link elf32_hppa_final_link
04199 #define bfd_elf32_bfd_link_hash_table_create elf32_hppa_link_hash_table_create
04200 #define bfd_elf32_bfd_link_hash_table_free elf32_hppa_link_hash_table_free
04201 #define elf_backend_adjust_dynamic_symbol elf32_hppa_adjust_dynamic_symbol
04202 #define elf_backend_copy_indirect_symbol elf32_hppa_copy_indirect_symbol
04203 #define elf_backend_check_relocs elf32_hppa_check_relocs
04204 #define elf_backend_create_dynamic_sections elf32_hppa_create_dynamic_sections
04205 #define elf_backend_fake_sections elf_hppa_fake_sections
04206 #define elf_backend_relocate_section elf32_hppa_relocate_section
04207 #define elf_backend_hide_symbol elf32_hppa_hide_symbol
04208 #define elf_backend_finish_dynamic_symbol elf32_hppa_finish_dynamic_symbol
04209 #define elf_backend_finish_dynamic_sections elf32_hppa_finish_dynamic_sections
04210 #define elf_backend_size_dynamic_sections elf32_hppa_size_dynamic_sections
04211 #define elf_backend_gc_mark_hook elf32_hppa_gc_mark_hook
04212 #define elf_backend_gc_sweep_hook elf32_hppa_gc_sweep_hook
04213 #define elf_backend_grok_prstatus elf32_hppa_grok_prstatus
04214 #define elf_backend_grok_psinfo elf32_hppa_grok_psinfo
04215 #define elf_backend_object_p elf32_hppa_object_p
04216 #define elf_backend_final_write_processing elf_hppa_final_write_processing
04217 #define elf_backend_post_process_headers elf32_hppa_post_process_headers
04218 #define elf_backend_get_symbol_type elf32_hppa_elf_get_symbol_type
04219 #define elf_backend_reloc_type_class elf32_hppa_reloc_type_class
04220
04221 #define elf_backend_can_gc_sections 1
04222 #define elf_backend_can_refcount 1
04223 #define elf_backend_plt_alignment 2
04224 #define elf_backend_want_got_plt 0
04225 #define elf_backend_plt_readonly 0
04226 #define elf_backend_want_plt_sym 0
04227 #define elf_backend_got_header_size 8
04228 #define elf_backend_rela_normal 1
04229
04230 #define TARGET_BIG_SYM bfd_elf32_hppa_vec
04231 #define TARGET_BIG_NAME "elf32-hppa"
04232 #define ELF_ARCH bfd_arch_hppa
04233 #define ELF_MACHINE_CODE EM_PARISC
04234 #define ELF_MAXPAGESIZE 0x1000
04235
04236 #include "elf32-target.h"
04237
04238 #undef TARGET_BIG_SYM
04239 #define TARGET_BIG_SYM bfd_elf32_hppa_linux_vec
04240 #undef TARGET_BIG_NAME
04241 #define TARGET_BIG_NAME "elf32-hppa-linux"
04242
04243 #define INCLUDED_TARGET_FILE 1
04244 #include "elf32-target.h"
04245
04246 #undef TARGET_BIG_SYM
04247 #define TARGET_BIG_SYM bfd_elf32_hppa_nbsd_vec
04248 #undef TARGET_BIG_NAME
04249 #define TARGET_BIG_NAME "elf32-hppa-netbsd"
04250
04251 #include "elf32-target.h"