include/elf/
[binutils.git] / bfd / elf64-alpha.c
blobe25e934aa6e9f0ff2f4214af5dc8f6d8c46ed525
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. */
25 #include "bfd.h"
26 #include "sysdep.h"
27 #include "libbfd.h"
28 #include "elf-bfd.h"
30 #include "elf/alpha.h"
32 #define ALPHAECOFF
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"
40 #include "coff/sym.h"
41 #include "coff/symconst.h"
42 #include "coff/ecoff.h"
43 #include "coff/alpha.h"
44 #include "aout/ar.h"
45 #include "libcoff.h"
46 #include "libecoff.h"
47 #define ECOFF_64
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
55 PARAMS((bfd *));
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 *, Elf64_Internal_Rela *));
71 static boolean elf64_alpha_mkobject
72 PARAMS((bfd *));
73 static boolean elf64_alpha_object_p
74 PARAMS((bfd *));
75 static boolean elf64_alpha_section_from_shdr
76 PARAMS((bfd *, Elf64_Internal_Shdr *, char *));
77 static boolean elf64_alpha_section_flags
78 PARAMS((flagword *, Elf64_Internal_Shdr *));
79 static boolean elf64_alpha_fake_sections
80 PARAMS((bfd *, Elf64_Internal_Shdr *, asection *));
81 static boolean elf64_alpha_create_got_section
82 PARAMS((bfd *, struct bfd_link_info *));
83 static boolean elf64_alpha_create_dynamic_sections
84 PARAMS((bfd *, struct bfd_link_info *));
86 static boolean elf64_alpha_read_ecoff_info
87 PARAMS((bfd *, asection *, struct ecoff_debug_info *));
88 static boolean elf64_alpha_is_local_label_name
89 PARAMS((bfd *, const char *));
90 static 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;
96 #endif
98 static boolean elf64_alpha_output_extsym
99 PARAMS((struct alpha_elf_link_hash_entry *, PTR));
101 static boolean elf64_alpha_can_merge_gots
102 PARAMS((bfd *, bfd *));
103 static void elf64_alpha_merge_gots
104 PARAMS((bfd *, bfd *));
105 static 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 PARAMS ((struct bfd_link_info *));
108 static boolean elf64_alpha_size_got_sections
109 PARAMS ((bfd *, struct bfd_link_info *));
110 static boolean elf64_alpha_always_size_sections
111 PARAMS ((bfd *, struct bfd_link_info *));
112 static int alpha_dynamic_entries_for_reloc
113 PARAMS ((int, int, int));
114 static boolean elf64_alpha_calc_dynrel_sizes
115 PARAMS ((struct alpha_elf_link_hash_entry *, struct bfd_link_info *));
116 static boolean elf64_alpha_add_symbol_hook
117 PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
118 const char **, flagword *, asection **, bfd_vma *));
119 static struct alpha_elf_got_entry *get_got_entry
120 PARAMS ((bfd *, struct alpha_elf_link_hash_entry *, unsigned long,
121 unsigned long, bfd_vma));
122 static boolean elf64_alpha_check_relocs
123 PARAMS((bfd *, struct bfd_link_info *, asection *sec,
124 const Elf_Internal_Rela *));
125 static boolean elf64_alpha_adjust_dynamic_symbol
126 PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
127 static boolean elf64_alpha_size_dynamic_sections
128 PARAMS((bfd *, struct bfd_link_info *));
129 static boolean elf64_alpha_relocate_section
130 PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
131 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
132 static boolean elf64_alpha_finish_dynamic_symbol
133 PARAMS((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
134 Elf_Internal_Sym *));
135 static boolean elf64_alpha_finish_dynamic_sections
136 PARAMS((bfd *, struct bfd_link_info *));
137 static boolean elf64_alpha_final_link
138 PARAMS((bfd *, struct bfd_link_info *));
139 static boolean elf64_alpha_merge_ind_symbols
140 PARAMS((struct alpha_elf_link_hash_entry *, PTR));
141 static Elf_Internal_Rela * elf64_alpha_find_reloc_at_ofs
142 PARAMS ((Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_vma, int));
143 static enum elf_reloc_type_class elf64_alpha_reloc_type_class
144 PARAMS ((const Elf_Internal_Rela *));
146 struct alpha_elf_link_hash_entry
148 struct elf_link_hash_entry root;
150 /* External symbol information. */
151 EXTR esym;
153 /* Cumulative flags for all the .got entries. */
154 int flags;
156 /* Contexts in which a literal was referenced. */
157 #define ALPHA_ELF_LINK_HASH_LU_ADDR 0x01
158 #define ALPHA_ELF_LINK_HASH_LU_MEM 0x02
159 #define ALPHA_ELF_LINK_HASH_LU_BYTE 0x04
160 #define ALPHA_ELF_LINK_HASH_LU_JSR 0x08
161 #define ALPHA_ELF_LINK_HASH_LU_TLSGD 0x10
162 #define ALPHA_ELF_LINK_HASH_LU_TLSLDM 0x20
163 #define ALPHA_ELF_LINK_HASH_LU_FUNC 0x38
164 #define ALPHA_ELF_LINK_HASH_TLS_IE 0x40
166 /* Used to implement multiple .got subsections. */
167 struct alpha_elf_got_entry
169 struct alpha_elf_got_entry *next;
171 /* which .got subsection? */
172 bfd *gotobj;
174 /* the addend in effect for this entry. */
175 bfd_vma addend;
177 /* the .got offset for this entry. */
178 int got_offset;
180 /* How many references to this entry? */
181 int use_count;
183 /* The relocation type of this entry. */
184 unsigned char reloc_type;
186 /* How a LITERAL is used. */
187 unsigned char flags;
189 /* Have we initialized the dynamic relocation for this entry? */
190 unsigned char reloc_done;
192 /* Have we adjusted this entry for SEC_MERGE? */
193 unsigned char reloc_xlated;
194 } *got_entries;
196 /* used to count non-got, non-plt relocations for delayed sizing
197 of relocation sections. */
198 struct alpha_elf_reloc_entry
200 struct alpha_elf_reloc_entry *next;
202 /* which .reloc section? */
203 asection *srel;
205 /* what kind of relocation? */
206 unsigned int rtype;
208 /* is this against read-only section? */
209 unsigned int reltext : 1;
211 /* how many did we find? */
212 unsigned long count;
213 } *reloc_entries;
216 /* Alpha ELF linker hash table. */
218 struct alpha_elf_link_hash_table
220 struct elf_link_hash_table root;
222 /* The head of a list of .got subsections linked through
223 alpha_elf_tdata(abfd)->got_link_next. */
224 bfd *got_list;
227 /* Look up an entry in a Alpha ELF linker hash table. */
229 #define alpha_elf_link_hash_lookup(table, string, create, copy, follow) \
230 ((struct alpha_elf_link_hash_entry *) \
231 elf_link_hash_lookup (&(table)->root, (string), (create), \
232 (copy), (follow)))
234 /* Traverse a Alpha ELF linker hash table. */
236 #define alpha_elf_link_hash_traverse(table, func, info) \
237 (elf_link_hash_traverse \
238 (&(table)->root, \
239 (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
240 (info)))
242 /* Get the Alpha ELF linker hash table from a link_info structure. */
244 #define alpha_elf_hash_table(p) \
245 ((struct alpha_elf_link_hash_table *) ((p)->hash))
247 /* Get the object's symbols as our own entry type. */
249 #define alpha_elf_sym_hashes(abfd) \
250 ((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
252 /* Should we do dynamic things to this symbol? */
254 static int
255 alpha_elf_dynamic_symbol_p (h, info)
256 struct elf_link_hash_entry *h;
257 struct bfd_link_info *info;
259 if (h == NULL)
260 return false;
262 while (h->root.type == bfd_link_hash_indirect
263 || h->root.type == bfd_link_hash_warning)
264 h = (struct elf_link_hash_entry *) h->root.u.i.link;
266 if (h->dynindx == -1)
267 return false;
269 if (h->root.type == bfd_link_hash_undefweak
270 || h->root.type == bfd_link_hash_defweak)
271 return true;
273 switch (ELF_ST_VISIBILITY (h->other))
275 case STV_DEFAULT:
276 break;
277 case STV_HIDDEN:
278 case STV_INTERNAL:
279 return false;
280 case STV_PROTECTED:
281 if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
282 return false;
283 break;
286 if ((info->shared && !info->symbolic)
287 || ((h->elf_link_hash_flags
288 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
289 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
290 return true;
292 return false;
295 /* Create an entry in a Alpha ELF linker hash table. */
297 static struct bfd_hash_entry *
298 elf64_alpha_link_hash_newfunc (entry, table, string)
299 struct bfd_hash_entry *entry;
300 struct bfd_hash_table *table;
301 const char *string;
303 struct alpha_elf_link_hash_entry *ret =
304 (struct alpha_elf_link_hash_entry *) entry;
306 /* Allocate the structure if it has not already been allocated by a
307 subclass. */
308 if (ret == (struct alpha_elf_link_hash_entry *) NULL)
309 ret = ((struct alpha_elf_link_hash_entry *)
310 bfd_hash_allocate (table,
311 sizeof (struct alpha_elf_link_hash_entry)));
312 if (ret == (struct alpha_elf_link_hash_entry *) NULL)
313 return (struct bfd_hash_entry *) ret;
315 /* Call the allocation method of the superclass. */
316 ret = ((struct alpha_elf_link_hash_entry *)
317 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
318 table, string));
319 if (ret != (struct alpha_elf_link_hash_entry *) NULL)
321 /* Set local fields. */
322 memset (&ret->esym, 0, sizeof (EXTR));
323 /* We use -2 as a marker to indicate that the information has
324 not been set. -1 means there is no associated ifd. */
325 ret->esym.ifd = -2;
326 ret->flags = 0;
327 ret->got_entries = NULL;
328 ret->reloc_entries = NULL;
331 return (struct bfd_hash_entry *) ret;
334 /* Create a Alpha ELF linker hash table. */
336 static struct bfd_link_hash_table *
337 elf64_alpha_bfd_link_hash_table_create (abfd)
338 bfd *abfd;
340 struct alpha_elf_link_hash_table *ret;
341 bfd_size_type amt = sizeof (struct alpha_elf_link_hash_table);
343 ret = (struct alpha_elf_link_hash_table *) bfd_zmalloc (amt);
344 if (ret == (struct alpha_elf_link_hash_table *) NULL)
345 return NULL;
347 if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
348 elf64_alpha_link_hash_newfunc))
350 free (ret);
351 return NULL;
354 return &ret->root.root;
357 /* We have some private fields hanging off of the elf_tdata structure. */
359 struct alpha_elf_obj_tdata
361 struct elf_obj_tdata root;
363 /* For every input file, these are the got entries for that object's
364 local symbols. */
365 struct alpha_elf_got_entry ** local_got_entries;
367 /* For every input file, this is the object that owns the got that
368 this input file uses. */
369 bfd *gotobj;
371 /* For every got, this is a linked list through the objects using this got */
372 bfd *in_got_link_next;
374 /* For every got, this is a link to the next got subsegment. */
375 bfd *got_link_next;
377 /* For every got, this is the section. */
378 asection *got;
380 /* For every got, this is it's total number of words. */
381 int total_got_size;
383 /* For every got, this is the sum of the number of words required
384 to hold all of the member object's local got. */
385 int local_got_size;
388 #define alpha_elf_tdata(abfd) \
389 ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any)
391 static boolean
392 elf64_alpha_mkobject (abfd)
393 bfd *abfd;
395 bfd_size_type amt = sizeof (struct alpha_elf_obj_tdata);
396 abfd->tdata.any = bfd_zalloc (abfd, amt);
397 if (abfd->tdata.any == NULL)
398 return false;
399 return true;
402 static boolean
403 elf64_alpha_object_p (abfd)
404 bfd *abfd;
406 /* Allocate our special target data. */
407 struct alpha_elf_obj_tdata *new_tdata;
408 bfd_size_type amt = sizeof (struct alpha_elf_obj_tdata);
409 new_tdata = bfd_zalloc (abfd, amt);
410 if (new_tdata == NULL)
411 return false;
412 new_tdata->root = *abfd->tdata.elf_obj_data;
413 abfd->tdata.any = new_tdata;
415 /* Set the right machine number for an Alpha ELF file. */
416 return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
419 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
420 from smaller values. Start with zero, widen, *then* decrement. */
421 #define MINUS_ONE (((bfd_vma)0) - 1)
423 #define SKIP_HOWTO(N) \
424 HOWTO(N, 0, 0, 0, 0, 0, 0, elf64_alpha_reloc_bad, 0, 0, 0, 0, 0)
426 static reloc_howto_type elf64_alpha_howto_table[] =
428 HOWTO (R_ALPHA_NONE, /* type */
429 0, /* rightshift */
430 0, /* size (0 = byte, 1 = short, 2 = long) */
431 8, /* bitsize */
432 true, /* pc_relative */
433 0, /* bitpos */
434 complain_overflow_dont, /* complain_on_overflow */
435 elf64_alpha_reloc_nil, /* special_function */
436 "NONE", /* name */
437 false, /* partial_inplace */
438 0, /* src_mask */
439 0, /* dst_mask */
440 true), /* pcrel_offset */
442 /* A 32 bit reference to a symbol. */
443 HOWTO (R_ALPHA_REFLONG, /* type */
444 0, /* rightshift */
445 2, /* size (0 = byte, 1 = short, 2 = long) */
446 32, /* bitsize */
447 false, /* pc_relative */
448 0, /* bitpos */
449 complain_overflow_bitfield, /* complain_on_overflow */
450 0, /* special_function */
451 "REFLONG", /* name */
452 false, /* partial_inplace */
453 0xffffffff, /* src_mask */
454 0xffffffff, /* dst_mask */
455 false), /* pcrel_offset */
457 /* A 64 bit reference to a symbol. */
458 HOWTO (R_ALPHA_REFQUAD, /* type */
459 0, /* rightshift */
460 4, /* size (0 = byte, 1 = short, 2 = long) */
461 64, /* bitsize */
462 false, /* pc_relative */
463 0, /* bitpos */
464 complain_overflow_bitfield, /* complain_on_overflow */
465 0, /* special_function */
466 "REFQUAD", /* name */
467 false, /* partial_inplace */
468 MINUS_ONE, /* src_mask */
469 MINUS_ONE, /* dst_mask */
470 false), /* pcrel_offset */
472 /* A 32 bit GP relative offset. This is just like REFLONG except
473 that when the value is used the value of the gp register will be
474 added in. */
475 HOWTO (R_ALPHA_GPREL32, /* type */
476 0, /* rightshift */
477 2, /* size (0 = byte, 1 = short, 2 = long) */
478 32, /* bitsize */
479 false, /* pc_relative */
480 0, /* bitpos */
481 complain_overflow_bitfield, /* complain_on_overflow */
482 0, /* special_function */
483 "GPREL32", /* name */
484 false, /* partial_inplace */
485 0xffffffff, /* src_mask */
486 0xffffffff, /* dst_mask */
487 false), /* pcrel_offset */
489 /* Used for an instruction that refers to memory off the GP register. */
490 HOWTO (R_ALPHA_LITERAL, /* type */
491 0, /* rightshift */
492 1, /* size (0 = byte, 1 = short, 2 = long) */
493 16, /* bitsize */
494 false, /* pc_relative */
495 0, /* bitpos */
496 complain_overflow_signed, /* complain_on_overflow */
497 0, /* special_function */
498 "ELF_LITERAL", /* name */
499 false, /* partial_inplace */
500 0xffff, /* src_mask */
501 0xffff, /* dst_mask */
502 false), /* pcrel_offset */
504 /* This reloc only appears immediately following an ELF_LITERAL reloc.
505 It identifies a use of the literal. The symbol index is special:
506 1 means the literal address is in the base register of a memory
507 format instruction; 2 means the literal address is in the byte
508 offset register of a byte-manipulation instruction; 3 means the
509 literal address is in the target register of a jsr instruction.
510 This does not actually do any relocation. */
511 HOWTO (R_ALPHA_LITUSE, /* type */
512 0, /* rightshift */
513 1, /* size (0 = byte, 1 = short, 2 = long) */
514 32, /* bitsize */
515 false, /* pc_relative */
516 0, /* bitpos */
517 complain_overflow_dont, /* complain_on_overflow */
518 elf64_alpha_reloc_nil, /* special_function */
519 "LITUSE", /* name */
520 false, /* partial_inplace */
521 0, /* src_mask */
522 0, /* dst_mask */
523 false), /* pcrel_offset */
525 /* Load the gp register. This is always used for a ldah instruction
526 which loads the upper 16 bits of the gp register. The symbol
527 index of the GPDISP instruction is an offset in bytes to the lda
528 instruction that loads the lower 16 bits. The value to use for
529 the relocation is the difference between the GP value and the
530 current location; the load will always be done against a register
531 holding the current address.
533 NOTE: Unlike ECOFF, partial in-place relocation is not done. If
534 any offset is present in the instructions, it is an offset from
535 the register to the ldah instruction. This lets us avoid any
536 stupid hackery like inventing a gp value to do partial relocation
537 against. Also unlike ECOFF, we do the whole relocation off of
538 the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair. An odd,
539 space consuming bit, that, since all the information was present
540 in the GPDISP_HI16 reloc. */
541 HOWTO (R_ALPHA_GPDISP, /* type */
542 16, /* rightshift */
543 2, /* size (0 = byte, 1 = short, 2 = long) */
544 16, /* bitsize */
545 false, /* pc_relative */
546 0, /* bitpos */
547 complain_overflow_dont, /* complain_on_overflow */
548 elf64_alpha_reloc_gpdisp, /* special_function */
549 "GPDISP", /* name */
550 false, /* partial_inplace */
551 0xffff, /* src_mask */
552 0xffff, /* dst_mask */
553 true), /* pcrel_offset */
555 /* A 21 bit branch. */
556 HOWTO (R_ALPHA_BRADDR, /* type */
557 2, /* rightshift */
558 2, /* size (0 = byte, 1 = short, 2 = long) */
559 21, /* bitsize */
560 true, /* pc_relative */
561 0, /* bitpos */
562 complain_overflow_signed, /* complain_on_overflow */
563 0, /* special_function */
564 "BRADDR", /* name */
565 false, /* partial_inplace */
566 0x1fffff, /* src_mask */
567 0x1fffff, /* dst_mask */
568 true), /* pcrel_offset */
570 /* A hint for a jump to a register. */
571 HOWTO (R_ALPHA_HINT, /* type */
572 2, /* rightshift */
573 1, /* size (0 = byte, 1 = short, 2 = long) */
574 14, /* bitsize */
575 true, /* pc_relative */
576 0, /* bitpos */
577 complain_overflow_dont, /* complain_on_overflow */
578 0, /* special_function */
579 "HINT", /* name */
580 false, /* partial_inplace */
581 0x3fff, /* src_mask */
582 0x3fff, /* dst_mask */
583 true), /* pcrel_offset */
585 /* 16 bit PC relative offset. */
586 HOWTO (R_ALPHA_SREL16, /* type */
587 0, /* rightshift */
588 1, /* size (0 = byte, 1 = short, 2 = long) */
589 16, /* bitsize */
590 true, /* pc_relative */
591 0, /* bitpos */
592 complain_overflow_signed, /* complain_on_overflow */
593 0, /* special_function */
594 "SREL16", /* name */
595 false, /* partial_inplace */
596 0xffff, /* src_mask */
597 0xffff, /* dst_mask */
598 true), /* pcrel_offset */
600 /* 32 bit PC relative offset. */
601 HOWTO (R_ALPHA_SREL32, /* type */
602 0, /* rightshift */
603 2, /* size (0 = byte, 1 = short, 2 = long) */
604 32, /* bitsize */
605 true, /* pc_relative */
606 0, /* bitpos */
607 complain_overflow_signed, /* complain_on_overflow */
608 0, /* special_function */
609 "SREL32", /* name */
610 false, /* partial_inplace */
611 0xffffffff, /* src_mask */
612 0xffffffff, /* dst_mask */
613 true), /* pcrel_offset */
615 /* A 64 bit PC relative offset. */
616 HOWTO (R_ALPHA_SREL64, /* type */
617 0, /* rightshift */
618 4, /* size (0 = byte, 1 = short, 2 = long) */
619 64, /* bitsize */
620 true, /* pc_relative */
621 0, /* bitpos */
622 complain_overflow_signed, /* complain_on_overflow */
623 0, /* special_function */
624 "SREL64", /* name */
625 false, /* partial_inplace */
626 MINUS_ONE, /* src_mask */
627 MINUS_ONE, /* dst_mask */
628 true), /* pcrel_offset */
630 /* Skip 12 - 16; deprecated ECOFF relocs. */
631 SKIP_HOWTO (12),
632 SKIP_HOWTO (13),
633 SKIP_HOWTO (14),
634 SKIP_HOWTO (15),
635 SKIP_HOWTO (16),
637 /* The high 16 bits of the displacement from GP to the target. */
638 HOWTO (R_ALPHA_GPRELHIGH,
639 0, /* rightshift */
640 1, /* size (0 = byte, 1 = short, 2 = long) */
641 16, /* bitsize */
642 false, /* pc_relative */
643 0, /* bitpos */
644 complain_overflow_signed, /* complain_on_overflow */
645 0, /* special_function */
646 "GPRELHIGH", /* name */
647 false, /* partial_inplace */
648 0xffff, /* src_mask */
649 0xffff, /* dst_mask */
650 false), /* pcrel_offset */
652 /* The low 16 bits of the displacement from GP to the target. */
653 HOWTO (R_ALPHA_GPRELLOW,
654 0, /* rightshift */
655 1, /* size (0 = byte, 1 = short, 2 = long) */
656 16, /* bitsize */
657 false, /* pc_relative */
658 0, /* bitpos */
659 complain_overflow_dont, /* complain_on_overflow */
660 0, /* special_function */
661 "GPRELLOW", /* name */
662 false, /* partial_inplace */
663 0xffff, /* src_mask */
664 0xffff, /* dst_mask */
665 false), /* pcrel_offset */
667 /* A 16-bit displacement from the GP to the target. */
668 HOWTO (R_ALPHA_GPREL16,
669 0, /* rightshift */
670 1, /* size (0 = byte, 1 = short, 2 = long) */
671 16, /* bitsize */
672 false, /* pc_relative */
673 0, /* bitpos */
674 complain_overflow_signed, /* complain_on_overflow */
675 0, /* special_function */
676 "GPREL16", /* name */
677 false, /* partial_inplace */
678 0xffff, /* src_mask */
679 0xffff, /* dst_mask */
680 false), /* pcrel_offset */
682 /* Skip 20 - 23; deprecated ECOFF relocs. */
683 SKIP_HOWTO (20),
684 SKIP_HOWTO (21),
685 SKIP_HOWTO (22),
686 SKIP_HOWTO (23),
688 /* Misc ELF relocations. */
690 /* A dynamic relocation to copy the target into our .dynbss section. */
691 /* Not generated, as all Alpha objects use PIC, so it is not needed. It
692 is present because every other ELF has one, but should not be used
693 because .dynbss is an ugly thing. */
694 HOWTO (R_ALPHA_COPY,
698 false,
700 complain_overflow_dont,
701 bfd_elf_generic_reloc,
702 "COPY",
703 false,
706 true),
708 /* A dynamic relocation for a .got entry. */
709 HOWTO (R_ALPHA_GLOB_DAT,
713 false,
715 complain_overflow_dont,
716 bfd_elf_generic_reloc,
717 "GLOB_DAT",
718 false,
721 true),
723 /* A dynamic relocation for a .plt entry. */
724 HOWTO (R_ALPHA_JMP_SLOT,
728 false,
730 complain_overflow_dont,
731 bfd_elf_generic_reloc,
732 "JMP_SLOT",
733 false,
736 true),
738 /* A dynamic relocation to add the base of the DSO to a 64-bit field. */
739 HOWTO (R_ALPHA_RELATIVE,
743 false,
745 complain_overflow_dont,
746 bfd_elf_generic_reloc,
747 "RELATIVE",
748 false,
751 true),
753 /* A 21 bit branch that adjusts for gp loads. */
754 HOWTO (R_ALPHA_BRSGP, /* type */
755 2, /* rightshift */
756 2, /* size (0 = byte, 1 = short, 2 = long) */
757 21, /* bitsize */
758 true, /* pc_relative */
759 0, /* bitpos */
760 complain_overflow_signed, /* complain_on_overflow */
761 0, /* special_function */
762 "BRSGP", /* name */
763 false, /* partial_inplace */
764 0x1fffff, /* src_mask */
765 0x1fffff, /* dst_mask */
766 true), /* pcrel_offset */
768 /* Creates a tls_index for the symbol in the got. */
769 HOWTO (R_ALPHA_TLSGD, /* type */
770 0, /* rightshift */
771 1, /* size (0 = byte, 1 = short, 2 = long) */
772 16, /* bitsize */
773 false, /* pc_relative */
774 0, /* bitpos */
775 complain_overflow_signed, /* complain_on_overflow */
776 0, /* special_function */
777 "TLSGD", /* name */
778 false, /* partial_inplace */
779 0xffff, /* src_mask */
780 0xffff, /* dst_mask */
781 false), /* pcrel_offset */
783 /* Creates a tls_index for the (current) module in the got. */
784 HOWTO (R_ALPHA_TLSLDM, /* type */
785 0, /* rightshift */
786 1, /* size (0 = byte, 1 = short, 2 = long) */
787 16, /* bitsize */
788 false, /* pc_relative */
789 0, /* bitpos */
790 complain_overflow_signed, /* complain_on_overflow */
791 0, /* special_function */
792 "TLSLDM", /* name */
793 false, /* partial_inplace */
794 0xffff, /* src_mask */
795 0xffff, /* dst_mask */
796 false), /* pcrel_offset */
798 /* A dynamic relocation for a DTP module entry. */
799 HOWTO (R_ALPHA_DTPMOD64, /* type */
800 0, /* rightshift */
801 4, /* size (0 = byte, 1 = short, 2 = long) */
802 64, /* bitsize */
803 false, /* pc_relative */
804 0, /* bitpos */
805 complain_overflow_bitfield, /* complain_on_overflow */
806 0, /* special_function */
807 "DTPMOD64", /* name */
808 false, /* partial_inplace */
809 MINUS_ONE, /* src_mask */
810 MINUS_ONE, /* dst_mask */
811 false), /* pcrel_offset */
813 /* Creates a 64-bit offset in the got for the displacement
814 from DTP to the target. */
815 HOWTO (R_ALPHA_GOTDTPREL, /* type */
816 0, /* rightshift */
817 1, /* size (0 = byte, 1 = short, 2 = long) */
818 16, /* bitsize */
819 false, /* pc_relative */
820 0, /* bitpos */
821 complain_overflow_signed, /* complain_on_overflow */
822 0, /* special_function */
823 "GOTDTPREL", /* name */
824 false, /* partial_inplace */
825 0xffff, /* src_mask */
826 0xffff, /* dst_mask */
827 false), /* pcrel_offset */
829 /* A dynamic relocation for a displacement from DTP to the target. */
830 HOWTO (R_ALPHA_DTPREL64, /* type */
831 0, /* rightshift */
832 4, /* size (0 = byte, 1 = short, 2 = long) */
833 64, /* bitsize */
834 false, /* pc_relative */
835 0, /* bitpos */
836 complain_overflow_bitfield, /* complain_on_overflow */
837 0, /* special_function */
838 "DTPREL64", /* name */
839 false, /* partial_inplace */
840 MINUS_ONE, /* src_mask */
841 MINUS_ONE, /* dst_mask */
842 false), /* pcrel_offset */
844 /* The high 16 bits of the displacement from DTP to the target. */
845 HOWTO (R_ALPHA_DTPRELHI, /* type */
846 0, /* rightshift */
847 1, /* size (0 = byte, 1 = short, 2 = long) */
848 16, /* bitsize */
849 false, /* pc_relative */
850 0, /* bitpos */
851 complain_overflow_signed, /* complain_on_overflow */
852 0, /* special_function */
853 "DTPRELHI", /* name */
854 false, /* partial_inplace */
855 0xffff, /* src_mask */
856 0xffff, /* dst_mask */
857 false), /* pcrel_offset */
859 /* The low 16 bits of the displacement from DTP to the target. */
860 HOWTO (R_ALPHA_DTPRELLO, /* type */
861 0, /* rightshift */
862 1, /* size (0 = byte, 1 = short, 2 = long) */
863 16, /* bitsize */
864 false, /* pc_relative */
865 0, /* bitpos */
866 complain_overflow_dont, /* complain_on_overflow */
867 0, /* special_function */
868 "DTPRELLO", /* name */
869 false, /* partial_inplace */
870 0xffff, /* src_mask */
871 0xffff, /* dst_mask */
872 false), /* pcrel_offset */
874 /* A 16-bit displacement from DTP to the target. */
875 HOWTO (R_ALPHA_DTPREL16, /* type */
876 0, /* rightshift */
877 1, /* size (0 = byte, 1 = short, 2 = long) */
878 16, /* bitsize */
879 false, /* pc_relative */
880 0, /* bitpos */
881 complain_overflow_signed, /* complain_on_overflow */
882 0, /* special_function */
883 "DTPREL16", /* name */
884 false, /* partial_inplace */
885 0xffff, /* src_mask */
886 0xffff, /* dst_mask */
887 false), /* pcrel_offset */
889 /* Creates a 64-bit offset in the got for the displacement
890 from TP to the target. */
891 HOWTO (R_ALPHA_GOTTPREL, /* type */
892 0, /* rightshift */
893 1, /* size (0 = byte, 1 = short, 2 = long) */
894 16, /* bitsize */
895 false, /* pc_relative */
896 0, /* bitpos */
897 complain_overflow_signed, /* complain_on_overflow */
898 0, /* special_function */
899 "GOTTPREL", /* name */
900 false, /* partial_inplace */
901 0xffff, /* src_mask */
902 0xffff, /* dst_mask */
903 false), /* pcrel_offset */
905 /* A dynamic relocation for a displacement from TP to the target. */
906 HOWTO (R_ALPHA_TPREL64, /* type */
907 0, /* rightshift */
908 4, /* size (0 = byte, 1 = short, 2 = long) */
909 64, /* bitsize */
910 false, /* pc_relative */
911 0, /* bitpos */
912 complain_overflow_bitfield, /* complain_on_overflow */
913 0, /* special_function */
914 "TPREL64", /* name */
915 false, /* partial_inplace */
916 MINUS_ONE, /* src_mask */
917 MINUS_ONE, /* dst_mask */
918 false), /* pcrel_offset */
920 /* The high 16 bits of the displacement from TP to the target. */
921 HOWTO (R_ALPHA_TPRELHI, /* type */
922 0, /* rightshift */
923 1, /* size (0 = byte, 1 = short, 2 = long) */
924 16, /* bitsize */
925 false, /* pc_relative */
926 0, /* bitpos */
927 complain_overflow_signed, /* complain_on_overflow */
928 0, /* special_function */
929 "TPRELHI", /* name */
930 false, /* partial_inplace */
931 0xffff, /* src_mask */
932 0xffff, /* dst_mask */
933 false), /* pcrel_offset */
935 /* The low 16 bits of the displacement from TP to the target. */
936 HOWTO (R_ALPHA_TPRELLO, /* type */
937 0, /* rightshift */
938 1, /* size (0 = byte, 1 = short, 2 = long) */
939 16, /* bitsize */
940 false, /* pc_relative */
941 0, /* bitpos */
942 complain_overflow_dont, /* complain_on_overflow */
943 0, /* special_function */
944 "TPRELLO", /* name */
945 false, /* partial_inplace */
946 0xffff, /* src_mask */
947 0xffff, /* dst_mask */
948 false), /* pcrel_offset */
950 /* A 16-bit displacement from TP to the target. */
951 HOWTO (R_ALPHA_TPREL16, /* type */
952 0, /* rightshift */
953 1, /* size (0 = byte, 1 = short, 2 = long) */
954 16, /* bitsize */
955 false, /* pc_relative */
956 0, /* bitpos */
957 complain_overflow_signed, /* complain_on_overflow */
958 0, /* special_function */
959 "TPREL16", /* name */
960 false, /* partial_inplace */
961 0xffff, /* src_mask */
962 0xffff, /* dst_mask */
963 false), /* pcrel_offset */
966 /* A relocation function which doesn't do anything. */
968 static bfd_reloc_status_type
969 elf64_alpha_reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
970 bfd *abfd ATTRIBUTE_UNUSED;
971 arelent *reloc;
972 asymbol *sym ATTRIBUTE_UNUSED;
973 PTR data ATTRIBUTE_UNUSED;
974 asection *sec;
975 bfd *output_bfd;
976 char **error_message ATTRIBUTE_UNUSED;
978 if (output_bfd)
979 reloc->address += sec->output_offset;
980 return bfd_reloc_ok;
983 /* A relocation function used for an unsupported reloc. */
985 static bfd_reloc_status_type
986 elf64_alpha_reloc_bad (abfd, reloc, sym, data, sec, output_bfd, error_message)
987 bfd *abfd ATTRIBUTE_UNUSED;
988 arelent *reloc;
989 asymbol *sym ATTRIBUTE_UNUSED;
990 PTR data ATTRIBUTE_UNUSED;
991 asection *sec;
992 bfd *output_bfd;
993 char **error_message ATTRIBUTE_UNUSED;
995 if (output_bfd)
996 reloc->address += sec->output_offset;
997 return bfd_reloc_notsupported;
1000 /* Do the work of the GPDISP relocation. */
1002 static bfd_reloc_status_type
1003 elf64_alpha_do_reloc_gpdisp (abfd, gpdisp, p_ldah, p_lda)
1004 bfd *abfd;
1005 bfd_vma gpdisp;
1006 bfd_byte *p_ldah;
1007 bfd_byte *p_lda;
1009 bfd_reloc_status_type ret = bfd_reloc_ok;
1010 bfd_vma addend;
1011 unsigned long i_ldah, i_lda;
1013 i_ldah = bfd_get_32 (abfd, p_ldah);
1014 i_lda = bfd_get_32 (abfd, p_lda);
1016 /* Complain if the instructions are not correct. */
1017 if (((i_ldah >> 26) & 0x3f) != 0x09
1018 || ((i_lda >> 26) & 0x3f) != 0x08)
1019 ret = bfd_reloc_dangerous;
1021 /* Extract the user-supplied offset, mirroring the sign extensions
1022 that the instructions perform. */
1023 addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff);
1024 addend = (addend ^ 0x80008000) - 0x80008000;
1026 gpdisp += addend;
1028 if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000
1029 || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000)
1030 ret = bfd_reloc_overflow;
1032 /* compensate for the sign extension again. */
1033 i_ldah = ((i_ldah & 0xffff0000)
1034 | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff));
1035 i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff);
1037 bfd_put_32 (abfd, (bfd_vma) i_ldah, p_ldah);
1038 bfd_put_32 (abfd, (bfd_vma) i_lda, p_lda);
1040 return ret;
1043 /* The special function for the GPDISP reloc. */
1045 static bfd_reloc_status_type
1046 elf64_alpha_reloc_gpdisp (abfd, reloc_entry, sym, data, input_section,
1047 output_bfd, err_msg)
1048 bfd *abfd;
1049 arelent *reloc_entry;
1050 asymbol *sym ATTRIBUTE_UNUSED;
1051 PTR data;
1052 asection *input_section;
1053 bfd *output_bfd;
1054 char **err_msg;
1056 bfd_reloc_status_type ret;
1057 bfd_vma gp, relocation;
1058 bfd_byte *p_ldah, *p_lda;
1060 /* Don't do anything if we're not doing a final link. */
1061 if (output_bfd)
1063 reloc_entry->address += input_section->output_offset;
1064 return bfd_reloc_ok;
1067 if (reloc_entry->address > input_section->_cooked_size ||
1068 reloc_entry->address + reloc_entry->addend > input_section->_cooked_size)
1069 return bfd_reloc_outofrange;
1071 /* The gp used in the portion of the output object to which this
1072 input object belongs is cached on the input bfd. */
1073 gp = _bfd_get_gp_value (abfd);
1075 relocation = (input_section->output_section->vma
1076 + input_section->output_offset
1077 + reloc_entry->address);
1079 p_ldah = (bfd_byte *) data + reloc_entry->address;
1080 p_lda = p_ldah + reloc_entry->addend;
1082 ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda);
1084 /* Complain if the instructions are not correct. */
1085 if (ret == bfd_reloc_dangerous)
1086 *err_msg = _("GPDISP relocation did not find ldah and lda instructions");
1088 return ret;
1091 /* A mapping from BFD reloc types to Alpha ELF reloc types. */
1093 struct elf_reloc_map
1095 bfd_reloc_code_real_type bfd_reloc_val;
1096 int elf_reloc_val;
1099 static const struct elf_reloc_map elf64_alpha_reloc_map[] =
1101 {BFD_RELOC_NONE, R_ALPHA_NONE},
1102 {BFD_RELOC_32, R_ALPHA_REFLONG},
1103 {BFD_RELOC_64, R_ALPHA_REFQUAD},
1104 {BFD_RELOC_CTOR, R_ALPHA_REFQUAD},
1105 {BFD_RELOC_GPREL32, R_ALPHA_GPREL32},
1106 {BFD_RELOC_ALPHA_ELF_LITERAL, R_ALPHA_LITERAL},
1107 {BFD_RELOC_ALPHA_LITUSE, R_ALPHA_LITUSE},
1108 {BFD_RELOC_ALPHA_GPDISP, R_ALPHA_GPDISP},
1109 {BFD_RELOC_23_PCREL_S2, R_ALPHA_BRADDR},
1110 {BFD_RELOC_ALPHA_HINT, R_ALPHA_HINT},
1111 {BFD_RELOC_16_PCREL, R_ALPHA_SREL16},
1112 {BFD_RELOC_32_PCREL, R_ALPHA_SREL32},
1113 {BFD_RELOC_64_PCREL, R_ALPHA_SREL64},
1114 {BFD_RELOC_ALPHA_GPREL_HI16, R_ALPHA_GPRELHIGH},
1115 {BFD_RELOC_ALPHA_GPREL_LO16, R_ALPHA_GPRELLOW},
1116 {BFD_RELOC_GPREL16, R_ALPHA_GPREL16},
1117 {BFD_RELOC_ALPHA_BRSGP, R_ALPHA_BRSGP},
1118 {BFD_RELOC_ALPHA_TLSGD, R_ALPHA_TLSGD},
1119 {BFD_RELOC_ALPHA_TLSLDM, R_ALPHA_TLSLDM},
1120 {BFD_RELOC_ALPHA_DTPMOD64, R_ALPHA_DTPMOD64},
1121 {BFD_RELOC_ALPHA_GOTDTPREL16, R_ALPHA_GOTDTPREL},
1122 {BFD_RELOC_ALPHA_DTPREL64, R_ALPHA_DTPREL64},
1123 {BFD_RELOC_ALPHA_DTPREL_HI16, R_ALPHA_DTPRELHI},
1124 {BFD_RELOC_ALPHA_DTPREL_LO16, R_ALPHA_DTPRELLO},
1125 {BFD_RELOC_ALPHA_DTPREL16, R_ALPHA_DTPREL16},
1126 {BFD_RELOC_ALPHA_GOTTPREL16, R_ALPHA_GOTTPREL},
1127 {BFD_RELOC_ALPHA_TPREL64, R_ALPHA_TPREL64},
1128 {BFD_RELOC_ALPHA_TPREL_HI16, R_ALPHA_TPRELHI},
1129 {BFD_RELOC_ALPHA_TPREL_LO16, R_ALPHA_TPRELLO},
1130 {BFD_RELOC_ALPHA_TPREL16, R_ALPHA_TPREL16},
1133 /* Given a BFD reloc type, return a HOWTO structure. */
1135 static reloc_howto_type *
1136 elf64_alpha_bfd_reloc_type_lookup (abfd, code)
1137 bfd *abfd ATTRIBUTE_UNUSED;
1138 bfd_reloc_code_real_type code;
1140 const struct elf_reloc_map *i, *e;
1141 i = e = elf64_alpha_reloc_map;
1142 e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map);
1143 for (; i != e; ++i)
1145 if (i->bfd_reloc_val == code)
1146 return &elf64_alpha_howto_table[i->elf_reloc_val];
1148 return 0;
1151 /* Given an Alpha ELF reloc type, fill in an arelent structure. */
1153 static void
1154 elf64_alpha_info_to_howto (abfd, cache_ptr, dst)
1155 bfd *abfd ATTRIBUTE_UNUSED;
1156 arelent *cache_ptr;
1157 Elf64_Internal_Rela *dst;
1159 unsigned r_type;
1161 r_type = ELF64_R_TYPE(dst->r_info);
1162 BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max);
1163 cache_ptr->howto = &elf64_alpha_howto_table[r_type];
1166 /* These two relocations create a two-word entry in the got. */
1167 #define alpha_got_entry_size(r_type) \
1168 (r_type == R_ALPHA_TLSGD || r_type == R_ALPHA_TLSLDM ? 16 : 8)
1170 /* This is PT_TLS segment p_vaddr. */
1171 #define alpha_get_dtprel_base(tlss) \
1172 ((tlss)->start)
1174 /* Main program TLS (whose template starts at PT_TLS p_vaddr)
1175 is assigned offset round(16, PT_TLS p_align). */
1176 #define alpha_get_tprel_base(tlss) \
1177 ((tlss)->start - align_power ((bfd_vma) 16, (tlss)->align))
1179 /* These functions do relaxation for Alpha ELF.
1181 Currently I'm only handling what I can do with existing compiler
1182 and assembler support, which means no instructions are removed,
1183 though some may be nopped. At this time GCC does not emit enough
1184 information to do all of the relaxing that is possible. It will
1185 take some not small amount of work for that to happen.
1187 There are a couple of interesting papers that I once read on this
1188 subject, that I cannot find references to at the moment, that
1189 related to Alpha in particular. They are by David Wall, then of
1190 DEC WRL. */
1192 #define OP_LDA 0x08
1193 #define OP_LDAH 0x09
1194 #define INSN_JSR 0x68004000
1195 #define INSN_JSR_MASK 0xfc00c000
1196 #define OP_LDQ 0x29
1197 #define OP_BR 0x30
1198 #define OP_BSR 0x34
1199 #define INSN_UNOP 0x2ffe0000
1200 #define INSN_ADDQ 0x40000400
1201 #define INSN_RDUNIQ 0x0000009e
1203 struct alpha_relax_info
1205 bfd *abfd;
1206 asection *sec;
1207 bfd_byte *contents;
1208 Elf_Internal_Shdr *symtab_hdr;
1209 Elf_Internal_Rela *relocs, *relend;
1210 struct bfd_link_info *link_info;
1211 struct elf_link_tls_segment *tls_segment;
1212 bfd_vma gp;
1213 bfd *gotobj;
1214 asection *tsec;
1215 struct alpha_elf_link_hash_entry *h;
1216 struct alpha_elf_got_entry **first_gotent;
1217 struct alpha_elf_got_entry *gotent;
1218 boolean changed_contents;
1219 boolean changed_relocs;
1220 unsigned char other;
1223 static boolean elf64_alpha_relax_with_lituse
1224 PARAMS((struct alpha_relax_info *info, bfd_vma symval,
1225 Elf_Internal_Rela *irel));
1226 static bfd_vma elf64_alpha_relax_opt_call
1227 PARAMS((struct alpha_relax_info *info, bfd_vma symval));
1228 static boolean elf64_alpha_relax_got_load
1229 PARAMS((struct alpha_relax_info *info, bfd_vma symval,
1230 Elf_Internal_Rela *irel, unsigned long));
1231 static boolean elf64_alpha_relax_gprelhilo
1232 PARAMS((struct alpha_relax_info *info, bfd_vma symval,
1233 Elf_Internal_Rela *irel, boolean));
1234 static boolean elf64_alpha_relax_tls_get_addr
1235 PARAMS((struct alpha_relax_info *info, bfd_vma symval,
1236 Elf_Internal_Rela *irel, boolean));
1237 static struct elf_link_tls_segment *elf64_alpha_relax_find_tls_segment
1238 PARAMS((struct alpha_relax_info *, struct elf_link_tls_segment *));
1239 static boolean elf64_alpha_relax_section
1240 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
1241 boolean *again));
1243 static Elf_Internal_Rela *
1244 elf64_alpha_find_reloc_at_ofs (rel, relend, offset, type)
1245 Elf_Internal_Rela *rel, *relend;
1246 bfd_vma offset;
1247 int type;
1249 while (rel < relend)
1251 if (rel->r_offset == offset
1252 && ELF64_R_TYPE (rel->r_info) == (unsigned int) type)
1253 return rel;
1254 ++rel;
1256 return NULL;
1259 static boolean
1260 elf64_alpha_relax_with_lituse (info, symval, irel)
1261 struct alpha_relax_info *info;
1262 bfd_vma symval;
1263 Elf_Internal_Rela *irel;
1265 Elf_Internal_Rela *urel, *irelend = info->relend;
1266 int flags, count, i;
1267 bfd_signed_vma disp;
1268 boolean fits16;
1269 boolean fits32;
1270 boolean lit_reused = false;
1271 boolean all_optimized = true;
1272 unsigned int lit_insn;
1274 lit_insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
1275 if (lit_insn >> 26 != OP_LDQ)
1277 ((*_bfd_error_handler)
1278 ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn",
1279 bfd_archive_filename (info->abfd), info->sec->name,
1280 (unsigned long) irel->r_offset));
1281 return true;
1284 /* Can't relax dynamic symbols. */
1285 if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
1286 return true;
1288 /* Summarize how this particular LITERAL is used. */
1289 for (urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count)
1291 if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE)
1292 break;
1293 if (urel->r_addend <= 3)
1294 flags |= 1 << urel->r_addend;
1297 /* A little preparation for the loop... */
1298 disp = symval - info->gp;
1300 for (urel = irel+1, i = 0; i < count; ++i, ++urel)
1302 unsigned int insn;
1303 int insn_disp;
1304 bfd_signed_vma xdisp;
1306 insn = bfd_get_32 (info->abfd, info->contents + urel->r_offset);
1308 switch (urel->r_addend)
1310 case LITUSE_ALPHA_ADDR:
1311 default:
1312 /* This type is really just a placeholder to note that all
1313 uses cannot be optimized, but to still allow some. */
1314 all_optimized = false;
1315 break;
1317 case LITUSE_ALPHA_BASE:
1318 /* We can always optimize 16-bit displacements. */
1320 /* Extract the displacement from the instruction, sign-extending
1321 it if necessary, then test whether it is within 16 or 32 bits
1322 displacement from GP. */
1323 insn_disp = insn & 0x0000ffff;
1324 if (insn_disp & 0x8000)
1325 insn_disp |= ~0xffff; /* Negative: sign-extend. */
1327 xdisp = disp + insn_disp;
1328 fits16 = (xdisp >= - (bfd_signed_vma) 0x8000 && xdisp < 0x8000);
1329 fits32 = (xdisp >= - (bfd_signed_vma) 0x80000000
1330 && xdisp < 0x7fff8000);
1332 if (fits16)
1334 /* Take the op code and dest from this insn, take the base
1335 register from the literal insn. Leave the offset alone. */
1336 insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
1337 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1338 R_ALPHA_GPREL16);
1339 urel->r_addend = irel->r_addend;
1340 info->changed_relocs = true;
1342 bfd_put_32 (info->abfd, (bfd_vma) insn,
1343 info->contents + urel->r_offset);
1344 info->changed_contents = true;
1347 /* If all mem+byte, we can optimize 32-bit mem displacements. */
1348 else if (fits32 && !(flags & ~6))
1350 /* FIXME: sanity check that lit insn Ra is mem insn Rb. */
1352 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1353 R_ALPHA_GPRELHIGH);
1354 lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
1355 bfd_put_32 (info->abfd, (bfd_vma) lit_insn,
1356 info->contents + irel->r_offset);
1357 lit_reused = true;
1358 info->changed_contents = true;
1360 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1361 R_ALPHA_GPRELLOW);
1362 urel->r_addend = irel->r_addend;
1363 info->changed_relocs = true;
1365 else
1366 all_optimized = false;
1367 break;
1369 case LITUSE_ALPHA_BYTOFF:
1370 /* We can always optimize byte instructions. */
1372 /* FIXME: sanity check the insn for byte op. Check that the
1373 literal dest reg is indeed Rb in the byte insn. */
1375 insn &= ~ (unsigned) 0x001ff000;
1376 insn |= ((symval & 7) << 13) | 0x1000;
1378 urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1379 urel->r_addend = 0;
1380 info->changed_relocs = true;
1382 bfd_put_32 (info->abfd, (bfd_vma) insn,
1383 info->contents + urel->r_offset);
1384 info->changed_contents = true;
1385 break;
1387 case LITUSE_ALPHA_JSR:
1388 case LITUSE_ALPHA_TLSGD:
1389 case LITUSE_ALPHA_TLSLDM:
1391 /* If not zero, place to jump without needing pv. */
1392 bfd_vma optdest = elf64_alpha_relax_opt_call (info, symval);
1393 bfd_vma org = (info->sec->output_section->vma
1394 + info->sec->output_offset
1395 + urel->r_offset + 4);
1396 bfd_signed_vma odisp;
1398 odisp = (optdest ? optdest : symval) - org;
1399 if (odisp >= -0x400000 && odisp < 0x400000)
1401 Elf_Internal_Rela *xrel;
1403 /* Preserve branch prediction call stack when possible. */
1404 if ((insn & INSN_JSR_MASK) == INSN_JSR)
1405 insn = (OP_BSR << 26) | (insn & 0x03e00000);
1406 else
1407 insn = (OP_BR << 26) | (insn & 0x03e00000);
1409 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1410 R_ALPHA_BRADDR);
1411 urel->r_addend = irel->r_addend;
1413 if (optdest)
1414 urel->r_addend += optdest - symval;
1415 else
1416 all_optimized = false;
1418 bfd_put_32 (info->abfd, (bfd_vma) insn,
1419 info->contents + urel->r_offset);
1421 /* Kill any HINT reloc that might exist for this insn. */
1422 xrel = (elf64_alpha_find_reloc_at_ofs
1423 (info->relocs, info->relend, urel->r_offset,
1424 R_ALPHA_HINT));
1425 if (xrel)
1426 xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1428 info->changed_contents = true;
1429 info->changed_relocs = true;
1431 else
1432 all_optimized = false;
1434 /* Even if the target is not in range for a direct branch,
1435 if we share a GP, we can eliminate the gp reload. */
1436 if (optdest)
1438 Elf_Internal_Rela *gpdisp
1439 = (elf64_alpha_find_reloc_at_ofs
1440 (info->relocs, irelend, urel->r_offset + 4,
1441 R_ALPHA_GPDISP));
1442 if (gpdisp)
1444 bfd_byte *p_ldah = info->contents + gpdisp->r_offset;
1445 bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
1446 unsigned int ldah = bfd_get_32 (info->abfd, p_ldah);
1447 unsigned int lda = bfd_get_32 (info->abfd, p_lda);
1449 /* Verify that the instruction is "ldah $29,0($26)".
1450 Consider a function that ends in a noreturn call,
1451 and that the next function begins with an ldgp,
1452 and that by accident there is no padding between.
1453 In that case the insn would use $27 as the base. */
1454 if (ldah == 0x27ba0000 && lda == 0x23bd0000)
1456 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_ldah);
1457 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_lda);
1459 gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1460 info->changed_contents = true;
1461 info->changed_relocs = true;
1466 break;
1470 /* If all cases were optimized, we can reduce the use count on this
1471 got entry by one, possibly eliminating it. */
1472 if (all_optimized)
1474 if (--info->gotent->use_count == 0)
1476 int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
1477 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
1478 if (!info->h)
1479 alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
1482 /* If the literal instruction is no longer needed (it may have been
1483 reused. We can eliminate it. */
1484 /* ??? For now, I don't want to deal with compacting the section,
1485 so just nop it out. */
1486 if (!lit_reused)
1488 irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1489 info->changed_relocs = true;
1491 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP,
1492 info->contents + irel->r_offset);
1493 info->changed_contents = true;
1497 return true;
1500 static bfd_vma
1501 elf64_alpha_relax_opt_call (info, symval)
1502 struct alpha_relax_info *info;
1503 bfd_vma symval;
1505 /* If the function has the same gp, and we can identify that the
1506 function does not use its function pointer, we can eliminate the
1507 address load. */
1509 /* If the symbol is marked NOPV, we are being told the function never
1510 needs its procedure value. */
1511 if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV)
1512 return symval;
1514 /* If the symbol is marked STD_GP, we are being told the function does
1515 a normal ldgp in the first two words. */
1516 else if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD)
1519 /* Otherwise, we may be able to identify a GP load in the first two
1520 words, which we can then skip. */
1521 else
1523 Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp;
1524 bfd_vma ofs;
1526 /* Load the relocations from the section that the target symbol is in. */
1527 if (info->sec == info->tsec)
1529 tsec_relocs = info->relocs;
1530 tsec_relend = info->relend;
1531 tsec_free = NULL;
1533 else
1535 tsec_relocs = (_bfd_elf64_link_read_relocs
1536 (info->abfd, info->tsec, (PTR) NULL,
1537 (Elf_Internal_Rela *) NULL,
1538 info->link_info->keep_memory));
1539 if (tsec_relocs == NULL)
1540 return 0;
1541 tsec_relend = tsec_relocs + info->tsec->reloc_count;
1542 tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs);
1545 /* Recover the symbol's offset within the section. */
1546 ofs = (symval - info->tsec->output_section->vma
1547 - info->tsec->output_offset);
1549 /* Look for a GPDISP reloc. */
1550 gpdisp = (elf64_alpha_find_reloc_at_ofs
1551 (tsec_relocs, tsec_relend, ofs, R_ALPHA_GPDISP));
1553 if (!gpdisp || gpdisp->r_addend != 4)
1555 if (tsec_free)
1556 free (tsec_free);
1557 return 0;
1559 if (tsec_free)
1560 free (tsec_free);
1563 /* We've now determined that we can skip an initial gp load. Verify
1564 that the call and the target use the same gp. */
1565 if (info->link_info->hash->creator != info->tsec->owner->xvec
1566 || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
1567 return 0;
1569 return symval + 8;
1572 static boolean
1573 elf64_alpha_relax_got_load (info, symval, irel, r_type)
1574 struct alpha_relax_info *info;
1575 bfd_vma symval;
1576 Elf_Internal_Rela *irel;
1577 unsigned long r_type;
1579 unsigned int insn;
1580 bfd_signed_vma disp;
1582 /* Get the instruction. */
1583 insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
1585 if (insn >> 26 != OP_LDQ)
1587 reloc_howto_type *howto = elf64_alpha_howto_table + r_type;
1588 ((*_bfd_error_handler)
1589 ("%s: %s+0x%lx: warning: %s relocation against unexpected insn",
1590 bfd_archive_filename (info->abfd), info->sec->name,
1591 (unsigned long) irel->r_offset, howto->name));
1592 return true;
1595 /* Can't relax dynamic symbols. */
1596 if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
1597 return true;
1599 /* Can't use local-exec relocations in shared libraries. */
1600 if (r_type == R_ALPHA_GOTTPREL && info->link_info->shared)
1601 return true;
1603 if (r_type == R_ALPHA_LITERAL)
1604 disp = symval - info->gp;
1605 else
1607 bfd_vma dtp_base, tp_base;
1609 BFD_ASSERT (info->tls_segment != NULL);
1610 dtp_base = alpha_get_dtprel_base (info->tls_segment);
1611 tp_base = alpha_get_tprel_base (info->tls_segment);
1612 disp = symval - (r_type == R_ALPHA_GOTDTPREL ? dtp_base : tp_base);
1615 if (disp < -0x8000 || disp >= 0x8000)
1616 return true;
1618 /* Exchange LDQ for LDA. In the case of the TLS relocs, we're loading
1619 a constant, so force the base register to be $31. */
1620 if (r_type == R_ALPHA_LITERAL)
1621 insn = (OP_LDA << 26) | (insn & 0x03ff0000);
1622 else
1623 insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
1624 bfd_put_32 (info->abfd, (bfd_vma) insn, info->contents + irel->r_offset);
1625 info->changed_contents = true;
1627 switch (r_type)
1629 case R_ALPHA_LITERAL:
1630 r_type = R_ALPHA_GPREL16;
1631 break;
1632 case R_ALPHA_GOTDTPREL:
1633 r_type = R_ALPHA_DTPREL16;
1634 break;
1635 case R_ALPHA_GOTTPREL:
1636 r_type = R_ALPHA_TPREL16;
1637 break;
1638 default:
1639 BFD_ASSERT (0);
1640 return false;
1643 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), r_type);
1644 info->changed_relocs = true;
1646 /* Reduce the use count on this got entry by one, possibly
1647 eliminating it. */
1648 if (--info->gotent->use_count == 0)
1650 int sz = alpha_got_entry_size (r_type);
1651 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
1652 if (!info->h)
1653 alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
1656 /* ??? Search forward through this basic block looking for insns
1657 that use the target register. Stop after an insn modifying the
1658 register is seen, or after a branch or call.
1660 Any such memory load insn may be substituted by a load directly
1661 off the GP. This allows the memory load insn to be issued before
1662 the calculated GP register would otherwise be ready.
1664 Any such jsr insn can be replaced by a bsr if it is in range.
1666 This would mean that we'd have to _add_ relocations, the pain of
1667 which gives one pause. */
1669 return true;
1672 static boolean
1673 elf64_alpha_relax_gprelhilo (info, symval, irel, hi)
1674 struct alpha_relax_info *info;
1675 bfd_vma symval;
1676 Elf_Internal_Rela *irel;
1677 boolean hi;
1679 unsigned int insn;
1680 bfd_signed_vma disp;
1681 bfd_byte *pos = info->contents + irel->r_offset;
1683 /* ??? This assumes that the compiler doesn't render
1685 array[i]
1687 ldah t, array(gp) !gprelhigh
1688 s8addl i, t, t
1689 ldq r, array(t) !gprellow
1691 which would indeed be the most efficient way to implement this. */
1693 return true;
1695 disp = symval - info->gp;
1696 if (disp < -0x8000 || disp >= 0x8000)
1697 return true;
1699 if (hi)
1701 /* Nop out the high instruction. */
1703 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos);
1704 info->changed_contents = true;
1706 irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1707 irel->r_addend = 0;
1708 info->changed_relocs = true;
1710 else
1712 /* Adjust the low instruction to reference GP directly. */
1714 insn = bfd_get_32 (info->abfd, pos);
1715 insn = (insn & 0xffe00000) | (29 << 16);
1716 bfd_put_32 (info->abfd, (bfd_vma) insn, pos);
1717 info->changed_contents = true;
1719 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1720 R_ALPHA_GPREL16);
1721 info->changed_relocs = true;
1724 return true;
1727 static boolean
1728 elf64_alpha_relax_tls_get_addr (info, symval, irel, is_gd)
1729 struct alpha_relax_info *info;
1730 bfd_vma symval;
1731 Elf_Internal_Rela *irel;
1732 boolean is_gd;
1734 bfd_byte *pos[5];
1735 unsigned int insn;
1736 Elf_Internal_Rela *gpdisp, *hint;
1737 boolean dynamic, use_gottprel;
1739 dynamic = alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info);
1741 /* ??? For LD relaxation, we need a symbol referencing the beginning
1742 of the TLS segment. */
1743 if (!is_gd)
1744 return true;
1746 /* If a TLS symbol is accessed using IE at least once, there is no point
1747 to use dynamic model for it. */
1748 if (is_gd && info->h && (info->h->flags & ALPHA_ELF_LINK_HASH_TLS_IE))
1751 /* If the symbol is local, and we've already committed to DF_STATIC_TLS,
1752 then we might as well relax to IE. */
1753 else if (info->link_info->shared && !dynamic
1754 && (info->link_info->flags & DF_STATIC_TLS))
1757 /* Otherwise we must be building an executable to do anything. */
1758 else if (info->link_info->shared)
1759 return true;
1761 /* The TLSGD/TLSLDM relocation must be followed by a LITERAL and
1762 the matching LITUSE_TLS relocations. */
1763 if (irel + 2 >= info->relend)
1764 return true;
1765 if (ELF64_R_TYPE (irel[1].r_info) != R_ALPHA_LITERAL
1766 || ELF64_R_TYPE (irel[2].r_info) != R_ALPHA_LITUSE
1767 || irel[2].r_addend != (is_gd ? LITUSE_ALPHA_TLSGD : LITUSE_ALPHA_TLSLDM))
1768 return true;
1770 /* There must be a GPDISP relocation positioned immediately after the
1771 LITUSE relocation. */
1772 gpdisp = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
1773 irel[2].r_offset + 4, R_ALPHA_GPDISP);
1774 if (!gpdisp)
1775 return true;
1777 pos[0] = info->contents + irel[0].r_offset;
1778 pos[1] = info->contents + irel[1].r_offset;
1779 pos[2] = info->contents + irel[2].r_offset;
1780 pos[3] = info->contents + gpdisp->r_offset;
1781 pos[4] = pos[3] + gpdisp->r_addend;
1783 /* Only positions 0 and 1 are allowed to be out of order. */
1784 if (pos[1] < pos[0])
1786 bfd_byte *tmp = pos[0];
1787 pos[0] = pos[1];
1788 pos[1] = tmp;
1790 if (pos[1] >= pos[2] || pos[2] >= pos[3] || pos[3] >= pos[4])
1791 return true;
1793 /* Reduce the use count on the LITERAL relocation. Do this before we
1794 smash the symndx when we adjust the relocations below. */
1796 struct alpha_elf_got_entry *lit_gotent;
1797 struct alpha_elf_link_hash_entry *lit_h;
1798 unsigned long indx;
1800 BFD_ASSERT (ELF64_R_SYM (irel[1].r_info) >= info->symtab_hdr->sh_info);
1801 indx = ELF64_R_SYM (irel[1].r_info) - info->symtab_hdr->sh_info;
1802 lit_h = alpha_elf_sym_hashes (info->abfd)[indx];
1804 while (lit_h->root.root.type == bfd_link_hash_indirect
1805 || lit_h->root.root.type == bfd_link_hash_warning)
1806 lit_h = (struct alpha_elf_link_hash_entry *) lit_h->root.root.u.i.link;
1808 for (lit_gotent = lit_h->got_entries; lit_gotent ;
1809 lit_gotent = lit_gotent->next)
1810 if (lit_gotent->gotobj == info->gotobj
1811 && lit_gotent->reloc_type == R_ALPHA_LITERAL
1812 && lit_gotent->addend == irel[1].r_addend)
1813 break;
1814 BFD_ASSERT (lit_gotent);
1816 if (--lit_gotent->use_count == 0)
1818 int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
1819 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
1823 /* Change
1825 lda $16,x($gp) !tlsgd!1
1826 ldq $27,__tls_get_addr($gp) !literal!1
1827 jsr $26,($27)__tls_get_addr !lituse_tlsgd!1
1828 ldah $29,0($26) !gpdisp!2
1829 lda $29,0($29) !gpdisp!2
1831 ldq $16,x($gp) !gottprel
1832 unop
1833 call_pal rduniq
1834 addq $16,$0,$0
1835 unop
1836 or the first pair to
1837 lda $16,x($gp) !tprel
1838 unop
1840 ldah $16,x($gp) !tprelhi
1841 lda $16,x($16) !tprello
1843 as appropriate. */
1845 use_gottprel = false;
1846 switch (!dynamic && !info->link_info->shared)
1848 case 1:
1850 bfd_vma tp_base;
1851 bfd_signed_vma disp;
1853 BFD_ASSERT (info->tls_segment != NULL);
1854 tp_base = alpha_get_tprel_base (info->tls_segment);
1855 disp = symval - tp_base;
1857 if (disp >= -0x8000 && disp < 0x8000)
1859 insn = (OP_LDA << 26) | (16 << 21) | (31 << 16);
1860 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
1861 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
1863 irel[0].r_offset = pos[0] - info->contents;
1864 irel[0].r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1865 R_ALPHA_TPREL16);
1866 irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1867 break;
1869 else if (disp >= -(bfd_signed_vma) 0x80000000
1870 && disp < (bfd_signed_vma) 0x7fff8000)
1872 insn = (OP_LDAH << 26) | (16 << 21) | (31 << 16);
1873 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
1874 insn = (OP_LDA << 26) | (16 << 21) | (16 << 16);
1875 bfd_put_32 (info->abfd, (bfd_vma) insn, 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),
1879 R_ALPHA_TPRELHI);
1880 irel[1].r_offset = pos[1] - info->contents;
1881 irel[1].r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1882 R_ALPHA_TPRELLO);
1883 break;
1886 /* FALLTHRU */
1888 default:
1889 use_gottprel = true;
1891 insn = (OP_LDQ << 26) | (16 << 21) | (29 << 16);
1892 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
1893 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
1895 irel[0].r_offset = pos[0] - info->contents;
1896 irel[0].r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1897 R_ALPHA_GOTTPREL);
1898 irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1899 break;
1902 bfd_put_32 (info->abfd, (bfd_vma) INSN_RDUNIQ, pos[2]);
1904 insn = INSN_ADDQ | (16 << 21) | (0 << 16) | (0 << 0);
1905 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[3]);
1907 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[4]);
1909 irel[2].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1910 gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1912 hint = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
1913 irel[2].r_offset, R_ALPHA_HINT);
1914 if (hint)
1915 hint->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1917 info->changed_contents = true;
1918 info->changed_relocs = true;
1920 /* Reduce the use count on the TLSGD/TLSLDM relocation. */
1921 if (--info->gotent->use_count == 0)
1923 int sz = alpha_got_entry_size (info->gotent->reloc_type);
1924 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
1925 if (!info->h)
1926 alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
1929 /* If we've switched to a GOTTPREL relocation, increment the reference
1930 count on that got entry. */
1931 if (use_gottprel)
1933 struct alpha_elf_got_entry *tprel_gotent;
1935 for (tprel_gotent = *info->first_gotent; tprel_gotent ;
1936 tprel_gotent = tprel_gotent->next)
1937 if (tprel_gotent->gotobj == info->gotobj
1938 && tprel_gotent->reloc_type == R_ALPHA_GOTTPREL
1939 && tprel_gotent->addend == irel->r_addend)
1940 break;
1941 if (tprel_gotent)
1942 tprel_gotent->use_count++;
1943 else
1945 if (info->gotent->use_count == 0)
1946 tprel_gotent = info->gotent;
1947 else
1949 tprel_gotent = (struct alpha_elf_got_entry *)
1950 bfd_alloc (info->abfd, sizeof (struct alpha_elf_got_entry));
1951 if (!tprel_gotent)
1952 return false;
1954 tprel_gotent->next = *info->first_gotent;
1955 *info->first_gotent = tprel_gotent;
1957 tprel_gotent->gotobj = info->gotobj;
1958 tprel_gotent->addend = irel->r_addend;
1959 tprel_gotent->got_offset = -1;
1960 tprel_gotent->reloc_done = 0;
1961 tprel_gotent->reloc_xlated = 0;
1964 tprel_gotent->use_count = 1;
1965 tprel_gotent->reloc_type = R_ALPHA_GOTTPREL;
1969 return true;
1972 static struct elf_link_tls_segment *
1973 elf64_alpha_relax_find_tls_segment (info, seg)
1974 struct alpha_relax_info *info;
1975 struct elf_link_tls_segment *seg;
1977 bfd *output_bfd = info->sec->output_section->owner;
1978 asection *first_tls_sec = NULL, *o;
1979 unsigned int align;
1980 bfd_vma base, end;
1982 for (o = output_bfd->sections; o ; o = o->next)
1983 if ((o->flags & SEC_THREAD_LOCAL) != 0
1984 && (o->flags & SEC_LOAD) != 0)
1986 first_tls_sec = o;
1987 break;
1989 if (!first_tls_sec)
1990 return NULL;
1992 base = first_tls_sec->vma;
1993 align = 0;
1995 for (o = first_tls_sec; o && (o->flags & SEC_THREAD_LOCAL); o = o->next)
1997 bfd_vma size;
1999 if (bfd_get_section_alignment (output_bfd, o) > align)
2000 align = bfd_get_section_alignment (output_bfd, o);
2002 size = o->_raw_size;
2003 if (size == 0 && (o->flags & SEC_HAS_CONTENTS) == 0)
2005 struct bfd_link_order *lo;
2006 for (lo = o->link_order_head; lo ; lo = lo->next)
2007 if (size < lo->offset + lo->size)
2008 size = lo->offset + lo->size;
2010 end = o->vma + size;
2013 seg->start = base;
2014 seg->size = end - base;
2015 seg->align = align;
2017 return seg;
2020 static boolean
2021 elf64_alpha_relax_section (abfd, sec, link_info, again)
2022 bfd *abfd;
2023 asection *sec;
2024 struct bfd_link_info *link_info;
2025 boolean *again;
2027 Elf_Internal_Shdr *symtab_hdr;
2028 Elf_Internal_Shdr *shndx_hdr;
2029 Elf_Internal_Rela *internal_relocs;
2030 Elf_Internal_Rela *free_relocs = NULL;
2031 Elf_Internal_Rela *irel, *irelend;
2032 bfd_byte *free_contents = NULL;
2033 Elf64_External_Sym *extsyms;
2034 Elf64_External_Sym *free_extsyms = NULL;
2035 Elf_External_Sym_Shndx *shndx_buf = NULL;
2036 struct alpha_elf_got_entry **local_got_entries;
2037 struct alpha_relax_info info;
2038 struct elf_link_tls_segment tls_segment;
2040 /* We are not currently changing any sizes, so only one pass. */
2041 *again = false;
2043 if (link_info->relocateable
2044 || (sec->flags & SEC_RELOC) == 0
2045 || sec->reloc_count == 0)
2046 return true;
2048 /* If this is the first time we have been called for this section,
2049 initialize the cooked size. */
2050 if (sec->_cooked_size == 0)
2051 sec->_cooked_size = sec->_raw_size;
2053 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2054 local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
2056 /* Load the relocations for this section. */
2057 internal_relocs = (_bfd_elf64_link_read_relocs
2058 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
2059 link_info->keep_memory));
2060 if (internal_relocs == NULL)
2061 goto error_return;
2062 if (! link_info->keep_memory)
2063 free_relocs = internal_relocs;
2065 memset(&info, 0, sizeof (info));
2066 info.abfd = abfd;
2067 info.sec = sec;
2068 info.link_info = link_info;
2069 info.symtab_hdr = symtab_hdr;
2070 info.relocs = internal_relocs;
2071 info.relend = irelend = internal_relocs + sec->reloc_count;
2073 /* Find the GP for this object. Do not store the result back via
2074 _bfd_set_gp_value, since this could change again before final. */
2075 info.gotobj = alpha_elf_tdata (abfd)->gotobj;
2076 if (info.gotobj)
2078 asection *sgot = alpha_elf_tdata (info.gotobj)->got;
2079 info.gp = (sgot->output_section->vma
2080 + sgot->output_offset
2081 + 0x8000);
2084 /* Get the section contents. */
2085 if (elf_section_data (sec)->this_hdr.contents != NULL)
2086 info.contents = elf_section_data (sec)->this_hdr.contents;
2087 else
2089 info.contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
2090 if (info.contents == NULL)
2091 goto error_return;
2092 free_contents = info.contents;
2094 if (! bfd_get_section_contents (abfd, sec, info.contents,
2095 (file_ptr) 0, sec->_raw_size))
2096 goto error_return;
2099 /* Read this BFD's symbols. */
2100 if (symtab_hdr->contents != NULL)
2101 extsyms = (Elf64_External_Sym *) symtab_hdr->contents;
2102 else
2104 bfd_size_type amt = symtab_hdr->sh_info * sizeof (Elf64_External_Sym);
2105 extsyms = (Elf64_External_Sym *) bfd_malloc (amt);
2106 if (extsyms == NULL)
2107 goto error_return;
2108 free_extsyms = extsyms;
2109 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
2110 || bfd_bread ((PTR) extsyms, amt, abfd) != amt)
2111 goto error_return;
2114 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
2115 if (shndx_hdr->sh_size != 0)
2117 bfd_size_type amt;
2118 amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
2119 shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
2120 if (shndx_buf == NULL)
2121 goto error_return;
2122 if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
2123 || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
2124 goto error_return;
2127 /* Compute the TLS segment information. The version normally found in
2128 elf_hash_table (link_info)->tls_segment isn't built until final_link.
2129 ??? Probably should look into extracting this into a common function. */
2130 info.tls_segment = elf64_alpha_relax_find_tls_segment (&info, &tls_segment);
2132 for (irel = internal_relocs; irel < irelend; irel++)
2134 bfd_vma symval;
2135 Elf_Internal_Sym isym;
2136 struct alpha_elf_got_entry *gotent;
2137 unsigned long r_type = ELF64_R_TYPE (irel->r_info);
2139 /* Early exit for unhandled or unrelaxable relocations. */
2140 switch (r_type)
2142 case R_ALPHA_LITERAL:
2143 case R_ALPHA_GPRELHIGH:
2144 case R_ALPHA_GPRELLOW:
2145 case R_ALPHA_GOTDTPREL:
2146 case R_ALPHA_GOTTPREL:
2147 case R_ALPHA_TLSGD:
2148 case R_ALPHA_TLSLDM:
2149 break;
2150 default:
2151 continue;
2154 /* Get the value of the symbol referred to by the reloc. */
2155 if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2157 /* A local symbol. */
2158 Elf64_External_Sym *esym;
2159 Elf_External_Sym_Shndx *shndx;
2161 esym = extsyms + ELF64_R_SYM (irel->r_info);
2162 shndx = shndx_buf + (shndx_buf ? ELF64_R_SYM (irel->r_info) : 0);
2163 bfd_elf64_swap_symbol_in (abfd, esym, shndx, &isym);
2164 if (isym.st_shndx == SHN_UNDEF)
2165 info.tsec = bfd_und_section_ptr;
2166 else if (isym.st_shndx == SHN_ABS)
2167 info.tsec = bfd_abs_section_ptr;
2168 else if (isym.st_shndx == SHN_COMMON)
2169 info.tsec = bfd_com_section_ptr;
2170 else
2171 info.tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
2173 info.h = NULL;
2174 info.other = isym.st_other;
2175 info.first_gotent = &local_got_entries[ELF64_R_SYM(irel->r_info)];
2176 symval = isym.st_value;
2178 else
2180 unsigned long indx;
2181 struct alpha_elf_link_hash_entry *h;
2183 indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2184 h = alpha_elf_sym_hashes (abfd)[indx];
2185 BFD_ASSERT (h != NULL);
2187 while (h->root.root.type == bfd_link_hash_indirect
2188 || h->root.root.type == bfd_link_hash_warning)
2189 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
2191 info.h = h;
2192 info.tsec = h->root.root.u.def.section;
2193 info.other = h->root.other;
2194 info.first_gotent = &h->got_entries;
2195 symval = h->root.root.u.def.value;
2198 /* Search for the got entry to be used by this relocation. */
2199 for (gotent = *info.first_gotent; gotent ; gotent = gotent->next)
2200 if (gotent->gotobj == info.gotobj
2201 && gotent->reloc_type == r_type
2202 && gotent->addend == irel->r_addend)
2203 break;
2204 info.gotent = gotent;
2206 symval += info.tsec->output_section->vma + info.tsec->output_offset;
2207 symval += irel->r_addend;
2209 switch (r_type)
2211 case R_ALPHA_LITERAL:
2212 BFD_ASSERT(info.gotent != NULL);
2214 /* If there exist LITUSE relocations immediately following, this
2215 opens up all sorts of interesting optimizations, because we
2216 now know every location that this address load is used. */
2217 if (irel+1 < irelend
2218 && ELF64_R_TYPE (irel[1].r_info) == R_ALPHA_LITUSE)
2220 if (!elf64_alpha_relax_with_lituse (&info, symval, irel))
2221 goto error_return;
2223 else
2225 if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
2226 goto error_return;
2228 break;
2230 case R_ALPHA_GPRELHIGH:
2231 case R_ALPHA_GPRELLOW:
2232 if (!elf64_alpha_relax_gprelhilo (&info, symval, irel,
2233 r_type == R_ALPHA_GPRELHIGH))
2234 goto error_return;
2235 break;
2237 case R_ALPHA_GOTDTPREL:
2238 case R_ALPHA_GOTTPREL:
2239 BFD_ASSERT(info.gotent != NULL);
2240 if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
2241 goto error_return;
2242 break;
2244 case R_ALPHA_TLSGD:
2245 case R_ALPHA_TLSLDM:
2246 BFD_ASSERT(info.gotent != NULL);
2247 if (!elf64_alpha_relax_tls_get_addr (&info, symval, irel,
2248 r_type == R_ALPHA_TLSGD))
2249 goto error_return;
2250 break;
2254 if (!elf64_alpha_size_got_sections (abfd, link_info))
2255 return false;
2257 if (info.changed_relocs)
2258 elf_section_data (sec)->relocs = internal_relocs;
2259 else if (free_relocs != NULL)
2260 free (free_relocs);
2262 if (info.changed_contents)
2263 elf_section_data (sec)->this_hdr.contents = info.contents;
2264 else if (free_contents != NULL)
2266 if (! link_info->keep_memory)
2267 free (free_contents);
2268 else
2270 /* Cache the section contents for elf_link_input_bfd. */
2271 elf_section_data (sec)->this_hdr.contents = info.contents;
2275 if (shndx_buf != NULL)
2276 free (shndx_buf);
2278 if (free_extsyms != NULL)
2280 if (! link_info->keep_memory)
2281 free (free_extsyms);
2282 else
2284 /* Cache the symbols for elf_link_input_bfd. */
2285 symtab_hdr->contents = (unsigned char *) extsyms;
2289 *again = info.changed_contents || info.changed_relocs;
2291 return true;
2293 error_return:
2294 if (free_relocs != NULL)
2295 free (free_relocs);
2296 if (free_contents != NULL)
2297 free (free_contents);
2298 if (shndx_buf != NULL)
2299 free (shndx_buf);
2300 if (free_extsyms != NULL)
2301 free (free_extsyms);
2302 return false;
2305 /* PLT/GOT Stuff */
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
2324 how to. */
2326 static boolean
2327 elf64_alpha_section_from_shdr (abfd, hdr, name)
2328 bfd *abfd;
2329 Elf64_Internal_Shdr *hdr;
2330 char *name;
2332 asection *newsect;
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)
2343 return false;
2344 break;
2345 default:
2346 return false;
2349 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
2350 return false;
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)
2357 | SEC_DEBUGGING)))
2358 return false;
2361 return true;
2364 /* Convert Alpha specific section flags to bfd internal section flags. */
2366 static boolean
2367 elf64_alpha_section_flags (flags, hdr)
2368 flagword *flags;
2369 Elf64_Internal_Shdr *hdr;
2371 if (hdr->sh_flags & SHF_ALPHA_GPREL)
2372 *flags |= SEC_SMALL_DATA;
2374 return true;
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. */
2380 static boolean
2381 elf64_alpha_fake_sections (abfd, hdr, sec)
2382 bfd *abfd;
2383 Elf64_Internal_Shdr *hdr;
2384 asection *sec;
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;
2397 else
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;
2407 return true;
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. */
2413 static boolean
2414 elf64_alpha_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
2415 bfd *abfd;
2416 struct bfd_link_info *info;
2417 const Elf_Internal_Sym *sym;
2418 const char **namep ATTRIBUTE_UNUSED;
2419 flagword *flagsp ATTRIBUTE_UNUSED;
2420 asection **secp;
2421 bfd_vma *valp;
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");
2432 if (scomm == NULL)
2434 scomm = bfd_make_section (abfd, ".scommon");
2435 if (scomm == NULL
2436 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
2437 | SEC_IS_COMMON
2438 | SEC_LINKER_CREATED)))
2439 return false;
2442 *secp = scomm;
2443 *valp = sym->st_size;
2446 return true;
2449 /* Create the .got section. */
2451 static boolean
2452 elf64_alpha_create_got_section(abfd, info)
2453 bfd *abfd;
2454 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2456 asection *s;
2458 if (bfd_get_section_by_name (abfd, ".got"))
2459 return true;
2461 s = bfd_make_section (abfd, ".got");
2462 if (s == NULL
2463 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
2464 | SEC_HAS_CONTENTS
2465 | SEC_IN_MEMORY
2466 | SEC_LINKER_CREATED))
2467 || !bfd_set_section_alignment (abfd, s, 3))
2468 return false;
2470 alpha_elf_tdata (abfd)->got = s;
2472 return true;
2475 /* Create all the dynamic sections. */
2477 static boolean
2478 elf64_alpha_create_dynamic_sections (abfd, info)
2479 bfd *abfd;
2480 struct bfd_link_info *info;
2482 asection *s;
2483 struct elf_link_hash_entry *h;
2485 /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */
2487 s = bfd_make_section (abfd, ".plt");
2488 if (s == NULL
2489 || ! bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
2490 | SEC_HAS_CONTENTS
2491 | SEC_IN_MEMORY
2492 | SEC_LINKER_CREATED
2493 | SEC_CODE))
2494 || ! bfd_set_section_alignment (abfd, s, 3))
2495 return false;
2497 /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
2498 .plt section. */
2499 h = NULL;
2500 if (! (_bfd_generic_link_add_one_symbol
2501 (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
2502 (bfd_vma) 0, (const char *) NULL, false,
2503 get_elf_backend_data (abfd)->collect,
2504 (struct bfd_link_hash_entry **) &h)))
2505 return false;
2506 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
2507 h->type = STT_OBJECT;
2509 if (info->shared
2510 && ! _bfd_elf_link_record_dynamic_symbol (info, h))
2511 return false;
2513 s = bfd_make_section (abfd, ".rela.plt");
2514 if (s == NULL
2515 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
2516 | SEC_HAS_CONTENTS
2517 | SEC_IN_MEMORY
2518 | SEC_LINKER_CREATED
2519 | SEC_READONLY))
2520 || ! bfd_set_section_alignment (abfd, s, 3))
2521 return false;
2523 /* We may or may not have created a .got section for this object, but
2524 we definitely havn't done the rest of the work. */
2526 if (!elf64_alpha_create_got_section (abfd, info))
2527 return false;
2529 s = bfd_make_section(abfd, ".rela.got");
2530 if (s == NULL
2531 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
2532 | SEC_HAS_CONTENTS
2533 | SEC_IN_MEMORY
2534 | SEC_LINKER_CREATED
2535 | SEC_READONLY))
2536 || !bfd_set_section_alignment (abfd, s, 3))
2537 return false;
2539 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
2540 dynobj's .got section. We don't do this in the linker script
2541 because we don't want to define the symbol if we are not creating
2542 a global offset table. */
2543 h = NULL;
2544 if (!(_bfd_generic_link_add_one_symbol
2545 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL,
2546 alpha_elf_tdata(abfd)->got, (bfd_vma) 0, (const char *) NULL,
2547 false, get_elf_backend_data (abfd)->collect,
2548 (struct bfd_link_hash_entry **) &h)))
2549 return false;
2550 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
2551 h->type = STT_OBJECT;
2553 if (info->shared
2554 && ! _bfd_elf_link_record_dynamic_symbol (info, h))
2555 return false;
2557 elf_hash_table (info)->hgot = h;
2559 return true;
2562 /* Read ECOFF debugging information from a .mdebug section into a
2563 ecoff_debug_info structure. */
2565 static boolean
2566 elf64_alpha_read_ecoff_info (abfd, section, debug)
2567 bfd *abfd;
2568 asection *section;
2569 struct ecoff_debug_info *debug;
2571 HDRR *symhdr;
2572 const struct ecoff_debug_swap *swap;
2573 char *ext_hdr = NULL;
2575 swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
2576 memset (debug, 0, sizeof (*debug));
2578 ext_hdr = (char *) bfd_malloc (swap->external_hdr_size);
2579 if (ext_hdr == NULL && swap->external_hdr_size != 0)
2580 goto error_return;
2582 if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
2583 swap->external_hdr_size)
2584 == false)
2585 goto error_return;
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
2591 read. */
2592 #define READ(ptr, offset, count, size, type) \
2593 if (symhdr->count == 0) \
2594 debug->ptr = NULL; \
2595 else \
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),
2612 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);
2618 #undef READ
2620 debug->fdr = NULL;
2621 debug->adjust = NULL;
2623 return true;
2625 error_return:
2626 if (ext_hdr != NULL)
2627 free (ext_hdr);
2628 if (debug->line != NULL)
2629 free (debug->line);
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)
2641 free (debug->ss);
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);
2650 return false;
2653 /* Alpha ELF local labels start with '$'. */
2655 static boolean
2656 elf64_alpha_is_local_label_name (abfd, name)
2657 bfd *abfd ATTRIBUTE_UNUSED;
2658 const char *name;
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;
2674 static boolean
2675 elf64_alpha_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
2676 functionname_ptr, line_ptr)
2677 bfd *abfd;
2678 asection *section;
2679 asymbol **symbols;
2680 bfd_vma offset;
2681 const char **filename_ptr;
2682 const char **functionname_ptr;
2683 unsigned int *line_ptr;
2685 asection *msec;
2687 if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
2688 filename_ptr, functionname_ptr,
2689 line_ptr, 0,
2690 &elf_tdata (abfd)->dwarf2_find_line_info))
2691 return true;
2693 msec = bfd_get_section_by_name (abfd, ".mdebug");
2694 if (msec != NULL)
2696 flagword origflags;
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;
2709 if (fi == NULL)
2711 bfd_size_type external_fdr_size;
2712 char *fraw_src;
2713 char *fraw_end;
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);
2718 if (fi == NULL)
2720 msec->flags = origflags;
2721 return false;
2724 if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d))
2726 msec->flags = origflags;
2727 return false;
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;
2736 return false;
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,
2758 line_ptr))
2760 msec->flags = origflags;
2761 return true;
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,
2771 line_ptr);
2774 /* Structure used to pass information to alpha_elf_output_extsym. */
2776 struct extsym_info
2778 bfd *abfd;
2779 struct bfd_link_info *info;
2780 struct ecoff_debug_info *debug;
2781 const struct ecoff_debug_swap *swap;
2782 boolean failed;
2785 static boolean
2786 elf64_alpha_output_extsym (h, data)
2787 struct alpha_elf_link_hash_entry *h;
2788 PTR data;
2790 struct extsym_info *einfo = (struct extsym_info *) data;
2791 boolean strip;
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)
2798 strip = false;
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)
2803 strip = true;
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))
2809 strip = true;
2810 else
2811 strip = false;
2813 if (strip)
2814 return true;
2816 if (h->esym.ifd == -2)
2818 h->esym.jmptbl = 0;
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;
2829 else
2831 const char *name;
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;
2840 else
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;
2861 else
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);
2886 else
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");
2894 if (sec == NULL)
2895 h->esym.asym.value = 0;
2896 else
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);
2903 else
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,
2910 &h->esym))
2912 einfo->failed = true;
2913 return false;
2916 return 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)
2923 bfd *abfd;
2924 struct alpha_elf_link_hash_entry *h;
2925 unsigned long r_type, r_symndx;
2926 bfd_vma r_addend;
2928 struct alpha_elf_got_entry *gotent;
2929 struct alpha_elf_got_entry **slot;
2931 if (h)
2932 slot = &h->got_entries;
2933 else
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)
2942 bfd_size_type size;
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 *);
2949 local_got_entries
2950 = (struct alpha_elf_got_entry **) bfd_alloc (abfd, size);
2951 if (!local_got_entries)
2952 return NULL;
2954 memset (local_got_entries, 0, (size_t) size);
2955 alpha_elf_tdata (abfd)->local_got_entries = local_got_entries;
2958 slot = &local_got_entries[r_symndx];
2961 for (gotent = *slot; gotent ; gotent = gotent->next)
2962 if (gotent->gotobj == abfd
2963 && gotent->reloc_type == r_type
2964 && gotent->addend == r_addend)
2965 break;
2967 if (!gotent)
2969 int entry_size;
2970 bfd_size_type amt;
2972 amt = sizeof (struct alpha_elf_got_entry);
2973 gotent = (struct alpha_elf_got_entry *) bfd_alloc (abfd, amt);
2974 if (!gotent)
2975 return NULL;
2977 gotent->gotobj = abfd;
2978 gotent->addend = r_addend;
2979 gotent->got_offset = -1;
2980 gotent->use_count = 1;
2981 gotent->reloc_type = r_type;
2982 gotent->reloc_done = 0;
2983 gotent->reloc_xlated = 0;
2985 gotent->next = *slot;
2986 *slot = gotent;
2988 entry_size = alpha_got_entry_size (r_type);
2989 alpha_elf_tdata (abfd)->total_got_size += entry_size;
2990 if (!h)
2991 alpha_elf_tdata(abfd)->local_got_size += entry_size;
2993 else
2994 gotent->use_count += 1;
2996 return gotent;
2999 /* Handle dynamic relocations when doing an Alpha ELF link. */
3001 static boolean
3002 elf64_alpha_check_relocs (abfd, info, sec, relocs)
3003 bfd *abfd;
3004 struct bfd_link_info *info;
3005 asection *sec;
3006 const Elf_Internal_Rela *relocs;
3008 bfd *dynobj;
3009 asection *sreloc;
3010 const char *rel_sec_name;
3011 Elf_Internal_Shdr *symtab_hdr;
3012 struct alpha_elf_link_hash_entry **sym_hashes;
3013 const Elf_Internal_Rela *rel, *relend;
3014 boolean got_created;
3015 bfd_size_type amt;
3017 if (info->relocateable)
3018 return true;
3020 dynobj = elf_hash_table(info)->dynobj;
3021 if (dynobj == NULL)
3022 elf_hash_table(info)->dynobj = dynobj = abfd;
3024 sreloc = NULL;
3025 rel_sec_name = NULL;
3026 symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
3027 sym_hashes = alpha_elf_sym_hashes(abfd);
3028 got_created = false;
3030 relend = relocs + sec->reloc_count;
3031 for (rel = relocs; rel < relend; ++rel)
3033 enum {
3034 NEED_GOT = 1,
3035 NEED_GOT_ENTRY = 2,
3036 NEED_DYNREL = 4
3039 unsigned long r_symndx, r_type;
3040 struct alpha_elf_link_hash_entry *h;
3041 unsigned int gotent_flags;
3042 boolean maybe_dynamic;
3043 unsigned int need;
3044 bfd_vma addend;
3046 r_symndx = ELF64_R_SYM (rel->r_info);
3047 if (r_symndx < symtab_hdr->sh_info)
3048 h = NULL;
3049 else
3051 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3053 while (h->root.root.type == bfd_link_hash_indirect
3054 || h->root.root.type == bfd_link_hash_warning)
3055 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
3057 h->root.elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
3060 /* We can only get preliminary data on whether a symbol is
3061 locally or externally defined, as not all of the input files
3062 have yet been processed. Do something with what we know, as
3063 this may help reduce memory usage and processing time later. */
3064 maybe_dynamic = false;
3065 if (h && ((info->shared
3066 && (!info->symbolic || info->allow_shlib_undefined))
3067 || ! (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
3068 || h->root.root.type == bfd_link_hash_defweak))
3069 maybe_dynamic = true;
3071 need = 0;
3072 gotent_flags = 0;
3073 r_type = ELF64_R_TYPE (rel->r_info);
3074 addend = rel->r_addend;
3076 switch (r_type)
3078 case R_ALPHA_LITERAL:
3079 need = NEED_GOT | NEED_GOT_ENTRY;
3081 /* Remember how this literal is used from its LITUSEs.
3082 This will be important when it comes to decide if we can
3083 create a .plt entry for a function symbol. */
3084 while (++rel < relend && ELF64_R_TYPE (rel->r_info) == R_ALPHA_LITUSE)
3085 if (rel->r_addend >= 1 && rel->r_addend <= 5)
3086 gotent_flags |= 1 << rel->r_addend;
3087 --rel;
3089 /* No LITUSEs -- presumably the address is used somehow. */
3090 if (gotent_flags == 0)
3091 gotent_flags = ALPHA_ELF_LINK_HASH_LU_ADDR;
3092 break;
3094 case R_ALPHA_GPDISP:
3095 case R_ALPHA_GPREL16:
3096 case R_ALPHA_GPREL32:
3097 case R_ALPHA_GPRELHIGH:
3098 case R_ALPHA_GPRELLOW:
3099 case R_ALPHA_BRSGP:
3100 need = NEED_GOT;
3101 break;
3103 case R_ALPHA_REFLONG:
3104 case R_ALPHA_REFQUAD:
3105 if (info->shared || maybe_dynamic)
3106 need = NEED_DYNREL;
3107 break;
3109 case R_ALPHA_TLSGD:
3110 case R_ALPHA_TLSLDM:
3111 case R_ALPHA_GOTDTPREL:
3112 need = NEED_GOT | NEED_GOT_ENTRY;
3113 break;
3115 case R_ALPHA_GOTTPREL:
3116 need = NEED_GOT | NEED_GOT_ENTRY;
3117 gotent_flags = ALPHA_ELF_LINK_HASH_TLS_IE;
3118 if (info->shared)
3119 info->flags |= DF_STATIC_TLS;
3120 break;
3122 case R_ALPHA_TPREL64:
3123 if (info->shared || maybe_dynamic)
3124 need = NEED_DYNREL;
3125 if (info->shared)
3126 info->flags |= DF_STATIC_TLS;
3127 break;
3130 if (need & NEED_GOT)
3132 if (!got_created)
3134 if (!elf64_alpha_create_got_section (abfd, info))
3135 return false;
3137 /* Make sure the object's gotobj is set to itself so
3138 that we default to every object with its own .got.
3139 We'll merge .gots later once we've collected each
3140 object's info. */
3141 alpha_elf_tdata(abfd)->gotobj = abfd;
3143 got_created = 1;
3147 if (need & NEED_GOT_ENTRY)
3149 struct alpha_elf_got_entry *gotent;
3151 gotent = get_got_entry (abfd, h, r_type, r_symndx, addend);
3152 if (!gotent)
3153 return false;
3155 if (gotent_flags)
3157 gotent->flags |= gotent_flags;
3158 if (h)
3160 gotent_flags |= h->flags;
3161 h->flags = gotent_flags;
3163 /* Make a guess as to whether a .plt entry is needed. */
3164 if ((gotent_flags & ALPHA_ELF_LINK_HASH_LU_FUNC)
3165 && !(gotent_flags & ~ALPHA_ELF_LINK_HASH_LU_FUNC))
3166 h->root.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
3167 else
3168 h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
3173 if (need & NEED_DYNREL)
3175 if (rel_sec_name == NULL)
3177 rel_sec_name = (bfd_elf_string_from_elf_section
3178 (abfd, elf_elfheader(abfd)->e_shstrndx,
3179 elf_section_data(sec)->rel_hdr.sh_name));
3180 if (rel_sec_name == NULL)
3181 return false;
3183 BFD_ASSERT (strncmp (rel_sec_name, ".rela", 5) == 0
3184 && strcmp (bfd_get_section_name (abfd, sec),
3185 rel_sec_name+5) == 0);
3188 /* We need to create the section here now whether we eventually
3189 use it or not so that it gets mapped to an output section by
3190 the linker. If not used, we'll kill it in
3191 size_dynamic_sections. */
3192 if (sreloc == NULL)
3194 sreloc = bfd_get_section_by_name (dynobj, rel_sec_name);
3195 if (sreloc == NULL)
3197 flagword flags;
3199 sreloc = bfd_make_section (dynobj, rel_sec_name);
3200 flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
3201 | SEC_LINKER_CREATED | SEC_READONLY);
3202 if (sec->flags & SEC_ALLOC)
3203 flags |= SEC_ALLOC | SEC_LOAD;
3204 if (sreloc == NULL
3205 || !bfd_set_section_flags (dynobj, sreloc, flags)
3206 || !bfd_set_section_alignment (dynobj, sreloc, 3))
3207 return false;
3211 if (h)
3213 /* Since we havn't seen all of the input symbols yet, we
3214 don't know whether we'll actually need a dynamic relocation
3215 entry for this reloc. So make a record of it. Once we
3216 find out if this thing needs dynamic relocation we'll
3217 expand the relocation sections by the appropriate amount. */
3219 struct alpha_elf_reloc_entry *rent;
3221 for (rent = h->reloc_entries; rent; rent = rent->next)
3222 if (rent->rtype == r_type && rent->srel == sreloc)
3223 break;
3225 if (!rent)
3227 amt = sizeof (struct alpha_elf_reloc_entry);
3228 rent = (struct alpha_elf_reloc_entry *) bfd_alloc (abfd, amt);
3229 if (!rent)
3230 return false;
3232 rent->srel = sreloc;
3233 rent->rtype = r_type;
3234 rent->count = 1;
3235 rent->reltext = ((sec->flags & (SEC_READONLY | SEC_ALLOC))
3236 == (SEC_READONLY | SEC_ALLOC));
3238 rent->next = h->reloc_entries;
3239 h->reloc_entries = rent;
3241 else
3242 rent->count++;
3244 else if (info->shared)
3246 /* If this is a shared library, and the section is to be
3247 loaded into memory, we need a RELATIVE reloc. */
3248 sreloc->_raw_size += sizeof (Elf64_External_Rela);
3249 if ((sec->flags & (SEC_READONLY | SEC_ALLOC))
3250 == (SEC_READONLY | SEC_ALLOC))
3251 info->flags |= DF_TEXTREL;
3256 return true;
3259 /* Adjust a symbol defined by a dynamic object and referenced by a
3260 regular object. The current definition is in some section of the
3261 dynamic object, but we're not including those sections. We have to
3262 change the definition to something the rest of the link can
3263 understand. */
3265 static boolean
3266 elf64_alpha_adjust_dynamic_symbol (info, h)
3267 struct bfd_link_info *info;
3268 struct elf_link_hash_entry *h;
3270 bfd *dynobj;
3271 asection *s;
3272 struct alpha_elf_link_hash_entry *ah;
3274 dynobj = elf_hash_table(info)->dynobj;
3275 ah = (struct alpha_elf_link_hash_entry *)h;
3277 /* Now that we've seen all of the input symbols, finalize our decision
3278 about whether this symbol should get a .plt entry. */
3280 if (alpha_elf_dynamic_symbol_p (h, info)
3281 && ((h->type == STT_FUNC
3282 && !(ah->flags & ALPHA_ELF_LINK_HASH_LU_ADDR))
3283 || (h->type == STT_NOTYPE
3284 && (ah->flags & ALPHA_ELF_LINK_HASH_LU_FUNC)
3285 && !(ah->flags & ~ALPHA_ELF_LINK_HASH_LU_FUNC)))
3286 /* Don't prevent otherwise valid programs from linking by attempting
3287 to create a new .got entry somewhere. A Correct Solution would be
3288 to add a new .got section to a new object file and let it be merged
3289 somewhere later. But for now don't bother. */
3290 && ah->got_entries)
3292 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
3294 s = bfd_get_section_by_name(dynobj, ".plt");
3295 if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
3296 return false;
3298 /* The first bit of the .plt is reserved. */
3299 if (s->_raw_size == 0)
3300 s->_raw_size = PLT_HEADER_SIZE;
3302 h->plt.offset = s->_raw_size;
3303 s->_raw_size += PLT_ENTRY_SIZE;
3305 /* If this symbol is not defined in a regular file, and we are not
3306 generating a shared library, then set the symbol to the location
3307 in the .plt. This is required to make function pointers compare
3308 equal between the normal executable and the shared library. */
3309 if (! info->shared
3310 && h->root.type != bfd_link_hash_defweak)
3312 h->root.u.def.section = s;
3313 h->root.u.def.value = h->plt.offset;
3316 /* We also need a JMP_SLOT entry in the .rela.plt section. */
3317 s = bfd_get_section_by_name (dynobj, ".rela.plt");
3318 BFD_ASSERT (s != NULL);
3319 s->_raw_size += sizeof (Elf64_External_Rela);
3321 return true;
3323 else
3324 h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
3326 /* If this is a weak symbol, and there is a real definition, the
3327 processor independent code will have arranged for us to see the
3328 real definition first, and we can just use the same value. */
3329 if (h->weakdef != NULL)
3331 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
3332 || h->weakdef->root.type == bfd_link_hash_defweak);
3333 h->root.u.def.section = h->weakdef->root.u.def.section;
3334 h->root.u.def.value = h->weakdef->root.u.def.value;
3335 return true;
3338 /* This is a reference to a symbol defined by a dynamic object which
3339 is not a function. The Alpha, since it uses .got entries for all
3340 symbols even in regular objects, does not need the hackery of a
3341 .dynbss section and COPY dynamic relocations. */
3343 return true;
3346 /* Symbol versioning can create new symbols, and make our old symbols
3347 indirect to the new ones. Consolidate the got and reloc information
3348 in these situations. */
3350 static boolean
3351 elf64_alpha_merge_ind_symbols (hi, dummy)
3352 struct alpha_elf_link_hash_entry *hi;
3353 PTR dummy ATTRIBUTE_UNUSED;
3355 struct alpha_elf_link_hash_entry *hs;
3357 if (hi->root.root.type != bfd_link_hash_indirect)
3358 return true;
3359 hs = hi;
3360 do {
3361 hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link;
3362 } while (hs->root.root.type == bfd_link_hash_indirect);
3364 /* Merge the flags. Whee. */
3366 hs->flags |= hi->flags;
3368 /* Merge the .got entries. Cannibalize the old symbol's list in
3369 doing so, since we don't need it anymore. */
3371 if (hs->got_entries == NULL)
3372 hs->got_entries = hi->got_entries;
3373 else
3375 struct alpha_elf_got_entry *gi, *gs, *gin, *gsh;
3377 gsh = hs->got_entries;
3378 for (gi = hi->got_entries; gi ; gi = gin)
3380 gin = gi->next;
3381 for (gs = gsh; gs ; gs = gs->next)
3382 if (gi->gotobj == gs->gotobj
3383 && gi->reloc_type == gs->reloc_type
3384 && gi->addend == gs->addend)
3386 gi->use_count += gs->use_count;
3387 goto got_found;
3389 gi->next = hs->got_entries;
3390 hs->got_entries = gi;
3391 got_found:;
3394 hi->got_entries = NULL;
3396 /* And similar for the reloc entries. */
3398 if (hs->reloc_entries == NULL)
3399 hs->reloc_entries = hi->reloc_entries;
3400 else
3402 struct alpha_elf_reloc_entry *ri, *rs, *rin, *rsh;
3404 rsh = hs->reloc_entries;
3405 for (ri = hi->reloc_entries; ri ; ri = rin)
3407 rin = ri->next;
3408 for (rs = rsh; rs ; rs = rs->next)
3409 if (ri->rtype == rs->rtype)
3411 rs->count += ri->count;
3412 goto found_reloc;
3414 ri->next = hs->reloc_entries;
3415 hs->reloc_entries = ri;
3416 found_reloc:;
3419 hi->reloc_entries = NULL;
3421 return true;
3424 /* Is it possible to merge two object file's .got tables? */
3426 static boolean
3427 elf64_alpha_can_merge_gots (a, b)
3428 bfd *a, *b;
3430 int total = alpha_elf_tdata (a)->total_got_size;
3431 bfd *bsub;
3433 /* Trivial quick fallout test. */
3434 if (total + alpha_elf_tdata (b)->total_got_size <= MAX_GOT_SIZE)
3435 return true;
3437 /* By their nature, local .got entries cannot be merged. */
3438 if ((total += alpha_elf_tdata (b)->local_got_size) > MAX_GOT_SIZE)
3439 return false;
3441 /* Failing the common trivial comparison, we must effectively
3442 perform the merge. Not actually performing the merge means that
3443 we don't have to store undo information in case we fail. */
3444 for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
3446 struct alpha_elf_link_hash_entry **hashes = alpha_elf_sym_hashes (bsub);
3447 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
3448 int i, n;
3450 n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
3451 for (i = 0; i < n; ++i)
3453 struct alpha_elf_got_entry *ae, *be;
3454 struct alpha_elf_link_hash_entry *h;
3456 h = hashes[i];
3457 while (h->root.root.type == bfd_link_hash_indirect
3458 || h->root.root.type == bfd_link_hash_warning)
3459 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
3461 for (be = h->got_entries; be ; be = be->next)
3463 if (be->use_count == 0)
3464 continue;
3465 if (be->gotobj != b)
3466 continue;
3468 for (ae = h->got_entries; ae ; ae = ae->next)
3469 if (ae->gotobj == a
3470 && ae->reloc_type == be->reloc_type
3471 && ae->addend == be->addend)
3472 goto global_found;
3474 total += alpha_got_entry_size (be->reloc_type);
3475 if (total > MAX_GOT_SIZE)
3476 return false;
3477 global_found:;
3482 return true;
3485 /* Actually merge two .got tables. */
3487 static void
3488 elf64_alpha_merge_gots (a, b)
3489 bfd *a, *b;
3491 int total = alpha_elf_tdata (a)->total_got_size;
3492 bfd *bsub;
3494 /* Remember local expansion. */
3496 int e = alpha_elf_tdata (b)->local_got_size;
3497 total += e;
3498 alpha_elf_tdata (a)->local_got_size += e;
3501 for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
3503 struct alpha_elf_got_entry **local_got_entries;
3504 struct alpha_elf_link_hash_entry **hashes;
3505 Elf_Internal_Shdr *symtab_hdr;
3506 int i, n;
3508 /* Let the local .got entries know they are part of a new subsegment. */
3509 local_got_entries = alpha_elf_tdata (bsub)->local_got_entries;
3510 if (local_got_entries)
3512 n = elf_tdata (bsub)->symtab_hdr.sh_info;
3513 for (i = 0; i < n; ++i)
3515 struct alpha_elf_got_entry *ent;
3516 for (ent = local_got_entries[i]; ent; ent = ent->next)
3517 ent->gotobj = a;
3521 /* Merge the global .got entries. */
3522 hashes = alpha_elf_sym_hashes (bsub);
3523 symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
3525 n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
3526 for (i = 0; i < n; ++i)
3528 struct alpha_elf_got_entry *ae, *be, **pbe, **start;
3529 struct alpha_elf_link_hash_entry *h;
3531 h = hashes[i];
3532 while (h->root.root.type == bfd_link_hash_indirect
3533 || h->root.root.type == bfd_link_hash_warning)
3534 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
3536 start = &h->got_entries;
3537 for (pbe = start, be = *start; be ; pbe = &be->next, be = be->next)
3539 if (be->use_count == 0)
3541 *pbe = be->next;
3542 continue;
3544 if (be->gotobj != b)
3545 continue;
3547 for (ae = *start; ae ; ae = ae->next)
3548 if (ae->gotobj == a
3549 && ae->reloc_type == be->reloc_type
3550 && ae->addend == be->addend)
3552 ae->flags |= be->flags;
3553 ae->use_count += be->use_count;
3554 *pbe = be->next;
3555 goto global_found;
3557 be->gotobj = a;
3558 total += alpha_got_entry_size (be->reloc_type);
3560 global_found:;
3564 alpha_elf_tdata (bsub)->gotobj = a;
3566 alpha_elf_tdata (a)->total_got_size = total;
3568 /* Merge the two in_got chains. */
3570 bfd *next;
3572 bsub = a;
3573 while ((next = alpha_elf_tdata (bsub)->in_got_link_next) != NULL)
3574 bsub = next;
3576 alpha_elf_tdata (bsub)->in_got_link_next = b;
3580 /* Calculate the offsets for the got entries. */
3582 static boolean
3583 elf64_alpha_calc_got_offsets_for_symbol (h, arg)
3584 struct alpha_elf_link_hash_entry *h;
3585 PTR arg ATTRIBUTE_UNUSED;
3587 struct alpha_elf_got_entry *gotent;
3589 if (h->root.root.type == bfd_link_hash_warning)
3590 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
3592 for (gotent = h->got_entries; gotent; gotent = gotent->next)
3593 if (gotent->use_count > 0)
3595 bfd_size_type *plge
3596 = &alpha_elf_tdata (gotent->gotobj)->got->_raw_size;
3598 gotent->got_offset = *plge;
3599 *plge += alpha_got_entry_size (gotent->reloc_type);
3602 return true;
3605 static void
3606 elf64_alpha_calc_got_offsets (info)
3607 struct bfd_link_info *info;
3609 bfd *i, *got_list = alpha_elf_hash_table(info)->got_list;
3611 /* First, zero out the .got sizes, as we may be recalculating the
3612 .got after optimizing it. */
3613 for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
3614 alpha_elf_tdata(i)->got->_raw_size = 0;
3616 /* Next, fill in the offsets for all the global entries. */
3617 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
3618 elf64_alpha_calc_got_offsets_for_symbol,
3619 NULL);
3621 /* Finally, fill in the offsets for the local entries. */
3622 for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
3624 bfd_size_type got_offset = alpha_elf_tdata(i)->got->_raw_size;
3625 bfd *j;
3627 for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
3629 struct alpha_elf_got_entry **local_got_entries, *gotent;
3630 int k, n;
3632 local_got_entries = alpha_elf_tdata(j)->local_got_entries;
3633 if (!local_got_entries)
3634 continue;
3636 for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
3637 for (gotent = local_got_entries[k]; gotent; gotent = gotent->next)
3638 if (gotent->use_count > 0)
3640 gotent->got_offset = got_offset;
3641 got_offset += alpha_got_entry_size (gotent->reloc_type);
3645 alpha_elf_tdata(i)->got->_raw_size = got_offset;
3646 alpha_elf_tdata(i)->got->_cooked_size = got_offset;
3650 /* Constructs the gots. */
3652 static boolean
3653 elf64_alpha_size_got_sections (output_bfd, info)
3654 bfd *output_bfd ATTRIBUTE_UNUSED;
3655 struct bfd_link_info *info;
3657 bfd *i, *got_list, *cur_got_obj = NULL;
3658 int something_changed = 0;
3660 got_list = alpha_elf_hash_table (info)->got_list;
3662 /* On the first time through, pretend we have an existing got list
3663 consisting of all of the input files. */
3664 if (got_list == NULL)
3666 for (i = info->input_bfds; i ; i = i->link_next)
3668 bfd *this_got = alpha_elf_tdata (i)->gotobj;
3669 if (this_got == NULL)
3670 continue;
3672 /* We are assuming no merging has yet ocurred. */
3673 BFD_ASSERT (this_got == i);
3675 if (alpha_elf_tdata (this_got)->total_got_size > MAX_GOT_SIZE)
3677 /* Yikes! A single object file has too many entries. */
3678 (*_bfd_error_handler)
3679 (_("%s: .got subsegment exceeds 64K (size %d)"),
3680 bfd_archive_filename (i),
3681 alpha_elf_tdata (this_got)->total_got_size);
3682 return false;
3685 if (got_list == NULL)
3686 got_list = this_got;
3687 else
3688 alpha_elf_tdata(cur_got_obj)->got_link_next = this_got;
3689 cur_got_obj = this_got;
3692 /* Strange degenerate case of no got references. */
3693 if (got_list == NULL)
3694 return true;
3696 alpha_elf_hash_table (info)->got_list = got_list;
3698 /* Force got offsets to be recalculated. */
3699 something_changed = 1;
3702 cur_got_obj = got_list;
3703 i = alpha_elf_tdata(cur_got_obj)->got_link_next;
3704 while (i != NULL)
3706 if (elf64_alpha_can_merge_gots (cur_got_obj, i))
3708 elf64_alpha_merge_gots (cur_got_obj, i);
3709 i = alpha_elf_tdata(i)->got_link_next;
3710 alpha_elf_tdata(cur_got_obj)->got_link_next = i;
3711 something_changed = 1;
3713 else
3715 cur_got_obj = i;
3716 i = alpha_elf_tdata(i)->got_link_next;
3720 /* Once the gots have been merged, fill in the got offsets for
3721 everything therein. */
3722 if (1 || something_changed)
3723 elf64_alpha_calc_got_offsets (info);
3725 return true;
3728 static boolean
3729 elf64_alpha_always_size_sections (output_bfd, info)
3730 bfd *output_bfd;
3731 struct bfd_link_info *info;
3733 bfd *i;
3735 if (info->relocateable)
3736 return true;
3738 /* First, take care of the indirect symbols created by versioning. */
3739 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
3740 elf64_alpha_merge_ind_symbols,
3741 NULL);
3743 if (!elf64_alpha_size_got_sections (output_bfd, info))
3744 return false;
3746 /* Allocate space for all of the .got subsections. */
3747 i = alpha_elf_hash_table (info)->got_list;
3748 for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
3750 asection *s = alpha_elf_tdata(i)->got;
3751 if (s->_raw_size > 0)
3753 s->contents = (bfd_byte *) bfd_zalloc (i, s->_raw_size);
3754 if (s->contents == NULL)
3755 return false;
3759 return true;
3762 /* The number of dynamic relocations required by a static relocation. */
3764 static int
3765 alpha_dynamic_entries_for_reloc (r_type, dynamic, shared)
3766 int r_type, dynamic, shared;
3768 switch (r_type)
3770 /* May appear in GOT entries. */
3771 case R_ALPHA_TLSGD:
3772 return (dynamic ? 2 : shared ? 1 : 0);
3773 case R_ALPHA_TLSLDM:
3774 return shared;
3775 case R_ALPHA_LITERAL:
3776 return dynamic || shared;
3777 case R_ALPHA_GOTDTPREL:
3778 case R_ALPHA_GOTTPREL:
3779 return dynamic;
3781 /* May appear in data sections. */
3782 case R_ALPHA_REFLONG:
3783 case R_ALPHA_REFQUAD:
3784 return dynamic || shared;
3785 case R_ALPHA_SREL64:
3786 case R_ALPHA_TPREL64:
3787 return dynamic;
3789 /* Everything else is illegal. We'll issue an error during
3790 relocate_section. */
3791 default:
3792 return 0;
3796 /* Work out the sizes of the dynamic relocation entries. */
3798 static boolean
3799 elf64_alpha_calc_dynrel_sizes (h, info)
3800 struct alpha_elf_link_hash_entry *h;
3801 struct bfd_link_info *info;
3803 boolean dynamic;
3804 struct alpha_elf_reloc_entry *relent;
3805 struct alpha_elf_got_entry *gotent;
3806 int entries;
3808 if (h->root.root.type == bfd_link_hash_warning)
3809 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
3811 /* If the symbol was defined as a common symbol in a regular object
3812 file, and there was no definition in any dynamic object, then the
3813 linker will have allocated space for the symbol in a common
3814 section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been
3815 set. This is done for dynamic symbols in
3816 elf_adjust_dynamic_symbol but this is not done for non-dynamic
3817 symbols, somehow. */
3818 if (((h->root.elf_link_hash_flags
3819 & (ELF_LINK_HASH_DEF_REGULAR
3820 | ELF_LINK_HASH_REF_REGULAR
3821 | ELF_LINK_HASH_DEF_DYNAMIC))
3822 == ELF_LINK_HASH_REF_REGULAR)
3823 && (h->root.root.type == bfd_link_hash_defined
3824 || h->root.root.type == bfd_link_hash_defweak)
3825 && !(h->root.root.u.def.section->owner->flags & DYNAMIC))
3827 h->root.elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
3830 /* If the symbol is dynamic, we'll need all the relocations in their
3831 natural form. If this is a shared object, and it has been forced
3832 local, we'll need the same number of RELATIVE relocations. */
3834 dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
3836 for (relent = h->reloc_entries; relent; relent = relent->next)
3838 entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
3839 info->shared);
3840 if (entries)
3842 relent->srel->_raw_size +=
3843 entries * sizeof (Elf64_External_Rela) * relent->count;
3844 if (relent->reltext)
3845 info->flags |= DT_TEXTREL;
3849 entries = 0;
3850 for (gotent = h->got_entries; gotent ; gotent = gotent->next)
3851 entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type,
3852 dynamic, info->shared);
3854 /* If we are using a .plt entry, subtract one, as the first
3855 reference uses a .rela.plt entry instead. */
3856 if (h->root.plt.offset != MINUS_ONE)
3857 entries--;
3859 if (entries > 0)
3861 bfd *dynobj = elf_hash_table(info)->dynobj;
3862 asection *srel = bfd_get_section_by_name (dynobj, ".rela.got");
3863 BFD_ASSERT (srel != NULL);
3864 srel->_raw_size += sizeof (Elf64_External_Rela) * entries;
3867 return true;
3870 /* Set the sizes of the dynamic sections. */
3872 static boolean
3873 elf64_alpha_size_dynamic_sections (output_bfd, info)
3874 bfd *output_bfd ATTRIBUTE_UNUSED;
3875 struct bfd_link_info *info;
3877 bfd *dynobj;
3878 asection *s;
3879 boolean relplt;
3881 dynobj = elf_hash_table(info)->dynobj;
3882 BFD_ASSERT(dynobj != NULL);
3884 if (elf_hash_table (info)->dynamic_sections_created)
3886 int entries;
3887 bfd *i;
3889 /* Set the contents of the .interp section to the interpreter. */
3890 if (!info->shared)
3892 s = bfd_get_section_by_name (dynobj, ".interp");
3893 BFD_ASSERT (s != NULL);
3894 s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
3895 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
3898 /* Now that we've seen all of the input files, we can decide which
3899 symbols need dynamic relocation entries and which don't. We've
3900 collected information in check_relocs that we can now apply to
3901 size the dynamic relocation sections. */
3902 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
3903 elf64_alpha_calc_dynrel_sizes,
3904 info);
3906 /* Shared libraries often require RELATIVE relocs, and some relocs
3907 require attention for the main application as well. */
3909 entries = 0;
3910 for (i = alpha_elf_hash_table(info)->got_list;
3911 i ; i = alpha_elf_tdata(i)->got_link_next)
3913 bfd *j;
3915 for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
3917 struct alpha_elf_got_entry **local_got_entries, *gotent;
3918 int k, n;
3920 local_got_entries = alpha_elf_tdata(j)->local_got_entries;
3921 if (!local_got_entries)
3922 continue;
3924 for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
3925 for (gotent = local_got_entries[k];
3926 gotent ; gotent = gotent->next)
3927 if (gotent->use_count > 0)
3928 entries += (alpha_dynamic_entries_for_reloc
3929 (gotent->reloc_type, 0, info->shared));
3933 if (entries > 0)
3935 s = bfd_get_section_by_name (dynobj, ".rela.got");
3936 BFD_ASSERT (s != NULL);
3937 s->_raw_size += sizeof (Elf64_External_Rela) * entries;
3940 /* else we're not dynamic and by definition we don't need such things. */
3942 /* The check_relocs and adjust_dynamic_symbol entry points have
3943 determined the sizes of the various dynamic sections. Allocate
3944 memory for them. */
3945 relplt = false;
3946 for (s = dynobj->sections; s != NULL; s = s->next)
3948 const char *name;
3949 boolean strip;
3951 if (!(s->flags & SEC_LINKER_CREATED))
3952 continue;
3954 /* It's OK to base decisions on the section name, because none
3955 of the dynobj section names depend upon the input files. */
3956 name = bfd_get_section_name (dynobj, s);
3958 /* If we don't need this section, strip it from the output file.
3959 This is to handle .rela.bss and .rela.plt. We must create it
3960 in create_dynamic_sections, because it must be created before
3961 the linker maps input sections to output sections. The
3962 linker does that before adjust_dynamic_symbol is called, and
3963 it is that function which decides whether anything needs to
3964 go into these sections. */
3966 strip = false;
3968 if (strncmp (name, ".rela", 5) == 0)
3970 strip = (s->_raw_size == 0);
3972 if (!strip)
3974 if (strcmp(name, ".rela.plt") == 0)
3975 relplt = true;
3977 /* We use the reloc_count field as a counter if we need
3978 to copy relocs into the output file. */
3979 s->reloc_count = 0;
3982 else if (strcmp (name, ".plt") != 0)
3984 /* It's not one of our dynamic sections, so don't allocate space. */
3985 continue;
3988 if (strip)
3989 _bfd_strip_section_from_output (info, s);
3990 else
3992 /* Allocate memory for the section contents. */
3993 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
3994 if (s->contents == NULL && s->_raw_size != 0)
3995 return false;
3999 if (elf_hash_table (info)->dynamic_sections_created)
4001 /* Add some entries to the .dynamic section. We fill in the
4002 values later, in elf64_alpha_finish_dynamic_sections, but we
4003 must add the entries now so that we get the correct size for
4004 the .dynamic section. The DT_DEBUG entry is filled in by the
4005 dynamic linker and used by the debugger. */
4006 #define add_dynamic_entry(TAG, VAL) \
4007 bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
4009 if (!info->shared)
4011 if (!add_dynamic_entry (DT_DEBUG, 0))
4012 return false;
4015 if (!add_dynamic_entry (DT_PLTGOT, 0))
4016 return false;
4018 if (relplt)
4020 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
4021 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
4022 || !add_dynamic_entry (DT_JMPREL, 0))
4023 return false;
4026 if (!add_dynamic_entry (DT_RELA, 0)
4027 || !add_dynamic_entry (DT_RELASZ, 0)
4028 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
4029 return false;
4031 if (info->flags & DF_TEXTREL)
4033 if (!add_dynamic_entry (DT_TEXTREL, 0))
4034 return false;
4037 #undef add_dynamic_entry
4039 return true;
4042 /* Relocate an Alpha ELF section. */
4044 static boolean
4045 elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
4046 contents, relocs, local_syms, local_sections)
4047 bfd *output_bfd;
4048 struct bfd_link_info *info;
4049 bfd *input_bfd;
4050 asection *input_section;
4051 bfd_byte *contents;
4052 Elf_Internal_Rela *relocs;
4053 Elf_Internal_Sym *local_syms;
4054 asection **local_sections;
4056 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4057 Elf_Internal_Rela *rel;
4058 Elf_Internal_Rela *relend;
4059 struct elf_link_tls_segment *tls_segment = NULL;
4060 asection *sgot = NULL, *srel = NULL, *srelgot = NULL;
4061 bfd *dynobj = NULL, *gotobj = NULL;
4062 bfd_vma gp = 0, tp_base = 0, dtp_base = 0;
4063 boolean ret_val = true;
4065 if (!info->relocateable)
4067 const char *name;
4069 dynobj = elf_hash_table (info)->dynobj;
4070 if (dynobj)
4071 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
4073 name = (bfd_elf_string_from_elf_section
4074 (input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
4075 elf_section_data(input_section)->rel_hdr.sh_name));
4076 BFD_ASSERT(name != NULL);
4077 srel = bfd_get_section_by_name (dynobj, name);
4079 /* Find the gp value for this input bfd. */
4080 gotobj = alpha_elf_tdata (input_bfd)->gotobj;
4081 if (gotobj)
4083 sgot = alpha_elf_tdata (gotobj)->got;
4084 gp = _bfd_get_gp_value (gotobj);
4085 if (gp == 0)
4087 gp = (sgot->output_section->vma
4088 + sgot->output_offset
4089 + 0x8000);
4090 _bfd_set_gp_value (gotobj, gp);
4094 tls_segment = elf_hash_table (info)->tls_segment;
4095 if (tls_segment)
4097 dtp_base = alpha_get_dtprel_base (tls_segment);
4098 tp_base = alpha_get_tprel_base (tls_segment);
4102 rel = relocs;
4103 relend = relocs + input_section->reloc_count;
4104 for (; rel < relend; rel++)
4106 struct alpha_elf_link_hash_entry *h;
4107 struct alpha_elf_got_entry *gotent;
4108 bfd_reloc_status_type r;
4109 reloc_howto_type *howto;
4110 unsigned long r_symndx;
4111 Elf_Internal_Sym *sym;
4112 asection *sec;
4113 bfd_vma value;
4114 bfd_vma addend;
4115 boolean dynamic_symbol_p;
4116 boolean undef_weak_ref;
4117 unsigned long r_type;
4119 r_type = ELF64_R_TYPE(rel->r_info);
4120 if (r_type >= R_ALPHA_max)
4122 (*_bfd_error_handler)
4123 (_("%s: unknown relocation type %d"),
4124 bfd_archive_filename (input_bfd), (int)r_type);
4125 bfd_set_error (bfd_error_bad_value);
4126 ret_val = false;
4127 continue;
4130 howto = elf64_alpha_howto_table + r_type;
4131 r_symndx = ELF64_R_SYM(rel->r_info);
4133 if (info->relocateable)
4135 /* This is a relocateable link. We don't have to change
4136 anything, unless the reloc is against a section symbol,
4137 in which case we have to adjust according to where the
4138 section symbol winds up in the output section. */
4140 /* The symbol associated with GPDISP and LITUSE is
4141 immaterial. Only the addend is significant. */
4142 if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE)
4143 continue;
4145 if (r_symndx < symtab_hdr->sh_info)
4147 sym = local_syms + r_symndx;
4148 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
4150 sec = local_sections[r_symndx];
4151 rel->r_addend += sec->output_offset + sym->st_value;
4155 continue;
4158 /* This is a final link. */
4160 h = NULL;
4161 sym = NULL;
4162 sec = NULL;
4163 undef_weak_ref = false;
4165 if (r_symndx < symtab_hdr->sh_info)
4167 sym = local_syms + r_symndx;
4168 sec = local_sections[r_symndx];
4169 value = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
4171 gotent = alpha_elf_tdata(input_bfd)->local_got_entries[r_symndx];
4173 /* Need to adjust local GOT entries' addends for SEC_MERGE
4174 unless it has been done already. */
4175 if ((sec->flags & SEC_MERGE)
4176 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
4177 && (elf_section_data (sec)->sec_info_type
4178 == ELF_INFO_TYPE_MERGE)
4179 && !gotent->reloc_xlated)
4181 struct alpha_elf_got_entry *ent;
4182 asection *msec;
4184 for (ent = gotent; ent; ent = ent->next)
4186 ent->reloc_xlated = 1;
4187 if (ent->use_count == 0)
4188 continue;
4189 msec = sec;
4190 ent->addend =
4191 _bfd_merged_section_offset (output_bfd, &msec,
4192 elf_section_data (sec)->
4193 sec_info,
4194 sym->st_value + ent->addend,
4195 (bfd_vma) 0);
4196 ent->addend -= sym->st_value;
4197 ent->addend += msec->output_section->vma
4198 + msec->output_offset
4199 - sec->output_section->vma
4200 - sec->output_offset;
4204 dynamic_symbol_p = false;
4206 else
4208 h = alpha_elf_sym_hashes (input_bfd)[r_symndx - symtab_hdr->sh_info];
4210 while (h->root.root.type == bfd_link_hash_indirect
4211 || h->root.root.type == bfd_link_hash_warning)
4212 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
4214 value = 0;
4215 if (h->root.root.type == bfd_link_hash_defined
4216 || h->root.root.type == bfd_link_hash_defweak)
4218 sec = h->root.root.u.def.section;
4220 /* Detect the cases that sym_sec->output_section is
4221 expected to be NULL -- all cases in which the symbol
4222 is defined in another shared module. This includes
4223 PLT relocs for which we've created a PLT entry and
4224 other relocs for which we're prepared to create
4225 dynamic relocations. */
4226 /* ??? Just accept it NULL and continue. */
4228 if (sec->output_section != NULL)
4229 value = (h->root.root.u.def.value
4230 + sec->output_section->vma
4231 + sec->output_offset);
4233 else if (h->root.root.type == bfd_link_hash_undefweak)
4234 undef_weak_ref = true;
4235 else if (info->shared
4236 && (!info->symbolic || info->allow_shlib_undefined)
4237 && !info->no_undefined
4238 && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
4240 else
4242 if (!((*info->callbacks->undefined_symbol)
4243 (info, h->root.root.root.string, input_bfd,
4244 input_section, rel->r_offset,
4245 (!info->shared || info->no_undefined
4246 || ELF_ST_VISIBILITY (h->root.other)))))
4247 return false;
4248 ret_val = false;
4249 continue;
4252 dynamic_symbol_p = alpha_elf_dynamic_symbol_p (&h->root, info);
4253 gotent = h->got_entries;
4256 addend = rel->r_addend;
4257 value += addend;
4259 /* Search for the proper got entry. */
4260 for (; gotent ; gotent = gotent->next)
4261 if (gotent->gotobj == gotobj
4262 && gotent->reloc_type == r_type
4263 && gotent->addend == addend)
4264 break;
4266 switch (r_type)
4268 case R_ALPHA_GPDISP:
4270 bfd_byte *p_ldah, *p_lda;
4272 BFD_ASSERT(gp != 0);
4274 value = (input_section->output_section->vma
4275 + input_section->output_offset
4276 + rel->r_offset);
4278 p_ldah = contents + rel->r_offset;
4279 p_lda = p_ldah + rel->r_addend;
4281 r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - value,
4282 p_ldah, p_lda);
4284 break;
4286 case R_ALPHA_LITERAL:
4287 BFD_ASSERT(sgot != NULL);
4288 BFD_ASSERT(gp != 0);
4289 BFD_ASSERT(gotent != NULL);
4290 BFD_ASSERT(gotent->use_count >= 1);
4292 if (!gotent->reloc_done)
4294 gotent->reloc_done = 1;
4296 bfd_put_64 (output_bfd, value,
4297 sgot->contents + gotent->got_offset);
4299 /* If the symbol has been forced local, output a
4300 RELATIVE reloc, otherwise it will be handled in
4301 finish_dynamic_symbol. */
4302 if (info->shared && !dynamic_symbol_p)
4304 Elf_Internal_Rela outrel;
4306 BFD_ASSERT(srelgot != NULL);
4308 outrel.r_offset = (sgot->output_section->vma
4309 + sgot->output_offset
4310 + gotent->got_offset);
4311 outrel.r_info = ELF64_R_INFO (0, R_ALPHA_RELATIVE);
4312 outrel.r_addend = value;
4314 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
4315 ((Elf64_External_Rela *)
4316 srelgot->contents)
4317 + srelgot->reloc_count++);
4318 BFD_ASSERT (sizeof (Elf64_External_Rela)
4319 * srelgot->reloc_count
4320 <= srelgot->_cooked_size);
4324 value = (sgot->output_section->vma
4325 + sgot->output_offset
4326 + gotent->got_offset);
4327 value -= gp;
4328 goto default_reloc;
4330 case R_ALPHA_GPREL16:
4331 case R_ALPHA_GPREL32:
4332 case R_ALPHA_GPRELLOW:
4333 if (dynamic_symbol_p)
4335 (*_bfd_error_handler)
4336 (_("%s: gp-relative relocation against dynamic symbol %s"),
4337 bfd_archive_filename (input_bfd), h->root.root.root.string);
4338 ret_val = false;
4340 BFD_ASSERT(gp != 0);
4341 value -= gp;
4342 goto default_reloc;
4344 case R_ALPHA_GPRELHIGH:
4345 if (dynamic_symbol_p)
4347 (*_bfd_error_handler)
4348 (_("%s: gp-relative relocation against dynamic symbol %s"),
4349 bfd_archive_filename (input_bfd), h->root.root.root.string);
4350 ret_val = false;
4352 BFD_ASSERT(gp != 0);
4353 value -= gp;
4354 value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
4355 goto default_reloc;
4357 case R_ALPHA_HINT:
4358 /* A call to a dynamic symbol is definitely out of range of
4359 the 16-bit displacement. Don't bother writing anything. */
4360 if (dynamic_symbol_p)
4362 r = bfd_reloc_ok;
4363 break;
4365 /* The regular PC-relative stuff measures from the start of
4366 the instruction rather than the end. */
4367 value -= 4;
4368 goto default_reloc;
4370 case R_ALPHA_BRADDR:
4371 if (dynamic_symbol_p)
4373 (*_bfd_error_handler)
4374 (_("%s: pc-relative relocation against dynamic symbol %s"),
4375 bfd_archive_filename (input_bfd), h->root.root.root.string);
4376 ret_val = false;
4378 /* The regular PC-relative stuff measures from the start of
4379 the instruction rather than the end. */
4380 value -= 4;
4381 goto default_reloc;
4383 case R_ALPHA_BRSGP:
4385 int other;
4386 const char *name;
4388 /* The regular PC-relative stuff measures from the start of
4389 the instruction rather than the end. */
4390 value -= 4;
4392 /* The source and destination gp must be the same. Note that
4393 the source will always have an assigned gp, since we forced
4394 one in check_relocs, but that the destination may not, as
4395 it might not have had any relocations at all. Also take
4396 care not to crash if H is an undefined symbol. */
4397 if (h != NULL && sec != NULL
4398 && alpha_elf_tdata (sec->owner)->gotobj
4399 && gotobj != alpha_elf_tdata (sec->owner)->gotobj)
4401 (*_bfd_error_handler)
4402 (_("%s: change in gp: BRSGP %s"),
4403 bfd_archive_filename (input_bfd), h->root.root.root.string);
4404 ret_val = false;
4407 /* The symbol should be marked either NOPV or STD_GPLOAD. */
4408 if (h != NULL)
4409 other = h->root.other;
4410 else
4411 other = sym->st_other;
4412 switch (other & STO_ALPHA_STD_GPLOAD)
4414 case STO_ALPHA_NOPV:
4415 break;
4416 case STO_ALPHA_STD_GPLOAD:
4417 addend += 8;
4418 break;
4419 default:
4420 if (h != NULL)
4421 name = h->root.root.root.string;
4422 else
4424 name = (bfd_elf_string_from_elf_section
4425 (input_bfd, symtab_hdr->sh_link, sym->st_name));
4426 if (name == NULL)
4427 name = _("<unknown>");
4428 else if (name[0] == 0)
4429 name = bfd_section_name (input_bfd, sec);
4431 (*_bfd_error_handler)
4432 (_("%s: !samegp reloc against symbol without .prologue: %s"),
4433 bfd_archive_filename (input_bfd), name);
4434 ret_val = false;
4435 break;
4438 goto default_reloc;
4441 case R_ALPHA_REFLONG:
4442 case R_ALPHA_REFQUAD:
4443 case R_ALPHA_DTPREL64:
4444 case R_ALPHA_TPREL64:
4446 Elf_Internal_Rela outrel;
4448 /* Careful here to remember RELATIVE relocations for global
4449 variables for symbolic shared objects. */
4451 if (dynamic_symbol_p)
4453 BFD_ASSERT(h->root.dynindx != -1);
4454 outrel.r_info = ELF64_R_INFO (h->root.dynindx, r_type);
4455 outrel.r_addend = addend;
4456 addend = 0, value = 0;
4458 else if (r_type == R_ALPHA_DTPREL64)
4460 BFD_ASSERT(tls_segment != NULL);
4461 value -= dtp_base;
4462 goto default_reloc;
4464 else if (r_type == R_ALPHA_TPREL64)
4466 BFD_ASSERT(tls_segment != NULL);
4467 value -= dtp_base;
4468 goto default_reloc;
4470 else if (info->shared
4471 && r_symndx != 0
4472 && (input_section->flags & SEC_ALLOC))
4474 if (r_type == R_ALPHA_REFLONG)
4476 (*_bfd_error_handler)
4477 (_("%s: unhandled dynamic relocation against %s"),
4478 bfd_archive_filename (input_bfd),
4479 h->root.root.root.string);
4480 ret_val = false;
4482 outrel.r_info = ELF64_R_INFO (0, R_ALPHA_RELATIVE);
4483 outrel.r_addend = value;
4485 else
4486 goto default_reloc;
4488 BFD_ASSERT(srel != NULL);
4490 outrel.r_offset =
4491 _bfd_elf_section_offset (output_bfd, info, input_section,
4492 rel->r_offset);
4493 if ((outrel.r_offset | 1) != (bfd_vma) -1)
4494 outrel.r_offset += (input_section->output_section->vma
4495 + input_section->output_offset);
4496 else
4497 memset (&outrel, 0, sizeof outrel);
4499 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
4500 ((Elf64_External_Rela *)
4501 srel->contents)
4502 + srel->reloc_count++);
4503 BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
4504 <= srel->_cooked_size);
4506 goto default_reloc;
4508 case R_ALPHA_SREL16:
4509 case R_ALPHA_SREL32:
4510 case R_ALPHA_SREL64:
4511 if (dynamic_symbol_p)
4513 (*_bfd_error_handler)
4514 (_("%s: pc-relative relocation against dynamic symbol %s"),
4515 bfd_archive_filename (input_bfd), h->root.root.root.string);
4516 ret_val = false;
4519 /* ??? .eh_frame references to discarded sections will be smashed
4520 to relocations against SHN_UNDEF. The .eh_frame format allows
4521 NULL to be encoded as 0 in any format, so this works here. */
4522 if (r_symndx == 0)
4523 howto = (elf64_alpha_howto_table
4524 + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG));
4525 goto default_reloc;
4527 case R_ALPHA_TLSLDM:
4528 /* Ignore the symbol for the relocation. The result is always
4529 the current module. */
4530 dynamic_symbol_p = 0;
4531 /* FALLTHRU */
4533 case R_ALPHA_TLSGD:
4534 if (!gotent->reloc_done)
4536 gotent->reloc_done = 1;
4538 /* Note that the module index for the main program is 1. */
4539 bfd_put_64 (output_bfd, !info->shared && !dynamic_symbol_p,
4540 sgot->contents + gotent->got_offset);
4542 /* If the symbol has been forced local, output a
4543 DTPMOD64 reloc, otherwise it will be handled in
4544 finish_dynamic_symbol. */
4545 if (info->shared && !dynamic_symbol_p)
4547 Elf_Internal_Rela outrel;
4549 BFD_ASSERT(srelgot != NULL);
4551 outrel.r_offset = (sgot->output_section->vma
4552 + sgot->output_offset
4553 + gotent->got_offset);
4554 /* ??? Proper dynindx here. */
4555 outrel.r_info = ELF64_R_INFO (0, R_ALPHA_DTPMOD64);
4556 outrel.r_addend = 0;
4558 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
4559 ((Elf64_External_Rela *)
4560 srelgot->contents)
4561 + srelgot->reloc_count++);
4562 BFD_ASSERT (sizeof (Elf64_External_Rela)
4563 * srelgot->reloc_count
4564 <= srelgot->_cooked_size);
4567 if (dynamic_symbol_p || r_type == R_ALPHA_TLSLDM)
4568 value = 0;
4569 else
4571 BFD_ASSERT(tls_segment != NULL);
4572 value -= dtp_base;
4574 bfd_put_64 (output_bfd, value,
4575 sgot->contents + gotent->got_offset + 8);
4578 value = (sgot->output_section->vma
4579 + sgot->output_offset
4580 + gotent->got_offset);
4581 value -= gp;
4582 goto default_reloc;
4584 case R_ALPHA_DTPRELHI:
4585 case R_ALPHA_DTPRELLO:
4586 case R_ALPHA_DTPREL16:
4587 if (dynamic_symbol_p)
4589 (*_bfd_error_handler)
4590 (_("%s: dtp-relative relocation against dynamic symbol %s"),
4591 bfd_archive_filename (input_bfd), h->root.root.root.string);
4592 ret_val = false;
4594 BFD_ASSERT(tls_segment != NULL);
4595 value -= dtp_base;
4596 if (r_type == R_ALPHA_DTPRELHI)
4597 value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
4598 goto default_reloc;
4600 case R_ALPHA_TPRELHI:
4601 case R_ALPHA_TPRELLO:
4602 case R_ALPHA_TPREL16:
4603 if (info->shared)
4605 (*_bfd_error_handler)
4606 (_("%s: TLS local exec code cannot be linked into shared objects"),
4607 bfd_archive_filename (input_bfd));
4608 ret_val = false;
4610 else if (dynamic_symbol_p)
4612 (*_bfd_error_handler)
4613 (_("%s: tp-relative relocation against dynamic symbol %s"),
4614 bfd_archive_filename (input_bfd), h->root.root.root.string);
4615 ret_val = false;
4617 BFD_ASSERT(tls_segment != NULL);
4618 value -= tp_base;
4619 if (r_type == R_ALPHA_TPRELHI)
4620 value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
4621 goto default_reloc;
4623 case R_ALPHA_GOTDTPREL:
4624 case R_ALPHA_GOTTPREL:
4625 BFD_ASSERT(sgot != NULL);
4626 BFD_ASSERT(gp != 0);
4627 BFD_ASSERT(gotent != NULL);
4628 BFD_ASSERT(gotent->use_count >= 1);
4630 if (!gotent->reloc_done)
4632 gotent->reloc_done = 1;
4634 if (dynamic_symbol_p)
4635 value = 0;
4636 else
4638 BFD_ASSERT(tls_segment != NULL);
4639 value -= (r_type == R_ALPHA_GOTDTPREL ? dtp_base : tp_base);
4641 bfd_put_64 (output_bfd, value,
4642 sgot->contents + gotent->got_offset);
4645 value = (sgot->output_section->vma
4646 + sgot->output_offset
4647 + gotent->got_offset);
4648 value -= gp;
4649 goto default_reloc;
4651 default:
4652 default_reloc:
4653 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
4654 contents, rel->r_offset, value, 0);
4655 break;
4658 switch (r)
4660 case bfd_reloc_ok:
4661 break;
4663 case bfd_reloc_overflow:
4665 const char *name;
4667 /* Don't warn if the overflow is due to pc relative reloc
4668 against discarded section. Section optimization code should
4669 handle it. */
4671 if (r_symndx < symtab_hdr->sh_info
4672 && sec != NULL && howto->pc_relative
4673 && elf_discarded_section (sec))
4674 break;
4676 if (h != NULL)
4677 name = h->root.root.root.string;
4678 else
4680 name = (bfd_elf_string_from_elf_section
4681 (input_bfd, symtab_hdr->sh_link, sym->st_name));
4682 if (name == NULL)
4683 return false;
4684 if (*name == '\0')
4685 name = bfd_section_name (input_bfd, sec);
4687 if (! ((*info->callbacks->reloc_overflow)
4688 (info, name, howto->name, (bfd_vma) 0,
4689 input_bfd, input_section, rel->r_offset)))
4690 ret_val = false;
4692 break;
4694 default:
4695 case bfd_reloc_outofrange:
4696 abort ();
4700 return ret_val;
4703 /* Finish up dynamic symbol handling. We set the contents of various
4704 dynamic sections here. */
4706 static boolean
4707 elf64_alpha_finish_dynamic_symbol (output_bfd, info, h, sym)
4708 bfd *output_bfd;
4709 struct bfd_link_info *info;
4710 struct elf_link_hash_entry *h;
4711 Elf_Internal_Sym *sym;
4713 bfd *dynobj = elf_hash_table(info)->dynobj;
4715 if (h->plt.offset != MINUS_ONE)
4717 /* Fill in the .plt entry for this symbol. */
4718 asection *splt, *sgot, *srel;
4719 Elf_Internal_Rela outrel;
4720 bfd_vma got_addr, plt_addr;
4721 bfd_vma plt_index;
4722 struct alpha_elf_got_entry *gotent;
4724 BFD_ASSERT (h->dynindx != -1);
4726 /* The first .got entry will be updated by the .plt with the
4727 address of the target function. */
4728 gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
4729 BFD_ASSERT (gotent && gotent->addend == 0);
4731 splt = bfd_get_section_by_name (dynobj, ".plt");
4732 BFD_ASSERT (splt != NULL);
4733 srel = bfd_get_section_by_name (dynobj, ".rela.plt");
4734 BFD_ASSERT (srel != NULL);
4735 sgot = alpha_elf_tdata (gotent->gotobj)->got;
4736 BFD_ASSERT (sgot != NULL);
4738 got_addr = (sgot->output_section->vma
4739 + sgot->output_offset
4740 + gotent->got_offset);
4741 plt_addr = (splt->output_section->vma
4742 + splt->output_offset
4743 + h->plt.offset);
4745 plt_index = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
4747 /* Fill in the entry in the procedure linkage table. */
4749 bfd_vma insn1, insn2, insn3;
4751 insn1 = PLT_ENTRY_WORD1 | ((-(h->plt.offset + 4) >> 2) & 0x1fffff);
4752 insn2 = PLT_ENTRY_WORD2;
4753 insn3 = PLT_ENTRY_WORD3;
4755 bfd_put_32 (output_bfd, insn1, splt->contents + h->plt.offset);
4756 bfd_put_32 (output_bfd, insn2, splt->contents + h->plt.offset + 4);
4757 bfd_put_32 (output_bfd, insn3, splt->contents + h->plt.offset + 8);
4760 /* Fill in the entry in the .rela.plt section. */
4761 outrel.r_offset = got_addr;
4762 outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT);
4763 outrel.r_addend = 0;
4765 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
4766 ((Elf64_External_Rela *)srel->contents
4767 + plt_index));
4769 if (!(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
4771 /* Mark the symbol as undefined, rather than as defined in the
4772 .plt section. Leave the value alone. */
4773 sym->st_shndx = SHN_UNDEF;
4776 /* Fill in the entries in the .got. */
4777 bfd_put_64 (output_bfd, plt_addr, sgot->contents + gotent->got_offset);
4779 /* Subsequent .got entries will continue to bounce through the .plt. */
4780 if (gotent->next)
4782 srel = bfd_get_section_by_name (dynobj, ".rela.got");
4783 BFD_ASSERT (! info->shared || srel != NULL);
4785 gotent = gotent->next;
4788 sgot = alpha_elf_tdata(gotent->gotobj)->got;
4789 BFD_ASSERT(sgot != NULL);
4790 BFD_ASSERT(gotent->addend == 0);
4792 bfd_put_64 (output_bfd, plt_addr,
4793 sgot->contents + gotent->got_offset);
4795 if (info->shared)
4797 outrel.r_offset = (sgot->output_section->vma
4798 + sgot->output_offset
4799 + gotent->got_offset);
4800 outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
4801 outrel.r_addend = plt_addr;
4803 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
4804 ((Elf64_External_Rela *)
4805 srel->contents)
4806 + srel->reloc_count++);
4807 BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
4808 <= srel->_cooked_size);
4811 gotent = gotent->next;
4813 while (gotent != NULL);
4816 else if (alpha_elf_dynamic_symbol_p (h, info))
4818 /* Fill in the dynamic relocations for this symbol's .got entries. */
4819 asection *srel;
4820 Elf_Internal_Rela outrel;
4821 struct alpha_elf_got_entry *gotent;
4823 srel = bfd_get_section_by_name (dynobj, ".rela.got");
4824 BFD_ASSERT (srel != NULL);
4826 for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
4827 gotent != NULL;
4828 gotent = gotent->next)
4830 asection *sgot = alpha_elf_tdata (gotent->gotobj)->got;
4831 int r_type;
4833 outrel.r_offset = (sgot->output_section->vma
4834 + sgot->output_offset
4835 + gotent->got_offset);
4837 r_type = gotent->reloc_type;
4838 switch (r_type)
4840 case R_ALPHA_LITERAL:
4841 r_type = R_ALPHA_GLOB_DAT;
4842 break;
4843 case R_ALPHA_TLSGD:
4844 r_type = R_ALPHA_DTPMOD64;
4845 break;
4846 case R_ALPHA_GOTDTPREL:
4847 r_type = R_ALPHA_DTPREL64;
4848 break;
4849 case R_ALPHA_GOTTPREL:
4850 r_type = R_ALPHA_TPREL64;
4851 break;
4852 case R_ALPHA_TLSLDM:
4853 default:
4854 abort ();
4857 outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
4858 outrel.r_addend = gotent->addend;
4860 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
4861 ((Elf64_External_Rela *)srel->contents
4862 + srel->reloc_count++));
4864 if (gotent->reloc_type == R_ALPHA_TLSGD)
4866 outrel.r_offset += 8;
4867 outrel.r_info = ELF64_R_INFO (h->dynindx, R_ALPHA_DTPREL64);
4869 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
4870 ((Elf64_External_Rela *)srel->contents
4871 + srel->reloc_count++));
4874 BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
4875 <= srel->_cooked_size);
4879 /* Mark some specially defined symbols as absolute. */
4880 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4881 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4882 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4883 sym->st_shndx = SHN_ABS;
4885 return true;
4888 /* Finish up the dynamic sections. */
4890 static boolean
4891 elf64_alpha_finish_dynamic_sections (output_bfd, info)
4892 bfd *output_bfd;
4893 struct bfd_link_info *info;
4895 bfd *dynobj;
4896 asection *sdyn;
4898 dynobj = elf_hash_table (info)->dynobj;
4899 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4901 if (elf_hash_table (info)->dynamic_sections_created)
4903 asection *splt;
4904 Elf64_External_Dyn *dyncon, *dynconend;
4906 splt = bfd_get_section_by_name (dynobj, ".plt");
4907 BFD_ASSERT (splt != NULL && sdyn != NULL);
4909 dyncon = (Elf64_External_Dyn *) sdyn->contents;
4910 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4911 for (; dyncon < dynconend; dyncon++)
4913 Elf_Internal_Dyn dyn;
4914 const char *name;
4915 asection *s;
4917 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
4919 switch (dyn.d_tag)
4921 case DT_PLTGOT:
4922 name = ".plt";
4923 goto get_vma;
4924 case DT_PLTRELSZ:
4925 name = ".rela.plt";
4926 goto get_size;
4927 case DT_JMPREL:
4928 name = ".rela.plt";
4929 goto get_vma;
4931 case DT_RELASZ:
4932 /* My interpretation of the TIS v1.1 ELF document indicates
4933 that RELASZ should not include JMPREL. This is not what
4934 the rest of the BFD does. It is, however, what the
4935 glibc ld.so wants. Do this fixup here until we found
4936 out who is right. */
4937 s = bfd_get_section_by_name (output_bfd, ".rela.plt");
4938 if (s)
4940 dyn.d_un.d_val -=
4941 (s->_cooked_size ? s->_cooked_size : s->_raw_size);
4943 break;
4945 get_vma:
4946 s = bfd_get_section_by_name (output_bfd, name);
4947 dyn.d_un.d_ptr = (s ? s->vma : 0);
4948 break;
4950 get_size:
4951 s = bfd_get_section_by_name (output_bfd, name);
4952 dyn.d_un.d_val =
4953 (s->_cooked_size ? s->_cooked_size : s->_raw_size);
4954 break;
4957 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
4960 /* Initialize the PLT0 entry */
4961 if (splt->_raw_size > 0)
4963 bfd_put_32 (output_bfd, PLT_HEADER_WORD1, splt->contents);
4964 bfd_put_32 (output_bfd, PLT_HEADER_WORD2, splt->contents + 4);
4965 bfd_put_32 (output_bfd, PLT_HEADER_WORD3, splt->contents + 8);
4966 bfd_put_32 (output_bfd, PLT_HEADER_WORD4, splt->contents + 12);
4968 /* The next two words will be filled in by ld.so */
4969 bfd_put_64 (output_bfd, (bfd_vma) 0, splt->contents + 16);
4970 bfd_put_64 (output_bfd, (bfd_vma) 0, splt->contents + 24);
4972 elf_section_data (splt->output_section)->this_hdr.sh_entsize =
4973 PLT_HEADER_SIZE;
4977 return true;
4980 /* We need to use a special link routine to handle the .mdebug section.
4981 We need to merge all instances of these sections together, not write
4982 them all out sequentially. */
4984 static boolean
4985 elf64_alpha_final_link (abfd, info)
4986 bfd *abfd;
4987 struct bfd_link_info *info;
4989 asection *o;
4990 struct bfd_link_order *p;
4991 asection *mdebug_sec;
4992 struct ecoff_debug_info debug;
4993 const struct ecoff_debug_swap *swap
4994 = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
4995 HDRR *symhdr = &debug.symbolic_header;
4996 PTR mdebug_handle = NULL;
4998 /* Go through the sections and collect the mdebug information. */
4999 mdebug_sec = NULL;
5000 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
5002 if (strcmp (o->name, ".mdebug") == 0)
5004 struct extsym_info einfo;
5006 /* We have found the .mdebug section in the output file.
5007 Look through all the link_orders comprising it and merge
5008 the information together. */
5009 symhdr->magic = swap->sym_magic;
5010 /* FIXME: What should the version stamp be? */
5011 symhdr->vstamp = 0;
5012 symhdr->ilineMax = 0;
5013 symhdr->cbLine = 0;
5014 symhdr->idnMax = 0;
5015 symhdr->ipdMax = 0;
5016 symhdr->isymMax = 0;
5017 symhdr->ioptMax = 0;
5018 symhdr->iauxMax = 0;
5019 symhdr->issMax = 0;
5020 symhdr->issExtMax = 0;
5021 symhdr->ifdMax = 0;
5022 symhdr->crfd = 0;
5023 symhdr->iextMax = 0;
5025 /* We accumulate the debugging information itself in the
5026 debug_info structure. */
5027 debug.line = NULL;
5028 debug.external_dnr = NULL;
5029 debug.external_pdr = NULL;
5030 debug.external_sym = NULL;
5031 debug.external_opt = NULL;
5032 debug.external_aux = NULL;
5033 debug.ss = NULL;
5034 debug.ssext = debug.ssext_end = NULL;
5035 debug.external_fdr = NULL;
5036 debug.external_rfd = NULL;
5037 debug.external_ext = debug.external_ext_end = NULL;
5039 mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
5040 if (mdebug_handle == (PTR) NULL)
5041 return false;
5043 if (1)
5045 asection *s;
5046 EXTR esym;
5047 bfd_vma last = 0;
5048 unsigned int i;
5049 static const char * const name[] =
5051 ".text", ".init", ".fini", ".data",
5052 ".rodata", ".sdata", ".sbss", ".bss"
5054 static const int sc[] = { scText, scInit, scFini, scData,
5055 scRData, scSData, scSBss, scBss };
5057 esym.jmptbl = 0;
5058 esym.cobol_main = 0;
5059 esym.weakext = 0;
5060 esym.reserved = 0;
5061 esym.ifd = ifdNil;
5062 esym.asym.iss = issNil;
5063 esym.asym.st = stLocal;
5064 esym.asym.reserved = 0;
5065 esym.asym.index = indexNil;
5066 for (i = 0; i < 8; i++)
5068 esym.asym.sc = sc[i];
5069 s = bfd_get_section_by_name (abfd, name[i]);
5070 if (s != NULL)
5072 esym.asym.value = s->vma;
5073 last = s->vma + s->_raw_size;
5075 else
5076 esym.asym.value = last;
5078 if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
5079 name[i], &esym))
5080 return false;
5084 for (p = o->link_order_head;
5085 p != (struct bfd_link_order *) NULL;
5086 p = p->next)
5088 asection *input_section;
5089 bfd *input_bfd;
5090 const struct ecoff_debug_swap *input_swap;
5091 struct ecoff_debug_info input_debug;
5092 char *eraw_src;
5093 char *eraw_end;
5095 if (p->type != bfd_indirect_link_order)
5097 if (p->type == bfd_data_link_order)
5098 continue;
5099 abort ();
5102 input_section = p->u.indirect.section;
5103 input_bfd = input_section->owner;
5105 if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour
5106 || (get_elf_backend_data (input_bfd)
5107 ->elf_backend_ecoff_debug_swap) == NULL)
5109 /* I don't know what a non ALPHA ELF bfd would be
5110 doing with a .mdebug section, but I don't really
5111 want to deal with it. */
5112 continue;
5115 input_swap = (get_elf_backend_data (input_bfd)
5116 ->elf_backend_ecoff_debug_swap);
5118 BFD_ASSERT (p->size == input_section->_raw_size);
5120 /* The ECOFF linking code expects that we have already
5121 read in the debugging information and set up an
5122 ecoff_debug_info structure, so we do that now. */
5123 if (!elf64_alpha_read_ecoff_info (input_bfd, input_section,
5124 &input_debug))
5125 return false;
5127 if (! (bfd_ecoff_debug_accumulate
5128 (mdebug_handle, abfd, &debug, swap, input_bfd,
5129 &input_debug, input_swap, info)))
5130 return false;
5132 /* Loop through the external symbols. For each one with
5133 interesting information, try to find the symbol in
5134 the linker global hash table and save the information
5135 for the output external symbols. */
5136 eraw_src = input_debug.external_ext;
5137 eraw_end = (eraw_src
5138 + (input_debug.symbolic_header.iextMax
5139 * input_swap->external_ext_size));
5140 for (;
5141 eraw_src < eraw_end;
5142 eraw_src += input_swap->external_ext_size)
5144 EXTR ext;
5145 const char *name;
5146 struct alpha_elf_link_hash_entry *h;
5148 (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
5149 if (ext.asym.sc == scNil
5150 || ext.asym.sc == scUndefined
5151 || ext.asym.sc == scSUndefined)
5152 continue;
5154 name = input_debug.ssext + ext.asym.iss;
5155 h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info),
5156 name, false, false, true);
5157 if (h == NULL || h->esym.ifd != -2)
5158 continue;
5160 if (ext.ifd != -1)
5162 BFD_ASSERT (ext.ifd
5163 < input_debug.symbolic_header.ifdMax);
5164 ext.ifd = input_debug.ifdmap[ext.ifd];
5167 h->esym = ext;
5170 /* Free up the information we just read. */
5171 free (input_debug.line);
5172 free (input_debug.external_dnr);
5173 free (input_debug.external_pdr);
5174 free (input_debug.external_sym);
5175 free (input_debug.external_opt);
5176 free (input_debug.external_aux);
5177 free (input_debug.ss);
5178 free (input_debug.ssext);
5179 free (input_debug.external_fdr);
5180 free (input_debug.external_rfd);
5181 free (input_debug.external_ext);
5183 /* Hack: reset the SEC_HAS_CONTENTS flag so that
5184 elf_link_input_bfd ignores this section. */
5185 input_section->flags &=~ SEC_HAS_CONTENTS;
5188 /* Build the external symbol information. */
5189 einfo.abfd = abfd;
5190 einfo.info = info;
5191 einfo.debug = &debug;
5192 einfo.swap = swap;
5193 einfo.failed = false;
5194 elf_link_hash_traverse (elf_hash_table (info),
5195 elf64_alpha_output_extsym,
5196 (PTR) &einfo);
5197 if (einfo.failed)
5198 return false;
5200 /* Set the size of the .mdebug section. */
5201 o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap);
5203 /* Skip this section later on (I don't think this currently
5204 matters, but someday it might). */
5205 o->link_order_head = (struct bfd_link_order *) NULL;
5207 mdebug_sec = o;
5211 /* Invoke the regular ELF backend linker to do all the work. */
5212 if (! bfd_elf64_bfd_final_link (abfd, info))
5213 return false;
5215 /* Now write out the computed sections. */
5217 /* The .got subsections... */
5219 bfd *i, *dynobj = elf_hash_table(info)->dynobj;
5220 for (i = alpha_elf_hash_table(info)->got_list;
5221 i != NULL;
5222 i = alpha_elf_tdata(i)->got_link_next)
5224 asection *sgot;
5226 /* elf_bfd_final_link already did everything in dynobj. */
5227 if (i == dynobj)
5228 continue;
5230 sgot = alpha_elf_tdata(i)->got;
5231 if (! bfd_set_section_contents (abfd, sgot->output_section,
5232 sgot->contents,
5233 (file_ptr) sgot->output_offset,
5234 sgot->_raw_size))
5235 return false;
5239 if (mdebug_sec != (asection *) NULL)
5241 BFD_ASSERT (abfd->output_has_begun);
5242 if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
5243 swap, info,
5244 mdebug_sec->filepos))
5245 return false;
5247 bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
5250 return true;
5253 static enum elf_reloc_type_class
5254 elf64_alpha_reloc_type_class (rela)
5255 const Elf_Internal_Rela *rela;
5257 switch ((int) ELF64_R_TYPE (rela->r_info))
5259 case R_ALPHA_RELATIVE:
5260 return reloc_class_relative;
5261 case R_ALPHA_JMP_SLOT:
5262 return reloc_class_plt;
5263 case R_ALPHA_COPY:
5264 return reloc_class_copy;
5265 default:
5266 return reloc_class_normal;
5270 /* ECOFF swapping routines. These are used when dealing with the
5271 .mdebug section, which is in the ECOFF debugging format. Copied
5272 from elf32-mips.c. */
5273 static const struct ecoff_debug_swap
5274 elf64_alpha_ecoff_debug_swap =
5276 /* Symbol table magic number. */
5277 magicSym2,
5278 /* Alignment of debugging information. E.g., 4. */
5280 /* Sizes of external symbolic information. */
5281 sizeof (struct hdr_ext),
5282 sizeof (struct dnr_ext),
5283 sizeof (struct pdr_ext),
5284 sizeof (struct sym_ext),
5285 sizeof (struct opt_ext),
5286 sizeof (struct fdr_ext),
5287 sizeof (struct rfd_ext),
5288 sizeof (struct ext_ext),
5289 /* Functions to swap in external symbolic data. */
5290 ecoff_swap_hdr_in,
5291 ecoff_swap_dnr_in,
5292 ecoff_swap_pdr_in,
5293 ecoff_swap_sym_in,
5294 ecoff_swap_opt_in,
5295 ecoff_swap_fdr_in,
5296 ecoff_swap_rfd_in,
5297 ecoff_swap_ext_in,
5298 _bfd_ecoff_swap_tir_in,
5299 _bfd_ecoff_swap_rndx_in,
5300 /* Functions to swap out external symbolic data. */
5301 ecoff_swap_hdr_out,
5302 ecoff_swap_dnr_out,
5303 ecoff_swap_pdr_out,
5304 ecoff_swap_sym_out,
5305 ecoff_swap_opt_out,
5306 ecoff_swap_fdr_out,
5307 ecoff_swap_rfd_out,
5308 ecoff_swap_ext_out,
5309 _bfd_ecoff_swap_tir_out,
5310 _bfd_ecoff_swap_rndx_out,
5311 /* Function to read in symbolic data. */
5312 elf64_alpha_read_ecoff_info
5315 /* Use a non-standard hash bucket size of 8. */
5317 const struct elf_size_info alpha_elf_size_info =
5319 sizeof (Elf64_External_Ehdr),
5320 sizeof (Elf64_External_Phdr),
5321 sizeof (Elf64_External_Shdr),
5322 sizeof (Elf64_External_Rel),
5323 sizeof (Elf64_External_Rela),
5324 sizeof (Elf64_External_Sym),
5325 sizeof (Elf64_External_Dyn),
5326 sizeof (Elf_External_Note),
5329 64, 8,
5330 ELFCLASS64, EV_CURRENT,
5331 bfd_elf64_write_out_phdrs,
5332 bfd_elf64_write_shdrs_and_ehdr,
5333 bfd_elf64_write_relocs,
5334 bfd_elf64_swap_symbol_out,
5335 bfd_elf64_slurp_reloc_table,
5336 bfd_elf64_slurp_symbol_table,
5337 bfd_elf64_swap_dyn_in,
5338 bfd_elf64_swap_dyn_out,
5339 NULL,
5340 NULL,
5341 NULL,
5342 NULL
5345 #define TARGET_LITTLE_SYM bfd_elf64_alpha_vec
5346 #define TARGET_LITTLE_NAME "elf64-alpha"
5347 #define ELF_ARCH bfd_arch_alpha
5348 #define ELF_MACHINE_CODE EM_ALPHA
5349 #define ELF_MAXPAGESIZE 0x10000
5351 #define bfd_elf64_bfd_link_hash_table_create \
5352 elf64_alpha_bfd_link_hash_table_create
5354 #define bfd_elf64_bfd_reloc_type_lookup \
5355 elf64_alpha_bfd_reloc_type_lookup
5356 #define elf_info_to_howto \
5357 elf64_alpha_info_to_howto
5359 #define bfd_elf64_mkobject \
5360 elf64_alpha_mkobject
5361 #define elf_backend_object_p \
5362 elf64_alpha_object_p
5364 #define elf_backend_section_from_shdr \
5365 elf64_alpha_section_from_shdr
5366 #define elf_backend_section_flags \
5367 elf64_alpha_section_flags
5368 #define elf_backend_fake_sections \
5369 elf64_alpha_fake_sections
5371 #define bfd_elf64_bfd_is_local_label_name \
5372 elf64_alpha_is_local_label_name
5373 #define bfd_elf64_find_nearest_line \
5374 elf64_alpha_find_nearest_line
5375 #define bfd_elf64_bfd_relax_section \
5376 elf64_alpha_relax_section
5378 #define elf_backend_add_symbol_hook \
5379 elf64_alpha_add_symbol_hook
5380 #define elf_backend_check_relocs \
5381 elf64_alpha_check_relocs
5382 #define elf_backend_create_dynamic_sections \
5383 elf64_alpha_create_dynamic_sections
5384 #define elf_backend_adjust_dynamic_symbol \
5385 elf64_alpha_adjust_dynamic_symbol
5386 #define elf_backend_always_size_sections \
5387 elf64_alpha_always_size_sections
5388 #define elf_backend_size_dynamic_sections \
5389 elf64_alpha_size_dynamic_sections
5390 #define elf_backend_relocate_section \
5391 elf64_alpha_relocate_section
5392 #define elf_backend_finish_dynamic_symbol \
5393 elf64_alpha_finish_dynamic_symbol
5394 #define elf_backend_finish_dynamic_sections \
5395 elf64_alpha_finish_dynamic_sections
5396 #define bfd_elf64_bfd_final_link \
5397 elf64_alpha_final_link
5398 #define elf_backend_reloc_type_class \
5399 elf64_alpha_reloc_type_class
5401 #define elf_backend_ecoff_debug_swap \
5402 &elf64_alpha_ecoff_debug_swap
5404 #define elf_backend_size_info \
5405 alpha_elf_size_info
5407 /* A few constants that determine how the .plt section is set up. */
5408 #define elf_backend_want_got_plt 0
5409 #define elf_backend_plt_readonly 0
5410 #define elf_backend_want_plt_sym 1
5411 #define elf_backend_got_header_size 0
5412 #define elf_backend_plt_header_size PLT_HEADER_SIZE
5414 #include "elf64-target.h"