00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "bfd.h"
00035 #include "sysdep.h"
00036 #include "libbfd.h"
00037 #include "libiberty.h"
00038 #include "elf-bfd.h"
00039 #include "elfxx-mips.h"
00040 #include "elf/mips.h"
00041
00042
00043 #include "coff/sym.h"
00044 #include "coff/symconst.h"
00045 #include "coff/ecoff.h"
00046 #include "coff/mips.h"
00047
00048 #include "hashtab.h"
00049
00050
00051
00052 struct mips_got_entry
00053 {
00054
00055 bfd *abfd;
00056
00057
00058 long symndx;
00059 union
00060 {
00061
00062 bfd_vma address;
00063
00064
00065 bfd_vma addend;
00066
00067
00068
00069 struct mips_elf_link_hash_entry *h;
00070 } d;
00071
00072
00073
00074
00075
00076
00077 unsigned char tls_type;
00078
00079
00080
00081
00082 long gotidx;
00083 };
00084
00085
00086
00087 struct mips_got_info
00088 {
00089
00090
00091 struct elf_link_hash_entry *global_gotsym;
00092
00093 unsigned int global_gotno;
00094
00095 unsigned int tls_gotno;
00096
00097
00098 unsigned int tls_assigned_gotno;
00099
00100 unsigned int local_gotno;
00101
00102 unsigned int assigned_gotno;
00103
00104 struct htab *got_entries;
00105
00106
00107 struct htab *bfd2got;
00108
00109
00110 struct mips_got_info *next;
00111
00112
00113
00114
00115 bfd_vma tls_ldm_offset;
00116 };
00117
00118
00119
00120 struct mips_elf_bfd2got_hash {
00121 bfd *bfd;
00122 struct mips_got_info *g;
00123 };
00124
00125
00126
00127
00128 struct mips_elf_got_per_bfd_arg
00129 {
00130
00131 htab_t bfd2got;
00132
00133 bfd *obfd;
00134
00135 struct bfd_link_info *info;
00136
00137
00138
00139 struct mips_got_info *primary;
00140
00141
00142 struct mips_got_info *current;
00143
00144
00145 unsigned int max_count;
00146
00147 unsigned int primary_count;
00148
00149 unsigned int current_count;
00150
00151
00152
00153
00154 unsigned int global_count;
00155 };
00156
00157
00158
00159 struct mips_elf_set_global_got_offset_arg
00160 {
00161 struct mips_got_info *g;
00162 int value;
00163 unsigned int needed_relocs;
00164 struct bfd_link_info *info;
00165 };
00166
00167
00168
00169
00170 struct mips_elf_count_tls_arg
00171 {
00172 struct bfd_link_info *info;
00173 unsigned int needed;
00174 };
00175
00176 struct _mips_elf_section_data
00177 {
00178 struct bfd_elf_section_data elf;
00179 union
00180 {
00181 struct mips_got_info *got_info;
00182 bfd_byte *tdata;
00183 } u;
00184 };
00185
00186 #define mips_elf_section_data(sec) \
00187 ((struct _mips_elf_section_data *) elf_section_data (sec))
00188
00189
00190
00191
00192 struct mips_elf_hash_sort_data
00193 {
00194
00195
00196 struct elf_link_hash_entry *low;
00197
00198
00199 long min_got_dynindx;
00200
00201
00202
00203 long max_unref_got_dynindx;
00204
00205
00206 long max_non_got_dynindx;
00207 };
00208
00209
00210
00211
00212 struct mips_elf_link_hash_entry
00213 {
00214 struct elf_link_hash_entry root;
00215
00216
00217 EXTR esym;
00218
00219
00220
00221 unsigned int possibly_dynamic_relocs;
00222
00223
00224
00225 bfd_boolean readonly_reloc;
00226
00227
00228
00229
00230
00231 bfd_boolean no_fn_stub;
00232
00233
00234
00235 asection *fn_stub;
00236
00237
00238
00239 bfd_boolean need_fn_stub;
00240
00241
00242
00243 asection *call_stub;
00244
00245
00246
00247 asection *call_fp_stub;
00248
00249
00250
00251 bfd_boolean forced_local;
00252
00253 #define GOT_NORMAL 0
00254 #define GOT_TLS_GD 1
00255 #define GOT_TLS_LDM 2
00256 #define GOT_TLS_IE 4
00257 #define GOT_TLS_OFFSET_DONE 0x40
00258 #define GOT_TLS_DONE 0x80
00259 unsigned char tls_type;
00260
00261
00262
00263
00264
00265
00266 bfd_vma tls_got_offset;
00267 };
00268
00269
00270
00271 struct mips_elf_link_hash_table
00272 {
00273 struct elf_link_hash_table root;
00274 #if 0
00275
00276
00277 bfd_size_type dynsym_sec_strindex[SIZEOF_MIPS_DYNSYM_SECNAMES];
00278 #endif
00279
00280 bfd_size_type procedure_count;
00281
00282 bfd_size_type compact_rel_size;
00283
00284
00285 bfd_boolean use_rld_obj_head;
00286
00287 bfd_vma rld_value;
00288
00289 bfd_boolean mips16_stubs_seen;
00290 };
00291
00292 #define TLS_RELOC_P(r_type) \
00293 (r_type == R_MIPS_TLS_DTPMOD32 \
00294 || r_type == R_MIPS_TLS_DTPMOD64 \
00295 || r_type == R_MIPS_TLS_DTPREL32 \
00296 || r_type == R_MIPS_TLS_DTPREL64 \
00297 || r_type == R_MIPS_TLS_GD \
00298 || r_type == R_MIPS_TLS_LDM \
00299 || r_type == R_MIPS_TLS_DTPREL_HI16 \
00300 || r_type == R_MIPS_TLS_DTPREL_LO16 \
00301 || r_type == R_MIPS_TLS_GOTTPREL \
00302 || r_type == R_MIPS_TLS_TPREL32 \
00303 || r_type == R_MIPS_TLS_TPREL64 \
00304 || r_type == R_MIPS_TLS_TPREL_HI16 \
00305 || r_type == R_MIPS_TLS_TPREL_LO16)
00306
00307
00308
00309 struct extsym_info
00310 {
00311 bfd *abfd;
00312 struct bfd_link_info *info;
00313 struct ecoff_debug_info *debug;
00314 const struct ecoff_debug_swap *swap;
00315 bfd_boolean failed;
00316 };
00317
00318
00319
00320 static const char * const mips_elf_dynsym_rtproc_names[] =
00321 {
00322 "_procedure_table",
00323 "_procedure_string_table",
00324 "_procedure_table_size",
00325 NULL
00326 };
00327
00328
00329
00330
00331 typedef struct
00332 {
00333 unsigned long id1;
00334 unsigned long num;
00335 unsigned long id2;
00336 unsigned long offset;
00337 unsigned long reserved0;
00338 unsigned long reserved1;
00339 } Elf32_compact_rel;
00340
00341 typedef struct
00342 {
00343 bfd_byte id1[4];
00344 bfd_byte num[4];
00345 bfd_byte id2[4];
00346 bfd_byte offset[4];
00347 bfd_byte reserved0[4];
00348 bfd_byte reserved1[4];
00349 } Elf32_External_compact_rel;
00350
00351 typedef struct
00352 {
00353 unsigned int ctype : 1;
00354 unsigned int rtype : 4;
00355 unsigned int dist2to : 8;
00356 unsigned int relvaddr : 19;
00357 unsigned long konst;
00358 unsigned long vaddr;
00359 } Elf32_crinfo;
00360
00361 typedef struct
00362 {
00363 unsigned int ctype : 1;
00364 unsigned int rtype : 4;
00365 unsigned int dist2to : 8;
00366 unsigned int relvaddr : 19;
00367 unsigned long konst;
00368 } Elf32_crinfo2;
00369
00370 typedef struct
00371 {
00372 bfd_byte info[4];
00373 bfd_byte konst[4];
00374 bfd_byte vaddr[4];
00375 } Elf32_External_crinfo;
00376
00377 typedef struct
00378 {
00379 bfd_byte info[4];
00380 bfd_byte konst[4];
00381 } Elf32_External_crinfo2;
00382
00383
00384
00385 #define CRINFO_CTYPE (0x1)
00386 #define CRINFO_CTYPE_SH (31)
00387 #define CRINFO_RTYPE (0xf)
00388 #define CRINFO_RTYPE_SH (27)
00389 #define CRINFO_DIST2TO (0xff)
00390 #define CRINFO_DIST2TO_SH (19)
00391 #define CRINFO_RELVADDR (0x7ffff)
00392 #define CRINFO_RELVADDR_SH (0)
00393
00394
00395
00396
00397 #define CRF_MIPS_LONG 1
00398 #define CRF_MIPS_SHORT 0
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 #define CRT_MIPS_REL32 0xa
00411 #define CRT_MIPS_WORD 0xb
00412 #define CRT_MIPS_GPHI_LO 0xc
00413 #define CRT_MIPS_JMPAD 0xd
00414
00415 #define mips_elf_set_cr_format(x,format) ((x).ctype = (format))
00416 #define mips_elf_set_cr_type(x,type) ((x).rtype = (type))
00417 #define mips_elf_set_cr_dist2to(x,v) ((x).dist2to = (v))
00418 #define mips_elf_set_cr_relvaddr(x,d) ((x).relvaddr = (d)<<2)
00419
00420
00421
00422
00423 typedef struct runtime_pdr {
00424 bfd_vma adr;
00425 long regmask;
00426 long regoffset;
00427 long fregmask;
00428 long fregoffset;
00429 long frameoffset;
00430 short framereg;
00431 short pcreg;
00432 long irpss;
00433 long reserved;
00434 struct exception_info *exception_info;
00435 } RPDR, *pRPDR;
00436 #define cbRPDR sizeof (RPDR)
00437 #define rpdNil ((pRPDR) 0)
00438
00439 static struct mips_got_entry *mips_elf_create_local_got_entry
00440 (bfd *, bfd *, struct mips_got_info *, asection *, bfd_vma, unsigned long,
00441 struct mips_elf_link_hash_entry *, int);
00442 static bfd_boolean mips_elf_sort_hash_table_f
00443 (struct mips_elf_link_hash_entry *, void *);
00444 static bfd_vma mips_elf_high
00445 (bfd_vma);
00446 static bfd_boolean mips_elf_stub_section_p
00447 (bfd *, asection *);
00448 static bfd_boolean mips_elf_create_dynamic_relocation
00449 (bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
00450 struct mips_elf_link_hash_entry *, asection *, bfd_vma,
00451 bfd_vma *, asection *);
00452 static hashval_t mips_elf_got_entry_hash
00453 (const void *);
00454 static bfd_vma mips_elf_adjust_gp
00455 (bfd *, struct mips_got_info *, bfd *);
00456 static struct mips_got_info *mips_elf_got_for_ibfd
00457 (struct mips_got_info *, bfd *);
00458
00459
00460 static bfd *reldyn_sorting_bfd;
00461
00462
00463
00464 #define ABI_N32_P(abfd) \
00465 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
00466
00467
00468 #define ABI_64_P(abfd) \
00469 (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
00470
00471
00472 #define NEWABI_P(abfd) (ABI_N32_P (abfd) || ABI_64_P (abfd))
00473
00474
00475 #define IRIX_COMPAT(abfd) \
00476 (get_elf_backend_data (abfd)->elf_backend_mips_irix_compat (abfd))
00477
00478
00479 #define SGI_COMPAT(abfd) \
00480 (IRIX_COMPAT (abfd) != ict_none)
00481
00482
00483 #define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \
00484 (NEWABI_P (abfd) ? ".MIPS.options" : ".options")
00485
00486
00487
00488 #define MIPS_ELF_OPTIONS_SECTION_NAME_P(NAME) \
00489 (strcmp (NAME, ".MIPS.options") == 0 || strcmp (NAME, ".options") == 0)
00490
00491
00492 #define MIPS_ELF_STUB_SECTION_NAME(abfd) ".MIPS.stubs"
00493
00494
00495 #define MIPS_ELF_REL_SIZE(abfd) \
00496 (get_elf_backend_data (abfd)->s->sizeof_rel)
00497
00498
00499 #define MIPS_ELF_DYN_SIZE(abfd) \
00500 (get_elf_backend_data (abfd)->s->sizeof_dyn)
00501
00502
00503 #define MIPS_ELF_GOT_SIZE(abfd) \
00504 (get_elf_backend_data (abfd)->s->arch_size / 8)
00505
00506
00507 #define MIPS_ELF_SYM_SIZE(abfd) \
00508 (get_elf_backend_data (abfd)->s->sizeof_sym)
00509
00510
00511 #define MIPS_ELF_LOG_FILE_ALIGN(abfd) \
00512 (get_elf_backend_data (abfd)->s->log_file_align)
00513
00514
00515 #define MIPS_ELF_GET_WORD(abfd, ptr) \
00516 (ABI_64_P (abfd) ? bfd_get_64 (abfd, ptr) : bfd_get_32 (abfd, ptr))
00517
00518
00519 #define MIPS_ELF_PUT_WORD(abfd, val, ptr) \
00520 (ABI_64_P (abfd) \
00521 ? bfd_put_64 (abfd, val, ptr) \
00522 : bfd_put_32 (abfd, val, ptr))
00523
00524
00525 #define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
00526 _bfd_elf_add_dynamic_entry (info, tag, val)
00527
00528 #define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela) \
00529 (get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela))
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 #define MIPS_RELOC_RELA_P(abfd, sec, rel_idx) \
00541 ((NUM_SHDR_ENTRIES (&elf_section_data (sec)->rel_hdr) \
00542 * get_elf_backend_data (abfd)->s->int_rels_per_ext_rel \
00543 > (bfd_vma)(rel_idx)) \
00544 == (elf_section_data (sec)->rel_hdr.sh_entsize \
00545 == (ABI_64_P (abfd) ? sizeof (Elf64_External_Rela) \
00546 : sizeof (Elf32_External_Rela))))
00547
00548
00549
00550 #define MINUS_ONE (((bfd_vma)0) - 1)
00551 #define MINUS_TWO (((bfd_vma)0) - 2)
00552
00553
00554 #define MIPS_RESERVED_GOTNO (2)
00555
00556
00557 #define ELF_MIPS_GP_OFFSET(abfd) (0x7ff0)
00558
00559
00560
00561 #define MIPS_ELF_GOT_MAX_SIZE(abfd) (ELF_MIPS_GP_OFFSET(abfd) + 0x7fff)
00562
00563
00564 #define STUB_LW(abfd) \
00565 ((ABI_64_P (abfd) \
00566 ? 0xdf998010 \
00567 : 0x8f998010))
00568 #define STUB_MOVE(abfd) \
00569 ((ABI_64_P (abfd) \
00570 ? 0x03e0782d \
00571 : 0x03e07821))
00572 #define STUB_JALR 0x0320f809
00573 #define STUB_LI16(abfd) \
00574 ((ABI_64_P (abfd) \
00575 ? 0x64180000 \
00576 : 0x24180000))
00577 #define MIPS_FUNCTION_STUB_SIZE (16)
00578
00579
00580
00581
00582 #define ELF_DYNAMIC_INTERPRETER(abfd) \
00583 (ABI_N32_P (abfd) ? "/usr/lib32/libc.so.1" \
00584 : ABI_64_P (abfd) ? "/usr/lib64/libc.so.1" \
00585 : "/usr/lib/libc.so.1")
00586
00587 #ifdef BFD64
00588 #define MNAME(bfd,pre,pos) \
00589 (ABI_64_P (bfd) ? CONCAT4 (pre,64,_,pos) : CONCAT4 (pre,32,_,pos))
00590 #define ELF_R_SYM(bfd, i) \
00591 (ABI_64_P (bfd) ? ELF64_R_SYM (i) : ELF32_R_SYM (i))
00592 #define ELF_R_TYPE(bfd, i) \
00593 (ABI_64_P (bfd) ? ELF64_MIPS_R_TYPE (i) : ELF32_R_TYPE (i))
00594 #define ELF_R_INFO(bfd, s, t) \
00595 (ABI_64_P (bfd) ? ELF64_R_INFO (s, t) : ELF32_R_INFO (s, t))
00596 #else
00597 #define MNAME(bfd,pre,pos) CONCAT4 (pre,32,_,pos)
00598 #define ELF_R_SYM(bfd, i) \
00599 (ELF32_R_SYM (i))
00600 #define ELF_R_TYPE(bfd, i) \
00601 (ELF32_R_TYPE (i))
00602 #define ELF_R_INFO(bfd, s, t) \
00603 (ELF32_R_INFO (s, t))
00604 #endif
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 #define FN_STUB ".mips16.fn."
00641 #define CALL_STUB ".mips16.call."
00642 #define CALL_FP_STUB ".mips16.call.fp."
00643
00644
00645
00646 #define mips_elf_link_hash_lookup(table, string, create, copy, follow) \
00647 ((struct mips_elf_link_hash_entry *) \
00648 elf_link_hash_lookup (&(table)->root, (string), (create), \
00649 (copy), (follow)))
00650
00651
00652
00653 #define mips_elf_link_hash_traverse(table, func, info) \
00654 (elf_link_hash_traverse \
00655 (&(table)->root, \
00656 (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
00657 (info)))
00658
00659
00660
00661 #define mips_elf_hash_table(p) \
00662 ((struct mips_elf_link_hash_table *) ((p)->hash))
00663
00664
00665
00666
00667 #define TP_OFFSET 0x7000
00668 #define DTP_OFFSET 0x8000
00669
00670 static bfd_vma
00671 dtprel_base (struct bfd_link_info *info)
00672 {
00673
00674 if (elf_hash_table (info)->tls_sec == NULL)
00675 return 0;
00676 return elf_hash_table (info)->tls_sec->vma + DTP_OFFSET;
00677 }
00678
00679 static bfd_vma
00680 tprel_base (struct bfd_link_info *info)
00681 {
00682
00683 if (elf_hash_table (info)->tls_sec == NULL)
00684 return 0;
00685 return elf_hash_table (info)->tls_sec->vma + TP_OFFSET;
00686 }
00687
00688
00689
00690 static struct bfd_hash_entry *
00691 mips_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
00692 struct bfd_hash_table *table, const char *string)
00693 {
00694 struct mips_elf_link_hash_entry *ret =
00695 (struct mips_elf_link_hash_entry *) entry;
00696
00697
00698
00699 if (ret == NULL)
00700 ret = bfd_hash_allocate (table, sizeof (struct mips_elf_link_hash_entry));
00701 if (ret == NULL)
00702 return (struct bfd_hash_entry *) ret;
00703
00704
00705 ret = ((struct mips_elf_link_hash_entry *)
00706 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
00707 table, string));
00708 if (ret != NULL)
00709 {
00710
00711 memset (&ret->esym, 0, sizeof (EXTR));
00712
00713
00714 ret->esym.ifd = -2;
00715 ret->possibly_dynamic_relocs = 0;
00716 ret->readonly_reloc = FALSE;
00717 ret->no_fn_stub = FALSE;
00718 ret->fn_stub = NULL;
00719 ret->need_fn_stub = FALSE;
00720 ret->call_stub = NULL;
00721 ret->call_fp_stub = NULL;
00722 ret->forced_local = FALSE;
00723 ret->tls_type = GOT_NORMAL;
00724 }
00725
00726 return (struct bfd_hash_entry *) ret;
00727 }
00728
00729 bfd_boolean
00730 _bfd_mips_elf_new_section_hook (bfd *abfd, asection *sec)
00731 {
00732 struct _mips_elf_section_data *sdata;
00733 bfd_size_type amt = sizeof (*sdata);
00734
00735 sdata = bfd_zalloc (abfd, amt);
00736 if (sdata == NULL)
00737 return FALSE;
00738 sec->used_by_bfd = sdata;
00739
00740 return _bfd_elf_new_section_hook (abfd, sec);
00741 }
00742
00743
00744
00745
00746 bfd_boolean
00747 _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section,
00748 struct ecoff_debug_info *debug)
00749 {
00750 HDRR *symhdr;
00751 const struct ecoff_debug_swap *swap;
00752 char *ext_hdr;
00753
00754 swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
00755 memset (debug, 0, sizeof (*debug));
00756
00757 ext_hdr = bfd_malloc (swap->external_hdr_size);
00758 if (ext_hdr == NULL && swap->external_hdr_size != 0)
00759 goto error_return;
00760
00761 if (! bfd_get_section_contents (abfd, section, ext_hdr, 0,
00762 swap->external_hdr_size))
00763 goto error_return;
00764
00765 symhdr = &debug->symbolic_header;
00766 (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);
00767
00768
00769
00770 #define READ(ptr, offset, count, size, type) \
00771 if (symhdr->count == 0) \
00772 debug->ptr = NULL; \
00773 else \
00774 { \
00775 bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
00776 debug->ptr = bfd_malloc (amt); \
00777 if (debug->ptr == NULL) \
00778 goto error_return; \
00779 if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0 \
00780 || bfd_bread (debug->ptr, amt, abfd) != amt) \
00781 goto error_return; \
00782 }
00783
00784 READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
00785 READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);
00786 READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *);
00787 READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *);
00788 READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *);
00789 READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
00790 union aux_ext *);
00791 READ (ss, cbSsOffset, issMax, sizeof (char), char *);
00792 READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
00793 READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *);
00794 READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *);
00795 READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, void *);
00796 #undef READ
00797
00798 debug->fdr = NULL;
00799
00800 return TRUE;
00801
00802 error_return:
00803 if (ext_hdr != NULL)
00804 free (ext_hdr);
00805 if (debug->line != NULL)
00806 free (debug->line);
00807 if (debug->external_dnr != NULL)
00808 free (debug->external_dnr);
00809 if (debug->external_pdr != NULL)
00810 free (debug->external_pdr);
00811 if (debug->external_sym != NULL)
00812 free (debug->external_sym);
00813 if (debug->external_opt != NULL)
00814 free (debug->external_opt);
00815 if (debug->external_aux != NULL)
00816 free (debug->external_aux);
00817 if (debug->ss != NULL)
00818 free (debug->ss);
00819 if (debug->ssext != NULL)
00820 free (debug->ssext);
00821 if (debug->external_fdr != NULL)
00822 free (debug->external_fdr);
00823 if (debug->external_rfd != NULL)
00824 free (debug->external_rfd);
00825 if (debug->external_ext != NULL)
00826 free (debug->external_ext);
00827 return FALSE;
00828 }
00829
00830
00831
00832 static void
00833 ecoff_swap_rpdr_out (bfd *abfd, const RPDR *in, struct rpdr_ext *ex)
00834 {
00835 H_PUT_S32 (abfd, in->adr, ex->p_adr);
00836 H_PUT_32 (abfd, in->regmask, ex->p_regmask);
00837 H_PUT_32 (abfd, in->regoffset, ex->p_regoffset);
00838 H_PUT_32 (abfd, in->fregmask, ex->p_fregmask);
00839 H_PUT_32 (abfd, in->fregoffset, ex->p_fregoffset);
00840 H_PUT_32 (abfd, in->frameoffset, ex->p_frameoffset);
00841
00842 H_PUT_16 (abfd, in->framereg, ex->p_framereg);
00843 H_PUT_16 (abfd, in->pcreg, ex->p_pcreg);
00844
00845 H_PUT_32 (abfd, in->irpss, ex->p_irpss);
00846 }
00847
00848
00849
00850 static bfd_boolean
00851 mips_elf_create_procedure_table (void *handle, bfd *abfd,
00852 struct bfd_link_info *info, asection *s,
00853 struct ecoff_debug_info *debug)
00854 {
00855 const struct ecoff_debug_swap *swap;
00856 HDRR *hdr = &debug->symbolic_header;
00857 RPDR *rpdr, *rp;
00858 struct rpdr_ext *erp;
00859 void *rtproc;
00860 struct pdr_ext *epdr;
00861 struct sym_ext *esym;
00862 char *ss, **sv;
00863 char *str;
00864 bfd_size_type size;
00865 bfd_size_type count;
00866 unsigned long sindex;
00867 unsigned long i;
00868 PDR pdr;
00869 SYMR sym;
00870 const char *no_name_func = _("static procedure (no name)");
00871
00872 epdr = NULL;
00873 rpdr = NULL;
00874 esym = NULL;
00875 ss = NULL;
00876 sv = NULL;
00877
00878 swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
00879
00880 sindex = strlen (no_name_func) + 1;
00881 count = hdr->ipdMax;
00882 if (count > 0)
00883 {
00884 size = swap->external_pdr_size;
00885
00886 epdr = bfd_malloc (size * count);
00887 if (epdr == NULL)
00888 goto error_return;
00889
00890 if (! _bfd_ecoff_get_accumulated_pdr (handle, (bfd_byte *) epdr))
00891 goto error_return;
00892
00893 size = sizeof (RPDR);
00894 rp = rpdr = bfd_malloc (size * count);
00895 if (rpdr == NULL)
00896 goto error_return;
00897
00898 size = sizeof (char *);
00899 sv = bfd_malloc (size * count);
00900 if (sv == NULL)
00901 goto error_return;
00902
00903 count = hdr->isymMax;
00904 size = swap->external_sym_size;
00905 esym = bfd_malloc (size * count);
00906 if (esym == NULL)
00907 goto error_return;
00908
00909 if (! _bfd_ecoff_get_accumulated_sym (handle, (bfd_byte *) esym))
00910 goto error_return;
00911
00912 count = hdr->issMax;
00913 ss = bfd_malloc (count);
00914 if (ss == NULL)
00915 goto error_return;
00916 if (! _bfd_ecoff_get_accumulated_ss (handle, (bfd_byte *) ss))
00917 goto error_return;
00918
00919 count = hdr->ipdMax;
00920 for (i = 0; i < (unsigned long) count; i++, rp++)
00921 {
00922 (*swap->swap_pdr_in) (abfd, epdr + i, &pdr);
00923 (*swap->swap_sym_in) (abfd, &esym[pdr.isym], &sym);
00924 rp->adr = sym.value;
00925 rp->regmask = pdr.regmask;
00926 rp->regoffset = pdr.regoffset;
00927 rp->fregmask = pdr.fregmask;
00928 rp->fregoffset = pdr.fregoffset;
00929 rp->frameoffset = pdr.frameoffset;
00930 rp->framereg = pdr.framereg;
00931 rp->pcreg = pdr.pcreg;
00932 rp->irpss = sindex;
00933 sv[i] = ss + sym.iss;
00934 sindex += strlen (sv[i]) + 1;
00935 }
00936 }
00937
00938 size = sizeof (struct rpdr_ext) * (count + 2) + sindex;
00939 size = BFD_ALIGN (size, 16);
00940 rtproc = bfd_alloc (abfd, size);
00941 if (rtproc == NULL)
00942 {
00943 mips_elf_hash_table (info)->procedure_count = 0;
00944 goto error_return;
00945 }
00946
00947 mips_elf_hash_table (info)->procedure_count = count + 2;
00948
00949 erp = rtproc;
00950 memset (erp, 0, sizeof (struct rpdr_ext));
00951 erp++;
00952 str = (char *) rtproc + sizeof (struct rpdr_ext) * (count + 2);
00953 strcpy (str, no_name_func);
00954 str += strlen (no_name_func) + 1;
00955 for (i = 0; i < count; i++)
00956 {
00957 ecoff_swap_rpdr_out (abfd, rpdr + i, erp + i);
00958 strcpy (str, sv[i]);
00959 str += strlen (sv[i]) + 1;
00960 }
00961 H_PUT_S32 (abfd, -1, (erp + count)->p_adr);
00962
00963
00964 s->size = size;
00965 s->contents = rtproc;
00966
00967
00968
00969 s->link_order_head = NULL;
00970
00971 if (epdr != NULL)
00972 free (epdr);
00973 if (rpdr != NULL)
00974 free (rpdr);
00975 if (esym != NULL)
00976 free (esym);
00977 if (ss != NULL)
00978 free (ss);
00979 if (sv != NULL)
00980 free (sv);
00981
00982 return TRUE;
00983
00984 error_return:
00985 if (epdr != NULL)
00986 free (epdr);
00987 if (rpdr != NULL)
00988 free (rpdr);
00989 if (esym != NULL)
00990 free (esym);
00991 if (ss != NULL)
00992 free (ss);
00993 if (sv != NULL)
00994 free (sv);
00995 return FALSE;
00996 }
00997
00998
00999
01000
01001 static bfd_boolean
01002 mips_elf_check_mips16_stubs (struct mips_elf_link_hash_entry *h,
01003 void *data ATTRIBUTE_UNUSED)
01004 {
01005 if (h->root.root.type == bfd_link_hash_warning)
01006 h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
01007
01008 if (h->fn_stub != NULL
01009 && ! h->need_fn_stub)
01010 {
01011
01012
01013
01014 h->fn_stub->size = 0;
01015 h->fn_stub->flags &= ~SEC_RELOC;
01016 h->fn_stub->reloc_count = 0;
01017 h->fn_stub->flags |= SEC_EXCLUDE;
01018 }
01019
01020 if (h->call_stub != NULL
01021 && h->root.other == STO_MIPS16)
01022 {
01023
01024
01025
01026 h->call_stub->size = 0;
01027 h->call_stub->flags &= ~SEC_RELOC;
01028 h->call_stub->reloc_count = 0;
01029 h->call_stub->flags |= SEC_EXCLUDE;
01030 }
01031
01032 if (h->call_fp_stub != NULL
01033 && h->root.other == STO_MIPS16)
01034 {
01035
01036
01037
01038 h->call_fp_stub->size = 0;
01039 h->call_fp_stub->flags &= ~SEC_RELOC;
01040 h->call_fp_stub->reloc_count = 0;
01041 h->call_fp_stub->flags |= SEC_EXCLUDE;
01042 }
01043
01044 return TRUE;
01045 }
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 void
01133 _bfd_mips16_elf_reloc_unshuffle (bfd *abfd, int r_type,
01134 bfd_boolean jal_shuffle, bfd_byte *data)
01135 {
01136 bfd_vma extend, insn, val;
01137
01138 if (r_type != R_MIPS16_26 && r_type != R_MIPS16_GPREL
01139 && r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16)
01140 return;
01141
01142
01143 extend = bfd_get_16 (abfd, data);
01144 insn = bfd_get_16 (abfd, data + 2);
01145 if (r_type == R_MIPS16_26)
01146 {
01147 if (jal_shuffle)
01148 val = ((extend & 0xfc00) << 16) | ((extend & 0x3e0) << 11)
01149 | ((extend & 0x1f) << 21) | insn;
01150 else
01151 val = extend << 16 | insn;
01152 }
01153 else
01154 val = ((extend & 0xf800) << 16) | ((insn & 0xffe0) << 11)
01155 | ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
01156 bfd_put_32 (abfd, val, data);
01157 }
01158
01159 void
01160 _bfd_mips16_elf_reloc_shuffle (bfd *abfd, int r_type,
01161 bfd_boolean jal_shuffle, bfd_byte *data)
01162 {
01163 bfd_vma extend, insn, val;
01164
01165 if (r_type != R_MIPS16_26 && r_type != R_MIPS16_GPREL
01166 && r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16)
01167 return;
01168
01169 val = bfd_get_32 (abfd, data);
01170 if (r_type == R_MIPS16_26)
01171 {
01172 if (jal_shuffle)
01173 {
01174 insn = val & 0xffff;
01175 extend = ((val >> 16) & 0xfc00) | ((val >> 11) & 0x3e0)
01176 | ((val >> 21) & 0x1f);
01177 }
01178 else
01179 {
01180 insn = val & 0xffff;
01181 extend = val >> 16;
01182 }
01183 }
01184 else
01185 {
01186 insn = ((val >> 11) & 0xffe0) | (val & 0x1f);
01187 extend = ((val >> 16) & 0xf800) | ((val >> 11) & 0x1f) | (val & 0x7e0);
01188 }
01189 bfd_put_16 (abfd, insn, data + 2);
01190 bfd_put_16 (abfd, extend, data);
01191 }
01192
01193 bfd_reloc_status_type
01194 _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol,
01195 arelent *reloc_entry, asection *input_section,
01196 bfd_boolean relocatable, void *data, bfd_vma gp)
01197 {
01198 bfd_vma relocation;
01199 bfd_signed_vma val;
01200 bfd_reloc_status_type status;
01201
01202 if (bfd_is_com_section (symbol->section))
01203 relocation = 0;
01204 else
01205 relocation = symbol->value;
01206
01207 relocation += symbol->section->output_section->vma;
01208 relocation += symbol->section->output_offset;
01209
01210 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
01211 return bfd_reloc_outofrange;
01212
01213
01214 val = reloc_entry->addend;
01215
01216 _bfd_mips_elf_sign_extend (val, 16);
01217
01218
01219
01220
01221 if (! relocatable
01222 || (symbol->flags & BSF_SECTION_SYM) != 0)
01223 val += relocation - gp;
01224
01225 if (reloc_entry->howto->partial_inplace)
01226 {
01227 status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
01228 (bfd_byte *) data
01229 + reloc_entry->address);
01230 if (status != bfd_reloc_ok)
01231 return status;
01232 }
01233 else
01234 reloc_entry->addend = val;
01235
01236 if (relocatable)
01237 reloc_entry->address += input_section->output_offset;
01238
01239 return bfd_reloc_ok;
01240 }
01241
01242
01243
01244
01245
01246
01247 struct mips_hi16
01248 {
01249 struct mips_hi16 *next;
01250 bfd_byte *data;
01251 asection *input_section;
01252 arelent rel;
01253 };
01254
01255
01256
01257 static struct mips_hi16 *mips_hi16_list;
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268 bfd_reloc_status_type
01269 _bfd_mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
01270 asymbol *symbol ATTRIBUTE_UNUSED, void *data,
01271 asection *input_section, bfd *output_bfd,
01272 char **error_message ATTRIBUTE_UNUSED)
01273 {
01274 struct mips_hi16 *n;
01275
01276 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
01277 return bfd_reloc_outofrange;
01278
01279 n = bfd_malloc (sizeof *n);
01280 if (n == NULL)
01281 return bfd_reloc_outofrange;
01282
01283 n->next = mips_hi16_list;
01284 n->data = data;
01285 n->input_section = input_section;
01286 n->rel = *reloc_entry;
01287 mips_hi16_list = n;
01288
01289 if (output_bfd != NULL)
01290 reloc_entry->address += input_section->output_offset;
01291
01292 return bfd_reloc_ok;
01293 }
01294
01295
01296
01297
01298
01299 bfd_reloc_status_type
01300 _bfd_mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01301 void *data, asection *input_section,
01302 bfd *output_bfd, char **error_message)
01303 {
01304 if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
01305 || bfd_is_und_section (bfd_get_section (symbol))
01306 || bfd_is_com_section (bfd_get_section (symbol)))
01307
01308 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
01309 input_section, output_bfd,
01310 error_message);
01311
01312 return _bfd_mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
01313 input_section, output_bfd, error_message);
01314 }
01315
01316
01317
01318
01319
01320 bfd_reloc_status_type
01321 _bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
01322 void *data, asection *input_section,
01323 bfd *output_bfd, char **error_message)
01324 {
01325 bfd_vma vallo;
01326 bfd_byte *location = (bfd_byte *) data + reloc_entry->address;
01327
01328 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
01329 return bfd_reloc_outofrange;
01330
01331 _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
01332 location);
01333 vallo = bfd_get_32 (abfd, location);
01334 _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, FALSE,
01335 location);
01336
01337 while (mips_hi16_list != NULL)
01338 {
01339 bfd_reloc_status_type ret;
01340 struct mips_hi16 *hi;
01341
01342 hi = mips_hi16_list;
01343
01344
01345
01346
01347
01348
01349 if (hi->rel.howto->type == R_MIPS_GOT16)
01350 hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, FALSE);
01351
01352
01353
01354 hi->rel.addend += (vallo + 0x8000) & 0xffff;
01355
01356 ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data,
01357 hi->input_section, output_bfd,
01358 error_message);
01359 if (ret != bfd_reloc_ok)
01360 return ret;
01361
01362 mips_hi16_list = hi->next;
01363 free (hi);
01364 }
01365
01366 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
01367 input_section, output_bfd,
01368 error_message);
01369 }
01370
01371
01372
01373
01374
01375 bfd_reloc_status_type
01376 _bfd_mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
01377 asymbol *symbol, void *data ATTRIBUTE_UNUSED,
01378 asection *input_section, bfd *output_bfd,
01379 char **error_message ATTRIBUTE_UNUSED)
01380 {
01381 bfd_signed_vma val;
01382 bfd_reloc_status_type status;
01383 bfd_boolean relocatable;
01384
01385 relocatable = (output_bfd != NULL);
01386
01387 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
01388 return bfd_reloc_outofrange;
01389
01390
01391 val = 0;
01392 if (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0)
01393 {
01394
01395
01396
01397 val += symbol->section->output_section->vma;
01398 val += symbol->section->output_offset;
01399 }
01400
01401 if (!relocatable)
01402 {
01403
01404
01405 val += symbol->value;
01406 if (reloc_entry->howto->pc_relative)
01407 {
01408 val -= input_section->output_section->vma;
01409 val -= input_section->output_offset;
01410 val -= reloc_entry->address;
01411 }
01412 }
01413
01414
01415
01416
01417
01418 if (relocatable && !reloc_entry->howto->partial_inplace)
01419 reloc_entry->addend += val;
01420 else
01421 {
01422 bfd_byte *location = (bfd_byte *) data + reloc_entry->address;
01423
01424
01425 val += reloc_entry->addend;
01426
01427
01428 _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
01429 location);
01430 status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
01431 location);
01432 _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, FALSE,
01433 location);
01434
01435 if (status != bfd_reloc_ok)
01436 return status;
01437 }
01438
01439 if (relocatable)
01440 reloc_entry->address += input_section->output_offset;
01441
01442 return bfd_reloc_ok;
01443 }
01444
01445
01446
01447
01448 static void
01449 bfd_mips_elf32_swap_gptab_in (bfd *abfd, const Elf32_External_gptab *ex,
01450 Elf32_gptab *in)
01451 {
01452 in->gt_entry.gt_g_value = H_GET_32 (abfd, ex->gt_entry.gt_g_value);
01453 in->gt_entry.gt_bytes = H_GET_32 (abfd, ex->gt_entry.gt_bytes);
01454 }
01455
01456 static void
01457 bfd_mips_elf32_swap_gptab_out (bfd *abfd, const Elf32_gptab *in,
01458 Elf32_External_gptab *ex)
01459 {
01460 H_PUT_32 (abfd, in->gt_entry.gt_g_value, ex->gt_entry.gt_g_value);
01461 H_PUT_32 (abfd, in->gt_entry.gt_bytes, ex->gt_entry.gt_bytes);
01462 }
01463
01464 static void
01465 bfd_elf32_swap_compact_rel_out (bfd *abfd, const Elf32_compact_rel *in,
01466 Elf32_External_compact_rel *ex)
01467 {
01468 H_PUT_32 (abfd, in->id1, ex->id1);
01469 H_PUT_32 (abfd, in->num, ex->num);
01470 H_PUT_32 (abfd, in->id2, ex->id2);
01471 H_PUT_32 (abfd, in->offset, ex->offset);
01472 H_PUT_32 (abfd, in->reserved0, ex->reserved0);
01473 H_PUT_32 (abfd, in->reserved1, ex->reserved1);
01474 }
01475
01476 static void
01477 bfd_elf32_swap_crinfo_out (bfd *abfd, const Elf32_crinfo *in,
01478 Elf32_External_crinfo *ex)
01479 {
01480 unsigned long l;
01481
01482 l = (((in->ctype & CRINFO_CTYPE) << CRINFO_CTYPE_SH)
01483 | ((in->rtype & CRINFO_RTYPE) << CRINFO_RTYPE_SH)
01484 | ((in->dist2to & CRINFO_DIST2TO) << CRINFO_DIST2TO_SH)
01485 | ((in->relvaddr & CRINFO_RELVADDR) << CRINFO_RELVADDR_SH));
01486 H_PUT_32 (abfd, l, ex->info);
01487 H_PUT_32 (abfd, in->konst, ex->konst);
01488 H_PUT_32 (abfd, in->vaddr, ex->vaddr);
01489 }
01490
01491
01492
01493
01494
01495 void
01496 bfd_mips_elf32_swap_reginfo_in (bfd *abfd, const Elf32_External_RegInfo *ex,
01497 Elf32_RegInfo *in)
01498 {
01499 in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
01500 in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]);
01501 in->ri_cprmask[1] = H_GET_32 (abfd, ex->ri_cprmask[1]);
01502 in->ri_cprmask[2] = H_GET_32 (abfd, ex->ri_cprmask[2]);
01503 in->ri_cprmask[3] = H_GET_32 (abfd, ex->ri_cprmask[3]);
01504 in->ri_gp_value = H_GET_32 (abfd, ex->ri_gp_value);
01505 }
01506
01507 void
01508 bfd_mips_elf32_swap_reginfo_out (bfd *abfd, const Elf32_RegInfo *in,
01509 Elf32_External_RegInfo *ex)
01510 {
01511 H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
01512 H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]);
01513 H_PUT_32 (abfd, in->ri_cprmask[1], ex->ri_cprmask[1]);
01514 H_PUT_32 (abfd, in->ri_cprmask[2], ex->ri_cprmask[2]);
01515 H_PUT_32 (abfd, in->ri_cprmask[3], ex->ri_cprmask[3]);
01516 H_PUT_32 (abfd, in->ri_gp_value, ex->ri_gp_value);
01517 }
01518
01519
01520
01521
01522
01523
01524
01525 void
01526 bfd_mips_elf64_swap_reginfo_in (bfd *abfd, const Elf64_External_RegInfo *ex,
01527 Elf64_Internal_RegInfo *in)
01528 {
01529 in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
01530 in->ri_pad = H_GET_32 (abfd, ex->ri_pad);
01531 in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]);
01532 in->ri_cprmask[1] = H_GET_32 (abfd, ex->ri_cprmask[1]);
01533 in->ri_cprmask[2] = H_GET_32 (abfd, ex->ri_cprmask[2]);
01534 in->ri_cprmask[3] = H_GET_32 (abfd, ex->ri_cprmask[3]);
01535 in->ri_gp_value = H_GET_64 (abfd, ex->ri_gp_value);
01536 }
01537
01538 void
01539 bfd_mips_elf64_swap_reginfo_out (bfd *abfd, const Elf64_Internal_RegInfo *in,
01540 Elf64_External_RegInfo *ex)
01541 {
01542 H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
01543 H_PUT_32 (abfd, in->ri_pad, ex->ri_pad);
01544 H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]);
01545 H_PUT_32 (abfd, in->ri_cprmask[1], ex->ri_cprmask[1]);
01546 H_PUT_32 (abfd, in->ri_cprmask[2], ex->ri_cprmask[2]);
01547 H_PUT_32 (abfd, in->ri_cprmask[3], ex->ri_cprmask[3]);
01548 H_PUT_64 (abfd, in->ri_gp_value, ex->ri_gp_value);
01549 }
01550
01551
01552
01553 void
01554 bfd_mips_elf_swap_options_in (bfd *abfd, const Elf_External_Options *ex,
01555 Elf_Internal_Options *in)
01556 {
01557 in->kind = H_GET_8 (abfd, ex->kind);
01558 in->size = H_GET_8 (abfd, ex->size);
01559 in->section = H_GET_16 (abfd, ex->section);
01560 in->info = H_GET_32 (abfd, ex->info);
01561 }
01562
01563
01564
01565 void
01566 bfd_mips_elf_swap_options_out (bfd *abfd, const Elf_Internal_Options *in,
01567 Elf_External_Options *ex)
01568 {
01569 H_PUT_8 (abfd, in->kind, ex->kind);
01570 H_PUT_8 (abfd, in->size, ex->size);
01571 H_PUT_16 (abfd, in->section, ex->section);
01572 H_PUT_32 (abfd, in->info, ex->info);
01573 }
01574
01575
01576
01577
01578 static int
01579 sort_dynamic_relocs (const void *arg1, const void *arg2)
01580 {
01581 Elf_Internal_Rela int_reloc1;
01582 Elf_Internal_Rela int_reloc2;
01583
01584 bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
01585 bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
01586
01587 return ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info);
01588 }
01589
01590
01591
01592 static int
01593 sort_dynamic_relocs_64 (const void *arg1 ATTRIBUTE_UNUSED,
01594 const void *arg2 ATTRIBUTE_UNUSED)
01595 {
01596 #ifdef BFD64
01597 Elf_Internal_Rela int_reloc1[3];
01598 Elf_Internal_Rela int_reloc2[3];
01599
01600 (*get_elf_backend_data (reldyn_sorting_bfd)->s->swap_reloc_in)
01601 (reldyn_sorting_bfd, arg1, int_reloc1);
01602 (*get_elf_backend_data (reldyn_sorting_bfd)->s->swap_reloc_in)
01603 (reldyn_sorting_bfd, arg2, int_reloc2);
01604
01605 return (ELF64_R_SYM (int_reloc1[0].r_info)
01606 - ELF64_R_SYM (int_reloc2[0].r_info));
01607 #else
01608 abort ();
01609 #endif
01610 }
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627 static bfd_boolean
01628 mips_elf_output_extsym (struct mips_elf_link_hash_entry *h, void *data)
01629 {
01630 struct extsym_info *einfo = data;
01631 bfd_boolean strip;
01632 asection *sec, *output_section;
01633
01634 if (h->root.root.type == bfd_link_hash_warning)
01635 h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
01636
01637 if (h->root.indx == -2)
01638 strip = FALSE;
01639 else if ((h->root.def_dynamic
01640 || h->root.ref_dynamic
01641 || h->root.type == bfd_link_hash_new)
01642 && !h->root.def_regular
01643 && !h->root.ref_regular)
01644 strip = TRUE;
01645 else if (einfo->info->strip == strip_all
01646 || (einfo->info->strip == strip_some
01647 && bfd_hash_lookup (einfo->info->keep_hash,
01648 h->root.root.root.string,
01649 FALSE, FALSE) == NULL))
01650 strip = TRUE;
01651 else
01652 strip = FALSE;
01653
01654 if (strip)
01655 return TRUE;
01656
01657 if (h->esym.ifd == -2)
01658 {
01659 h->esym.jmptbl = 0;
01660 h->esym.cobol_main = 0;
01661 h->esym.weakext = 0;
01662 h->esym.reserved = 0;
01663 h->esym.ifd = ifdNil;
01664 h->esym.asym.value = 0;
01665 h->esym.asym.st = stGlobal;
01666
01667 if (h->root.root.type == bfd_link_hash_undefined
01668 || h->root.root.type == bfd_link_hash_undefweak)
01669 {
01670 const char *name;
01671
01672
01673
01674 name = h->root.root.root.string;
01675 if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0
01676 || strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0)
01677 {
01678 h->esym.asym.sc = scData;
01679 h->esym.asym.st = stLabel;
01680 h->esym.asym.value = 0;
01681 }
01682 else if (strcmp (name, mips_elf_dynsym_rtproc_names[2]) == 0)
01683 {
01684 h->esym.asym.sc = scAbs;
01685 h->esym.asym.st = stLabel;
01686 h->esym.asym.value =
01687 mips_elf_hash_table (einfo->info)->procedure_count;
01688 }
01689 else if (strcmp (name, "_gp_disp") == 0 && ! NEWABI_P (einfo->abfd))
01690 {
01691 h->esym.asym.sc = scAbs;
01692 h->esym.asym.st = stLabel;
01693 h->esym.asym.value = elf_gp (einfo->abfd);
01694 }
01695 else
01696 h->esym.asym.sc = scUndefined;
01697 }
01698 else if (h->root.root.type != bfd_link_hash_defined
01699 && h->root.root.type != bfd_link_hash_defweak)
01700 h->esym.asym.sc = scAbs;
01701 else
01702 {
01703 const char *name;
01704
01705 sec = h->root.root.u.def.section;
01706 output_section = sec->output_section;
01707
01708
01709
01710 if (output_section == NULL)
01711 h->esym.asym.sc = scUndefined;
01712 else
01713 {
01714 name = bfd_section_name (output_section->owner, output_section);
01715
01716 if (strcmp (name, ".text") == 0)
01717 h->esym.asym.sc = scText;
01718 else if (strcmp (name, ".data") == 0)
01719 h->esym.asym.sc = scData;
01720 else if (strcmp (name, ".sdata") == 0)
01721 h->esym.asym.sc = scSData;
01722 else if (strcmp (name, ".rodata") == 0
01723 || strcmp (name, ".rdata") == 0)
01724 h->esym.asym.sc = scRData;
01725 else if (strcmp (name, ".bss") == 0)
01726 h->esym.asym.sc = scBss;
01727 else if (strcmp (name, ".sbss") == 0)
01728 h->esym.asym.sc = scSBss;
01729 else if (strcmp (name, ".init") == 0)
01730 h->esym.asym.sc = scInit;
01731 else if (strcmp (name, ".fini") == 0)
01732 h->esym.asym.sc = scFini;
01733 else
01734 h->esym.asym.sc = scAbs;
01735 }
01736 }
01737
01738 h->esym.asym.reserved = 0;
01739 h->esym.asym.index = indexNil;
01740 }
01741
01742 if (h->root.root.type == bfd_link_hash_common)
01743 h->esym.asym.value = h->root.root.u.c.size;
01744 else if (h->root.root.type == bfd_link_hash_defined
01745 || h->root.root.type == bfd_link_hash_defweak)
01746 {
01747 if (h->esym.asym.sc == scCommon)
01748 h->esym.asym.sc = scBss;
01749 else if (h->esym.asym.sc == scSCommon)
01750 h->esym.asym.sc = scSBss;
01751
01752 sec = h->root.root.u.def.section;
01753 output_section = sec->output_section;
01754 if (output_section != NULL)
01755 h->esym.asym.value = (h->root.root.u.def.value
01756 + sec->output_offset
01757 + output_section->vma);
01758 else
01759 h->esym.asym.value = 0;
01760 }
01761 else if (h->root.needs_plt)
01762 {
01763 struct mips_elf_link_hash_entry *hd = h;
01764 bfd_boolean no_fn_stub = h->no_fn_stub;
01765
01766 while (hd->root.root.type == bfd_link_hash_indirect)
01767 {
01768 hd = (struct mips_elf_link_hash_entry *)h->root.root.u.i.link;
01769 no_fn_stub = no_fn_stub || hd->no_fn_stub;
01770 }
01771
01772 if (!no_fn_stub)
01773 {
01774
01775 h->esym.asym.st = stProc;
01776 sec = hd->root.root.u.def.section;
01777 if (sec == NULL)
01778 h->esym.asym.value = 0;
01779 else
01780 {
01781 output_section = sec->output_section;
01782 if (output_section != NULL)
01783 h->esym.asym.value = (hd->root.plt.offset
01784 + sec->output_offset
01785 + output_section->vma);
01786 else
01787 h->esym.asym.value = 0;
01788 }
01789 }
01790 }
01791
01792 if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
01793 h->root.root.root.string,
01794 &h->esym))
01795 {
01796 einfo->failed = TRUE;
01797 return FALSE;
01798 }
01799
01800 return TRUE;
01801 }
01802
01803
01804
01805 static int
01806 gptab_compare (const void *p1, const void *p2)
01807 {
01808 const Elf32_gptab *a1 = p1;
01809 const Elf32_gptab *a2 = p2;
01810
01811 return a1->gt_entry.gt_g_value - a2->gt_entry.gt_g_value;
01812 }
01813
01814
01815
01816
01817
01818
01819 static INLINE hashval_t
01820 mips_elf_hash_bfd_vma (bfd_vma addr)
01821 {
01822 #ifdef BFD64
01823 return addr + (addr >> 32);
01824 #else
01825 return addr;
01826 #endif
01827 }
01828
01829
01830
01831
01832
01833 static hashval_t
01834 mips_elf_got_entry_hash (const void *entry_)
01835 {
01836 const struct mips_got_entry *entry = (struct mips_got_entry *)entry_;
01837
01838 return entry->symndx
01839 + ((entry->tls_type & GOT_TLS_LDM) << 17)
01840 + (! entry->abfd ? mips_elf_hash_bfd_vma (entry->d.address)
01841 : entry->abfd->id
01842 + (entry->symndx >= 0 ? mips_elf_hash_bfd_vma (entry->d.addend)
01843 : entry->d.h->root.root.root.hash));
01844 }
01845
01846 static int
01847 mips_elf_got_entry_eq (const void *entry1, const void *entry2)
01848 {
01849 const struct mips_got_entry *e1 = (struct mips_got_entry *)entry1;
01850 const struct mips_got_entry *e2 = (struct mips_got_entry *)entry2;
01851
01852
01853 if ((e1->tls_type ^ e2->tls_type) & GOT_TLS_LDM)
01854 return 0;
01855
01856 return e1->abfd == e2->abfd && e1->symndx == e2->symndx
01857 && (! e1->abfd ? e1->d.address == e2->d.address
01858 : e1->symndx >= 0 ? e1->d.addend == e2->d.addend
01859 : e1->d.h == e2->d.h);
01860 }
01861
01862
01863
01864
01865
01866
01867 static hashval_t
01868 mips_elf_multi_got_entry_hash (const void *entry_)
01869 {
01870 const struct mips_got_entry *entry = (struct mips_got_entry *)entry_;
01871
01872 return entry->symndx
01873 + (! entry->abfd
01874 ? mips_elf_hash_bfd_vma (entry->d.address)
01875 : entry->symndx >= 0
01876 ? ((entry->tls_type & GOT_TLS_LDM)
01877 ? (GOT_TLS_LDM << 17)
01878 : (entry->abfd->id
01879 + mips_elf_hash_bfd_vma (entry->d.addend)))
01880 : entry->d.h->root.root.root.hash);
01881 }
01882
01883 static int
01884 mips_elf_multi_got_entry_eq (const void *entry1, const void *entry2)
01885 {
01886 const struct mips_got_entry *e1 = (struct mips_got_entry *)entry1;
01887 const struct mips_got_entry *e2 = (struct mips_got_entry *)entry2;
01888
01889
01890 if (e1->tls_type & e2->tls_type & GOT_TLS_LDM)
01891 return 1;
01892
01893
01894 if ((e1->tls_type ^ e2->tls_type) & GOT_TLS_LDM)
01895 return 0;
01896
01897 return e1->symndx == e2->symndx
01898 && (e1->symndx >= 0 ? e1->abfd == e2->abfd && e1->d.addend == e2->d.addend
01899 : e1->abfd == NULL || e2->abfd == NULL
01900 ? e1->abfd == e2->abfd && e1->d.address == e2->d.address
01901 : e1->d.h == e2->d.h);
01902 }
01903
01904
01905
01906 static asection *
01907 mips_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
01908 {
01909 static const char dname[] = ".rel.dyn";
01910 asection *sreloc;
01911
01912 sreloc = bfd_get_section_by_name (dynobj, dname);
01913 if (sreloc == NULL && create_p)
01914 {
01915 sreloc = bfd_make_section (dynobj, dname);
01916 if (sreloc == NULL
01917 || ! bfd_set_section_flags (dynobj, sreloc,
01918 (SEC_ALLOC
01919 | SEC_LOAD
01920 | SEC_HAS_CONTENTS
01921 | SEC_IN_MEMORY
01922 | SEC_LINKER_CREATED
01923 | SEC_READONLY))
01924 || ! bfd_set_section_alignment (dynobj, sreloc,
01925 MIPS_ELF_LOG_FILE_ALIGN (dynobj)))
01926 return NULL;
01927 }
01928 return sreloc;
01929 }
01930
01931
01932
01933 static asection *
01934 mips_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
01935 {
01936 asection *sgot = bfd_get_section_by_name (abfd, ".got");
01937 if (sgot == NULL
01938 || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
01939 return NULL;
01940 return sgot;
01941 }
01942
01943
01944
01945
01946
01947 static struct mips_got_info *
01948 mips_elf_got_info (bfd *abfd, asection **sgotp)
01949 {
01950 asection *sgot;
01951 struct mips_got_info *g;
01952
01953 sgot = mips_elf_got_section (abfd, TRUE);
01954 BFD_ASSERT (sgot != NULL);
01955 BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
01956 g = mips_elf_section_data (sgot)->u.got_info;
01957 BFD_ASSERT (g != NULL);
01958
01959 if (sgotp)
01960 *sgotp = (sgot->flags & SEC_EXCLUDE) == 0 ? sgot : NULL;
01961
01962 return g;
01963 }
01964
01965
01966
01967
01968
01969 static int
01970 mips_tls_got_relocs (struct bfd_link_info *info, unsigned char tls_type,
01971 struct elf_link_hash_entry *h)
01972 {
01973 int indx = 0;
01974 int ret = 0;
01975 bfd_boolean need_relocs = FALSE;
01976 bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;
01977
01978 if (h && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
01979 && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, h)))
01980 indx = h->dynindx;
01981
01982 if ((info->shared || indx != 0)
01983 && (h == NULL
01984 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
01985 || h->root.type != bfd_link_hash_undefweak))
01986 need_relocs = TRUE;
01987
01988 if (!need_relocs)
01989 return FALSE;
01990
01991 if (tls_type & GOT_TLS_GD)
01992 {
01993 ret++;
01994 if (indx != 0)
01995 ret++;
01996 }
01997
01998 if (tls_type & GOT_TLS_IE)
01999 ret++;
02000
02001 if ((tls_type & GOT_TLS_LDM) && info->shared)
02002 ret++;
02003
02004 return ret;
02005 }
02006
02007
02008
02009
02010 static int
02011 mips_elf_count_local_tls_relocs (void **arg1, void *arg2)
02012 {
02013 struct mips_got_entry *entry = * (struct mips_got_entry **) arg1;
02014 struct mips_elf_count_tls_arg *arg = arg2;
02015
02016 if (entry->abfd != NULL && entry->symndx != -1)
02017 arg->needed += mips_tls_got_relocs (arg->info, entry->tls_type, NULL);
02018
02019 return 1;
02020 }
02021
02022
02023
02024
02025 static int
02026 mips_elf_count_global_tls_entries (void *arg1, void *arg2)
02027 {
02028 struct mips_elf_link_hash_entry *hm
02029 = (struct mips_elf_link_hash_entry *) arg1;
02030 struct mips_elf_count_tls_arg *arg = arg2;
02031
02032 if (hm->tls_type & GOT_TLS_GD)
02033 arg->needed += 2;
02034 if (hm->tls_type & GOT_TLS_IE)
02035 arg->needed += 1;
02036
02037 return 1;
02038 }
02039
02040
02041
02042
02043 static int
02044 mips_elf_count_global_tls_relocs (void *arg1, void *arg2)
02045 {
02046 struct mips_elf_link_hash_entry *hm
02047 = (struct mips_elf_link_hash_entry *) arg1;
02048 struct mips_elf_count_tls_arg *arg = arg2;
02049
02050 arg->needed += mips_tls_got_relocs (arg->info, hm->tls_type, &hm->root);
02051
02052 return 1;
02053 }
02054
02055
02056
02057 static void
02058 mips_elf_output_dynamic_relocation (bfd *output_bfd,
02059 asection *sreloc,
02060 unsigned long indx,
02061 int r_type,
02062 bfd_vma offset)
02063 {
02064 Elf_Internal_Rela rel[3];
02065
02066 memset (rel, 0, sizeof (rel));
02067
02068 rel[0].r_info = ELF_R_INFO (output_bfd, indx, r_type);
02069 rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset;
02070
02071 if (ABI_64_P (output_bfd))
02072 {
02073 (*get_elf_backend_data (output_bfd)->s->swap_reloc_out)
02074 (output_bfd, &rel[0],
02075 (sreloc->contents
02076 + sreloc->reloc_count * sizeof (Elf64_Mips_External_Rel)));
02077 }
02078 else
02079 bfd_elf32_swap_reloc_out
02080 (output_bfd, &rel[0],
02081 (sreloc->contents
02082 + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
02083 ++sreloc->reloc_count;
02084 }
02085
02086
02087
02088 static void
02089 mips_elf_initialize_tls_slots (bfd *abfd, bfd_vma got_offset,
02090 unsigned char *tls_type_p,
02091 struct bfd_link_info *info,
02092 struct mips_elf_link_hash_entry *h,
02093 bfd_vma value)
02094 {
02095 int indx;
02096 asection *sreloc, *sgot;
02097 bfd_vma offset, offset2;
02098 bfd *dynobj;
02099 bfd_boolean need_relocs = FALSE;
02100
02101 dynobj = elf_hash_table (info)->dynobj;
02102 sgot = mips_elf_got_section (dynobj, FALSE);
02103
02104 indx = 0;
02105 if (h != NULL)
02106 {
02107 bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;
02108
02109 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, &h->root)
02110 && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, &h->root)))
02111 indx = h->root.dynindx;
02112 }
02113
02114 if (*tls_type_p & GOT_TLS_DONE)
02115 return;
02116
02117 if ((info->shared || indx != 0)
02118 && (h == NULL
02119 || ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT
02120 || h->root.type != bfd_link_hash_undefweak))
02121 need_relocs = TRUE;
02122
02123
02124
02125
02126 BFD_ASSERT (value != MINUS_ONE || (indx != 0 && need_relocs)
02127 || h->root.root.type == bfd_link_hash_undefweak);
02128
02129
02130 sreloc = mips_elf_rel_dyn_section (dynobj, FALSE);
02131
02132
02133 if (*tls_type_p & GOT_TLS_GD)
02134 {
02135 offset = got_offset;
02136 offset2 = offset + MIPS_ELF_GOT_SIZE (abfd);
02137
02138 if (need_relocs)
02139 {
02140 mips_elf_output_dynamic_relocation
02141 (abfd, sreloc, indx,
02142 ABI_64_P (abfd) ? R_MIPS_TLS_DTPMOD64 : R_MIPS_TLS_DTPMOD32,
02143 sgot->output_offset + sgot->output_section->vma + offset);
02144
02145 if (indx)
02146 mips_elf_output_dynamic_relocation
02147 (abfd, sreloc, indx,
02148 ABI_64_P (abfd) ? R_MIPS_TLS_DTPREL64 : R_MIPS_TLS_DTPREL32,
02149 sgot->output_offset + sgot->output_section->vma + offset2);
02150 else
02151 MIPS_ELF_PUT_WORD (abfd, value - dtprel_base (info),
02152 sgot->contents + offset2);
02153 }
02154 else
02155 {
02156 MIPS_ELF_PUT_WORD (abfd, 1,
02157 sgot->contents + offset);
02158 MIPS_ELF_PUT_WORD (abfd, value - dtprel_base (info),
02159 sgot->contents + offset2);
02160 }
02161
02162 got_offset += 2 * MIPS_ELF_GOT_SIZE (abfd);
02163 }
02164
02165
02166 if (*tls_type_p & GOT_TLS_IE)
02167 {
02168 offset = got_offset;
02169
02170 if (need_relocs)
02171 {
02172 if (indx == 0)
02173 MIPS_ELF_PUT_WORD (abfd, value - elf_hash_table (info)->tls_sec->vma,
02174 sgot->contents + offset);
02175 else
02176 MIPS_ELF_PUT_WORD (abfd, 0,
02177 sgot->contents + offset);
02178
02179 mips_elf_output_dynamic_relocation
02180 (abfd, sreloc, indx,
02181 ABI_64_P (abfd) ? R_MIPS_TLS_TPREL64 : R_MIPS_TLS_TPREL32,
02182 sgot->output_offset + sgot->output_section->vma + offset);
02183 }
02184 else
02185 MIPS_ELF_PUT_WORD (abfd, value - tprel_base (info),
02186 sgot->contents + offset);
02187 }
02188
02189 if (*tls_type_p & GOT_TLS_LDM)
02190 {
02191
02192
02193 MIPS_ELF_PUT_WORD (abfd, 0,
02194 sgot->contents + got_offset
02195 + MIPS_ELF_GOT_SIZE (abfd));
02196
02197 if (!info->shared)
02198 MIPS_ELF_PUT_WORD (abfd, 1,
02199 sgot->contents + got_offset);
02200 else
02201 mips_elf_output_dynamic_relocation
02202 (abfd, sreloc, indx,
02203 ABI_64_P (abfd) ? R_MIPS_TLS_DTPMOD64 : R_MIPS_TLS_DTPMOD32,
02204 sgot->output_offset + sgot->output_section->vma + got_offset);
02205 }
02206
02207 *tls_type_p |= GOT_TLS_DONE;
02208 }
02209
02210
02211
02212
02213
02214
02215 static bfd_vma
02216 mips_tls_got_index (bfd *abfd, bfd_vma got_index, unsigned char *tls_type,
02217 int r_type, struct bfd_link_info *info,
02218 struct mips_elf_link_hash_entry *h, bfd_vma symbol)
02219 {
02220 BFD_ASSERT (r_type == R_MIPS_TLS_GOTTPREL || r_type == R_MIPS_TLS_GD
02221 || r_type == R_MIPS_TLS_LDM);
02222
02223 mips_elf_initialize_tls_slots (abfd, got_index, tls_type, info, h, symbol);
02224
02225 if (r_type == R_MIPS_TLS_GOTTPREL)
02226 {
02227 BFD_ASSERT (*tls_type & GOT_TLS_IE);
02228 if (*tls_type & GOT_TLS_GD)
02229 return got_index + 2 * MIPS_ELF_GOT_SIZE (abfd);
02230 else
02231 return got_index;
02232 }
02233
02234 if (r_type == R_MIPS_TLS_GD)
02235 {
02236 BFD_ASSERT (*tls_type & GOT_TLS_GD);
02237 return got_index;
02238 }
02239
02240 if (r_type == R_MIPS_TLS_LDM)
02241 {
02242 BFD_ASSERT (*tls_type & GOT_TLS_LDM);
02243 return got_index;
02244 }
02245
02246 return got_index;
02247 }
02248
02249
02250
02251
02252
02253
02254 static bfd_vma
02255 mips_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
02256 bfd_vma value, unsigned long r_symndx,
02257 struct mips_elf_link_hash_entry *h, int r_type)
02258 {
02259 asection *sgot;
02260 struct mips_got_info *g;
02261 struct mips_got_entry *entry;
02262
02263 g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
02264
02265 entry = mips_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
02266 r_symndx, h, r_type);
02267 if (!entry)
02268 return MINUS_ONE;
02269
02270 if (TLS_RELOC_P (r_type))
02271 return mips_tls_got_index (abfd, entry->gotidx, &entry->tls_type, r_type,
02272 info, h, value);
02273 else
02274 return entry->gotidx;
02275 }
02276
02277
02278
02279 static bfd_vma
02280 mips_elf_global_got_index (bfd *abfd, bfd *ibfd, struct elf_link_hash_entry *h,
02281 int r_type, struct bfd_link_info *info)
02282 {
02283 bfd_vma index;
02284 asection *sgot;
02285 struct mips_got_info *g, *gg;
02286 long global_got_dynindx = 0;
02287
02288 gg = g = mips_elf_got_info (abfd, &sgot);
02289 if (g->bfd2got && ibfd)
02290 {
02291 struct mips_got_entry e, *p;
02292
02293 BFD_ASSERT (h->dynindx >= 0);
02294
02295 g = mips_elf_got_for_ibfd (g, ibfd);
02296 if (g->next != gg || TLS_RELOC_P (r_type))
02297 {
02298 e.abfd = ibfd;
02299 e.symndx = -1;
02300 e.d.h = (struct mips_elf_link_hash_entry *)h;
02301 e.tls_type = 0;
02302
02303 p = htab_find (g->got_entries, &e);
02304
02305 BFD_ASSERT (p->gotidx > 0);
02306
02307 if (TLS_RELOC_P (r_type))
02308 {
02309 bfd_vma value = MINUS_ONE;
02310 if ((h->root.type == bfd_link_hash_defined
02311 || h->root.type == bfd_link_hash_defweak)
02312 && h->root.u.def.section->output_section)
02313 value = (h->root.u.def.value
02314 + h->root.u.def.section->output_offset
02315 + h->root.u.def.section->output_section->vma);
02316
02317 return mips_tls_got_index (abfd, p->gotidx, &p->tls_type, r_type,
02318 info, e.d.h, value);
02319 }
02320 else
02321 return p->gotidx;
02322 }
02323 }
02324
02325 if (gg->global_gotsym != NULL)
02326 global_got_dynindx = gg->global_gotsym->dynindx;
02327
02328 if (TLS_RELOC_P (r_type))
02329 {
02330 struct mips_elf_link_hash_entry *hm
02331 = (struct mips_elf_link_hash_entry *) h;
02332 bfd_vma value = MINUS_ONE;
02333
02334 if ((h->root.type == bfd_link_hash_defined
02335 || h->root.type == bfd_link_hash_defweak)
02336 && h->root.u.def.section->output_section)
02337 value = (h->root.u.def.value
02338 + h->root.u.def.section->output_offset
02339 + h->root.u.def.section->output_section->vma);
02340
02341 index = mips_tls_got_index (abfd, hm->tls_got_offset, &hm->tls_type,
02342 r_type, info, hm, value);
02343 }
02344 else
02345 {
02346
02347
02348
02349
02350 BFD_ASSERT (h->dynindx >= global_got_dynindx);
02351 index = ((h->dynindx - global_got_dynindx + g->local_gotno)
02352 * MIPS_ELF_GOT_SIZE (abfd));
02353 }
02354 BFD_ASSERT (index < sgot->size);
02355
02356 return index;
02357 }
02358
02359
02360
02361
02362
02363
02364
02365 static bfd_vma
02366 mips_elf_got_page (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
02367 bfd_vma value, bfd_vma *offsetp)
02368 {
02369 asection *sgot;
02370 struct mips_got_info *g;
02371 bfd_vma index;
02372 struct mips_got_entry *entry;
02373
02374 g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
02375
02376 entry = mips_elf_create_local_got_entry (abfd, ibfd, g, sgot,
02377 (value + 0x8000)
02378 & (~(bfd_vma)0xffff), 0,
02379 NULL, R_MIPS_GOT_PAGE);
02380
02381 if (!entry)
02382 return MINUS_ONE;
02383
02384 index = entry->gotidx;
02385
02386 if (offsetp)
02387 *offsetp = value - entry->d.address;
02388
02389 return index;
02390 }
02391
02392
02393
02394
02395 static bfd_vma
02396 mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
02397 bfd_vma value, bfd_boolean external)
02398 {
02399 asection *sgot;
02400 struct mips_got_info *g;
02401 struct mips_got_entry *entry;
02402
02403 if (! external)
02404 {
02405
02406
02407
02408
02409 value = mips_elf_high (value) << 16;
02410 }
02411
02412 g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
02413
02414 entry = mips_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
02415 R_MIPS_GOT16);
02416 if (entry)
02417 return entry->gotidx;
02418 else
02419 return MINUS_ONE;
02420 }
02421
02422
02423
02424
02425 static bfd_vma
02426 mips_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd,
02427 bfd *input_bfd, bfd_vma index)
02428 {
02429 asection *sgot;
02430 bfd_vma gp;
02431 struct mips_got_info *g;
02432
02433 g = mips_elf_got_info (dynobj, &sgot);
02434 gp = _bfd_get_gp_value (output_bfd)
02435 + mips_elf_adjust_gp (output_bfd, g, input_bfd);
02436
02437 return sgot->output_section->vma + sgot->output_offset + index - gp;
02438 }
02439
02440
02441
02442
02443
02444 static struct mips_got_entry *
02445 mips_elf_create_local_got_entry (bfd *abfd, bfd *ibfd,
02446 struct mips_got_info *gg,
02447 asection *sgot, bfd_vma value,
02448 unsigned long r_symndx,
02449 struct mips_elf_link_hash_entry *h,
02450 int r_type)
02451 {
02452 struct mips_got_entry entry, **loc;
02453 struct mips_got_info *g;
02454
02455 entry.abfd = NULL;
02456 entry.symndx = -1;
02457 entry.d.address = value;
02458 entry.tls_type = 0;
02459
02460 g = mips_elf_got_for_ibfd (gg, ibfd);
02461 if (g == NULL)
02462 {
02463 g = mips_elf_got_for_ibfd (gg, abfd);
02464 BFD_ASSERT (g != NULL);
02465 }
02466
02467
02468
02469
02470
02471 BFD_ASSERT (h == NULL || h->root.forced_local);
02472 if (TLS_RELOC_P (r_type))
02473 {
02474 struct mips_got_entry *p;
02475
02476 entry.abfd = ibfd;
02477 if (r_type == R_MIPS_TLS_LDM)
02478 {
02479 entry.tls_type = GOT_TLS_LDM;
02480 entry.symndx = 0;
02481 entry.d.addend = 0;
02482 }
02483 else if (h == NULL)
02484 {
02485 entry.symndx = r_symndx;
02486 entry.d.addend = 0;
02487 }
02488 else
02489 entry.d.h = h;
02490
02491 p = (struct mips_got_entry *)
02492 htab_find (g->got_entries, &entry);
02493
02494 BFD_ASSERT (p);
02495 return p;
02496 }
02497
02498 loc = (struct mips_got_entry **) htab_find_slot (g->got_entries, &entry,
02499 INSERT);
02500 if (*loc)
02501 return *loc;
02502
02503 entry.gotidx = MIPS_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
02504 entry.tls_type = 0;
02505
02506 *loc = (struct mips_got_entry *)bfd_alloc (abfd, sizeof entry);
02507
02508 if (! *loc)
02509 return NULL;
02510
02511 memcpy (*loc, &entry, sizeof entry);
02512
02513 if (g->assigned_gotno >= g->local_gotno)
02514 {
02515 (*loc)->gotidx = -1;
02516
02517 (*_bfd_error_handler)
02518 (_("not enough GOT space for local GOT entries"));
02519 bfd_set_error (bfd_error_bad_value);
02520 return NULL;
02521 }
02522
02523 MIPS_ELF_PUT_WORD (abfd, value,
02524 (sgot->contents + entry.gotidx));
02525
02526 return *loc;
02527 }
02528
02529
02530
02531
02532
02533
02534
02535
02536 static bfd_boolean
02537 mips_elf_sort_hash_table (struct bfd_link_info *info, unsigned long max_local)
02538 {
02539 struct mips_elf_hash_sort_data hsd;
02540 struct mips_got_info *g;
02541 bfd *dynobj;
02542
02543 dynobj = elf_hash_table (info)->dynobj;
02544
02545 g = mips_elf_got_info (dynobj, NULL);
02546
02547 hsd.low = NULL;
02548 hsd.max_unref_got_dynindx =
02549 hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
02550
02551
02552
02553
02554
02555
02556
02557 - (g->next ? g->assigned_gotno : 0);
02558 hsd.max_non_got_dynindx = max_local;
02559 mips_elf_link_hash_traverse (((struct mips_elf_link_hash_table *)
02560 elf_hash_table (info)),
02561 mips_elf_sort_hash_table_f,
02562 &hsd);
02563
02564
02565
02566 BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
02567 BFD_ASSERT ((unsigned long)hsd.max_unref_got_dynindx
02568 <= elf_hash_table (info)->dynsymcount);
02569
02570
02571
02572 g->global_gotsym = hsd.low;
02573
02574 return TRUE;
02575 }
02576
02577
02578
02579
02580
02581 static bfd_boolean
02582 mips_elf_sort_hash_table_f (struct mips_elf_link_hash_entry *h, void *data)
02583 {
02584 struct mips_elf_hash_sort_data *hsd = data;
02585
02586 if (h->root.root.type == bfd_link_hash_warning)
02587 h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
02588
02589
02590
02591 if (h->root.dynindx == -1)
02592 return TRUE;
02593
02594
02595
02596
02597
02598 if (h->root.got.offset == 2)
02599 {
02600 BFD_ASSERT (h->tls_type == GOT_NORMAL);
02601
02602 if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
02603 hsd->low = (struct elf_link_hash_entry *) h;
02604 h->root.dynindx = hsd->max_unref_got_dynindx++;
02605 }
02606 else if (h->root.got.offset != 1)
02607 h->root.dynindx = hsd->max_non_got_dynindx++;
02608 else
02609 {
02610 BFD_ASSERT (h->tls_type == GOT_NORMAL);
02611
02612 h->root.dynindx = --hsd->min_got_dynindx;
02613 hsd->low = (struct elf_link_hash_entry *) h;
02614 }
02615
02616 return TRUE;
02617 }
02618
02619
02620
02621
02622
02623 static bfd_boolean
02624 mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
02625 bfd *abfd, struct bfd_link_info *info,
02626 struct mips_got_info *g,
02627 unsigned char tls_flag)
02628 {
02629 struct mips_got_entry entry, **loc;
02630
02631
02632
02633 if (h->dynindx == -1)
02634 {
02635 switch (ELF_ST_VISIBILITY (h->other))
02636 {
02637 case STV_INTERNAL:
02638 case STV_HIDDEN:
02639 _bfd_mips_elf_hide_symbol (info, h, TRUE);
02640 break;
02641 }
02642 if (!bfd_elf_link_record_dynamic_symbol (info, h))
02643 return FALSE;
02644 }
02645
02646 entry.abfd = abfd;
02647 entry.symndx = -1;
02648 entry.d.h = (struct mips_elf_link_hash_entry *) h;
02649 entry.tls_type = 0;
02650
02651 loc = (struct mips_got_entry **) htab_find_slot (g->got_entries, &entry,
02652 INSERT);
02653
02654
02655
02656 if (*loc)
02657 {
02658 (*loc)->tls_type |= tls_flag;
02659 return TRUE;
02660 }
02661
02662 *loc = (struct mips_got_entry *)bfd_alloc (abfd, sizeof entry);
02663
02664 if (! *loc)
02665 return FALSE;
02666
02667 entry.gotidx = -1;
02668 entry.tls_type = tls_flag;
02669
02670 memcpy (*loc, &entry, sizeof entry);
02671
02672 if (h->got.offset != MINUS_ONE)
02673 return TRUE;
02674
02675
02676
02677
02678 if (tls_flag == 0)
02679 h->got.offset = 1;
02680
02681 return TRUE;
02682 }
02683
02684
02685
02686
02687 static bfd_boolean
02688 mips_elf_record_local_got_symbol (bfd *abfd, long symndx, bfd_vma addend,
02689 struct mips_got_info *g,
02690 unsigned char tls_flag)
02691 {
02692 struct mips_got_entry entry, **loc;
02693
02694 entry.abfd = abfd;
02695 entry.symndx = symndx;
02696 entry.d.addend = addend;
02697 entry.tls_type = tls_flag;
02698 loc = (struct mips_got_entry **)
02699 htab_find_slot (g->got_entries, &entry, INSERT);
02700
02701 if (*loc)
02702 {
02703 if (tls_flag == GOT_TLS_GD && !((*loc)->tls_type & GOT_TLS_GD))
02704 {
02705 g->tls_gotno += 2;
02706 (*loc)->tls_type |= tls_flag;
02707 }
02708 else if (tls_flag == GOT_TLS_IE && !((*loc)->tls_type & GOT_TLS_IE))
02709 {
02710 g->tls_gotno += 1;
02711 (*loc)->tls_type |= tls_flag;
02712 }
02713 return TRUE;
02714 }
02715
02716 if (tls_flag != 0)
02717 {
02718 entry.gotidx = -1;
02719 entry.tls_type = tls_flag;
02720 if (tls_flag == GOT_TLS_IE)
02721 g->tls_gotno += 1;
02722 else if (tls_flag == GOT_TLS_GD)
02723 g->tls_gotno += 2;
02724 else if (g->tls_ldm_offset == MINUS_ONE)
02725 {
02726 g->tls_ldm_offset = MINUS_TWO;
02727 g->tls_gotno += 2;
02728 }
02729 }
02730 else
02731 {
02732 entry.gotidx = g->local_gotno++;
02733 entry.tls_type = 0;
02734 }
02735
02736 *loc = (struct mips_got_entry *)bfd_alloc (abfd, sizeof entry);
02737
02738 if (! *loc)
02739 return FALSE;
02740
02741 memcpy (*loc, &entry, sizeof entry);
02742
02743 return TRUE;
02744 }
02745
02746
02747
02748 static hashval_t
02749 mips_elf_bfd2got_entry_hash (const void *entry_)
02750 {
02751 const struct mips_elf_bfd2got_hash *entry
02752 = (struct mips_elf_bfd2got_hash *)entry_;
02753
02754 return entry->bfd->id;
02755 }
02756
02757
02758
02759 static int
02760 mips_elf_bfd2got_entry_eq (const void *entry1, const void *entry2)
02761 {
02762 const struct mips_elf_bfd2got_hash *e1
02763 = (const struct mips_elf_bfd2got_hash *)entry1;
02764 const struct mips_elf_bfd2got_hash *e2
02765 = (const struct mips_elf_bfd2got_hash *)entry2;
02766
02767 return e1->bfd == e2->bfd;
02768 }
02769
02770
02771
02772
02773 static struct mips_got_info *
02774 mips_elf_got_for_ibfd (struct mips_got_info *g, bfd *ibfd)
02775 {
02776 struct mips_elf_bfd2got_hash e, *p;
02777
02778 if (! g->bfd2got)
02779 return g;
02780
02781 e.bfd = ibfd;
02782 p = htab_find (g->bfd2got, &e);
02783 return p ? p->g : NULL;
02784 }
02785
02786
02787
02788
02789
02790 static int
02791 mips_elf_make_got_per_bfd (void **entryp, void *p)
02792 {
02793 struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
02794 struct mips_elf_got_per_bfd_arg *arg = (struct mips_elf_got_per_bfd_arg *)p;
02795 htab_t bfd2got = arg->bfd2got;
02796 struct mips_got_info *g;
02797 struct mips_elf_bfd2got_hash bfdgot_entry, *bfdgot;
02798 void **bfdgotp;
02799
02800
02801
02802 bfdgot_entry.bfd = entry->abfd;
02803 bfdgotp = htab_find_slot (bfd2got, &bfdgot_entry, INSERT);
02804 bfdgot = (struct mips_elf_bfd2got_hash *)*bfdgotp;
02805
02806 if (bfdgot != NULL)
02807 g = bfdgot->g;
02808 else
02809 {
02810 bfdgot = (struct mips_elf_bfd2got_hash *)bfd_alloc
02811 (arg->obfd, sizeof (struct mips_elf_bfd2got_hash));
02812
02813 if (bfdgot == NULL)
02814 {
02815 arg->obfd = 0;
02816 return 0;
02817 }
02818
02819 *bfdgotp = bfdgot;
02820
02821 bfdgot->bfd = entry->abfd;
02822 bfdgot->g = g = (struct mips_got_info *)
02823 bfd_alloc (arg->obfd, sizeof (struct mips_got_info));
02824 if (g == NULL)
02825 {
02826 arg->obfd = 0;
02827 return 0;
02828 }
02829
02830 g->global_gotsym = NULL;
02831 g->global_gotno = 0;
02832 g->local_gotno = 0;
02833 g->assigned_gotno = -1;
02834 g->tls_gotno = 0;
02835 g->tls_assigned_gotno = 0;
02836 g->tls_ldm_offset = MINUS_ONE;
02837 g->got_entries = htab_try_create (1, mips_elf_multi_got_entry_hash,
02838 mips_elf_multi_got_entry_eq, NULL);
02839 if (g->got_entries == NULL)
02840 {
02841 arg->obfd = 0;
02842 return 0;
02843 }
02844
02845 g->bfd2got = NULL;
02846 g->next = NULL;
02847 }
02848
02849
02850 entryp = htab_find_slot (g->got_entries, entry, INSERT);
02851 if (*entryp != NULL)
02852 return 1;
02853
02854 *entryp = entry;
02855
02856 if (entry->tls_type)
02857 {
02858 if (entry->tls_type & (GOT_TLS_GD | GOT_TLS_LDM))
02859 g->tls_gotno += 2;
02860 if (entry->tls_type & GOT_TLS_IE)
02861 g->tls_gotno += 1;
02862 }
02863 else if (entry->symndx >= 0 || entry->d.h->forced_local)
02864 ++g->local_gotno;
02865 else
02866 ++g->global_gotno;
02867
02868 return 1;
02869 }
02870
02871
02872
02873
02874
02875
02876
02877
02878 static int
02879 mips_elf_merge_gots (void **bfd2got_, void *p)
02880 {
02881 struct mips_elf_bfd2got_hash *bfd2got
02882 = (struct mips_elf_bfd2got_hash *)*bfd2got_;
02883 struct mips_elf_got_per_bfd_arg *arg = (struct mips_elf_got_per_bfd_arg *)p;
02884 unsigned int lcount = bfd2got->g->local_gotno;
02885 unsigned int gcount = bfd2got->g->global_gotno;
02886 unsigned int tcount = bfd2got->g->tls_gotno;
02887 unsigned int maxcnt = arg->max_count;
02888 bfd_boolean too_many_for_tls = FALSE;
02889
02890
02891
02892
02893
02894 if (tcount > 0)
02895 {
02896 unsigned int primary_total = lcount + tcount + arg->global_count;
02897 if (primary_total * MIPS_ELF_GOT_SIZE (bfd2got->bfd)
02898 >= MIPS_ELF_GOT_MAX_SIZE (bfd2got->bfd))
02899 too_many_for_tls = TRUE;
02900 }
02901
02902
02903
02904 if (! arg->primary && lcount + gcount + tcount <= maxcnt
02905 && ! too_many_for_tls)
02906 {
02907 arg->primary = bfd2got->g;
02908 arg->primary_count = lcount + gcount;
02909 }
02910
02911
02912
02913 else if (arg->primary && ! too_many_for_tls
02914 && (arg->primary_count + lcount + gcount + tcount) <= maxcnt)
02915 {
02916 struct mips_got_info *g = bfd2got->g;
02917 int old_lcount = arg->primary->local_gotno;
02918 int old_gcount = arg->primary->global_gotno;
02919 int old_tcount = arg->primary->tls_gotno;
02920
02921 bfd2got->g = arg->primary;
02922
02923 htab_traverse (g->got_entries,
02924 mips_elf_make_got_per_bfd,
02925 arg);
02926 if (arg->obfd == NULL)
02927 return 0;
02928
02929 htab_delete (g->got_entries);
02930
02931
02932
02933
02934 BFD_ASSERT (old_lcount + lcount >= arg->primary->local_gotno);
02935 BFD_ASSERT (old_gcount + gcount >= arg->primary->global_gotno);
02936 BFD_ASSERT (old_tcount + tcount >= arg->primary->tls_gotno);
02937
02938 arg->primary_count = arg->primary->local_gotno
02939 + arg->primary->global_gotno + arg->primary->tls_gotno;
02940 }
02941
02942 else if (arg->current
02943 && arg->current_count + lcount + gcount + tcount <= maxcnt)
02944 {
02945 struct mips_got_info *g = bfd2got->g;
02946 int old_lcount = arg->current->local_gotno;
02947 int old_gcount = arg->current->global_gotno;
02948 int old_tcount = arg->current->tls_gotno;
02949
02950 bfd2got->g = arg->current;
02951
02952 htab_traverse (g->got_entries,
02953 mips_elf_make_got_per_bfd,
02954 arg);
02955 if (arg->obfd == NULL)
02956 return 0;
02957
02958 htab_delete (g->got_entries);
02959
02960 BFD_ASSERT (old_lcount + lcount >= arg->current->local_gotno);
02961 BFD_ASSERT (old_gcount + gcount >= arg->current->global_gotno);
02962 BFD_ASSERT (old_tcount + tcount >= arg->current->tls_gotno);
02963
02964 arg->current_count = arg->current->local_gotno
02965 + arg->current->global_gotno + arg->current->tls_gotno;
02966 }
02967
02968
02969
02970 else
02971 {
02972 bfd2got->g->next = arg->current;
02973 arg->current = bfd2got->g;
02974
02975 arg->current_count = lcount + gcount + 2 * tcount;
02976 }
02977
02978 return 1;
02979 }
02980
02981
02982
02983 static int
02984 mips_elf_initialize_tls_index (void **entryp, void *p)
02985 {
02986 struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
02987 struct mips_got_info *g = p;
02988
02989
02990 if (entry->tls_type == 0)
02991 return 1;
02992
02993 if (entry->symndx == -1)
02994 {
02995
02996
02997 if (g->next == NULL)
02998 {
02999 if (entry->d.h->tls_type & GOT_TLS_OFFSET_DONE)
03000 return 1;
03001 entry->d.h->tls_type |= GOT_TLS_OFFSET_DONE;
03002 }
03003 }
03004 else if (entry->tls_type & GOT_TLS_LDM)
03005 {
03006
03007 if (g->tls_ldm_offset != MINUS_TWO && g->tls_ldm_offset != MINUS_ONE)
03008 {
03009 entry->gotidx = g->tls_ldm_offset;
03010 return 1;
03011 }
03012 }
03013
03014
03015 entry->gotidx = MIPS_ELF_GOT_SIZE (entry->abfd) * (long) g->tls_assigned_gotno;
03016 if (g->next == NULL && entry->symndx == -1)
03017 entry->d.h->tls_got_offset = entry->gotidx;
03018
03019 if (entry->tls_type & (GOT_TLS_GD | GOT_TLS_LDM))
03020 g->tls_assigned_gotno += 2;
03021 if (entry->tls_type & GOT_TLS_IE)
03022 g->tls_assigned_gotno += 1;
03023
03024 if (entry->tls_type & GOT_TLS_LDM)
03025 g->tls_ldm_offset = entry->gotidx;
03026
03027 return 1;
03028 }
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043 static int
03044 mips_elf_set_global_got_offset (void **entryp, void *p)
03045 {
03046 struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
03047 struct mips_elf_set_global_got_offset_arg *arg
03048 = (struct mips_elf_set_global_got_offset_arg *)p;
03049 struct mips_got_info *g = arg->g;
03050
03051 if (g && entry->tls_type != GOT_NORMAL)
03052 arg->needed_relocs +=
03053 mips_tls_got_relocs (arg->info, entry->tls_type,
03054 entry->symndx == -1 ? &entry->d.h->root : NULL);
03055
03056 if (entry->abfd != NULL && entry->symndx == -1
03057 && entry->d.h->root.dynindx != -1
03058 && entry->d.h->tls_type == GOT_NORMAL)
03059 {
03060 if (g)
03061 {
03062 BFD_ASSERT (g->global_gotsym == NULL);
03063
03064 entry->gotidx = arg->value * (long) g->assigned_gotno++;
03065 if (arg->info->shared
03066 || (elf_hash_table (arg->info)->dynamic_sections_created
03067 && entry->d.h->root.def_dynamic
03068 && !entry->d.h->root.def_regular))
03069 ++arg->needed_relocs;
03070 }
03071 else
03072 entry->d.h->root.got.offset = arg->value;
03073 }
03074
03075 return 1;
03076 }
03077
03078
03079
03080 static int
03081 mips_elf_set_no_stub (void **entryp, void *p ATTRIBUTE_UNUSED)
03082 {
03083 struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
03084
03085 if (entry->abfd != NULL
03086 && entry->symndx == -1
03087 && entry->d.h->root.dynindx != -1)
03088 entry->d.h->no_fn_stub = TRUE;
03089
03090 return 1;
03091 }
03092
03093
03094
03095
03096
03097
03098
03099 static int
03100 mips_elf_resolve_final_got_entry (void **entryp, void *p)
03101 {
03102 struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
03103 htab_t got_entries = *(htab_t *)p;
03104
03105 if (entry->abfd != NULL && entry->symndx == -1)
03106 {
03107 struct mips_elf_link_hash_entry *h = entry->d.h;
03108
03109 while (h->root.root.type == bfd_link_hash_indirect
03110 || h->root.root.type == bfd_link_hash_warning)
03111 h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
03112
03113 if (entry->d.h == h)
03114 return 1;
03115
03116 entry->d.h = h;
03117
03118
03119
03120 if (! htab_find (got_entries, entry))
03121 {
03122 htab_clear_slot (got_entries, entryp);
03123 entryp = htab_find_slot (got_entries, entry, INSERT);
03124 if (! *entryp)
03125 *entryp = entry;
03126
03127
03128
03129 *(htab_t *)p = NULL;
03130 return 0;
03131 }
03132
03133
03134 }
03135
03136 return 1;
03137 }
03138
03139
03140
03141 static void
03142 mips_elf_resolve_final_got_entries (struct mips_got_info *g)
03143 {
03144 htab_t got_entries;
03145
03146 do
03147 {
03148 got_entries = g->got_entries;
03149
03150 htab_traverse (got_entries,
03151 mips_elf_resolve_final_got_entry,
03152 &got_entries);
03153 }
03154 while (got_entries == NULL);
03155 }
03156
03157
03158
03159 static bfd_vma
03160 mips_elf_adjust_gp (bfd *abfd, struct mips_got_info *g, bfd *ibfd)
03161 {
03162 if (g->bfd2got == NULL)
03163 return 0;
03164
03165 g = mips_elf_got_for_ibfd (g, ibfd);
03166 if (! g)
03167 return 0;
03168
03169 BFD_ASSERT (g->next);
03170
03171 g = g->next;
03172
03173 return (g->local_gotno + g->global_gotno + g->tls_gotno)
03174 * MIPS_ELF_GOT_SIZE (abfd);
03175 }
03176
03177
03178
03179
03180 static bfd_boolean
03181 mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info,
03182 struct mips_got_info *g, asection *got,
03183 bfd_size_type pages)
03184 {
03185 struct mips_elf_got_per_bfd_arg got_per_bfd_arg;
03186 struct mips_elf_set_global_got_offset_arg set_got_offset_arg;
03187 struct mips_got_info *gg;
03188 unsigned int assign;
03189
03190 g->bfd2got = htab_try_create (1, mips_elf_bfd2got_entry_hash,
03191 mips_elf_bfd2got_entry_eq, NULL);
03192 if (g->bfd2got == NULL)
03193 return FALSE;
03194
03195 got_per_bfd_arg.bfd2got = g->bfd2got;
03196 got_per_bfd_arg.obfd = abfd;
03197 got_per_bfd_arg.info = info;
03198
03199
03200
03201 htab_traverse (g->got_entries, mips_elf_make_got_per_bfd, &got_per_bfd_arg);
03202 if (got_per_bfd_arg.obfd == NULL)
03203 return FALSE;
03204
03205 got_per_bfd_arg.current = NULL;
03206 got_per_bfd_arg.primary = NULL;
03207
03208
03209
03210 got_per_bfd_arg.max_count = ((MIPS_ELF_GOT_MAX_SIZE (abfd)
03211 / MIPS_ELF_GOT_SIZE (abfd))
03212 - MIPS_RESERVED_GOTNO - pages);
03213
03214
03215
03216 got_per_bfd_arg.global_count = g->global_gotno;
03217
03218
03219
03220
03221 htab_traverse (g->bfd2got, mips_elf_merge_gots, &got_per_bfd_arg);
03222 if (got_per_bfd_arg.obfd == NULL)
03223 return FALSE;
03224
03225
03226 if (got_per_bfd_arg.primary == NULL)
03227 {
03228 g->next = (struct mips_got_info *)
03229 bfd_alloc (abfd, sizeof (struct mips_got_info));
03230 if (g->next == NULL)
03231 return FALSE;
03232
03233 g->next->global_gotsym = NULL;
03234 g->next->global_gotno = 0;
03235 g->next->local_gotno = 0;
03236 g->next->tls_gotno = 0;
03237 g->next->assigned_gotno = 0;
03238 g->next->tls_assigned_gotno = 0;
03239 g->next->tls_ldm_offset = MINUS_ONE;
03240 g->next->got_entries = htab_try_create (1, mips_elf_multi_got_entry_hash,
03241 mips_elf_multi_got_entry_eq,
03242 NULL);
03243 if (g->next->got_entries == NULL)
03244 return FALSE;
03245 g->next->bfd2got = NULL;
03246 }
03247 else
03248 g->next = got_per_bfd_arg.primary;
03249 g->next->next = got_per_bfd_arg.current;
03250
03251
03252 gg = g;
03253 g = g->next;
03254
03255
03256
03257
03258
03259
03260 {
03261 struct mips_elf_bfd2got_hash *bfdgot;
03262 void **bfdgotp;
03263
03264 bfdgot = (struct mips_elf_bfd2got_hash *)bfd_alloc
03265 (abfd, sizeof (struct mips_elf_bfd2got_hash));
03266
03267 if (bfdgot == NULL)
03268 return FALSE;
03269
03270 bfdgot->bfd = abfd;
03271 bfdgot->g = g;
03272 bfdgotp = htab_find_slot (gg->bfd2got, bfdgot, INSERT);
03273
03274 BFD_ASSERT (*bfdgotp == NULL);
03275 *bfdgotp = bfdgot;
03276 }
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295 if (1)
03296 {
03297 gg->assigned_gotno = gg->global_gotno - g->global_gotno;
03298 g->global_gotno = gg->global_gotno;
03299 set_got_offset_arg.value = 2;
03300 }
03301 else
03302 {
03303
03304
03305
03306
03307
03308
03309 gg->assigned_gotno = 0;
03310 set_got_offset_arg.value = -1;
03311 }
03312
03313
03314
03315 set_got_offset_arg.g = NULL;
03316 htab_traverse (gg->got_entries, mips_elf_set_global_got_offset,
03317 &set_got_offset_arg);
03318 set_got_offset_arg.value = 1;
03319 htab_traverse (g->got_entries, mips_elf_set_global_got_offset,
03320 &set_got_offset_arg);
03321 if (! mips_elf_sort_hash_table (info, 1))
03322 return FALSE;
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337 gg->local_gotno = -g->global_gotno;
03338 gg->global_gotno = g->global_gotno;
03339 gg->tls_gotno = 0;
03340 assign = 0;
03341 gg->next = gg;
03342
03343 do
03344 {
03345 struct mips_got_info *gn;
03346
03347 assign += MIPS_RESERVED_GOTNO;
03348 g->assigned_gotno = assign;
03349 g->local_gotno += assign + pages;
03350 assign = g->local_gotno + g->global_gotno + g->tls_gotno;
03351
03352
03353
03354 g->tls_assigned_gotno = g->local_gotno + g->global_gotno;
03355 htab_traverse (g->got_entries, mips_elf_initialize_tls_index, g);
03356
03357
03358
03359 gn = g->next;
03360 g->next = gg->next;
03361 gg->next = g;
03362 g = gn;
03363
03364
03365
03366 if (g)
03367 htab_traverse (g->got_entries, mips_elf_set_no_stub, NULL);
03368 }
03369 while (g);
03370
03371 got->size = (gg->next->local_gotno
03372 + gg->next->global_gotno
03373 + gg->next->tls_gotno) * MIPS_ELF_GOT_SIZE (abfd);
03374
03375 return TRUE;
03376 }
03377
03378
03379
03380
03381
03382 static const Elf_Internal_Rela *
03383 mips_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
03384 const Elf_Internal_Rela *relocation,
03385 const Elf_Internal_Rela *relend)
03386 {
03387 while (relocation < relend)
03388 {
03389 if (ELF_R_TYPE (abfd, relocation->r_info) == r_type)
03390 return relocation;
03391
03392 ++relocation;
03393 }
03394
03395
03396 bfd_set_error (bfd_error_bad_value);
03397 return NULL;
03398 }
03399
03400
03401
03402 static bfd_boolean
03403 mips_elf_local_relocation_p (bfd *input_bfd,
03404 const Elf_Internal_Rela *relocation,
03405 asection **local_sections,
03406 bfd_boolean check_forced)
03407 {
03408 unsigned long r_symndx;
03409 Elf_Internal_Shdr *symtab_hdr;
03410 struct mips_elf_link_hash_entry *h;
03411 size_t extsymoff;
03412
03413 r_symndx = ELF_R_SYM (input_bfd, relocation->r_info);
03414 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
03415 extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
03416
03417 if (r_symndx < extsymoff)
03418 return TRUE;
03419 if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
03420 return TRUE;
03421
03422 if (check_forced)
03423 {
03424
03425
03426 h = (struct mips_elf_link_hash_entry *)
03427 elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
03428
03429 while (h->root.root.type == bfd_link_hash_indirect
03430 || h->root.root.type == bfd_link_hash_warning)
03431 h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
03432 if (h->root.forced_local)
03433 return TRUE;
03434 }
03435
03436 return FALSE;
03437 }
03438
03439
03440
03441 bfd_vma
03442 _bfd_mips_elf_sign_extend (bfd_vma value, int bits)
03443 {
03444 if (value & ((bfd_vma) 1 << (bits - 1)))
03445
03446 value |= ((bfd_vma) - 1) << bits;
03447
03448 return value;
03449 }
03450
03451
03452
03453
03454
03455 static bfd_boolean
03456 mips_elf_overflow_p (bfd_vma value, int bits)
03457 {
03458 bfd_signed_vma svalue = (bfd_signed_vma) value;
03459
03460 if (svalue > (1 << (bits - 1)) - 1)
03461
03462 return TRUE;
03463 else if (svalue < -(1 << (bits - 1)))
03464
03465 return TRUE;
03466
03467
03468 return FALSE;
03469 }
03470
03471
03472
03473 static bfd_vma
03474 mips_elf_high (bfd_vma value)
03475 {
03476 return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
03477 }
03478
03479
03480
03481 static bfd_vma
03482 mips_elf_higher (bfd_vma value ATTRIBUTE_UNUSED)
03483 {
03484 #ifdef BFD64
03485 return ((value + (bfd_vma) 0x80008000) >> 32) & 0xffff;
03486 #else
03487 abort ();
03488 return MINUS_ONE;
03489 #endif
03490 }
03491
03492
03493
03494 static bfd_vma
03495 mips_elf_highest (bfd_vma value ATTRIBUTE_UNUSED)
03496 {
03497 #ifdef BFD64
03498 return ((value + (((bfd_vma) 0x8000 << 32) | 0x80008000)) >> 48) & 0xffff;
03499 #else
03500 abort ();
03501 return MINUS_ONE;
03502 #endif
03503 }
03504
03505
03506
03507 static bfd_boolean
03508 mips_elf_create_compact_rel_section
03509 (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
03510 {
03511 flagword flags;
03512 register asection *s;
03513
03514 if (bfd_get_section_by_name (abfd, ".compact_rel") == NULL)
03515 {
03516 flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED
03517 | SEC_READONLY);
03518
03519 s = bfd_make_section (abfd, ".compact_rel");
03520 if (s == NULL
03521 || ! bfd_set_section_flags (abfd, s, flags)
03522 || ! bfd_set_section_alignment (abfd, s,
03523 MIPS_ELF_LOG_FILE_ALIGN (abfd)))
03524 return FALSE;
03525
03526 s->size = sizeof (Elf32_External_compact_rel);
03527 }
03528
03529 return TRUE;
03530 }
03531
03532
03533
03534 static bfd_boolean
03535 mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info,
03536 bfd_boolean maybe_exclude)
03537 {
03538 flagword flags;
03539 register asection *s;
03540 struct elf_link_hash_entry *h;
03541 struct bfd_link_hash_entry *bh;
03542 struct mips_got_info *g;
03543 bfd_size_type amt;
03544
03545
03546 s = mips_elf_got_section (abfd, TRUE);
03547 if (s)
03548 {
03549 if (! maybe_exclude)
03550 s->flags &= ~SEC_EXCLUDE;
03551 return TRUE;
03552 }
03553
03554 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03555 | SEC_LINKER_CREATED);
03556
03557 if (maybe_exclude)
03558 flags |= SEC_EXCLUDE;
03559
03560
03561
03562 s = bfd_make_section (abfd, ".got");
03563 if (s == NULL
03564 || ! bfd_set_section_flags (abfd, s, flags)
03565 || ! bfd_set_section_alignment (abfd, s, 4))
03566 return FALSE;
03567
03568
03569
03570
03571 bh = NULL;
03572 if (! (_bfd_generic_link_add_one_symbol
03573 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
03574 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
03575 return FALSE;
03576
03577 h = (struct elf_link_hash_entry *) bh;
03578 h->non_elf = 0;
03579 h->def_regular = 1;
03580 h->type = STT_OBJECT;
03581
03582 if (info->shared
03583 && ! bfd_elf_link_record_dynamic_symbol (info, h))
03584 return FALSE;
03585
03586 amt = sizeof (struct mips_got_info);
03587 g = bfd_alloc (abfd, amt);
03588 if (g == NULL)
03589 return FALSE;
03590 g->global_gotsym = NULL;
03591 g->global_gotno = 0;
03592 g->tls_gotno = 0;
03593 g->local_gotno = MIPS_RESERVED_GOTNO;
03594 g->assigned_gotno = MIPS_RESERVED_GOTNO;
03595 g->bfd2got = NULL;
03596 g->next = NULL;
03597 g->tls_ldm_offset = MINUS_ONE;
03598 g->got_entries = htab_try_create (1, mips_elf_got_entry_hash,
03599 mips_elf_got_entry_eq, NULL);
03600 if (g->got_entries == NULL)
03601 return FALSE;
03602 mips_elf_section_data (s)->u.got_info = g;
03603 mips_elf_section_data (s)->elf.this_hdr.sh_flags
03604 |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
03605
03606 return TRUE;
03607 }
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622 static bfd_reloc_status_type
03623 mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
03624 asection *input_section,
03625 struct bfd_link_info *info,
03626 const Elf_Internal_Rela *relocation,
03627 bfd_vma addend, reloc_howto_type *howto,
03628 Elf_Internal_Sym *local_syms,
03629 asection **local_sections, bfd_vma *valuep,
03630 const char **namep, bfd_boolean *require_jalxp,
03631 bfd_boolean save_addend)
03632 {
03633
03634 bfd_vma value;
03635
03636
03637 bfd_vma symbol = 0;
03638
03639
03640 bfd_vma gp = MINUS_ONE;
03641
03642
03643 bfd_vma p;
03644
03645 bfd_vma gp0 = MINUS_ONE;
03646
03647
03648
03649 bfd_vma g = MINUS_ONE;
03650
03651
03652 asection *sec = NULL;
03653 struct mips_elf_link_hash_entry *h = NULL;
03654
03655
03656 bfd_boolean local_p, was_local_p;
03657
03658 bfd_boolean gp_disp_p = FALSE;
03659
03660
03661 bfd_boolean gnu_local_gp_p = FALSE;
03662 Elf_Internal_Shdr *symtab_hdr;
03663 size_t extsymoff;
03664 unsigned long r_symndx;
03665 int r_type;
03666
03667
03668 bfd_boolean overflowed_p;
03669
03670 bfd_boolean target_is_16_bit_code_p = FALSE;
03671
03672
03673 r_symndx = ELF_R_SYM (input_bfd, relocation->r_info);
03674 r_type = ELF_R_TYPE (input_bfd, relocation->r_info);
03675 p = (input_section->output_section->vma
03676 + input_section->output_offset
03677 + relocation->r_offset);
03678
03679
03680 overflowed_p = FALSE;
03681
03682
03683
03684 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
03685 local_p = mips_elf_local_relocation_p (input_bfd, relocation,
03686 local_sections, FALSE);
03687 was_local_p = local_p;
03688 if (! elf_bad_symtab (input_bfd))
03689 extsymoff = symtab_hdr->sh_info;
03690 else
03691 {
03692
03693
03694 extsymoff = 0;
03695 }
03696
03697
03698 if (local_p)
03699 {
03700 Elf_Internal_Sym *sym;
03701
03702 sym = local_syms + r_symndx;
03703 sec = local_sections[r_symndx];
03704
03705 symbol = sec->output_section->vma + sec->output_offset;
03706 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
03707 || (sec->flags & SEC_MERGE))
03708 symbol += sym->st_value;
03709 if ((sec->flags & SEC_MERGE)
03710 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
03711 {
03712 addend = _bfd_elf_rel_local_sym (abfd, sym, &sec, addend);
03713 addend -= symbol;
03714 addend += sec->output_section->vma + sec->output_offset;
03715 }
03716
03717
03718 if (sym->st_other == STO_MIPS16)
03719 ++symbol;
03720
03721
03722 *namep = bfd_elf_string_from_elf_section (input_bfd,
03723 symtab_hdr->sh_link,
03724 sym->st_name);
03725 if (*namep == '\0')
03726 *namep = bfd_section_name (input_bfd, sec);
03727
03728 target_is_16_bit_code_p = (sym->st_other == STO_MIPS16);
03729 }
03730 else
03731 {
03732
03733
03734
03735 h = ((struct mips_elf_link_hash_entry *)
03736 elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
03737
03738 while (h->root.root.type == bfd_link_hash_indirect
03739 || h->root.root.type == bfd_link_hash_warning)
03740 h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
03741
03742
03743 *namep = h->root.root.root.string;
03744
03745
03746
03747 if (strcmp (*namep, "_gp_disp") == 0
03748 && ! NEWABI_P (input_bfd))
03749 {
03750
03751
03752 if (r_type != R_MIPS_HI16 && r_type != R_MIPS_LO16
03753 && r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16)
03754 return bfd_reloc_notsupported;
03755
03756 gp_disp_p = TRUE;
03757 }
03758
03759
03760 else if (strcmp (*namep, "__gnu_local_gp") == 0)
03761 gnu_local_gp_p = TRUE;
03762
03763
03764
03765
03766
03767
03768 else if ((h->root.root.type == bfd_link_hash_defined
03769 || h->root.root.type == bfd_link_hash_defweak)
03770 && h->root.root.u.def.section)
03771 {
03772 sec = h->root.root.u.def.section;
03773 if (sec->output_section)
03774 symbol = (h->root.root.u.def.value
03775 + sec->output_section->vma
03776 + sec->output_offset);
03777 else
03778 symbol = h->root.root.u.def.value;
03779 }
03780 else if (h->root.root.type == bfd_link_hash_undefweak)
03781
03782
03783
03784
03785 symbol = 0;
03786 else if (info->unresolved_syms_in_objects == RM_IGNORE
03787 && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
03788 symbol = 0;
03789 else if (strcmp (*namep, SGI_COMPAT (input_bfd)
03790 ? "_DYNAMIC_LINK" : "_DYNAMIC_LINKING") == 0)
03791 {
03792
03793
03794
03795
03796
03797
03798 BFD_ASSERT (! info->shared);
03799 BFD_ASSERT (bfd_get_section_by_name (abfd, ".dynamic") == NULL);
03800 symbol = 0;
03801 }
03802 else
03803 {
03804 if (! ((*info->callbacks->undefined_symbol)
03805 (info, h->root.root.root.string, input_bfd,
03806 input_section, relocation->r_offset,
03807 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
03808 || ELF_ST_VISIBILITY (h->root.other))))
03809 return bfd_reloc_undefined;
03810 symbol = 0;
03811 }
03812
03813 target_is_16_bit_code_p = (h->root.other == STO_MIPS16);
03814 }
03815
03816
03817
03818
03819 if (r_type != R_MIPS16_26 && !info->relocatable
03820 && ((h != NULL && h->fn_stub != NULL)
03821 || (local_p && elf_tdata (input_bfd)->local_stubs != NULL
03822 && elf_tdata (input_bfd)->local_stubs[r_symndx] != NULL))
03823 && !mips_elf_stub_section_p (input_bfd, input_section))
03824 {
03825
03826
03827
03828 if (local_p)
03829 sec = elf_tdata (input_bfd)->local_stubs[r_symndx];
03830 else
03831 {
03832 BFD_ASSERT (h->need_fn_stub);
03833 sec = h->fn_stub;
03834 }
03835
03836 symbol = sec->output_section->vma + sec->output_offset;
03837 }
03838
03839
03840 else if (r_type == R_MIPS16_26 && !info->relocatable
03841 && h != NULL
03842 && (h->call_stub != NULL || h->call_fp_stub != NULL)
03843 && !target_is_16_bit_code_p)
03844 {
03845
03846
03847
03848 if (h->call_stub != NULL && h->call_fp_stub != NULL)
03849 {
03850 asection *o;
03851
03852 sec = NULL;
03853 for (o = input_bfd->sections; o != NULL; o = o->next)
03854 {
03855 if (strncmp (bfd_get_section_name (input_bfd, o),
03856 CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0)
03857 {
03858 sec = h->call_fp_stub;
03859 break;
03860 }
03861 }
03862 if (sec == NULL)
03863 sec = h->call_stub;
03864 }
03865 else if (h->call_stub != NULL)
03866 sec = h->call_stub;
03867 else
03868 sec = h->call_fp_stub;
03869
03870 BFD_ASSERT (sec->size > 0);
03871 symbol = sec->output_section->vma + sec->output_offset;
03872 }
03873
03874
03875
03876 *require_jalxp = (!info->relocatable
03877 && (((r_type == R_MIPS16_26) && !target_is_16_bit_code_p)
03878 || ((r_type == R_MIPS_26) && target_is_16_bit_code_p)));
03879
03880 local_p = mips_elf_local_relocation_p (input_bfd, relocation,
03881 local_sections, TRUE);
03882
03883
03884
03885 switch (r_type)
03886 {
03887 case R_MIPS_GOT_PAGE:
03888 case R_MIPS_GOT_OFST:
03889
03890
03891 local_p = local_p || _bfd_elf_symbol_refs_local_p (&h->root, info, 1);
03892 if (local_p || r_type == R_MIPS_GOT_OFST)
03893 break;
03894
03895
03896 case R_MIPS_CALL16:
03897 case R_MIPS_GOT16:
03898 case R_MIPS_GOT_DISP:
03899 case R_MIPS_GOT_HI16:
03900 case R_MIPS_CALL_HI16:
03901 case R_MIPS_GOT_LO16:
03902 case R_MIPS_CALL_LO16:
03903 case R_MIPS_TLS_GD:
03904 case R_MIPS_TLS_GOTTPREL:
03905 case R_MIPS_TLS_LDM:
03906
03907 if (r_type == R_MIPS_TLS_LDM)
03908 {
03909 g = mips_elf_local_got_index (abfd, input_bfd, info, 0, 0, NULL,
03910 r_type);
03911 if (g == MINUS_ONE)
03912 return bfd_reloc_outofrange;
03913 }
03914 else if (!local_p)
03915 {
03916
03917
03918
03919
03920 BFD_ASSERT (addend == 0 || r_type == R_MIPS_GOT_PAGE);
03921 g = mips_elf_global_got_index (elf_hash_table (info)->dynobj,
03922 input_bfd,
03923 (struct elf_link_hash_entry *) h,
03924 r_type, info);
03925 if (h->tls_type == GOT_NORMAL
03926 && (! elf_hash_table(info)->dynamic_sections_created
03927 || (info->shared
03928 && (info->symbolic || h->root.dynindx == -1)
03929 && h->root.def_regular)))
03930 {
03931
03932
03933
03934 bfd *tmpbfd = elf_hash_table (info)->dynobj;
03935 asection *sgot = mips_elf_got_section (tmpbfd, FALSE);
03936 MIPS_ELF_PUT_WORD (tmpbfd, symbol, sgot->contents + g);
03937 }
03938 }
03939 else if (r_type == R_MIPS_GOT16 || r_type == R_MIPS_CALL16)
03940
03941
03942 break;
03943 else
03944 {
03945 g = mips_elf_local_got_index (abfd, input_bfd,
03946 info, symbol + addend, r_symndx, h,
03947 r_type);
03948 if (g == MINUS_ONE)
03949 return bfd_reloc_outofrange;
03950 }
03951
03952
03953 g = mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
03954 abfd, input_bfd, g);
03955 break;
03956
03957 case R_MIPS_HI16:
03958 case R_MIPS_LO16:
03959 case R_MIPS_GPREL16:
03960 case R_MIPS_GPREL32:
03961 case R_MIPS_LITERAL:
03962 case R_MIPS16_HI16:
03963 case R_MIPS16_LO16:
03964 case R_MIPS16_GPREL:
03965 gp0 = _bfd_get_gp_value (input_bfd);
03966 gp = _bfd_get_gp_value (abfd);
03967 if (elf_hash_table (info)->dynobj)
03968 gp += mips_elf_adjust_gp (abfd,
03969 mips_elf_got_info
03970 (elf_hash_table (info)->dynobj, NULL),
03971 input_bfd);
03972 break;
03973
03974 default:
03975 break;
03976 }
03977
03978 if (gnu_local_gp_p)
03979 symbol = gp;
03980
03981
03982 switch (r_type)
03983 {
03984 case R_MIPS_NONE:
03985 return bfd_reloc_continue;
03986
03987 case R_MIPS_16:
03988 value = symbol + _bfd_mips_elf_sign_extend (addend, 16);
03989 overflowed_p = mips_elf_overflow_p (value, 16);
03990 break;
03991
03992 case R_MIPS_32:
03993 case R_MIPS_REL32:
03994 case R_MIPS_64:
03995 if ((info->shared
03996 || (elf_hash_table (info)->dynamic_sections_created
03997 && h != NULL
03998 && h->root.def_dynamic
03999 && !h->root.def_regular))
04000 && r_symndx != 0
04001 && (input_section->flags & SEC_ALLOC) != 0)
04002 {
04003
04004
04005
04006
04007
04008 value = addend;
04009 if (!mips_elf_create_dynamic_relocation (abfd,
04010 info,
04011 relocation,
04012 h,
04013 sec,
04014 symbol,
04015 &value,
04016 input_section))
04017 return bfd_reloc_undefined;
04018 }
04019 else
04020 {
04021 if (r_type != R_MIPS_REL32)
04022 value = symbol + addend;
04023 else
04024 value = addend;
04025 }
04026 value &= howto->dst_mask;
04027 break;
04028
04029 case R_MIPS_PC32:
04030 value = symbol + addend - p;
04031 value &= howto->dst_mask;
04032 break;
04033
04034 case R_MIPS_GNU_REL16_S2:
04035 value = symbol + _bfd_mips_elf_sign_extend (addend, 18) - p;
04036 overflowed_p = mips_elf_overflow_p (value, 18);
04037 value = (value >> 2) & howto->dst_mask;
04038 break;
04039
04040 case R_MIPS16_26:
04041
04042
04043
04044
04045
04046 case R_MIPS_26:
04047 if (local_p)
04048 value = ((addend | ((p + 4) & 0xf0000000)) + symbol) >> 2;
04049 else
04050 {
04051 value = (_bfd_mips_elf_sign_extend (addend, 28) + symbol) >> 2;
04052 if (h->root.root.type != bfd_link_hash_undefweak)
04053 overflowed_p = (value >> 26) != ((p + 4) >> 28);
04054 }
04055 value &= howto->dst_mask;
04056 break;
04057
04058 case R_MIPS_TLS_DTPREL_HI16:
04059 value = (mips_elf_high (addend + symbol - dtprel_base (info))
04060 & howto->dst_mask);
04061 break;
04062
04063 case R_MIPS_TLS_DTPREL_LO16:
04064 value = (symbol + addend - dtprel_base (info)) & howto->dst_mask;
04065 break;
04066
04067 case R_MIPS_TLS_TPREL_HI16:
04068 value = (mips_elf_high (addend + symbol - tprel_base (info))
04069 & howto->dst_mask);
04070 break;
04071
04072 case R_MIPS_TLS_TPREL_LO16:
04073 value = (symbol + addend - tprel_base (info)) & howto->dst_mask;
04074 break;
04075
04076 case R_MIPS_HI16:
04077 case R_MIPS16_HI16:
04078 if (!gp_disp_p)
04079 {
04080 value = mips_elf_high (addend + symbol);
04081 value &= howto->dst_mask;
04082 }
04083 else
04084 {
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094 if (r_type == R_MIPS16_HI16)
04095 value = mips_elf_high (addend + gp - p - 4);
04096 else
04097 value = mips_elf_high (addend + gp - p);
04098 overflowed_p = mips_elf_overflow_p (value, 16);
04099 }
04100 break;
04101
04102 case R_MIPS_LO16:
04103 case R_MIPS16_LO16:
04104 if (!gp_disp_p)
04105 value = (symbol + addend) & howto->dst_mask;
04106 else
04107 {
04108
04109
04110 if (r_type == R_MIPS16_LO16)
04111 value = addend + gp - p;
04112 else
04113 value = addend + gp - p + 4;
04114
04115
04116
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127
04128
04129
04130 }
04131 break;
04132
04133 case R_MIPS_LITERAL:
04134
04135
04136
04137
04138
04139
04140
04141 case R_MIPS16_GPREL:
04142
04143
04144
04145
04146 case R_MIPS_GPREL16:
04147
04148
04149
04150 if (howto->partial_inplace)
04151 addend = _bfd_mips_elf_sign_extend (addend, 16);
04152 value = symbol + addend - gp;
04153
04154
04155
04156
04157
04158 if (was_local_p)
04159 value += gp0;
04160 overflowed_p = mips_elf_overflow_p (value, 16);
04161 break;
04162
04163 case R_MIPS_GOT16:
04164 case R_MIPS_CALL16:
04165 if (local_p)
04166 {
04167 bfd_boolean forced;
04168
04169
04170
04171
04172 forced = ! mips_elf_local_relocation_p (input_bfd, relocation,
04173 local_sections, FALSE);
04174 value = mips_elf_got16_entry (abfd, input_bfd, info,
04175 symbol + addend, forced);
04176 if (value == MINUS_ONE)
04177 return bfd_reloc_outofrange;
04178 value
04179 = mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
04180 abfd, input_bfd, value);
04181 overflowed_p = mips_elf_overflow_p (value, 16);
04182 break;
04183 }
04184
04185
04186
04187 case R_MIPS_TLS_GD:
04188 case R_MIPS_TLS_GOTTPREL:
04189 case R_MIPS_TLS_LDM:
04190 case R_MIPS_GOT_DISP:
04191 got_disp:
04192 value = g;
04193 overflowed_p = mips_elf_overflow_p (value, 16);
04194 break;
04195
04196 case R_MIPS_GPREL32:
04197 value = (addend + symbol + gp0 - gp);
04198 if (!save_addend)
04199 value &= howto->dst_mask;
04200 break;
04201
04202 case R_MIPS_PC16:
04203 value = _bfd_mips_elf_sign_extend (addend, 16) + symbol - p;
04204 overflowed_p = mips_elf_overflow_p (value, 16);
04205 break;
04206
04207 case R_MIPS_GOT_HI16:
04208 case R_MIPS_CALL_HI16:
04209
04210
04211
04212 value = g;
04213 value = mips_elf_high (value);
04214 value &= howto->dst_mask;
04215 break;
04216
04217 case R_MIPS_GOT_LO16:
04218 case R_MIPS_CALL_LO16:
04219 value = g & howto->dst_mask;
04220 break;
04221
04222 case R_MIPS_GOT_PAGE:
04223
04224
04225
04226 if (! local_p)
04227 goto got_disp;
04228 value = mips_elf_got_page (abfd, input_bfd, info, symbol + addend, NULL);
04229 if (value == MINUS_ONE)
04230 return bfd_reloc_outofrange;
04231 value = mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
04232 abfd, input_bfd, value);
04233 overflowed_p = mips_elf_overflow_p (value, 16);
04234 break;
04235
04236 case R_MIPS_GOT_OFST:
04237 if (local_p)
04238 mips_elf_got_page (abfd, input_bfd, info, symbol + addend, &value);
04239 else
04240 value = addend;
04241 overflowed_p = mips_elf_overflow_p (value, 16);
04242 break;
04243
04244 case R_MIPS_SUB:
04245 value = symbol - addend;
04246 value &= howto->dst_mask;
04247 break;
04248
04249 case R_MIPS_HIGHER:
04250 value = mips_elf_higher (addend + symbol);
04251 value &= howto->dst_mask;
04252 break;
04253
04254 case R_MIPS_HIGHEST:
04255 value = mips_elf_highest (addend + symbol);
04256 value &= howto->dst_mask;
04257 break;
04258
04259 case R_MIPS_SCN_DISP:
04260 value = symbol + addend - sec->output_offset;
04261 value &= howto->dst_mask;
04262 break;
04263
04264 case R_MIPS_JALR:
04265
04266
04267
04268 if (h != NULL && h->root.plt.offset != (bfd_vma) -1)
04269 return bfd_reloc_continue;
04270 value = symbol + addend;
04271 break;
04272
04273 case R_MIPS_PJUMP:
04274 case R_MIPS_GNU_VTINHERIT:
04275 case R_MIPS_GNU_VTENTRY:
04276
04277 return bfd_reloc_continue;
04278
04279 default:
04280
04281 return bfd_reloc_notsupported;
04282 }
04283
04284
04285 *valuep = value;
04286 return overflowed_p ? bfd_reloc_overflow : bfd_reloc_ok;
04287 }
04288
04289
04290
04291 static bfd_vma
04292 mips_elf_obtain_contents (reloc_howto_type *howto,
04293 const Elf_Internal_Rela *relocation,
04294 bfd *input_bfd, bfd_byte *contents)
04295 {
04296 bfd_vma x;
04297 bfd_byte *location = contents + relocation->r_offset;
04298
04299
04300 x = bfd_get ((8 * bfd_get_reloc_size (howto)), input_bfd, location);
04301
04302 return x;
04303 }
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314 static bfd_boolean
04315 mips_elf_perform_relocation (struct bfd_link_info *info,
04316 reloc_howto_type *howto,
04317 const Elf_Internal_Rela *relocation,
04318 bfd_vma value, bfd *input_bfd,
04319 asection *input_section, bfd_byte *contents,
04320 bfd_boolean require_jalx)
04321 {
04322 bfd_vma x;
04323 bfd_byte *location;
04324 int r_type = ELF_R_TYPE (input_bfd, relocation->r_info);
04325
04326
04327 location = contents + relocation->r_offset;
04328
04329 _bfd_mips16_elf_reloc_unshuffle (input_bfd, r_type, FALSE, location);
04330
04331
04332 x = mips_elf_obtain_contents (howto, relocation, input_bfd, contents);
04333
04334
04335 x &= ~howto->dst_mask;
04336
04337
04338 x |= (value & howto->dst_mask);
04339
04340
04341 if (require_jalx)
04342 {
04343 bfd_boolean ok;
04344 bfd_vma opcode = x >> 26;
04345 bfd_vma jalx_opcode;
04346
04347
04348 if (r_type == R_MIPS16_26)
04349 {
04350 ok = ((opcode == 0x6) || (opcode == 0x7));
04351 jalx_opcode = 0x7;
04352 }
04353 else
04354 {
04355 ok = ((opcode == 0x3) || (opcode == 0x1d));
04356 jalx_opcode = 0x1d;
04357 }
04358
04359
04360 if (!ok)
04361 {
04362 (*_bfd_error_handler)
04363 (_("%B: %A+0x%lx: jump to stub routine which is not jal"),
04364 input_bfd,
04365 input_section,
04366 (unsigned long) relocation->r_offset);
04367 bfd_set_error (bfd_error_bad_value);
04368 return FALSE;
04369 }
04370
04371
04372 x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
04373 }
04374
04375
04376
04377
04378
04379 if (bfd_get_mach (input_bfd) == bfd_mach_mips9000
04380 && !info->relocatable
04381 && !require_jalx
04382 && ((r_type == R_MIPS_26 && (x >> 26) == 0x3)
04383 || (r_type == R_MIPS_JALR && x == 0x0320f809)))
04384 {
04385 bfd_vma addr;
04386 bfd_vma dest;
04387 bfd_signed_vma off;
04388
04389 addr = (input_section->output_section->vma
04390 + input_section->output_offset
04391 + relocation->r_offset
04392 + 4);
04393 if (r_type == R_MIPS_26)
04394 dest = (value << 2) | ((addr >> 28) << 28);
04395 else
04396 dest = value;
04397 off = dest - addr;
04398 if (off <= 0x1ffff && off >= -0x20000)
04399 x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff);
04400 }
04401
04402
04403 bfd_put (8 * bfd_get_reloc_size (howto), input_bfd, x, location);
04404
04405 _bfd_mips16_elf_reloc_shuffle(input_bfd, r_type, !info->relocatable,
04406 location);
04407
04408 return TRUE;
04409 }
04410
04411
04412
04413 static bfd_boolean
04414 mips_elf_stub_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
04415 {
04416 const char *name = bfd_get_section_name (abfd, section);
04417
04418 return (strncmp (name, FN_STUB, sizeof FN_STUB - 1) == 0
04419 || strncmp (name, CALL_STUB, sizeof CALL_STUB - 1) == 0
04420 || strncmp (name, CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0);
04421 }
04422
04423
04424
04425 static void
04426 mips_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
04427 {
04428 asection *s;
04429
04430 s = mips_elf_rel_dyn_section (abfd, FALSE);
04431 BFD_ASSERT (s != NULL);
04432
04433 if (s->size == 0)
04434 {
04435
04436 s->size += MIPS_ELF_REL_SIZE (abfd);
04437 ++s->reloc_count;
04438 }
04439 s->size += n * MIPS_ELF_REL_SIZE (abfd);
04440 }
04441
04442
04443
04444
04445
04446
04447 static bfd_boolean
04448 mips_elf_create_dynamic_relocation (bfd *output_bfd,
04449 struct bfd_link_info *info,
04450 const Elf_Internal_Rela *rel,
04451 struct mips_elf_link_hash_entry *h,
04452 asection *sec, bfd_vma symbol,
04453 bfd_vma *addendp, asection *input_section)
04454 {
04455 Elf_Internal_Rela outrel[3];
04456 asection *sreloc;
04457 bfd *dynobj;
04458 int r_type;
04459 long indx;
04460 bfd_boolean defined_p;
04461
04462 r_type = ELF_R_TYPE (output_bfd, rel->r_info);
04463 dynobj = elf_hash_table (info)->dynobj;
04464 sreloc = mips_elf_rel_dyn_section (dynobj, FALSE);
04465 BFD_ASSERT (sreloc != NULL);
04466 BFD_ASSERT (sreloc->contents != NULL);
04467 BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd)
04468 < sreloc->size);
04469
04470 outrel[0].r_offset =
04471 _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
04472 outrel[1].r_offset =
04473 _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
04474 outrel[2].r_offset =
04475 _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
04476
04477 if (outrel[0].r_offset == MINUS_ONE)
04478
04479 return TRUE;
04480
04481 if (outrel[0].r_offset == MINUS_TWO)
04482 {
04483
04484
04485
04486 *addendp += symbol;
04487 return TRUE;
04488 }
04489
04490
04491
04492 if (h != NULL
04493 && (! info->symbolic || !h->root.def_regular)
04494
04495
04496 && h->root.dynindx != -1)
04497 {
04498 indx = h->root.dynindx;
04499 if (SGI_COMPAT (output_bfd))
04500 defined_p = h->root.def_regular;
04501 else
04502
04503
04504
04505
04506 defined_p = FALSE;
04507 }
04508 else
04509 {
04510 if (sec != NULL && bfd_is_abs_section (sec))
04511 indx = 0;
04512 else if (sec == NULL || sec->owner == NULL)
04513 {
04514 bfd_set_error (bfd_error_bad_value);
04515 return FALSE;
04516 }
04517 else
04518 {
04519 indx = elf_section_data (sec->output_section)->dynindx;
04520 if (indx == 0)
04521 abort ();
04522 }
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539 if (!SGI_COMPAT (output_bfd))
04540 indx = 0;
04541 defined_p = TRUE;
04542 }
04543
04544
04545
04546
04547
04548 if (defined_p && r_type != R_MIPS_REL32)
04549 *addendp += symbol;
04550
04551
04552
04553 outrel[0].r_info = ELF_R_INFO (output_bfd, (unsigned long) indx,
04554 R_MIPS_REL32);
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567 outrel[1].r_info = ELF_R_INFO (output_bfd, 0,
04568 ABI_64_P (output_bfd)
04569 ? R_MIPS_64
04570 : R_MIPS_NONE);
04571 outrel[2].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_NONE);
04572
04573
04574
04575 outrel[0].r_offset += (input_section->output_section->vma
04576 + input_section->output_offset);
04577 outrel[1].r_offset += (input_section->output_section->vma
04578 + input_section->output_offset);
04579 outrel[2].r_offset += (input_section->output_section->vma
04580 + input_section->output_offset);
04581
04582
04583
04584
04585 if (ABI_64_P (output_bfd))
04586 {
04587 (*get_elf_backend_data (output_bfd)->s->swap_reloc_out)
04588 (output_bfd, &outrel[0],
04589 (sreloc->contents
04590 + sreloc->reloc_count * sizeof (Elf64_Mips_External_Rel)));
04591 }
04592 else
04593 bfd_elf32_swap_reloc_out
04594 (output_bfd, &outrel[0],
04595 (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
04596
04597
04598 ++sreloc->reloc_count;
04599
04600
04601
04602 elf_section_data (input_section->output_section)->this_hdr.sh_flags
04603 |= SHF_WRITE;
04604
04605
04606 if (IRIX_COMPAT (output_bfd) == ict_irix5)
04607 {
04608 asection *scpt = bfd_get_section_by_name (dynobj, ".compact_rel");
04609 bfd_byte *cr;
04610
04611 if (scpt)
04612 {
04613 Elf32_crinfo cptrel;
04614
04615 mips_elf_set_cr_format (cptrel, CRF_MIPS_LONG);
04616 cptrel.vaddr = (rel->r_offset
04617 + input_section->output_section->vma
04618 + input_section->output_offset);
04619 if (r_type == R_MIPS_REL32)
04620 mips_elf_set_cr_type (cptrel, CRT_MIPS_REL32);
04621 else
04622 mips_elf_set_cr_type (cptrel, CRT_MIPS_WORD);
04623 mips_elf_set_cr_dist2to (cptrel, 0);
04624 cptrel.konst = *addendp;
04625
04626 cr = (scpt->contents
04627 + sizeof (Elf32_External_compact_rel));
04628 mips_elf_set_cr_relvaddr (cptrel, 0);
04629 bfd_elf32_swap_crinfo_out (output_bfd, &cptrel,
04630 ((Elf32_External_crinfo *) cr
04631 + scpt->reloc_count));
04632 ++scpt->reloc_count;
04633 }
04634 }
04635
04636 return TRUE;
04637 }
04638
04639
04640
04641 unsigned long
04642 _bfd_elf_mips_mach (flagword flags)
04643 {
04644 switch (flags & EF_MIPS_MACH)
04645 {
04646 case E_MIPS_MACH_3900:
04647 return bfd_mach_mips3900;
04648
04649 case E_MIPS_MACH_4010:
04650 return bfd_mach_mips4010;
04651
04652 case E_MIPS_MACH_4100:
04653 return bfd_mach_mips4100;
04654
04655 case E_MIPS_MACH_4111:
04656 return bfd_mach_mips4111;
04657
04658 case E_MIPS_MACH_4120:
04659 return bfd_mach_mips4120;
04660
04661 case E_MIPS_MACH_4650:
04662 return bfd_mach_mips4650;
04663
04664 case E_MIPS_MACH_5400:
04665 return bfd_mach_mips5400;
04666
04667 case E_MIPS_MACH_5500:
04668 return bfd_mach_mips5500;
04669
04670 case E_MIPS_MACH_9000:
04671 return bfd_mach_mips9000;
04672
04673 case E_MIPS_MACH_SB1:
04674 return bfd_mach_mips_sb1;
04675
04676 default:
04677 switch (flags & EF_MIPS_ARCH)
04678 {
04679 default:
04680 case E_MIPS_ARCH_1:
04681 return bfd_mach_mips3000;
04682 break;
04683
04684 case E_MIPS_ARCH_2:
04685 return bfd_mach_mips6000;
04686 break;
04687
04688 case E_MIPS_ARCH_3:
04689 return bfd_mach_mips4000;
04690 break;
04691
04692 case E_MIPS_ARCH_4:
04693 return bfd_mach_mips8000;
04694 break;
04695
04696 case E_MIPS_ARCH_5:
04697 return bfd_mach_mips5;
04698 break;
04699
04700 case E_MIPS_ARCH_32:
04701 return bfd_mach_mipsisa32;
04702 break;
04703
04704 case E_MIPS_ARCH_64:
04705 return bfd_mach_mipsisa64;
04706 break;
04707
04708 case E_MIPS_ARCH_32R2:
04709 return bfd_mach_mipsisa32r2;
04710 break;
04711
04712 case E_MIPS_ARCH_64R2:
04713 return bfd_mach_mipsisa64r2;
04714 break;
04715 }
04716 }
04717
04718 return 0;
04719 }
04720
04721
04722
04723 static INLINE char *
04724 elf_mips_abi_name (bfd *abfd)
04725 {
04726 flagword flags;
04727
04728 flags = elf_elfheader (abfd)->e_flags;
04729 switch (flags & EF_MIPS_ABI)
04730 {
04731 case 0:
04732 if (ABI_N32_P (abfd))
04733 return "N32";
04734 else if (ABI_64_P (abfd))
04735 return "64";
04736 else
04737 return "none";
04738 case E_MIPS_ABI_O32:
04739 return "O32";
04740 case E_MIPS_ABI_O64:
04741 return "O64";
04742 case E_MIPS_ABI_EABI32:
04743 return "EABI32";
04744 case E_MIPS_ABI_EABI64:
04745 return "EABI64";
04746 default:
04747 return "unknown abi";
04748 }
04749 }
04750
04751
04752
04753
04754
04755
04756 static asection mips_elf_scom_section;
04757 static asymbol mips_elf_scom_symbol;
04758 static asymbol *mips_elf_scom_symbol_ptr;
04759
04760
04761
04762
04763 static asection mips_elf_acom_section;
04764 static asymbol mips_elf_acom_symbol;
04765 static asymbol *mips_elf_acom_symbol_ptr;
04766
04767
04768
04769
04770 void
04771 _bfd_mips_elf_symbol_processing (bfd *abfd, asymbol *asym)
04772 {
04773 elf_symbol_type *elfsym;
04774
04775 elfsym = (elf_symbol_type *) asym;
04776 switch (elfsym->internal_elf_sym.st_shndx)
04777 {
04778 case SHN_MIPS_ACOMMON:
04779
04780
04781
04782
04783
04784 if (mips_elf_acom_section.name == NULL)
04785 {
04786
04787 mips_elf_acom_section.name = ".acommon";
04788 mips_elf_acom_section.flags = SEC_ALLOC;
04789 mips_elf_acom_section.output_section = &mips_elf_acom_section;
04790 mips_elf_acom_section.symbol = &mips_elf_acom_symbol;
04791 mips_elf_acom_section.symbol_ptr_ptr = &mips_elf_acom_symbol_ptr;
04792 mips_elf_acom_symbol.name = ".acommon";
04793 mips_elf_acom_symbol.flags = BSF_SECTION_SYM;
04794 mips_elf_acom_symbol.section = &mips_elf_acom_section;
04795 mips_elf_acom_symbol_ptr = &mips_elf_acom_symbol;
04796 }
04797 asym->section = &mips_elf_acom_section;
04798 break;
04799
04800 case SHN_COMMON:
04801
04802
04803 if (asym->value > elf_gp_size (abfd)
04804 || IRIX_COMPAT (abfd) == ict_irix6)
04805 break;
04806
04807 case SHN_MIPS_SCOMMON:
04808 if (mips_elf_scom_section.name == NULL)
04809 {
04810
04811 mips_elf_scom_section.name = ".scommon";
04812 mips_elf_scom_section.flags = SEC_IS_COMMON;
04813 mips_elf_scom_section.output_section = &mips_elf_scom_section;
04814 mips_elf_scom_section.symbol = &mips_elf_scom_symbol;
04815 mips_elf_scom_section.symbol_ptr_ptr = &mips_elf_scom_symbol_ptr;
04816 mips_elf_scom_symbol.name = ".scommon";
04817 mips_elf_scom_symbol.flags = BSF_SECTION_SYM;
04818 mips_elf_scom_symbol.section = &mips_elf_scom_section;
04819 mips_elf_scom_symbol_ptr = &mips_elf_scom_symbol;
04820 }
04821 asym->section = &mips_elf_scom_section;
04822 asym->value = elfsym->internal_elf_sym.st_size;
04823 break;
04824
04825 case SHN_MIPS_SUNDEFINED:
04826 asym->section = bfd_und_section_ptr;
04827 break;
04828
04829 case SHN_MIPS_TEXT:
04830 {
04831 asection *section = bfd_get_section_by_name (abfd, ".text");
04832
04833 BFD_ASSERT (SGI_COMPAT (abfd));
04834 if (section != NULL)
04835 {
04836 asym->section = section;
04837
04838
04839
04840 asym->value -= section->vma;
04841 }
04842 }
04843 break;
04844
04845 case SHN_MIPS_DATA:
04846 {
04847 asection *section = bfd_get_section_by_name (abfd, ".data");
04848
04849 BFD_ASSERT (SGI_COMPAT (abfd));
04850 if (section != NULL)
04851 {
04852 asym->section = section;
04853
04854
04855
04856 asym->value -= section->vma;
04857 }
04858 }
04859 break;
04860 }
04861 }
04862
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889
04890
04891
04892
04893
04894
04895
04896
04897
04898
04899
04900 unsigned int
04901 _bfd_mips_elf_eh_frame_address_size (bfd *abfd, asection *sec)
04902 {
04903 if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
04904 return 8;
04905 if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64)
04906 {
04907 bfd_boolean long32_p, long64_p;
04908
04909 long32_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long32") != 0;
04910 long64_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long64") != 0;
04911 if (long32_p && long64_p)
04912 return 0;
04913 if (long32_p)
04914 return 4;
04915 if (long64_p)
04916 return 8;
04917
04918 if (sec->reloc_count > 0
04919 && elf_section_data (sec)->relocs != NULL
04920 && (ELF32_R_TYPE (elf_section_data (sec)->relocs[0].r_info)
04921 == R_MIPS_64))
04922 return 8;
04923
04924 return 0;
04925 }
04926 return 4;
04927 }
04928
04929
04930
04931
04932
04933
04934
04935
04936
04937
04938
04939
04940
04941
04942
04943 bfd_boolean
04944 _bfd_mips_elf_name_local_section_symbols (bfd *abfd)
04945 {
04946 return SGI_COMPAT (abfd);
04947 }
04948
04949
04950
04951
04952
04953
04954 bfd_boolean
04955 _bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr)
04956 {
04957 if (hdr->sh_type == SHT_MIPS_REGINFO
04958 && hdr->sh_size > 0)
04959 {
04960 bfd_byte buf[4];
04961
04962 BFD_ASSERT (hdr->sh_size == sizeof (Elf32_External_RegInfo));
04963 BFD_ASSERT (hdr->contents == NULL);
04964
04965 if (bfd_seek (abfd,
04966 hdr->sh_offset + sizeof (Elf32_External_RegInfo) - 4,
04967 SEEK_SET) != 0)
04968 return FALSE;
04969 H_PUT_32 (abfd, elf_gp (abfd), buf);
04970 if (bfd_bwrite (buf, 4, abfd) != 4)
04971 return FALSE;
04972 }
04973
04974 if (hdr->sh_type == SHT_MIPS_OPTIONS
04975 && hdr->bfd_section != NULL
04976 && mips_elf_section_data (hdr->bfd_section) != NULL
04977 && mips_elf_section_data (hdr->bfd_section)->u.tdata != NULL)
04978 {
04979 bfd_byte *contents, *l, *lend;
04980
04981
04982
04983
04984
04985
04986
04987
04988 contents = mips_elf_section_data (hdr->bfd_section)->u.tdata;
04989 l = contents;
04990 lend = contents + hdr->sh_size;
04991 while (l + sizeof (Elf_External_Options) <= lend)
04992 {
04993 Elf_Internal_Options intopt;
04994
04995 bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
04996 &intopt);
04997 if (intopt.size < sizeof (Elf_External_Options))
04998 {
04999 (*_bfd_error_handler)
05000 (_("%B: Warning: bad `%s' option size %u smaller than its header"),
05001 abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size);
05002 break;
05003 }
05004 if (ABI_64_P (abfd) && intopt.kind == ODK_REGINFO)
05005 {
05006 bfd_byte buf[8];
05007
05008 if (bfd_seek (abfd,
05009 (hdr->sh_offset
05010 + (l - contents)
05011 + sizeof (Elf_External_Options)
05012 + (sizeof (Elf64_External_RegInfo) - 8)),
05013 SEEK_SET) != 0)
05014 return FALSE;
05015 H_PUT_64 (abfd, elf_gp (abfd), buf);
05016 if (bfd_bwrite (buf, 8, abfd) != 8)
05017 return FALSE;
05018 }
05019 else if (intopt.kind == ODK_REGINFO)
05020 {
05021 bfd_byte buf[4];
05022
05023 if (bfd_seek (abfd,
05024 (hdr->sh_offset
05025 + (l - contents)
05026 + sizeof (Elf_External_Options)
05027 + (sizeof (Elf32_External_RegInfo) - 4)),
05028 SEEK_SET) != 0)
05029 return FALSE;
05030 H_PUT_32 (abfd, elf_gp (abfd), buf);
05031 if (bfd_bwrite (buf, 4, abfd) != 4)
05032 return FALSE;
05033 }
05034 l += intopt.size;
05035 }
05036 }
05037
05038 if (hdr->bfd_section != NULL)
05039 {
05040 const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
05041
05042 if (strcmp (name, ".sdata") == 0
05043 || strcmp (name, ".lit8") == 0
05044 || strcmp (name, ".lit4") == 0)
05045 {
05046 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
05047 hdr->sh_type = SHT_PROGBITS;
05048 }
05049 else if (strcmp (name, ".sbss") == 0)
05050 {
05051 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
05052 hdr->sh_type = SHT_NOBITS;
05053 }
05054 else if (strcmp (name, ".srdata") == 0)
05055 {
05056 hdr->sh_flags |= SHF_ALLOC | SHF_MIPS_GPREL;
05057 hdr->sh_type = SHT_PROGBITS;
05058 }
05059 else if (strcmp (name, ".compact_rel") == 0)
05060 {
05061 hdr->sh_flags = 0;
05062 hdr->sh_type = SHT_PROGBITS;
05063 }
05064 else if (strcmp (name, ".rtproc") == 0)
05065 {
05066 if (hdr->sh_addralign != 0 && hdr->sh_entsize == 0)
05067 {
05068 unsigned int adjust;
05069
05070 adjust = hdr->sh_size % hdr->sh_addralign;
05071 if (adjust != 0)
05072 hdr->sh_size += hdr->sh_addralign - adjust;
05073 }
05074 }
05075 }
05076
05077 return TRUE;
05078 }
05079
05080
05081
05082
05083
05084
05085
05086
05087 bfd_boolean
05088 _bfd_mips_elf_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
05089 const char *name)
05090 {
05091 flagword flags = 0;
05092
05093
05094
05095
05096
05097
05098 switch (hdr->sh_type)
05099 {
05100 case SHT_MIPS_LIBLIST:
05101 if (strcmp (name, ".liblist") != 0)
05102 return FALSE;
05103 break;
05104 case SHT_MIPS_MSYM:
05105 if (strcmp (name, ".msym") != 0)
05106 return FALSE;
05107 break;
05108 case SHT_MIPS_CONFLICT:
05109 if (strcmp (name, ".conflict") != 0)
05110 return FALSE;
05111 break;
05112 case SHT_MIPS_GPTAB:
05113 if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) != 0)
05114 return FALSE;
05115 break;
05116 case SHT_MIPS_UCODE:
05117 if (strcmp (name, ".ucode") != 0)
05118 return FALSE;
05119 break;
05120 case SHT_MIPS_DEBUG:
05121 if (strcmp (name, ".mdebug") != 0)
05122 return FALSE;
05123 flags = SEC_DEBUGGING;
05124 break;
05125 case SHT_MIPS_REGINFO:
05126 if (strcmp (name, ".reginfo") != 0
05127 || hdr->sh_size != sizeof (Elf32_External_RegInfo))
05128 return FALSE;
05129 flags = (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_SIZE);
05130 break;
05131 case SHT_MIPS_IFACE:
05132 if (strcmp (name, ".MIPS.interfaces") != 0)
05133 return FALSE;
05134 break;
05135 case SHT_MIPS_CONTENT:
05136 if (strncmp (name, ".MIPS.content", sizeof ".MIPS.content" - 1) != 0)
05137 return FALSE;
05138 break;
05139 case SHT_MIPS_OPTIONS:
05140 if (!MIPS_ELF_OPTIONS_SECTION_NAME_P (name))
05141 return FALSE;
05142 break;
05143 case SHT_MIPS_DWARF:
05144 if (strncmp (name, ".debug_", sizeof ".debug_" - 1) != 0)
05145 return FALSE;
05146 break;
05147 case SHT_MIPS_SYMBOL_LIB:
05148 if (strcmp (name, ".MIPS.symlib") != 0)
05149 return FALSE;
05150 break;
05151 case SHT_MIPS_EVENTS:
05152 if (strncmp (name, ".MIPS.events", sizeof ".MIPS.events" - 1) != 0
05153 && strncmp (name, ".MIPS.post_rel",
05154 sizeof ".MIPS.post_rel" - 1) != 0)
05155 return FALSE;
05156 break;
05157 default:
05158 break;
05159 }
05160
05161 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
05162 return FALSE;
05163
05164 if (flags)
05165 {
05166 if (! bfd_set_section_flags (abfd, hdr->bfd_section,
05167 (bfd_get_section_flags (abfd,
05168 hdr->bfd_section)
05169 | flags)))
05170 return FALSE;
05171 }
05172
05173
05174
05175
05176
05177
05178
05179 if (hdr->sh_type == SHT_MIPS_REGINFO)
05180 {
05181 Elf32_External_RegInfo ext;
05182 Elf32_RegInfo s;
05183
05184 if (! bfd_get_section_contents (abfd, hdr->bfd_section,
05185 &ext, 0, sizeof ext))
05186 return FALSE;
05187 bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
05188 elf_gp (abfd) = s.ri_gp_value;
05189 }
05190
05191
05192
05193
05194
05195 if (hdr->sh_type == SHT_MIPS_OPTIONS)
05196 {
05197 bfd_byte *contents, *l, *lend;
05198
05199 contents = bfd_malloc (hdr->sh_size);
05200 if (contents == NULL)
05201 return FALSE;
05202 if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents,
05203 0, hdr->sh_size))
05204 {
05205 free (contents);
05206 return FALSE;
05207 }
05208 l = contents;
05209 lend = contents + hdr->sh_size;
05210 while (l + sizeof (Elf_External_Options) <= lend)
05211 {
05212 Elf_Internal_Options intopt;
05213
05214 bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
05215 &intopt);
05216 if (intopt.size < sizeof (Elf_External_Options))
05217 {
05218 (*_bfd_error_handler)
05219 (_("%B: Warning: bad `%s' option size %u smaller than its header"),
05220 abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size);
05221 break;
05222 }
05223 if (ABI_64_P (abfd) && intopt.kind == ODK_REGINFO)
05224 {
05225 Elf64_Internal_RegInfo intreg;
05226
05227 bfd_mips_elf64_swap_reginfo_in
05228 (abfd,
05229 ((Elf64_External_RegInfo *)
05230 (l + sizeof (Elf_External_Options))),
05231 &intreg);
05232 elf_gp (abfd) = intreg.ri_gp_value;
05233 }
05234 else if (intopt.kind == ODK_REGINFO)
05235 {
05236 Elf32_RegInfo intreg;
05237
05238 bfd_mips_elf32_swap_reginfo_in
05239 (abfd,
05240 ((Elf32_External_RegInfo *)
05241 (l + sizeof (Elf_External_Options))),
05242 &intreg);
05243 elf_gp (abfd) = intreg.ri_gp_value;
05244 }
05245 l += intopt.size;
05246 }
05247 free (contents);
05248 }
05249
05250 return TRUE;
05251 }
05252
05253
05254
05255
05256
05257 bfd_boolean
05258 _bfd_mips_elf_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
05259 {
05260 register const char *name;
05261 unsigned int sh_type;
05262
05263 name = bfd_get_section_name (abfd, sec);
05264 sh_type = hdr->sh_type;
05265
05266 if (strcmp (name, ".liblist") == 0)
05267 {
05268 hdr->sh_type = SHT_MIPS_LIBLIST;
05269 hdr->sh_info = sec->size / sizeof (Elf32_Lib);
05270
05271 }
05272 else if (strcmp (name, ".conflict") == 0)
05273 hdr->sh_type = SHT_MIPS_CONFLICT;
05274 else if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) == 0)
05275 {
05276 hdr->sh_type = SHT_MIPS_GPTAB;
05277 hdr->sh_entsize = sizeof (Elf32_External_gptab);
05278
05279 }
05280 else if (strcmp (name, ".ucode") == 0)
05281 hdr->sh_type = SHT_MIPS_UCODE;
05282 else if (strcmp (name, ".mdebug") == 0)
05283 {
05284 hdr->sh_type = SHT_MIPS_DEBUG;
05285
05286
05287 if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0)
05288 hdr->sh_entsize = 0;
05289 else
05290 hdr->sh_entsize = 1;
05291 }
05292 else if (strcmp (name, ".reginfo") == 0)
05293 {
05294 hdr->sh_type = SHT_MIPS_REGINFO;
05295
05296
05297 if (SGI_COMPAT (abfd))
05298 {
05299 if ((abfd->flags & DYNAMIC) != 0)
05300 hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
05301 else
05302 hdr->sh_entsize = 1;
05303 }
05304 else
05305 hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
05306 }
05307 else if (SGI_COMPAT (abfd)
05308 && (strcmp (name, ".hash") == 0
05309 || strcmp (name, ".dynamic") == 0
05310 || strcmp (name, ".dynstr") == 0))
05311 {
05312 if (SGI_COMPAT (abfd))
05313 hdr->sh_entsize = 0;
05314 #if 0
05315
05316 hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES;
05317 #endif
05318 }
05319 else if (strcmp (name, ".got") == 0
05320 || strcmp (name, ".srdata") == 0
05321 || strcmp (name, ".sdata") == 0
05322 || strcmp (name, ".sbss") == 0
05323 || strcmp (name, ".lit4") == 0
05324 || strcmp (name, ".lit8") == 0)
05325 hdr->sh_flags |= SHF_MIPS_GPREL;
05326 else if (strcmp (name, ".MIPS.interfaces") == 0)
05327 {
05328 hdr->sh_type = SHT_MIPS_IFACE;
05329 hdr->sh_flags |= SHF_MIPS_NOSTRIP;
05330 }
05331 else if (strncmp (name, ".MIPS.content", strlen (".MIPS.content")) == 0)
05332 {
05333 hdr->sh_type = SHT_MIPS_CONTENT;
05334 hdr->sh_flags |= SHF_MIPS_NOSTRIP;
05335
05336 }
05337 else if (MIPS_ELF_OPTIONS_SECTION_NAME_P (name))
05338 {
05339 hdr->sh_type = SHT_MIPS_OPTIONS;
05340 hdr->sh_entsize = 1;
05341 hdr->sh_flags |= SHF_MIPS_NOSTRIP;
05342 }
05343 else if (strncmp (name, ".debug_", sizeof ".debug_" - 1) == 0)
05344 hdr->sh_type = SHT_MIPS_DWARF;
05345 else if (strcmp (name, ".MIPS.symlib") == 0)
05346 {
05347 hdr->sh_type = SHT_MIPS_SYMBOL_LIB;
05348
05349
05350 }
05351 else if (strncmp (name, ".MIPS.events", sizeof ".MIPS.events" - 1) == 0
05352 || strncmp (name, ".MIPS.post_rel",
05353 sizeof ".MIPS.post_rel" - 1) == 0)
05354 {
05355 hdr->sh_type = SHT_MIPS_EVENTS;
05356 hdr->sh_flags |= SHF_MIPS_NOSTRIP;
05357
05358 }
05359 else if (strcmp (name, ".msym") == 0)
05360 {
05361 hdr->sh_type = SHT_MIPS_MSYM;
05362 hdr->sh_flags |= SHF_ALLOC;
05363 hdr->sh_entsize = 8;
05364 }
05365
05366
05367
05368
05369 if (sec->size > 0 && !(sec->flags & SEC_HAS_CONTENTS))
05370 hdr->sh_type = sh_type;
05371
05372
05373
05374
05375
05376
05377
05378 return TRUE;
05379 }
05380
05381
05382
05383
05384
05385
05386
05387 bfd_boolean
05388 _bfd_mips_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
05389 asection *sec, int *retval)
05390 {
05391 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
05392 {
05393 *retval = SHN_MIPS_SCOMMON;
05394 return TRUE;
05395 }
05396 if (strcmp (bfd_get_section_name (abfd, sec), ".acommon") == 0)
05397 {
05398 *retval = SHN_MIPS_ACOMMON;
05399 return TRUE;
05400 }
05401 return FALSE;
05402 }
05403
05404
05405
05406
05407 bfd_boolean
05408 _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
05409 Elf_Internal_Sym *sym, const char **namep,
05410 flagword *flagsp ATTRIBUTE_UNUSED,
05411 asection **secp, bfd_vma *valp)
05412 {
05413 if (SGI_COMPAT (abfd)
05414 && (abfd->flags & DYNAMIC) != 0
05415 && strcmp (*namep, "_rld_new_interface") == 0)
05416 {
05417
05418 *namep = NULL;
05419 return TRUE;
05420 }
05421
05422 switch (sym->st_shndx)
05423 {
05424 case SHN_COMMON:
05425
05426
05427 if (sym->st_size > elf_gp_size (abfd)
05428 || IRIX_COMPAT (abfd) == ict_irix6)
05429 break;
05430
05431 case SHN_MIPS_SCOMMON:
05432 *secp = bfd_make_section_old_way (abfd, ".scommon");
05433 (*secp)->flags |= SEC_IS_COMMON;
05434 *valp = sym->st_size;
05435 break;
05436
05437 case SHN_MIPS_TEXT:
05438
05439 if (elf_tdata (abfd)->elf_text_section == NULL)
05440 {
05441 asymbol *elf_text_symbol;
05442 asection *elf_text_section;
05443 bfd_size_type amt = sizeof (asection);
05444
05445 elf_text_section = bfd_zalloc (abfd, amt);
05446 if (elf_text_section == NULL)
05447 return FALSE;
05448
05449 amt = sizeof (asymbol);
05450 elf_text_symbol = bfd_zalloc (abfd, amt);
05451 if (elf_text_symbol == NULL)
05452 return FALSE;
05453
05454
05455
05456 elf_tdata (abfd)->elf_text_section = elf_text_section;
05457 elf_tdata (abfd)->elf_text_symbol = elf_text_symbol;
05458
05459 elf_text_section->symbol = elf_text_symbol;
05460 elf_text_section->symbol_ptr_ptr = &elf_tdata (abfd)->elf_text_symbol;
05461
05462 elf_text_section->name = ".text";
05463 elf_text_section->flags = SEC_NO_FLAGS;
05464 elf_text_section->output_section = NULL;
05465 elf_text_section->owner = abfd;
05466 elf_text_symbol->name = ".text";
05467 elf_text_symbol->flags = BSF_SECTION_SYM | BSF_DYNAMIC;
05468 elf_text_symbol->section = elf_text_section;
05469 }
05470
05471
05472
05473 *secp = elf_tdata (abfd)->elf_text_section;
05474 break;
05475
05476 case SHN_MIPS_ACOMMON:
05477
05478 case SHN_MIPS_DATA:
05479
05480 if (elf_tdata (abfd)->elf_data_section == NULL)
05481 {
05482 asymbol *elf_data_symbol;
05483 asection *elf_data_section;
05484 bfd_size_type amt = sizeof (asection);
05485
05486 elf_data_section = bfd_zalloc (abfd, amt);
05487 if (elf_data_section == NULL)
05488 return FALSE;
05489
05490 amt = sizeof (asymbol);
05491 elf_data_symbol = bfd_zalloc (abfd, amt);
05492 if (elf_data_symbol == NULL)
05493 return FALSE;
05494
05495
05496
05497 elf_tdata (abfd)->elf_data_section = elf_data_section;
05498 elf_tdata (abfd)->elf_data_symbol = elf_data_symbol;
05499
05500 elf_data_section->symbol = elf_data_symbol;
05501 elf_data_section->symbol_ptr_ptr = &elf_tdata (abfd)->elf_data_symbol;
05502
05503 elf_data_section->name = ".data";
05504 elf_data_section->flags = SEC_NO_FLAGS;
05505 elf_data_section->output_section = NULL;
05506 elf_data_section->owner = abfd;
05507 elf_data_symbol->name = ".data";
05508 elf_data_symbol->flags = BSF_SECTION_SYM | BSF_DYNAMIC;
05509 elf_data_symbol->section = elf_data_section;
05510 }
05511
05512
05513
05514 *secp = elf_tdata (abfd)->elf_data_section;
05515 break;
05516
05517 case SHN_MIPS_SUNDEFINED:
05518 *secp = bfd_und_section_ptr;
05519 break;
05520 }
05521
05522 if (SGI_COMPAT (abfd)
05523 && ! info->shared
05524 && info->hash->creator == abfd->xvec
05525 && strcmp (*namep, "__rld_obj_head") == 0)
05526 {
05527 struct elf_link_hash_entry *h;
05528 struct bfd_link_hash_entry *bh;
05529
05530
05531 bh = NULL;
05532 if (! (_bfd_generic_link_add_one_symbol
05533 (info, abfd, *namep, BSF_GLOBAL, *secp, *valp, NULL, FALSE,
05534 get_elf_backend_data (abfd)->collect, &bh)))
05535 return FALSE;
05536
05537 h = (struct elf_link_hash_entry *) bh;
05538 h->non_elf = 0;
05539 h->def_regular = 1;
05540 h->type = STT_OBJECT;
05541
05542 if (! bfd_elf_link_record_dynamic_symbol (info, h))
05543 return FALSE;
05544
05545 mips_elf_hash_table (info)->use_rld_obj_head = TRUE;
05546 }
05547
05548
05549
05550
05551 if (sym->st_other == STO_MIPS16)
05552 ++*valp;
05553
05554 return TRUE;
05555 }
05556
05557
05558
05559
05560
05561 bfd_boolean
05562 _bfd_mips_elf_link_output_symbol_hook
05563 (struct bfd_link_info *info ATTRIBUTE_UNUSED,
05564 const char *name ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym,
05565 asection *input_sec, struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
05566 {
05567
05568
05569
05570 if (sym->st_shndx == SHN_COMMON
05571 && strcmp (input_sec->name, ".scommon") == 0)
05572 sym->st_shndx = SHN_MIPS_SCOMMON;
05573
05574 if (sym->st_other == STO_MIPS16)
05575 sym->st_value &= ~1;
05576
05577 return TRUE;
05578 }
05579
05580
05581
05582
05583
05584 bfd_boolean
05585 _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
05586 {
05587 struct elf_link_hash_entry *h;
05588 struct bfd_link_hash_entry *bh;
05589 flagword flags;
05590 register asection *s;
05591 const char * const *namep;
05592
05593 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
05594 | SEC_LINKER_CREATED | SEC_READONLY);
05595
05596
05597 s = bfd_get_section_by_name (abfd, ".dynamic");
05598 if (s != NULL)
05599 {
05600 if (! bfd_set_section_flags (abfd, s, flags))
05601 return FALSE;
05602 }
05603
05604
05605 if (! mips_elf_create_got_section (abfd, info, FALSE))
05606 return FALSE;
05607
05608 if (! mips_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
05609 return FALSE;
05610
05611
05612 if (bfd_get_section_by_name (abfd,
05613 MIPS_ELF_STUB_SECTION_NAME (abfd)) == NULL)
05614 {
05615 s = bfd_make_section (abfd, MIPS_ELF_STUB_SECTION_NAME (abfd));
05616 if (s == NULL
05617 || ! bfd_set_section_flags (abfd, s, flags | SEC_CODE)
05618 || ! bfd_set_section_alignment (abfd, s,
05619 MIPS_ELF_LOG_FILE_ALIGN (abfd)))
05620 return FALSE;
05621 }
05622
05623 if ((IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none)
05624 && !info->shared
05625 && bfd_get_section_by_name (abfd, ".rld_map") == NULL)
05626 {
05627 s = bfd_make_section (abfd, ".rld_map");
05628 if (s == NULL
05629 || ! bfd_set_section_flags (abfd, s, flags &~ (flagword) SEC_READONLY)
05630 || ! bfd_set_section_alignment (abfd, s,
05631 MIPS_ELF_LOG_FILE_ALIGN (abfd)))
05632 return FALSE;
05633 }
05634
05635
05636
05637
05638
05639 if (IRIX_COMPAT (abfd) == ict_irix5)
05640 {
05641 for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++)
05642 {
05643 bh = NULL;
05644 if (! (_bfd_generic_link_add_one_symbol
05645 (info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr, 0,
05646 NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
05647 return FALSE;
05648
05649 h = (struct elf_link_hash_entry *) bh;
05650 h->non_elf = 0;
05651 h->def_regular = 1;
05652 h->type = STT_SECTION;
05653
05654 if (! bfd_elf_link_record_dynamic_symbol (info, h))
05655 return FALSE;
05656 }
05657
05658
05659 if (SGI_COMPAT (abfd))
05660 {
05661 if (!mips_elf_create_compact_rel_section (abfd, info))
05662 return FALSE;
05663 }
05664
05665
05666 s = bfd_get_section_by_name (abfd, ".hash");
05667 if (s != NULL)
05668 bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
05669 s = bfd_get_section_by_name (abfd, ".dynsym");
05670 if (s != NULL)
05671 bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
05672 s = bfd_get_section_by_name (abfd, ".dynstr");
05673 if (s != NULL)
05674 bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
05675 s = bfd_get_section_by_name (abfd, ".reginfo");
05676 if (s != NULL)
05677 bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
05678 s = bfd_get_section_by_name (abfd, ".dynamic");
05679 if (s != NULL)
05680 bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
05681 }
05682
05683 if (!info->shared)
05684 {
05685 const char *name;
05686
05687 name = SGI_COMPAT (abfd) ? "_DYNAMIC_LINK" : "_DYNAMIC_LINKING";
05688 bh = NULL;
05689 if (!(_bfd_generic_link_add_one_symbol
05690 (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr, 0,
05691 NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
05692 return FALSE;
05693
05694 h = (struct elf_link_hash_entry *) bh;
05695 h->non_elf = 0;
05696 h->def_regular = 1;
05697 h->type = STT_SECTION;
05698
05699 if (! bfd_elf_link_record_dynamic_symbol (info, h))
05700 return FALSE;
05701
05702 if (! mips_elf_hash_table (info)->use_rld_obj_head)
05703 {
05704
05705
05706
05707
05708 s = bfd_get_section_by_name (abfd, ".rld_map");
05709 BFD_ASSERT (s != NULL);
05710
05711 name = SGI_COMPAT (abfd) ? "__rld_map" : "__RLD_MAP";
05712 bh = NULL;
05713 if (!(_bfd_generic_link_add_one_symbol
05714 (info, abfd, name, BSF_GLOBAL, s, 0, NULL, FALSE,
05715 get_elf_backend_data (abfd)->collect, &bh)))
05716 return FALSE;
05717
05718 h = (struct elf_link_hash_entry *) bh;
05719 h->non_elf = 0;
05720 h->def_regular = 1;
05721 h->type = STT_OBJECT;
05722
05723 if (! bfd_elf_link_record_dynamic_symbol (info, h))
05724 return FALSE;
05725 }
05726 }
05727
05728 return TRUE;
05729 }
05730
05731
05732
05733
05734 bfd_boolean
05735 _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
05736 asection *sec, const Elf_Internal_Rela *relocs)
05737 {
05738 const char *name;
05739 bfd *dynobj;
05740 Elf_Internal_Shdr *symtab_hdr;
05741 struct elf_link_hash_entry **sym_hashes;
05742 struct mips_got_info *g;
05743 size_t extsymoff;
05744 const Elf_Internal_Rela *rel;
05745 const Elf_Internal_Rela *rel_end;
05746 asection *sgot;
05747 asection *sreloc;
05748 const struct elf_backend_data *bed;
05749
05750 if (info->relocatable)
05751 return TRUE;
05752
05753 dynobj = elf_hash_table (info)->dynobj;
05754 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
05755 sym_hashes = elf_sym_hashes (abfd);
05756 extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
05757
05758
05759
05760 name = bfd_get_section_name (abfd, sec);
05761 if (strncmp (name, FN_STUB, sizeof FN_STUB - 1) == 0)
05762 {
05763 unsigned long r_symndx;
05764
05765
05766
05767
05768 r_symndx = ELF_R_SYM (abfd, relocs->r_info);
05769
05770 if (r_symndx < extsymoff
05771 || sym_hashes[r_symndx - extsymoff] == NULL)
05772 {
05773 asection *o;
05774
05775
05776
05777
05778 for (o = abfd->sections; o != NULL; o = o->next)
05779 {
05780 Elf_Internal_Rela *sec_relocs;
05781 const Elf_Internal_Rela *r, *rend;
05782
05783
05784 if ((o->flags & SEC_RELOC) == 0
05785 || o->reloc_count == 0
05786 || strncmp (bfd_get_section_name (abfd, o), FN_STUB,
05787 sizeof FN_STUB - 1) == 0
05788 || strncmp (bfd_get_section_name (abfd, o), CALL_STUB,
05789 sizeof CALL_STUB - 1) == 0
05790 || strncmp (bfd_get_section_name (abfd, o), CALL_FP_STUB,
05791 sizeof CALL_FP_STUB - 1) == 0)
05792 continue;
05793
05794 sec_relocs
05795 = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
05796 info->keep_memory);
05797 if (sec_relocs == NULL)
05798 return FALSE;
05799
05800 rend = sec_relocs + o->reloc_count;
05801 for (r = sec_relocs; r < rend; r++)
05802 if (ELF_R_SYM (abfd, r->r_info) == r_symndx
05803 && ELF_R_TYPE (abfd, r->r_info) != R_MIPS16_26)
05804 break;
05805
05806 if (elf_section_data (o)->relocs != sec_relocs)
05807 free (sec_relocs);
05808
05809 if (r < rend)
05810 break;
05811 }
05812
05813 if (o == NULL)
05814 {
05815
05816
05817
05818
05819
05820 sec->flags |= SEC_EXCLUDE;
05821 return TRUE;
05822 }
05823
05824
05825
05826 if (elf_tdata (abfd)->local_stubs == NULL)
05827 {
05828 unsigned long symcount;
05829 asection **n;
05830 bfd_size_type amt;
05831
05832 if (elf_bad_symtab (abfd))
05833 symcount = NUM_SHDR_ENTRIES (symtab_hdr);
05834 else
05835 symcount = symtab_hdr->sh_info;
05836 amt = symcount * sizeof (asection *);
05837 n = bfd_zalloc (abfd, amt);
05838 if (n == NULL)
05839 return FALSE;
05840 elf_tdata (abfd)->local_stubs = n;
05841 }
05842
05843 elf_tdata (abfd)->local_stubs[r_symndx] = sec;
05844
05845
05846
05847
05848
05849 }
05850 else
05851 {
05852 struct mips_elf_link_hash_entry *h;
05853
05854 h = ((struct mips_elf_link_hash_entry *)
05855 sym_hashes[r_symndx - extsymoff]);
05856
05857
05858
05859 h->fn_stub = sec;
05860 mips_elf_hash_table (info)->mips16_stubs_seen = TRUE;
05861 }
05862 }
05863 else if (strncmp (name, CALL_STUB, sizeof CALL_STUB - 1) == 0
05864 || strncmp (name, CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0)
05865 {
05866 unsigned long r_symndx;
05867 struct mips_elf_link_hash_entry *h;
05868 asection **loc;
05869
05870
05871
05872
05873 r_symndx = ELF_R_SYM (abfd, relocs->r_info);
05874
05875 if (r_symndx < extsymoff
05876 || sym_hashes[r_symndx - extsymoff] == NULL)
05877 {
05878
05879
05880
05881
05882
05883
05884 sec->flags |= SEC_EXCLUDE;
05885 return TRUE;
05886 }
05887
05888 h = ((struct mips_elf_link_hash_entry *)
05889 sym_hashes[r_symndx - extsymoff]);
05890
05891
05892
05893 if (strncmp (name, CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0)
05894 loc = &h->call_fp_stub;
05895 else
05896 loc = &h->call_stub;
05897
05898
05899
05900
05901
05902
05903
05904
05905
05906 if (*loc != NULL || h->root.other == STO_MIPS16)
05907 {
05908 sec->flags |= SEC_EXCLUDE;
05909 return TRUE;
05910 }
05911
05912 *loc = sec;
05913 mips_elf_hash_table (info)->mips16_stubs_seen = TRUE;
05914 }
05915
05916 if (dynobj == NULL)
05917 {
05918 sgot = NULL;
05919 g = NULL;
05920 }
05921 else
05922 {
05923 sgot = mips_elf_got_section (dynobj, FALSE);
05924 if (sgot == NULL)
05925 g = NULL;
05926 else
05927 {
05928 BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
05929 g = mips_elf_section_data (sgot)->u.got_info;
05930 BFD_ASSERT (g != NULL);
05931 }
05932 }
05933
05934 sreloc = NULL;
05935 bed = get_elf_backend_data (abfd);
05936 rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
05937 for (rel = relocs; rel < rel_end; ++rel)
05938 {
05939 unsigned long r_symndx;
05940 unsigned int r_type;
05941 struct elf_link_hash_entry *h;
05942
05943 r_symndx = ELF_R_SYM (abfd, rel->r_info);
05944 r_type = ELF_R_TYPE (abfd, rel->r_info);
05945
05946 if (r_symndx < extsymoff)
05947 h = NULL;
05948 else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
05949 {
05950 (*_bfd_error_handler)
05951 (_("%B: Malformed reloc detected for section %s"),
05952 abfd, name);
05953 bfd_set_error (bfd_error_bad_value);
05954 return FALSE;
05955 }
05956 else
05957 {
05958 h = sym_hashes[r_symndx - extsymoff];
05959
05960
05961 if (h != NULL)
05962 {
05963 while (h->root.type == bfd_link_hash_indirect)
05964 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05965 }
05966 }
05967
05968
05969 if (dynobj == NULL || sgot == NULL)
05970 {
05971 switch (r_type)
05972 {
05973 case R_MIPS_GOT16:
05974 case R_MIPS_CALL16:
05975 case R_MIPS_CALL_HI16:
05976 case R_MIPS_CALL_LO16:
05977 case R_MIPS_GOT_HI16:
05978 case R_MIPS_GOT_LO16:
05979 case R_MIPS_GOT_PAGE:
05980 case R_MIPS_GOT_OFST:
05981 case R_MIPS_GOT_DISP:
05982 case R_MIPS_TLS_GD:
05983 case R_MIPS_TLS_LDM:
05984 if (dynobj == NULL)
05985 elf_hash_table (info)->dynobj = dynobj = abfd;
05986 if (! mips_elf_create_got_section (dynobj, info, FALSE))
05987 return FALSE;
05988 g = mips_elf_got_info (dynobj, &sgot);
05989 break;
05990
05991 case R_MIPS_32:
05992 case R_MIPS_REL32:
05993 case R_MIPS_64:
05994 if (dynobj == NULL
05995 && (info->shared || h != NULL)
05996 && (sec->flags & SEC_ALLOC) != 0)
05997 elf_hash_table (info)->dynobj = dynobj = abfd;
05998 break;
05999
06000 default:
06001 break;
06002 }
06003 }
06004
06005 if (!h && (r_type == R_MIPS_CALL_LO16
06006 || r_type == R_MIPS_GOT_LO16
06007 || r_type == R_MIPS_GOT_DISP))
06008 {
06009
06010
06011
06012
06013
06014
06015
06016 if (! mips_elf_record_local_got_symbol (abfd, r_symndx,
06017 rel->r_addend, g, 0))
06018 return FALSE;
06019 }
06020
06021 switch (r_type)
06022 {
06023 case R_MIPS_CALL16:
06024 if (h == NULL)
06025 {
06026 (*_bfd_error_handler)
06027 (_("%B: CALL16 reloc at 0x%lx not against global symbol"),
06028 abfd, (unsigned long) rel->r_offset);
06029 bfd_set_error (bfd_error_bad_value);
06030 return FALSE;
06031 }
06032
06033
06034 case R_MIPS_CALL_HI16:
06035 case R_MIPS_CALL_LO16:
06036 if (h != NULL)
06037 {
06038
06039 if (! mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
06040 return FALSE;
06041
06042
06043
06044
06045 h->needs_plt = 1;
06046 h->type = STT_FUNC;
06047 }
06048 break;
06049
06050 case R_MIPS_GOT_PAGE:
06051
06052
06053 if (h == NULL)
06054 break;
06055 else
06056 {
06057 struct mips_elf_link_hash_entry *hmips =
06058 (struct mips_elf_link_hash_entry *) h;
06059
06060 while (hmips->root.root.type == bfd_link_hash_indirect
06061 || hmips->root.root.type == bfd_link_hash_warning)
06062 hmips = (struct mips_elf_link_hash_entry *)
06063 hmips->root.root.u.i.link;
06064
06065 if (hmips->root.def_regular
06066 && ! (info->shared && ! info->symbolic
06067 && ! hmips->root.forced_local))
06068 break;
06069 }
06070
06071
06072 case R_MIPS_GOT16:
06073 case R_MIPS_GOT_HI16:
06074 case R_MIPS_GOT_LO16:
06075 case R_MIPS_GOT_DISP:
06076 if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
06077 return FALSE;
06078 break;
06079
06080 case R_MIPS_TLS_GOTTPREL:
06081 if (info->shared)
06082 info->flags |= DF_STATIC_TLS;
06083
06084
06085 case R_MIPS_TLS_LDM:
06086 if (r_type == R_MIPS_TLS_LDM)
06087 {
06088 r_symndx = 0;
06089 h = NULL;
06090 }
06091
06092
06093 case R_MIPS_TLS_GD:
06094
06095
06096 {
06097 unsigned char flag = (r_type == R_MIPS_TLS_GD
06098 ? GOT_TLS_GD
06099 : r_type == R_MIPS_TLS_LDM
06100 ? GOT_TLS_LDM
06101 : GOT_TLS_IE);
06102 if (h != NULL)
06103 {
06104 struct mips_elf_link_hash_entry *hmips =
06105 (struct mips_elf_link_hash_entry *) h;
06106 hmips->tls_type |= flag;
06107
06108 if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, flag))
06109 return FALSE;
06110 }
06111 else
06112 {
06113 BFD_ASSERT (flag == GOT_TLS_LDM || r_symndx != 0);
06114
06115 if (! mips_elf_record_local_got_symbol (abfd, r_symndx,
06116 rel->r_addend, g, flag))
06117 return FALSE;
06118 }
06119 }
06120 break;
06121
06122 case R_MIPS_32:
06123 case R_MIPS_REL32:
06124 case R_MIPS_64:
06125 if ((info->shared || h != NULL)
06126 && (sec->flags & SEC_ALLOC) != 0)
06127 {
06128 if (sreloc == NULL)
06129 {
06130 sreloc = mips_elf_rel_dyn_section (dynobj, TRUE);
06131 if (sreloc == NULL)
06132 return FALSE;
06133 }
06134 #define MIPS_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
06135 if (info->shared)
06136 {
06137
06138
06139
06140
06141 mips_elf_allocate_dynamic_relocations (dynobj, 1);
06142 if ((sec->flags & MIPS_READONLY_SECTION)
06143 == MIPS_READONLY_SECTION)
06144
06145
06146 info->flags |= DF_TEXTREL;
06147 }
06148 else
06149 {
06150 struct mips_elf_link_hash_entry *hmips;
06151
06152
06153
06154 hmips = (struct mips_elf_link_hash_entry *) h;
06155 ++hmips->possibly_dynamic_relocs;
06156 if ((sec->flags & MIPS_READONLY_SECTION)
06157 == MIPS_READONLY_SECTION)
06158
06159
06160 hmips->readonly_reloc = TRUE;
06161 }
06162
06163
06164
06165
06166
06167 if (h != NULL)
06168 {
06169 if (dynobj == NULL)
06170 elf_hash_table (info)->dynobj = dynobj = abfd;
06171 if (! mips_elf_create_got_section (dynobj, info, TRUE))
06172 return FALSE;
06173 g = mips_elf_got_info (dynobj, &sgot);
06174 if (! mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
06175 return FALSE;
06176 }
06177 }
06178
06179 if (SGI_COMPAT (abfd))
06180 mips_elf_hash_table (info)->compact_rel_size +=
06181 sizeof (Elf32_External_crinfo);
06182 break;
06183
06184 case R_MIPS_26:
06185 case R_MIPS_GPREL16:
06186 case R_MIPS_LITERAL:
06187 case R_MIPS_GPREL32:
06188 if (SGI_COMPAT (abfd))
06189 mips_elf_hash_table (info)->compact_rel_size +=
06190 sizeof (Elf32_External_crinfo);
06191 break;
06192
06193
06194
06195 case R_MIPS_GNU_VTINHERIT:
06196 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
06197 return FALSE;
06198 break;
06199
06200
06201
06202 case R_MIPS_GNU_VTENTRY:
06203 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
06204 return FALSE;
06205 break;
06206
06207 default:
06208 break;
06209 }
06210
06211
06212
06213 switch (r_type)
06214 {
06215 default:
06216 if (h != NULL)
06217 {
06218 struct mips_elf_link_hash_entry *mh;
06219
06220 mh = (struct mips_elf_link_hash_entry *) h;
06221 mh->no_fn_stub = TRUE;
06222 }
06223 break;
06224 case R_MIPS_CALL16:
06225 case R_MIPS_CALL_HI16:
06226 case R_MIPS_CALL_LO16:
06227 case R_MIPS_JALR:
06228 break;
06229 }
06230
06231
06232
06233
06234 if (h != NULL
06235 && r_type != R_MIPS16_26
06236 && strncmp (bfd_get_section_name (abfd, sec), FN_STUB,
06237 sizeof FN_STUB - 1) != 0
06238 && strncmp (bfd_get_section_name (abfd, sec), CALL_STUB,
06239 sizeof CALL_STUB - 1) != 0
06240 && strncmp (bfd_get_section_name (abfd, sec), CALL_FP_STUB,
06241 sizeof CALL_FP_STUB - 1) != 0)
06242 {
06243 struct mips_elf_link_hash_entry *mh;
06244
06245 mh = (struct mips_elf_link_hash_entry *) h;
06246 mh->need_fn_stub = TRUE;
06247 }
06248 }
06249
06250 return TRUE;
06251 }
06252
06253 bfd_boolean
06254 _bfd_mips_relax_section (bfd *abfd, asection *sec,
06255 struct bfd_link_info *link_info,
06256 bfd_boolean *again)
06257 {
06258 Elf_Internal_Rela *internal_relocs;
06259 Elf_Internal_Rela *irel, *irelend;
06260 Elf_Internal_Shdr *symtab_hdr;
06261 bfd_byte *contents = NULL;
06262 size_t extsymoff;
06263 bfd_boolean changed_contents = FALSE;
06264 bfd_vma sec_start = sec->output_section->vma + sec->output_offset;
06265 Elf_Internal_Sym *isymbuf = NULL;
06266
06267
06268 *again = FALSE;
06269
06270 if (link_info->relocatable)
06271 return TRUE;
06272
06273 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
06274 link_info->keep_memory);
06275 if (internal_relocs == NULL)
06276 return TRUE;
06277
06278 irelend = internal_relocs + sec->reloc_count
06279 * get_elf_backend_data (abfd)->s->int_rels_per_ext_rel;
06280 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
06281 extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
06282
06283 for (irel = internal_relocs; irel < irelend; irel++)
06284 {
06285 bfd_vma symval;
06286 bfd_signed_vma sym_offset;
06287 unsigned int r_type;
06288 unsigned long r_symndx;
06289 asection *sym_sec;
06290 unsigned long instruction;
06291
06292
06293
06294
06295 r_type = ELF_R_TYPE (abfd, irel->r_info);
06296 if (r_type != R_MIPS_JALR)
06297 continue;
06298
06299 r_symndx = ELF_R_SYM (abfd, irel->r_info);
06300
06301 if (r_symndx >= extsymoff)
06302 {
06303 struct mips_elf_link_hash_entry *h
06304 = ((struct mips_elf_link_hash_entry *)
06305 elf_sym_hashes (abfd) [r_symndx - extsymoff]);
06306
06307 while (h->root.root.type == bfd_link_hash_indirect
06308 || h->root.root.type == bfd_link_hash_warning)
06309 h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
06310
06311
06312
06313 if (! ((h->root.root.type == bfd_link_hash_defined
06314 || h->root.root.type == bfd_link_hash_defweak)
06315 && h->root.root.u.def.section)
06316 || (link_info->shared && ! link_info->symbolic
06317 && !h->root.forced_local))
06318 continue;
06319
06320 sym_sec = h->root.root.u.def.section;
06321 if (sym_sec->output_section)
06322 symval = (h->root.root.u.def.value
06323 + sym_sec->output_section->vma
06324 + sym_sec->output_offset);
06325 else
06326 symval = h->root.root.u.def.value;
06327 }
06328 else
06329 {
06330 Elf_Internal_Sym *isym;
06331
06332
06333 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
06334 {
06335 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
06336 if (isymbuf == NULL)
06337 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
06338 symtab_hdr->sh_info, 0,
06339 NULL, NULL, NULL);
06340 if (isymbuf == NULL)
06341 goto relax_return;
06342 }
06343
06344 isym = isymbuf + r_symndx;
06345 if (isym->st_shndx == SHN_UNDEF)
06346 continue;
06347 else if (isym->st_shndx == SHN_ABS)
06348 sym_sec = bfd_abs_section_ptr;
06349 else if (isym->st_shndx == SHN_COMMON)
06350 sym_sec = bfd_com_section_ptr;
06351 else
06352 sym_sec
06353 = bfd_section_from_elf_index (abfd, isym->st_shndx);
06354 symval = isym->st_value
06355 + sym_sec->output_section->vma
06356 + sym_sec->output_offset;
06357 }
06358
06359
06360
06361 sym_offset = (symval + irel->r_addend)
06362 - (sec_start + irel->r_offset + 4);
06363
06364
06365 if ((sym_offset & 3) != 0)
06366 continue;
06367
06368 sym_offset >>= 2;
06369
06370
06371 if (sym_offset < -0x8000 || sym_offset >= 0x8000)
06372 continue;
06373
06374
06375 if (contents == NULL)
06376 {
06377
06378 if (elf_section_data (sec)->this_hdr.contents != NULL)
06379 contents = elf_section_data (sec)->this_hdr.contents;
06380 else
06381 {
06382 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
06383 goto relax_return;
06384 }
06385 }
06386
06387 instruction = bfd_get_32 (abfd, contents + irel->r_offset);
06388
06389
06390 if ((instruction & 0xfc1fffff) == 0x0000f809)
06391 instruction = 0x04110000;
06392
06393 else if ((instruction & 0xfc1fffff) == 0x00000008)
06394 instruction = 0x10000000;
06395 else
06396 continue;
06397
06398 instruction |= (sym_offset & 0xffff);
06399 bfd_put_32 (abfd, instruction, contents + irel->r_offset);
06400 changed_contents = TRUE;
06401 }
06402
06403 if (contents != NULL
06404 && elf_section_data (sec)->this_hdr.contents != contents)
06405 {
06406 if (!changed_contents && !link_info->keep_memory)
06407 free (contents);
06408 else
06409 {
06410
06411 elf_section_data (sec)->this_hdr.contents = contents;
06412 }
06413 }
06414 return TRUE;
06415
06416 relax_return:
06417 if (contents != NULL
06418 && elf_section_data (sec)->this_hdr.contents != contents)
06419 free (contents);
06420 return FALSE;
06421 }
06422
06423
06424
06425
06426
06427
06428
06429 bfd_boolean
06430 _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
06431 struct elf_link_hash_entry *h)
06432 {
06433 bfd *dynobj;
06434 struct mips_elf_link_hash_entry *hmips;
06435 asection *s;
06436
06437 dynobj = elf_hash_table (info)->dynobj;
06438
06439
06440 BFD_ASSERT (dynobj != NULL
06441 && (h->needs_plt
06442 || h->u.weakdef != NULL
06443 || (h->def_dynamic
06444 && h->ref_regular
06445 && !h->def_regular)));
06446
06447
06448
06449
06450 hmips = (struct mips_elf_link_hash_entry *) h;
06451 if (! info->relocatable
06452 && hmips->possibly_dynamic_relocs != 0
06453 && (h->root.type == bfd_link_hash_defweak
06454 || !h->def_regular))
06455 {
06456 mips_elf_allocate_dynamic_relocations (dynobj,
06457 hmips->possibly_dynamic_relocs);
06458 if (hmips->readonly_reloc)
06459
06460
06461 info->flags |= DF_TEXTREL;
06462 }
06463
06464
06465 if (! hmips->no_fn_stub
06466 && h->needs_plt)
06467 {
06468 if (! elf_hash_table (info)->dynamic_sections_created)
06469 return TRUE;
06470
06471
06472
06473
06474
06475 if (!h->def_regular)
06476 {
06477
06478 s = bfd_get_section_by_name (dynobj,
06479 MIPS_ELF_STUB_SECTION_NAME (dynobj));
06480 BFD_ASSERT (s != NULL);
06481
06482 h->root.u.def.section = s;
06483 h->root.u.def.value = s->size;
06484
06485
06486 h->plt.offset = s->size;
06487
06488
06489 s->size += MIPS_FUNCTION_STUB_SIZE;
06490
06491
06492
06493 return TRUE;
06494 }
06495 }
06496 else if ((h->type == STT_FUNC)
06497 && !h->needs_plt)
06498 {
06499
06500
06501 h->root.u.def.value = 0;
06502 return TRUE;
06503 }
06504
06505
06506
06507
06508 if (h->u.weakdef != NULL)
06509 {
06510 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
06511 || h->u.weakdef->root.type == bfd_link_hash_defweak);
06512 h->root.u.def.section = h->u.weakdef->root.u.def.section;
06513 h->root.u.def.value = h->u.weakdef->root.u.def.value;
06514 return TRUE;
06515 }
06516
06517
06518
06519
06520 return TRUE;
06521 }
06522
06523
06524
06525
06526
06527 bfd_boolean
06528 _bfd_mips_elf_always_size_sections (bfd *output_bfd,
06529 struct bfd_link_info *info)
06530 {
06531 asection *ri;
06532
06533 bfd *dynobj;
06534 asection *s;
06535 struct mips_got_info *g;
06536 int i;
06537 bfd_size_type loadable_size = 0;
06538 bfd_size_type local_gotno;
06539 bfd *sub;
06540 struct mips_elf_count_tls_arg count_tls_arg;
06541
06542
06543 ri = bfd_get_section_by_name (output_bfd, ".reginfo");
06544 if (ri != NULL)
06545 bfd_set_section_size (output_bfd, ri, sizeof (Elf32_External_RegInfo));
06546
06547 if (! (info->relocatable
06548 || ! mips_elf_hash_table (info)->mips16_stubs_seen))
06549 mips_elf_link_hash_traverse (mips_elf_hash_table (info),
06550 mips_elf_check_mips16_stubs, NULL);
06551
06552 dynobj = elf_hash_table (info)->dynobj;
06553 if (dynobj == NULL)
06554
06555 return TRUE;
06556
06557 g = mips_elf_got_info (dynobj, &s);
06558 if (s == NULL)
06559 return TRUE;
06560
06561
06562
06563
06564 for (sub = info->input_bfds; sub; sub = sub->link_next)
06565 {
06566 asection *subsection;
06567
06568 for (subsection = sub->sections;
06569 subsection;
06570 subsection = subsection->next)
06571 {
06572 if ((subsection->flags & SEC_ALLOC) == 0)
06573 continue;
06574 loadable_size += ((subsection->size + 0xf)
06575 &~ (bfd_size_type) 0xf);
06576 }
06577 }
06578
06579
06580
06581
06582
06583
06584 if (! mips_elf_sort_hash_table (info, 1))
06585 return FALSE;
06586
06587 if (g->global_gotsym != NULL)
06588 i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
06589 else
06590
06591
06592 i = 0;
06593
06594
06595
06596
06597 loadable_size += MIPS_FUNCTION_STUB_SIZE * (i + 1);
06598
06599
06600
06601 local_gotno = (loadable_size >> 16) + 5;
06602
06603 g->local_gotno += local_gotno;
06604 s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
06605
06606 g->global_gotno = i;
06607 s->size += i * MIPS_ELF_GOT_SIZE (output_bfd);
06608
06609
06610
06611
06612 count_tls_arg.info = info;
06613 count_tls_arg.needed = 0;
06614 elf_link_hash_traverse (elf_hash_table (info),
06615 mips_elf_count_global_tls_entries,
06616 &count_tls_arg);
06617 g->tls_gotno += count_tls_arg.needed;
06618 s->size += g->tls_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
06619
06620 mips_elf_resolve_final_got_entries (g);
06621
06622 if (s->size > MIPS_ELF_GOT_MAX_SIZE (output_bfd))
06623 {
06624 if (! mips_elf_multi_got (output_bfd, info, g, s, local_gotno))
06625 return FALSE;
06626 }
06627 else
06628 {
06629
06630 g->tls_assigned_gotno = g->global_gotno + g->local_gotno;
06631 htab_traverse (g->got_entries, mips_elf_initialize_tls_index, g);
06632 }
06633
06634 return TRUE;
06635 }
06636
06637
06638
06639 bfd_boolean
06640 _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
06641 struct bfd_link_info *info)
06642 {
06643 bfd *dynobj;
06644 asection *s;
06645 bfd_boolean reltext;
06646
06647 dynobj = elf_hash_table (info)->dynobj;
06648 BFD_ASSERT (dynobj != NULL);
06649
06650 if (elf_hash_table (info)->dynamic_sections_created)
06651 {
06652
06653 if (info->executable)
06654 {
06655 s = bfd_get_section_by_name (dynobj, ".interp");
06656 BFD_ASSERT (s != NULL);
06657 s->size
06658 = strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1;
06659 s->contents
06660 = (bfd_byte *) ELF_DYNAMIC_INTERPRETER (output_bfd);
06661 }
06662 }
06663
06664
06665
06666
06667 reltext = FALSE;
06668 for (s = dynobj->sections; s != NULL; s = s->next)
06669 {
06670 const char *name;
06671 bfd_boolean strip;
06672
06673
06674
06675 name = bfd_get_section_name (dynobj, s);
06676
06677 if ((s->flags & SEC_LINKER_CREATED) == 0)
06678 continue;
06679
06680 strip = FALSE;
06681
06682 if (strncmp (name, ".rel", 4) == 0)
06683 {
06684 if (s->size == 0)
06685 {
06686
06687
06688
06689
06690
06691 if (s->output_section != NULL
06692 && strcmp (name,
06693 bfd_get_section_name (s->output_section->owner,
06694 s->output_section)) == 0)
06695 strip = TRUE;
06696 }
06697 else
06698 {
06699 const char *outname;
06700 asection *target;
06701
06702
06703
06704
06705
06706
06707
06708 outname = bfd_get_section_name (output_bfd,
06709 s->output_section);
06710 target = bfd_get_section_by_name (output_bfd, outname + 4);
06711 if ((target != NULL
06712 && (target->flags & SEC_READONLY) != 0
06713 && (target->flags & SEC_ALLOC) != 0)
06714 || strcmp (outname, ".rel.dyn") == 0)
06715 reltext = TRUE;
06716
06717
06718
06719 if (strcmp (name, ".rel.dyn") != 0)
06720 s->reloc_count = 0;
06721
06722
06723
06724
06725
06726
06727
06728 info->combreloc = 0;
06729 }
06730 }
06731 else if (strncmp (name, ".got", 4) == 0)
06732 {
06733
06734
06735
06736
06737 struct mips_got_info *gg = mips_elf_got_info (dynobj, NULL);
06738 struct mips_got_info *g = gg;
06739 struct mips_elf_set_global_got_offset_arg set_got_offset_arg;
06740 unsigned int needed_relocs = 0;
06741
06742 if (gg->next)
06743 {
06744 set_got_offset_arg.value = MIPS_ELF_GOT_SIZE (output_bfd);
06745 set_got_offset_arg.info = info;
06746
06747
06748
06749
06750 mips_elf_resolve_final_got_entries (gg);
06751 for (g = gg->next; g && g->next != gg; g = g->next)
06752 {
06753 unsigned int save_assign;
06754
06755 mips_elf_resolve_final_got_entries (g);
06756
06757
06758 save_assign = g->assigned_gotno;
06759 g->assigned_gotno = g->local_gotno;
06760 set_got_offset_arg.g = g;
06761 set_got_offset_arg.needed_relocs = 0;
06762 htab_traverse (g->got_entries,
06763 mips_elf_set_global_got_offset,
06764 &set_got_offset_arg);
06765 needed_relocs += set_got_offset_arg.needed_relocs;
06766 BFD_ASSERT (g->assigned_gotno - g->local_gotno
06767 <= g->global_gotno);
06768
06769 g->assigned_gotno = save_assign;
06770 if (info->shared)
06771 {
06772 needed_relocs += g->local_gotno - g->assigned_gotno;
06773 BFD_ASSERT (g->assigned_gotno == g->next->local_gotno
06774 + g->next->global_gotno
06775 + g->next->tls_gotno
06776 + MIPS_RESERVED_GOTNO);
06777 }
06778 }
06779 }
06780 else
06781 {
06782 struct mips_elf_count_tls_arg arg;
06783 arg.info = info;
06784 arg.needed = 0;
06785
06786 htab_traverse (gg->got_entries, mips_elf_count_local_tls_relocs,
06787 &arg);
06788 elf_link_hash_traverse (elf_hash_table (info),
06789 mips_elf_count_global_tls_relocs,
06790 &arg);
06791
06792 needed_relocs += arg.needed;
06793 }
06794
06795 if (needed_relocs)
06796 mips_elf_allocate_dynamic_relocations (dynobj, needed_relocs);
06797 }
06798 else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0)
06799 {
06800
06801
06802 s->size += MIPS_FUNCTION_STUB_SIZE;
06803 }
06804 else if (! info->shared
06805 && ! mips_elf_hash_table (info)->use_rld_obj_head
06806 && strncmp (name, ".rld_map", 8) == 0)
06807 {
06808
06809
06810 s->size += 4;
06811 }
06812 else if (SGI_COMPAT (output_bfd)
06813 && strncmp (name, ".compact_rel", 12) == 0)
06814 s->size += mips_elf_hash_table (info)->compact_rel_size;
06815 else if (strncmp (name, ".init", 5) != 0)
06816 {
06817
06818 continue;
06819 }
06820
06821 if (strip)
06822 {
06823 _bfd_strip_section_from_output (info, s);
06824 continue;
06825 }
06826
06827
06828 s->contents = bfd_zalloc (dynobj, s->size);
06829 if (s->contents == NULL && s->size != 0)
06830 {
06831 bfd_set_error (bfd_error_no_memory);
06832 return FALSE;
06833 }
06834 }
06835
06836 if (elf_hash_table (info)->dynamic_sections_created)
06837 {
06838
06839
06840
06841
06842
06843 if (! info->shared)
06844 {
06845
06846
06847 if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0))
06848 return FALSE;
06849 if (!SGI_COMPAT (output_bfd))
06850 {
06851 if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
06852 return FALSE;
06853 }
06854 }
06855 else
06856 {
06857
06858 if (!SGI_COMPAT (output_bfd))
06859 {
06860 if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
06861 return FALSE;
06862 }
06863 }
06864
06865 if (reltext && SGI_COMPAT (output_bfd))
06866 info->flags |= DF_TEXTREL;
06867
06868 if ((info->flags & DF_TEXTREL) != 0)
06869 {
06870 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
06871 return FALSE;
06872 }
06873
06874 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
06875 return FALSE;
06876
06877 if (mips_elf_rel_dyn_section (dynobj, FALSE))
06878 {
06879 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
06880 return FALSE;
06881
06882 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
06883 return FALSE;
06884
06885 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
06886 return FALSE;
06887 }
06888
06889 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_VERSION, 0))
06890 return FALSE;
06891
06892 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_FLAGS, 0))
06893 return FALSE;
06894
06895 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_BASE_ADDRESS, 0))
06896 return FALSE;
06897
06898 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LOCAL_GOTNO, 0))
06899 return FALSE;
06900
06901 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_SYMTABNO, 0))
06902 return FALSE;
06903
06904 if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_UNREFEXTNO, 0))
06905 return FALSE;
06906
06907 if (! MIPS_ELF_ADD_DYNAM