1 /* Alpha specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Richard Henderson <rth@tamu.edu>.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 /* We need a published ABI spec for this. Until one comes out, don't
23 assume this'll remain unchanged forever. */
30 #include "elf/alpha.h"
34 #define NO_COFF_RELOCS
35 #define NO_COFF_SYMBOLS
36 #define NO_COFF_LINENOS
38 /* Get the ECOFF swapping routines. Needed for the debug information. */
39 #include "coff/internal.h"
41 #include "coff/symconst.h"
42 #include "coff/ecoff.h"
43 #include "coff/alpha.h"
48 #include "ecoffswap.h"
50 static int alpha_elf_dynamic_symbol_p
51 PARAMS((struct elf_link_hash_entry
*, struct bfd_link_info
*));
52 static struct bfd_hash_entry
* elf64_alpha_link_hash_newfunc
53 PARAMS((struct bfd_hash_entry
*, struct bfd_hash_table
*, const char *));
54 static struct bfd_link_hash_table
* elf64_alpha_bfd_link_hash_table_create
57 static bfd_reloc_status_type elf64_alpha_reloc_nil
58 PARAMS((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
59 static bfd_reloc_status_type elf64_alpha_reloc_bad
60 PARAMS((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
61 static bfd_reloc_status_type elf64_alpha_do_reloc_gpdisp
62 PARAMS((bfd
*, bfd_vma
, bfd_byte
*, bfd_byte
*));
63 static bfd_reloc_status_type elf64_alpha_reloc_gpdisp
64 PARAMS((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
66 static reloc_howto_type
* elf64_alpha_bfd_reloc_type_lookup
67 PARAMS((bfd
*, bfd_reloc_code_real_type
));
68 static void elf64_alpha_info_to_howto
69 PARAMS((bfd
*, arelent
*, Elf_Internal_Rela
*));
71 static bfd_boolean elf64_alpha_mkobject
73 static bfd_boolean elf64_alpha_object_p
75 static bfd_boolean elf64_alpha_section_from_shdr
76 PARAMS((bfd
*, Elf_Internal_Shdr
*, const char *));
77 static bfd_boolean elf64_alpha_section_flags
78 PARAMS((flagword
*, Elf_Internal_Shdr
*));
79 static bfd_boolean elf64_alpha_fake_sections
80 PARAMS((bfd
*, Elf_Internal_Shdr
*, asection
*));
81 static bfd_boolean elf64_alpha_create_got_section
82 PARAMS((bfd
*, struct bfd_link_info
*));
83 static bfd_boolean elf64_alpha_create_dynamic_sections
84 PARAMS((bfd
*, struct bfd_link_info
*));
86 static bfd_boolean elf64_alpha_read_ecoff_info
87 PARAMS((bfd
*, asection
*, struct ecoff_debug_info
*));
88 static bfd_boolean elf64_alpha_is_local_label_name
89 PARAMS((bfd
*, const char *));
90 static bfd_boolean elf64_alpha_find_nearest_line
91 PARAMS((bfd
*, asection
*, asymbol
**, bfd_vma
, const char **,
92 const char **, unsigned int *));
94 #if defined(__STDC__) || defined(ALMOST_STDC)
95 struct alpha_elf_link_hash_entry
;
98 static bfd_boolean elf64_alpha_output_extsym
99 PARAMS((struct alpha_elf_link_hash_entry
*, PTR
));
101 static bfd_boolean elf64_alpha_can_merge_gots
102 PARAMS((bfd
*, bfd
*));
103 static void elf64_alpha_merge_gots
104 PARAMS((bfd
*, bfd
*));
105 static bfd_boolean elf64_alpha_calc_got_offsets_for_symbol
106 PARAMS ((struct alpha_elf_link_hash_entry
*, PTR
));
107 static void elf64_alpha_calc_got_offsets
108 PARAMS ((struct bfd_link_info
*));
109 static bfd_boolean elf64_alpha_size_got_sections
110 PARAMS ((struct bfd_link_info
*));
111 static bfd_boolean elf64_alpha_size_plt_section
112 PARAMS ((struct bfd_link_info
*));
113 static bfd_boolean elf64_alpha_size_plt_section_1
114 PARAMS ((struct alpha_elf_link_hash_entry
*, PTR
));
115 static bfd_boolean elf64_alpha_always_size_sections
116 PARAMS ((bfd
*, struct bfd_link_info
*));
117 static int alpha_dynamic_entries_for_reloc
118 PARAMS ((int, int, int));
119 static bfd_boolean elf64_alpha_calc_dynrel_sizes
120 PARAMS ((struct alpha_elf_link_hash_entry
*, struct bfd_link_info
*));
121 static bfd_boolean elf64_alpha_size_rela_got_section
122 PARAMS ((struct bfd_link_info
*));
123 static bfd_boolean elf64_alpha_size_rela_got_1
124 PARAMS ((struct alpha_elf_link_hash_entry
*, struct bfd_link_info
*));
125 static bfd_boolean elf64_alpha_add_symbol_hook
126 PARAMS ((bfd
*, struct bfd_link_info
*, const Elf_Internal_Sym
*,
127 const char **, flagword
*, asection
**, bfd_vma
*));
128 static struct alpha_elf_got_entry
*get_got_entry
129 PARAMS ((bfd
*, struct alpha_elf_link_hash_entry
*, unsigned long,
130 unsigned long, bfd_vma
));
131 static bfd_boolean elf64_alpha_check_relocs
132 PARAMS((bfd
*, struct bfd_link_info
*, asection
*sec
,
133 const Elf_Internal_Rela
*));
134 static bfd_boolean elf64_alpha_adjust_dynamic_symbol
135 PARAMS((struct bfd_link_info
*, struct elf_link_hash_entry
*));
136 static bfd_boolean elf64_alpha_size_dynamic_sections
137 PARAMS((bfd
*, struct bfd_link_info
*));
138 static bfd_boolean elf64_alpha_relocate_section_r
139 PARAMS((bfd
*, struct bfd_link_info
*, bfd
*, asection
*, bfd_byte
*,
140 Elf_Internal_Rela
*, Elf_Internal_Sym
*, asection
**));
141 static bfd_boolean elf64_alpha_relocate_section
142 PARAMS((bfd
*, struct bfd_link_info
*, bfd
*, asection
*, bfd_byte
*,
143 Elf_Internal_Rela
*, Elf_Internal_Sym
*, asection
**));
144 static bfd_boolean elf64_alpha_finish_dynamic_symbol
145 PARAMS((bfd
*, struct bfd_link_info
*, struct elf_link_hash_entry
*,
146 Elf_Internal_Sym
*));
147 static bfd_boolean elf64_alpha_finish_dynamic_sections
148 PARAMS((bfd
*, struct bfd_link_info
*));
149 static bfd_boolean elf64_alpha_final_link
150 PARAMS((bfd
*, struct bfd_link_info
*));
151 static bfd_boolean elf64_alpha_merge_ind_symbols
152 PARAMS((struct alpha_elf_link_hash_entry
*, PTR
));
153 static Elf_Internal_Rela
* elf64_alpha_find_reloc_at_ofs
154 PARAMS ((Elf_Internal_Rela
*, Elf_Internal_Rela
*, bfd_vma
, int));
155 static enum elf_reloc_type_class elf64_alpha_reloc_type_class
156 PARAMS ((const Elf_Internal_Rela
*));
158 struct alpha_elf_link_hash_entry
160 struct elf_link_hash_entry root
;
162 /* External symbol information. */
165 /* Cumulative flags for all the .got entries. */
168 /* Contexts in which a literal was referenced. */
169 #define ALPHA_ELF_LINK_HASH_LU_ADDR 0x01
170 #define ALPHA_ELF_LINK_HASH_LU_MEM 0x02
171 #define ALPHA_ELF_LINK_HASH_LU_BYTE 0x04
172 #define ALPHA_ELF_LINK_HASH_LU_JSR 0x08
173 #define ALPHA_ELF_LINK_HASH_LU_TLSGD 0x10
174 #define ALPHA_ELF_LINK_HASH_LU_TLSLDM 0x20
175 #define ALPHA_ELF_LINK_HASH_LU_FUNC 0x38
176 #define ALPHA_ELF_LINK_HASH_TLS_IE 0x40
178 /* Used to implement multiple .got subsections. */
179 struct alpha_elf_got_entry
181 struct alpha_elf_got_entry
*next
;
183 /* which .got subsection? */
186 /* the addend in effect for this entry. */
189 /* the .got offset for this entry. */
192 /* How many references to this entry? */
195 /* The relocation type of this entry. */
196 unsigned char reloc_type
;
198 /* How a LITERAL is used. */
201 /* Have we initialized the dynamic relocation for this entry? */
202 unsigned char reloc_done
;
204 /* Have we adjusted this entry for SEC_MERGE? */
205 unsigned char reloc_xlated
;
208 /* used to count non-got, non-plt relocations for delayed sizing
209 of relocation sections. */
210 struct alpha_elf_reloc_entry
212 struct alpha_elf_reloc_entry
*next
;
214 /* which .reloc section? */
217 /* what kind of relocation? */
220 /* is this against read-only section? */
221 unsigned int reltext
: 1;
223 /* how many did we find? */
228 /* Alpha ELF linker hash table. */
230 struct alpha_elf_link_hash_table
232 struct elf_link_hash_table root
;
234 /* The head of a list of .got subsections linked through
235 alpha_elf_tdata(abfd)->got_link_next. */
239 /* Look up an entry in a Alpha ELF linker hash table. */
241 #define alpha_elf_link_hash_lookup(table, string, create, copy, follow) \
242 ((struct alpha_elf_link_hash_entry *) \
243 elf_link_hash_lookup (&(table)->root, (string), (create), \
246 /* Traverse a Alpha ELF linker hash table. */
248 #define alpha_elf_link_hash_traverse(table, func, info) \
249 (elf_link_hash_traverse \
251 (bfd_boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
254 /* Get the Alpha ELF linker hash table from a link_info structure. */
256 #define alpha_elf_hash_table(p) \
257 ((struct alpha_elf_link_hash_table *) ((p)->hash))
259 /* Get the object's symbols as our own entry type. */
261 #define alpha_elf_sym_hashes(abfd) \
262 ((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
264 /* Should we do dynamic things to this symbol? */
267 alpha_elf_dynamic_symbol_p (h
, info
)
268 struct elf_link_hash_entry
*h
;
269 struct bfd_link_info
*info
;
274 while (h
->root
.type
== bfd_link_hash_indirect
275 || h
->root
.type
== bfd_link_hash_warning
)
276 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
278 if (h
->dynindx
== -1)
281 if (h
->root
.type
== bfd_link_hash_undefweak
282 || h
->root
.type
== bfd_link_hash_defweak
)
285 switch (ELF_ST_VISIBILITY (h
->other
))
293 if (h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
298 if ((info
->shared
&& !info
->symbolic
)
299 || ((h
->elf_link_hash_flags
300 & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
))
301 == (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
)))
307 /* Create an entry in a Alpha ELF linker hash table. */
309 static struct bfd_hash_entry
*
310 elf64_alpha_link_hash_newfunc (entry
, table
, string
)
311 struct bfd_hash_entry
*entry
;
312 struct bfd_hash_table
*table
;
315 struct alpha_elf_link_hash_entry
*ret
=
316 (struct alpha_elf_link_hash_entry
*) entry
;
318 /* Allocate the structure if it has not already been allocated by a
320 if (ret
== (struct alpha_elf_link_hash_entry
*) NULL
)
321 ret
= ((struct alpha_elf_link_hash_entry
*)
322 bfd_hash_allocate (table
,
323 sizeof (struct alpha_elf_link_hash_entry
)));
324 if (ret
== (struct alpha_elf_link_hash_entry
*) NULL
)
325 return (struct bfd_hash_entry
*) ret
;
327 /* Call the allocation method of the superclass. */
328 ret
= ((struct alpha_elf_link_hash_entry
*)
329 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry
*) ret
,
331 if (ret
!= (struct alpha_elf_link_hash_entry
*) NULL
)
333 /* Set local fields. */
334 memset (&ret
->esym
, 0, sizeof (EXTR
));
335 /* We use -2 as a marker to indicate that the information has
336 not been set. -1 means there is no associated ifd. */
339 ret
->got_entries
= NULL
;
340 ret
->reloc_entries
= NULL
;
343 return (struct bfd_hash_entry
*) ret
;
346 /* Create a Alpha ELF linker hash table. */
348 static struct bfd_link_hash_table
*
349 elf64_alpha_bfd_link_hash_table_create (abfd
)
352 struct alpha_elf_link_hash_table
*ret
;
353 bfd_size_type amt
= sizeof (struct alpha_elf_link_hash_table
);
355 ret
= (struct alpha_elf_link_hash_table
*) bfd_zmalloc (amt
);
356 if (ret
== (struct alpha_elf_link_hash_table
*) NULL
)
359 if (! _bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
360 elf64_alpha_link_hash_newfunc
))
366 return &ret
->root
.root
;
369 /* We have some private fields hanging off of the elf_tdata structure. */
371 struct alpha_elf_obj_tdata
373 struct elf_obj_tdata root
;
375 /* For every input file, these are the got entries for that object's
377 struct alpha_elf_got_entry
** local_got_entries
;
379 /* For every input file, this is the object that owns the got that
380 this input file uses. */
383 /* For every got, this is a linked list through the objects using this got */
384 bfd
*in_got_link_next
;
386 /* For every got, this is a link to the next got subsegment. */
389 /* For every got, this is the section. */
392 /* For every got, this is it's total number of words. */
395 /* For every got, this is the sum of the number of words required
396 to hold all of the member object's local got. */
400 #define alpha_elf_tdata(abfd) \
401 ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any)
404 elf64_alpha_mkobject (abfd
)
407 bfd_size_type amt
= sizeof (struct alpha_elf_obj_tdata
);
408 abfd
->tdata
.any
= bfd_zalloc (abfd
, amt
);
409 if (abfd
->tdata
.any
== NULL
)
415 elf64_alpha_object_p (abfd
)
418 /* Allocate our special target data. */
419 struct alpha_elf_obj_tdata
*new_tdata
;
420 bfd_size_type amt
= sizeof (struct alpha_elf_obj_tdata
);
421 new_tdata
= bfd_zalloc (abfd
, amt
);
422 if (new_tdata
== NULL
)
424 new_tdata
->root
= *abfd
->tdata
.elf_obj_data
;
425 abfd
->tdata
.any
= new_tdata
;
427 /* Set the right machine number for an Alpha ELF file. */
428 return bfd_default_set_arch_mach (abfd
, bfd_arch_alpha
, 0);
431 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
432 from smaller values. Start with zero, widen, *then* decrement. */
433 #define MINUS_ONE (((bfd_vma)0) - 1)
435 #define SKIP_HOWTO(N) \
436 HOWTO(N, 0, 0, 0, 0, 0, 0, elf64_alpha_reloc_bad, 0, 0, 0, 0, 0)
438 static reloc_howto_type elf64_alpha_howto_table
[] =
440 HOWTO (R_ALPHA_NONE
, /* type */
442 0, /* size (0 = byte, 1 = short, 2 = long) */
444 TRUE
, /* pc_relative */
446 complain_overflow_dont
, /* complain_on_overflow */
447 elf64_alpha_reloc_nil
, /* special_function */
449 FALSE
, /* partial_inplace */
452 TRUE
), /* pcrel_offset */
454 /* A 32 bit reference to a symbol. */
455 HOWTO (R_ALPHA_REFLONG
, /* type */
457 2, /* size (0 = byte, 1 = short, 2 = long) */
459 FALSE
, /* pc_relative */
461 complain_overflow_bitfield
, /* complain_on_overflow */
462 0, /* special_function */
463 "REFLONG", /* name */
464 FALSE
, /* partial_inplace */
465 0xffffffff, /* src_mask */
466 0xffffffff, /* dst_mask */
467 FALSE
), /* pcrel_offset */
469 /* A 64 bit reference to a symbol. */
470 HOWTO (R_ALPHA_REFQUAD
, /* type */
472 4, /* size (0 = byte, 1 = short, 2 = long) */
474 FALSE
, /* pc_relative */
476 complain_overflow_bitfield
, /* complain_on_overflow */
477 0, /* special_function */
478 "REFQUAD", /* name */
479 FALSE
, /* partial_inplace */
480 MINUS_ONE
, /* src_mask */
481 MINUS_ONE
, /* dst_mask */
482 FALSE
), /* pcrel_offset */
484 /* A 32 bit GP relative offset. This is just like REFLONG except
485 that when the value is used the value of the gp register will be
487 HOWTO (R_ALPHA_GPREL32
, /* type */
489 2, /* size (0 = byte, 1 = short, 2 = long) */
491 FALSE
, /* pc_relative */
493 complain_overflow_bitfield
, /* complain_on_overflow */
494 0, /* special_function */
495 "GPREL32", /* name */
496 FALSE
, /* partial_inplace */
497 0xffffffff, /* src_mask */
498 0xffffffff, /* dst_mask */
499 FALSE
), /* pcrel_offset */
501 /* Used for an instruction that refers to memory off the GP register. */
502 HOWTO (R_ALPHA_LITERAL
, /* type */
504 1, /* size (0 = byte, 1 = short, 2 = long) */
506 FALSE
, /* pc_relative */
508 complain_overflow_signed
, /* complain_on_overflow */
509 0, /* special_function */
510 "ELF_LITERAL", /* name */
511 FALSE
, /* partial_inplace */
512 0xffff, /* src_mask */
513 0xffff, /* dst_mask */
514 FALSE
), /* pcrel_offset */
516 /* This reloc only appears immediately following an ELF_LITERAL reloc.
517 It identifies a use of the literal. The symbol index is special:
518 1 means the literal address is in the base register of a memory
519 format instruction; 2 means the literal address is in the byte
520 offset register of a byte-manipulation instruction; 3 means the
521 literal address is in the target register of a jsr instruction.
522 This does not actually do any relocation. */
523 HOWTO (R_ALPHA_LITUSE
, /* type */
525 1, /* size (0 = byte, 1 = short, 2 = long) */
527 FALSE
, /* pc_relative */
529 complain_overflow_dont
, /* complain_on_overflow */
530 elf64_alpha_reloc_nil
, /* special_function */
532 FALSE
, /* partial_inplace */
535 FALSE
), /* pcrel_offset */
537 /* Load the gp register. This is always used for a ldah instruction
538 which loads the upper 16 bits of the gp register. The symbol
539 index of the GPDISP instruction is an offset in bytes to the lda
540 instruction that loads the lower 16 bits. The value to use for
541 the relocation is the difference between the GP value and the
542 current location; the load will always be done against a register
543 holding the current address.
545 NOTE: Unlike ECOFF, partial in-place relocation is not done. If
546 any offset is present in the instructions, it is an offset from
547 the register to the ldah instruction. This lets us avoid any
548 stupid hackery like inventing a gp value to do partial relocation
549 against. Also unlike ECOFF, we do the whole relocation off of
550 the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair. An odd,
551 space consuming bit, that, since all the information was present
552 in the GPDISP_HI16 reloc. */
553 HOWTO (R_ALPHA_GPDISP
, /* type */
555 2, /* size (0 = byte, 1 = short, 2 = long) */
557 FALSE
, /* pc_relative */
559 complain_overflow_dont
, /* complain_on_overflow */
560 elf64_alpha_reloc_gpdisp
, /* special_function */
562 FALSE
, /* partial_inplace */
563 0xffff, /* src_mask */
564 0xffff, /* dst_mask */
565 TRUE
), /* pcrel_offset */
567 /* A 21 bit branch. */
568 HOWTO (R_ALPHA_BRADDR
, /* type */
570 2, /* size (0 = byte, 1 = short, 2 = long) */
572 TRUE
, /* pc_relative */
574 complain_overflow_signed
, /* complain_on_overflow */
575 0, /* special_function */
577 FALSE
, /* partial_inplace */
578 0x1fffff, /* src_mask */
579 0x1fffff, /* dst_mask */
580 TRUE
), /* pcrel_offset */
582 /* A hint for a jump to a register. */
583 HOWTO (R_ALPHA_HINT
, /* type */
585 1, /* size (0 = byte, 1 = short, 2 = long) */
587 TRUE
, /* pc_relative */
589 complain_overflow_dont
, /* complain_on_overflow */
590 0, /* special_function */
592 FALSE
, /* partial_inplace */
593 0x3fff, /* src_mask */
594 0x3fff, /* dst_mask */
595 TRUE
), /* pcrel_offset */
597 /* 16 bit PC relative offset. */
598 HOWTO (R_ALPHA_SREL16
, /* type */
600 1, /* size (0 = byte, 1 = short, 2 = long) */
602 TRUE
, /* pc_relative */
604 complain_overflow_signed
, /* complain_on_overflow */
605 0, /* special_function */
607 FALSE
, /* partial_inplace */
608 0xffff, /* src_mask */
609 0xffff, /* dst_mask */
610 TRUE
), /* pcrel_offset */
612 /* 32 bit PC relative offset. */
613 HOWTO (R_ALPHA_SREL32
, /* type */
615 2, /* size (0 = byte, 1 = short, 2 = long) */
617 TRUE
, /* pc_relative */
619 complain_overflow_signed
, /* complain_on_overflow */
620 0, /* special_function */
622 FALSE
, /* partial_inplace */
623 0xffffffff, /* src_mask */
624 0xffffffff, /* dst_mask */
625 TRUE
), /* pcrel_offset */
627 /* A 64 bit PC relative offset. */
628 HOWTO (R_ALPHA_SREL64
, /* type */
630 4, /* size (0 = byte, 1 = short, 2 = long) */
632 TRUE
, /* pc_relative */
634 complain_overflow_signed
, /* complain_on_overflow */
635 0, /* special_function */
637 FALSE
, /* partial_inplace */
638 MINUS_ONE
, /* src_mask */
639 MINUS_ONE
, /* dst_mask */
640 TRUE
), /* pcrel_offset */
642 /* Skip 12 - 16; deprecated ECOFF relocs. */
649 /* The high 16 bits of the displacement from GP to the target. */
650 HOWTO (R_ALPHA_GPRELHIGH
,
652 1, /* size (0 = byte, 1 = short, 2 = long) */
654 FALSE
, /* pc_relative */
656 complain_overflow_signed
, /* complain_on_overflow */
657 0, /* special_function */
658 "GPRELHIGH", /* name */
659 FALSE
, /* partial_inplace */
660 0xffff, /* src_mask */
661 0xffff, /* dst_mask */
662 FALSE
), /* pcrel_offset */
664 /* The low 16 bits of the displacement from GP to the target. */
665 HOWTO (R_ALPHA_GPRELLOW
,
667 1, /* size (0 = byte, 1 = short, 2 = long) */
669 FALSE
, /* pc_relative */
671 complain_overflow_dont
, /* complain_on_overflow */
672 0, /* special_function */
673 "GPRELLOW", /* name */
674 FALSE
, /* partial_inplace */
675 0xffff, /* src_mask */
676 0xffff, /* dst_mask */
677 FALSE
), /* pcrel_offset */
679 /* A 16-bit displacement from the GP to the target. */
680 HOWTO (R_ALPHA_GPREL16
,
682 1, /* size (0 = byte, 1 = short, 2 = long) */
684 FALSE
, /* pc_relative */
686 complain_overflow_signed
, /* complain_on_overflow */
687 0, /* special_function */
688 "GPREL16", /* name */
689 FALSE
, /* partial_inplace */
690 0xffff, /* src_mask */
691 0xffff, /* dst_mask */
692 FALSE
), /* pcrel_offset */
694 /* Skip 20 - 23; deprecated ECOFF relocs. */
700 /* Misc ELF relocations. */
702 /* A dynamic relocation to copy the target into our .dynbss section. */
703 /* Not generated, as all Alpha objects use PIC, so it is not needed. It
704 is present because every other ELF has one, but should not be used
705 because .dynbss is an ugly thing. */
712 complain_overflow_dont
,
713 bfd_elf_generic_reloc
,
720 /* A dynamic relocation for a .got entry. */
721 HOWTO (R_ALPHA_GLOB_DAT
,
727 complain_overflow_dont
,
728 bfd_elf_generic_reloc
,
735 /* A dynamic relocation for a .plt entry. */
736 HOWTO (R_ALPHA_JMP_SLOT
,
742 complain_overflow_dont
,
743 bfd_elf_generic_reloc
,
750 /* A dynamic relocation to add the base of the DSO to a 64-bit field. */
751 HOWTO (R_ALPHA_RELATIVE
,
757 complain_overflow_dont
,
758 bfd_elf_generic_reloc
,
765 /* A 21 bit branch that adjusts for gp loads. */
766 HOWTO (R_ALPHA_BRSGP
, /* type */
768 2, /* size (0 = byte, 1 = short, 2 = long) */
770 TRUE
, /* pc_relative */
772 complain_overflow_signed
, /* complain_on_overflow */
773 0, /* special_function */
775 FALSE
, /* partial_inplace */
776 0x1fffff, /* src_mask */
777 0x1fffff, /* dst_mask */
778 TRUE
), /* pcrel_offset */
780 /* Creates a tls_index for the symbol in the got. */
781 HOWTO (R_ALPHA_TLSGD
, /* type */
783 1, /* size (0 = byte, 1 = short, 2 = long) */
785 FALSE
, /* pc_relative */
787 complain_overflow_signed
, /* complain_on_overflow */
788 0, /* special_function */
790 FALSE
, /* partial_inplace */
791 0xffff, /* src_mask */
792 0xffff, /* dst_mask */
793 FALSE
), /* pcrel_offset */
795 /* Creates a tls_index for the (current) module in the got. */
796 HOWTO (R_ALPHA_TLSLDM
, /* type */
798 1, /* size (0 = byte, 1 = short, 2 = long) */
800 FALSE
, /* pc_relative */
802 complain_overflow_signed
, /* complain_on_overflow */
803 0, /* special_function */
805 FALSE
, /* partial_inplace */
806 0xffff, /* src_mask */
807 0xffff, /* dst_mask */
808 FALSE
), /* pcrel_offset */
810 /* A dynamic relocation for a DTP module entry. */
811 HOWTO (R_ALPHA_DTPMOD64
, /* type */
813 4, /* size (0 = byte, 1 = short, 2 = long) */
815 FALSE
, /* pc_relative */
817 complain_overflow_bitfield
, /* complain_on_overflow */
818 0, /* special_function */
819 "DTPMOD64", /* name */
820 FALSE
, /* partial_inplace */
821 MINUS_ONE
, /* src_mask */
822 MINUS_ONE
, /* dst_mask */
823 FALSE
), /* pcrel_offset */
825 /* Creates a 64-bit offset in the got for the displacement
826 from DTP to the target. */
827 HOWTO (R_ALPHA_GOTDTPREL
, /* type */
829 1, /* size (0 = byte, 1 = short, 2 = long) */
831 FALSE
, /* pc_relative */
833 complain_overflow_signed
, /* complain_on_overflow */
834 0, /* special_function */
835 "GOTDTPREL", /* name */
836 FALSE
, /* partial_inplace */
837 0xffff, /* src_mask */
838 0xffff, /* dst_mask */
839 FALSE
), /* pcrel_offset */
841 /* A dynamic relocation for a displacement from DTP to the target. */
842 HOWTO (R_ALPHA_DTPREL64
, /* type */
844 4, /* size (0 = byte, 1 = short, 2 = long) */
846 FALSE
, /* pc_relative */
848 complain_overflow_bitfield
, /* complain_on_overflow */
849 0, /* special_function */
850 "DTPREL64", /* name */
851 FALSE
, /* partial_inplace */
852 MINUS_ONE
, /* src_mask */
853 MINUS_ONE
, /* dst_mask */
854 FALSE
), /* pcrel_offset */
856 /* The high 16 bits of the displacement from DTP to the target. */
857 HOWTO (R_ALPHA_DTPRELHI
, /* type */
859 1, /* size (0 = byte, 1 = short, 2 = long) */
861 FALSE
, /* pc_relative */
863 complain_overflow_signed
, /* complain_on_overflow */
864 0, /* special_function */
865 "DTPRELHI", /* name */
866 FALSE
, /* partial_inplace */
867 0xffff, /* src_mask */
868 0xffff, /* dst_mask */
869 FALSE
), /* pcrel_offset */
871 /* The low 16 bits of the displacement from DTP to the target. */
872 HOWTO (R_ALPHA_DTPRELLO
, /* type */
874 1, /* size (0 = byte, 1 = short, 2 = long) */
876 FALSE
, /* pc_relative */
878 complain_overflow_dont
, /* complain_on_overflow */
879 0, /* special_function */
880 "DTPRELLO", /* name */
881 FALSE
, /* partial_inplace */
882 0xffff, /* src_mask */
883 0xffff, /* dst_mask */
884 FALSE
), /* pcrel_offset */
886 /* A 16-bit displacement from DTP to the target. */
887 HOWTO (R_ALPHA_DTPREL16
, /* type */
889 1, /* size (0 = byte, 1 = short, 2 = long) */
891 FALSE
, /* pc_relative */
893 complain_overflow_signed
, /* complain_on_overflow */
894 0, /* special_function */
895 "DTPREL16", /* name */
896 FALSE
, /* partial_inplace */
897 0xffff, /* src_mask */
898 0xffff, /* dst_mask */
899 FALSE
), /* pcrel_offset */
901 /* Creates a 64-bit offset in the got for the displacement
902 from TP to the target. */
903 HOWTO (R_ALPHA_GOTTPREL
, /* type */
905 1, /* size (0 = byte, 1 = short, 2 = long) */
907 FALSE
, /* pc_relative */
909 complain_overflow_signed
, /* complain_on_overflow */
910 0, /* special_function */
911 "GOTTPREL", /* name */
912 FALSE
, /* partial_inplace */
913 0xffff, /* src_mask */
914 0xffff, /* dst_mask */
915 FALSE
), /* pcrel_offset */
917 /* A dynamic relocation for a displacement from TP to the target. */
918 HOWTO (R_ALPHA_TPREL64
, /* type */
920 4, /* size (0 = byte, 1 = short, 2 = long) */
922 FALSE
, /* pc_relative */
924 complain_overflow_bitfield
, /* complain_on_overflow */
925 0, /* special_function */
926 "TPREL64", /* name */
927 FALSE
, /* partial_inplace */
928 MINUS_ONE
, /* src_mask */
929 MINUS_ONE
, /* dst_mask */
930 FALSE
), /* pcrel_offset */
932 /* The high 16 bits of the displacement from TP to the target. */
933 HOWTO (R_ALPHA_TPRELHI
, /* type */
935 1, /* size (0 = byte, 1 = short, 2 = long) */
937 FALSE
, /* pc_relative */
939 complain_overflow_signed
, /* complain_on_overflow */
940 0, /* special_function */
941 "TPRELHI", /* name */
942 FALSE
, /* partial_inplace */
943 0xffff, /* src_mask */
944 0xffff, /* dst_mask */
945 FALSE
), /* pcrel_offset */
947 /* The low 16 bits of the displacement from TP to the target. */
948 HOWTO (R_ALPHA_TPRELLO
, /* type */
950 1, /* size (0 = byte, 1 = short, 2 = long) */
952 FALSE
, /* pc_relative */
954 complain_overflow_dont
, /* complain_on_overflow */
955 0, /* special_function */
956 "TPRELLO", /* name */
957 FALSE
, /* partial_inplace */
958 0xffff, /* src_mask */
959 0xffff, /* dst_mask */
960 FALSE
), /* pcrel_offset */
962 /* A 16-bit displacement from TP to the target. */
963 HOWTO (R_ALPHA_TPREL16
, /* type */
965 1, /* size (0 = byte, 1 = short, 2 = long) */
967 FALSE
, /* pc_relative */
969 complain_overflow_signed
, /* complain_on_overflow */
970 0, /* special_function */
971 "TPREL16", /* name */
972 FALSE
, /* partial_inplace */
973 0xffff, /* src_mask */
974 0xffff, /* dst_mask */
975 FALSE
), /* pcrel_offset */
978 /* A relocation function which doesn't do anything. */
980 static bfd_reloc_status_type
981 elf64_alpha_reloc_nil (abfd
, reloc
, sym
, data
, sec
, output_bfd
, error_message
)
982 bfd
*abfd ATTRIBUTE_UNUSED
;
984 asymbol
*sym ATTRIBUTE_UNUSED
;
985 PTR data ATTRIBUTE_UNUSED
;
988 char **error_message ATTRIBUTE_UNUSED
;
991 reloc
->address
+= sec
->output_offset
;
995 /* A relocation function used for an unsupported reloc. */
997 static bfd_reloc_status_type
998 elf64_alpha_reloc_bad (abfd
, reloc
, sym
, data
, sec
, output_bfd
, error_message
)
999 bfd
*abfd ATTRIBUTE_UNUSED
;
1001 asymbol
*sym ATTRIBUTE_UNUSED
;
1002 PTR data ATTRIBUTE_UNUSED
;
1005 char **error_message ATTRIBUTE_UNUSED
;
1008 reloc
->address
+= sec
->output_offset
;
1009 return bfd_reloc_notsupported
;
1012 /* Do the work of the GPDISP relocation. */
1014 static bfd_reloc_status_type
1015 elf64_alpha_do_reloc_gpdisp (abfd
, gpdisp
, p_ldah
, p_lda
)
1021 bfd_reloc_status_type ret
= bfd_reloc_ok
;
1023 unsigned long i_ldah
, i_lda
;
1025 i_ldah
= bfd_get_32 (abfd
, p_ldah
);
1026 i_lda
= bfd_get_32 (abfd
, p_lda
);
1028 /* Complain if the instructions are not correct. */
1029 if (((i_ldah
>> 26) & 0x3f) != 0x09
1030 || ((i_lda
>> 26) & 0x3f) != 0x08)
1031 ret
= bfd_reloc_dangerous
;
1033 /* Extract the user-supplied offset, mirroring the sign extensions
1034 that the instructions perform. */
1035 addend
= ((i_ldah
& 0xffff) << 16) | (i_lda
& 0xffff);
1036 addend
= (addend
^ 0x80008000) - 0x80008000;
1040 if ((bfd_signed_vma
) gpdisp
< -(bfd_signed_vma
) 0x80000000
1041 || (bfd_signed_vma
) gpdisp
>= (bfd_signed_vma
) 0x7fff8000)
1042 ret
= bfd_reloc_overflow
;
1044 /* compensate for the sign extension again. */
1045 i_ldah
= ((i_ldah
& 0xffff0000)
1046 | (((gpdisp
>> 16) + ((gpdisp
>> 15) & 1)) & 0xffff));
1047 i_lda
= (i_lda
& 0xffff0000) | (gpdisp
& 0xffff);
1049 bfd_put_32 (abfd
, (bfd_vma
) i_ldah
, p_ldah
);
1050 bfd_put_32 (abfd
, (bfd_vma
) i_lda
, p_lda
);
1055 /* The special function for the GPDISP reloc. */
1057 static bfd_reloc_status_type
1058 elf64_alpha_reloc_gpdisp (abfd
, reloc_entry
, sym
, data
, input_section
,
1059 output_bfd
, err_msg
)
1061 arelent
*reloc_entry
;
1062 asymbol
*sym ATTRIBUTE_UNUSED
;
1064 asection
*input_section
;
1068 bfd_reloc_status_type ret
;
1069 bfd_vma gp
, relocation
;
1070 bfd_byte
*p_ldah
, *p_lda
;
1072 /* Don't do anything if we're not doing a final link. */
1075 reloc_entry
->address
+= input_section
->output_offset
;
1076 return bfd_reloc_ok
;
1079 if (reloc_entry
->address
> input_section
->_cooked_size
||
1080 reloc_entry
->address
+ reloc_entry
->addend
> input_section
->_cooked_size
)
1081 return bfd_reloc_outofrange
;
1083 /* The gp used in the portion of the output object to which this
1084 input object belongs is cached on the input bfd. */
1085 gp
= _bfd_get_gp_value (abfd
);
1087 relocation
= (input_section
->output_section
->vma
1088 + input_section
->output_offset
1089 + reloc_entry
->address
);
1091 p_ldah
= (bfd_byte
*) data
+ reloc_entry
->address
;
1092 p_lda
= p_ldah
+ reloc_entry
->addend
;
1094 ret
= elf64_alpha_do_reloc_gpdisp (abfd
, gp
- relocation
, p_ldah
, p_lda
);
1096 /* Complain if the instructions are not correct. */
1097 if (ret
== bfd_reloc_dangerous
)
1098 *err_msg
= _("GPDISP relocation did not find ldah and lda instructions");
1103 /* A mapping from BFD reloc types to Alpha ELF reloc types. */
1105 struct elf_reloc_map
1107 bfd_reloc_code_real_type bfd_reloc_val
;
1111 static const struct elf_reloc_map elf64_alpha_reloc_map
[] =
1113 {BFD_RELOC_NONE
, R_ALPHA_NONE
},
1114 {BFD_RELOC_32
, R_ALPHA_REFLONG
},
1115 {BFD_RELOC_64
, R_ALPHA_REFQUAD
},
1116 {BFD_RELOC_CTOR
, R_ALPHA_REFQUAD
},
1117 {BFD_RELOC_GPREL32
, R_ALPHA_GPREL32
},
1118 {BFD_RELOC_ALPHA_ELF_LITERAL
, R_ALPHA_LITERAL
},
1119 {BFD_RELOC_ALPHA_LITUSE
, R_ALPHA_LITUSE
},
1120 {BFD_RELOC_ALPHA_GPDISP
, R_ALPHA_GPDISP
},
1121 {BFD_RELOC_23_PCREL_S2
, R_ALPHA_BRADDR
},
1122 {BFD_RELOC_ALPHA_HINT
, R_ALPHA_HINT
},
1123 {BFD_RELOC_16_PCREL
, R_ALPHA_SREL16
},
1124 {BFD_RELOC_32_PCREL
, R_ALPHA_SREL32
},
1125 {BFD_RELOC_64_PCREL
, R_ALPHA_SREL64
},
1126 {BFD_RELOC_ALPHA_GPREL_HI16
, R_ALPHA_GPRELHIGH
},
1127 {BFD_RELOC_ALPHA_GPREL_LO16
, R_ALPHA_GPRELLOW
},
1128 {BFD_RELOC_GPREL16
, R_ALPHA_GPREL16
},
1129 {BFD_RELOC_ALPHA_BRSGP
, R_ALPHA_BRSGP
},
1130 {BFD_RELOC_ALPHA_TLSGD
, R_ALPHA_TLSGD
},
1131 {BFD_RELOC_ALPHA_TLSLDM
, R_ALPHA_TLSLDM
},
1132 {BFD_RELOC_ALPHA_DTPMOD64
, R_ALPHA_DTPMOD64
},
1133 {BFD_RELOC_ALPHA_GOTDTPREL16
, R_ALPHA_GOTDTPREL
},
1134 {BFD_RELOC_ALPHA_DTPREL64
, R_ALPHA_DTPREL64
},
1135 {BFD_RELOC_ALPHA_DTPREL_HI16
, R_ALPHA_DTPRELHI
},
1136 {BFD_RELOC_ALPHA_DTPREL_LO16
, R_ALPHA_DTPRELLO
},
1137 {BFD_RELOC_ALPHA_DTPREL16
, R_ALPHA_DTPREL16
},
1138 {BFD_RELOC_ALPHA_GOTTPREL16
, R_ALPHA_GOTTPREL
},
1139 {BFD_RELOC_ALPHA_TPREL64
, R_ALPHA_TPREL64
},
1140 {BFD_RELOC_ALPHA_TPREL_HI16
, R_ALPHA_TPRELHI
},
1141 {BFD_RELOC_ALPHA_TPREL_LO16
, R_ALPHA_TPRELLO
},
1142 {BFD_RELOC_ALPHA_TPREL16
, R_ALPHA_TPREL16
},
1145 /* Given a BFD reloc type, return a HOWTO structure. */
1147 static reloc_howto_type
*
1148 elf64_alpha_bfd_reloc_type_lookup (abfd
, code
)
1149 bfd
*abfd ATTRIBUTE_UNUSED
;
1150 bfd_reloc_code_real_type code
;
1152 const struct elf_reloc_map
*i
, *e
;
1153 i
= e
= elf64_alpha_reloc_map
;
1154 e
+= sizeof (elf64_alpha_reloc_map
) / sizeof (struct elf_reloc_map
);
1157 if (i
->bfd_reloc_val
== code
)
1158 return &elf64_alpha_howto_table
[i
->elf_reloc_val
];
1163 /* Given an Alpha ELF reloc type, fill in an arelent structure. */
1166 elf64_alpha_info_to_howto (abfd
, cache_ptr
, dst
)
1167 bfd
*abfd ATTRIBUTE_UNUSED
;
1169 Elf_Internal_Rela
*dst
;
1173 r_type
= ELF64_R_TYPE(dst
->r_info
);
1174 BFD_ASSERT (r_type
< (unsigned int) R_ALPHA_max
);
1175 cache_ptr
->howto
= &elf64_alpha_howto_table
[r_type
];
1178 /* These two relocations create a two-word entry in the got. */
1179 #define alpha_got_entry_size(r_type) \
1180 (r_type == R_ALPHA_TLSGD || r_type == R_ALPHA_TLSLDM ? 16 : 8)
1182 /* This is PT_TLS segment p_vaddr. */
1183 #define alpha_get_dtprel_base(tlss) \
1186 /* Main program TLS (whose template starts at PT_TLS p_vaddr)
1187 is assigned offset round(16, PT_TLS p_align). */
1188 #define alpha_get_tprel_base(tlss) \
1189 ((tlss)->start - align_power ((bfd_vma) 16, (tlss)->align))
1191 /* These functions do relaxation for Alpha ELF.
1193 Currently I'm only handling what I can do with existing compiler
1194 and assembler support, which means no instructions are removed,
1195 though some may be nopped. At this time GCC does not emit enough
1196 information to do all of the relaxing that is possible. It will
1197 take some not small amount of work for that to happen.
1199 There are a couple of interesting papers that I once read on this
1200 subject, that I cannot find references to at the moment, that
1201 related to Alpha in particular. They are by David Wall, then of
1205 #define OP_LDAH 0x09
1206 #define INSN_JSR 0x68004000
1207 #define INSN_JSR_MASK 0xfc00c000
1211 #define INSN_UNOP 0x2ffe0000
1212 #define INSN_ADDQ 0x40000400
1213 #define INSN_RDUNIQ 0x0000009e
1215 struct alpha_relax_info
1220 Elf_Internal_Shdr
*symtab_hdr
;
1221 Elf_Internal_Rela
*relocs
, *relend
;
1222 struct bfd_link_info
*link_info
;
1223 struct elf_link_tls_segment
*tls_segment
;
1227 struct alpha_elf_link_hash_entry
*h
;
1228 struct alpha_elf_got_entry
**first_gotent
;
1229 struct alpha_elf_got_entry
*gotent
;
1230 bfd_boolean changed_contents
;
1231 bfd_boolean changed_relocs
;
1232 unsigned char other
;
1235 static bfd_boolean elf64_alpha_relax_with_lituse
1236 PARAMS((struct alpha_relax_info
*info
, bfd_vma symval
,
1237 Elf_Internal_Rela
*irel
));
1238 static bfd_vma elf64_alpha_relax_opt_call
1239 PARAMS((struct alpha_relax_info
*info
, bfd_vma symval
));
1240 static bfd_boolean elf64_alpha_relax_got_load
1241 PARAMS((struct alpha_relax_info
*info
, bfd_vma symval
,
1242 Elf_Internal_Rela
*irel
, unsigned long));
1243 static bfd_boolean elf64_alpha_relax_gprelhilo
1244 PARAMS((struct alpha_relax_info
*info
, bfd_vma symval
,
1245 Elf_Internal_Rela
*irel
, bfd_boolean
));
1246 static bfd_boolean elf64_alpha_relax_tls_get_addr
1247 PARAMS((struct alpha_relax_info
*info
, bfd_vma symval
,
1248 Elf_Internal_Rela
*irel
, bfd_boolean
));
1249 static struct elf_link_tls_segment
*elf64_alpha_relax_find_tls_segment
1250 PARAMS((struct alpha_relax_info
*, struct elf_link_tls_segment
*));
1251 static bfd_boolean elf64_alpha_relax_section
1252 PARAMS((bfd
*abfd
, asection
*sec
, struct bfd_link_info
*link_info
,
1253 bfd_boolean
*again
));
1255 static Elf_Internal_Rela
*
1256 elf64_alpha_find_reloc_at_ofs (rel
, relend
, offset
, type
)
1257 Elf_Internal_Rela
*rel
, *relend
;
1261 while (rel
< relend
)
1263 if (rel
->r_offset
== offset
1264 && ELF64_R_TYPE (rel
->r_info
) == (unsigned int) type
)
1272 elf64_alpha_relax_with_lituse (info
, symval
, irel
)
1273 struct alpha_relax_info
*info
;
1275 Elf_Internal_Rela
*irel
;
1277 Elf_Internal_Rela
*urel
, *irelend
= info
->relend
;
1278 int flags
, count
, i
;
1279 bfd_signed_vma disp
;
1282 bfd_boolean lit_reused
= FALSE
;
1283 bfd_boolean all_optimized
= TRUE
;
1284 unsigned int lit_insn
;
1286 lit_insn
= bfd_get_32 (info
->abfd
, info
->contents
+ irel
->r_offset
);
1287 if (lit_insn
>> 26 != OP_LDQ
)
1289 ((*_bfd_error_handler
)
1290 ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn",
1291 bfd_archive_filename (info
->abfd
), info
->sec
->name
,
1292 (unsigned long) irel
->r_offset
));
1296 /* Can't relax dynamic symbols. */
1297 if (alpha_elf_dynamic_symbol_p (&info
->h
->root
, info
->link_info
))
1300 /* Summarize how this particular LITERAL is used. */
1301 for (urel
= irel
+1, flags
= count
= 0; urel
< irelend
; ++urel
, ++count
)
1303 if (ELF64_R_TYPE (urel
->r_info
) != R_ALPHA_LITUSE
)
1305 if (urel
->r_addend
<= 3)
1306 flags
|= 1 << urel
->r_addend
;
1309 /* A little preparation for the loop... */
1310 disp
= symval
- info
->gp
;
1312 for (urel
= irel
+1, i
= 0; i
< count
; ++i
, ++urel
)
1316 bfd_signed_vma xdisp
;
1318 insn
= bfd_get_32 (info
->abfd
, info
->contents
+ urel
->r_offset
);
1320 switch (urel
->r_addend
)
1322 case LITUSE_ALPHA_ADDR
:
1324 /* This type is really just a placeholder to note that all
1325 uses cannot be optimized, but to still allow some. */
1326 all_optimized
= FALSE
;
1329 case LITUSE_ALPHA_BASE
:
1330 /* We can always optimize 16-bit displacements. */
1332 /* Extract the displacement from the instruction, sign-extending
1333 it if necessary, then test whether it is within 16 or 32 bits
1334 displacement from GP. */
1335 insn_disp
= insn
& 0x0000ffff;
1336 if (insn_disp
& 0x8000)
1337 insn_disp
|= ~0xffff; /* Negative: sign-extend. */
1339 xdisp
= disp
+ insn_disp
;
1340 fits16
= (xdisp
>= - (bfd_signed_vma
) 0x8000 && xdisp
< 0x8000);
1341 fits32
= (xdisp
>= - (bfd_signed_vma
) 0x80000000
1342 && xdisp
< 0x7fff8000);
1346 /* Take the op code and dest from this insn, take the base
1347 register from the literal insn. Leave the offset alone. */
1348 insn
= (insn
& 0xffe0ffff) | (lit_insn
& 0x001f0000);
1349 urel
->r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
),
1351 urel
->r_addend
= irel
->r_addend
;
1352 info
->changed_relocs
= TRUE
;
1354 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
,
1355 info
->contents
+ urel
->r_offset
);
1356 info
->changed_contents
= TRUE
;
1359 /* If all mem+byte, we can optimize 32-bit mem displacements. */
1360 else if (fits32
&& !(flags
& ~6))
1362 /* FIXME: sanity check that lit insn Ra is mem insn Rb. */
1364 irel
->r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
),
1366 lit_insn
= (OP_LDAH
<< 26) | (lit_insn
& 0x03ff0000);
1367 bfd_put_32 (info
->abfd
, (bfd_vma
) lit_insn
,
1368 info
->contents
+ irel
->r_offset
);
1370 info
->changed_contents
= TRUE
;
1372 urel
->r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
),
1374 urel
->r_addend
= irel
->r_addend
;
1375 info
->changed_relocs
= TRUE
;
1378 all_optimized
= FALSE
;
1381 case LITUSE_ALPHA_BYTOFF
:
1382 /* We can always optimize byte instructions. */
1384 /* FIXME: sanity check the insn for byte op. Check that the
1385 literal dest reg is indeed Rb in the byte insn. */
1387 insn
&= ~ (unsigned) 0x001ff000;
1388 insn
|= ((symval
& 7) << 13) | 0x1000;
1390 urel
->r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1392 info
->changed_relocs
= TRUE
;
1394 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
,
1395 info
->contents
+ urel
->r_offset
);
1396 info
->changed_contents
= TRUE
;
1399 case LITUSE_ALPHA_JSR
:
1400 case LITUSE_ALPHA_TLSGD
:
1401 case LITUSE_ALPHA_TLSLDM
:
1403 bfd_vma optdest
, org
;
1404 bfd_signed_vma odisp
;
1406 /* If not zero, place to jump without needing pv. */
1407 optdest
= elf64_alpha_relax_opt_call (info
, symval
);
1408 org
= (info
->sec
->output_section
->vma
1409 + info
->sec
->output_offset
1410 + urel
->r_offset
+ 4);
1411 odisp
= (optdest
? optdest
: symval
) - org
;
1413 if (odisp
>= -0x400000 && odisp
< 0x400000)
1415 Elf_Internal_Rela
*xrel
;
1417 /* Preserve branch prediction call stack when possible. */
1418 if ((insn
& INSN_JSR_MASK
) == INSN_JSR
)
1419 insn
= (OP_BSR
<< 26) | (insn
& 0x03e00000);
1421 insn
= (OP_BR
<< 26) | (insn
& 0x03e00000);
1423 urel
->r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
),
1425 urel
->r_addend
= irel
->r_addend
;
1428 urel
->r_addend
+= optdest
- symval
;
1430 all_optimized
= FALSE
;
1432 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
,
1433 info
->contents
+ urel
->r_offset
);
1435 /* Kill any HINT reloc that might exist for this insn. */
1436 xrel
= (elf64_alpha_find_reloc_at_ofs
1437 (info
->relocs
, info
->relend
, urel
->r_offset
,
1440 xrel
->r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1442 info
->changed_contents
= TRUE
;
1443 info
->changed_relocs
= TRUE
;
1446 all_optimized
= FALSE
;
1448 /* Even if the target is not in range for a direct branch,
1449 if we share a GP, we can eliminate the gp reload. */
1452 Elf_Internal_Rela
*gpdisp
1453 = (elf64_alpha_find_reloc_at_ofs
1454 (info
->relocs
, irelend
, urel
->r_offset
+ 4,
1458 bfd_byte
*p_ldah
= info
->contents
+ gpdisp
->r_offset
;
1459 bfd_byte
*p_lda
= p_ldah
+ gpdisp
->r_addend
;
1460 unsigned int ldah
= bfd_get_32 (info
->abfd
, p_ldah
);
1461 unsigned int lda
= bfd_get_32 (info
->abfd
, p_lda
);
1463 /* Verify that the instruction is "ldah $29,0($26)".
1464 Consider a function that ends in a noreturn call,
1465 and that the next function begins with an ldgp,
1466 and that by accident there is no padding between.
1467 In that case the insn would use $27 as the base. */
1468 if (ldah
== 0x27ba0000 && lda
== 0x23bd0000)
1470 bfd_put_32 (info
->abfd
, (bfd_vma
) INSN_UNOP
, p_ldah
);
1471 bfd_put_32 (info
->abfd
, (bfd_vma
) INSN_UNOP
, p_lda
);
1473 gpdisp
->r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1474 info
->changed_contents
= TRUE
;
1475 info
->changed_relocs
= TRUE
;
1484 /* If all cases were optimized, we can reduce the use count on this
1485 got entry by one, possibly eliminating it. */
1488 if (--info
->gotent
->use_count
== 0)
1490 int sz
= alpha_got_entry_size (R_ALPHA_LITERAL
);
1491 alpha_elf_tdata (info
->gotobj
)->total_got_size
-= sz
;
1493 alpha_elf_tdata (info
->gotobj
)->local_got_size
-= sz
;
1496 /* If the literal instruction is no longer needed (it may have been
1497 reused. We can eliminate it. */
1498 /* ??? For now, I don't want to deal with compacting the section,
1499 so just nop it out. */
1502 irel
->r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1503 info
->changed_relocs
= TRUE
;
1505 bfd_put_32 (info
->abfd
, (bfd_vma
) INSN_UNOP
,
1506 info
->contents
+ irel
->r_offset
);
1507 info
->changed_contents
= TRUE
;
1515 elf64_alpha_relax_opt_call (info
, symval
)
1516 struct alpha_relax_info
*info
;
1519 /* If the function has the same gp, and we can identify that the
1520 function does not use its function pointer, we can eliminate the
1523 /* If the symbol is marked NOPV, we are being told the function never
1524 needs its procedure value. */
1525 if ((info
->other
& STO_ALPHA_STD_GPLOAD
) == STO_ALPHA_NOPV
)
1528 /* If the symbol is marked STD_GP, we are being told the function does
1529 a normal ldgp in the first two words. */
1530 else if ((info
->other
& STO_ALPHA_STD_GPLOAD
) == STO_ALPHA_STD_GPLOAD
)
1533 /* Otherwise, we may be able to identify a GP load in the first two
1534 words, which we can then skip. */
1537 Elf_Internal_Rela
*tsec_relocs
, *tsec_relend
, *tsec_free
, *gpdisp
;
1540 /* Load the relocations from the section that the target symbol is in. */
1541 if (info
->sec
== info
->tsec
)
1543 tsec_relocs
= info
->relocs
;
1544 tsec_relend
= info
->relend
;
1549 tsec_relocs
= (_bfd_elf64_link_read_relocs
1550 (info
->abfd
, info
->tsec
, (PTR
) NULL
,
1551 (Elf_Internal_Rela
*) NULL
,
1552 info
->link_info
->keep_memory
));
1553 if (tsec_relocs
== NULL
)
1555 tsec_relend
= tsec_relocs
+ info
->tsec
->reloc_count
;
1556 tsec_free
= (info
->link_info
->keep_memory
? NULL
: tsec_relocs
);
1559 /* Recover the symbol's offset within the section. */
1560 ofs
= (symval
- info
->tsec
->output_section
->vma
1561 - info
->tsec
->output_offset
);
1563 /* Look for a GPDISP reloc. */
1564 gpdisp
= (elf64_alpha_find_reloc_at_ofs
1565 (tsec_relocs
, tsec_relend
, ofs
, R_ALPHA_GPDISP
));
1567 if (!gpdisp
|| gpdisp
->r_addend
!= 4)
1577 /* We've now determined that we can skip an initial gp load. Verify
1578 that the call and the target use the same gp. */
1579 if (info
->link_info
->hash
->creator
!= info
->tsec
->owner
->xvec
1580 || info
->gotobj
!= alpha_elf_tdata (info
->tsec
->owner
)->gotobj
)
1587 elf64_alpha_relax_got_load (info
, symval
, irel
, r_type
)
1588 struct alpha_relax_info
*info
;
1590 Elf_Internal_Rela
*irel
;
1591 unsigned long r_type
;
1594 bfd_signed_vma disp
;
1596 /* Get the instruction. */
1597 insn
= bfd_get_32 (info
->abfd
, info
->contents
+ irel
->r_offset
);
1599 if (insn
>> 26 != OP_LDQ
)
1601 reloc_howto_type
*howto
= elf64_alpha_howto_table
+ r_type
;
1602 ((*_bfd_error_handler
)
1603 ("%s: %s+0x%lx: warning: %s relocation against unexpected insn",
1604 bfd_archive_filename (info
->abfd
), info
->sec
->name
,
1605 (unsigned long) irel
->r_offset
, howto
->name
));
1609 /* Can't relax dynamic symbols. */
1610 if (alpha_elf_dynamic_symbol_p (&info
->h
->root
, info
->link_info
))
1613 /* Can't use local-exec relocations in shared libraries. */
1614 if (r_type
== R_ALPHA_GOTTPREL
&& info
->link_info
->shared
)
1617 if (r_type
== R_ALPHA_LITERAL
)
1618 disp
= symval
- info
->gp
;
1621 bfd_vma dtp_base
, tp_base
;
1623 BFD_ASSERT (info
->tls_segment
!= NULL
);
1624 dtp_base
= alpha_get_dtprel_base (info
->tls_segment
);
1625 tp_base
= alpha_get_tprel_base (info
->tls_segment
);
1626 disp
= symval
- (r_type
== R_ALPHA_GOTDTPREL
? dtp_base
: tp_base
);
1629 if (disp
< -0x8000 || disp
>= 0x8000)
1632 /* Exchange LDQ for LDA. In the case of the TLS relocs, we're loading
1633 a constant, so force the base register to be $31. */
1634 if (r_type
== R_ALPHA_LITERAL
)
1635 insn
= (OP_LDA
<< 26) | (insn
& 0x03ff0000);
1637 insn
= (OP_LDA
<< 26) | (insn
& (31 << 21)) | (31 << 16);
1638 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
, info
->contents
+ irel
->r_offset
);
1639 info
->changed_contents
= TRUE
;
1643 case R_ALPHA_LITERAL
:
1644 r_type
= R_ALPHA_GPREL16
;
1646 case R_ALPHA_GOTDTPREL
:
1647 r_type
= R_ALPHA_DTPREL16
;
1649 case R_ALPHA_GOTTPREL
:
1650 r_type
= R_ALPHA_TPREL16
;
1657 irel
->r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
), r_type
);
1658 info
->changed_relocs
= TRUE
;
1660 /* Reduce the use count on this got entry by one, possibly
1662 if (--info
->gotent
->use_count
== 0)
1664 int sz
= alpha_got_entry_size (r_type
);
1665 alpha_elf_tdata (info
->gotobj
)->total_got_size
-= sz
;
1667 alpha_elf_tdata (info
->gotobj
)->local_got_size
-= sz
;
1670 /* ??? Search forward through this basic block looking for insns
1671 that use the target register. Stop after an insn modifying the
1672 register is seen, or after a branch or call.
1674 Any such memory load insn may be substituted by a load directly
1675 off the GP. This allows the memory load insn to be issued before
1676 the calculated GP register would otherwise be ready.
1678 Any such jsr insn can be replaced by a bsr if it is in range.
1680 This would mean that we'd have to _add_ relocations, the pain of
1681 which gives one pause. */
1687 elf64_alpha_relax_gprelhilo (info
, symval
, irel
, hi
)
1688 struct alpha_relax_info
*info
;
1690 Elf_Internal_Rela
*irel
;
1694 bfd_signed_vma disp
;
1695 bfd_byte
*pos
= info
->contents
+ irel
->r_offset
;
1697 /* ??? This assumes that the compiler doesn't render
1701 ldah t, array(gp) !gprelhigh
1703 ldq r, array(t) !gprellow
1705 which would indeed be the most efficient way to implement this. */
1709 disp
= symval
- info
->gp
;
1710 if (disp
< -0x8000 || disp
>= 0x8000)
1715 /* Nop out the high instruction. */
1717 bfd_put_32 (info
->abfd
, (bfd_vma
) INSN_UNOP
, pos
);
1718 info
->changed_contents
= TRUE
;
1720 irel
->r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1722 info
->changed_relocs
= TRUE
;
1726 /* Adjust the low instruction to reference GP directly. */
1728 insn
= bfd_get_32 (info
->abfd
, pos
);
1729 insn
= (insn
& 0xffe00000) | (29 << 16);
1730 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
, pos
);
1731 info
->changed_contents
= TRUE
;
1733 irel
->r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
),
1735 info
->changed_relocs
= TRUE
;
1742 elf64_alpha_relax_tls_get_addr (info
, symval
, irel
, is_gd
)
1743 struct alpha_relax_info
*info
;
1745 Elf_Internal_Rela
*irel
;
1750 Elf_Internal_Rela
*gpdisp
, *hint
;
1751 bfd_boolean dynamic
, use_gottprel
;
1753 dynamic
= alpha_elf_dynamic_symbol_p (&info
->h
->root
, info
->link_info
);
1755 /* ??? For LD relaxation, we need a symbol referencing the beginning
1756 of the TLS segment. */
1760 /* If a TLS symbol is accessed using IE at least once, there is no point
1761 to use dynamic model for it. */
1762 if (is_gd
&& info
->h
&& (info
->h
->flags
& ALPHA_ELF_LINK_HASH_TLS_IE
))
1765 /* If the symbol is local, and we've already committed to DF_STATIC_TLS,
1766 then we might as well relax to IE. */
1767 else if (info
->link_info
->shared
&& !dynamic
1768 && (info
->link_info
->flags
& DF_STATIC_TLS
))
1771 /* Otherwise we must be building an executable to do anything. */
1772 else if (info
->link_info
->shared
)
1775 /* The TLSGD/TLSLDM relocation must be followed by a LITERAL and
1776 the matching LITUSE_TLS relocations. */
1777 if (irel
+ 2 >= info
->relend
)
1779 if (ELF64_R_TYPE (irel
[1].r_info
) != R_ALPHA_LITERAL
1780 || ELF64_R_TYPE (irel
[2].r_info
) != R_ALPHA_LITUSE
1781 || irel
[2].r_addend
!= (is_gd
? LITUSE_ALPHA_TLSGD
: LITUSE_ALPHA_TLSLDM
))
1784 /* There must be a GPDISP relocation positioned immediately after the
1785 LITUSE relocation. */
1786 gpdisp
= elf64_alpha_find_reloc_at_ofs (info
->relocs
, info
->relend
,
1787 irel
[2].r_offset
+ 4, R_ALPHA_GPDISP
);
1791 pos
[0] = info
->contents
+ irel
[0].r_offset
;
1792 pos
[1] = info
->contents
+ irel
[1].r_offset
;
1793 pos
[2] = info
->contents
+ irel
[2].r_offset
;
1794 pos
[3] = info
->contents
+ gpdisp
->r_offset
;
1795 pos
[4] = pos
[3] + gpdisp
->r_addend
;
1797 /* Only positions 0 and 1 are allowed to be out of order. */
1798 if (pos
[1] < pos
[0])
1800 bfd_byte
*tmp
= pos
[0];
1804 if (pos
[1] >= pos
[2] || pos
[2] >= pos
[3] || pos
[3] >= pos
[4])
1807 /* Reduce the use count on the LITERAL relocation. Do this before we
1808 smash the symndx when we adjust the relocations below. */
1810 struct alpha_elf_got_entry
*lit_gotent
;
1811 struct alpha_elf_link_hash_entry
*lit_h
;
1814 BFD_ASSERT (ELF64_R_SYM (irel
[1].r_info
) >= info
->symtab_hdr
->sh_info
);
1815 indx
= ELF64_R_SYM (irel
[1].r_info
) - info
->symtab_hdr
->sh_info
;
1816 lit_h
= alpha_elf_sym_hashes (info
->abfd
)[indx
];
1818 while (lit_h
->root
.root
.type
== bfd_link_hash_indirect
1819 || lit_h
->root
.root
.type
== bfd_link_hash_warning
)
1820 lit_h
= (struct alpha_elf_link_hash_entry
*) lit_h
->root
.root
.u
.i
.link
;
1822 for (lit_gotent
= lit_h
->got_entries
; lit_gotent
;
1823 lit_gotent
= lit_gotent
->next
)
1824 if (lit_gotent
->gotobj
== info
->gotobj
1825 && lit_gotent
->reloc_type
== R_ALPHA_LITERAL
1826 && lit_gotent
->addend
== irel
[1].r_addend
)
1828 BFD_ASSERT (lit_gotent
);
1830 if (--lit_gotent
->use_count
== 0)
1832 int sz
= alpha_got_entry_size (R_ALPHA_LITERAL
);
1833 alpha_elf_tdata (info
->gotobj
)->total_got_size
-= sz
;
1839 lda $16,x($gp) !tlsgd!1
1840 ldq $27,__tls_get_addr($gp) !literal!1
1841 jsr $26,($27)__tls_get_addr !lituse_tlsgd!1
1842 ldah $29,0($26) !gpdisp!2
1843 lda $29,0($29) !gpdisp!2
1845 ldq $16,x($gp) !gottprel
1850 or the first pair to
1851 lda $16,x($gp) !tprel
1854 ldah $16,x($gp) !tprelhi
1855 lda $16,x($16) !tprello
1859 use_gottprel
= FALSE
;
1860 switch (!dynamic
&& !info
->link_info
->shared
)
1865 bfd_signed_vma disp
;
1867 BFD_ASSERT (info
->tls_segment
!= NULL
);
1868 tp_base
= alpha_get_tprel_base (info
->tls_segment
);
1869 disp
= symval
- tp_base
;
1871 if (disp
>= -0x8000 && disp
< 0x8000)
1873 insn
= (OP_LDA
<< 26) | (16 << 21) | (31 << 16);
1874 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
, pos
[0]);
1875 bfd_put_32 (info
->abfd
, (bfd_vma
) INSN_UNOP
, pos
[1]);
1877 irel
[0].r_offset
= pos
[0] - info
->contents
;
1878 irel
[0].r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
),
1880 irel
[1].r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1883 else if (disp
>= -(bfd_signed_vma
) 0x80000000
1884 && disp
< (bfd_signed_vma
) 0x7fff8000)
1886 insn
= (OP_LDAH
<< 26) | (16 << 21) | (31 << 16);
1887 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
, pos
[0]);
1888 insn
= (OP_LDA
<< 26) | (16 << 21) | (16 << 16);
1889 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
, pos
[1]);
1891 irel
[0].r_offset
= pos
[0] - info
->contents
;
1892 irel
[0].r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
),
1894 irel
[1].r_offset
= pos
[1] - info
->contents
;
1895 irel
[1].r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
),
1903 use_gottprel
= TRUE
;
1905 insn
= (OP_LDQ
<< 26) | (16 << 21) | (29 << 16);
1906 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
, pos
[0]);
1907 bfd_put_32 (info
->abfd
, (bfd_vma
) INSN_UNOP
, pos
[1]);
1909 irel
[0].r_offset
= pos
[0] - info
->contents
;
1910 irel
[0].r_info
= ELF64_R_INFO (ELF64_R_SYM (irel
->r_info
),
1912 irel
[1].r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1916 bfd_put_32 (info
->abfd
, (bfd_vma
) INSN_RDUNIQ
, pos
[2]);
1918 insn
= INSN_ADDQ
| (16 << 21) | (0 << 16) | (0 << 0);
1919 bfd_put_32 (info
->abfd
, (bfd_vma
) insn
, pos
[3]);
1921 bfd_put_32 (info
->abfd
, (bfd_vma
) INSN_UNOP
, pos
[4]);
1923 irel
[2].r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1924 gpdisp
->r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1926 hint
= elf64_alpha_find_reloc_at_ofs (info
->relocs
, info
->relend
,
1927 irel
[2].r_offset
, R_ALPHA_HINT
);
1929 hint
->r_info
= ELF64_R_INFO (0, R_ALPHA_NONE
);
1931 info
->changed_contents
= TRUE
;
1932 info
->changed_relocs
= TRUE
;
1934 /* Reduce the use count on the TLSGD/TLSLDM relocation. */
1935 if (--info
->gotent
->use_count
== 0)
1937 int sz
= alpha_got_entry_size (info
->gotent
->reloc_type
);
1938 alpha_elf_tdata (info
->gotobj
)->total_got_size
-= sz
;
1940 alpha_elf_tdata (info
->gotobj
)->local_got_size
-= sz
;
1943 /* If we've switched to a GOTTPREL relocation, increment the reference
1944 count on that got entry. */
1947 struct alpha_elf_got_entry
*tprel_gotent
;
1949 for (tprel_gotent
= *info
->first_gotent
; tprel_gotent
;
1950 tprel_gotent
= tprel_gotent
->next
)
1951 if (tprel_gotent
->gotobj
== info
->gotobj
1952 && tprel_gotent
->reloc_type
== R_ALPHA_GOTTPREL
1953 && tprel_gotent
->addend
== irel
->r_addend
)
1956 tprel_gotent
->use_count
++;
1959 if (info
->gotent
->use_count
== 0)
1960 tprel_gotent
= info
->gotent
;
1963 tprel_gotent
= (struct alpha_elf_got_entry
*)
1964 bfd_alloc (info
->abfd
, sizeof (struct alpha_elf_got_entry
));
1968 tprel_gotent
->next
= *info
->first_gotent
;
1969 *info
->first_gotent
= tprel_gotent
;
1971 tprel_gotent
->gotobj
= info
->gotobj
;
1972 tprel_gotent
->addend
= irel
->r_addend
;
1973 tprel_gotent
->got_offset
= -1;
1974 tprel_gotent
->reloc_done
= 0;
1975 tprel_gotent
->reloc_xlated
= 0;
1978 tprel_gotent
->use_count
= 1;
1979 tprel_gotent
->reloc_type
= R_ALPHA_GOTTPREL
;
1986 static struct elf_link_tls_segment
*
1987 elf64_alpha_relax_find_tls_segment (info
, seg
)
1988 struct alpha_relax_info
*info
;
1989 struct elf_link_tls_segment
*seg
;
1991 bfd
*output_bfd
= info
->sec
->output_section
->owner
;
1996 for (o
= output_bfd
->sections
; o
; o
= o
->next
)
1997 if ((o
->flags
& SEC_THREAD_LOCAL
) != 0
1998 && (o
->flags
& SEC_LOAD
) != 0)
2010 if (bfd_get_section_alignment (output_bfd
, o
) > align
)
2011 align
= bfd_get_section_alignment (output_bfd
, o
);
2013 size
= o
->_raw_size
;
2014 if (size
== 0 && (o
->flags
& SEC_HAS_CONTENTS
) == 0)
2016 struct bfd_link_order
*lo
;
2017 for (lo
= o
->link_order_head
; lo
; lo
= lo
->next
)
2018 if (size
< lo
->offset
+ lo
->size
)
2019 size
= lo
->offset
+ lo
->size
;
2021 end
= o
->vma
+ size
;
2024 while (o
&& (o
->flags
& SEC_THREAD_LOCAL
));
2027 seg
->size
= end
- base
;
2034 elf64_alpha_relax_section (abfd
, sec
, link_info
, again
)
2037 struct bfd_link_info
*link_info
;
2040 Elf_Internal_Shdr
*symtab_hdr
;
2041 Elf_Internal_Rela
*internal_relocs
;
2042 Elf_Internal_Rela
*irel
, *irelend
;
2043 Elf_Internal_Sym
*isymbuf
= NULL
;
2044 struct alpha_elf_got_entry
**local_got_entries
;
2045 struct alpha_relax_info info
;
2046 struct elf_link_tls_segment tls_segment
;
2048 /* We are not currently changing any sizes, so only one pass. */
2051 if (link_info
->relocateable
2052 || (sec
->flags
& SEC_RELOC
) == 0
2053 || sec
->reloc_count
== 0)
2056 /* If this is the first time we have been called for this section,
2057 initialize the cooked size. */
2058 if (sec
->_cooked_size
== 0)
2059 sec
->_cooked_size
= sec
->_raw_size
;
2061 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2062 local_got_entries
= alpha_elf_tdata(abfd
)->local_got_entries
;
2064 /* Load the relocations for this section. */
2065 internal_relocs
= (_bfd_elf64_link_read_relocs
2066 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
2067 link_info
->keep_memory
));
2068 if (internal_relocs
== NULL
)
2071 memset(&info
, 0, sizeof (info
));
2074 info
.link_info
= link_info
;
2075 info
.symtab_hdr
= symtab_hdr
;
2076 info
.relocs
= internal_relocs
;
2077 info
.relend
= irelend
= internal_relocs
+ sec
->reloc_count
;
2079 /* Find the GP for this object. Do not store the result back via
2080 _bfd_set_gp_value, since this could change again before final. */
2081 info
.gotobj
= alpha_elf_tdata (abfd
)->gotobj
;
2084 asection
*sgot
= alpha_elf_tdata (info
.gotobj
)->got
;
2085 info
.gp
= (sgot
->output_section
->vma
2086 + sgot
->output_offset
2090 /* Get the section contents. */
2091 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
2092 info
.contents
= elf_section_data (sec
)->this_hdr
.contents
;
2095 info
.contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
2096 if (info
.contents
== NULL
)
2099 if (! bfd_get_section_contents (abfd
, sec
, info
.contents
,
2100 (file_ptr
) 0, sec
->_raw_size
))
2104 /* Compute the TLS segment information. The version normally found in
2105 elf_hash_table (link_info)->tls_segment isn't built until final_link.
2106 ??? Probably should look into extracting this into a common function. */
2107 info
.tls_segment
= elf64_alpha_relax_find_tls_segment (&info
, &tls_segment
);
2109 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
2112 struct alpha_elf_got_entry
*gotent
;
2113 unsigned long r_type
= ELF64_R_TYPE (irel
->r_info
);
2115 /* Early exit for unhandled or unrelaxable relocations. */
2118 case R_ALPHA_LITERAL
:
2119 case R_ALPHA_GPRELHIGH
:
2120 case R_ALPHA_GPRELLOW
:
2121 case R_ALPHA_GOTDTPREL
:
2122 case R_ALPHA_GOTTPREL
:
2124 case R_ALPHA_TLSLDM
:
2130 /* Get the value of the symbol referred to by the reloc. */
2131 if (ELF64_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
2133 /* A local symbol. */
2134 Elf_Internal_Sym
*isym
;
2136 /* Read this BFD's local symbols. */
2137 if (isymbuf
== NULL
)
2139 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
2140 if (isymbuf
== NULL
)
2141 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
2142 symtab_hdr
->sh_info
, 0,
2144 if (isymbuf
== NULL
)
2148 isym
= isymbuf
+ ELF64_R_SYM (irel
->r_info
);
2149 if (isym
->st_shndx
== SHN_UNDEF
)
2151 else if (isym
->st_shndx
== SHN_ABS
)
2152 info
.tsec
= bfd_abs_section_ptr
;
2153 else if (isym
->st_shndx
== SHN_COMMON
)
2154 info
.tsec
= bfd_com_section_ptr
;
2156 info
.tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2159 info
.other
= isym
->st_other
;
2160 info
.first_gotent
= &local_got_entries
[ELF64_R_SYM(irel
->r_info
)];
2161 symval
= isym
->st_value
;
2166 struct alpha_elf_link_hash_entry
*h
;
2168 indx
= ELF64_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
2169 h
= alpha_elf_sym_hashes (abfd
)[indx
];
2170 BFD_ASSERT (h
!= NULL
);
2172 while (h
->root
.root
.type
== bfd_link_hash_indirect
2173 || h
->root
.root
.type
== bfd_link_hash_warning
)
2174 h
= (struct alpha_elf_link_hash_entry
*)h
->root
.root
.u
.i
.link
;
2176 /* If the symbol is undefined, we can't do anything with it. */
2177 if (h
->root
.root
.type
== bfd_link_hash_undefweak
2178 || h
->root
.root
.type
== bfd_link_hash_undefined
)
2181 /* If the symbol isn't defined in the current module, again
2182 we can't do anything. */
2183 if (!(h
->root
.elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
))
2187 info
.tsec
= h
->root
.root
.u
.def
.section
;
2188 info
.other
= h
->root
.other
;
2189 info
.first_gotent
= &h
->got_entries
;
2190 symval
= h
->root
.root
.u
.def
.value
;
2193 /* Search for the got entry to be used by this relocation. */
2194 for (gotent
= *info
.first_gotent
; gotent
; gotent
= gotent
->next
)
2195 if (gotent
->gotobj
== info
.gotobj
2196 && gotent
->reloc_type
== r_type
2197 && gotent
->addend
== irel
->r_addend
)
2199 info
.gotent
= gotent
;
2201 symval
+= info
.tsec
->output_section
->vma
+ info
.tsec
->output_offset
;
2202 symval
+= irel
->r_addend
;
2206 case R_ALPHA_LITERAL
:
2207 BFD_ASSERT(info
.gotent
!= NULL
);
2209 /* If there exist LITUSE relocations immediately following, this
2210 opens up all sorts of interesting optimizations, because we
2211 now know every location that this address load is used. */
2212 if (irel
+1 < irelend
2213 && ELF64_R_TYPE (irel
[1].r_info
) == R_ALPHA_LITUSE
)
2215 if (!elf64_alpha_relax_with_lituse (&info
, symval
, irel
))
2220 if (!elf64_alpha_relax_got_load (&info
, symval
, irel
, r_type
))
2225 case R_ALPHA_GPRELHIGH
:
2226 case R_ALPHA_GPRELLOW
:
2227 if (!elf64_alpha_relax_gprelhilo (&info
, symval
, irel
,
2228 r_type
== R_ALPHA_GPRELHIGH
))
2232 case R_ALPHA_GOTDTPREL
:
2233 case R_ALPHA_GOTTPREL
:
2234 BFD_ASSERT(info
.gotent
!= NULL
);
2235 if (!elf64_alpha_relax_got_load (&info
, symval
, irel
, r_type
))
2240 case R_ALPHA_TLSLDM
:
2241 BFD_ASSERT(info
.gotent
!= NULL
);
2242 if (!elf64_alpha_relax_tls_get_addr (&info
, symval
, irel
,
2243 r_type
== R_ALPHA_TLSGD
))
2249 if (!elf64_alpha_size_plt_section (link_info
))
2251 if (!elf64_alpha_size_got_sections (link_info
))
2253 if (!elf64_alpha_size_rela_got_section (link_info
))
2257 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
2259 if (!link_info
->keep_memory
)
2263 /* Cache the symbols for elf_link_input_bfd. */
2264 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
2268 if (info
.contents
!= NULL
2269 && elf_section_data (sec
)->this_hdr
.contents
!= info
.contents
)
2271 if (!info
.changed_contents
&& !link_info
->keep_memory
)
2272 free (info
.contents
);
2275 /* Cache the section contents for elf_link_input_bfd. */
2276 elf_section_data (sec
)->this_hdr
.contents
= info
.contents
;
2280 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
2282 if (!info
.changed_relocs
)
2283 free (internal_relocs
);
2285 elf_section_data (sec
)->relocs
= internal_relocs
;
2288 *again
= info
.changed_contents
|| info
.changed_relocs
;
2294 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
2296 if (info
.contents
!= NULL
2297 && elf_section_data (sec
)->this_hdr
.contents
!= info
.contents
)
2298 free (info
.contents
);
2299 if (internal_relocs
!= NULL
2300 && elf_section_data (sec
)->relocs
!= internal_relocs
)
2301 free (internal_relocs
);
2306 #define PLT_HEADER_SIZE 32
2307 #define PLT_HEADER_WORD1 (bfd_vma) 0xc3600000 /* br $27,.+4 */
2308 #define PLT_HEADER_WORD2 (bfd_vma) 0xa77b000c /* ldq $27,12($27) */
2309 #define PLT_HEADER_WORD3 (bfd_vma) 0x47ff041f /* nop */
2310 #define PLT_HEADER_WORD4 (bfd_vma) 0x6b7b0000 /* jmp $27,($27) */
2312 #define PLT_ENTRY_SIZE 12
2313 #define PLT_ENTRY_WORD1 0xc3800000 /* br $28, plt0 */
2314 #define PLT_ENTRY_WORD2 0
2315 #define PLT_ENTRY_WORD3 0
2317 #define MAX_GOT_SIZE (64*1024)
2319 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so"
2321 /* Handle an Alpha specific section when reading an object file. This
2322 is called when elfcode.h finds a section with an unknown type.
2323 FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure
2327 elf64_alpha_section_from_shdr (abfd
, hdr
, name
)
2329 Elf_Internal_Shdr
*hdr
;
2334 /* There ought to be a place to keep ELF backend specific flags, but
2335 at the moment there isn't one. We just keep track of the
2336 sections by their name, instead. Fortunately, the ABI gives
2337 suggested names for all the MIPS specific sections, so we will
2338 probably get away with this. */
2339 switch (hdr
->sh_type
)
2341 case SHT_ALPHA_DEBUG
:
2342 if (strcmp (name
, ".mdebug") != 0)
2349 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
))
2351 newsect
= hdr
->bfd_section
;
2353 if (hdr
->sh_type
== SHT_ALPHA_DEBUG
)
2355 if (! bfd_set_section_flags (abfd
, newsect
,
2356 (bfd_get_section_flags (abfd
, newsect
)
2364 /* Convert Alpha specific section flags to bfd internal section flags. */
2367 elf64_alpha_section_flags (flags
, hdr
)
2369 Elf_Internal_Shdr
*hdr
;
2371 if (hdr
->sh_flags
& SHF_ALPHA_GPREL
)
2372 *flags
|= SEC_SMALL_DATA
;
2377 /* Set the correct type for an Alpha ELF section. We do this by the
2378 section name, which is a hack, but ought to work. */
2381 elf64_alpha_fake_sections (abfd
, hdr
, sec
)
2383 Elf_Internal_Shdr
*hdr
;
2386 register const char *name
;
2388 name
= bfd_get_section_name (abfd
, sec
);
2390 if (strcmp (name
, ".mdebug") == 0)
2392 hdr
->sh_type
= SHT_ALPHA_DEBUG
;
2393 /* In a shared object on Irix 5.3, the .mdebug section has an
2394 entsize of 0. FIXME: Does this matter? */
2395 if ((abfd
->flags
& DYNAMIC
) != 0 )
2396 hdr
->sh_entsize
= 0;
2398 hdr
->sh_entsize
= 1;
2400 else if ((sec
->flags
& SEC_SMALL_DATA
)
2401 || strcmp (name
, ".sdata") == 0
2402 || strcmp (name
, ".sbss") == 0
2403 || strcmp (name
, ".lit4") == 0
2404 || strcmp (name
, ".lit8") == 0)
2405 hdr
->sh_flags
|= SHF_ALPHA_GPREL
;
2410 /* Hook called by the linker routine which adds symbols from an object
2411 file. We use it to put .comm items in .sbss, and not .bss. */
2414 elf64_alpha_add_symbol_hook (abfd
, info
, sym
, namep
, flagsp
, secp
, valp
)
2416 struct bfd_link_info
*info
;
2417 const Elf_Internal_Sym
*sym
;
2418 const char **namep ATTRIBUTE_UNUSED
;
2419 flagword
*flagsp ATTRIBUTE_UNUSED
;
2423 if (sym
->st_shndx
== SHN_COMMON
2424 && !info
->relocateable
2425 && sym
->st_size
<= elf_gp_size (abfd
))
2427 /* Common symbols less than or equal to -G nn bytes are
2428 automatically put into .sbss. */
2430 asection
*scomm
= bfd_get_section_by_name (abfd
, ".scommon");
2434 scomm
= bfd_make_section (abfd
, ".scommon");
2436 || !bfd_set_section_flags (abfd
, scomm
, (SEC_ALLOC
2438 | SEC_LINKER_CREATED
)))
2443 *valp
= sym
->st_size
;
2449 /* Create the .got section. */
2452 elf64_alpha_create_got_section(abfd
, info
)
2454 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
2458 if (bfd_get_section_by_name (abfd
, ".got"))
2461 s
= bfd_make_section (abfd
, ".got");
2463 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
2466 | SEC_LINKER_CREATED
))
2467 || !bfd_set_section_alignment (abfd
, s
, 3))
2470 alpha_elf_tdata (abfd
)->got
= s
;
2475 /* Create all the dynamic sections. */
2478 elf64_alpha_create_dynamic_sections (abfd
, info
)
2480 struct bfd_link_info
*info
;
2483 struct elf_link_hash_entry
*h
;
2484 struct bfd_link_hash_entry
*bh
;
2486 /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */
2488 s
= bfd_make_section (abfd
, ".plt");
2490 || ! bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
2493 | SEC_LINKER_CREATED
2495 || ! bfd_set_section_alignment (abfd
, s
, 3))
2498 /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
2501 if (! (_bfd_generic_link_add_one_symbol
2502 (info
, abfd
, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL
, s
,
2503 (bfd_vma
) 0, (const char *) NULL
, FALSE
,
2504 get_elf_backend_data (abfd
)->collect
, &bh
)))
2506 h
= (struct elf_link_hash_entry
*) bh
;
2507 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
2508 h
->type
= STT_OBJECT
;
2511 && ! _bfd_elf_link_record_dynamic_symbol (info
, h
))
2514 s
= bfd_make_section (abfd
, ".rela.plt");
2516 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
2519 | SEC_LINKER_CREATED
2521 || ! bfd_set_section_alignment (abfd
, s
, 3))
2524 /* We may or may not have created a .got section for this object, but
2525 we definitely havn't done the rest of the work. */
2527 if (!elf64_alpha_create_got_section (abfd
, info
))
2530 s
= bfd_make_section(abfd
, ".rela.got");
2532 || !bfd_set_section_flags (abfd
, s
, (SEC_ALLOC
| SEC_LOAD
2535 | SEC_LINKER_CREATED
2537 || !bfd_set_section_alignment (abfd
, s
, 3))
2540 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
2541 dynobj's .got section. We don't do this in the linker script
2542 because we don't want to define the symbol if we are not creating
2543 a global offset table. */
2545 if (!(_bfd_generic_link_add_one_symbol
2546 (info
, abfd
, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL
,
2547 alpha_elf_tdata(abfd
)->got
, (bfd_vma
) 0, (const char *) NULL
,
2548 FALSE
, get_elf_backend_data (abfd
)->collect
, &bh
)))
2550 h
= (struct elf_link_hash_entry
*) bh
;
2551 h
->elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
2552 h
->type
= STT_OBJECT
;
2555 && ! _bfd_elf_link_record_dynamic_symbol (info
, h
))
2558 elf_hash_table (info
)->hgot
= h
;
2563 /* Read ECOFF debugging information from a .mdebug section into a
2564 ecoff_debug_info structure. */
2567 elf64_alpha_read_ecoff_info (abfd
, section
, debug
)
2570 struct ecoff_debug_info
*debug
;
2573 const struct ecoff_debug_swap
*swap
;
2574 char *ext_hdr
= NULL
;
2576 swap
= get_elf_backend_data (abfd
)->elf_backend_ecoff_debug_swap
;
2577 memset (debug
, 0, sizeof (*debug
));
2579 ext_hdr
= (char *) bfd_malloc (swap
->external_hdr_size
);
2580 if (ext_hdr
== NULL
&& swap
->external_hdr_size
!= 0)
2583 if (! bfd_get_section_contents (abfd
, section
, ext_hdr
, (file_ptr
) 0,
2584 swap
->external_hdr_size
))
2587 symhdr
= &debug
->symbolic_header
;
2588 (*swap
->swap_hdr_in
) (abfd
, ext_hdr
, symhdr
);
2590 /* The symbolic header contains absolute file offsets and sizes to
2592 #define READ(ptr, offset, count, size, type) \
2593 if (symhdr->count == 0) \
2594 debug->ptr = NULL; \
2597 bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
2598 debug->ptr = (type) bfd_malloc (amt); \
2599 if (debug->ptr == NULL) \
2600 goto error_return; \
2601 if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
2602 || bfd_bread (debug->ptr, amt, abfd) != amt) \
2603 goto error_return; \
2606 READ (line
, cbLineOffset
, cbLine
, sizeof (unsigned char), unsigned char *);
2607 READ (external_dnr
, cbDnOffset
, idnMax
, swap
->external_dnr_size
, PTR
);
2608 READ (external_pdr
, cbPdOffset
, ipdMax
, swap
->external_pdr_size
, PTR
);
2609 READ (external_sym
, cbSymOffset
, isymMax
, swap
->external_sym_size
, PTR
);
2610 READ (external_opt
, cbOptOffset
, ioptMax
, swap
->external_opt_size
, PTR
);
2611 READ (external_aux
, cbAuxOffset
, iauxMax
, sizeof (union aux_ext
),
2613 READ (ss
, cbSsOffset
, issMax
, sizeof (char), char *);
2614 READ (ssext
, cbSsExtOffset
, issExtMax
, sizeof (char), char *);
2615 READ (external_fdr
, cbFdOffset
, ifdMax
, swap
->external_fdr_size
, PTR
);
2616 READ (external_rfd
, cbRfdOffset
, crfd
, swap
->external_rfd_size
, PTR
);
2617 READ (external_ext
, cbExtOffset
, iextMax
, swap
->external_ext_size
, PTR
);
2621 debug
->adjust
= NULL
;
2626 if (ext_hdr
!= NULL
)
2628 if (debug
->line
!= NULL
)
2630 if (debug
->external_dnr
!= NULL
)
2631 free (debug
->external_dnr
);
2632 if (debug
->external_pdr
!= NULL
)
2633 free (debug
->external_pdr
);
2634 if (debug
->external_sym
!= NULL
)
2635 free (debug
->external_sym
);
2636 if (debug
->external_opt
!= NULL
)
2637 free (debug
->external_opt
);
2638 if (debug
->external_aux
!= NULL
)
2639 free (debug
->external_aux
);
2640 if (debug
->ss
!= NULL
)
2642 if (debug
->ssext
!= NULL
)
2643 free (debug
->ssext
);
2644 if (debug
->external_fdr
!= NULL
)
2645 free (debug
->external_fdr
);
2646 if (debug
->external_rfd
!= NULL
)
2647 free (debug
->external_rfd
);
2648 if (debug
->external_ext
!= NULL
)
2649 free (debug
->external_ext
);
2653 /* Alpha ELF local labels start with '$'. */
2656 elf64_alpha_is_local_label_name (abfd
, name
)
2657 bfd
*abfd ATTRIBUTE_UNUSED
;
2660 return name
[0] == '$';
2663 /* Alpha ELF follows MIPS ELF in using a special find_nearest_line
2664 routine in order to handle the ECOFF debugging information. We
2665 still call this mips_elf_find_line because of the slot
2666 find_line_info in elf_obj_tdata is declared that way. */
2668 struct mips_elf_find_line
2670 struct ecoff_debug_info d
;
2671 struct ecoff_find_line i
;
2675 elf64_alpha_find_nearest_line (abfd
, section
, symbols
, offset
, filename_ptr
,
2676 functionname_ptr
, line_ptr
)
2681 const char **filename_ptr
;
2682 const char **functionname_ptr
;
2683 unsigned int *line_ptr
;
2687 if (_bfd_dwarf2_find_nearest_line (abfd
, section
, symbols
, offset
,
2688 filename_ptr
, functionname_ptr
,
2690 &elf_tdata (abfd
)->dwarf2_find_line_info
))
2693 msec
= bfd_get_section_by_name (abfd
, ".mdebug");
2697 struct mips_elf_find_line
*fi
;
2698 const struct ecoff_debug_swap
* const swap
=
2699 get_elf_backend_data (abfd
)->elf_backend_ecoff_debug_swap
;
2701 /* If we are called during a link, alpha_elf_final_link may have
2702 cleared the SEC_HAS_CONTENTS field. We force it back on here
2703 if appropriate (which it normally will be). */
2704 origflags
= msec
->flags
;
2705 if (elf_section_data (msec
)->this_hdr
.sh_type
!= SHT_NOBITS
)
2706 msec
->flags
|= SEC_HAS_CONTENTS
;
2708 fi
= elf_tdata (abfd
)->find_line_info
;
2711 bfd_size_type external_fdr_size
;
2714 struct fdr
*fdr_ptr
;
2715 bfd_size_type amt
= sizeof (struct mips_elf_find_line
);
2717 fi
= (struct mips_elf_find_line
*) bfd_zalloc (abfd
, amt
);
2720 msec
->flags
= origflags
;
2724 if (!elf64_alpha_read_ecoff_info (abfd
, msec
, &fi
->d
))
2726 msec
->flags
= origflags
;
2730 /* Swap in the FDR information. */
2731 amt
= fi
->d
.symbolic_header
.ifdMax
* sizeof (struct fdr
);
2732 fi
->d
.fdr
= (struct fdr
*) bfd_alloc (abfd
, amt
);
2733 if (fi
->d
.fdr
== NULL
)
2735 msec
->flags
= origflags
;
2738 external_fdr_size
= swap
->external_fdr_size
;
2739 fdr_ptr
= fi
->d
.fdr
;
2740 fraw_src
= (char *) fi
->d
.external_fdr
;
2741 fraw_end
= (fraw_src
2742 + fi
->d
.symbolic_header
.ifdMax
* external_fdr_size
);
2743 for (; fraw_src
< fraw_end
; fraw_src
+= external_fdr_size
, fdr_ptr
++)
2744 (*swap
->swap_fdr_in
) (abfd
, (PTR
) fraw_src
, fdr_ptr
);
2746 elf_tdata (abfd
)->find_line_info
= fi
;
2748 /* Note that we don't bother to ever free this information.
2749 find_nearest_line is either called all the time, as in
2750 objdump -l, so the information should be saved, or it is
2751 rarely called, as in ld error messages, so the memory
2752 wasted is unimportant. Still, it would probably be a
2753 good idea for free_cached_info to throw it away. */
2756 if (_bfd_ecoff_locate_line (abfd
, section
, offset
, &fi
->d
, swap
,
2757 &fi
->i
, filename_ptr
, functionname_ptr
,
2760 msec
->flags
= origflags
;
2764 msec
->flags
= origflags
;
2767 /* Fall back on the generic ELF find_nearest_line routine. */
2769 return _bfd_elf_find_nearest_line (abfd
, section
, symbols
, offset
,
2770 filename_ptr
, functionname_ptr
,
2774 /* Structure used to pass information to alpha_elf_output_extsym. */
2779 struct bfd_link_info
*info
;
2780 struct ecoff_debug_info
*debug
;
2781 const struct ecoff_debug_swap
*swap
;
2786 elf64_alpha_output_extsym (h
, data
)
2787 struct alpha_elf_link_hash_entry
*h
;
2790 struct extsym_info
*einfo
= (struct extsym_info
*) data
;
2792 asection
*sec
, *output_section
;
2794 if (h
->root
.root
.type
== bfd_link_hash_warning
)
2795 h
= (struct alpha_elf_link_hash_entry
*) h
->root
.root
.u
.i
.link
;
2797 if (h
->root
.indx
== -2)
2799 else if (((h
->root
.elf_link_hash_flags
& ELF_LINK_HASH_DEF_DYNAMIC
) != 0
2800 || (h
->root
.elf_link_hash_flags
& ELF_LINK_HASH_REF_DYNAMIC
) != 0)
2801 && (h
->root
.elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
) == 0
2802 && (h
->root
.elf_link_hash_flags
& ELF_LINK_HASH_REF_REGULAR
) == 0)
2804 else if (einfo
->info
->strip
== strip_all
2805 || (einfo
->info
->strip
== strip_some
2806 && bfd_hash_lookup (einfo
->info
->keep_hash
,
2807 h
->root
.root
.root
.string
,
2808 FALSE
, FALSE
) == NULL
))
2816 if (h
->esym
.ifd
== -2)
2819 h
->esym
.cobol_main
= 0;
2820 h
->esym
.weakext
= 0;
2821 h
->esym
.reserved
= 0;
2822 h
->esym
.ifd
= ifdNil
;
2823 h
->esym
.asym
.value
= 0;
2824 h
->esym
.asym
.st
= stGlobal
;
2826 if (h
->root
.root
.type
!= bfd_link_hash_defined
2827 && h
->root
.root
.type
!= bfd_link_hash_defweak
)
2828 h
->esym
.asym
.sc
= scAbs
;
2833 sec
= h
->root
.root
.u
.def
.section
;
2834 output_section
= sec
->output_section
;
2836 /* When making a shared library and symbol h is the one from
2837 the another shared library, OUTPUT_SECTION may be null. */
2838 if (output_section
== NULL
)
2839 h
->esym
.asym
.sc
= scUndefined
;
2842 name
= bfd_section_name (output_section
->owner
, output_section
);
2844 if (strcmp (name
, ".text") == 0)
2845 h
->esym
.asym
.sc
= scText
;
2846 else if (strcmp (name
, ".data") == 0)
2847 h
->esym
.asym
.sc
= scData
;
2848 else if (strcmp (name
, ".sdata") == 0)
2849 h
->esym
.asym
.sc
= scSData
;
2850 else if (strcmp (name
, ".rodata") == 0
2851 || strcmp (name
, ".rdata") == 0)
2852 h
->esym
.asym
.sc
= scRData
;
2853 else if (strcmp (name
, ".bss") == 0)
2854 h
->esym
.asym
.sc
= scBss
;
2855 else if (strcmp (name
, ".sbss") == 0)
2856 h
->esym
.asym
.sc
= scSBss
;
2857 else if (strcmp (name
, ".init") == 0)
2858 h
->esym
.asym
.sc
= scInit
;
2859 else if (strcmp (name
, ".fini") == 0)
2860 h
->esym
.asym
.sc
= scFini
;
2862 h
->esym
.asym
.sc
= scAbs
;
2866 h
->esym
.asym
.reserved
= 0;
2867 h
->esym
.asym
.index
= indexNil
;
2870 if (h
->root
.root
.type
== bfd_link_hash_common
)
2871 h
->esym
.asym
.value
= h
->root
.root
.u
.c
.size
;
2872 else if (h
->root
.root
.type
== bfd_link_hash_defined
2873 || h
->root
.root
.type
== bfd_link_hash_defweak
)
2875 if (h
->esym
.asym
.sc
== scCommon
)
2876 h
->esym
.asym
.sc
= scBss
;
2877 else if (h
->esym
.asym
.sc
== scSCommon
)
2878 h
->esym
.asym
.sc
= scSBss
;
2880 sec
= h
->root
.root
.u
.def
.section
;
2881 output_section
= sec
->output_section
;
2882 if (output_section
!= NULL
)
2883 h
->esym
.asym
.value
= (h
->root
.root
.u
.def
.value
2884 + sec
->output_offset
2885 + output_section
->vma
);
2887 h
->esym
.asym
.value
= 0;
2889 else if ((h
->root
.elf_link_hash_flags
& ELF_LINK_HASH_NEEDS_PLT
) != 0)
2891 /* Set type and value for a symbol with a function stub. */
2892 h
->esym
.asym
.st
= stProc
;
2893 sec
= bfd_get_section_by_name (einfo
->abfd
, ".plt");
2895 h
->esym
.asym
.value
= 0;
2898 output_section
= sec
->output_section
;
2899 if (output_section
!= NULL
)
2900 h
->esym
.asym
.value
= (h
->root
.plt
.offset
2901 + sec
->output_offset
2902 + output_section
->vma
);
2904 h
->esym
.asym
.value
= 0;
2908 if (! bfd_ecoff_debug_one_external (einfo
->abfd
, einfo
->debug
, einfo
->swap
,
2909 h
->root
.root
.root
.string
,
2912 einfo
->failed
= TRUE
;
2919 /* Search for and possibly create a got entry. */
2921 static struct alpha_elf_got_entry
*
2922 get_got_entry (abfd
, h
, r_type
, r_symndx
, r_addend
)
2924 struct alpha_elf_link_hash_entry
*h
;
2925 unsigned long r_type
, r_symndx
;
2928 struct alpha_elf_got_entry
*gotent
;
2929 struct alpha_elf_got_entry
**slot
;
2932 slot
= &h
->got_entries
;
2935 /* This is a local .got entry -- record for merge. */
2937 struct alpha_elf_got_entry
**local_got_entries
;
2939 local_got_entries
= alpha_elf_tdata(abfd
)->local_got_entries
;
2940 if (!local_got_entries
)
2943 Elf_Internal_Shdr
*symtab_hdr
;
2945 symtab_hdr
= &elf_tdata(abfd
)->symtab_hdr
;
2946 size
= symtab_hdr
->sh_info
;
2947 size
*= sizeof (struct alpha_elf_got_entry
*);
2950 = (struct alpha_elf_got_entry
**) bfd_zalloc (abfd
, size
);
2951 if (!local_got_entries
)
2954 alpha_elf_tdata (abfd
)->local_got_entries
= local_got_entries
;
2957 slot
= &local_got_entries
[r_symndx
];
2960 for (gotent
= *slot
; gotent
; gotent
= gotent
->next
)
2961 if (gotent
->gotobj
== abfd
2962 && gotent
->reloc_type
== r_type
2963 && gotent
->addend
== r_addend
)
2971 amt
= sizeof (struct alpha_elf_got_entry
);
2972 gotent
= (struct alpha_elf_got_entry
*) bfd_alloc (abfd
, amt
);
2976 gotent
->gotobj
= abfd
;
2977 gotent
->addend
= r_addend
;
2978 gotent
->got_offset
= -1;
2979 gotent
->use_count
= 1;
2980 gotent
->reloc_type
= r_type
;
2981 gotent
->reloc_done
= 0;
2982 gotent
->reloc_xlated
= 0;
2984 gotent
->next
= *slot
;
2987 entry_size
= alpha_got_entry_size (r_type
);
2988 alpha_elf_tdata (abfd
)->total_got_size
+= entry_size
;
2990 alpha_elf_tdata(abfd
)->local_got_size
+= entry_size
;
2993 gotent
->use_count
+= 1;
2998 /* Handle dynamic relocations when doing an Alpha ELF link. */
3001 elf64_alpha_check_relocs (abfd
, info
, sec
, relocs
)
3003 struct bfd_link_info
*info
;
3005 const Elf_Internal_Rela
*relocs
;
3009 const char *rel_sec_name
;
3010 Elf_Internal_Shdr
*symtab_hdr
;
3011 struct alpha_elf_link_hash_entry
**sym_hashes
;
3012 const Elf_Internal_Rela
*rel
, *relend
;
3013 bfd_boolean got_created
;
3016 if (info
->relocateable
)
3019 dynobj
= elf_hash_table(info
)->dynobj
;
3021 elf_hash_table(info
)->dynobj
= dynobj
= abfd
;
3024 rel_sec_name
= NULL
;
3025 symtab_hdr
= &elf_tdata(abfd
)->symtab_hdr
;
3026 sym_hashes
= alpha_elf_sym_hashes(abfd
);
3027 got_created
= FALSE
;
3029 relend
= relocs
+ sec
->reloc_count
;
3030 for (rel
= relocs
; rel
< relend
; ++rel
)
3038 unsigned long r_symndx
, r_type
;
3039 struct alpha_elf_link_hash_entry
*h
;
3040 unsigned int gotent_flags
;
3041 bfd_boolean maybe_dynamic
;
3045 r_symndx
= ELF64_R_SYM (rel
->r_info
);
3046 if (r_symndx
< symtab_hdr
->sh_info
)
3050 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
3052 while (h
->root
.root
.type
== bfd_link_hash_indirect
3053 || h
->root
.root
.type
== bfd_link_hash_warning
)
3054 h
= (struct alpha_elf_link_hash_entry
*)h
->root
.root
.u
.i
.link
;
3056 h
->root
.elf_link_hash_flags
|= ELF_LINK_HASH_REF_REGULAR
;
3059 /* We can only get preliminary data on whether a symbol is
3060 locally or externally defined, as not all of the input files
3061 have yet been processed. Do something with what we know, as
3062 this may help reduce memory usage and processing time later. */
3063 maybe_dynamic
= FALSE
;
3064 if (h
&& ((info
->shared
3065 && (!info
->symbolic
|| info
->allow_shlib_undefined
))
3066 || ! (h
->root
.elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
)
3067 || h
->root
.root
.type
== bfd_link_hash_defweak
))
3068 maybe_dynamic
= TRUE
;
3072 r_type
= ELF64_R_TYPE (rel
->r_info
);
3073 addend
= rel
->r_addend
;
3077 case R_ALPHA_LITERAL
:
3078 need
= NEED_GOT
| NEED_GOT_ENTRY
;
3080 /* Remember how this literal is used from its LITUSEs.
3081 This will be important when it comes to decide if we can
3082 create a .plt entry for a function symbol. */
3083 while (++rel
< relend
&& ELF64_R_TYPE (rel
->r_info
) == R_ALPHA_LITUSE
)
3084 if (rel
->r_addend
>= 1 && rel
->r_addend
<= 5)
3085 gotent_flags
|= 1 << rel
->r_addend
;
3088 /* No LITUSEs -- presumably the address is used somehow. */
3089 if (gotent_flags
== 0)
3090 gotent_flags
= ALPHA_ELF_LINK_HASH_LU_ADDR
;
3093 case R_ALPHA_GPDISP
:
3094 case R_ALPHA_GPREL16
:
3095 case R_ALPHA_GPREL32
:
3096 case R_ALPHA_GPRELHIGH
:
3097 case R_ALPHA_GPRELLOW
:
3102 case R_ALPHA_REFLONG
:
3103 case R_ALPHA_REFQUAD
:
3104 if ((info
->shared
&& (sec
->flags
& SEC_ALLOC
)) || maybe_dynamic
)
3109 case R_ALPHA_TLSLDM
:
3110 case R_ALPHA_GOTDTPREL
:
3111 need
= NEED_GOT
| NEED_GOT_ENTRY
;
3114 case R_ALPHA_GOTTPREL
:
3115 need
= NEED_GOT
| NEED_GOT_ENTRY
;
3116 gotent_flags
= ALPHA_ELF_LINK_HASH_TLS_IE
;
3118 info
->flags
|= DF_STATIC_TLS
;
3121 case R_ALPHA_TPREL64
:
3122 if (info
->shared
|| maybe_dynamic
)
3125 info
->flags
|= DF_STATIC_TLS
;
3129 if (need
& NEED_GOT
)
3133 if (!elf64_alpha_create_got_section (abfd
, info
))
3136 /* Make sure the object's gotobj is set to itself so
3137 that we default to every object with its own .got.
3138 We'll merge .gots later once we've collected each
3140 alpha_elf_tdata(abfd
)->gotobj
= abfd
;
3146 if (need
& NEED_GOT_ENTRY
)
3148 struct alpha_elf_got_entry
*gotent
;
3150 gotent
= get_got_entry (abfd
, h
, r_type
, r_symndx
, addend
);
3156 gotent
->flags
|= gotent_flags
;
3159 gotent_flags
|= h
->flags
;
3160 h
->flags
= gotent_flags
;
3162 /* Make a guess as to whether a .plt entry is needed. */
3163 if ((gotent_flags
& ALPHA_ELF_LINK_HASH_LU_FUNC
)
3164 && !(gotent_flags
& ~ALPHA_ELF_LINK_HASH_LU_FUNC
))
3165 h
->root
.elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
3167 h
->root
.elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
3172 if (need
& NEED_DYNREL
)
3174 if (rel_sec_name
== NULL
)
3176 rel_sec_name
= (bfd_elf_string_from_elf_section
3177 (abfd
, elf_elfheader(abfd
)->e_shstrndx
,
3178 elf_section_data(sec
)->rel_hdr
.sh_name
));
3179 if (rel_sec_name
== NULL
)
3182 BFD_ASSERT (strncmp (rel_sec_name
, ".rela", 5) == 0
3183 && strcmp (bfd_get_section_name (abfd
, sec
),
3184 rel_sec_name
+5) == 0);
3187 /* We need to create the section here now whether we eventually
3188 use it or not so that it gets mapped to an output section by
3189 the linker. If not used, we'll kill it in
3190 size_dynamic_sections. */
3193 sreloc
= bfd_get_section_by_name (dynobj
, rel_sec_name
);
3198 sreloc
= bfd_make_section (dynobj
, rel_sec_name
);
3199 flags
= (SEC_HAS_CONTENTS
| SEC_IN_MEMORY
3200 | SEC_LINKER_CREATED
| SEC_READONLY
);
3201 if (sec
->flags
& SEC_ALLOC
)
3202 flags
|= SEC_ALLOC
| SEC_LOAD
;
3204 || !bfd_set_section_flags (dynobj
, sreloc
, flags
)
3205 || !bfd_set_section_alignment (dynobj
, sreloc
, 3))
3212 /* Since we havn't seen all of the input symbols yet, we
3213 don't know whether we'll actually need a dynamic relocation
3214 entry for this reloc. So make a record of it. Once we
3215 find out if this thing needs dynamic relocation we'll
3216 expand the relocation sections by the appropriate amount. */
3218 struct alpha_elf_reloc_entry
*rent
;
3220 for (rent
= h
->reloc_entries
; rent
; rent
= rent
->next
)
3221 if (rent
->rtype
== r_type
&& rent
->srel
== sreloc
)
3226 amt
= sizeof (struct alpha_elf_reloc_entry
);
3227 rent
= (struct alpha_elf_reloc_entry
*) bfd_alloc (abfd
, amt
);
3231 rent
->srel
= sreloc
;
3232 rent
->rtype
= r_type
;
3234 rent
->reltext
= ((sec
->flags
& (SEC_READONLY
| SEC_ALLOC
))
3235 == (SEC_READONLY
| SEC_ALLOC
));
3237 rent
->next
= h
->reloc_entries
;
3238 h
->reloc_entries
= rent
;
3243 else if (info
->shared
)
3245 /* If this is a shared library, and the section is to be
3246 loaded into memory, we need a RELATIVE reloc. */
3247 sreloc
->_raw_size
+= sizeof (Elf64_External_Rela
);
3248 if ((sec
->flags
& (SEC_READONLY
| SEC_ALLOC
))
3249 == (SEC_READONLY
| SEC_ALLOC
))
3250 info
->flags
|= DF_TEXTREL
;
3258 /* Adjust a symbol defined by a dynamic object and referenced by a
3259 regular object. The current definition is in some section of the
3260 dynamic object, but we're not including those sections. We have to
3261 change the definition to something the rest of the link can
3265 elf64_alpha_adjust_dynamic_symbol (info
, h
)
3266 struct bfd_link_info
*info
;
3267 struct elf_link_hash_entry
*h
;
3271 struct alpha_elf_link_hash_entry
*ah
;
3273 dynobj
= elf_hash_table(info
)->dynobj
;
3274 ah
= (struct alpha_elf_link_hash_entry
*)h
;
3276 /* Now that we've seen all of the input symbols, finalize our decision
3277 about whether this symbol should get a .plt entry. */
3279 if (alpha_elf_dynamic_symbol_p (h
, info
)
3280 && ((h
->type
== STT_FUNC
3281 && !(ah
->flags
& ALPHA_ELF_LINK_HASH_LU_ADDR
))
3282 || (h
->type
== STT_NOTYPE
3283 && (ah
->flags
& ALPHA_ELF_LINK_HASH_LU_FUNC
)
3284 && !(ah
->flags
& ~ALPHA_ELF_LINK_HASH_LU_FUNC
)))
3285 /* Don't prevent otherwise valid programs from linking by attempting
3286 to create a new .got entry somewhere. A Correct Solution would be
3287 to add a new .got section to a new object file and let it be merged
3288 somewhere later. But for now don't bother. */
3291 h
->elf_link_hash_flags
|= ELF_LINK_HASH_NEEDS_PLT
;
3293 s
= bfd_get_section_by_name(dynobj
, ".plt");
3294 if (!s
&& !elf64_alpha_create_dynamic_sections (dynobj
, info
))
3297 /* The first bit of the .plt is reserved. */
3298 if (s
->_raw_size
== 0)
3299 s
->_raw_size
= PLT_HEADER_SIZE
;
3301 h
->plt
.offset
= s
->_raw_size
;
3302 s
->_raw_size
+= PLT_ENTRY_SIZE
;
3304 /* If this symbol is not defined in a regular file, and we are not
3305 generating a shared library, then set the symbol to the location
3306 in the .plt. This is required to make function pointers compare
3307 equal between the normal executable and the shared library. */
3309 && h
->root
.type
!= bfd_link_hash_defweak
)
3311 h
->root
.u
.def
.section
= s
;
3312 h
->root
.u
.def
.value
= h
->plt
.offset
;
3315 /* We also need a JMP_SLOT entry in the .rela.plt section. */
3316 s
= bfd_get_section_by_name (dynobj
, ".rela.plt");
3317 BFD_ASSERT (s
!= NULL
);
3318 s
->_raw_size
+= sizeof (Elf64_External_Rela
);
3323 h
->elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
3325 /* If this is a weak symbol, and there is a real definition, the
3326 processor independent code will have arranged for us to see the
3327 real definition first, and we can just use the same value. */
3328 if (h
->weakdef
!= NULL
)
3330 BFD_ASSERT (h
->weakdef
->root
.type
== bfd_link_hash_defined
3331 || h
->weakdef
->root
.type
== bfd_link_hash_defweak
);
3332 h
->root
.u
.def
.section
= h
->weakdef
->root
.u
.def
.section
;
3333 h
->root
.u
.def
.value
= h
->weakdef
->root
.u
.def
.value
;
3337 /* This is a reference to a symbol defined by a dynamic object which
3338 is not a function. The Alpha, since it uses .got entries for all
3339 symbols even in regular objects, does not need the hackery of a
3340 .dynbss section and COPY dynamic relocations. */
3345 /* Symbol versioning can create new symbols, and make our old symbols
3346 indirect to the new ones. Consolidate the got and reloc information
3347 in these situations. */
3350 elf64_alpha_merge_ind_symbols (hi
, dummy
)
3351 struct alpha_elf_link_hash_entry
*hi
;
3352 PTR dummy ATTRIBUTE_UNUSED
;
3354 struct alpha_elf_link_hash_entry
*hs
;
3356 if (hi
->root
.root
.type
!= bfd_link_hash_indirect
)
3360 hs
= (struct alpha_elf_link_hash_entry
*)hs
->root
.root
.u
.i
.link
;
3361 } while (hs
->root
.root
.type
== bfd_link_hash_indirect
);
3363 /* Merge the flags. Whee. */
3365 hs
->flags
|= hi
->flags
;
3367 /* Merge the .got entries. Cannibalize the old symbol's list in
3368 doing so, since we don't need it anymore. */
3370 if (hs
->got_entries
== NULL
)
3371 hs
->got_entries
= hi
->got_entries
;
3374 struct alpha_elf_got_entry
*gi
, *gs
, *gin
, *gsh
;
3376 gsh
= hs
->got_entries
;
3377 for (gi
= hi
->got_entries
; gi
; gi
= gin
)
3380 for (gs
= gsh
; gs
; gs
= gs
->next
)
3381 if (gi
->gotobj
== gs
->gotobj
3382 && gi
->reloc_type
== gs
->reloc_type
3383 && gi
->addend
== gs
->addend
)
3385 gi
->use_count
+= gs
->use_count
;
3388 gi
->next
= hs
->got_entries
;
3389 hs
->got_entries
= gi
;
3393 hi
->got_entries
= NULL
;
3395 /* And similar for the reloc entries. */
3397 if (hs
->reloc_entries
== NULL
)
3398 hs
->reloc_entries
= hi
->reloc_entries
;
3401 struct alpha_elf_reloc_entry
*ri
, *rs
, *rin
, *rsh
;
3403 rsh
= hs
->reloc_entries
;
3404 for (ri
= hi
->reloc_entries
; ri
; ri
= rin
)
3407 for (rs
= rsh
; rs
; rs
= rs
->next
)
3408 if (ri
->rtype
== rs
->rtype
&& ri
->srel
== rs
->srel
)
3410 rs
->count
+= ri
->count
;
3413 ri
->next
= hs
->reloc_entries
;
3414 hs
->reloc_entries
= ri
;
3418 hi
->reloc_entries
= NULL
;
3423 /* Is it possible to merge two object file's .got tables? */
3426 elf64_alpha_can_merge_gots (a
, b
)
3429 int total
= alpha_elf_tdata (a
)->total_got_size
;
3432 /* Trivial quick fallout test. */
3433 if (total
+ alpha_elf_tdata (b
)->total_got_size
<= MAX_GOT_SIZE
)
3436 /* By their nature, local .got entries cannot be merged. */
3437 if ((total
+= alpha_elf_tdata (b
)->local_got_size
) > MAX_GOT_SIZE
)
3440 /* Failing the common trivial comparison, we must effectively
3441 perform the merge. Not actually performing the merge means that
3442 we don't have to store undo information in case we fail. */
3443 for (bsub
= b
; bsub
; bsub
= alpha_elf_tdata (bsub
)->in_got_link_next
)
3445 struct alpha_elf_link_hash_entry
**hashes
= alpha_elf_sym_hashes (bsub
);
3446 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (bsub
)->symtab_hdr
;
3449 n
= NUM_SHDR_ENTRIES (symtab_hdr
) - symtab_hdr
->sh_info
;
3450 for (i
= 0; i
< n
; ++i
)
3452 struct alpha_elf_got_entry
*ae
, *be
;
3453 struct alpha_elf_link_hash_entry
*h
;
3456 while (h
->root
.root
.type
== bfd_link_hash_indirect
3457 || h
->root
.root
.type
== bfd_link_hash_warning
)
3458 h
= (struct alpha_elf_link_hash_entry
*)h
->root
.root
.u
.i
.link
;
3460 for (be
= h
->got_entries
; be
; be
= be
->next
)
3462 if (be
->use_count
== 0)
3464 if (be
->gotobj
!= b
)
3467 for (ae
= h
->got_entries
; ae
; ae
= ae
->next
)
3469 && ae
->reloc_type
== be
->reloc_type
3470 && ae
->addend
== be
->addend
)
3473 total
+= alpha_got_entry_size (be
->reloc_type
);
3474 if (total
> MAX_GOT_SIZE
)
3484 /* Actually merge two .got tables. */
3487 elf64_alpha_merge_gots (a
, b
)
3490 int total
= alpha_elf_tdata (a
)->total_got_size
;
3493 /* Remember local expansion. */
3495 int e
= alpha_elf_tdata (b
)->local_got_size
;
3497 alpha_elf_tdata (a
)->local_got_size
+= e
;
3500 for (bsub
= b
; bsub
; bsub
= alpha_elf_tdata (bsub
)->in_got_link_next
)
3502 struct alpha_elf_got_entry
**local_got_entries
;
3503 struct alpha_elf_link_hash_entry
**hashes
;
3504 Elf_Internal_Shdr
*symtab_hdr
;
3507 /* Let the local .got entries know they are part of a new subsegment. */
3508 local_got_entries
= alpha_elf_tdata (bsub
)->local_got_entries
;
3509 if (local_got_entries
)
3511 n
= elf_tdata (bsub
)->symtab_hdr
.sh_info
;
3512 for (i
= 0; i
< n
; ++i
)
3514 struct alpha_elf_got_entry
*ent
;
3515 for (ent
= local_got_entries
[i
]; ent
; ent
= ent
->next
)
3520 /* Merge the global .got entries. */
3521 hashes
= alpha_elf_sym_hashes (bsub
);
3522 symtab_hdr
= &elf_tdata (bsub
)->symtab_hdr
;
3524 n
= NUM_SHDR_ENTRIES (symtab_hdr
) - symtab_hdr
->sh_info
;
3525 for (i
= 0; i
< n
; ++i
)
3527 struct alpha_elf_got_entry
*ae
, *be
, **pbe
, **start
;
3528 struct alpha_elf_link_hash_entry
*h
;
3531 while (h
->root
.root
.type
== bfd_link_hash_indirect
3532 || h
->root
.root
.type
== bfd_link_hash_warning
)
3533 h
= (struct alpha_elf_link_hash_entry
*)h
->root
.root
.u
.i
.link
;
3535 start
= &h
->got_entries
;
3536 for (pbe
= start
, be
= *start
; be
; pbe
= &be
->next
, be
= be
->next
)
3538 if (be
->use_count
== 0)
3543 if (be
->gotobj
!= b
)
3546 for (ae
= *start
; ae
; ae
= ae
->next
)
3548 && ae
->reloc_type
== be
->reloc_type
3549 && ae
->addend
== be
->addend
)
3551 ae
->flags
|= be
->flags
;
3552 ae
->use_count
+= be
->use_count
;
3557 total
+= alpha_got_entry_size (be
->reloc_type
);
3563 alpha_elf_tdata (bsub
)->gotobj
= a
;
3565 alpha_elf_tdata (a
)->total_got_size
= total
;
3567 /* Merge the two in_got chains. */
3572 while ((next
= alpha_elf_tdata (bsub
)->in_got_link_next
) != NULL
)
3575 alpha_elf_tdata (bsub
)->in_got_link_next
= b
;
3579 /* Calculate the offsets for the got entries. */
3582 elf64_alpha_calc_got_offsets_for_symbol (h
, arg
)
3583 struct alpha_elf_link_hash_entry
*h
;
3584 PTR arg ATTRIBUTE_UNUSED
;
3586 struct alpha_elf_got_entry
*gotent
;
3588 if (h
->root
.root
.type
== bfd_link_hash_warning
)
3589 h
= (struct alpha_elf_link_hash_entry
*) h
->root
.root
.u
.i
.link
;
3591 for (gotent
= h
->got_entries
; gotent
; gotent
= gotent
->next
)
3592 if (gotent
->use_count
> 0)
3595 = &alpha_elf_tdata (gotent
->gotobj
)->got
->_raw_size
;
3597 gotent
->got_offset
= *plge
;
3598 *plge
+= alpha_got_entry_size (gotent
->reloc_type
);
3605 elf64_alpha_calc_got_offsets (info
)
3606 struct bfd_link_info
*info
;
3608 bfd
*i
, *got_list
= alpha_elf_hash_table(info
)->got_list
;
3610 /* First, zero out the .got sizes, as we may be recalculating the
3611 .got after optimizing it. */
3612 for (i
= got_list
; i
; i
= alpha_elf_tdata(i
)->got_link_next
)
3613 alpha_elf_tdata(i
)->got
->_raw_size
= 0;
3615 /* Next, fill in the offsets for all the global entries. */
3616 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info
),
3617 elf64_alpha_calc_got_offsets_for_symbol
,
3620 /* Finally, fill in the offsets for the local entries. */
3621 for (i
= got_list
; i
; i
= alpha_elf_tdata(i
)->got_link_next
)
3623 bfd_size_type got_offset
= alpha_elf_tdata(i
)->got
->_raw_size
;
3626 for (j
= i
; j
; j
= alpha_elf_tdata(j
)->in_got_link_next
)
3628 struct alpha_elf_got_entry
**local_got_entries
, *gotent
;
3631 local_got_entries
= alpha_elf_tdata(j
)->local_got_entries
;
3632 if (!local_got_entries
)
3635 for (k
= 0, n
= elf_tdata(j
)->symtab_hdr
.sh_info
; k
< n
; ++k
)
3636 for (gotent
= local_got_entries
[k
]; gotent
; gotent
= gotent
->next
)
3637 if (gotent
->use_count
> 0)
3639 gotent
->got_offset
= got_offset
;
3640 got_offset
+= alpha_got_entry_size (gotent
->reloc_type
);
3644 alpha_elf_tdata(i
)->got
->_raw_size
= got_offset
;
3645 alpha_elf_tdata(i
)->got
->_cooked_size
= got_offset
;
3649 /* Constructs the gots. */
3652 elf64_alpha_size_got_sections (info
)
3653 struct bfd_link_info
*info
;
3655 bfd
*i
, *got_list
, *cur_got_obj
= NULL
;
3656 int something_changed
= 0;
3658 got_list
= alpha_elf_hash_table (info
)->got_list
;
3660 /* On the first time through, pretend we have an existing got list
3661 consisting of all of the input files. */
3662 if (got_list
== NULL
)
3664 for (i
= info
->input_bfds
; i
; i
= i
->link_next
)
3666 bfd
*this_got
= alpha_elf_tdata (i
)->gotobj
;
3667 if (this_got
== NULL
)
3670 /* We are assuming no merging has yet ocurred. */
3671 BFD_ASSERT (this_got
== i
);
3673 if (alpha_elf_tdata (this_got
)->total_got_size
> MAX_GOT_SIZE
)
3675 /* Yikes! A single object file has too many entries. */
3676 (*_bfd_error_handler
)
3677 (_("%s: .got subsegment exceeds 64K (size %d)"),
3678 bfd_archive_filename (i
),
3679 alpha_elf_tdata (this_got
)->total_got_size
);
3683 if (got_list
== NULL
)
3684 got_list
= this_got
;
3686 alpha_elf_tdata(cur_got_obj
)->got_link_next
= this_got
;
3687 cur_got_obj
= this_got
;
3690 /* Strange degenerate case of no got references. */
3691 if (got_list
== NULL
)
3694 alpha_elf_hash_table (info
)->got_list
= got_list
;
3696 /* Force got offsets to be recalculated. */
3697 something_changed
= 1;
3700 cur_got_obj
= got_list
;
3701 i
= alpha_elf_tdata(cur_got_obj
)->got_link_next
;
3704 if (elf64_alpha_can_merge_gots (cur_got_obj
, i
))
3706 elf64_alpha_merge_gots (cur_got_obj
, i
);
3707 i
= alpha_elf_tdata(i
)->got_link_next
;
3708 alpha_elf_tdata(cur_got_obj
)->got_link_next
= i
;
3709 something_changed
= 1;
3714 i
= alpha_elf_tdata(i
)->got_link_next
;
3718 /* Once the gots have been merged, fill in the got offsets for
3719 everything therein. */
3720 if (1 || something_changed
)
3721 elf64_alpha_calc_got_offsets (info
);
3726 /* Called from relax_section to rebuild the PLT in light of
3727 potential changes in the function's status. */
3730 elf64_alpha_size_plt_section (info
)
3731 struct bfd_link_info
*info
;
3733 asection
*splt
, *spltrel
;
3734 unsigned long entries
;
3737 dynobj
= elf_hash_table(info
)->dynobj
;
3738 splt
= bfd_get_section_by_name(dynobj
, ".plt");
3742 splt
->_raw_size
= 0;
3744 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info
),
3745 elf64_alpha_size_plt_section_1
, splt
);
3747 splt
->_cooked_size
= splt
->_raw_size
;
3749 /* Every plt entry requires a JMP_SLOT relocation. */
3750 spltrel
= bfd_get_section_by_name (dynobj
, ".rela.plt");
3751 if (splt
->_raw_size
)
3752 entries
= (splt
->_raw_size
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
3755 spltrel
->_raw_size
= entries
* sizeof (Elf64_External_Rela
);
3756 spltrel
->_cooked_size
= spltrel
->_raw_size
;
3762 elf64_alpha_size_plt_section_1 (h
, data
)
3763 struct alpha_elf_link_hash_entry
*h
;
3766 asection
*splt
= (asection
*) data
;
3767 struct alpha_elf_got_entry
*gotent
;
3769 /* If we didn't need an entry before, we still don't. */
3770 if (!(h
->root
.elf_link_hash_flags
& ELF_LINK_HASH_NEEDS_PLT
))
3773 /* There must still be a LITERAL got entry for the function. */
3774 for (gotent
= h
->got_entries
; gotent
; gotent
= gotent
->next
)
3775 if (gotent
->reloc_type
== R_ALPHA_LITERAL
3776 && gotent
->use_count
> 0)
3779 /* If there is, reset the PLT offset. If not, there's no longer
3780 a need for the PLT entry. */
3783 if (splt
->_raw_size
== 0)
3784 splt
->_raw_size
= PLT_HEADER_SIZE
;
3785 h
->root
.plt
.offset
= splt
->_raw_size
;
3786 splt
->_raw_size
+= PLT_ENTRY_SIZE
;
3790 h
->root
.elf_link_hash_flags
&= ~ELF_LINK_HASH_NEEDS_PLT
;
3791 h
->root
.plt
.offset
= -1;
3798 elf64_alpha_always_size_sections (output_bfd
, info
)
3799 bfd
*output_bfd ATTRIBUTE_UNUSED
;
3800 struct bfd_link_info
*info
;
3804 if (info
->relocateable
)
3807 /* First, take care of the indirect symbols created by versioning. */
3808 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info
),
3809 elf64_alpha_merge_ind_symbols
,
3812 if (!elf64_alpha_size_got_sections (info
))
3815 /* Allocate space for all of the .got subsections. */
3816 i
= alpha_elf_hash_table (info
)->got_list
;
3817 for ( ; i
; i
= alpha_elf_tdata(i
)->got_link_next
)
3819 asection
*s
= alpha_elf_tdata(i
)->got
;
3820 if (s
->_raw_size
> 0)
3822 s
->contents
= (bfd_byte
*) bfd_zalloc (i
, s
->_raw_size
);
3823 if (s
->contents
== NULL
)
3831 /* The number of dynamic relocations required by a static relocation. */
3834 alpha_dynamic_entries_for_reloc (r_type
, dynamic
, shared
)
3835 int r_type
, dynamic
, shared
;
3839 /* May appear in GOT entries. */
3841 return (dynamic
? 2 : shared
? 1 : 0);
3842 case R_ALPHA_TLSLDM
:
3844 case R_ALPHA_LITERAL
:
3845 return dynamic
|| shared
;
3846 case R_ALPHA_GOTDTPREL
:
3847 case R_ALPHA_GOTTPREL
:
3850 /* May appear in data sections. */
3851 case R_ALPHA_REFLONG
:
3852 case R_ALPHA_REFQUAD
:
3853 return dynamic
|| shared
;
3854 case R_ALPHA_SREL64
:
3855 case R_ALPHA_TPREL64
:
3858 /* Everything else is illegal. We'll issue an error during
3859 relocate_section. */
3865 /* Work out the sizes of the dynamic relocation entries. */
3868 elf64_alpha_calc_dynrel_sizes (h
, info
)
3869 struct alpha_elf_link_hash_entry
*h
;
3870 struct bfd_link_info
*info
;
3872 bfd_boolean dynamic
;
3873 struct alpha_elf_reloc_entry
*relent
;
3874 unsigned long entries
;
3876 if (h
->root
.root
.type
== bfd_link_hash_warning
)
3877 h
= (struct alpha_elf_link_hash_entry
*) h
->root
.root
.u
.i
.link
;
3879 /* If the symbol was defined as a common symbol in a regular object
3880 file, and there was no definition in any dynamic object, then the
3881 linker will have allocated space for the symbol in a common
3882 section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been
3883 set. This is done for dynamic symbols in
3884 elf_adjust_dynamic_symbol but this is not done for non-dynamic
3885 symbols, somehow. */
3886 if (((h
->root
.elf_link_hash_flags
3887 & (ELF_LINK_HASH_DEF_REGULAR
3888 | ELF_LINK_HASH_REF_REGULAR
3889 | ELF_LINK_HASH_DEF_DYNAMIC
))
3890 == ELF_LINK_HASH_REF_REGULAR
)
3891 && (h
->root
.root
.type
== bfd_link_hash_defined
3892 || h
->root
.root
.type
== bfd_link_hash_defweak
)
3893 && !(h
->root
.root
.u
.def
.section
->owner
->flags
& DYNAMIC
))
3894 h
->root
.elf_link_hash_flags
|= ELF_LINK_HASH_DEF_REGULAR
;
3896 /* If the symbol is dynamic, we'll need all the relocations in their
3897 natural form. If this is a shared object, and it has been forced
3898 local, we'll need the same number of RELATIVE relocations. */
3900 dynamic
= alpha_elf_dynamic_symbol_p (&h
->root
, info
);
3902 for (relent
= h
->reloc_entries
; relent
; relent
= relent
->next
)
3904 entries
= alpha_dynamic_entries_for_reloc (relent
->rtype
, dynamic
,
3908 relent
->srel
->_raw_size
+=
3909 entries
* sizeof (Elf64_External_Rela
) * relent
->count
;
3910 if (relent
->reltext
)
3911 info
->flags
|= DT_TEXTREL
;
3918 /* Set the sizes of the dynamic relocation sections. */
3921 elf64_alpha_size_rela_got_section (info
)
3922 struct bfd_link_info
*info
;
3924 unsigned long entries
;
3928 /* Shared libraries often require RELATIVE relocs, and some relocs
3929 require attention for the main application as well. */
3932 for (i
= alpha_elf_hash_table(info
)->got_list
;
3933 i
; i
= alpha_elf_tdata(i
)->got_link_next
)
3937 for (j
= i
; j
; j
= alpha_elf_tdata(j
)->in_got_link_next
)
3939 struct alpha_elf_got_entry
**local_got_entries
, *gotent
;
3942 local_got_entries
= alpha_elf_tdata(j
)->local_got_entries
;
3943 if (!local_got_entries
)
3946 for (k
= 0, n
= elf_tdata(j
)->symtab_hdr
.sh_info
; k
< n
; ++k
)
3947 for (gotent
= local_got_entries
[k
];
3948 gotent
; gotent
= gotent
->next
)
3949 if (gotent
->use_count
> 0)
3950 entries
+= (alpha_dynamic_entries_for_reloc
3951 (gotent
->reloc_type
, 0, info
->shared
));
3955 dynobj
= elf_hash_table(info
)->dynobj
;
3956 srel
= bfd_get_section_by_name (dynobj
, ".rela.got");
3959 BFD_ASSERT (entries
== 0);
3962 srel
->_raw_size
= sizeof (Elf64_External_Rela
) * entries
;
3964 /* Now do the non-local symbols. */
3965 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info
),
3966 elf64_alpha_size_rela_got_1
, info
);
3968 srel
->_cooked_size
= srel
->_raw_size
;
3973 /* Subroutine of elf64_alpha_size_rela_got_section for doing the
3977 elf64_alpha_size_rela_got_1 (h
, info
)
3978 struct alpha_elf_link_hash_entry
*h
;
3979 struct bfd_link_info
*info
;
3981 bfd_boolean dynamic
;
3982 struct alpha_elf_got_entry
*gotent
;
3983 unsigned long entries
;
3985 if (h
->root
.root
.type
== bfd_link_hash_warning
)
3986 h
= (struct alpha_elf_link_hash_entry
*) h
->root
.root
.u
.i
.link
;
3988 /* If the symbol is dynamic, we'll need all the relocations in their
3989 natural form. If this is a shared object, and it has been forced
3990 local, we'll need the same number of RELATIVE relocations. */
3992 dynamic
= alpha_elf_dynamic_symbol_p (&h
->root
, info
);
3995 for (gotent
= h
->got_entries
; gotent
; gotent
= gotent
->next
)
3996 if (gotent
->use_count
> 0)
3997 entries
+= alpha_dynamic_entries_for_reloc (gotent
->reloc_type
,
3998 dynamic
, info
->shared
);
4000 /* If we are using a .plt entry, subtract one, as the first
4001 reference uses a .rela.plt entry instead. */
4002 if (h
->root
.plt
.offset
!= MINUS_ONE
)
4007 bfd
*dynobj
= elf_hash_table(info
)->dynobj
;
4008 asection
*srel
= bfd_get_section_by_name (dynobj
, ".rela.got");
4009 BFD_ASSERT (srel
!= NULL
);
4010 srel
->_raw_size
+= sizeof (Elf64_External_Rela
) * entries
;
4016 /* Set the sizes of the dynamic sections. */
4019 elf64_alpha_size_dynamic_sections (output_bfd
, info
)
4020 bfd
*output_bfd ATTRIBUTE_UNUSED
;
4021 struct bfd_link_info
*info
;
4027 dynobj
= elf_hash_table(info
)->dynobj
;
4028 BFD_ASSERT(dynobj
!= NULL
);
4030 if (elf_hash_table (info
)->dynamic_sections_created
)
4032 /* Set the contents of the .interp section to the interpreter. */
4035 s
= bfd_get_section_by_name (dynobj
, ".interp");
4036 BFD_ASSERT (s
!= NULL
);
4037 s
->_raw_size
= sizeof ELF_DYNAMIC_INTERPRETER
;
4038 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
4041 /* Now that we've seen all of the input files, we can decide which
4042 symbols need dynamic relocation entries and which don't. We've
4043 collected information in check_relocs that we can now apply to
4044 size the dynamic relocation sections. */
4045 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info
),
4046 elf64_alpha_calc_dynrel_sizes
, info
);
4048 elf64_alpha_size_rela_got_section (info
);
4050 /* else we're not dynamic and by definition we don't need such things. */
4052 /* The check_relocs and adjust_dynamic_symbol entry points have
4053 determined the sizes of the various dynamic sections. Allocate
4056 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
4061 if (!(s
->flags
& SEC_LINKER_CREATED
))
4064 /* It's OK to base decisions on the section name, because none
4065 of the dynobj section names depend upon the input files. */
4066 name
= bfd_get_section_name (dynobj
, s
);
4068 /* If we don't need this section, strip it from the output file.
4069 This is to handle .rela.bss and .rela.plt. We must create it
4070 in create_dynamic_sections, because it must be created before
4071 the linker maps input sections to output sections. The
4072 linker does that before adjust_dynamic_symbol is called, and
4073 it is that function which decides whether anything needs to
4074 go into these sections. */
4078 if (strncmp (name
, ".rela", 5) == 0)
4080 strip
= (s
->_raw_size
== 0);
4084 if (strcmp(name
, ".rela.plt") == 0)
4087 /* We use the reloc_count field as a counter if we need
4088 to copy relocs into the output file. */
4092 else if (strcmp (name
, ".plt") != 0)
4094 /* It's not one of our dynamic sections, so don't allocate space. */
4099 _bfd_strip_section_from_output (info
, s
);
4102 /* Allocate memory for the section contents. */
4103 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->_raw_size
);
4104 if (s
->contents
== NULL
&& s
->_raw_size
!= 0)
4109 if (elf_hash_table (info
)->dynamic_sections_created
)
4111 /* Add some entries to the .dynamic section. We fill in the
4112 values later, in elf64_alpha_finish_dynamic_sections, but we
4113 must add the entries now so that we get the correct size for
4114 the .dynamic section. The DT_DEBUG entry is filled in by the
4115 dynamic linker and used by the debugger. */
4116 #define add_dynamic_entry(TAG, VAL) \
4117 bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
4121 if (!add_dynamic_entry (DT_DEBUG
, 0))
4127 if (!add_dynamic_entry (DT_PLTGOT
, 0)
4128 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
4129 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
4130 || !add_dynamic_entry (DT_JMPREL
, 0))
4134 if (!add_dynamic_entry (DT_RELA
, 0)
4135 || !add_dynamic_entry (DT_RELASZ
, 0)
4136 || !add_dynamic_entry (DT_RELAENT
, sizeof (Elf64_External_Rela
)))
4139 if (info
->flags
& DF_TEXTREL
)
4141 if (!add_dynamic_entry (DT_TEXTREL
, 0))
4145 #undef add_dynamic_entry
4150 /* Relocate an Alpha ELF section for a relocatable link.
4152 We don't have to change anything unless the reloc is against a section
4153 symbol, in which case we have to adjust according to where the section
4154 symbol winds up in the output section. */
4157 elf64_alpha_relocate_section_r (output_bfd
, info
, input_bfd
, input_section
,
4158 contents
, relocs
, local_syms
, local_sections
)
4159 bfd
*output_bfd ATTRIBUTE_UNUSED
;
4160 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
4162 asection
*input_section
;
4163 bfd_byte
*contents ATTRIBUTE_UNUSED
;
4164 Elf_Internal_Rela
*relocs
;
4165 Elf_Internal_Sym
*local_syms
;
4166 asection
**local_sections
;
4168 unsigned long symtab_hdr_sh_info
;
4169 Elf_Internal_Rela
*rel
;
4170 Elf_Internal_Rela
*relend
;
4171 bfd_boolean ret_val
= TRUE
;
4173 symtab_hdr_sh_info
= elf_tdata (input_bfd
)->symtab_hdr
.sh_info
;
4175 relend
= relocs
+ input_section
->reloc_count
;
4176 for (rel
= relocs
; rel
< relend
; rel
++)
4178 unsigned long r_symndx
;
4179 Elf_Internal_Sym
*sym
;
4181 unsigned long r_type
;
4183 r_type
= ELF64_R_TYPE(rel
->r_info
);
4184 if (r_type
>= R_ALPHA_max
)
4186 (*_bfd_error_handler
)
4187 (_("%s: unknown relocation type %d"),
4188 bfd_archive_filename (input_bfd
), (int)r_type
);
4189 bfd_set_error (bfd_error_bad_value
);
4194 r_symndx
= ELF64_R_SYM(rel
->r_info
);
4196 /* The symbol associated with GPDISP and LITUSE is
4197 immaterial. Only the addend is significant. */
4198 if (r_type
== R_ALPHA_GPDISP
|| r_type
== R_ALPHA_LITUSE
)
4201 if (r_symndx
< symtab_hdr_sh_info
)
4203 sym
= local_syms
+ r_symndx
;
4204 if (ELF_ST_TYPE(sym
->st_info
) == STT_SECTION
)
4206 sec
= local_sections
[r_symndx
];
4207 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
4215 /* Relocate an Alpha ELF section. */
4218 elf64_alpha_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
4219 contents
, relocs
, local_syms
, local_sections
)
4221 struct bfd_link_info
*info
;
4223 asection
*input_section
;
4225 Elf_Internal_Rela
*relocs
;
4226 Elf_Internal_Sym
*local_syms
;
4227 asection
**local_sections
;
4229 Elf_Internal_Shdr
*symtab_hdr
;
4230 Elf_Internal_Rela
*rel
;
4231 Elf_Internal_Rela
*relend
;
4232 struct elf_link_tls_segment
*tls_segment
;
4233 asection
*sgot
, *srel
, *srelgot
;
4234 bfd
*dynobj
, *gotobj
;
4235 bfd_vma gp
, tp_base
, dtp_base
;
4236 struct alpha_elf_got_entry
**local_got_entries
;
4237 bfd_boolean ret_val
;
4238 const char *section_name
;
4240 /* Handle relocatable links with a smaller loop. */
4241 if (info
->relocateable
)
4242 return elf64_alpha_relocate_section_r (output_bfd
, info
, input_bfd
,
4243 input_section
, contents
, relocs
,
4244 local_syms
, local_sections
);
4246 /* This is a final link. */
4250 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
4252 dynobj
= elf_hash_table (info
)->dynobj
;
4254 srelgot
= bfd_get_section_by_name (dynobj
, ".rela.got");
4258 section_name
= (bfd_elf_string_from_elf_section
4259 (input_bfd
, elf_elfheader(input_bfd
)->e_shstrndx
,
4260 elf_section_data(input_section
)->rel_hdr
.sh_name
));
4261 BFD_ASSERT(section_name
!= NULL
);
4262 srel
= bfd_get_section_by_name (dynobj
, section_name
);
4264 /* Find the gp value for this input bfd. */
4265 gotobj
= alpha_elf_tdata (input_bfd
)->gotobj
;
4268 sgot
= alpha_elf_tdata (gotobj
)->got
;
4269 gp
= _bfd_get_gp_value (gotobj
);
4272 gp
= (sgot
->output_section
->vma
4273 + sgot
->output_offset
4275 _bfd_set_gp_value (gotobj
, gp
);
4284 local_got_entries
= alpha_elf_tdata(input_bfd
)->local_got_entries
;
4286 tls_segment
= elf_hash_table (info
)->tls_segment
;
4289 dtp_base
= alpha_get_dtprel_base (tls_segment
);
4290 tp_base
= alpha_get_tprel_base (tls_segment
);
4293 dtp_base
= tp_base
= 0;
4295 relend
= relocs
+ input_section
->reloc_count
;
4296 for (rel
= relocs
; rel
< relend
; rel
++)
4298 struct alpha_elf_link_hash_entry
*h
= NULL
;
4299 struct alpha_elf_got_entry
*gotent
;
4300 bfd_reloc_status_type r
;
4301 reloc_howto_type
*howto
;
4302 unsigned long r_symndx
;
4303 Elf_Internal_Sym
*sym
= NULL
;
4304 asection
*sec
= NULL
;
4307 bfd_boolean dynamic_symbol_p
;
4308 bfd_boolean undef_weak_ref
= FALSE
;
4309 unsigned long r_type
;
4311 r_type
= ELF64_R_TYPE(rel
->r_info
);
4312 if (r_type
>= R_ALPHA_max
)
4314 (*_bfd_error_handler
)
4315 (_("%s: unknown relocation type %d"),
4316 bfd_archive_filename (input_bfd
), (int)r_type
);
4317 bfd_set_error (bfd_error_bad_value
);
4322 howto
= elf64_alpha_howto_table
+ r_type
;
4323 r_symndx
= ELF64_R_SYM(rel
->r_info
);
4325 if (r_symndx
< symtab_hdr
->sh_info
)
4327 sym
= local_syms
+ r_symndx
;
4328 sec
= local_sections
[r_symndx
];
4329 value
= _bfd_elf_rela_local_sym (output_bfd
, sym
, sec
, rel
);
4331 if (local_got_entries
)
4332 gotent
= local_got_entries
[r_symndx
];
4336 /* Need to adjust local GOT entries' addends for SEC_MERGE
4337 unless it has been done already. */
4338 if ((sec
->flags
& SEC_MERGE
)
4339 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
4340 && (elf_section_data (sec
)->sec_info_type
4341 == ELF_INFO_TYPE_MERGE
)
4343 && !gotent
->reloc_xlated
)
4345 struct alpha_elf_got_entry
*ent
;
4348 for (ent
= gotent
; ent
; ent
= ent
->next
)
4350 ent
->reloc_xlated
= 1;
4351 if (ent
->use_count
== 0)
4355 _bfd_merged_section_offset (output_bfd
, &msec
,
4356 elf_section_data (sec
)->
4358 sym
->st_value
+ ent
->addend
,
4360 ent
->addend
-= sym
->st_value
;
4361 ent
->addend
+= msec
->output_section
->vma
4362 + msec
->output_offset
4363 - sec
->output_section
->vma
4364 - sec
->output_offset
;
4368 dynamic_symbol_p
= FALSE
;
4372 h
= alpha_elf_sym_hashes (input_bfd
)[r_symndx
- symtab_hdr
->sh_info
];
4374 while (h
->root
.root
.type
== bfd_link_hash_indirect
4375 || h
->root
.root
.type
== bfd_link_hash_warning
)
4376 h
= (struct alpha_elf_link_hash_entry
*)h
->root
.root
.u
.i
.link
;
4379 if (h
->root
.root
.type
== bfd_link_hash_defined
4380 || h
->root
.root
.type
== bfd_link_hash_defweak
)
4382 sec
= h
->root
.root
.u
.def
.section
;
4384 /* Detect the cases that sym_sec->output_section is
4385 expected to be NULL -- all cases in which the symbol
4386 is defined in another shared module. This includes
4387 PLT relocs for which we've created a PLT entry and
4388 other relocs for which we're prepared to create
4389 dynamic relocations. */
4390 /* ??? Just accept it NULL and continue. */
4392 if (sec
->output_section
!= NULL
)
4393 value
= (h
->root
.root
.u
.def
.value
4394 + sec
->output_section
->vma
4395 + sec
->output_offset
);
4397 else if (h
->root
.root
.type
== bfd_link_hash_undefweak
)
4398 undef_weak_ref
= TRUE
;
4399 else if (info
->shared
4400 && (!info
->symbolic
|| info
->allow_shlib_undefined
)
4401 && !info
->no_undefined
4402 && ELF_ST_VISIBILITY (h
->root
.other
) == STV_DEFAULT
)
4406 if (!((*info
->callbacks
->undefined_symbol
)
4407 (info
, h
->root
.root
.root
.string
, input_bfd
,
4408 input_section
, rel
->r_offset
,
4409 (!info
->shared
|| info
->no_undefined
4410 || ELF_ST_VISIBILITY (h
->root
.other
)))))
4416 dynamic_symbol_p
= alpha_elf_dynamic_symbol_p (&h
->root
, info
);
4417 gotent
= h
->got_entries
;
4420 addend
= rel
->r_addend
;
4423 /* Search for the proper got entry. */
4424 for (; gotent
; gotent
= gotent
->next
)
4425 if (gotent
->gotobj
== gotobj
4426 && gotent
->reloc_type
== r_type
4427 && gotent
->addend
== addend
)
4432 case R_ALPHA_GPDISP
:
4434 bfd_byte
*p_ldah
, *p_lda
;
4436 BFD_ASSERT(gp
!= 0);
4438 value
= (input_section
->output_section
->vma
4439 + input_section
->output_offset
4442 p_ldah
= contents
+ rel
->r_offset
;
4443 p_lda
= p_ldah
+ rel
->r_addend
;
4445 r
= elf64_alpha_do_reloc_gpdisp (input_bfd
, gp
- value
,
4450 case R_ALPHA_LITERAL
:
4451 BFD_ASSERT(sgot
!= NULL
);
4452 BFD_ASSERT(gp
!= 0);
4453 BFD_ASSERT(gotent
!= NULL
);
4454 BFD_ASSERT(gotent
->use_count
>= 1);
4456 if (!gotent
->reloc_done
)
4458 gotent
->reloc_done
= 1;
4460 bfd_put_64 (output_bfd
, value
,
4461 sgot
->contents
+ gotent
->got_offset
);
4463 /* If the symbol has been forced local, output a
4464 RELATIVE reloc, otherwise it will be handled in
4465 finish_dynamic_symbol. */
4466 if (info
->shared
&& !dynamic_symbol_p
)
4468 Elf_Internal_Rela outrel
;
4471 BFD_ASSERT(srelgot
!= NULL
);
4473 outrel
.r_offset
= (sgot
->output_section
->vma
4474 + sgot
->output_offset
4475 + gotent
->got_offset
);
4476 outrel
.r_info
= ELF64_R_INFO (0, R_ALPHA_RELATIVE
);
4477 outrel
.r_addend
= value
;
4479 loc
= srelgot
->contents
;
4480 loc
+= srelgot
->reloc_count
++ * sizeof (Elf64_External_Rela
);
4481 bfd_elf64_swap_reloca_out (output_bfd
, &outrel
, loc
);
4482 BFD_ASSERT (sizeof (Elf64_External_Rela
)
4483 * srelgot
->reloc_count
4484 <= srelgot
->_cooked_size
);
4488 value
= (sgot
->output_section
->vma
4489 + sgot
->output_offset
4490 + gotent
->got_offset
);
4494 case R_ALPHA_GPREL16
:
4495 case R_ALPHA_GPREL32
:
4496 case R_ALPHA_GPRELLOW
:
4497 if (dynamic_symbol_p
)
4499 (*_bfd_error_handler
)
4500 (_("%s: gp-relative relocation against dynamic symbol %s"),
4501 bfd_archive_filename (input_bfd
), h
->root
.root
.root
.string
);
4504 BFD_ASSERT(gp
!= 0);
4508 case R_ALPHA_GPRELHIGH
:
4509 if (dynamic_symbol_p
)
4511 (*_bfd_error_handler
)
4512 (_("%s: gp-relative relocation against dynamic symbol %s"),
4513 bfd_archive_filename (input_bfd
), h
->root
.root
.root
.string
);
4516 BFD_ASSERT(gp
!= 0);
4518 value
= ((bfd_signed_vma
) value
>> 16) + ((value
>> 15) & 1);
4522 /* A call to a dynamic symbol is definitely out of range of
4523 the 16-bit displacement. Don't bother writing anything. */
4524 if (dynamic_symbol_p
)
4529 /* The regular PC-relative stuff measures from the start of
4530 the instruction rather than the end. */
4534 case R_ALPHA_BRADDR
:
4535 if (dynamic_symbol_p
)
4537 (*_bfd_error_handler
)
4538 (_("%s: pc-relative relocation against dynamic symbol %s"),
4539 bfd_archive_filename (input_bfd
), h
->root
.root
.root
.string
);
4542 /* The regular PC-relative stuff measures from the start of
4543 the instruction rather than the end. */
4552 /* The regular PC-relative stuff measures from the start of
4553 the instruction rather than the end. */
4556 /* The source and destination gp must be the same. Note that
4557 the source will always have an assigned gp, since we forced
4558 one in check_relocs, but that the destination may not, as
4559 it might not have had any relocations at all. Also take
4560 care not to crash if H is an undefined symbol. */
4561 if (h
!= NULL
&& sec
!= NULL
4562 && alpha_elf_tdata (sec
->owner
)->gotobj
4563 && gotobj
!= alpha_elf_tdata (sec
->owner
)->gotobj
)
4565 (*_bfd_error_handler
)
4566 (_("%s: change in gp: BRSGP %s"),
4567 bfd_archive_filename (input_bfd
), h
->root
.root
.root
.string
);
4571 /* The symbol should be marked either NOPV or STD_GPLOAD. */
4573 other
= h
->root
.other
;
4575 other
= sym
->st_other
;
4576 switch (other
& STO_ALPHA_STD_GPLOAD
)
4578 case STO_ALPHA_NOPV
:
4580 case STO_ALPHA_STD_GPLOAD
:
4585 name
= h
->root
.root
.root
.string
;
4588 name
= (bfd_elf_string_from_elf_section
4589 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
4591 name
= _("<unknown>");
4592 else if (name
[0] == 0)
4593 name
= bfd_section_name (input_bfd
, sec
);
4595 (*_bfd_error_handler
)
4596 (_("%s: !samegp reloc against symbol without .prologue: %s"),
4597 bfd_archive_filename (input_bfd
), name
);
4605 case R_ALPHA_REFLONG
:
4606 case R_ALPHA_REFQUAD
:
4607 case R_ALPHA_DTPREL64
:
4608 case R_ALPHA_TPREL64
:
4610 Elf_Internal_Rela outrel
;
4613 /* Careful here to remember RELATIVE relocations for global
4614 variables for symbolic shared objects. */
4616 if (dynamic_symbol_p
)
4618 BFD_ASSERT(h
->root
.dynindx
!= -1);
4619 outrel
.r_info
= ELF64_R_INFO (h
->root
.dynindx
, r_type
);
4620 outrel
.r_addend
= addend
;
4621 addend
= 0, value
= 0;
4623 else if (r_type
== R_ALPHA_DTPREL64
)
4625 BFD_ASSERT(tls_segment
!= NULL
);
4629 else if (r_type
== R_ALPHA_TPREL64
)
4631 BFD_ASSERT(tls_segment
!= NULL
);
4635 else if (info
->shared
4637 && (input_section
->flags
& SEC_ALLOC
))
4639 if (r_type
== R_ALPHA_REFLONG
)
4641 (*_bfd_error_handler
)
4642 (_("%s: unhandled dynamic relocation against %s"),
4643 bfd_archive_filename (input_bfd
),
4644 h
->root
.root
.root
.string
);
4647 outrel
.r_info
= ELF64_R_INFO (0, R_ALPHA_RELATIVE
);
4648 outrel
.r_addend
= value
;
4653 BFD_ASSERT(srel
!= NULL
);
4656 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
4658 if ((outrel
.r_offset
| 1) != (bfd_vma
) -1)
4659 outrel
.r_offset
+= (input_section
->output_section
->vma
4660 + input_section
->output_offset
);
4662 memset (&outrel
, 0, sizeof outrel
);
4664 loc
= srel
->contents
;
4665 loc
+= srel
->reloc_count
++ * sizeof (Elf64_External_Rela
);
4666 bfd_elf64_swap_reloca_out (output_bfd
, &outrel
, loc
);
4667 BFD_ASSERT (sizeof (Elf64_External_Rela
) * srel
->reloc_count
4668 <= srel
->_cooked_size
);
4672 case R_ALPHA_SREL16
:
4673 case R_ALPHA_SREL32
:
4674 case R_ALPHA_SREL64
:
4675 if (dynamic_symbol_p
)
4677 (*_bfd_error_handler
)
4678 (_("%s: pc-relative relocation against dynamic symbol %s"),
4679 bfd_archive_filename (input_bfd
), h
->root
.root
.root
.string
);
4683 /* ??? .eh_frame references to discarded sections will be smashed
4684 to relocations against SHN_UNDEF. The .eh_frame format allows
4685 NULL to be encoded as 0 in any format, so this works here. */
4687 howto
= (elf64_alpha_howto_table
4688 + (r_type
- R_ALPHA_SREL32
+ R_ALPHA_REFLONG
));
4691 case R_ALPHA_TLSLDM
:
4692 /* Ignore the symbol for the relocation. The result is always
4693 the current module. */
4694 dynamic_symbol_p
= 0;
4698 if (!gotent
->reloc_done
)
4700 gotent
->reloc_done
= 1;
4702 /* Note that the module index for the main program is 1. */
4703 bfd_put_64 (output_bfd
, !info
->shared
&& !dynamic_symbol_p
,
4704 sgot
->contents
+ gotent
->got_offset
);
4706 /* If the symbol has been forced local, output a
4707 DTPMOD64 reloc, otherwise it will be handled in
4708 finish_dynamic_symbol. */
4709 if (info
->shared
&& !dynamic_symbol_p
)
4711 Elf_Internal_Rela outrel
;
4714 BFD_ASSERT(srelgot
!= NULL
);
4716 outrel
.r_offset
= (sgot
->output_section
->vma
4717 + sgot
->output_offset
4718 + gotent
->got_offset
);
4719 /* ??? Proper dynindx here. */
4720 outrel
.r_info
= ELF64_R_INFO (0, R_ALPHA_DTPMOD64
);
4721 outrel
.r_addend
= 0;
4723 loc
= srelgot
->contents
;
4724 loc
+= srelgot
->reloc_count
++ * sizeof (Elf64_External_Rela
);
4725 bfd_elf64_swap_reloca_out (output_bfd
, &outrel
, loc
);
4726 BFD_ASSERT (sizeof (Elf64_External_Rela
)
4727 * srelgot
->reloc_count
4728 <= srelgot
->_cooked_size
);
4731 if (dynamic_symbol_p
|| r_type
== R_ALPHA_TLSLDM
)
4735 BFD_ASSERT(tls_segment
!= NULL
);
4738 bfd_put_64 (output_bfd
, value
,
4739 sgot
->contents
+ gotent
->got_offset
+ 8);
4742 value
= (sgot
->output_section
->vma
4743 + sgot
->output_offset
4744 + gotent
->got_offset
);
4748 case R_ALPHA_DTPRELHI
:
4749 case R_ALPHA_DTPRELLO
:
4750 case R_ALPHA_DTPREL16
:
4751 if (dynamic_symbol_p
)
4753 (*_bfd_error_handler
)
4754 (_("%s: dtp-relative relocation against dynamic symbol %s"),
4755 bfd_archive_filename (input_bfd
), h
->root
.root
.root
.string
);
4758 BFD_ASSERT(tls_segment
!= NULL
);
4760 if (r_type
== R_ALPHA_DTPRELHI
)
4761 value
= ((bfd_signed_vma
) value
>> 16) + ((value
>> 15) & 1);
4764 case R_ALPHA_TPRELHI
:
4765 case R_ALPHA_TPRELLO
:
4766 case R_ALPHA_TPREL16
:
4769 (*_bfd_error_handler
)
4770 (_("%s: TLS local exec code cannot be linked into shared objects"),
4771 bfd_archive_filename (input_bfd
));
4774 else if (dynamic_symbol_p
)
4776 (*_bfd_error_handler
)
4777 (_("%s: tp-relative relocation against dynamic symbol %s"),
4778 bfd_archive_filename (input_bfd
), h
->root
.root
.root
.string
);
4781 BFD_ASSERT(tls_segment
!= NULL
);
4783 if (r_type
== R_ALPHA_TPRELHI
)
4784 value
= ((bfd_signed_vma
) value
>> 16) + ((value
>> 15) & 1);
4787 case R_ALPHA_GOTDTPREL
:
4788 case R_ALPHA_GOTTPREL
:
4789 BFD_ASSERT(sgot
!= NULL
);
4790 BFD_ASSERT(gp
!= 0);
4791 BFD_ASSERT(gotent
!= NULL
);
4792 BFD_ASSERT(gotent
->use_count
>= 1);
4794 if (!gotent
->reloc_done
)
4796 gotent
->reloc_done
= 1;
4798 if (dynamic_symbol_p
)
4802 BFD_ASSERT(tls_segment
!= NULL
);
4803 value
-= (r_type
== R_ALPHA_GOTDTPREL
? dtp_base
: tp_base
);
4805 bfd_put_64 (output_bfd
, value
,
4806 sgot
->contents
+ gotent
->got_offset
);
4809 value
= (sgot
->output_section
->vma
4810 + sgot
->output_offset
4811 + gotent
->got_offset
);
4817 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
4818 contents
, rel
->r_offset
, value
, 0);
4827 case bfd_reloc_overflow
:
4831 /* Don't warn if the overflow is due to pc relative reloc
4832 against discarded section. Section optimization code should
4835 if (r_symndx
< symtab_hdr
->sh_info
4836 && sec
!= NULL
&& howto
->pc_relative
4837 && elf_discarded_section (sec
))
4841 name
= h
->root
.root
.root
.string
;
4844 name
= (bfd_elf_string_from_elf_section
4845 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
4849 name
= bfd_section_name (input_bfd
, sec
);
4851 if (! ((*info
->callbacks
->reloc_overflow
)
4852 (info
, name
, howto
->name
, (bfd_vma
) 0,
4853 input_bfd
, input_section
, rel
->r_offset
)))
4859 case bfd_reloc_outofrange
:
4867 /* Finish up dynamic symbol handling. We set the contents of various
4868 dynamic sections here. */
4871 elf64_alpha_finish_dynamic_symbol (output_bfd
, info
, h
, sym
)
4873 struct bfd_link_info
*info
;
4874 struct elf_link_hash_entry
*h
;
4875 Elf_Internal_Sym
*sym
;
4877 bfd
*dynobj
= elf_hash_table(info
)->dynobj
;
4879 if (h
->plt
.offset
!= MINUS_ONE
)
4881 /* Fill in the .plt entry for this symbol. */
4882 asection
*splt
, *sgot
, *srel
;
4883 Elf_Internal_Rela outrel
;
4885 bfd_vma got_addr
, plt_addr
;
4887 struct alpha_elf_got_entry
*gotent
;
4889 BFD_ASSERT (h
->dynindx
!= -1);
4891 /* The first .got entry will be updated by the .plt with the
4892 address of the target function. */
4893 gotent
= ((struct alpha_elf_link_hash_entry
*) h
)->got_entries
;
4894 BFD_ASSERT (gotent
&& gotent
->addend
== 0);
4896 splt
= bfd_get_section_by_name (dynobj
, ".plt");
4897 BFD_ASSERT (splt
!= NULL
);
4898 srel
= bfd_get_section_by_name (dynobj
, ".rela.plt");
4899 BFD_ASSERT (srel
!= NULL
);
4900 sgot
= alpha_elf_tdata (gotent
->gotobj
)->got
;
4901 BFD_ASSERT (sgot
!= NULL
);
4903 got_addr
= (sgot
->output_section
->vma
4904 + sgot
->output_offset
4905 + gotent
->got_offset
);
4906 plt_addr
= (splt
->output_section
->vma
4907 + splt
->output_offset
4910 plt_index
= (h
->plt
.offset
- PLT_HEADER_SIZE
) / PLT_ENTRY_SIZE
;
4912 /* Fill in the entry in the procedure linkage table. */
4914 bfd_vma insn1
, insn2
, insn3
;
4916 insn1
= PLT_ENTRY_WORD1
| ((-(h
->plt
.offset
+ 4) >> 2) & 0x1fffff);
4917 insn2
= PLT_ENTRY_WORD2
;
4918 insn3
= PLT_ENTRY_WORD3
;
4920 bfd_put_32 (output_bfd
, insn1
, splt
->contents
+ h
->plt
.offset
);
4921 bfd_put_32 (output_bfd
, insn2
, splt
->contents
+ h
->plt
.offset
+ 4);
4922 bfd_put_32 (output_bfd
, insn3
, splt
->contents
+ h
->plt
.offset
+ 8);
4925 /* Fill in the entry in the .rela.plt section. */
4926 outrel
.r_offset
= got_addr
;
4927 outrel
.r_info
= ELF64_R_INFO(h
->dynindx
, R_ALPHA_JMP_SLOT
);
4928 outrel
.r_addend
= 0;
4930 loc
= srel
->contents
+ plt_index
* sizeof (Elf64_External_Rela
);
4931 bfd_elf64_swap_reloca_out (output_bfd
, &outrel
, loc
);
4933 if (!(h
->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR
))
4935 /* Mark the symbol as undefined, rather than as defined in the
4936 .plt section. Leave the value alone. */
4937 sym
->st_shndx
= SHN_UNDEF
;
4940 /* Fill in the entries in the .got. */
4941 bfd_put_64 (output_bfd
, plt_addr
, sgot
->contents
+ gotent
->got_offset
);
4943 /* Subsequent .got entries will continue to bounce through the .plt. */
4946 srel
= bfd_get_section_by_name (dynobj
, ".rela.got");
4947 BFD_ASSERT (! info
->shared
|| srel
!= NULL
);
4949 gotent
= gotent
->next
;
4952 sgot
= alpha_elf_tdata(gotent
->gotobj
)->got
;
4953 BFD_ASSERT(sgot
!= NULL
);
4954 BFD_ASSERT(gotent
->addend
== 0);
4956 bfd_put_64 (output_bfd
, plt_addr
,
4957 sgot
->contents
+ gotent
->got_offset
);
4961 outrel
.r_offset
= (sgot
->output_section
->vma
4962 + sgot
->output_offset
4963 + gotent
->got_offset
);
4964 outrel
.r_info
= ELF64_R_INFO(0, R_ALPHA_RELATIVE
);
4965 outrel
.r_addend
= plt_addr
;
4967 loc
= srel
->contents
;
4968 loc
+= srel
->reloc_count
++ * sizeof (Elf64_External_Rela
);
4969 bfd_elf64_swap_reloca_out (output_bfd
, &outrel
, loc
);
4970 BFD_ASSERT (sizeof (Elf64_External_Rela
) * srel
->reloc_count
4971 <= srel
->_cooked_size
);
4974 gotent
= gotent
->next
;
4976 while (gotent
!= NULL
);
4979 else if (alpha_elf_dynamic_symbol_p (h
, info
))
4981 /* Fill in the dynamic relocations for this symbol's .got entries. */
4983 Elf_Internal_Rela outrel
;
4985 struct alpha_elf_got_entry
*gotent
;
4987 srel
= bfd_get_section_by_name (dynobj
, ".rela.got");
4988 BFD_ASSERT (srel
!= NULL
);
4990 for (gotent
= ((struct alpha_elf_link_hash_entry
*) h
)->got_entries
;
4992 gotent
= gotent
->next
)
4997 if (gotent
->use_count
== 0)
5000 sgot
= alpha_elf_tdata (gotent
->gotobj
)->got
;
5001 outrel
.r_offset
= (sgot
->output_section
->vma
5002 + sgot
->output_offset
5003 + gotent
->got_offset
);
5005 r_type
= gotent
->reloc_type
;
5008 case R_ALPHA_LITERAL
:
5009 r_type
= R_ALPHA_GLOB_DAT
;
5012 r_type
= R_ALPHA_DTPMOD64
;
5014 case R_ALPHA_GOTDTPREL
:
5015 r_type
= R_ALPHA_DTPREL64
;
5017 case R_ALPHA_GOTTPREL
:
5018 r_type
= R_ALPHA_TPREL64
;
5020 case R_ALPHA_TLSLDM
:
5025 outrel
.r_info
= ELF64_R_INFO (h
->dynindx
, r_type
);
5026 outrel
.r_addend
= gotent
->addend
;
5028 loc
= srel
->contents
;
5029 loc
+= srel
->reloc_count
++ * sizeof (Elf64_External_Rela
);
5030 bfd_elf64_swap_reloca_out (output_bfd
, &outrel
, loc
);
5032 if (gotent
->reloc_type
== R_ALPHA_TLSGD
)
5034 outrel
.r_offset
+= 8;
5035 outrel
.r_info
= ELF64_R_INFO (h
->dynindx
, R_ALPHA_DTPREL64
);
5037 loc
= srel
->contents
;
5038 loc
+= srel
->reloc_count
++ * sizeof (Elf64_External_Rela
);
5039 bfd_elf64_swap_reloca_out (output_bfd
, &outrel
, loc
);
5042 BFD_ASSERT (sizeof (Elf64_External_Rela
) * srel
->reloc_count
5043 <= srel
->_cooked_size
);
5047 /* Mark some specially defined symbols as absolute. */
5048 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
5049 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0
5050 || strcmp (h
->root
.root
.string
, "_PROCEDURE_LINKAGE_TABLE_") == 0)
5051 sym
->st_shndx
= SHN_ABS
;
5056 /* Finish up the dynamic sections. */
5059 elf64_alpha_finish_dynamic_sections (output_bfd
, info
)
5061 struct bfd_link_info
*info
;
5066 dynobj
= elf_hash_table (info
)->dynobj
;
5067 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
5069 if (elf_hash_table (info
)->dynamic_sections_created
)
5072 Elf64_External_Dyn
*dyncon
, *dynconend
;
5074 splt
= bfd_get_section_by_name (dynobj
, ".plt");
5075 BFD_ASSERT (splt
!= NULL
&& sdyn
!= NULL
);
5077 dyncon
= (Elf64_External_Dyn
*) sdyn
->contents
;
5078 dynconend
= (Elf64_External_Dyn
*) (sdyn
->contents
+ sdyn
->_raw_size
);
5079 for (; dyncon
< dynconend
; dyncon
++)
5081 Elf_Internal_Dyn dyn
;
5085 bfd_elf64_swap_dyn_in (dynobj
, dyncon
, &dyn
);
5100 /* My interpretation of the TIS v1.1 ELF document indicates
5101 that RELASZ should not include JMPREL. This is not what
5102 the rest of the BFD does. It is, however, what the
5103 glibc ld.so wants. Do this fixup here until we found
5104 out who is right. */
5105 s
= bfd_get_section_by_name (output_bfd
, ".rela.plt");
5109 (s
->_cooked_size
? s
->_cooked_size
: s
->_raw_size
);
5114 s
= bfd_get_section_by_name (output_bfd
, name
);
5115 dyn
.d_un
.d_ptr
= (s
? s
->vma
: 0);
5119 s
= bfd_get_section_by_name (output_bfd
, name
);
5121 (s
->_cooked_size
? s
->_cooked_size
: s
->_raw_size
);
5125 bfd_elf64_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
5128 /* Initialize the PLT0 entry */
5129 if (splt
->_raw_size
> 0)
5131 bfd_put_32 (output_bfd
, PLT_HEADER_WORD1
, splt
->contents
);
5132 bfd_put_32 (output_bfd
, PLT_HEADER_WORD2
, splt
->contents
+ 4);
5133 bfd_put_32 (output_bfd
, PLT_HEADER_WORD3
, splt
->contents
+ 8);
5134 bfd_put_32 (output_bfd
, PLT_HEADER_WORD4
, splt
->contents
+ 12);
5136 /* The next two words will be filled in by ld.so */
5137 bfd_put_64 (output_bfd
, (bfd_vma
) 0, splt
->contents
+ 16);
5138 bfd_put_64 (output_bfd
, (bfd_vma
) 0, splt
->contents
+ 24);
5140 elf_section_data (splt
->output_section
)->this_hdr
.sh_entsize
=
5148 /* We need to use a special link routine to handle the .mdebug section.
5149 We need to merge all instances of these sections together, not write
5150 them all out sequentially. */
5153 elf64_alpha_final_link (abfd
, info
)
5155 struct bfd_link_info
*info
;
5158 struct bfd_link_order
*p
;
5159 asection
*mdebug_sec
;
5160 struct ecoff_debug_info debug
;
5161 const struct ecoff_debug_swap
*swap
5162 = get_elf_backend_data (abfd
)->elf_backend_ecoff_debug_swap
;
5163 HDRR
*symhdr
= &debug
.symbolic_header
;
5164 PTR mdebug_handle
= NULL
;
5166 /* Go through the sections and collect the mdebug information. */
5168 for (o
= abfd
->sections
; o
!= (asection
*) NULL
; o
= o
->next
)
5170 if (strcmp (o
->name
, ".mdebug") == 0)
5172 struct extsym_info einfo
;
5174 /* We have found the .mdebug section in the output file.
5175 Look through all the link_orders comprising it and merge
5176 the information together. */
5177 symhdr
->magic
= swap
->sym_magic
;
5178 /* FIXME: What should the version stamp be? */
5180 symhdr
->ilineMax
= 0;
5184 symhdr
->isymMax
= 0;
5185 symhdr
->ioptMax
= 0;
5186 symhdr
->iauxMax
= 0;
5188 symhdr
->issExtMax
= 0;
5191 symhdr
->iextMax
= 0;
5193 /* We accumulate the debugging information itself in the
5194 debug_info structure. */
5196 debug
.external_dnr
= NULL
;
5197 debug
.external_pdr
= NULL
;
5198 debug
.external_sym
= NULL
;
5199 debug
.external_opt
= NULL
;
5200 debug
.external_aux
= NULL
;
5202 debug
.ssext
= debug
.ssext_end
= NULL
;
5203 debug
.external_fdr
= NULL
;
5204 debug
.external_rfd
= NULL
;
5205 debug
.external_ext
= debug
.external_ext_end
= NULL
;
5207 mdebug_handle
= bfd_ecoff_debug_init (abfd
, &debug
, swap
, info
);
5208 if (mdebug_handle
== (PTR
) NULL
)
5217 static const char * const name
[] =
5219 ".text", ".init", ".fini", ".data",
5220 ".rodata", ".sdata", ".sbss", ".bss"
5222 static const int sc
[] = { scText
, scInit
, scFini
, scData
,
5223 scRData
, scSData
, scSBss
, scBss
};
5226 esym
.cobol_main
= 0;
5230 esym
.asym
.iss
= issNil
;
5231 esym
.asym
.st
= stLocal
;
5232 esym
.asym
.reserved
= 0;
5233 esym
.asym
.index
= indexNil
;
5234 for (i
= 0; i
< 8; i
++)
5236 esym
.asym
.sc
= sc
[i
];
5237 s
= bfd_get_section_by_name (abfd
, name
[i
]);
5240 esym
.asym
.value
= s
->vma
;
5241 last
= s
->vma
+ s
->_raw_size
;
5244 esym
.asym
.value
= last
;
5246 if (! bfd_ecoff_debug_one_external (abfd
, &debug
, swap
,
5252 for (p
= o
->link_order_head
;
5253 p
!= (struct bfd_link_order
*) NULL
;
5256 asection
*input_section
;
5258 const struct ecoff_debug_swap
*input_swap
;
5259 struct ecoff_debug_info input_debug
;
5263 if (p
->type
!= bfd_indirect_link_order
)
5265 if (p
->type
== bfd_data_link_order
)
5270 input_section
= p
->u
.indirect
.section
;
5271 input_bfd
= input_section
->owner
;
5273 if (bfd_get_flavour (input_bfd
) != bfd_target_elf_flavour
5274 || (get_elf_backend_data (input_bfd
)
5275 ->elf_backend_ecoff_debug_swap
) == NULL
)
5277 /* I don't know what a non ALPHA ELF bfd would be
5278 doing with a .mdebug section, but I don't really
5279 want to deal with it. */
5283 input_swap
= (get_elf_backend_data (input_bfd
)
5284 ->elf_backend_ecoff_debug_swap
);
5286 BFD_ASSERT (p
->size
== input_section
->_raw_size
);
5288 /* The ECOFF linking code expects that we have already
5289 read in the debugging information and set up an
5290 ecoff_debug_info structure, so we do that now. */
5291 if (!elf64_alpha_read_ecoff_info (input_bfd
, input_section
,
5295 if (! (bfd_ecoff_debug_accumulate
5296 (mdebug_handle
, abfd
, &debug
, swap
, input_bfd
,
5297 &input_debug
, input_swap
, info
)))
5300 /* Loop through the external symbols. For each one with
5301 interesting information, try to find the symbol in
5302 the linker global hash table and save the information
5303 for the output external symbols. */
5304 eraw_src
= input_debug
.external_ext
;
5305 eraw_end
= (eraw_src
5306 + (input_debug
.symbolic_header
.iextMax
5307 * input_swap
->external_ext_size
));
5309 eraw_src
< eraw_end
;
5310 eraw_src
+= input_swap
->external_ext_size
)
5314 struct alpha_elf_link_hash_entry
*h
;
5316 (*input_swap
->swap_ext_in
) (input_bfd
, (PTR
) eraw_src
, &ext
);
5317 if (ext
.asym
.sc
== scNil
5318 || ext
.asym
.sc
== scUndefined
5319 || ext
.asym
.sc
== scSUndefined
)
5322 name
= input_debug
.ssext
+ ext
.asym
.iss
;
5323 h
= alpha_elf_link_hash_lookup (alpha_elf_hash_table (info
),
5324 name
, FALSE
, FALSE
, TRUE
);
5325 if (h
== NULL
|| h
->esym
.ifd
!= -2)
5331 < input_debug
.symbolic_header
.ifdMax
);
5332 ext
.ifd
= input_debug
.ifdmap
[ext
.ifd
];
5338 /* Free up the information we just read. */
5339 free (input_debug
.line
);
5340 free (input_debug
.external_dnr
);
5341 free (input_debug
.external_pdr
);
5342 free (input_debug
.external_sym
);
5343 free (input_debug
.external_opt
);
5344 free (input_debug
.external_aux
);
5345 free (input_debug
.ss
);
5346 free (input_debug
.ssext
);
5347 free (input_debug
.external_fdr
);
5348 free (input_debug
.external_rfd
);
5349 free (input_debug
.external_ext
);
5351 /* Hack: reset the SEC_HAS_CONTENTS flag so that
5352 elf_link_input_bfd ignores this section. */
5353 input_section
->flags
&=~ SEC_HAS_CONTENTS
;
5356 /* Build the external symbol information. */
5359 einfo
.debug
= &debug
;
5361 einfo
.failed
= FALSE
;
5362 elf_link_hash_traverse (elf_hash_table (info
),
5363 elf64_alpha_output_extsym
,
5368 /* Set the size of the .mdebug section. */
5369 o
->_raw_size
= bfd_ecoff_debug_size (abfd
, &debug
, swap
);
5371 /* Skip this section later on (I don't think this currently
5372 matters, but someday it might). */
5373 o
->link_order_head
= (struct bfd_link_order
*) NULL
;
5379 /* Invoke the regular ELF backend linker to do all the work. */
5380 if (! bfd_elf64_bfd_final_link (abfd
, info
))
5383 /* Now write out the computed sections. */
5385 /* The .got subsections... */
5387 bfd
*i
, *dynobj
= elf_hash_table(info
)->dynobj
;
5388 for (i
= alpha_elf_hash_table(info
)->got_list
;
5390 i
= alpha_elf_tdata(i
)->got_link_next
)
5394 /* elf_bfd_final_link already did everything in dynobj. */
5398 sgot
= alpha_elf_tdata(i
)->got
;
5399 if (! bfd_set_section_contents (abfd
, sgot
->output_section
,
5401 (file_ptr
) sgot
->output_offset
,
5407 if (mdebug_sec
!= (asection
*) NULL
)
5409 BFD_ASSERT (abfd
->output_has_begun
);
5410 if (! bfd_ecoff_write_accumulated_debug (mdebug_handle
, abfd
, &debug
,
5412 mdebug_sec
->filepos
))
5415 bfd_ecoff_debug_free (mdebug_handle
, abfd
, &debug
, swap
, info
);
5421 static enum elf_reloc_type_class
5422 elf64_alpha_reloc_type_class (rela
)
5423 const Elf_Internal_Rela
*rela
;
5425 switch ((int) ELF64_R_TYPE (rela
->r_info
))
5427 case R_ALPHA_RELATIVE
:
5428 return reloc_class_relative
;
5429 case R_ALPHA_JMP_SLOT
:
5430 return reloc_class_plt
;
5432 return reloc_class_copy
;
5434 return reloc_class_normal
;
5438 /* ECOFF swapping routines. These are used when dealing with the
5439 .mdebug section, which is in the ECOFF debugging format. Copied
5440 from elf32-mips.c. */
5441 static const struct ecoff_debug_swap
5442 elf64_alpha_ecoff_debug_swap
=
5444 /* Symbol table magic number. */
5446 /* Alignment of debugging information. E.g., 4. */
5448 /* Sizes of external symbolic information. */
5449 sizeof (struct hdr_ext
),
5450 sizeof (struct dnr_ext
),
5451 sizeof (struct pdr_ext
),
5452 sizeof (struct sym_ext
),
5453 sizeof (struct opt_ext
),
5454 sizeof (struct fdr_ext
),
5455 sizeof (struct rfd_ext
),
5456 sizeof (struct ext_ext
),
5457 /* Functions to swap in external symbolic data. */
5466 _bfd_ecoff_swap_tir_in
,
5467 _bfd_ecoff_swap_rndx_in
,
5468 /* Functions to swap out external symbolic data. */
5477 _bfd_ecoff_swap_tir_out
,
5478 _bfd_ecoff_swap_rndx_out
,
5479 /* Function to read in symbolic data. */
5480 elf64_alpha_read_ecoff_info
5483 /* Use a non-standard hash bucket size of 8. */
5485 static const struct elf_size_info alpha_elf_size_info
=
5487 sizeof (Elf64_External_Ehdr
),
5488 sizeof (Elf64_External_Phdr
),
5489 sizeof (Elf64_External_Shdr
),
5490 sizeof (Elf64_External_Rel
),
5491 sizeof (Elf64_External_Rela
),
5492 sizeof (Elf64_External_Sym
),
5493 sizeof (Elf64_External_Dyn
),
5494 sizeof (Elf_External_Note
),
5498 ELFCLASS64
, EV_CURRENT
,
5499 bfd_elf64_write_out_phdrs
,
5500 bfd_elf64_write_shdrs_and_ehdr
,
5501 bfd_elf64_write_relocs
,
5502 bfd_elf64_swap_symbol_in
,
5503 bfd_elf64_swap_symbol_out
,
5504 bfd_elf64_slurp_reloc_table
,
5505 bfd_elf64_slurp_symbol_table
,
5506 bfd_elf64_swap_dyn_in
,
5507 bfd_elf64_swap_dyn_out
,
5508 bfd_elf64_swap_reloc_in
,
5509 bfd_elf64_swap_reloc_out
,
5510 bfd_elf64_swap_reloca_in
,
5511 bfd_elf64_swap_reloca_out
5514 #define TARGET_LITTLE_SYM bfd_elf64_alpha_vec
5515 #define TARGET_LITTLE_NAME "elf64-alpha"
5516 #define ELF_ARCH bfd_arch_alpha
5517 #define ELF_MACHINE_CODE EM_ALPHA
5518 #define ELF_MAXPAGESIZE 0x10000
5520 #define bfd_elf64_bfd_link_hash_table_create \
5521 elf64_alpha_bfd_link_hash_table_create
5523 #define bfd_elf64_bfd_reloc_type_lookup \
5524 elf64_alpha_bfd_reloc_type_lookup
5525 #define elf_info_to_howto \
5526 elf64_alpha_info_to_howto
5528 #define bfd_elf64_mkobject \
5529 elf64_alpha_mkobject
5530 #define elf_backend_object_p \
5531 elf64_alpha_object_p
5533 #define elf_backend_section_from_shdr \
5534 elf64_alpha_section_from_shdr
5535 #define elf_backend_section_flags \
5536 elf64_alpha_section_flags
5537 #define elf_backend_fake_sections \
5538 elf64_alpha_fake_sections
5540 #define bfd_elf64_bfd_is_local_label_name \
5541 elf64_alpha_is_local_label_name
5542 #define bfd_elf64_find_nearest_line \
5543 elf64_alpha_find_nearest_line
5544 #define bfd_elf64_bfd_relax_section \
5545 elf64_alpha_relax_section
5547 #define elf_backend_add_symbol_hook \
5548 elf64_alpha_add_symbol_hook
5549 #define elf_backend_check_relocs \
5550 elf64_alpha_check_relocs
5551 #define elf_backend_create_dynamic_sections \
5552 elf64_alpha_create_dynamic_sections
5553 #define elf_backend_adjust_dynamic_symbol \
5554 elf64_alpha_adjust_dynamic_symbol
5555 #define elf_backend_always_size_sections \
5556 elf64_alpha_always_size_sections
5557 #define elf_backend_size_dynamic_sections \
5558 elf64_alpha_size_dynamic_sections
5559 #define elf_backend_relocate_section \
5560 elf64_alpha_relocate_section
5561 #define elf_backend_finish_dynamic_symbol \
5562 elf64_alpha_finish_dynamic_symbol
5563 #define elf_backend_finish_dynamic_sections \
5564 elf64_alpha_finish_dynamic_sections
5565 #define bfd_elf64_bfd_final_link \
5566 elf64_alpha_final_link
5567 #define elf_backend_reloc_type_class \
5568 elf64_alpha_reloc_type_class
5570 #define elf_backend_ecoff_debug_swap \
5571 &elf64_alpha_ecoff_debug_swap
5573 #define elf_backend_size_info \
5576 /* A few constants that determine how the .plt section is set up. */
5577 #define elf_backend_want_got_plt 0
5578 #define elf_backend_plt_readonly 0
5579 #define elf_backend_want_plt_sym 1
5580 #define elf_backend_got_header_size 0
5581 #define elf_backend_plt_header_size PLT_HEADER_SIZE
5583 #include "elf64-target.h"
5585 /* FreeBSD support. */
5587 #undef TARGET_LITTLE_SYM
5588 #define TARGET_LITTLE_SYM bfd_elf64_alpha_freebsd_vec
5589 #undef TARGET_LITTLE_NAME
5590 #define TARGET_LITTLE_NAME "elf64-alpha-freebsd"
5592 /* The kernel recognizes executables as valid only if they carry a
5593 "FreeBSD" label in the ELF header. So we put this label on all
5594 executables and (for simplicity) also all other object files. */
5596 static void elf64_alpha_fbsd_post_process_headers
5597 PARAMS ((bfd
*, struct bfd_link_info
*));
5600 elf64_alpha_fbsd_post_process_headers (abfd
, link_info
)
5602 struct bfd_link_info
* link_info ATTRIBUTE_UNUSED
;
5604 Elf_Internal_Ehdr
* i_ehdrp
; /* ELF file header, internal form. */
5606 i_ehdrp
= elf_elfheader (abfd
);
5608 /* Put an ABI label supported by FreeBSD >= 4.1. */
5609 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
5610 #ifdef OLD_FREEBSD_ABI_LABEL
5611 /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */
5612 memcpy (&i_ehdrp
->e_ident
[EI_ABIVERSION
], "FreeBSD", 8);
5616 #undef elf_backend_post_process_headers
5617 #define elf_backend_post_process_headers \
5618 elf64_alpha_fbsd_post_process_headers
5620 #define elf64_bed elf64_alpha_fbsd_bed
5622 #include "elf64-target.h"