00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "bfd.h"
00033 #include "sysdep.h"
00034 #include "bfdlink.h"
00035 #include "libbfd.h"
00036 #include "elf-bfd.h"
00037 #include "elf/ppc.h"
00038 #include "elf32-ppc.h"
00039
00040
00041
00042 static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
00043 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00044 static bfd_reloc_status_type ppc_elf_unhandled_reloc
00045 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00046
00047
00048 #define BRANCH_PREDICT_BIT 0x200000
00049
00050 #define RA_REGISTER_MASK 0x001f0000
00051
00052 #define RA_REGISTER_SHIFT 16
00053
00054
00055
00056 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
00057
00058
00059 #define PLT_ENTRY_SIZE 12
00060
00061 #define PLT_INITIAL_ENTRY_SIZE 72
00062
00063 #define PLT_SLOT_SIZE 8
00064
00065 #define PLT_NUM_SINGLE_ENTRIES 8192
00066
00067
00068 #define NOP 0x60000000
00069 #define CROR_151515 0x4def7b82
00070 #define CROR_313131 0x4ffffb82
00071
00072
00073 #define TP_OFFSET 0x7000
00074 #define DTP_OFFSET 0x8000
00075
00076
00077
00078 enum elf_linker_section_enum
00079 {
00080 LINKER_SECTION_SDATA,
00081 LINKER_SECTION_SDATA2
00082 };
00083
00084
00085
00086 typedef struct elf_linker_section
00087 {
00088
00089 asection *section;
00090
00091 asection *rel_section;
00092
00093 struct elf_link_hash_entry *sym_hash;
00094
00095 bfd_vma sym_offset;
00096 } elf_linker_section_t;
00097
00098
00099
00100
00101
00102 typedef struct elf_linker_section_pointers
00103 {
00104
00105 struct elf_linker_section_pointers *next;
00106
00107 bfd_vma offset;
00108
00109 bfd_vma addend;
00110
00111 elf_linker_section_t *lsect;
00112
00113 bfd_boolean written_address_p;
00114 } elf_linker_section_pointers_t;
00115
00116 struct ppc_elf_obj_tdata
00117 {
00118 struct elf_obj_tdata elf;
00119
00120
00121
00122 elf_linker_section_pointers_t **linker_section_pointers;
00123 };
00124
00125 #define ppc_elf_tdata(bfd) \
00126 ((struct ppc_elf_obj_tdata *) (bfd)->tdata.any)
00127
00128 #define elf_local_ptr_offsets(bfd) \
00129 (ppc_elf_tdata (bfd)->linker_section_pointers)
00130
00131
00132
00133 static bfd_boolean
00134 ppc_elf_mkobject (bfd *abfd)
00135 {
00136 bfd_size_type amt = sizeof (struct ppc_elf_obj_tdata);
00137 abfd->tdata.any = bfd_zalloc (abfd, amt);
00138 if (abfd->tdata.any == NULL)
00139 return FALSE;
00140 return TRUE;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 struct ppc_elf_dyn_relocs
00150 {
00151 struct ppc_elf_dyn_relocs *next;
00152
00153
00154 asection *sec;
00155
00156
00157 bfd_size_type count;
00158
00159
00160 bfd_size_type pc_count;
00161 };
00162
00163
00164
00165 struct ppc_elf_link_hash_entry
00166 {
00167 struct elf_link_hash_entry elf;
00168
00169
00170
00171
00172 elf_linker_section_pointers_t *linker_section_pointer;
00173
00174
00175 struct ppc_elf_dyn_relocs *dyn_relocs;
00176
00177
00178
00179
00180
00181
00182 #define TLS_GD 1
00183 #define TLS_LD 2
00184 #define TLS_TPREL 4
00185 #define TLS_DTPREL 8
00186 #define TLS_TLS 16
00187 #define TLS_TPRELGD 32
00188 char tls_mask;
00189 };
00190
00191 #define ppc_elf_hash_entry(ent) ((struct ppc_elf_link_hash_entry *) (ent))
00192
00193
00194
00195 struct ppc_elf_link_hash_table
00196 {
00197 struct elf_link_hash_table elf;
00198
00199
00200 asection *got;
00201 asection *relgot;
00202 asection *plt;
00203 asection *relplt;
00204 asection *dynbss;
00205 asection *relbss;
00206 asection *dynsbss;
00207 asection *relsbss;
00208 elf_linker_section_t *sdata;
00209 elf_linker_section_t *sdata2;
00210 asection *sbss;
00211
00212
00213 struct elf_link_hash_entry *tls_get_addr;
00214
00215
00216 union {
00217 bfd_signed_vma refcount;
00218 bfd_vma offset;
00219 } tlsld_got;
00220
00221
00222 struct sym_sec_cache sym_sec;
00223 };
00224
00225
00226
00227 #define ppc_elf_hash_table(p) \
00228 ((struct ppc_elf_link_hash_table *) (p)->hash)
00229
00230
00231
00232 static struct bfd_hash_entry *
00233 ppc_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
00234 struct bfd_hash_table *table,
00235 const char *string)
00236 {
00237
00238
00239 if (entry == NULL)
00240 {
00241 entry = bfd_hash_allocate (table,
00242 sizeof (struct ppc_elf_link_hash_entry));
00243 if (entry == NULL)
00244 return entry;
00245 }
00246
00247
00248 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
00249 if (entry != NULL)
00250 {
00251 ppc_elf_hash_entry (entry)->linker_section_pointer = NULL;
00252 ppc_elf_hash_entry (entry)->dyn_relocs = NULL;
00253 ppc_elf_hash_entry (entry)->tls_mask = 0;
00254 }
00255
00256 return entry;
00257 }
00258
00259
00260
00261 static struct bfd_link_hash_table *
00262 ppc_elf_link_hash_table_create (bfd *abfd)
00263 {
00264 struct ppc_elf_link_hash_table *ret;
00265
00266 ret = bfd_zmalloc (sizeof (struct ppc_elf_link_hash_table));
00267 if (ret == NULL)
00268 return NULL;
00269
00270 if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd,
00271 ppc_elf_link_hash_newfunc))
00272 {
00273 free (ret);
00274 return NULL;
00275 }
00276
00277 return &ret->elf.root;
00278 }
00279
00280
00281
00282
00283
00284 #define ELIMINATE_COPY_RELOCS 1
00285
00286
00287
00288 static void
00289 ppc_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
00290 struct elf_link_hash_entry *dir,
00291 struct elf_link_hash_entry *ind)
00292 {
00293 struct ppc_elf_link_hash_entry *edir, *eind;
00294
00295 edir = (struct ppc_elf_link_hash_entry *) dir;
00296 eind = (struct ppc_elf_link_hash_entry *) ind;
00297
00298 if (eind->dyn_relocs != NULL)
00299 {
00300 if (edir->dyn_relocs != NULL)
00301 {
00302 struct ppc_elf_dyn_relocs **pp;
00303 struct ppc_elf_dyn_relocs *p;
00304
00305 if (ind->root.type == bfd_link_hash_indirect)
00306 abort ();
00307
00308
00309
00310 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
00311 {
00312 struct ppc_elf_dyn_relocs *q;
00313
00314 for (q = edir->dyn_relocs; q != NULL; q = q->next)
00315 if (q->sec == p->sec)
00316 {
00317 q->pc_count += p->pc_count;
00318 q->count += p->count;
00319 *pp = p->next;
00320 break;
00321 }
00322 if (q == NULL)
00323 pp = &p->next;
00324 }
00325 *pp = edir->dyn_relocs;
00326 }
00327
00328 edir->dyn_relocs = eind->dyn_relocs;
00329 eind->dyn_relocs = NULL;
00330 }
00331
00332 edir->tls_mask |= eind->tls_mask;
00333
00334 if (ELIMINATE_COPY_RELOCS
00335 && ind->root.type != bfd_link_hash_indirect
00336 && dir->dynamic_adjusted)
00337 {
00338
00339
00340
00341 dir->ref_dynamic |= ind->ref_dynamic;
00342 dir->ref_regular |= ind->ref_regular;
00343 dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
00344 dir->needs_plt |= ind->needs_plt;
00345 }
00346 else
00347 _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
00348 }
00349
00350 static reloc_howto_type *ppc_elf_howto_table[R_PPC_max];
00351
00352 static reloc_howto_type ppc_elf_howto_raw[] = {
00353
00354 HOWTO (R_PPC_NONE,
00355 0,
00356 2,
00357 32,
00358 FALSE,
00359 0,
00360 complain_overflow_bitfield,
00361 bfd_elf_generic_reloc,
00362 "R_PPC_NONE",
00363 FALSE,
00364 0,
00365 0,
00366 FALSE),
00367
00368
00369 HOWTO (R_PPC_ADDR32,
00370 0,
00371 2,
00372 32,
00373 FALSE,
00374 0,
00375 complain_overflow_bitfield,
00376 bfd_elf_generic_reloc,
00377 "R_PPC_ADDR32",
00378 FALSE,
00379 0,
00380 0xffffffff,
00381 FALSE),
00382
00383
00384
00385 HOWTO (R_PPC_ADDR24,
00386 0,
00387 2,
00388 26,
00389 FALSE,
00390 0,
00391 complain_overflow_bitfield,
00392 bfd_elf_generic_reloc,
00393 "R_PPC_ADDR24",
00394 FALSE,
00395 0,
00396 0x3fffffc,
00397 FALSE),
00398
00399
00400 HOWTO (R_PPC_ADDR16,
00401 0,
00402 1,
00403 16,
00404 FALSE,
00405 0,
00406 complain_overflow_bitfield,
00407 bfd_elf_generic_reloc,
00408 "R_PPC_ADDR16",
00409 FALSE,
00410 0,
00411 0xffff,
00412 FALSE),
00413
00414
00415 HOWTO (R_PPC_ADDR16_LO,
00416 0,
00417 1,
00418 16,
00419 FALSE,
00420 0,
00421 complain_overflow_dont,
00422 bfd_elf_generic_reloc,
00423 "R_PPC_ADDR16_LO",
00424 FALSE,
00425 0,
00426 0xffff,
00427 FALSE),
00428
00429
00430 HOWTO (R_PPC_ADDR16_HI,
00431 16,
00432 1,
00433 16,
00434 FALSE,
00435 0,
00436 complain_overflow_dont,
00437 bfd_elf_generic_reloc,
00438 "R_PPC_ADDR16_HI",
00439 FALSE,
00440 0,
00441 0xffff,
00442 FALSE),
00443
00444
00445
00446 HOWTO (R_PPC_ADDR16_HA,
00447 16,
00448 1,
00449 16,
00450 FALSE,
00451 0,
00452 complain_overflow_dont,
00453 ppc_elf_addr16_ha_reloc,
00454 "R_PPC_ADDR16_HA",
00455 FALSE,
00456 0,
00457 0xffff,
00458 FALSE),
00459
00460
00461
00462 HOWTO (R_PPC_ADDR14,
00463 0,
00464 2,
00465 16,
00466 FALSE,
00467 0,
00468 complain_overflow_bitfield,
00469 bfd_elf_generic_reloc,
00470 "R_PPC_ADDR14",
00471 FALSE,
00472 0,
00473 0xfffc,
00474 FALSE),
00475
00476
00477
00478
00479 HOWTO (R_PPC_ADDR14_BRTAKEN,
00480 0,
00481 2,
00482 16,
00483 FALSE,
00484 0,
00485 complain_overflow_bitfield,
00486 bfd_elf_generic_reloc,
00487 "R_PPC_ADDR14_BRTAKEN",
00488 FALSE,
00489 0,
00490 0xfffc,
00491 FALSE),
00492
00493
00494
00495
00496 HOWTO (R_PPC_ADDR14_BRNTAKEN,
00497 0,
00498 2,
00499 16,
00500 FALSE,
00501 0,
00502 complain_overflow_bitfield,
00503 bfd_elf_generic_reloc,
00504 "R_PPC_ADDR14_BRNTAKEN",
00505 FALSE,
00506 0,
00507 0xfffc,
00508 FALSE),
00509
00510
00511 HOWTO (R_PPC_REL24,
00512 0,
00513 2,
00514 26,
00515 TRUE,
00516 0,
00517 complain_overflow_signed,
00518 bfd_elf_generic_reloc,
00519 "R_PPC_REL24",
00520 FALSE,
00521 0,
00522 0x3fffffc,
00523 TRUE),
00524
00525
00526 HOWTO (R_PPC_REL14,
00527 0,
00528 2,
00529 16,
00530 TRUE,
00531 0,
00532 complain_overflow_signed,
00533 bfd_elf_generic_reloc,
00534 "R_PPC_REL14",
00535 FALSE,
00536 0,
00537 0xfffc,
00538 TRUE),
00539
00540
00541
00542
00543 HOWTO (R_PPC_REL14_BRTAKEN,
00544 0,
00545 2,
00546 16,
00547 TRUE,
00548 0,
00549 complain_overflow_signed,
00550 bfd_elf_generic_reloc,
00551 "R_PPC_REL14_BRTAKEN",
00552 FALSE,
00553 0,
00554 0xfffc,
00555 TRUE),
00556
00557
00558
00559
00560 HOWTO (R_PPC_REL14_BRNTAKEN,
00561 0,
00562 2,
00563 16,
00564 TRUE,
00565 0,
00566 complain_overflow_signed,
00567 bfd_elf_generic_reloc,
00568 "R_PPC_REL14_BRNTAKEN",
00569 FALSE,
00570 0,
00571 0xfffc,
00572 TRUE),
00573
00574
00575
00576 HOWTO (R_PPC_GOT16,
00577 0,
00578 1,
00579 16,
00580 FALSE,
00581 0,
00582 complain_overflow_signed,
00583 bfd_elf_generic_reloc,
00584 "R_PPC_GOT16",
00585 FALSE,
00586 0,
00587 0xffff,
00588 FALSE),
00589
00590
00591
00592 HOWTO (R_PPC_GOT16_LO,
00593 0,
00594 1,
00595 16,
00596 FALSE,
00597 0,
00598 complain_overflow_dont,
00599 bfd_elf_generic_reloc,
00600 "R_PPC_GOT16_LO",
00601 FALSE,
00602 0,
00603 0xffff,
00604 FALSE),
00605
00606
00607
00608 HOWTO (R_PPC_GOT16_HI,
00609 16,
00610 1,
00611 16,
00612 FALSE,
00613 0,
00614 complain_overflow_bitfield,
00615 bfd_elf_generic_reloc,
00616 "R_PPC_GOT16_HI",
00617 FALSE,
00618 0,
00619 0xffff,
00620 FALSE),
00621
00622
00623
00624 HOWTO (R_PPC_GOT16_HA,
00625 16,
00626 1,
00627 16,
00628 FALSE,
00629 0,
00630 complain_overflow_bitfield,
00631 ppc_elf_addr16_ha_reloc,
00632 "R_PPC_GOT16_HA",
00633 FALSE,
00634 0,
00635 0xffff,
00636 FALSE),
00637
00638
00639
00640 HOWTO (R_PPC_PLTREL24,
00641 0,
00642 2,
00643 26,
00644 TRUE,
00645 0,
00646 complain_overflow_signed,
00647 bfd_elf_generic_reloc,
00648 "R_PPC_PLTREL24",
00649 FALSE,
00650 0,
00651 0x3fffffc,
00652 TRUE),
00653
00654
00655
00656
00657
00658
00659 HOWTO (R_PPC_COPY,
00660 0,
00661 2,
00662 32,
00663 FALSE,
00664 0,
00665 complain_overflow_bitfield,
00666 bfd_elf_generic_reloc,
00667 "R_PPC_COPY",
00668 FALSE,
00669 0,
00670 0,
00671 FALSE),
00672
00673
00674
00675 HOWTO (R_PPC_GLOB_DAT,
00676 0,
00677 2,
00678 32,
00679 FALSE,
00680 0,
00681 complain_overflow_bitfield,
00682 bfd_elf_generic_reloc,
00683 "R_PPC_GLOB_DAT",
00684 FALSE,
00685 0,
00686 0xffffffff,
00687 FALSE),
00688
00689
00690 HOWTO (R_PPC_JMP_SLOT,
00691 0,
00692 2,
00693 32,
00694 FALSE,
00695 0,
00696 complain_overflow_bitfield,
00697 bfd_elf_generic_reloc,
00698 "R_PPC_JMP_SLOT",
00699 FALSE,
00700 0,
00701 0,
00702 FALSE),
00703
00704
00705
00706
00707 HOWTO (R_PPC_RELATIVE,
00708 0,
00709 2,
00710 32,
00711 FALSE,
00712 0,
00713 complain_overflow_bitfield,
00714 bfd_elf_generic_reloc,
00715 "R_PPC_RELATIVE",
00716 FALSE,
00717 0,
00718 0xffffffff,
00719 FALSE),
00720
00721
00722
00723
00724 HOWTO (R_PPC_LOCAL24PC,
00725 0,
00726 2,
00727 26,
00728 TRUE,
00729 0,
00730 complain_overflow_signed,
00731 bfd_elf_generic_reloc,
00732 "R_PPC_LOCAL24PC",
00733 FALSE,
00734 0,
00735 0x3fffffc,
00736 TRUE),
00737
00738
00739 HOWTO (R_PPC_UADDR32,
00740 0,
00741 2,
00742 32,
00743 FALSE,
00744 0,
00745 complain_overflow_bitfield,
00746 bfd_elf_generic_reloc,
00747 "R_PPC_UADDR32",
00748 FALSE,
00749 0,
00750 0xffffffff,
00751 FALSE),
00752
00753
00754 HOWTO (R_PPC_UADDR16,
00755 0,
00756 1,
00757 16,
00758 FALSE,
00759 0,
00760 complain_overflow_bitfield,
00761 bfd_elf_generic_reloc,
00762 "R_PPC_UADDR16",
00763 FALSE,
00764 0,
00765 0xffff,
00766 FALSE),
00767
00768
00769 HOWTO (R_PPC_REL32,
00770 0,
00771 2,
00772 32,
00773 TRUE,
00774 0,
00775 complain_overflow_bitfield,
00776 bfd_elf_generic_reloc,
00777 "R_PPC_REL32",
00778 FALSE,
00779 0,
00780 0xffffffff,
00781 TRUE),
00782
00783
00784
00785 HOWTO (R_PPC_PLT32,
00786 0,
00787 2,
00788 32,
00789 FALSE,
00790 0,
00791 complain_overflow_bitfield,
00792 bfd_elf_generic_reloc,
00793 "R_PPC_PLT32",
00794 FALSE,
00795 0,
00796 0,
00797 FALSE),
00798
00799
00800
00801 HOWTO (R_PPC_PLTREL32,
00802 0,
00803 2,
00804 32,
00805 TRUE,
00806 0,
00807 complain_overflow_bitfield,
00808 bfd_elf_generic_reloc,
00809 "R_PPC_PLTREL32",
00810 FALSE,
00811 0,
00812 0,
00813 TRUE),
00814
00815
00816
00817 HOWTO (R_PPC_PLT16_LO,
00818 0,
00819 1,
00820 16,
00821 FALSE,
00822 0,
00823 complain_overflow_dont,
00824 bfd_elf_generic_reloc,
00825 "R_PPC_PLT16_LO",
00826 FALSE,
00827 0,
00828 0xffff,
00829 FALSE),
00830
00831
00832
00833 HOWTO (R_PPC_PLT16_HI,
00834 16,
00835 1,
00836 16,
00837 FALSE,
00838 0,
00839 complain_overflow_bitfield,
00840 bfd_elf_generic_reloc,
00841 "R_PPC_PLT16_HI",
00842 FALSE,
00843 0,
00844 0xffff,
00845 FALSE),
00846
00847
00848
00849 HOWTO (R_PPC_PLT16_HA,
00850 16,
00851 1,
00852 16,
00853 FALSE,
00854 0,
00855 complain_overflow_bitfield,
00856 ppc_elf_addr16_ha_reloc,
00857 "R_PPC_PLT16_HA",
00858 FALSE,
00859 0,
00860 0xffff,
00861 FALSE),
00862
00863
00864
00865 HOWTO (R_PPC_SDAREL16,
00866 0,
00867 1,
00868 16,
00869 FALSE,
00870 0,
00871 complain_overflow_signed,
00872 bfd_elf_generic_reloc,
00873 "R_PPC_SDAREL16",
00874 FALSE,
00875 0,
00876 0xffff,
00877 FALSE),
00878
00879
00880 HOWTO (R_PPC_SECTOFF,
00881 0,
00882 1,
00883 16,
00884 FALSE,
00885 0,
00886 complain_overflow_bitfield,
00887 bfd_elf_generic_reloc,
00888 "R_PPC_SECTOFF",
00889 FALSE,
00890 0,
00891 0xffff,
00892 FALSE),
00893
00894
00895 HOWTO (R_PPC_SECTOFF_LO,
00896 0,
00897 1,
00898 16,
00899 FALSE,
00900 0,
00901 complain_overflow_dont,
00902 bfd_elf_generic_reloc,
00903 "R_PPC_SECTOFF_LO",
00904 FALSE,
00905 0,
00906 0xffff,
00907 FALSE),
00908
00909
00910 HOWTO (R_PPC_SECTOFF_HI,
00911 16,
00912 1,
00913 16,
00914 FALSE,
00915 0,
00916 complain_overflow_bitfield,
00917 bfd_elf_generic_reloc,
00918 "R_PPC_SECTOFF_HI",
00919 FALSE,
00920 0,
00921 0xffff,
00922 FALSE),
00923
00924
00925 HOWTO (R_PPC_SECTOFF_HA,
00926 16,
00927 1,
00928 16,
00929 FALSE,
00930 0,
00931 complain_overflow_bitfield,
00932 ppc_elf_addr16_ha_reloc,
00933 "R_PPC_SECTOFF_HA",
00934 FALSE,
00935 0,
00936 0xffff,
00937 FALSE),
00938
00939
00940 HOWTO (R_PPC_TLS,
00941 0,
00942 2,
00943 32,
00944 FALSE,
00945 0,
00946 complain_overflow_dont,
00947 bfd_elf_generic_reloc,
00948 "R_PPC_TLS",
00949 FALSE,
00950 0,
00951 0,
00952 FALSE),
00953
00954
00955
00956 HOWTO (R_PPC_DTPMOD32,
00957 0,
00958 2,
00959 32,
00960 FALSE,
00961 0,
00962 complain_overflow_dont,
00963 ppc_elf_unhandled_reloc,
00964 "R_PPC_DTPMOD32",
00965 FALSE,
00966 0,
00967 0xffffffff,
00968 FALSE),
00969
00970
00971
00972
00973 HOWTO (R_PPC_DTPREL32,
00974 0,
00975 2,
00976 32,
00977 FALSE,
00978 0,
00979 complain_overflow_dont,
00980 ppc_elf_unhandled_reloc,
00981 "R_PPC_DTPREL32",
00982 FALSE,
00983 0,
00984 0xffffffff,
00985 FALSE),
00986
00987
00988 HOWTO (R_PPC_DTPREL16,
00989 0,
00990 1,
00991 16,
00992 FALSE,
00993 0,
00994 complain_overflow_signed,
00995 ppc_elf_unhandled_reloc,
00996 "R_PPC_DTPREL16",
00997 FALSE,
00998 0,
00999 0xffff,
01000 FALSE),
01001
01002
01003 HOWTO (R_PPC_DTPREL16_LO,
01004 0,
01005 1,
01006 16,
01007 FALSE,
01008 0,
01009 complain_overflow_dont,
01010 ppc_elf_unhandled_reloc,
01011 "R_PPC_DTPREL16_LO",
01012 FALSE,
01013 0,
01014 0xffff,
01015 FALSE),
01016
01017
01018 HOWTO (R_PPC_DTPREL16_HI,
01019 16,
01020 1,
01021 16,
01022 FALSE,
01023 0,
01024 complain_overflow_dont,
01025 ppc_elf_unhandled_reloc,
01026 "R_PPC_DTPREL16_HI",
01027 FALSE,
01028 0,
01029 0xffff,
01030 FALSE),
01031
01032
01033 HOWTO (R_PPC_DTPREL16_HA,
01034 16,
01035 1,
01036 16,
01037 FALSE,
01038 0,
01039 complain_overflow_dont,
01040 ppc_elf_unhandled_reloc,
01041 "R_PPC_DTPREL16_HA",
01042 FALSE,
01043 0,
01044 0xffff,
01045 FALSE),
01046
01047
01048
01049 HOWTO (R_PPC_TPREL32,
01050 0,
01051 2,
01052 32,
01053 FALSE,
01054 0,
01055 complain_overflow_dont,
01056 ppc_elf_unhandled_reloc,
01057 "R_PPC_TPREL32",
01058 FALSE,
01059 0,
01060 0xffffffff,
01061 FALSE),
01062
01063
01064 HOWTO (R_PPC_TPREL16,
01065 0,
01066 1,
01067 16,
01068 FALSE,
01069 0,
01070 complain_overflow_signed,
01071 ppc_elf_unhandled_reloc,
01072 "R_PPC_TPREL16",
01073 FALSE,
01074 0,
01075 0xffff,
01076 FALSE),
01077
01078
01079 HOWTO (R_PPC_TPREL16_LO,
01080 0,
01081 1,
01082 16,
01083 FALSE,
01084 0,
01085 complain_overflow_dont,
01086 ppc_elf_unhandled_reloc,
01087 "R_PPC_TPREL16_LO",
01088 FALSE,
01089 0,
01090 0xffff,
01091 FALSE),
01092
01093
01094 HOWTO (R_PPC_TPREL16_HI,
01095 16,
01096 1,
01097 16,
01098 FALSE,
01099 0,
01100 complain_overflow_dont,
01101 ppc_elf_unhandled_reloc,
01102 "R_PPC_TPREL16_HI",
01103 FALSE,
01104 0,
01105 0xffff,
01106 FALSE),
01107
01108
01109 HOWTO (R_PPC_TPREL16_HA,
01110 16,
01111 1,
01112 16,
01113 FALSE,
01114 0,
01115 complain_overflow_dont,
01116 ppc_elf_unhandled_reloc,
01117 "R_PPC_TPREL16_HA",
01118 FALSE,
01119 0,
01120 0xffff,
01121 FALSE),
01122
01123
01124
01125
01126 HOWTO (R_PPC_GOT_TLSGD16,
01127 0,
01128 1,
01129 16,
01130 FALSE,
01131 0,
01132 complain_overflow_signed,
01133 ppc_elf_unhandled_reloc,
01134 "R_PPC_GOT_TLSGD16",
01135 FALSE,
01136 0,
01137 0xffff,
01138 FALSE),
01139
01140
01141 HOWTO (R_PPC_GOT_TLSGD16_LO,
01142 0,
01143 1,
01144 16,
01145 FALSE,
01146 0,
01147 complain_overflow_dont,
01148 ppc_elf_unhandled_reloc,
01149 "R_PPC_GOT_TLSGD16_LO",
01150 FALSE,
01151 0,
01152 0xffff,
01153 FALSE),
01154
01155
01156 HOWTO (R_PPC_GOT_TLSGD16_HI,
01157 16,
01158 1,
01159 16,
01160 FALSE,
01161 0,
01162 complain_overflow_dont,
01163 ppc_elf_unhandled_reloc,
01164 "R_PPC_GOT_TLSGD16_HI",
01165 FALSE,
01166 0,
01167 0xffff,
01168 FALSE),
01169
01170
01171 HOWTO (R_PPC_GOT_TLSGD16_HA,
01172 16,
01173 1,
01174 16,
01175 FALSE,
01176 0,
01177 complain_overflow_dont,
01178 ppc_elf_unhandled_reloc,
01179 "R_PPC_GOT_TLSGD16_HA",
01180 FALSE,
01181 0,
01182 0xffff,
01183 FALSE),
01184
01185
01186
01187
01188 HOWTO (R_PPC_GOT_TLSLD16,
01189 0,
01190 1,
01191 16,
01192 FALSE,
01193 0,
01194 complain_overflow_signed,
01195 ppc_elf_unhandled_reloc,
01196 "R_PPC_GOT_TLSLD16",
01197 FALSE,
01198 0,
01199 0xffff,
01200 FALSE),
01201
01202
01203 HOWTO (R_PPC_GOT_TLSLD16_LO,
01204 0,
01205 1,
01206 16,
01207 FALSE,
01208 0,
01209 complain_overflow_dont,
01210 ppc_elf_unhandled_reloc,
01211 "R_PPC_GOT_TLSLD16_LO",
01212 FALSE,
01213 0,
01214 0xffff,
01215 FALSE),
01216
01217
01218 HOWTO (R_PPC_GOT_TLSLD16_HI,
01219 16,
01220 1,
01221 16,
01222 FALSE,
01223 0,
01224 complain_overflow_dont,
01225 ppc_elf_unhandled_reloc,
01226 "R_PPC_GOT_TLSLD16_HI",
01227 FALSE,
01228 0,
01229 0xffff,
01230 FALSE),
01231
01232
01233 HOWTO (R_PPC_GOT_TLSLD16_HA,
01234 16,
01235 1,
01236 16,
01237 FALSE,
01238 0,
01239 complain_overflow_dont,
01240 ppc_elf_unhandled_reloc,
01241 "R_PPC_GOT_TLSLD16_HA",
01242 FALSE,
01243 0,
01244 0xffff,
01245 FALSE),
01246
01247
01248
01249 HOWTO (R_PPC_GOT_DTPREL16,
01250 0,
01251 1,
01252 16,
01253 FALSE,
01254 0,
01255 complain_overflow_signed,
01256 ppc_elf_unhandled_reloc,
01257 "R_PPC_GOT_DTPREL16",
01258 FALSE,
01259 0,
01260 0xffff,
01261 FALSE),
01262
01263
01264 HOWTO (R_PPC_GOT_DTPREL16_LO,
01265 0,
01266 1,
01267 16,
01268 FALSE,
01269 0,
01270 complain_overflow_dont,
01271 ppc_elf_unhandled_reloc,
01272 "R_PPC_GOT_DTPREL16_LO",
01273 FALSE,
01274 0,
01275 0xffff,
01276 FALSE),
01277
01278
01279 HOWTO (R_PPC_GOT_DTPREL16_HI,
01280 16,
01281 1,
01282 16,
01283 FALSE,
01284 0,
01285 complain_overflow_dont,
01286 ppc_elf_unhandled_reloc,
01287 "R_PPC_GOT_DTPREL16_HI",
01288 FALSE,
01289 0,
01290 0xffff,
01291 FALSE),
01292
01293
01294 HOWTO (R_PPC_GOT_DTPREL16_HA,
01295 16,
01296 1,
01297 16,
01298 FALSE,
01299 0,
01300 complain_overflow_dont,
01301 ppc_elf_unhandled_reloc,
01302 "R_PPC_GOT_DTPREL16_HA",
01303 FALSE,
01304 0,
01305 0xffff,
01306 FALSE),
01307
01308
01309
01310 HOWTO (R_PPC_GOT_TPREL16,
01311 0,
01312 1,
01313 16,
01314 FALSE,
01315 0,
01316 complain_overflow_signed,
01317 ppc_elf_unhandled_reloc,
01318 "R_PPC_GOT_TPREL16",
01319 FALSE,
01320 0,
01321 0xffff,
01322 FALSE),
01323
01324
01325 HOWTO (R_PPC_GOT_TPREL16_LO,
01326 0,
01327 1,
01328 16,
01329 FALSE,
01330 0,
01331 complain_overflow_dont,
01332 ppc_elf_unhandled_reloc,
01333 "R_PPC_GOT_TPREL16_LO",
01334 FALSE,
01335 0,
01336 0xffff,
01337 FALSE),
01338
01339
01340 HOWTO (R_PPC_GOT_TPREL16_HI,
01341 16,
01342 1,
01343 16,
01344 FALSE,
01345 0,
01346 complain_overflow_dont,
01347 ppc_elf_unhandled_reloc,
01348 "R_PPC_GOT_TPREL16_HI",
01349 FALSE,
01350 0,
01351 0xffff,
01352 FALSE),
01353
01354
01355 HOWTO (R_PPC_GOT_TPREL16_HA,
01356 16,
01357 1,
01358 16,
01359 FALSE,
01360 0,
01361 complain_overflow_dont,
01362 ppc_elf_unhandled_reloc,
01363 "R_PPC_GOT_TPREL16_HA",
01364 FALSE,
01365 0,
01366 0xffff,
01367 FALSE),
01368
01369
01370
01371
01372
01373 HOWTO (R_PPC_EMB_NADDR32,
01374 0,
01375 2,
01376 32,
01377 FALSE,
01378 0,
01379 complain_overflow_bitfield,
01380 bfd_elf_generic_reloc,
01381 "R_PPC_EMB_NADDR32",
01382 FALSE,
01383 0,
01384 0xffffffff,
01385 FALSE),
01386
01387
01388 HOWTO (R_PPC_EMB_NADDR16,
01389 0,
01390 1,
01391 16,
01392 FALSE,
01393 0,
01394 complain_overflow_bitfield,
01395 bfd_elf_generic_reloc,
01396 "R_PPC_EMB_NADDR16",
01397 FALSE,
01398 0,
01399 0xffff,
01400 FALSE),
01401
01402
01403 HOWTO (R_PPC_EMB_NADDR16_LO,
01404 0,
01405 1,
01406 16,
01407 FALSE,
01408 0,
01409 complain_overflow_dont,
01410 bfd_elf_generic_reloc,
01411 "R_PPC_EMB_ADDR16_LO",
01412 FALSE,
01413 0,
01414 0xffff,
01415 FALSE),
01416
01417
01418 HOWTO (R_PPC_EMB_NADDR16_HI,
01419 16,
01420 1,
01421 16,
01422 FALSE,
01423 0,
01424 complain_overflow_dont,
01425 bfd_elf_generic_reloc,
01426 "R_PPC_EMB_NADDR16_HI",
01427 FALSE,
01428 0,
01429 0xffff,
01430 FALSE),
01431
01432
01433
01434
01435 HOWTO (R_PPC_EMB_NADDR16_HA,
01436 16,
01437 1,
01438 16,
01439 FALSE,
01440 0,
01441 complain_overflow_dont,
01442 ppc_elf_addr16_ha_reloc,
01443 "R_PPC_EMB_NADDR16_HA",
01444 FALSE,
01445 0,
01446 0xffff,
01447 FALSE),
01448
01449
01450
01451
01452 HOWTO (R_PPC_EMB_SDAI16,
01453 0,
01454 1,
01455 16,
01456 FALSE,
01457 0,
01458 complain_overflow_bitfield,
01459 bfd_elf_generic_reloc,
01460 "R_PPC_EMB_SDAI16",
01461 FALSE,
01462 0,
01463 0xffff,
01464 FALSE),
01465
01466
01467
01468
01469 HOWTO (R_PPC_EMB_SDA2I16,
01470 0,
01471 1,
01472 16,
01473 FALSE,
01474 0,
01475 complain_overflow_bitfield,
01476 bfd_elf_generic_reloc,
01477 "R_PPC_EMB_SDA2I16",
01478 FALSE,
01479 0,
01480 0xffff,
01481 FALSE),
01482
01483
01484
01485 HOWTO (R_PPC_EMB_SDA2REL,
01486 0,
01487 1,
01488 16,
01489 FALSE,
01490 0,
01491 complain_overflow_signed,
01492 bfd_elf_generic_reloc,
01493 "R_PPC_EMB_SDA2REL",
01494 FALSE,
01495 0,
01496 0xffff,
01497 FALSE),
01498
01499
01500
01501
01502 HOWTO (R_PPC_EMB_SDA21,
01503 0,
01504 2,
01505 16,
01506 FALSE,
01507 0,
01508 complain_overflow_signed,
01509 bfd_elf_generic_reloc,
01510 "R_PPC_EMB_SDA21",
01511 FALSE,
01512 0,
01513 0xffff,
01514 FALSE),
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 HOWTO (R_PPC_EMB_RELSDA,
01527 0,
01528 1,
01529 16,
01530 TRUE,
01531 0,
01532 complain_overflow_signed,
01533 bfd_elf_generic_reloc,
01534 "R_PPC_EMB_RELSDA",
01535 FALSE,
01536 0,
01537 0xffff,
01538 FALSE),
01539
01540
01541 HOWTO (R_PPC_GNU_VTINHERIT,
01542 0,
01543 0,
01544 0,
01545 FALSE,
01546 0,
01547 complain_overflow_dont,
01548 NULL,
01549 "R_PPC_GNU_VTINHERIT",
01550 FALSE,
01551 0,
01552 0,
01553 FALSE),
01554
01555
01556 HOWTO (R_PPC_GNU_VTENTRY,
01557 0,
01558 0,
01559 0,
01560 FALSE,
01561 0,
01562 complain_overflow_dont,
01563 NULL,
01564 "R_PPC_GNU_VTENTRY",
01565 FALSE,
01566 0,
01567 0,
01568 FALSE),
01569
01570
01571 HOWTO (R_PPC_TOC16,
01572 0,
01573 1,
01574 16,
01575 FALSE,
01576 0,
01577 complain_overflow_signed,
01578 bfd_elf_generic_reloc,
01579 "R_PPC_TOC16",
01580 FALSE,
01581 0,
01582 0xffff,
01583 FALSE),
01584 };
01585
01586
01587
01588 static void
01589 ppc_elf_howto_init (void)
01590 {
01591 unsigned int i, type;
01592
01593 for (i = 0;
01594 i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]);
01595 i++)
01596 {
01597 type = ppc_elf_howto_raw[i].type;
01598 if (type >= (sizeof (ppc_elf_howto_table)
01599 / sizeof (ppc_elf_howto_table[0])))
01600 abort ();
01601 ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i];
01602 }
01603 }
01604
01605 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
01606
01607 static const int shared_stub_entry[] =
01608 {
01609 0x7c0802a6,
01610 0x429f0005,
01611 0x7d6802a6,
01612 0x3d6b0000,
01613 0x396b0018,
01614 0x7c0803a6,
01615 0x7d6903a6,
01616 0x4e800420,
01617 };
01618
01619 static const int stub_entry[] =
01620 {
01621 0x3d600000,
01622 0x396b0000,
01623 0x7d6903a6,
01624 0x4e800420,
01625 };
01626
01627
01628 static bfd_boolean
01629 ppc_elf_relax_section (bfd *abfd,
01630 asection *isec,
01631 struct bfd_link_info *link_info,
01632 bfd_boolean *again)
01633 {
01634 struct one_fixup
01635 {
01636 struct one_fixup *next;
01637 asection *tsec;
01638 bfd_vma toff;
01639 bfd_vma trampoff;
01640 };
01641
01642 Elf_Internal_Shdr *symtab_hdr;
01643 bfd_byte *contents = NULL;
01644 Elf_Internal_Sym *isymbuf = NULL;
01645 Elf_Internal_Rela *internal_relocs = NULL;
01646 Elf_Internal_Rela *irel, *irelend;
01647 struct one_fixup *fixups = NULL;
01648 bfd_boolean changed;
01649 struct ppc_elf_link_hash_table *ppc_info;
01650 bfd_size_type trampoff;
01651
01652 *again = FALSE;
01653
01654
01655
01656 if ((isec->flags & SEC_ALLOC) == 0
01657 || (isec->flags & SEC_RELOC) == 0
01658 || isec->reloc_count == 0)
01659 return TRUE;
01660
01661 trampoff = (isec->size + 3) & (bfd_vma) -4;
01662
01663 trampoff += 4;
01664
01665 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01666
01667
01668 internal_relocs = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL,
01669 link_info->keep_memory);
01670 if (internal_relocs == NULL)
01671 goto error_return;
01672
01673 ppc_info = ppc_elf_hash_table (link_info);
01674 irelend = internal_relocs + isec->reloc_count;
01675
01676 for (irel = internal_relocs; irel < irelend; irel++)
01677 {
01678 unsigned long r_type = ELF32_R_TYPE (irel->r_info);
01679 bfd_vma symaddr, reladdr, toff, roff;
01680 asection *tsec;
01681 struct one_fixup *f;
01682 size_t insn_offset = 0;
01683 bfd_vma max_branch_offset, val;
01684 bfd_byte *hit_addr;
01685 unsigned long t0;
01686 unsigned char sym_type;
01687
01688 switch (r_type)
01689 {
01690 case R_PPC_REL24:
01691 case R_PPC_LOCAL24PC:
01692 case R_PPC_PLTREL24:
01693 max_branch_offset = 1 << 25;
01694 break;
01695
01696 case R_PPC_REL14:
01697 case R_PPC_REL14_BRTAKEN:
01698 case R_PPC_REL14_BRNTAKEN:
01699 max_branch_offset = 1 << 15;
01700 break;
01701
01702 default:
01703 continue;
01704 }
01705
01706
01707 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
01708 {
01709
01710 Elf_Internal_Sym *isym;
01711
01712
01713 if (isymbuf == NULL)
01714 {
01715 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
01716 if (isymbuf == NULL)
01717 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
01718 symtab_hdr->sh_info, 0,
01719 NULL, NULL, NULL);
01720 if (isymbuf == 0)
01721 goto error_return;
01722 }
01723 isym = isymbuf + ELF32_R_SYM (irel->r_info);
01724 if (isym->st_shndx == SHN_UNDEF)
01725 continue;
01726 else if (isym->st_shndx == SHN_ABS)
01727 tsec = bfd_abs_section_ptr;
01728 else if (isym->st_shndx == SHN_COMMON)
01729 tsec = bfd_com_section_ptr;
01730 else
01731 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
01732
01733 toff = isym->st_value;
01734 sym_type = ELF_ST_TYPE (isym->st_info);
01735 }
01736 else
01737 {
01738
01739 unsigned long indx;
01740 struct elf_link_hash_entry *h;
01741
01742 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
01743 h = elf_sym_hashes (abfd)[indx];
01744
01745 while (h->root.type == bfd_link_hash_indirect
01746 || h->root.type == bfd_link_hash_warning)
01747 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01748
01749 if (r_type == R_PPC_PLTREL24
01750 && ppc_info->plt != NULL
01751 && h->plt.offset != (bfd_vma) -1)
01752 {
01753 tsec = ppc_info->plt;
01754 toff = h->plt.offset;
01755 }
01756 else if (h->root.type == bfd_link_hash_defined
01757 || h->root.type == bfd_link_hash_defweak)
01758 {
01759 tsec = h->root.u.def.section;
01760 toff = h->root.u.def.value;
01761 }
01762 else
01763 continue;
01764
01765 sym_type = h->type;
01766 }
01767
01768
01769
01770
01771 if (tsec == isec)
01772 continue;
01773
01774
01775
01776
01777
01778
01779 if (0 && tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
01780 {
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797 if (sym_type == STT_SECTION)
01798 toff += irel->r_addend;
01799
01800 toff = _bfd_merged_section_offset (abfd, &tsec,
01801 elf_section_data (tsec)->sec_info,
01802 toff);
01803
01804 if (sym_type != STT_SECTION)
01805 toff += irel->r_addend;
01806 }
01807 else
01808 toff += irel->r_addend;
01809
01810 symaddr = tsec->output_section->vma + tsec->output_offset + toff;
01811
01812 roff = irel->r_offset;
01813 reladdr = isec->output_section->vma + isec->output_offset + roff;
01814
01815
01816 if (symaddr - reladdr + max_branch_offset < 2 * max_branch_offset)
01817 continue;
01818
01819
01820 for (f = fixups; f ; f = f->next)
01821 if (f->tsec == tsec && f->toff == toff)
01822 break;
01823
01824 if (f == NULL)
01825 {
01826 size_t size;
01827 unsigned long stub_rtype;
01828
01829 val = trampoff - roff;
01830 if (val >= max_branch_offset)
01831
01832
01833 continue;
01834
01835 if (link_info->shared)
01836 {
01837 size = 4 * ARRAY_SIZE (shared_stub_entry);
01838 insn_offset = 12;
01839 stub_rtype = R_PPC_RELAX32PC;
01840 }
01841 else
01842 {
01843 size = 4 * ARRAY_SIZE (stub_entry);
01844 insn_offset = 0;
01845 stub_rtype = R_PPC_RELAX32;
01846 }
01847
01848 if (R_PPC_RELAX32_PLT - R_PPC_RELAX32
01849 != R_PPC_RELAX32PC_PLT - R_PPC_RELAX32PC)
01850 abort ();
01851 if (tsec == ppc_info->plt)
01852 stub_rtype += R_PPC_RELAX32_PLT - R_PPC_RELAX32;
01853
01854
01855
01856 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01857 stub_rtype);
01858 irel->r_offset = trampoff + insn_offset;
01859
01860
01861 f = bfd_malloc (sizeof (*f));
01862 f->next = fixups;
01863 f->tsec = tsec;
01864 f->toff = toff;
01865 f->trampoff = trampoff;
01866 fixups = f;
01867
01868 trampoff += size;
01869 }
01870 else
01871 {
01872 val = f->trampoff - roff;
01873 if (val >= max_branch_offset)
01874 continue;
01875
01876
01877 irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
01878 }
01879
01880
01881 if (contents == NULL)
01882 {
01883
01884 if (elf_section_data (isec)->this_hdr.contents != NULL)
01885 contents = elf_section_data (isec)->this_hdr.contents;
01886 else
01887 {
01888
01889 if (!bfd_malloc_and_get_section (abfd, isec, &contents))
01890 goto error_return;
01891 }
01892 }
01893
01894
01895 hit_addr = contents + roff;
01896 switch (r_type)
01897 {
01898 case R_PPC_REL24:
01899 case R_PPC_LOCAL24PC:
01900 case R_PPC_PLTREL24:
01901 t0 = bfd_get_32 (abfd, hit_addr);
01902 t0 &= ~0x3fffffc;
01903 t0 |= val & 0x3fffffc;
01904 bfd_put_32 (abfd, t0, hit_addr);
01905 break;
01906
01907 case R_PPC_REL14:
01908 case R_PPC_REL14_BRTAKEN:
01909 case R_PPC_REL14_BRNTAKEN:
01910 t0 = bfd_get_32 (abfd, hit_addr);
01911 t0 &= ~0xfffc;
01912 t0 |= val & 0xfffc;
01913 bfd_put_32 (abfd, t0, hit_addr);
01914 break;
01915 }
01916 }
01917
01918
01919 changed = fixups != NULL;
01920 if (fixups != NULL)
01921 {
01922 const int *stub;
01923 bfd_byte *dest;
01924 bfd_vma val;
01925 int i, size;
01926
01927 do
01928 {
01929 struct one_fixup *f = fixups;
01930 fixups = fixups->next;
01931 free (f);
01932 }
01933 while (fixups);
01934
01935 contents = bfd_realloc (contents, trampoff);
01936 if (contents == NULL)
01937 goto error_return;
01938
01939 isec->size = (isec->size + 3) & (bfd_vma) -4;
01940
01941 val = trampoff - isec->size + 0x48000000;
01942 dest = contents + isec->size;
01943 isec->size = trampoff;
01944 bfd_put_32 (abfd, val, dest);
01945 dest += 4;
01946
01947 if (link_info->shared)
01948 {
01949 stub = shared_stub_entry;
01950 size = ARRAY_SIZE (shared_stub_entry);
01951 }
01952 else
01953 {
01954 stub = stub_entry;
01955 size = ARRAY_SIZE (stub_entry);
01956 }
01957
01958 i = 0;
01959 while (dest < contents + trampoff)
01960 {
01961 bfd_put_32 (abfd, stub[i], dest);
01962 i++;
01963 if (i == size)
01964 i = 0;
01965 dest += 4;
01966 }
01967 BFD_ASSERT (i == 0);
01968 }
01969
01970 if (isymbuf != NULL
01971 && symtab_hdr->contents != (unsigned char *) isymbuf)
01972 {
01973 if (! link_info->keep_memory)
01974 free (isymbuf);
01975 else
01976 {
01977
01978 symtab_hdr->contents = (unsigned char *) isymbuf;
01979 }
01980 }
01981
01982 if (contents != NULL
01983 && elf_section_data (isec)->this_hdr.contents != contents)
01984 {
01985 if (!changed && !link_info->keep_memory)
01986 free (contents);
01987 else
01988 {
01989
01990 elf_section_data (isec)->this_hdr.contents = contents;
01991 }
01992 }
01993
01994 if (elf_section_data (isec)->relocs != internal_relocs)
01995 {
01996 if (!changed)
01997 free (internal_relocs);
01998 else
01999 elf_section_data (isec)->relocs = internal_relocs;
02000 }
02001
02002 *again = changed;
02003 return TRUE;
02004
02005 error_return:
02006 if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
02007 free (isymbuf);
02008 if (contents != NULL
02009 && elf_section_data (isec)->this_hdr.contents != contents)
02010 free (contents);
02011 if (internal_relocs != NULL
02012 && elf_section_data (isec)->relocs != internal_relocs)
02013 free (internal_relocs);
02014 return FALSE;
02015 }
02016
02017 static reloc_howto_type *
02018 ppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
02019 bfd_reloc_code_real_type code)
02020 {
02021 enum elf_ppc_reloc_type r;
02022
02023
02024 if (!ppc_elf_howto_table[R_PPC_ADDR32])
02025 ppc_elf_howto_init ();
02026
02027 switch (code)
02028 {
02029 default:
02030 return NULL;
02031
02032 case BFD_RELOC_NONE: r = R_PPC_NONE; break;
02033 case BFD_RELOC_32: r = R_PPC_ADDR32; break;
02034 case BFD_RELOC_PPC_BA26: r = R_PPC_ADDR24; break;
02035 case BFD_RELOC_16: r = R_PPC_ADDR16; break;
02036 case BFD_RELOC_LO16: r = R_PPC_ADDR16_LO; break;
02037 case BFD_RELOC_HI16: r = R_PPC_ADDR16_HI; break;
02038 case BFD_RELOC_HI16_S: r = R_PPC_ADDR16_HA; break;
02039 case BFD_RELOC_PPC_BA16: r = R_PPC_ADDR14; break;
02040 case BFD_RELOC_PPC_BA16_BRTAKEN: r = R_PPC_ADDR14_BRTAKEN; break;
02041 case BFD_RELOC_PPC_BA16_BRNTAKEN: r = R_PPC_ADDR14_BRNTAKEN; break;
02042 case BFD_RELOC_PPC_B26: r = R_PPC_REL24; break;
02043 case BFD_RELOC_PPC_B16: r = R_PPC_REL14; break;
02044 case BFD_RELOC_PPC_B16_BRTAKEN: r = R_PPC_REL14_BRTAKEN; break;
02045 case BFD_RELOC_PPC_B16_BRNTAKEN: r = R_PPC_REL14_BRNTAKEN; break;
02046 case BFD_RELOC_16_GOTOFF: r = R_PPC_GOT16; break;
02047 case BFD_RELOC_LO16_GOTOFF: r = R_PPC_GOT16_LO; break;
02048 case BFD_RELOC_HI16_GOTOFF: r = R_PPC_GOT16_HI; break;
02049 case BFD_RELOC_HI16_S_GOTOFF: r = R_PPC_GOT16_HA; break;
02050 case BFD_RELOC_24_PLT_PCREL: r = R_PPC_PLTREL24; break;
02051 case BFD_RELOC_PPC_COPY: r = R_PPC_COPY; break;
02052 case BFD_RELOC_PPC_GLOB_DAT: r = R_PPC_GLOB_DAT; break;
02053 case BFD_RELOC_PPC_LOCAL24PC: r = R_PPC_LOCAL24PC; break;
02054 case BFD_RELOC_32_PCREL: r = R_PPC_REL32; break;
02055 case BFD_RELOC_32_PLTOFF: r = R_PPC_PLT32; break;
02056 case BFD_RELOC_32_PLT_PCREL: r = R_PPC_PLTREL32; break;
02057 case BFD_RELOC_LO16_PLTOFF: r = R_PPC_PLT16_LO; break;
02058 case BFD_RELOC_HI16_PLTOFF: r = R_PPC_PLT16_HI; break;
02059 case BFD_RELOC_HI16_S_PLTOFF: r = R_PPC_PLT16_HA; break;
02060 case BFD_RELOC_GPREL16: r = R_PPC_SDAREL16; break;
02061 case BFD_RELOC_16_BASEREL: r = R_PPC_SECTOFF; break;
02062 case BFD_RELOC_LO16_BASEREL: r = R_PPC_SECTOFF_LO; break;
02063 case BFD_RELOC_HI16_BASEREL: r = R_PPC_SECTOFF_HI; break;
02064 case BFD_RELOC_HI16_S_BASEREL: r = R_PPC_SECTOFF_HA; break;
02065 case BFD_RELOC_CTOR: r = R_PPC_ADDR32; break;
02066 case BFD_RELOC_PPC_TOC16: r = R_PPC_TOC16; break;
02067 case BFD_RELOC_PPC_TLS: r = R_PPC_TLS; break;
02068 case BFD_RELOC_PPC_DTPMOD: r = R_PPC_DTPMOD32; break;
02069 case BFD_RELOC_PPC_TPREL16: r = R_PPC_TPREL16; break;
02070 case BFD_RELOC_PPC_TPREL16_LO: r = R_PPC_TPREL16_LO; break;
02071 case BFD_RELOC_PPC_TPREL16_HI: r = R_PPC_TPREL16_HI; break;
02072 case BFD_RELOC_PPC_TPREL16_HA: r = R_PPC_TPREL16_HA; break;
02073 case BFD_RELOC_PPC_TPREL: r = R_PPC_TPREL32; break;
02074 case BFD_RELOC_PPC_DTPREL16: r = R_PPC_DTPREL16; break;
02075 case BFD_RELOC_PPC_DTPREL16_LO: r = R_PPC_DTPREL16_LO; break;
02076 case BFD_RELOC_PPC_DTPREL16_HI: r = R_PPC_DTPREL16_HI; break;
02077 case BFD_RELOC_PPC_DTPREL16_HA: r = R_PPC_DTPREL16_HA; break;
02078 case BFD_RELOC_PPC_DTPREL: r = R_PPC_DTPREL32; break;
02079 case BFD_RELOC_PPC_GOT_TLSGD16: r = R_PPC_GOT_TLSGD16; break;
02080 case BFD_RELOC_PPC_GOT_TLSGD16_LO: r = R_PPC_GOT_TLSGD16_LO; break;
02081 case BFD_RELOC_PPC_GOT_TLSGD16_HI: r = R_PPC_GOT_TLSGD16_HI; break;
02082 case BFD_RELOC_PPC_GOT_TLSGD16_HA: r = R_PPC_GOT_TLSGD16_HA; break;
02083 case BFD_RELOC_PPC_GOT_TLSLD16: r = R_PPC_GOT_TLSLD16; break;
02084 case BFD_RELOC_PPC_GOT_TLSLD16_LO: r = R_PPC_GOT_TLSLD16_LO; break;
02085 case BFD_RELOC_PPC_GOT_TLSLD16_HI: r = R_PPC_GOT_TLSLD16_HI; break;
02086 case BFD_RELOC_PPC_GOT_TLSLD16_HA: r = R_PPC_GOT_TLSLD16_HA; break;
02087 case BFD_RELOC_PPC_GOT_TPREL16: r = R_PPC_GOT_TPREL16; break;
02088 case BFD_RELOC_PPC_GOT_TPREL16_LO: r = R_PPC_GOT_TPREL16_LO; break;
02089 case BFD_RELOC_PPC_GOT_TPREL16_HI: r = R_PPC_GOT_TPREL16_HI; break;
02090 case BFD_RELOC_PPC_GOT_TPREL16_HA: r = R_PPC_GOT_TPREL16_HA; break;
02091 case BFD_RELOC_PPC_GOT_DTPREL16: r = R_PPC_GOT_DTPREL16; break;
02092 case BFD_RELOC_PPC_GOT_DTPREL16_LO: r = R_PPC_GOT_DTPREL16_LO; break;
02093 case BFD_RELOC_PPC_GOT_DTPREL16_HI: r = R_PPC_GOT_DTPREL16_HI; break;
02094 case BFD_RELOC_PPC_GOT_DTPREL16_HA: r = R_PPC_GOT_DTPREL16_HA; break;
02095 case BFD_RELOC_PPC_EMB_NADDR32: r = R_PPC_EMB_NADDR32; break;
02096 case BFD_RELOC_PPC_EMB_NADDR16: r = R_PPC_EMB_NADDR16; break;
02097 case BFD_RELOC_PPC_EMB_NADDR16_LO: r = R_PPC_EMB_NADDR16_LO; break;
02098 case BFD_RELOC_PPC_EMB_NADDR16_HI: r = R_PPC_EMB_NADDR16_HI; break;
02099 case BFD_RELOC_PPC_EMB_NADDR16_HA: r = R_PPC_EMB_NADDR16_HA; break;
02100 case BFD_RELOC_PPC_EMB_SDAI16: r = R_PPC_EMB_SDAI16; break;
02101 case BFD_RELOC_PPC_EMB_SDA2I16: r = R_PPC_EMB_SDA2I16; break;
02102 case BFD_RELOC_PPC_EMB_SDA2REL: r = R_PPC_EMB_SDA2REL; break;
02103 case BFD_RELOC_PPC_EMB_SDA21: r = R_PPC_EMB_SDA21; break;
02104 case BFD_RELOC_PPC_EMB_MRKREF: r = R_PPC_EMB_MRKREF; break;
02105 case BFD_RELOC_PPC_EMB_RELSEC16: r = R_PPC_EMB_RELSEC16; break;
02106 case BFD_RELOC_PPC_EMB_RELST_LO: r = R_PPC_EMB_RELST_LO; break;
02107 case BFD_RELOC_PPC_EMB_RELST_HI: r = R_PPC_EMB_RELST_HI; break;
02108 case BFD_RELOC_PPC_EMB_RELST_HA: r = R_PPC_EMB_RELST_HA; break;
02109 case BFD_RELOC_PPC_EMB_BIT_FLD: r = R_PPC_EMB_BIT_FLD; break;
02110 case BFD_RELOC_PPC_EMB_RELSDA: r = R_PPC_EMB_RELSDA; break;
02111 case BFD_RELOC_VTABLE_INHERIT: r = R_PPC_GNU_VTINHERIT; break;
02112 case BFD_RELOC_VTABLE_ENTRY: r = R_PPC_GNU_VTENTRY; break;
02113 }
02114
02115 return ppc_elf_howto_table[r];
02116 };
02117
02118
02119
02120 static void
02121 ppc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
02122 arelent *cache_ptr,
02123 Elf_Internal_Rela *dst)
02124 {
02125
02126 if (!ppc_elf_howto_table[R_PPC_ADDR32])
02127 ppc_elf_howto_init ();
02128
02129 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max);
02130 cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
02131 }
02132
02133
02134
02135 static bfd_reloc_status_type
02136 ppc_elf_addr16_ha_reloc (bfd *abfd ATTRIBUTE_UNUSED,
02137 arelent *reloc_entry,
02138 asymbol *symbol,
02139 void *data ATTRIBUTE_UNUSED,
02140 asection *input_section,
02141 bfd *output_bfd,
02142 char **error_message ATTRIBUTE_UNUSED)
02143 {
02144 bfd_vma relocation;
02145
02146 if (output_bfd != NULL)
02147 {
02148 reloc_entry->address += input_section->output_offset;
02149 return bfd_reloc_ok;
02150 }
02151
02152 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
02153 return bfd_reloc_outofrange;
02154
02155 if (bfd_is_com_section (symbol->section))
02156 relocation = 0;
02157 else
02158 relocation = symbol->value;
02159
02160 relocation += symbol->section->output_section->vma;
02161 relocation += symbol->section->output_offset;
02162 relocation += reloc_entry->addend;
02163
02164 reloc_entry->addend += (relocation & 0x8000) << 1;
02165
02166 return bfd_reloc_continue;
02167 }
02168
02169 static bfd_reloc_status_type
02170 ppc_elf_unhandled_reloc (bfd *abfd,
02171 arelent *reloc_entry,
02172 asymbol *symbol,
02173 void *data,
02174 asection *input_section,
02175 bfd *output_bfd,
02176 char **error_message)
02177 {
02178
02179
02180
02181 if (output_bfd != NULL)
02182 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02183 input_section, output_bfd, error_message);
02184
02185 if (error_message != NULL)
02186 {
02187 static char buf[60];
02188 sprintf (buf, _("generic linker can't handle %s"),
02189 reloc_entry->howto->name);
02190 *error_message = buf;
02191 }
02192 return bfd_reloc_dangerous;
02193 }
02194
02195
02196
02197
02198 static bfd_boolean
02199 ppc_elf_object_p (bfd *abfd)
02200 {
02201 if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 64)
02202 {
02203 Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd);
02204
02205 if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS32)
02206 {
02207
02208 abfd->arch_info = abfd->arch_info->next;
02209 BFD_ASSERT (abfd->arch_info->bits_per_word == 32);
02210 }
02211 }
02212 return TRUE;
02213 }
02214
02215
02216
02217 static bfd_boolean
02218 ppc_elf_set_private_flags (bfd *abfd, flagword flags)
02219 {
02220 BFD_ASSERT (!elf_flags_init (abfd)
02221 || elf_elfheader (abfd)->e_flags == flags);
02222
02223 elf_elfheader (abfd)->e_flags = flags;
02224 elf_flags_init (abfd) = TRUE;
02225 return TRUE;
02226 }
02227
02228
02229
02230 static bfd_boolean
02231 is_ppc_elf_target (const struct bfd_target *targ)
02232 {
02233 extern const bfd_target bfd_elf32_powerpc_vec;
02234 extern const bfd_target bfd_elf32_powerpcle_vec;
02235
02236 return targ == &bfd_elf32_powerpc_vec || targ == &bfd_elf32_powerpcle_vec;
02237 }
02238
02239
02240
02241
02242 static bfd_boolean
02243 ppc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
02244 {
02245 flagword old_flags;
02246 flagword new_flags;
02247 bfd_boolean error;
02248
02249 if (!is_ppc_elf_target (ibfd->xvec)
02250 || !is_ppc_elf_target (obfd->xvec))
02251 return TRUE;
02252
02253
02254 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
02255 return FALSE;
02256
02257 new_flags = elf_elfheader (ibfd)->e_flags;
02258 old_flags = elf_elfheader (obfd)->e_flags;
02259 if (!elf_flags_init (obfd))
02260 {
02261
02262 elf_flags_init (obfd) = TRUE;
02263 elf_elfheader (obfd)->e_flags = new_flags;
02264 }
02265
02266
02267 else if (new_flags == old_flags)
02268 ;
02269
02270
02271 else
02272 {
02273
02274
02275 error = FALSE;
02276 if ((new_flags & EF_PPC_RELOCATABLE) != 0
02277 && (old_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0)
02278 {
02279 error = TRUE;
02280 (*_bfd_error_handler)
02281 (_("%B: compiled with -mrelocatable and linked with "
02282 "modules compiled normally"), ibfd);
02283 }
02284 else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
02285 && (old_flags & EF_PPC_RELOCATABLE) != 0)
02286 {
02287 error = TRUE;
02288 (*_bfd_error_handler)
02289 (_("%B: compiled normally and linked with "
02290 "modules compiled with -mrelocatable"), ibfd);
02291 }
02292
02293
02294 if (! (new_flags & EF_PPC_RELOCATABLE_LIB))
02295 elf_elfheader (obfd)->e_flags &= ~EF_PPC_RELOCATABLE_LIB;
02296
02297
02298
02299 if (! (elf_elfheader (obfd)->e_flags & EF_PPC_RELOCATABLE_LIB)
02300 && (new_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE))
02301 && (old_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE)))
02302 elf_elfheader (obfd)->e_flags |= EF_PPC_RELOCATABLE;
02303
02304
02305
02306 elf_elfheader (obfd)->e_flags |= (new_flags & EF_PPC_EMB);
02307
02308 new_flags &= ~(EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB);
02309 old_flags &= ~(EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB);
02310
02311
02312 if (new_flags != old_flags)
02313 {
02314 error = TRUE;
02315 (*_bfd_error_handler)
02316 (_("%B: uses different e_flags (0x%lx) fields "
02317 "than previous modules (0x%lx)"),
02318 ibfd, (long) new_flags, (long) old_flags);
02319 }
02320
02321 if (error)
02322 {
02323 bfd_set_error (bfd_error_bad_value);
02324 return FALSE;
02325 }
02326 }
02327
02328 return TRUE;
02329 }
02330
02331
02332
02333
02334 static bfd_boolean
02335 ppc_elf_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, const char *name)
02336 {
02337 asection *newsect;
02338 flagword flags;
02339
02340 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
02341 return FALSE;
02342
02343 newsect = hdr->bfd_section;
02344 flags = bfd_get_section_flags (abfd, newsect);
02345 if (hdr->sh_flags & SHF_EXCLUDE)
02346 flags |= SEC_EXCLUDE;
02347
02348 if (hdr->sh_type == SHT_ORDERED)
02349 flags |= SEC_SORT_ENTRIES;
02350
02351 bfd_set_section_flags (abfd, newsect, flags);
02352 return TRUE;
02353 }
02354
02355
02356
02357 static bfd_boolean
02358 ppc_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
02359 Elf_Internal_Shdr *shdr,
02360 asection *asect)
02361 {
02362 if ((asect->flags & SEC_EXCLUDE) != 0)
02363 shdr->sh_flags |= SHF_EXCLUDE;
02364
02365 if ((asect->flags & SEC_SORT_ENTRIES) != 0)
02366 shdr->sh_type = SHT_ORDERED;
02367
02368 return TRUE;
02369 }
02370
02371
02372
02373 static elf_linker_section_pointers_t *
02374 elf_find_pointer_linker_section
02375 (elf_linker_section_pointers_t *linker_pointers,
02376 bfd_vma addend,
02377 elf_linker_section_t *lsect)
02378 {
02379 for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
02380 if (lsect == linker_pointers->lsect && addend == linker_pointers->addend)
02381 return linker_pointers;
02382
02383 return NULL;
02384 }
02385
02386
02387
02388 static bfd_boolean
02389 elf_create_pointer_linker_section (bfd *abfd,
02390 struct bfd_link_info *info,
02391 elf_linker_section_t *lsect,
02392 struct elf_link_hash_entry *h,
02393 const Elf_Internal_Rela *rel)
02394 {
02395 elf_linker_section_pointers_t **ptr_linker_section_ptr = NULL;
02396 elf_linker_section_pointers_t *linker_section_ptr;
02397 unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
02398 bfd_size_type amt;
02399
02400 BFD_ASSERT (lsect != NULL);
02401
02402
02403 if (h != NULL)
02404 {
02405 struct ppc_elf_link_hash_entry *eh;
02406
02407
02408 eh = (struct ppc_elf_link_hash_entry *) h;
02409 if (elf_find_pointer_linker_section (eh->linker_section_pointer,
02410 rel->r_addend,
02411 lsect))
02412 return TRUE;
02413
02414 ptr_linker_section_ptr = &eh->linker_section_pointer;
02415
02416 if (h->dynindx == -1)
02417 {
02418 if (! bfd_elf_link_record_dynamic_symbol (info, h))
02419 return FALSE;
02420 }
02421
02422 if (lsect->rel_section)
02423 lsect->rel_section->size += sizeof (Elf32_External_Rela);
02424 }
02425 else
02426 {
02427
02428 elf_linker_section_pointers_t **ptr = elf_local_ptr_offsets (abfd);
02429
02430
02431 if (!ptr)
02432 {
02433 unsigned int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info;
02434
02435 amt = num_symbols;
02436 amt *= sizeof (elf_linker_section_pointers_t *);
02437 ptr = bfd_zalloc (abfd, amt);
02438
02439 if (!ptr)
02440 return FALSE;
02441
02442 elf_local_ptr_offsets (abfd) = ptr;
02443 }
02444
02445
02446 if (elf_find_pointer_linker_section (ptr[r_symndx],
02447 rel->r_addend,
02448 lsect))
02449 return TRUE;
02450
02451 ptr_linker_section_ptr = &ptr[r_symndx];
02452
02453 if (info->shared)
02454 {
02455
02456
02457
02458 BFD_ASSERT (lsect->rel_section != NULL);
02459 lsect->rel_section->size += sizeof (Elf32_External_Rela);
02460 }
02461 }
02462
02463
02464
02465 BFD_ASSERT (ptr_linker_section_ptr != NULL);
02466 amt = sizeof (elf_linker_section_pointers_t);
02467 linker_section_ptr = bfd_alloc (abfd, amt);
02468
02469 if (!linker_section_ptr)
02470 return FALSE;
02471
02472 linker_section_ptr->next = *ptr_linker_section_ptr;
02473 linker_section_ptr->addend = rel->r_addend;
02474 linker_section_ptr->lsect = lsect;
02475 linker_section_ptr->written_address_p = FALSE;
02476 *ptr_linker_section_ptr = linker_section_ptr;
02477
02478 linker_section_ptr->offset = lsect->section->size;
02479 lsect->section->size += 4;
02480
02481 #ifdef DEBUG
02482 fprintf (stderr,
02483 "Create pointer in linker section %s, offset = %ld, section size = %ld\n",
02484 lsect->name, (long) linker_section_ptr->offset,
02485 (long) lsect->section->size);
02486 #endif
02487
02488 return TRUE;
02489 }
02490
02491 #define bfd_put_ptr(BFD, VAL, ADDR) bfd_put_32 (BFD, VAL, ADDR)
02492
02493
02494
02495 static bfd_vma
02496 elf_finish_pointer_linker_section (bfd *output_bfd,
02497 bfd *input_bfd,
02498 struct bfd_link_info *info,
02499 elf_linker_section_t *lsect,
02500 struct elf_link_hash_entry *h,
02501 bfd_vma relocation,
02502 const Elf_Internal_Rela *rel,
02503 int relative_reloc)
02504 {
02505 elf_linker_section_pointers_t *linker_section_ptr;
02506
02507 BFD_ASSERT (lsect != NULL);
02508
02509 if (h != NULL)
02510 {
02511
02512 struct ppc_elf_link_hash_entry *eh;
02513
02514 eh = (struct ppc_elf_link_hash_entry *) h;
02515 linker_section_ptr
02516 = elf_find_pointer_linker_section (eh->linker_section_pointer,
02517 rel->r_addend,
02518 lsect);
02519
02520 BFD_ASSERT (linker_section_ptr != NULL);
02521
02522 if (! elf_hash_table (info)->dynamic_sections_created
02523 || (info->shared
02524 && info->symbolic
02525 && h->def_regular))
02526 {
02527
02528
02529
02530
02531
02532
02533
02534
02535 if (!linker_section_ptr->written_address_p)
02536 {
02537 linker_section_ptr->written_address_p = TRUE;
02538 bfd_put_ptr (output_bfd,
02539 relocation + linker_section_ptr->addend,
02540 (lsect->section->contents
02541 + linker_section_ptr->offset));
02542 }
02543 }
02544 }
02545 else
02546 {
02547
02548 unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
02549 BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL);
02550 BFD_ASSERT (elf_local_ptr_offsets (input_bfd)[r_symndx] != NULL);
02551 linker_section_ptr = (elf_find_pointer_linker_section
02552 (elf_local_ptr_offsets (input_bfd)[r_symndx],
02553 rel->r_addend,
02554 lsect));
02555
02556 BFD_ASSERT (linker_section_ptr != NULL);
02557
02558
02559 if (!linker_section_ptr->written_address_p)
02560 {
02561 linker_section_ptr->written_address_p = TRUE;
02562 bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend,
02563 lsect->section->contents + linker_section_ptr->offset);
02564
02565 if (info->shared)
02566 {
02567
02568
02569
02570 asection *srel = lsect->rel_section;
02571 Elf_Internal_Rela outrel[MAX_INT_RELS_PER_EXT_REL];
02572 bfd_byte *erel;
02573 const struct elf_backend_data *bed;
02574 unsigned int i;
02575
02576 BFD_ASSERT (srel != NULL);
02577
02578 bed = get_elf_backend_data (output_bfd);
02579 for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
02580 {
02581 outrel[i].r_offset = (lsect->section->output_section->vma
02582 + lsect->section->output_offset
02583 + linker_section_ptr->offset);
02584 outrel[i].r_info = 0;
02585 outrel[i].r_addend = 0;
02586 }
02587 outrel[0].r_info = ELF32_R_INFO (0, relative_reloc);
02588 erel = lsect->section->contents;
02589 erel += (elf_section_data (lsect->section)->rel_count++
02590 * sizeof (Elf32_External_Rela));
02591 bfd_elf32_swap_reloca_out (output_bfd, outrel, erel);
02592 }
02593 }
02594 }
02595
02596 relocation = (lsect->section->output_offset
02597 + linker_section_ptr->offset
02598 - lsect->sym_offset);
02599
02600 #ifdef DEBUG
02601 fprintf (stderr,
02602 "Finish pointer in linker section %s, offset = %ld (0x%lx)\n",
02603 lsect->name, (long) relocation, (long) relocation);
02604 #endif
02605
02606
02607
02608 return relocation - linker_section_ptr->addend;
02609 }
02610
02611
02612 static elf_linker_section_t *
02613 ppc_elf_create_linker_section (bfd *abfd,
02614 struct bfd_link_info *info,
02615 enum elf_linker_section_enum which)
02616 {
02617 elf_linker_section_t *lsect;
02618 struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
02619 asection *s, *sym_sec;
02620 bfd_size_type amt;
02621 flagword flags;
02622 const char *name;
02623 const char *rel_name;
02624 const char *sym_name;
02625 bfd_vma sym_offset;
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
02636 | SEC_LINKER_CREATED);
02637 sym_offset = 32768;
02638
02639 switch (which)
02640 {
02641 default:
02642 abort ();
02643 return NULL;
02644
02645 case LINKER_SECTION_SDATA:
02646 name = ".sdata";
02647 rel_name = ".rela.sdata";
02648 sym_name = "_SDA_BASE_";
02649 break;
02650
02651 case LINKER_SECTION_SDATA2:
02652 name = ".sdata2";
02653 rel_name = ".rela.sdata2";
02654 sym_name = "_SDA2_BASE_";
02655 flags |= SEC_READONLY;
02656 break;
02657 }
02658
02659
02660 if (!htab->elf.dynobj)
02661 htab->elf.dynobj = abfd;
02662
02663 amt = sizeof (elf_linker_section_t);
02664 lsect = bfd_zalloc (htab->elf.dynobj, amt);
02665
02666 lsect->sym_offset = sym_offset;
02667
02668
02669 sym_sec = s = bfd_get_section_by_name (htab->elf.dynobj, name);
02670 if (s == NULL || (s->flags & flags) != flags)
02671 {
02672 s = bfd_make_section_anyway (htab->elf.dynobj, name);
02673 if (s == NULL
02674 || !bfd_set_section_flags (htab->elf.dynobj, s, flags))
02675 return NULL;
02676 if (sym_sec == NULL)
02677 sym_sec = s;
02678 }
02679 lsect->section = s;
02680
02681 if (bfd_get_section_alignment (htab->elf.dynobj, s) < 2
02682 && !bfd_set_section_alignment (htab->elf.dynobj, s, 2))
02683 return NULL;
02684
02685 s->size = align_power (s->size, 2);
02686
02687 #ifdef DEBUG
02688 fprintf (stderr, "Creating section %s, current size = %ld\n",
02689 name, (long) s->size);
02690 #endif
02691
02692 if (sym_name)
02693 {
02694 struct elf_link_hash_entry *h;
02695 struct bfd_link_hash_entry *bh;
02696
02697 #ifdef DEBUG
02698 fprintf (stderr, "Adding %s to section %s\n", sym_name, name);
02699 #endif
02700 bh = bfd_link_hash_lookup (info->hash, sym_name,
02701 FALSE, FALSE, FALSE);
02702
02703 if ((bh == NULL || bh->type == bfd_link_hash_undefined)
02704 && !(_bfd_generic_link_add_one_symbol
02705 (info, abfd, sym_name, BSF_GLOBAL, sym_sec, sym_offset, NULL,
02706 FALSE, get_elf_backend_data (abfd)->collect, &bh)))
02707 return NULL;
02708 h = (struct elf_link_hash_entry *) bh;
02709
02710 h->type = STT_OBJECT;
02711 lsect->sym_hash = h;
02712
02713 if (info->shared
02714 && ! bfd_elf_link_record_dynamic_symbol (info, h))
02715 return NULL;
02716 }
02717
02718 if (info->shared)
02719 {
02720 s = bfd_make_section_anyway (htab->elf.dynobj, rel_name);
02721 lsect->rel_section = s;
02722 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
02723 | SEC_LINKER_CREATED | SEC_READONLY);
02724 if (s == NULL
02725 || ! bfd_set_section_flags (htab->elf.dynobj, s, flags)
02726 || ! bfd_set_section_alignment (htab->elf.dynobj, s, 2))
02727 return NULL;
02728 }
02729
02730 return lsect;
02731 }
02732
02733
02734
02735
02736 static int
02737 ppc_elf_additional_program_headers (bfd *abfd)
02738 {
02739 asection *s;
02740 int ret = 0;
02741
02742 s = bfd_get_section_by_name (abfd, ".sbss2");
02743 if (s != NULL && (s->flags & SEC_ALLOC) != 0)
02744 ++ret;
02745
02746 s = bfd_get_section_by_name (abfd, ".PPC.EMB.sbss0");
02747 if (s != NULL && (s->flags & SEC_ALLOC) != 0)
02748 ++ret;
02749
02750 return ret;
02751 }
02752
02753
02754
02755 static bfd_boolean
02756 ppc_elf_create_got (bfd *abfd, struct bfd_link_info *info)
02757 {
02758 struct ppc_elf_link_hash_table *htab;
02759 asection *s;
02760 flagword flags;
02761
02762 if (!_bfd_elf_create_got_section (abfd, info))
02763 return FALSE;
02764
02765 htab = ppc_elf_hash_table (info);
02766 htab->got = s = bfd_get_section_by_name (abfd, ".got");
02767 if (s == NULL)
02768 abort ();
02769
02770 flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
02771 | SEC_LINKER_CREATED);
02772 if (!bfd_set_section_flags (abfd, s, flags))
02773 return FALSE;
02774
02775 htab->relgot = bfd_make_section (abfd, ".rela.got");
02776 if (!htab->relgot
02777 || ! bfd_set_section_flags (abfd, htab->relgot,
02778 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
02779 | SEC_IN_MEMORY | SEC_LINKER_CREATED
02780 | SEC_READONLY))
02781 || ! bfd_set_section_alignment (abfd, htab->relgot, 2))
02782 return FALSE;
02783
02784 return TRUE;
02785 }
02786
02787
02788
02789
02790
02791 static bfd_boolean
02792 ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
02793 {
02794 struct ppc_elf_link_hash_table *htab;
02795 asection *s;
02796 flagword flags;
02797
02798 htab = ppc_elf_hash_table (info);
02799
02800 if (htab->got == NULL
02801 && !ppc_elf_create_got (abfd, info))
02802 return FALSE;
02803
02804 if (!_bfd_elf_create_dynamic_sections (abfd, info))
02805 return FALSE;
02806
02807 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
02808 | SEC_LINKER_CREATED);
02809
02810 htab->dynbss = bfd_get_section_by_name (abfd, ".dynbss");
02811 htab->dynsbss = s = bfd_make_section (abfd, ".dynsbss");
02812 if (s == NULL
02813 || ! bfd_set_section_flags (abfd, s, SEC_ALLOC | SEC_LINKER_CREATED))
02814 return FALSE;
02815
02816 if (! info->shared)
02817 {
02818 htab->relbss = bfd_get_section_by_name (abfd, ".rela.bss");
02819 htab->relsbss = s = bfd_make_section (abfd, ".rela.sbss");
02820 if (s == NULL
02821 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
02822 || ! bfd_set_section_alignment (abfd, s, 2))
02823 return FALSE;
02824 }
02825
02826 htab->relplt = bfd_get_section_by_name (abfd, ".rela.plt");
02827 htab->plt = s = bfd_get_section_by_name (abfd, ".plt");
02828 if (s == NULL)
02829 abort ();
02830
02831 flags = SEC_ALLOC | SEC_CODE | SEC_IN_MEMORY | SEC_LINKER_CREATED;
02832 return bfd_set_section_flags (abfd, s, flags);
02833 }
02834
02835
02836
02837
02838
02839
02840
02841 static bfd_boolean
02842 ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
02843 struct elf_link_hash_entry *h)
02844 {
02845 struct ppc_elf_link_hash_table *htab;
02846 asection *s;
02847 unsigned int power_of_two;
02848
02849 #ifdef DEBUG
02850 fprintf (stderr, "ppc_elf_adjust_dynamic_symbol called for %s\n",
02851 h->root.root.string);
02852 #endif
02853
02854
02855 htab = ppc_elf_hash_table (info);
02856 BFD_ASSERT (htab->elf.dynobj != NULL
02857 && (h->needs_plt
02858 || h->u.weakdef != NULL
02859 || (h->def_dynamic
02860 && h->ref_regular
02861 && !h->def_regular)));
02862
02863
02864 if (h->type == STT_FUNC
02865 || h->needs_plt)
02866 {
02867
02868
02869 if (h->plt.refcount <= 0
02870 || SYMBOL_CALLS_LOCAL (info, h)
02871 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
02872 && h->root.type == bfd_link_hash_undefweak))
02873 {
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884 h->plt.offset = (bfd_vma) -1;
02885 h->needs_plt = 0;
02886 }
02887 return TRUE;
02888 }
02889 else
02890 h->plt.offset = (bfd_vma) -1;
02891
02892
02893
02894
02895 if (h->u.weakdef != NULL)
02896 {
02897 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
02898 || h->u.weakdef->root.type == bfd_link_hash_defweak);
02899 h->root.u.def.section = h->u.weakdef->root.u.def.section;
02900 h->root.u.def.value = h->u.weakdef->root.u.def.value;
02901 if (ELIMINATE_COPY_RELOCS)
02902 h->non_got_ref = h->u.weakdef->non_got_ref;
02903 return TRUE;
02904 }
02905
02906
02907
02908
02909
02910
02911
02912
02913 if (info->shared)
02914 return TRUE;
02915
02916
02917
02918 if (!h->non_got_ref)
02919 return TRUE;
02920
02921 if (ELIMINATE_COPY_RELOCS)
02922 {
02923 struct ppc_elf_dyn_relocs *p;
02924 for (p = ppc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
02925 {
02926 s = p->sec->output_section;
02927 if (s != NULL && (s->flags & SEC_READONLY) != 0)
02928 break;
02929 }
02930
02931
02932
02933 if (p == NULL)
02934 {
02935 h->non_got_ref = 0;
02936 return TRUE;
02937 }
02938 }
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954 if (h->size <= elf_gp_size (htab->elf.dynobj))
02955 s = htab->dynsbss;
02956 else
02957 s = htab->dynbss;
02958 BFD_ASSERT (s != NULL);
02959
02960
02961
02962
02963
02964 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
02965 {
02966 asection *srel;
02967
02968 if (h->size <= elf_gp_size (htab->elf.dynobj))
02969 srel = htab->relsbss;
02970 else
02971 srel = htab->relbss;
02972 BFD_ASSERT (srel != NULL);
02973 srel->size += sizeof (Elf32_External_Rela);
02974 h->needs_copy = 1;
02975 }
02976
02977
02978
02979 power_of_two = bfd_log2 (h->size);
02980 if (power_of_two > 4)
02981 power_of_two = 4;
02982
02983
02984 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
02985 if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
02986 {
02987 if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
02988 return FALSE;
02989 }
02990
02991
02992 h->root.u.def.section = s;
02993 h->root.u.def.value = s->size;
02994
02995
02996 s->size += h->size;
02997
02998 return TRUE;
02999 }
03000
03001
03002
03003
03004
03005 #define MUST_BE_DYN_RELOC(RTYPE) \
03006 ((RTYPE) != R_PPC_REL24 \
03007 && (RTYPE) != R_PPC_REL14 \
03008 && (RTYPE) != R_PPC_REL14_BRTAKEN \
03009 && (RTYPE) != R_PPC_REL14_BRNTAKEN \
03010 && (RTYPE) != R_PPC_REL32)
03011
03012
03013
03014 static bfd_boolean
03015 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
03016 {
03017 struct bfd_link_info *info = inf;
03018 struct ppc_elf_link_hash_entry *eh;
03019 struct ppc_elf_link_hash_table *htab;
03020 struct ppc_elf_dyn_relocs *p;
03021
03022 if (h->root.type == bfd_link_hash_indirect)
03023 return TRUE;
03024
03025 if (h->root.type == bfd_link_hash_warning)
03026
03027
03028
03029 h = (struct elf_link_hash_entry *) h->root.u.i.link;
03030
03031 htab = ppc_elf_hash_table (info);
03032 if (htab->elf.dynamic_sections_created
03033 && h->plt.refcount > 0)
03034 {
03035
03036 if (h->dynindx == -1
03037 && !h->forced_local)
03038 {
03039 if (! bfd_elf_link_record_dynamic_symbol (info, h))
03040 return FALSE;
03041 }
03042
03043 if (info->shared
03044 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
03045 {
03046 asection *s = htab->plt;
03047
03048
03049
03050 if (s->size == 0)
03051 s->size += PLT_INITIAL_ENTRY_SIZE;
03052
03053
03054
03055
03056 h->plt.offset = (PLT_INITIAL_ENTRY_SIZE
03057 + (PLT_SLOT_SIZE
03058 * ((s->size - PLT_INITIAL_ENTRY_SIZE)
03059 / PLT_ENTRY_SIZE)));
03060
03061
03062
03063
03064
03065
03066 if (! info->shared
03067 && !h->def_regular)
03068 {
03069 h->root.u.def.section = s;
03070 h->root.u.def.value = h->plt.offset;
03071 }
03072
03073
03074
03075 s->size += PLT_ENTRY_SIZE;
03076 if ((s->size - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
03077 > PLT_NUM_SINGLE_ENTRIES)
03078 s->size += PLT_ENTRY_SIZE;
03079
03080
03081 htab->relplt->size += sizeof (Elf32_External_Rela);
03082 }
03083 else
03084 {
03085 h->plt.offset = (bfd_vma) -1;
03086 h->needs_plt = 0;
03087 }
03088 }
03089 else
03090 {
03091 h->plt.offset = (bfd_vma) -1;
03092 h->needs_plt = 0;
03093 }
03094
03095 eh = (struct ppc_elf_link_hash_entry *) h;
03096 if (eh->elf.got.refcount > 0)
03097 {
03098
03099 if (eh->elf.dynindx == -1
03100 && !eh->elf.forced_local)
03101 {
03102 if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf))
03103 return FALSE;
03104 }
03105
03106 if (eh->tls_mask == (TLS_TLS | TLS_LD)
03107 && !eh->elf.def_dynamic)
03108
03109 eh->elf.got.offset = (bfd_vma) -1;
03110 else
03111 {
03112 bfd_boolean dyn;
03113 eh->elf.got.offset = htab->got->size;
03114 if ((eh->tls_mask & TLS_TLS) != 0)
03115 {
03116 if ((eh->tls_mask & TLS_LD) != 0)
03117 htab->got->size += 8;
03118 if ((eh->tls_mask & TLS_GD) != 0)
03119 htab->got->size += 8;
03120 if ((eh->tls_mask & (TLS_TPREL | TLS_TPRELGD)) != 0)
03121 htab->got->size += 4;
03122 if ((eh->tls_mask & TLS_DTPREL) != 0)
03123 htab->got->size += 4;
03124 }
03125 else
03126 htab->got->size += 4;
03127 dyn = htab->elf.dynamic_sections_created;
03128 if ((info->shared
03129 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
03130 && (ELF_ST_VISIBILITY (eh->elf.other) == STV_DEFAULT
03131 || eh->elf.root.type != bfd_link_hash_undefweak))
03132 {
03133
03134 htab->relgot->size
03135 += ((htab->got->size - eh->elf.got.offset) / 4
03136 * sizeof (Elf32_External_Rela));
03137
03138 if ((eh->tls_mask & TLS_LD) != 0)
03139 htab->relgot->size -= sizeof (Elf32_External_Rela);
03140 }
03141 }
03142 }
03143 else
03144 eh->elf.got.offset = (bfd_vma) -1;
03145
03146 if (eh->dyn_relocs == NULL)
03147 return TRUE;
03148
03149
03150
03151
03152
03153
03154
03155 if (info->shared)
03156 {
03157
03158
03159
03160
03161
03162
03163 if (SYMBOL_CALLS_LOCAL (info, h))
03164 {
03165 struct ppc_elf_dyn_relocs **pp;
03166
03167 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
03168 {
03169 p->count -= p->pc_count;
03170 p->pc_count = 0;
03171 if (p->count == 0)
03172 *pp = p->next;
03173 else
03174 pp = &p->next;
03175 }
03176 }
03177
03178
03179
03180 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
03181 && h->root.type == bfd_link_hash_undefweak)
03182 eh->dyn_relocs = NULL;
03183
03184
03185
03186 if (info->pie
03187 && eh->dyn_relocs != NULL
03188 && h->dynindx == -1
03189 && h->root.type == bfd_link_hash_undefweak
03190 && !h->forced_local)
03191 {
03192 if (! bfd_elf_link_record_dynamic_symbol (info, h))
03193 return FALSE;
03194 }
03195 }
03196 else if (ELIMINATE_COPY_RELOCS)
03197 {
03198
03199
03200
03201
03202 if (!h->non_got_ref
03203 && h->def_dynamic
03204 && !h->def_regular)
03205 {
03206
03207
03208 if (h->dynindx == -1
03209 && !h->forced_local)
03210 {
03211 if (! bfd_elf_link_record_dynamic_symbol (info, h))
03212 return FALSE;
03213 }
03214
03215
03216
03217 if (h->dynindx != -1)
03218 goto keep;
03219 }
03220
03221 eh->dyn_relocs = NULL;
03222
03223 keep: ;
03224 }
03225
03226
03227 for (p = eh->dyn_relocs; p != NULL; p = p->next)
03228 {
03229 asection *sreloc = elf_section_data (p->sec)->sreloc;
03230 sreloc->size += p->count * sizeof (Elf32_External_Rela);
03231 }
03232
03233 return TRUE;
03234 }
03235
03236
03237
03238 static bfd_boolean
03239 readonly_dynrelocs (struct elf_link_hash_entry *h, void *info)
03240 {
03241 struct ppc_elf_dyn_relocs *p;
03242
03243 if (h->root.type == bfd_link_hash_indirect)
03244 return TRUE;
03245
03246 if (h->root.type == bfd_link_hash_warning)
03247 h = (struct elf_link_hash_entry *) h->root.u.i.link;
03248
03249 for (p = ppc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
03250 {
03251 asection *s = p->sec->output_section;
03252
03253 if (s != NULL
03254 && ((s->flags & (SEC_READONLY | SEC_ALLOC))
03255 == (SEC_READONLY | SEC_ALLOC)))
03256 {
03257 ((struct bfd_link_info *) info)->flags |= DF_TEXTREL;
03258
03259
03260 return FALSE;
03261 }
03262 }
03263 return TRUE;
03264 }
03265
03266
03267
03268 static bfd_boolean
03269 ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
03270 struct bfd_link_info *info)
03271 {
03272 struct ppc_elf_link_hash_table *htab;
03273 asection *s;
03274 bfd_boolean relocs;
03275 bfd *ibfd;
03276
03277 #ifdef DEBUG
03278 fprintf (stderr, "ppc_elf_size_dynamic_sections called\n");
03279 #endif
03280
03281 htab = ppc_elf_hash_table (info);
03282 BFD_ASSERT (htab->elf.dynobj != NULL);
03283
03284 if (elf_hash_table (info)->dynamic_sections_created)
03285 {
03286
03287 if (info->executable)
03288 {
03289 s = bfd_get_section_by_name (htab->elf.dynobj, ".interp");
03290 BFD_ASSERT (s != NULL);
03291 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
03292 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
03293 }
03294 }
03295
03296 if (htab->tlsld_got.refcount > 0)
03297 {
03298 htab->tlsld_got.offset = htab->got->size;
03299 htab->got->size += 8;
03300 if (info->shared)
03301 htab->relgot->size += sizeof (Elf32_External_Rela);
03302 }
03303 else
03304 htab->tlsld_got.offset = (bfd_vma) -1;
03305
03306
03307
03308 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
03309 {
03310 bfd_signed_vma *local_got;
03311 bfd_signed_vma *end_local_got;
03312 char *lgot_masks;
03313 bfd_size_type locsymcount;
03314 Elf_Internal_Shdr *symtab_hdr;
03315 asection *srel;
03316
03317 if (!is_ppc_elf_target (ibfd->xvec))
03318 continue;
03319
03320 for (s = ibfd->sections; s != NULL; s = s->next)
03321 {
03322 struct ppc_elf_dyn_relocs *p;
03323
03324 for (p = ((struct ppc_elf_dyn_relocs *)
03325 elf_section_data (s)->local_dynrel);
03326 p != NULL;
03327 p = p->next)
03328 {
03329 if (!bfd_is_abs_section (p->sec)
03330 && bfd_is_abs_section (p->sec->output_section))
03331 {
03332
03333
03334
03335
03336 }
03337 else if (p->count != 0)
03338 {
03339 elf_section_data (p->sec)->sreloc->size
03340 += p->count * sizeof (Elf32_External_Rela);
03341 if ((p->sec->output_section->flags
03342 & (SEC_READONLY | SEC_ALLOC))
03343 == (SEC_READONLY | SEC_ALLOC))
03344 info->flags |= DF_TEXTREL;
03345 }
03346 }
03347 }
03348
03349 local_got = elf_local_got_refcounts (ibfd);
03350 if (!local_got)
03351 continue;
03352
03353 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
03354 locsymcount = symtab_hdr->sh_info;
03355 end_local_got = local_got + locsymcount;
03356 lgot_masks = (char *) end_local_got;
03357 s = htab->got;
03358 srel = htab->relgot;
03359 for (; local_got < end_local_got; ++local_got, ++lgot_masks)
03360 if (*local_got > 0)
03361 {
03362 if (*lgot_masks == (TLS_TLS | TLS_LD))
03363 {
03364
03365
03366 if (htab->tlsld_got.offset == (bfd_vma) -1)
03367 {
03368 htab->tlsld_got.offset = s->size;
03369 s->size += 8;
03370 if (info->shared)
03371 srel->size += sizeof (Elf32_External_Rela);
03372 }
03373 *local_got = (bfd_vma) -1;
03374 }
03375 else
03376 {
03377 *local_got = s->size;
03378 if ((*lgot_masks & TLS_TLS) != 0)
03379 {
03380 if ((*lgot_masks & TLS_GD) != 0)
03381 s->size += 8;
03382 if ((*lgot_masks & (TLS_TPREL | TLS_TPRELGD)) != 0)
03383 s->size += 4;
03384 if ((*lgot_masks & TLS_DTPREL) != 0)
03385 s->size += 4;
03386 }
03387 else
03388 s->size += 4;
03389 if (info->shared)
03390 srel->size += ((s->size - *local_got) / 4
03391 * sizeof (Elf32_External_Rela));
03392 }
03393 }
03394 else
03395 *local_got = (bfd_vma) -1;
03396 }
03397
03398
03399 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
03400
03401
03402
03403 relocs = FALSE;
03404 for (s = htab->elf.dynobj->sections; s != NULL; s = s->next)
03405 {
03406 if ((s->flags & SEC_LINKER_CREATED) == 0)
03407 continue;
03408
03409 if (s == htab->plt
03410 || s == htab->got)
03411 {
03412
03413
03414 }
03415 else if ((htab->sdata != NULL && s == htab->sdata->section)
03416 || (htab->sdata2 != NULL && s == htab->sdata2->section))
03417 {
03418 if (s->size == 0)
03419
03420
03421
03422 continue;
03423 }
03424 else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
03425 {
03426 if (s->size == 0)
03427 {
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437 }
03438 else
03439 {
03440
03441 relocs = TRUE;
03442
03443
03444
03445 s->reloc_count = 0;
03446 }
03447 }
03448 else
03449 {
03450
03451 continue;
03452 }
03453
03454 if (s->size == 0)
03455 {
03456 _bfd_strip_section_from_output (info, s);
03457 continue;
03458 }
03459
03460
03461 s->contents = bfd_zalloc (htab->elf.dynobj, s->size);
03462 if (s->contents == NULL)
03463 return FALSE;
03464 }
03465
03466 if (htab->elf.dynamic_sections_created)
03467 {
03468
03469
03470
03471
03472
03473 #define add_dynamic_entry(TAG, VAL) \
03474 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
03475
03476 if (info->executable)
03477 {
03478 if (!add_dynamic_entry (DT_DEBUG, 0))
03479 return FALSE;
03480 }
03481
03482 if (htab->plt != NULL && htab->plt->size != 0)
03483 {
03484 if (!add_dynamic_entry (DT_PLTGOT, 0)
03485 || !add_dynamic_entry (DT_PLTRELSZ, 0)
03486 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
03487 || !add_dynamic_entry (DT_JMPREL, 0))
03488 return FALSE;
03489 }
03490
03491 if (relocs)
03492 {
03493 if (!add_dynamic_entry (DT_RELA, 0)
03494 || !add_dynamic_entry (DT_RELASZ, 0)
03495 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
03496 return FALSE;
03497 }
03498
03499
03500
03501 if ((info->flags & DF_TEXTREL) == 0)
03502 elf_link_hash_traverse (elf_hash_table (info), readonly_dynrelocs,
03503 info);
03504
03505 if ((info->flags & DF_TEXTREL) != 0)
03506 {
03507 if (!add_dynamic_entry (DT_TEXTREL, 0))
03508 return FALSE;
03509 }
03510 }
03511 #undef add_dynamic_entry
03512
03513 return TRUE;
03514 }
03515
03516 static bfd_boolean
03517 update_local_sym_info (bfd *abfd,
03518 Elf_Internal_Shdr *symtab_hdr,
03519 unsigned long r_symndx,
03520 int tls_type)
03521 {
03522 bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
03523 char *local_got_tls_masks;
03524
03525 if (local_got_refcounts == NULL)
03526 {
03527 bfd_size_type size = symtab_hdr->sh_info;
03528
03529 size *= sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks);
03530 local_got_refcounts = bfd_zalloc (abfd, size);
03531 if (local_got_refcounts == NULL)
03532 return FALSE;
03533 elf_local_got_refcounts (abfd) = local_got_refcounts;
03534 }
03535
03536 local_got_refcounts[r_symndx] += 1;
03537 local_got_tls_masks = (char *) (local_got_refcounts + symtab_hdr->sh_info);
03538 local_got_tls_masks[r_symndx] |= tls_type;
03539 return TRUE;
03540 }
03541
03542 static void
03543 bad_shared_reloc (bfd *abfd, enum elf_ppc_reloc_type r_type)
03544 {
03545 (*_bfd_error_handler)
03546 (_("%B: relocation %s cannot be used when making a shared object"),
03547 abfd,
03548 ppc_elf_howto_table[r_type]->name);
03549 bfd_set_error (bfd_error_bad_value);
03550 }
03551
03552
03553
03554
03555
03556 static bfd_boolean
03557 ppc_elf_check_relocs (bfd *abfd,
03558 struct bfd_link_info *info,
03559 asection *sec,
03560 const Elf_Internal_Rela *relocs)
03561 {
03562 struct ppc_elf_link_hash_table *htab;
03563 Elf_Internal_Shdr *symtab_hdr;
03564 struct elf_link_hash_entry **sym_hashes;
03565 const Elf_Internal_Rela *rel;
03566 const Elf_Internal_Rela *rel_end;
03567 asection *sreloc;
03568
03569 if (info->relocatable)
03570 return TRUE;
03571
03572
03573
03574
03575
03576
03577
03578 if ((sec->flags & SEC_ALLOC) == 0)
03579 return TRUE;
03580
03581 #ifdef DEBUG
03582 _bfd_error_handler ("ppc_elf_check_relocs called for section %A in %B",
03583 sec, abfd);
03584 #endif
03585
03586
03587 if (!ppc_elf_howto_table[R_PPC_ADDR32])
03588 ppc_elf_howto_init ();
03589
03590
03591
03592 htab = ppc_elf_hash_table (info);
03593 if (htab->sdata == NULL)
03594 {
03595 htab->sdata = ppc_elf_create_linker_section (abfd, info,
03596 LINKER_SECTION_SDATA);
03597 if (htab->sdata == NULL)
03598 return FALSE;
03599 }
03600
03601 if (htab->sdata2 == NULL)
03602 {
03603 htab->sdata2 = ppc_elf_create_linker_section (abfd, info,
03604 LINKER_SECTION_SDATA2);
03605 if (htab->sdata2 == NULL)
03606 return FALSE;
03607 }
03608
03609 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
03610 sym_hashes = elf_sym_hashes (abfd);
03611 sreloc = NULL;
03612
03613 rel_end = relocs + sec->reloc_count;
03614 for (rel = relocs; rel < rel_end; rel++)
03615 {
03616 unsigned long r_symndx;
03617 enum elf_ppc_reloc_type r_type;
03618 struct elf_link_hash_entry *h;
03619 int tls_type = 0;
03620
03621 r_symndx = ELF32_R_SYM (rel->r_info);
03622 if (r_symndx < symtab_hdr->sh_info)
03623 h = NULL;
03624 else
03625 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
03626
03627
03628
03629
03630 if (h && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
03631 {
03632 if (htab->got == NULL)
03633 {
03634 if (htab->elf.dynobj == NULL)
03635 htab->elf.dynobj = abfd;
03636 if (!ppc_elf_create_got (htab->elf.dynobj, info))
03637 return FALSE;
03638 }
03639 }
03640
03641 r_type = ELF32_R_TYPE (rel->r_info);
03642 switch (r_type)
03643 {
03644 case R_PPC_GOT_TLSLD16:
03645 case R_PPC_GOT_TLSLD16_LO:
03646 case R_PPC_GOT_TLSLD16_HI:
03647 case R_PPC_GOT_TLSLD16_HA:
03648 htab->tlsld_got.refcount += 1;
03649 tls_type = TLS_TLS | TLS_LD;
03650 goto dogottls;
03651
03652 case R_PPC_GOT_TLSGD16:
03653 case R_PPC_GOT_TLSGD16_LO:
03654 case R_PPC_GOT_TLSGD16_HI:
03655 case R_PPC_GOT_TLSGD16_HA:
03656 tls_type = TLS_TLS | TLS_GD;
03657 goto dogottls;
03658
03659 case R_PPC_GOT_TPREL16:
03660 case R_PPC_GOT_TPREL16_LO:
03661 case R_PPC_GOT_TPREL16_HI:
03662 case R_PPC_GOT_TPREL16_HA:
03663 if (info->shared)
03664 info->flags |= DF_STATIC_TLS;
03665 tls_type = TLS_TLS | TLS_TPREL;
03666 goto dogottls;
03667
03668 case R_PPC_GOT_DTPREL16:
03669 case R_PPC_GOT_DTPREL16_LO:
03670 case R_PPC_GOT_DTPREL16_HI:
03671 case R_PPC_GOT_DTPREL16_HA:
03672 tls_type = TLS_TLS | TLS_DTPREL;
03673 dogottls:
03674 sec->has_tls_reloc = 1;
03675
03676
03677
03678 case R_PPC_GOT16:
03679 case R_PPC_GOT16_LO:
03680 case R_PPC_GOT16_HI:
03681 case R_PPC_GOT16_HA:
03682
03683 if (htab->got == NULL)
03684 {
03685 if (htab->elf.dynobj == NULL)
03686 htab->elf.dynobj = abfd;
03687 if (!ppc_elf_create_got (htab->elf.dynobj, info))
03688 return FALSE;
03689 }
03690 if (h != NULL)
03691 {
03692 h->got.refcount += 1;
03693 ppc_elf_hash_entry (h)->tls_mask |= tls_type;
03694 }
03695 else
03696
03697 if (!update_local_sym_info (abfd, symtab_hdr, r_symndx, tls_type))
03698 return FALSE;
03699 break;
03700
03701
03702 case R_PPC_EMB_SDAI16:
03703 if (info->shared)
03704 {
03705 bad_shared_reloc (abfd, r_type);
03706 return FALSE;
03707 }
03708 if (!elf_create_pointer_linker_section (abfd, info,
03709 htab->sdata, h, rel))
03710 return FALSE;
03711 break;
03712
03713
03714 case R_PPC_EMB_SDA2I16:
03715 if (info->shared)
03716 {
03717 bad_shared_reloc (abfd, r_type);
03718 return FALSE;
03719 }
03720 if (!elf_create_pointer_linker_section (abfd, info,
03721 htab->sdata2, h, rel))
03722 return FALSE;
03723 break;
03724
03725 case R_PPC_SDAREL16:
03726 case R_PPC_EMB_SDA2REL:
03727 case R_PPC_EMB_SDA21:
03728 case R_PPC_EMB_RELSDA:
03729 case R_PPC_EMB_NADDR32:
03730 case R_PPC_EMB_NADDR16:
03731 case R_PPC_EMB_NADDR16_LO:
03732 case R_PPC_EMB_NADDR16_HI:
03733 case R_PPC_EMB_NADDR16_HA:
03734 if (info->shared)
03735 {
03736 bad_shared_reloc (abfd, r_type);
03737 return FALSE;
03738 }
03739 break;
03740
03741 case R_PPC_PLT32:
03742 case R_PPC_PLTREL24:
03743 case R_PPC_PLTREL32:
03744 case R_PPC_PLT16_LO:
03745 case R_PPC_PLT16_HI:
03746 case R_PPC_PLT16_HA:
03747 #ifdef DEBUG
03748 fprintf (stderr, "Reloc requires a PLT entry\n");
03749 #endif
03750
03751
03752
03753
03754
03755
03756 if (h == NULL)
03757 {
03758
03759
03760 (*_bfd_error_handler) (_("%B(%A+0x%lx): %s reloc against "
03761 "local symbol"),
03762 abfd,
03763 sec,
03764 (long) rel->r_offset,
03765 ppc_elf_howto_table[r_type]->name);
03766 bfd_set_error (bfd_error_bad_value);
03767 return FALSE;
03768 }
03769
03770 h->needs_plt = 1;
03771 h->plt.refcount++;
03772 break;
03773
03774
03775
03776
03777 case R_PPC_SECTOFF:
03778 case R_PPC_SECTOFF_LO:
03779 case R_PPC_SECTOFF_HI:
03780 case R_PPC_SECTOFF_HA:
03781 case R_PPC_DTPREL16:
03782 case R_PPC_DTPREL16_LO:
03783 case R_PPC_DTPREL16_HI:
03784 case R_PPC_DTPREL16_HA:
03785 case R_PPC_TOC16:
03786 break;
03787
03788
03789 case R_PPC_TLS:
03790 case R_PPC_EMB_MRKREF:
03791 case R_PPC_NONE:
03792 case R_PPC_max:
03793 break;
03794
03795
03796 case R_PPC_COPY:
03797 case R_PPC_GLOB_DAT:
03798 case R_PPC_JMP_SLOT:
03799 case R_PPC_RELATIVE:
03800 break;
03801
03802
03803 case R_PPC_ADDR30:
03804 case R_PPC_EMB_RELSEC16:
03805 case R_PPC_EMB_RELST_LO:
03806 case R_PPC_EMB_RELST_HI:
03807 case R_PPC_EMB_RELST_HA:
03808 case R_PPC_EMB_BIT_FLD:
03809 break;
03810
03811
03812 case R_PPC_LOCAL24PC:
03813 break;
03814
03815
03816
03817 case R_PPC_GNU_VTINHERIT:
03818 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
03819 return FALSE;
03820 break;
03821
03822
03823
03824 case R_PPC_GNU_VTENTRY:
03825 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
03826 return FALSE;
03827 break;
03828
03829
03830 case R_PPC_TPREL32:
03831 if (info->shared)
03832 info->flags |= DF_STATIC_TLS;
03833 goto dodyn;
03834
03835
03836 case R_PPC_DTPMOD32:
03837 case R_PPC_DTPREL32:
03838 goto dodyn;
03839
03840 case R_PPC_TPREL16:
03841 case R_PPC_TPREL16_LO:
03842 case R_PPC_TPREL16_HI:
03843 case R_PPC_TPREL16_HA:
03844 if (info->shared)
03845 info->flags |= DF_STATIC_TLS;
03846 goto dodyn;
03847
03848
03849
03850
03851 case R_PPC_REL24:
03852 case R_PPC_REL14:
03853 case R_PPC_REL14_BRTAKEN:
03854 case R_PPC_REL14_BRNTAKEN:
03855 case R_PPC_REL32:
03856 if (h == NULL
03857 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
03858 break;
03859
03860
03861 case R_PPC_ADDR32:
03862 case R_PPC_ADDR24:
03863 case R_PPC_ADDR16:
03864 case R_PPC_ADDR16_LO:
03865 case R_PPC_ADDR16_HI:
03866 case R_PPC_ADDR16_HA:
03867 case R_PPC_ADDR14:
03868 case R_PPC_ADDR14_BRTAKEN:
03869 case R_PPC_ADDR14_BRNTAKEN:
03870 case R_PPC_UADDR32:
03871 case R_PPC_UADDR16:
03872 if (h != NULL && !info->shared)
03873 {
03874
03875
03876 h->plt.refcount++;
03877
03878
03879 h->non_got_ref = 1;
03880 }
03881
03882 dodyn:
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904 if ((info->shared
03905 && (MUST_BE_DYN_RELOC (r_type)
03906 || (h != NULL
03907 && (! info->symbolic
03908 || h->root.type == bfd_link_hash_defweak
03909 || !h->def_regular))))
03910 || (ELIMINATE_COPY_RELOCS
03911 && !info->shared
03912 && h != NULL
03913 && (h->root.type == bfd_link_hash_defweak
03914 || !h->def_regular)))
03915 {
03916 struct ppc_elf_dyn_relocs *p;
03917 struct ppc_elf_dyn_relocs **head;
03918
03919 #ifdef DEBUG
03920 fprintf (stderr,
03921 "ppc_elf_check_relocs needs to "
03922 "create relocation for %s\n",
03923 (h && h->root.root.string
03924 ? h->root.root.string : "<unknown>"));
03925 #endif
03926 if (sreloc == NULL)
03927 {
03928 const char *name;
03929
03930 name = (bfd_elf_string_from_elf_section
03931 (abfd,
03932 elf_elfheader (abfd)->e_shstrndx,
03933 elf_section_data (sec)->rel_hdr.sh_name));
03934 if (name == NULL)
03935 return FALSE;
03936
03937 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
03938 && strcmp (bfd_get_section_name (abfd, sec),
03939 name + 5) == 0);
03940
03941 sreloc = bfd_get_section_by_name (htab->elf.dynobj, name);
03942 if (sreloc == NULL)
03943 {
03944 flagword flags;
03945
03946 sreloc = bfd_make_section (htab->elf.dynobj, name);
03947 flags = (SEC_HAS_CONTENTS | SEC_READONLY
03948 | SEC_IN_MEMORY | SEC_LINKER_CREATED
03949 | SEC_ALLOC | SEC_LOAD);
03950 if (sreloc == NULL
03951 || ! bfd_set_section_flags (htab->elf.dynobj,
03952 sreloc, flags)
03953 || ! bfd_set_section_alignment (htab->elf.dynobj,
03954 sreloc, 2))
03955 return FALSE;
03956 }
03957 elf_section_data (sec)->sreloc = sreloc;
03958 }
03959
03960
03961
03962 if (h != NULL)
03963 {
03964 head = &ppc_elf_hash_entry (h)->dyn_relocs;
03965 }
03966 else
03967 {
03968
03969
03970
03971
03972 asection *s;
03973 s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
03974 sec, r_symndx);
03975 if (s == NULL)
03976 return FALSE;
03977
03978 head = ((struct ppc_elf_dyn_relocs **)
03979 &elf_section_data (s)->local_dynrel);
03980 }
03981
03982 p = *head;
03983 if (p == NULL || p->sec != sec)
03984 {
03985 p = bfd_alloc (htab->elf.dynobj, sizeof *p);
03986 if (p == NULL)
03987 return FALSE;
03988 p->next = *head;
03989 *head = p;
03990 p->sec = sec;
03991 p->count = 0;
03992 p->pc_count = 0;
03993 }
03994
03995 p->count += 1;
03996 if (!MUST_BE_DYN_RELOC (r_type))
03997 p->pc_count += 1;
03998 }
03999
04000 break;
04001 }
04002 }
04003
04004 return TRUE;
04005 }
04006
04007
04008
04009
04010 static asection *
04011 ppc_elf_gc_mark_hook (asection *sec,
04012 struct bfd_link_info *info ATTRIBUTE_UNUSED,
04013 Elf_Internal_Rela *rel,
04014 struct elf_link_hash_entry *h,
04015 Elf_Internal_Sym *sym)
04016 {
04017 if (h != NULL)
04018 {
04019 switch (ELF32_R_TYPE (rel->r_info))
04020 {
04021 case R_PPC_GNU_VTINHERIT:
04022 case R_PPC_GNU_VTENTRY:
04023 break;
04024
04025 default:
04026 switch (h->root.type)
04027 {
04028 case bfd_link_hash_defined:
04029 case bfd_link_hash_defweak:
04030 return h->root.u.def.section;
04031
04032 case bfd_link_hash_common:
04033 return h->root.u.c.p->section;
04034
04035 default:
04036 break;
04037 }
04038 }
04039 }
04040 else
04041 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
04042
04043 return NULL;
04044 }
04045
04046
04047
04048
04049 static bfd_boolean
04050 ppc_elf_gc_sweep_hook (bfd *abfd,
04051 struct bfd_link_info *info,
04052 asection *sec,
04053 const Elf_Internal_Rela *relocs)
04054 {
04055 struct ppc_elf_link_hash_table *htab;
04056 Elf_Internal_Shdr *symtab_hdr;
04057 struct elf_link_hash_entry **sym_hashes;
04058 bfd_signed_vma *local_got_refcounts;
04059 const Elf_Internal_Rela *rel, *relend;
04060
04061 if ((sec->flags & SEC_ALLOC) == 0)
04062 return TRUE;
04063
04064 elf_section_data (sec)->local_dynrel = NULL;
04065
04066 htab = ppc_elf_hash_table (info);
04067 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
04068 sym_hashes = elf_sym_hashes (abfd);
04069 local_got_refcounts = elf_local_got_refcounts (abfd);
04070
04071 relend = relocs + sec->reloc_count;
04072 for (rel = relocs; rel < relend; rel++)
04073 {
04074 unsigned long r_symndx;
04075 enum elf_ppc_reloc_type r_type;
04076 struct elf_link_hash_entry *h = NULL;
04077
04078 r_symndx = ELF32_R_SYM (rel->r_info);
04079 if (r_symndx >= symtab_hdr->sh_info)
04080 {
04081 struct ppc_elf_dyn_relocs **pp, *p;
04082 struct ppc_elf_link_hash_entry *eh;
04083
04084 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
04085 while (h->root.type == bfd_link_hash_indirect
04086 || h->root.type == bfd_link_hash_warning)
04087 h = (struct elf_link_hash_entry *) h->root.u.i.link;
04088 eh = (struct ppc_elf_link_hash_entry *) h;
04089
04090 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
04091 if (p->sec == sec)
04092 {
04093
04094 *pp = p->next;
04095 break;
04096 }
04097 }
04098
04099 r_type = ELF32_R_TYPE (rel->r_info);
04100 switch (r_type)
04101 {
04102 case R_PPC_GOT_TLSLD16:
04103 case R_PPC_GOT_TLSLD16_LO:
04104 case R_PPC_GOT_TLSLD16_HI:
04105 case R_PPC_GOT_TLSLD16_HA:
04106 htab->tlsld_got.refcount -= 1;
04107
04108
04109 case R_PPC_GOT_TLSGD16:
04110 case R_PPC_GOT_TLSGD16_LO:
04111 case R_PPC_GOT_TLSGD16_HI:
04112 case R_PPC_GOT_TLSGD16_HA:
04113 case R_PPC_GOT_TPREL16:
04114 case R_PPC_GOT_TPREL16_LO:
04115 case R_PPC_GOT_TPREL16_HI:
04116 case R_PPC_GOT_TPREL16_HA:
04117 case R_PPC_GOT_DTPREL16:
04118 case R_PPC_GOT_DTPREL16_LO:
04119 case R_PPC_GOT_DTPREL16_HI:
04120 case R_PPC_GOT_DTPREL16_HA:
04121 case R_PPC_GOT16:
04122 case R_PPC_GOT16_LO:
04123 case R_PPC_GOT16_HI:
04124 case R_PPC_GOT16_HA:
04125 if (h != NULL)
04126 {
04127 if (h->got.refcount > 0)
04128 h->got.refcount--;
04129 }
04130 else if (local_got_refcounts != NULL)
04131 {
04132 if (local_got_refcounts[r_symndx] > 0)
04133 local_got_refcounts[r_symndx]--;
04134 }
04135 break;
04136
04137 case R_PPC_REL24:
04138 case R_PPC_REL14:
04139 case R_PPC_REL14_BRTAKEN:
04140 case R_PPC_REL14_BRNTAKEN:
04141 case R_PPC_REL32:
04142 if (h == NULL
04143 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
04144 break;
04145
04146
04147 case R_PPC_ADDR32:
04148 case R_PPC_ADDR24:
04149 case R_PPC_ADDR16:
04150 case R_PPC_ADDR16_LO:
04151 case R_PPC_ADDR16_HI:
04152 case R_PPC_ADDR16_HA:
04153 case R_PPC_ADDR14:
04154 case R_PPC_ADDR14_BRTAKEN:
04155 case R_PPC_ADDR14_BRNTAKEN:
04156 case R_PPC_UADDR32:
04157 case R_PPC_UADDR16:
04158 case R_PPC_PLT32:
04159 case R_PPC_PLTREL24:
04160 case R_PPC_PLT16_LO:
04161 case R_PPC_PLT16_HI:
04162 case R_PPC_PLT16_HA:
04163 if (h != NULL)
04164 {
04165 if (h->plt.refcount > 0)
04166 h->plt.refcount--;
04167 }
04168 break;
04169
04170 default:
04171 break;
04172 }
04173 }
04174 return TRUE;
04175 }
04176
04177
04178
04179 asection *
04180 ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
04181 {
04182 struct ppc_elf_link_hash_table *htab;
04183
04184 htab = ppc_elf_hash_table (info);
04185 htab->tls_get_addr = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
04186 FALSE, FALSE, TRUE);
04187
04188 return _bfd_elf_tls_setup (obfd, info);
04189 }
04190
04191
04192
04193
04194 bfd_boolean
04195 ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
04196 struct bfd_link_info *info)
04197 {
04198 bfd *ibfd;
04199 asection *sec;
04200 struct ppc_elf_link_hash_table *htab;
04201
04202 if (info->relocatable || info->shared)
04203 return TRUE;
04204
04205 htab = ppc_elf_hash_table (info);
04206 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
04207 {
04208 Elf_Internal_Sym *locsyms = NULL;
04209 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
04210
04211 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
04212 if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
04213 {
04214 Elf_Internal_Rela *relstart, *rel, *relend;
04215 int expecting_tls_get_addr;
04216
04217
04218 relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
04219 info->keep_memory);
04220 if (relstart == NULL)
04221 return FALSE;
04222
04223 expecting_tls_get_addr = 0;
04224 relend = relstart + sec->reloc_count;
04225 for (rel = relstart; rel < relend; rel++)
04226 {
04227 enum elf_ppc_reloc_type r_type;
04228 unsigned long r_symndx;
04229 struct elf_link_hash_entry *h = NULL;
04230 char *tls_mask;
04231 char tls_set, tls_clear;
04232 bfd_boolean is_local;
04233
04234 r_symndx = ELF32_R_SYM (rel->r_info);
04235 if (r_symndx >= symtab_hdr->sh_info)
04236 {
04237 struct elf_link_hash_entry **sym_hashes;
04238
04239 sym_hashes = elf_sym_hashes (ibfd);
04240 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
04241 while (h->root.type == bfd_link_hash_indirect
04242 || h->root.type == bfd_link_hash_warning)
04243 h = (struct elf_link_hash_entry *) h->root.u.i.link;
04244 }
04245
04246 is_local = FALSE;
04247 if (h == NULL
04248 || !h->def_dynamic)
04249 is_local = TRUE;
04250
04251 r_type = ELF32_R_TYPE (rel->r_info);
04252 switch (r_type)
04253 {
04254 case R_PPC_GOT_TLSLD16:
04255 case R_PPC_GOT_TLSLD16_LO:
04256 case R_PPC_GOT_TLSLD16_HI:
04257 case R_PPC_GOT_TLSLD16_HA:
04258
04259
04260
04261 expecting_tls_get_addr = 0;
04262 htab->tlsld_got.refcount -= 1;
04263 if (!is_local)
04264 continue;
04265
04266
04267 tls_set = 0;
04268 tls_clear = TLS_LD;
04269 expecting_tls_get_addr = 1;
04270 break;
04271
04272 case R_PPC_GOT_TLSGD16:
04273 case R_PPC_GOT_TLSGD16_LO:
04274 case R_PPC_GOT_TLSGD16_HI:
04275 case R_PPC_GOT_TLSGD16_HA:
04276 if (is_local)
04277
04278 tls_set = 0;
04279 else
04280
04281 tls_set = TLS_TLS | TLS_TPRELGD;
04282 tls_clear = TLS_GD;
04283 expecting_tls_get_addr = 1;
04284 break;
04285
04286 case R_PPC_GOT_TPREL16:
04287 case R_PPC_GOT_TPREL16_LO:
04288 case R_PPC_GOT_TPREL16_HI:
04289 case R_PPC_GOT_TPREL16_HA:
04290 expecting_tls_get_addr = 0;
04291 if (is_local)
04292 {
04293
04294 tls_set = 0;
04295 tls_clear = TLS_TPREL;
04296 break;
04297 }
04298 else
04299 continue;
04300
04301 case R_PPC_REL14:
04302 case R_PPC_REL14_BRTAKEN:
04303 case R_PPC_REL14_BRNTAKEN:
04304 case R_PPC_REL24:
04305 if (expecting_tls_get_addr
04306 && h != NULL
04307 && h == htab->tls_get_addr)
04308 {
04309 if (h->plt.refcount > 0)
04310 h->plt.refcount -= 1;
04311 }
04312 expecting_tls_get_addr = 0;
04313 continue;
04314
04315 default:
04316 expecting_tls_get_addr = 0;
04317 continue;
04318 }
04319
04320 if (h != NULL)
04321 {
04322 if (tls_set == 0)
04323 {
04324
04325 if (h->got.refcount > 0)
04326 h->got.refcount -= 1;
04327 }
04328 tls_mask = &ppc_elf_hash_entry (h)->tls_mask;
04329 }
04330 else
04331 {
04332 Elf_Internal_Sym *sym;
04333 bfd_signed_vma *lgot_refs;
04334 char *lgot_masks;
04335
04336 if (locsyms == NULL)
04337 {
04338 locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
04339 if (locsyms == NULL)
04340 locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
04341 symtab_hdr->sh_info,
04342 0, NULL, NULL, NULL);
04343 if (locsyms == NULL)
04344 {
04345 if (elf_section_data (sec)->relocs != relstart)
04346 free (relstart);
04347 return FALSE;
04348 }
04349 }
04350 sym = locsyms + r_symndx;
04351 lgot_refs = elf_local_got_refcounts (ibfd);
04352 if (lgot_refs == NULL)
04353 abort ();
04354 if (tls_set == 0)
04355 {
04356
04357 if (lgot_refs[r_symndx] > 0)
04358 lgot_refs[r_symndx] -= 1;
04359 }
04360 lgot_masks = (char *) (lgot_refs + symtab_hdr->sh_info);
04361 tls_mask = &lgot_masks[r_symndx];
04362 }
04363
04364 *tls_mask |= tls_set;
04365 *tls_mask &= ~tls_clear;
04366 }
04367
04368 if (elf_section_data (sec)->relocs != relstart)
04369 free (relstart);
04370 }
04371
04372 if (locsyms != NULL
04373 && (symtab_hdr->contents != (unsigned char *) locsyms))
04374 {
04375 if (!info->keep_memory)
04376 free (locsyms);
04377 else
04378 symtab_hdr->contents = (unsigned char *) locsyms;
04379 }
04380 }
04381 return TRUE;
04382 }
04383
04384
04385
04386
04387 static bfd_boolean
04388 ppc_elf_add_symbol_hook (bfd *abfd,
04389 struct bfd_link_info *info,
04390 Elf_Internal_Sym *sym,
04391 const char **namep ATTRIBUTE_UNUSED,
04392 flagword *flagsp ATTRIBUTE_UNUSED,
04393 asection **secp,
04394 bfd_vma *valp)
04395 {
04396 if (sym->st_shndx == SHN_COMMON
04397 && !info->relocatable
04398 && sym->st_size <= elf_gp_size (abfd)
04399 && is_ppc_elf_target (info->hash->creator))
04400 {
04401
04402
04403 struct ppc_elf_link_hash_table *htab;
04404
04405 htab = ppc_elf_hash_table (info);
04406 if (htab->sbss == NULL)
04407 {
04408 flagword flags = SEC_IS_COMMON;
04409
04410 htab->sbss = bfd_make_section_anyway (abfd, ".sbss");
04411 if (htab->sbss == NULL
04412 || ! bfd_set_section_flags (abfd, htab->sbss, flags))
04413 return FALSE;
04414 }
04415
04416 *secp = htab->sbss;
04417 *valp = sym->st_size;
04418 }
04419
04420 return TRUE;
04421 }
04422
04423
04424
04425
04426 static bfd_boolean
04427 ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
04428 struct bfd_link_info *info,
04429 struct elf_link_hash_entry *h,
04430 Elf_Internal_Sym *sym)
04431 {
04432 struct ppc_elf_link_hash_table *htab;
04433
04434 #ifdef DEBUG
04435 fprintf (stderr, "ppc_elf_finish_dynamic_symbol called for %s",
04436 h->root.root.string);
04437 #endif
04438
04439 htab = ppc_elf_hash_table (info);
04440 BFD_ASSERT (htab->elf.dynobj != NULL);
04441
04442 if (h->plt.offset != (bfd_vma) -1)
04443 {
04444 Elf_Internal_Rela rela;
04445 bfd_byte *loc;
04446 bfd_vma reloc_index;
04447
04448 #ifdef DEBUG
04449 fprintf (stderr, ", plt_offset = %d", h->plt.offset);
04450 #endif
04451
04452
04453
04454
04455 BFD_ASSERT (h->dynindx != -1);
04456 BFD_ASSERT (htab->plt != NULL && htab->relplt != NULL);
04457
04458
04459
04460
04461
04462 rela.r_offset = (htab->plt->output_section->vma
04463 + htab->plt->output_offset
04464 + h->plt.offset);
04465 rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_JMP_SLOT);
04466 rela.r_addend = 0;
04467
04468 reloc_index = (h->plt.offset - PLT_INITIAL_ENTRY_SIZE) / PLT_SLOT_SIZE;
04469 if (reloc_index > PLT_NUM_SINGLE_ENTRIES)
04470 reloc_index -= (reloc_index - PLT_NUM_SINGLE_ENTRIES) / 2;
04471 loc = (htab->relplt->contents
04472 + reloc_index * sizeof (Elf32_External_Rela));
04473 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
04474
04475 if (!h->def_regular)
04476 {
04477
04478
04479 sym->st_shndx = SHN_UNDEF;
04480
04481
04482
04483
04484 if (!h->ref_regular_nonweak)
04485 sym->st_value = 0;
04486 }
04487 }
04488
04489 if (h->needs_copy)
04490 {
04491 asection *s;
04492 Elf_Internal_Rela rela;
04493 bfd_byte *loc;
04494
04495
04496
04497 #ifdef DEBUG
04498 fprintf (stderr, ", copy");
04499 #endif
04500
04501 BFD_ASSERT (h->dynindx != -1);
04502
04503 if (h->size <= elf_gp_size (htab->elf.dynobj))
04504 s = htab->relsbss;
04505 else
04506 s = htab->relbss;
04507 BFD_ASSERT (s != NULL);
04508
04509 rela.r_offset = (h->root.u.def.value
04510 + h->root.u.def.section->output_section->vma
04511 + h->root.u.def.section->output_offset);
04512 rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_COPY);
04513 rela.r_addend = 0;
04514 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
04515 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
04516 }
04517
04518 #ifdef DEBUG
04519 fprintf (stderr, "\n");
04520 #endif
04521
04522
04523 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
04524 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
04525 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
04526 sym->st_shndx = SHN_ABS;
04527
04528 return TRUE;
04529 }
04530
04531
04532
04533 static bfd_boolean
04534 ppc_elf_finish_dynamic_sections (bfd *output_bfd,
04535 struct bfd_link_info *info)
04536 {
04537 asection *sdyn;
04538 struct ppc_elf_link_hash_table *htab;
04539
04540 #ifdef DEBUG
04541 fprintf (stderr, "ppc_elf_finish_dynamic_sections called\n");
04542 #endif
04543
04544 htab = ppc_elf_hash_table (info);
04545 sdyn = bfd_get_section_by_name (htab->elf.dynobj, ".dynamic");
04546
04547 if (htab->elf.dynamic_sections_created)
04548 {
04549 Elf32_External_Dyn *dyncon, *dynconend;
04550
04551 BFD_ASSERT (htab->plt != NULL && sdyn != NULL);
04552
04553 dyncon = (Elf32_External_Dyn *) sdyn->contents;
04554 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
04555 for (; dyncon < dynconend; dyncon++)
04556 {
04557 Elf_Internal_Dyn dyn;
04558 asection *s;
04559
04560 bfd_elf32_swap_dyn_in (htab->elf.dynobj, dyncon, &dyn);
04561
04562 switch (dyn.d_tag)
04563 {
04564 case DT_PLTGOT:
04565 s = htab->plt;
04566 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
04567 break;
04568
04569 case DT_PLTRELSZ:
04570 dyn.d_un.d_val = htab->relplt->size;
04571 break;
04572
04573 case DT_JMPREL:
04574 s = htab->relplt;
04575 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
04576 break;
04577
04578 default:
04579 continue;
04580 }
04581
04582 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
04583 }
04584 }
04585
04586
04587
04588 if (htab->got)
04589 {
04590 unsigned char *contents = htab->got->contents;
04591 bfd_put_32 (output_bfd, 0x4e800021 , contents);
04592
04593 if (sdyn == NULL)
04594 bfd_put_32 (output_bfd, 0, contents + 4);
04595 else
04596 bfd_put_32 (output_bfd,
04597 sdyn->output_section->vma + sdyn->output_offset,
04598 contents + 4);
04599
04600 elf_section_data (htab->got->output_section)->this_hdr.sh_entsize = 4;
04601 }
04602
04603 return TRUE;
04604 }
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635 static bfd_boolean
04636 ppc_elf_relocate_section (bfd *output_bfd,
04637 struct bfd_link_info *info,
04638 bfd *input_bfd,
04639 asection *input_section,
04640 bfd_byte *contents,
04641 Elf_Internal_Rela *relocs,
04642 Elf_Internal_Sym *local_syms,
04643 asection **local_sections)
04644 {
04645 Elf_Internal_Shdr *symtab_hdr;
04646 struct elf_link_hash_entry **sym_hashes;
04647 struct ppc_elf_link_hash_table *htab;
04648 Elf_Internal_Rela *rel;
04649 Elf_Internal_Rela *relend;
04650 Elf_Internal_Rela outrel;
04651 bfd_byte *loc;
04652 asection *sreloc = NULL;
04653 bfd_vma *local_got_offsets;
04654 bfd_boolean ret = TRUE;
04655
04656 #ifdef DEBUG
04657 _bfd_error_handler ("ppc_elf_relocate_section called for %B section %A, "
04658 "%ld relocations%s",
04659 input_bfd, input_section,
04660 (long) input_section->reloc_count,
04661 (info->relocatable) ? " (relocatable)" : "");
04662 #endif
04663
04664 if (info->relocatable)
04665 return TRUE;
04666
04667
04668 if (!ppc_elf_howto_table[R_PPC_ADDR32])
04669 ppc_elf_howto_init ();
04670
04671 htab = ppc_elf_hash_table (info);
04672 local_got_offsets = elf_local_got_offsets (input_bfd);
04673 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
04674 sym_hashes = elf_sym_hashes (input_bfd);
04675 rel = relocs;
04676 relend = relocs + input_section->reloc_count;
04677 for (; rel < relend; rel++)
04678 {
04679 enum elf_ppc_reloc_type r_type;
04680 bfd_vma addend;
04681 bfd_reloc_status_type r;
04682 Elf_Internal_Sym *sym;
04683 asection *sec;
04684 struct elf_link_hash_entry *h;
04685 const char *sym_name;
04686 reloc_howto_type *howto;
04687 unsigned long r_symndx;
04688 bfd_vma relocation;
04689 bfd_vma branch_bit, insn, from;
04690 bfd_boolean unresolved_reloc;
04691 bfd_boolean warned;
04692 unsigned int tls_type, tls_mask, tls_gd;
04693
04694 r_type = ELF32_R_TYPE (rel->r_info);
04695 sym = NULL;
04696 sec = NULL;
04697 h = NULL;
04698 unresolved_reloc = FALSE;
04699 warned = FALSE;
04700 r_symndx = ELF32_R_SYM (rel->r_info);
04701
04702 if (r_symndx < symtab_hdr->sh_info)
04703 {
04704 sym = local_syms + r_symndx;
04705 sec = local_sections[r_symndx];
04706 sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym);
04707
04708 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
04709 }
04710 else
04711 {
04712 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
04713 r_symndx, symtab_hdr, sym_hashes,
04714 h, sec, relocation,
04715 unresolved_reloc, warned);
04716
04717 sym_name = h->root.root.string;
04718 }
04719
04720
04721
04722
04723
04724 tls_mask = 0;
04725 tls_gd = 0;
04726 if (IS_PPC_TLS_RELOC (r_type))
04727 {
04728 if (h != NULL)
04729 tls_mask = ((struct ppc_elf_link_hash_entry *) h)->tls_mask;
04730 else if (local_got_offsets != NULL)
04731 {
04732 char *lgot_masks;
04733 lgot_masks = (char *) (local_got_offsets + symtab_hdr->sh_info);
04734 tls_mask = lgot_masks[r_symndx];
04735 }
04736 }
04737
04738
04739 if ((R_PPC_GOT_TLSLD16 & 3) != (R_PPC_GOT_TLSGD16 & 3)
04740 || (R_PPC_GOT_TLSLD16_LO & 3) != (R_PPC_GOT_TLSGD16_LO & 3)
04741 || (R_PPC_GOT_TLSLD16_HI & 3) != (R_PPC_GOT_TLSGD16_HI & 3)
04742 || (R_PPC_GOT_TLSLD16_HA & 3) != (R_PPC_GOT_TLSGD16_HA & 3)
04743 || (R_PPC_GOT_TLSLD16 & 3) != (R_PPC_GOT_TPREL16 & 3)
04744 || (R_PPC_GOT_TLSLD16_LO & 3) != (R_PPC_GOT_TPREL16_LO & 3)
04745 || (R_PPC_GOT_TLSLD16_HI & 3) != (R_PPC_GOT_TPREL16_HI & 3)
04746 || (R_PPC_GOT_TLSLD16_HA & 3) != (R_PPC_GOT_TPREL16_HA & 3))
04747 abort ();
04748 switch (r_type)
04749 {
04750 default:
04751 break;
04752
04753 case R_PPC_GOT_TPREL16:
04754 case R_PPC_GOT_TPREL16_LO:
04755 if (tls_mask != 0
04756 && (tls_mask & TLS_TPREL) == 0)
04757 {
04758 bfd_vma insn;
04759 insn = bfd_get_32 (output_bfd, contents + rel->r_offset - 2);
04760 insn &= 31 << 21;
04761 insn |= 0x3c020000;
04762 bfd_put_32 (output_bfd, insn, contents + rel->r_offset - 2);
04763 r_type = R_PPC_TPREL16_HA;
04764 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
04765 }
04766 break;
04767
04768 case R_PPC_TLS:
04769 if (tls_mask != 0
04770 && (tls_mask & TLS_TPREL) == 0)
04771 {
04772 bfd_vma insn, rtra;
04773 insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
04774 if ((insn & ((31 << 26) | (31 << 11)))
04775 == ((31 << 26) | (2 << 11)))
04776 rtra = insn & ((1 << 26) - (1 << 16));
04777 else if ((insn & ((31 << 26) | (31 << 16)))
04778 == ((31 << 26) | (2 << 16)))
04779 rtra = (insn & (31 << 21)) | ((insn & (31 << 11)) << 5);
04780 else
04781 abort ();
04782 if ((insn & ((1 << 11) - (1 << 1))) == 266 << 1)
04783
04784 insn = 14 << 26;
04785 else if ((insn & (31 << 1)) == 23 << 1
04786 && ((insn & (31 << 6)) < 14 << 6
04787 || ((insn & (31 << 6)) >= 16 << 6
04788 && (insn & (31 << 6)) < 24 << 6)))
04789
04790 insn = (32 | ((insn >> 6) & 31)) << 26;
04791 else if ((insn & (31 << 1)) == 21 << 1
04792 && (insn & (0x1a << 6)) == 0)
04793
04794 insn = (((58 | ((insn >> 6) & 4)) << 26)
04795 | ((insn >> 6) & 1));
04796 else if ((insn & (31 << 1)) == 21 << 1
04797 && (insn & ((1 << 11) - (1 << 1))) == 341 << 1)
04798
04799 insn = (58 << 26) | 2;
04800 else
04801 abort ();
04802 insn |= rtra;
04803 bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
04804 r_type = R_PPC_TPREL16_LO;
04805 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
04806
04807
04808 rel->r_offset += 2;
04809 }
04810 break;
04811
04812 case R_PPC_GOT_TLSGD16_HI:
04813 case R_PPC_GOT_TLSGD16_HA:
04814 tls_gd = TLS_TPRELGD;
04815 if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
04816 goto tls_gdld_hi;
04817 break;
04818
04819 case R_PPC_GOT_TLSLD16_HI:
04820 case R_PPC_GOT_TLSLD16_HA:
04821 if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
04822 {
04823 tls_gdld_hi:
04824 if ((tls_mask & tls_gd) != 0)
04825 r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
04826 + R_PPC_GOT_TPREL16);
04827 else
04828 {
04829 bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
04830 rel->r_offset -= 2;
04831 r_type = R_PPC_NONE;
04832 }
04833 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
04834 }
04835 break;
04836
04837 case R_PPC_GOT_TLSGD16:
04838 case R_PPC_GOT_TLSGD16_LO:
04839 tls_gd = TLS_TPRELGD;
04840 if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
04841 goto tls_get_addr_check;
04842 break;
04843
04844 case R_PPC_GOT_TLSLD16:
04845 case R_PPC_GOT_TLSLD16_LO:
04846 if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
04847 {
04848 tls_get_addr_check:
04849 if (rel + 1 < relend)
04850 {
04851 enum elf_ppc_reloc_type r_type2;
04852 unsigned long r_symndx2;
04853 struct elf_link_hash_entry *h2;
04854 bfd_vma insn1, insn2;
04855 bfd_vma offset;
04856
04857
04858
04859 r_type2 = ELF32_R_TYPE (rel[1].r_info);
04860 r_symndx2 = ELF32_R_SYM (rel[1].r_info);
04861 if (r_symndx2 < symtab_hdr->sh_info
04862 || (r_type2 != R_PPC_REL14
04863 && r_type2 != R_PPC_REL14_BRTAKEN
04864 && r_type2 != R_PPC_REL14_BRNTAKEN
04865 && r_type2 != R_PPC_REL24
04866 && r_type2 != R_PPC_PLTREL24))
04867 break;
04868
04869 h2 = sym_hashes[r_symndx2 - symtab_hdr->sh_info];
04870 while (h2->root.type == bfd_link_hash_indirect
04871 || h2->root.type == bfd_link_hash_warning)
04872 h2 = (struct elf_link_hash_entry *) h2->root.u.i.link;
04873 if (h2 == NULL || h2 != htab->tls_get_addr)
04874 break;
04875
04876
04877 offset = rel[1].r_offset;
04878 insn1 = bfd_get_32 (output_bfd,
04879 contents + rel->r_offset - 2);
04880 if ((tls_mask & tls_gd) != 0)
04881 {
04882
04883 insn1 &= (1 << 26) - 1;
04884 insn1 |= 32 << 26;
04885 insn2 = 0x7c631214;
04886 rel[1].r_info = ELF32_R_INFO (r_symndx2, R_PPC_NONE);
04887 r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
04888 + R_PPC_GOT_TPREL16);
04889 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
04890 }
04891 else
04892 {
04893
04894 insn1 = 0x3c620000;
04895 insn2 = 0x38630000;
04896 if (tls_gd == 0)
04897 {
04898
04899 r_symndx = 0;
04900 rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
04901 rel[1].r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
04902 }
04903 r_type = R_PPC_TPREL16_HA;
04904 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
04905 rel[1].r_info = ELF32_R_INFO (r_symndx,
04906 R_PPC_TPREL16_LO);
04907 rel[1].r_offset += 2;
04908 }
04909 bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - 2);
04910 bfd_put_32 (output_bfd, insn2, contents + offset);
04911 if (tls_gd == 0)
04912 {
04913
04914
04915 rel--;
04916 continue;
04917 }
04918 }
04919 }
04920 break;
04921 }
04922
04923
04924 branch_bit = 0;
04925 switch (r_type)
04926 {
04927 default:
04928 break;
04929
04930
04931 case R_PPC_ADDR14_BRTAKEN:
04932 case R_PPC_REL14_BRTAKEN:
04933 branch_bit = BRANCH_PREDICT_BIT;
04934
04935
04936
04937 case R_PPC_ADDR14_BRNTAKEN:
04938 case R_PPC_REL14_BRNTAKEN:
04939 insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
04940 insn &= ~BRANCH_PREDICT_BIT;
04941 insn |= branch_bit;
04942
04943 from = (rel->r_offset
04944 + input_section->output_offset
04945 + input_section->output_section->vma);
04946
04947
04948 if ((bfd_signed_vma) (relocation + rel->r_addend - from) < 0)
04949 insn ^= BRANCH_PREDICT_BIT;
04950
04951 bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
04952 break;
04953 }
04954
04955 addend = rel->r_addend;
04956 tls_type = 0;
04957 howto = NULL;
04958 if (r_type < R_PPC_max)
04959 howto = ppc_elf_howto_table[r_type];
04960 switch (r_type)
04961 {
04962 default:
04963 (*_bfd_error_handler)
04964 (_("%B: unknown relocation type %d for symbol %s"),
04965 input_bfd, (int) r_type, sym_name);
04966
04967 bfd_set_error (bfd_error_bad_value);
04968 ret = FALSE;
04969 continue;
04970
04971 case R_PPC_NONE:
04972 case R_PPC_TLS:
04973 case R_PPC_EMB_MRKREF:
04974 case R_PPC_GNU_VTINHERIT:
04975 case R_PPC_GNU_VTENTRY:
04976 continue;
04977
04978
04979
04980
04981
04982 case R_PPC_GOT_TLSGD16:
04983 case R_PPC_GOT_TLSGD16_LO:
04984 case R_PPC_GOT_TLSGD16_HI:
04985 case R_PPC_GOT_TLSGD16_HA:
04986 tls_type = TLS_TLS | TLS_GD;
04987 goto dogot;
04988
04989 case R_PPC_GOT_TLSLD16:
04990 case R_PPC_GOT_TLSLD16_LO:
04991 case R_PPC_GOT_TLSLD16_HI:
04992 case R_PPC_GOT_TLSLD16_HA:
04993 tls_type = TLS_TLS | TLS_LD;
04994 goto dogot;
04995
04996 case R_PPC_GOT_TPREL16:
04997 case R_PPC_GOT_TPREL16_LO:
04998 case R_PPC_GOT_TPREL16_HI:
04999 case R_PPC_GOT_TPREL16_HA:
05000 tls_type = TLS_TLS | TLS_TPREL;
05001 goto dogot;
05002
05003 case R_PPC_GOT_DTPREL16:
05004 case R_PPC_GOT_DTPREL16_LO:
05005 case R_PPC_GOT_DTPREL16_HI:
05006 case R_PPC_GOT_DTPREL16_HA:
05007 tls_type = TLS_TLS | TLS_DTPREL;
05008 goto dogot;
05009
05010 case R_PPC_GOT16:
05011 case R_PPC_GOT16_LO:
05012 case R_PPC_GOT16_HI:
05013 case R_PPC_GOT16_HA:
05014 dogot:
05015 {
05016
05017
05018 bfd_vma off;
05019 bfd_vma *offp;
05020 unsigned long indx;
05021
05022 if (htab->got == NULL)
05023 abort ();
05024
05025 indx = 0;
05026 if (tls_type == (TLS_TLS | TLS_LD)
05027 && (h == NULL
05028 || !h->def_dynamic))
05029 offp = &htab->tlsld_got.offset;
05030 else if (h != NULL)
05031 {
05032 bfd_boolean dyn;
05033 dyn = htab->elf.dynamic_sections_created;
05034 if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
05035 || (info->shared
05036 && SYMBOL_REFERENCES_LOCAL (info, h)))
05037
05038
05039
05040
05041 ;
05042 else
05043 {
05044 indx = h->dynindx;
05045 unresolved_reloc = FALSE;
05046 }
05047 offp = &h->got.offset;
05048 }
05049 else
05050 {
05051 if (local_got_offsets == NULL)
05052 abort ();
05053 offp = &local_got_offsets[r_symndx];
05054 }
05055
05056
05057
05058
05059 off = *offp;
05060 if ((off & 1) != 0)
05061 off &= ~1;
05062 else
05063 {
05064 unsigned int tls_m = (tls_mask
05065 & (TLS_LD | TLS_GD | TLS_DTPREL
05066 | TLS_TPREL | TLS_TPRELGD));
05067
05068 if (offp == &htab->tlsld_got.offset)
05069 tls_m = TLS_LD;
05070 else if (h == NULL
05071 || !h->def_dynamic)
05072 tls_m &= ~TLS_LD;
05073
05074
05075
05076 do
05077 {
05078 int tls_ty = 0;
05079
05080 if ((tls_m & TLS_LD) != 0)
05081 {
05082 tls_ty = TLS_TLS | TLS_LD;
05083 tls_m &= ~TLS_LD;
05084 }
05085 else if ((tls_m & TLS_GD) != 0)
05086 {
05087 tls_ty = TLS_TLS | TLS_GD;
05088 tls_m &= ~TLS_GD;
05089 }
05090 else if ((tls_m & TLS_DTPREL) != 0)
05091 {
05092 tls_ty = TLS_TLS | TLS_DTPREL;
05093 tls_m &= ~TLS_DTPREL;
05094 }
05095 else if ((tls_m & (TLS_TPREL | TLS_TPRELGD)) != 0)
05096 {
05097 tls_ty = TLS_TLS | TLS_TPREL;
05098 tls_m = 0;
05099 }
05100
05101
05102 if ((info->shared || indx != 0)
05103 && (h == NULL
05104 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
05105 || h->root.type != bfd_link_hash_undefweak))
05106 {
05107 outrel.r_offset = (htab->got->output_section->vma
05108 + htab->got->output_offset
05109 + off);
05110 outrel.r_addend = 0;
05111 if (tls_ty & (TLS_LD | TLS_GD))
05112 {
05113 outrel.r_info = ELF32_R_INFO (indx, R_PPC_DTPMOD32);
05114 if (tls_ty == (TLS_TLS | TLS_GD))
05115 {
05116 loc = htab->relgot->contents;
05117 loc += (htab->relgot->reloc_count++
05118 * sizeof (Elf32_External_Rela));
05119 bfd_elf32_swap_reloca_out (output_bfd,
05120 &outrel, loc);
05121 outrel.r_offset += 4;
05122 outrel.r_info
05123 = ELF32_R_INFO (indx, R_PPC_DTPREL32);
05124 }
05125 }
05126 else if (tls_ty == (TLS_TLS | TLS_DTPREL))
05127 outrel.r_info = ELF32_R_INFO (indx, R_PPC_DTPREL32);
05128 else if (tls_ty == (TLS_TLS | TLS_TPREL))
05129 outrel.r_info = ELF32_R_INFO (indx, R_PPC_TPREL32);
05130 else if (indx == 0)
05131 outrel.r_info = ELF32_R_INFO (indx, R_PPC_RELATIVE);
05132 else
05133 outrel.r_info = ELF32_R_INFO (indx, R_PPC_GLOB_DAT);
05134 if (indx == 0)
05135 {
05136 outrel.r_addend += relocation;
05137 if (tls_ty & (TLS_GD | TLS_DTPREL | TLS_TPREL))
05138 outrel.r_addend -= htab->elf.tls_sec->vma;
05139 }
05140 loc = htab->relgot->contents;
05141 loc += (htab->relgot->reloc_count++
05142 * sizeof (Elf32_External_Rela));
05143 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
05144 }
05145
05146
05147
05148 else
05149 {
05150 bfd_vma value = relocation;
05151
05152 if (tls_ty == (TLS_TLS | TLS_LD))
05153 value = 1;
05154 else if (tls_ty != 0)
05155 {
05156 value -= htab->elf.tls_sec->vma + DTP_OFFSET;
05157 if (tls_ty == (TLS_TLS | TLS_TPREL))
05158 value += DTP_OFFSET - TP_OFFSET;
05159
05160 if (tls_ty == (TLS_TLS | TLS_GD))
05161 {
05162 bfd_put_32 (output_bfd, value,
05163 htab->got->contents + off + 4);
05164 value = 1;
05165 }
05166 }
05167 bfd_put_32 (output_bfd, value,
05168 htab->got->contents + off);
05169 }
05170
05171 off += 4;
05172 if (tls_ty & (TLS_LD | TLS_GD))
05173 off += 4;
05174 }
05175 while (tls_m != 0);
05176
05177 off = *offp;
05178 *offp = off | 1;
05179 }
05180
05181 if (off >= (bfd_vma) -2)
05182 abort ();
05183
05184 if ((tls_type & TLS_TLS) != 0)
05185 {
05186 if (tls_type != (TLS_TLS | TLS_LD))
05187 {
05188 if ((tls_mask & TLS_LD) != 0
05189 && !(h == NULL
05190 || !h->def_dynamic))
05191 off += 8;
05192 if (tls_type != (TLS_TLS | TLS_GD))
05193 {
05194 if ((tls_mask & TLS_GD) != 0)
05195 off += 8;
05196 if (tls_type != (TLS_TLS | TLS_DTPREL))
05197 {
05198 if ((tls_mask & TLS_DTPREL) != 0)
05199 off += 4;
05200 }
05201 }
05202 }
05203 }
05204
05205 relocation = htab->got->output_offset + off - 4;
05206
05207
05208
05209
05210
05211 if (addend != 0)
05212 (*_bfd_error_handler)
05213 (_("%B(%A+0x%lx): non-zero addend on %s reloc against `%s'"),
05214 input_bfd,
05215 input_section,
05216 (long) rel->r_offset,
05217 howto->name,
05218 sym_name);
05219 }
05220 break;
05221
05222
05223 case R_PPC_LOCAL24PC:
05224
05225
05226 if (unresolved_reloc)
05227 {
05228 if (! (*info->callbacks->undefined_symbol) (info,
05229 h->root.root.string,
05230 input_bfd,
05231 input_section,
05232 rel->r_offset,
05233 TRUE))
05234 return FALSE;
05235 continue;
05236 }
05237 break;
05238
05239 case R_PPC_DTPREL16:
05240 case R_PPC_DTPREL16_LO:
05241 case R_PPC_DTPREL16_HI:
05242 case R_PPC_DTPREL16_HA:
05243 addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
05244 break;
05245
05246
05247
05248 case R_PPC_TPREL16:
05249 case R_PPC_TPREL16_LO:
05250 case R_PPC_TPREL16_HI:
05251 case R_PPC_TPREL16_HA:
05252 addend -= htab->elf.tls_sec->vma + TP_OFFSET;
05253
05254
05255
05256 goto dodyn;
05257
05258 case R_PPC_TPREL32:
05259 addend -= htab->elf.tls_sec->vma + TP_OFFSET;
05260 goto dodyn;
05261
05262 case R_PPC_DTPREL32:
05263 addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
05264 goto dodyn;
05265
05266 case R_PPC_DTPMOD32:
05267 relocation = 1;
05268 addend = 0;
05269 goto dodyn;
05270
05271 case R_PPC_REL24:
05272 case R_PPC_REL32:
05273 case R_PPC_REL14:
05274 case R_PPC_REL14_BRTAKEN:
05275 case R_PPC_REL14_BRNTAKEN:
05276
05277
05278 if (SYMBOL_REFERENCES_LOCAL (info, h)
05279 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
05280 break;
05281
05282
05283
05284
05285 case R_PPC_ADDR32:
05286 case R_PPC_ADDR24:
05287 case R_PPC_ADDR16:
05288 case R_PPC_ADDR16_LO:
05289 case R_PPC_ADDR16_HI:
05290 case R_PPC_ADDR16_HA:
05291 case R_PPC_ADDR14:
05292 case R_PPC_ADDR14_BRTAKEN:
05293 case R_PPC_ADDR14_BRNTAKEN:
05294 case R_PPC_UADDR32:
05295 case R_PPC_UADDR16:
05296
05297
05298
05299 dodyn:
05300 if (r_symndx == 0)
05301 break;
05302
05303
05304 if ((input_section->flags & SEC_ALLOC) == 0)
05305 break;
05306
05307
05308 if ((info->shared
05309 && (h == NULL
05310 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
05311 || h->root.type != bfd_link_hash_undefweak)
05312 && (MUST_BE_DYN_RELOC (r_type)
05313 || !SYMBOL_CALLS_LOCAL (info, h)))
05314 || (ELIMINATE_COPY_RELOCS
05315 && !info->shared
05316 && h != NULL
05317 && h->dynindx != -1
05318 && !h->non_got_ref
05319 && h->def_dynamic
05320 && !h->def_regular))
05321 {
05322 int skip;
05323
05324 #ifdef DEBUG
05325 fprintf (stderr, "ppc_elf_relocate_section needs to "
05326 "create relocation for %s\n",
05327 (h && h->root.root.string
05328 ? h->root.root.string : "<unknown>"));
05329 #endif
05330
05331
05332
05333
05334 if (sreloc == NULL)
05335 {
05336 const char *name;
05337
05338 name = (bfd_elf_string_from_elf_section
05339 (input_bfd,
05340 elf_elfheader (input_bfd)->e_shstrndx,
05341 elf_section_data (input_section)->rel_hdr.sh_name));
05342 if (name == NULL)
05343 return FALSE;
05344
05345 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
05346 && strcmp (bfd_get_section_name (input_bfd,
05347 input_section),
05348 name + 5) == 0);
05349
05350 sreloc = bfd_get_section_by_name (htab->elf.dynobj, name);
05351 BFD_ASSERT (sreloc != NULL);
05352 }
05353
05354 skip = 0;
05355
05356 outrel.r_offset =
05357 _bfd_elf_section_offset (output_bfd, info, input_section,
05358 rel->r_offset);
05359 if (outrel.r_offset == (bfd_vma) -1
05360 || outrel.r_offset == (bfd_vma) -2)
05361 skip = (int) outrel.r_offset;
05362 outrel.r_offset += (input_section->output_section->vma
05363 + input_section->output_offset);
05364
05365 if (skip)
05366 memset (&outrel, 0, sizeof outrel);
05367 else if (!SYMBOL_REFERENCES_LOCAL (info, h))
05368 {
05369 unresolved_reloc = FALSE;
05370 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
05371 outrel.r_addend = rel->r_addend;
05372 }
05373 else
05374 {
05375 outrel.r_addend = relocation + rel->r_addend;
05376
05377 if (r_type == R_PPC_ADDR32)
05378 outrel.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
05379 else
05380 {
05381 long indx;
05382
05383 if (bfd_is_abs_section (sec))
05384 indx = 0;
05385 else if (sec == NULL || sec->owner == NULL)
05386 {
05387 bfd_set_error (bfd_error_bad_value);
05388 return FALSE;
05389 }
05390 else
05391 {
05392 asection *osec;
05393
05394
05395
05396
05397
05398
05399 osec = sec->output_section;
05400 indx = elf_section_data (osec)->dynindx;
05401 BFD_ASSERT (indx > 0);
05402 #ifdef DEBUG
05403 if (indx <= 0)
05404 printf ("indx=%d section=%s flags=%08x name=%s\n",
05405 indx, osec->name, osec->flags,
05406 h->root.root.string);
05407 #endif
05408 }
05409
05410 outrel.r_info = ELF32_R_INFO (indx, r_type);
05411 }
05412 }
05413
05414 loc = sreloc->contents;
05415 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
05416 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
05417
05418 if (skip == -1)
05419 continue;
05420
05421
05422
05423 if (! skip
05424 && ((input_section->flags & SEC_ALLOC) != 0
05425 || ELF32_R_TYPE (outrel.r_info) != R_PPC_RELATIVE))
05426 {
05427 relocation = howto->pc_relative ? outrel.r_offset : 0;
05428 addend = 0;
05429 break;
05430 }
05431 }
05432 break;
05433
05434 case R_PPC_RELAX32PC_PLT:
05435 case R_PPC_RELAX32_PLT:
05436 BFD_ASSERT (h != NULL
05437 && h->plt.offset != (bfd_vma) -1
05438 && htab->plt != NULL);
05439
05440 relocation = (htab->plt->output_section->vma
05441 + htab->plt->output_offset
05442 + h->plt.offset);
05443 if (r_type == R_PPC_RELAX32_PLT)
05444 goto relax32;
05445
05446
05447 case R_PPC_RELAX32PC:
05448 relocation -= (input_section->output_section->vma
05449 + input_section->output_offset
05450 + rel->r_offset - 4);
05451
05452
05453 case R_PPC_RELAX32:
05454 relax32:
05455 {
05456 unsigned long t0;
05457 unsigned long t1;
05458
05459 t0 = bfd_get_32 (output_bfd, contents + rel->r_offset);
05460 t1 = bfd_get_32 (output_bfd, contents + rel->r_offset + 4);
05461
05462
05463
05464 t0 &= ~0xffff;
05465 t1 &= ~0xffff;
05466
05467
05468 relocation += addend;
05469 t0 |= ((relocation + 0x8000) >> 16) & 0xffff;
05470 t1 |= relocation & 0xffff;
05471
05472 bfd_put_32 (output_bfd, t0, contents + rel->r_offset);
05473 bfd_put_32 (output_bfd, t1, contents + rel->r_offset + 4);
05474 }
05475 continue;
05476
05477
05478 case R_PPC_EMB_SDAI16:
05479 BFD_ASSERT (htab->sdata != NULL);
05480 relocation
05481 = elf_finish_pointer_linker_section (output_bfd, input_bfd, info,
05482 htab->sdata, h, relocation,
05483 rel, R_PPC_RELATIVE);
05484 break;
05485
05486
05487 case R_PPC_EMB_SDA2I16:
05488 BFD_ASSERT (htab->sdata2 != NULL);
05489 relocation
05490 = elf_finish_pointer_linker_section (output_bfd, input_bfd, info,
05491 htab->sdata2, h, relocation,
05492 rel, R_PPC_RELATIVE);
05493 break;
05494
05495
05496
05497
05498
05499 case R_PPC_TOC16:
05500 BFD_ASSERT (sec != NULL);
05501 BFD_ASSERT (bfd_is_und_section (sec)
05502 || strcmp (bfd_get_section_name (abfd, sec), ".got") == 0
05503 || strcmp (bfd_get_section_name (abfd, sec), ".cgot") == 0);
05504
05505 addend -= sec->output_section->vma + sec->output_offset + 0x8000;
05506 break;
05507
05508 case R_PPC_PLTREL24:
05509
05510
05511 BFD_ASSERT (h != NULL);
05512
05513 if (h->plt.offset == (bfd_vma) -1
05514 || htab->plt == NULL)
05515 {
05516
05517
05518
05519 break;
05520 }
05521
05522 unresolved_reloc = FALSE;
05523 relocation = (htab->plt->output_section->vma
05524 + htab->plt->output_offset
05525 + h->plt.offset);
05526 break;
05527
05528
05529 case R_PPC_SDAREL16:
05530 {
05531 const char *name;
05532 const struct elf_link_hash_entry *sh;
05533
05534 BFD_ASSERT (sec != NULL);
05535 name = bfd_get_section_name (abfd, sec->output_section);
05536 if (! ((strncmp (name, ".sdata", 6) == 0
05537 && (name[6] == 0 || name[6] == '.'))
05538 || (strncmp (name, ".sbss", 5) == 0
05539 && (name[5] == 0 || name[5] == '.'))))
05540 {
05541 (*_bfd_error_handler)
05542 (_("%B: the target (%s) of a %s relocation is "
05543 "in the wrong output section (%s)"),
05544 input_bfd,
05545 sym_name,
05546 howto->name,
05547 name);
05548 }
05549 sh = htab->sdata->sym_hash;
05550 addend -= (sh->root.u.def.value
05551 + sh->root.u.def.section->output_section->vma
05552 + sh->root.u.def.section->output_offset);
05553 }
05554 break;
05555
05556
05557 case R_PPC_EMB_SDA2REL:
05558 {
05559 const char *name;
05560 const struct elf_link_hash_entry *sh;
05561
05562 BFD_ASSERT (sec != NULL);
05563 name = bfd_get_section_name (abfd, sec->output_section);
05564 if (! (strncmp (name, ".sdata2", 7) == 0
05565 || strncmp (name, ".sbss2", 6) == 0))
05566 {
05567 (*_bfd_error_handler)
05568 (_("%B: the target (%s) of a %s relocation is "
05569 "in the wrong output section (%s)"),
05570 input_bfd,
05571 sym_name,
05572 howto->name,
05573 name);
05574
05575 bfd_set_error (bfd_error_bad_value);
05576 ret = FALSE;
05577 continue;
05578 }
05579 sh = htab->sdata2->sym_hash;
05580 addend -= (sh->root.u.def.value
05581 + sh->root.u.def.section->output_section->vma
05582 + sh->root.u.def.section->output_offset);
05583 }
05584 break;
05585
05586
05587 case R_PPC_EMB_SDA21:
05588 case R_PPC_EMB_RELSDA:
05589 {
05590 const char *name;
05591 const struct elf_link_hash_entry *sh;
05592 int reg;
05593
05594 BFD_ASSERT (sec != NULL);
05595 name = bfd_get_section_name (abfd, sec->output_section);
05596 if (((strncmp (name, ".sdata", 6) == 0
05597 && (name[6] == 0 || name[6] == '.'))
05598 || (strncmp (name, ".sbss", 5) == 0
05599 && (name[5] == 0 || name[5] == '.'))))
05600 {
05601 reg = 13;
05602 sh = htab->sdata->sym_hash;
05603 addend -= (sh->root.u.def.value
05604 + sh->root.u.def.section->output_section->vma
05605 + sh->root.u.def.section->output_offset);
05606 }
05607
05608 else if (strncmp (name, ".sdata2", 7) == 0
05609 || strncmp (name, ".sbss2", 6) == 0)
05610 {
05611 reg = 2;
05612 sh = htab->sdata2->sym_hash;
05613 addend -= (sh->root.u.def.value
05614 + sh->root.u.def.section->output_section->vma
05615 + sh->root.u.def.section->output_offset);
05616 }
05617
05618 else if (strcmp (name, ".PPC.EMB.sdata0") == 0
05619 || strcmp (name, ".PPC.EMB.sbss0") == 0)
05620 {
05621 reg = 0;
05622 }
05623
05624 else
05625 {
05626 (*_bfd_error_handler)
05627 (_("%B: the target (%s) of a %s relocation is "
05628 "in the wrong output section (%s)"),
05629 input_bfd,
05630 sym_name,
05631 howto->name,
05632 name);
05633
05634 bfd_set_error (bfd_error_bad_value);
05635 ret = FALSE;
05636 continue;
05637 }
05638
05639 if (r_type == R_PPC_EMB_SDA21)
05640 {
05641 insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
05642 insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
05643 bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
05644 }
05645 }
05646 break;
05647
05648
05649 case R_PPC_SECTOFF:
05650 case R_PPC_SECTOFF_LO:
05651 case R_PPC_SECTOFF_HI:
05652 case R_PPC_SECTOFF_HA:
05653 BFD_ASSERT (sec != NULL);
05654 addend -= sec->output_section->vma;
05655 break;
05656
05657
05658 case R_PPC_EMB_NADDR32:
05659 case R_PPC_EMB_NADDR16:
05660 case R_PPC_EMB_NADDR16_LO:
05661 case R_PPC_EMB_NADDR16_HI:
05662 case R_PPC_EMB_NADDR16_HA:
05663 addend -= 2 * relocation;
05664 break;
05665
05666 case R_PPC_COPY:
05667 case R_PPC_GLOB_DAT:
05668 case R_PPC_JMP_SLOT:
05669 case R_PPC_RELATIVE:
05670 case R_PPC_PLT32:
05671 case R_PPC_PLTREL32:
05672 case R_PPC_PLT16_LO:
05673 case R_PPC_PLT16_HI:
05674 case R_PPC_PLT16_HA:
05675 case R_PPC_ADDR30:
05676 case R_PPC_EMB_RELSEC16:
05677 case R_PPC_EMB_RELST_LO:
05678 case R_PPC_EMB_RELST_HI:
05679 case R_PPC_EMB_RELST_HA:
05680 case R_PPC_EMB_BIT_FLD:
05681 (*_bfd_error_handler)
05682 (_("%B: relocation %s is not yet supported for symbol %s."),
05683 input_bfd,
05684 howto->name,
05685 sym_name);
05686
05687 bfd_set_error (bfd_error_invalid_operation);
05688 ret = FALSE;
05689 continue;
05690 }
05691
05692
05693 switch (r_type)
05694 {
05695 default:
05696 break;
05697
05698 case R_PPC_ADDR16_HA:
05699 case R_PPC_GOT16_HA:
05700 case R_PPC_PLT16_HA:
05701 case R_PPC_SECTOFF_HA:
05702 case R_PPC_TPREL16_HA:
05703 case R_PPC_DTPREL16_HA:
05704 case R_PPC_GOT_TLSGD16_HA:
05705 case R_PPC_GOT_TLSLD16_HA:
05706 case R_PPC_GOT_TPREL16_HA:
05707 case R_PPC_GOT_DTPREL16_HA:
05708 case R_PPC_EMB_NADDR16_HA:
05709 case R_PPC_EMB_RELST_HA:
05710
05711
05712
05713
05714 if (sec != NULL)
05715
05716
05717 addend += 0x8000;
05718 break;
05719 }
05720
05721 #ifdef DEBUG
05722 fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, "
05723 "offset = %ld, addend = %ld\n",
05724 howto->name,
05725 (int) r_type,
05726 sym_name,
05727 r_symndx,
05728 (long) rel->r_offset,
05729 (long) addend);
05730 #endif
05731
05732 if (unresolved_reloc
05733 && !((input_section->flags & SEC_DEBUGGING) != 0
05734 && h->def_dynamic))
05735 {
05736 (*_bfd_error_handler)
05737 (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
05738 input_bfd,
05739 input_section,
05740 (long) rel->r_offset,
05741 howto->name,
05742 sym_name);
05743 ret = FALSE;
05744 }
05745
05746 r = _bfd_final_link_relocate (howto,
05747 input_bfd,
05748 input_section,
05749 contents,
05750 rel->r_offset,
05751 relocation,
05752 addend);
05753
05754 if (r != bfd_reloc_ok)
05755 {
05756 if (sym_name == NULL)
05757 sym_name = "(null)";
05758 if (r == bfd_reloc_overflow)
05759 {
05760 if (warned)
05761 continue;
05762 if (h != NULL
05763 && h->root.type == bfd_link_hash_undefweak
05764 && howto->pc_relative)
05765 {
05766
05767
05768
05769
05770
05771
05772 continue;
05773 }
05774
05775 if (! (*info->callbacks->reloc_overflow) (info,
05776 (h ? &h->root : NULL),
05777 sym_name,
05778 howto->name,
05779 rel->r_addend,
05780 input_bfd,
05781 input_section,
05782 rel->r_offset))
05783 return FALSE;
05784 }
05785 else
05786 {
05787 (*_bfd_error_handler)
05788 (_("%B(%A+0x%lx): %s reloc against `%s': error %d"),
05789 input_bfd, input_section,
05790 (long) rel->r_offset, howto->name, sym_name, (int) r);
05791 ret = FALSE;
05792 }
05793 }
05794 }
05795
05796 #ifdef DEBUG
05797 fprintf (stderr, "\n");
05798 #endif
05799
05800 return ret;
05801 }
05802
05803 static enum elf_reloc_type_class
05804 ppc_elf_reloc_type_class (const Elf_Internal_Rela *rela)
05805 {
05806 switch (ELF32_R_TYPE (rela->r_info))
05807 {
05808 case R_PPC_RELATIVE:
05809 return reloc_class_relative;
05810 case R_PPC_REL24:
05811 case R_PPC_ADDR24:
05812 case R_PPC_JMP_SLOT:
05813 return reloc_class_plt;
05814 case R_PPC_COPY:
05815 return reloc_class_copy;
05816 default:
05817 return reloc_class_normal;
05818 }
05819 }
05820
05821
05822
05823 static bfd_boolean
05824 ppc_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
05825 {
05826 int offset;
05827 unsigned int size;
05828
05829 switch (note->descsz)
05830 {
05831 default:
05832 return FALSE;
05833
05834 case 268:
05835
05836 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
05837
05838
05839 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
05840
05841
05842 offset = 72;
05843 size = 192;
05844
05845 break;
05846 }
05847
05848
05849 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
05850 size, note->descpos + offset);
05851 }
05852
05853 static bfd_boolean
05854 ppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
05855 {
05856 switch (note->descsz)
05857 {
05858 default:
05859 return FALSE;
05860
05861 case 128:
05862 elf_tdata (abfd)->core_program
05863 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
05864 elf_tdata (abfd)->core_command
05865 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
05866 }
05867
05868
05869
05870
05871
05872 {
05873 char *command = elf_tdata (abfd)->core_command;
05874 int n = strlen (command);
05875
05876 if (0 < n && command[n - 1] == ' ')
05877 command[n - 1] = '\0';
05878 }
05879
05880 return TRUE;
05881 }
05882
05883
05884 typedef struct apuinfo_list
05885 {
05886 struct apuinfo_list *next;
05887 unsigned long value;
05888 }
05889 apuinfo_list;
05890
05891 static apuinfo_list *head;
05892
05893
05894 static void
05895 apuinfo_list_init (void)
05896 {
05897 head = NULL;
05898 }
05899
05900 static void
05901 apuinfo_list_add (unsigned long value)
05902 {
05903 apuinfo_list *entry = head;
05904
05905 while (entry != NULL)
05906 {
05907 if (entry->value == value)
05908 return;
05909 entry = entry->next;
05910 }
05911
05912 entry = bfd_malloc (sizeof (* entry));
05913 if (entry == NULL)
05914 return;
05915
05916 entry->value = value;
05917 entry->next = head;
05918 head = entry;
05919 }
05920
05921 static unsigned
05922 apuinfo_list_length (void)
05923 {
05924 apuinfo_list *entry;
05925 unsigned long count;
05926
05927 for (entry = head, count = 0;
05928 entry;
05929 entry = entry->next)
05930 ++ count;
05931
05932 return count;
05933 }
05934
05935 static inline unsigned long
05936 apuinfo_list_element (unsigned long number)
05937 {
05938 apuinfo_list * entry;
05939
05940 for (entry = head;
05941 entry && number --;
05942 entry = entry->next)
05943 ;
05944
05945 return entry ? entry->value : 0;
05946 }
05947
05948 static void
05949 apuinfo_list_finish (void)
05950 {
05951 apuinfo_list *entry;
05952
05953 for (entry = head; entry;)
05954 {
05955 apuinfo_list *next = entry->next;
05956 free (entry);
05957 entry = next;
05958 }
05959
05960 head = NULL;
05961 }
05962
05963 #define APUINFO_SECTION_NAME ".PPC.EMB.apuinfo"
05964 #define APUINFO_LABEL "APUinfo"
05965
05966
05967
05968
05969 static void
05970 ppc_elf_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
05971 {
05972 bfd *ibfd;
05973 asection *asec;
05974 char *buffer;
05975 unsigned num_input_sections;
05976 bfd_size_type output_section_size;
05977 unsigned i;
05978 unsigned num_entries;
05979 unsigned long offset;
05980 unsigned long length;
05981 const char *error_message = NULL;
05982
05983 if (link_info == NULL)
05984 return;
05985
05986
05987 num_input_sections = 0;
05988 output_section_size = 0;
05989
05990 for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link_next)
05991 {
05992 asec = bfd_get_section_by_name (ibfd, APUINFO_SECTION_NAME);
05993 if (asec)
05994 {
05995 ++ num_input_sections;
05996 output_section_size += asec->size;
05997 }
05998 }
05999
06000
06001
06002 if (num_input_sections < 1)
06003 return;
06004
06005
06006 asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
06007 if (asec == NULL)
06008 return;
06009
06010
06011 buffer = bfd_malloc (output_section_size);
06012 if (buffer == NULL)
06013 return;
06014
06015 offset = 0;
06016 apuinfo_list_init ();
06017
06018
06019 for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link_next)
06020 {
06021 unsigned long datum;
06022 char *ptr;
06023
06024 asec = bfd_get_section_by_name (ibfd, APUINFO_SECTION_NAME);
06025 if (asec == NULL)
06026 continue;
06027
06028 length = asec->size;
06029 if (length < 24)
06030 {
06031 error_message = _("corrupt or empty %s section in %B");
06032 goto fail;
06033 }
06034
06035 if (bfd_seek (ibfd, asec->filepos, SEEK_SET) != 0
06036 || (bfd_bread (buffer + offset, length, ibfd) != length))
06037 {
06038 error_message = _("unable to read in %s section from %B");
06039 goto fail;
06040 }
06041
06042
06043 ptr = buffer + offset;
06044 error_message = _("corrupt %s section in %B");
06045
06046
06047
06048
06049 datum = bfd_get_32 (ibfd, ptr);
06050 if (datum != sizeof APUINFO_LABEL)
06051 goto fail;
06052
06053 datum = bfd_get_32 (ibfd, ptr + 8);
06054 if (datum != 0x2)
06055 goto fail;
06056
06057 if (strcmp (ptr + 12, APUINFO_LABEL) != 0)
06058 goto fail;
06059
06060
06061 datum = bfd_get_32 (ibfd, ptr + 4);
06062 if (datum + 20 != length)
06063 goto fail;
06064
06065
06066 if (offset + length > output_section_size)
06067 goto fail;
06068
06069
06070 for (i = 0; i < datum; i += 4)
06071 apuinfo_list_add (bfd_get_32 (ibfd, ptr + 20 + i));
06072
06073
06074 offset += length;
06075 }
06076
06077 error_message = NULL;
06078
06079
06080 num_entries = apuinfo_list_length ();
06081 output_section_size = 20 + num_entries * 4;
06082
06083 asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
06084
06085 if (! bfd_set_section_size (abfd, asec, output_section_size))
06086 ibfd = abfd,
06087 error_message = _("warning: unable to set size of %s section in %B");
06088
06089 fail:
06090 free (buffer);
06091
06092 if (error_message)
06093 (*_bfd_error_handler) (error_message, ibfd, APUINFO_SECTION_NAME);
06094 }
06095
06096
06097
06098
06099
06100 static bfd_boolean
06101 ppc_elf_write_section (bfd *abfd ATTRIBUTE_UNUSED,
06102 asection *asec,
06103 bfd_byte *contents ATTRIBUTE_UNUSED)
06104 {
06105 return (apuinfo_list_length ()
06106 && strcmp (asec->name, APUINFO_SECTION_NAME) == 0);
06107 }
06108
06109
06110
06111
06112 static void
06113 ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
06114 {
06115 bfd_byte *buffer;
06116 asection *asec;
06117 unsigned i;
06118 unsigned num_entries;
06119 bfd_size_type length;
06120
06121 asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
06122 if (asec == NULL)
06123 return;
06124
06125 if (apuinfo_list_length () == 0)
06126 return;
06127
06128 length = asec->size;
06129 if (length < 20)
06130 return;
06131
06132 buffer = bfd_malloc (length);
06133 if (buffer == NULL)
06134 {
06135 (*_bfd_error_handler)
06136 (_("failed to allocate space for new APUinfo section."));
06137 return;
06138 }
06139
06140
06141 num_entries = apuinfo_list_length ();
06142 bfd_put_32 (abfd, sizeof APUINFO_LABEL, buffer);
06143 bfd_put_32 (abfd, num_entries * 4, buffer + 4);
06144 bfd_put_32 (abfd, 0x2, buffer + 8);
06145 strcpy ((char *) buffer + 12, APUINFO_LABEL);
06146
06147 length = 20;
06148 for (i = 0; i < num_entries; i++)
06149 {
06150 bfd_put_32 (abfd, apuinfo_list_element (i), buffer + length);
06151 length += 4;
06152 }
06153
06154 if (length != asec->size)
06155 (*_bfd_error_handler) (_("failed to compute new APUinfo section."));
06156
06157 if (! bfd_set_section_contents (abfd, asec, buffer, (file_ptr) 0, length))
06158 (*_bfd_error_handler) (_("failed to install new APUinfo section."));
06159
06160 free (buffer);
06161
06162 apuinfo_list_finish ();
06163 }
06164
06165
06166
06167
06168 static bfd_vma
06169 ppc_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED,
06170 const asection *plt ATTRIBUTE_UNUSED,
06171 const arelent *rel)
06172 {
06173 return rel->address;
06174 }
06175
06176
06177
06178
06179
06180
06181 static struct bfd_elf_special_section const ppc_elf_special_sections[]=
06182 {
06183 { ".tags", 5, 0, SHT_ORDERED, SHF_ALLOC },
06184 { ".sdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
06185 { ".sbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
06186 { ".sdata2", 7, -2, SHT_PROGBITS, SHF_ALLOC },
06187 { ".sbss2", 6, -2, SHT_PROGBITS, SHF_ALLOC },
06188 { ".PPC.EMB.apuinfo", 16, 0, SHT_NOTE, 0 },
06189 { ".PPC.EMB.sdata0", 15, 0, SHT_PROGBITS, SHF_ALLOC },
06190 { ".PPC.EMB.sbss0", 14, 0, SHT_PROGBITS, SHF_ALLOC },
06191 { ".plt", 4, 0, SHT_NOBITS, SHF_ALLOC + SHF_EXECINSTR },
06192 { NULL, 0, 0, 0, 0 }
06193 };
06194
06195 #define TARGET_LITTLE_SYM bfd_elf32_powerpcle_vec
06196 #define TARGET_LITTLE_NAME "elf32-powerpcle"
06197 #define TARGET_BIG_SYM bfd_elf32_powerpc_vec
06198 #define TARGET_BIG_NAME "elf32-powerpc"
06199 #define ELF_ARCH bfd_arch_powerpc
06200 #define ELF_MACHINE_CODE EM_PPC
06201 #ifdef __QNXTARGET__
06202 #define ELF_MAXPAGESIZE 0x1000
06203 #else
06204 #define ELF_MAXPAGESIZE 0x10000
06205 #endif
06206 #define ELF_MINPAGESIZE 0x1000
06207 #define elf_info_to_howto ppc_elf_info_to_howto
06208
06209 #ifdef EM_CYGNUS_POWERPC
06210 #define ELF_MACHINE_ALT1 EM_CYGNUS_POWERPC
06211 #endif
06212
06213 #ifdef EM_PPC_OLD
06214 #define ELF_MACHINE_ALT2 EM_PPC_OLD
06215 #endif
06216
06217 #define elf_backend_plt_not_loaded 1
06218 #define elf_backend_got_symbol_offset 4
06219 #define elf_backend_can_gc_sections 1
06220 #define elf_backend_can_refcount 1
06221 #define elf_backend_got_header_size 12
06222 #define elf_backend_rela_normal 1
06223
06224 #define bfd_elf32_mkobject ppc_elf_mkobject
06225 #define bfd_elf32_bfd_merge_private_bfd_data ppc_elf_merge_private_bfd_data
06226 #define bfd_elf32_bfd_relax_section ppc_elf_relax_section
06227 #define bfd_elf32_bfd_reloc_type_lookup ppc_elf_reloc_type_lookup
06228 #define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags
06229 #define bfd_elf32_bfd_link_hash_table_create ppc_elf_link_hash_table_create
06230
06231 #define elf_backend_object_p ppc_elf_object_p
06232 #define elf_backend_gc_mark_hook ppc_elf_gc_mark_hook
06233 #define elf_backend_gc_sweep_hook ppc_elf_gc_sweep_hook
06234 #define elf_backend_section_from_shdr ppc_elf_section_from_shdr
06235 #define elf_backend_relocate_section ppc_elf_relocate_section
06236 #define elf_backend_create_dynamic_sections ppc_elf_create_dynamic_sections
06237 #define elf_backend_check_relocs ppc_elf_check_relocs
06238 #define elf_backend_copy_indirect_symbol ppc_elf_copy_indirect_symbol
06239 #define elf_backend_adjust_dynamic_symbol ppc_elf_adjust_dynamic_symbol
06240 #define elf_backend_add_symbol_hook ppc_elf_add_symbol_hook
06241 #define elf_backend_size_dynamic_sections ppc_elf_size_dynamic_sections
06242 #define elf_backend_finish_dynamic_symbol ppc_elf_finish_dynamic_symbol
06243 #define elf_backend_finish_dynamic_sections ppc_elf_finish_dynamic_sections
06244 #define elf_backend_fake_sections ppc_elf_fake_sections
06245 #define elf_backend_additional_program_headers ppc_elf_additional_program_headers
06246 #define elf_backend_grok_prstatus ppc_elf_grok_prstatus
06247 #define elf_backend_grok_psinfo ppc_elf_grok_psinfo
06248 #define elf_backend_reloc_type_class ppc_elf_reloc_type_class
06249 #define elf_backend_begin_write_processing ppc_elf_begin_write_processing
06250 #define elf_backend_final_write_processing ppc_elf_final_write_processing
06251 #define elf_backend_write_section ppc_elf_write_section
06252 #define elf_backend_special_sections ppc_elf_special_sections
06253 #define elf_backend_plt_sym_val ppc_elf_plt_sym_val
06254
06255 #include "elf32-target.h"