bfd/
[binutils.git] / bfd / elf64-alpha.c
blobc0702bb870644a5ef49799d63726752d5911a4c2
1 /* Alpha specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 /* We need a published ABI spec for this. Until one comes out, don't
25 assume this'll remain unchanged forever. */
27 #include "sysdep.h"
28 #include "bfd.h"
29 #include "libbfd.h"
30 #include "elf-bfd.h"
32 #include "elf/alpha.h"
34 #define ALPHAECOFF
36 #define NO_COFF_RELOCS
37 #define NO_COFF_SYMBOLS
38 #define NO_COFF_LINENOS
40 /* Get the ECOFF swapping routines. Needed for the debug information. */
41 #include "coff/internal.h"
42 #include "coff/sym.h"
43 #include "coff/symconst.h"
44 #include "coff/ecoff.h"
45 #include "coff/alpha.h"
46 #include "aout/ar.h"
47 #include "libcoff.h"
48 #include "libecoff.h"
49 #define ECOFF_64
50 #include "ecoffswap.h"
53 /* Instruction data for plt generation and relaxation. */
55 #define OP_LDA 0x08
56 #define OP_LDAH 0x09
57 #define OP_LDQ 0x29
58 #define OP_BR 0x30
59 #define OP_BSR 0x34
61 #define INSN_LDA (OP_LDA << 26)
62 #define INSN_LDAH (OP_LDAH << 26)
63 #define INSN_LDQ (OP_LDQ << 26)
64 #define INSN_BR (OP_BR << 26)
66 #define INSN_ADDQ 0x40000400
67 #define INSN_RDUNIQ 0x0000009e
68 #define INSN_SUBQ 0x40000520
69 #define INSN_S4SUBQ 0x40000560
70 #define INSN_UNOP 0x2ffe0000
72 #define INSN_JSR 0x68004000
73 #define INSN_JMP 0x68000000
74 #define INSN_JSR_MASK 0xfc00c000
76 #define INSN_A(I,A) (I | (A << 21))
77 #define INSN_AB(I,A,B) (I | (A << 21) | (B << 16))
78 #define INSN_ABC(I,A,B,C) (I | (A << 21) | (B << 16) | C)
79 #define INSN_ABO(I,A,B,O) (I | (A << 21) | (B << 16) | ((O) & 0xffff))
80 #define INSN_AD(I,A,D) (I | (A << 21) | (((D) >> 2) & 0x1fffff))
82 /* PLT/GOT Stuff */
84 /* Set by ld emulation. Putting this into the link_info or hash structure
85 is simply working too hard. */
86 #ifdef USE_SECUREPLT
87 bfd_boolean elf64_alpha_use_secureplt = TRUE;
88 #else
89 bfd_boolean elf64_alpha_use_secureplt = FALSE;
90 #endif
92 #define OLD_PLT_HEADER_SIZE 32
93 #define OLD_PLT_ENTRY_SIZE 12
94 #define NEW_PLT_HEADER_SIZE 36
95 #define NEW_PLT_ENTRY_SIZE 4
97 #define PLT_HEADER_SIZE \
98 (elf64_alpha_use_secureplt ? NEW_PLT_HEADER_SIZE : OLD_PLT_HEADER_SIZE)
99 #define PLT_ENTRY_SIZE \
100 (elf64_alpha_use_secureplt ? NEW_PLT_ENTRY_SIZE : OLD_PLT_ENTRY_SIZE)
102 #define MAX_GOT_SIZE (64*1024)
104 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so"
106 struct alpha_elf_link_hash_entry
108 struct elf_link_hash_entry root;
110 /* External symbol information. */
111 EXTR esym;
113 /* Cumulative flags for all the .got entries. */
114 int flags;
116 /* Contexts in which a literal was referenced. */
117 #define ALPHA_ELF_LINK_HASH_LU_ADDR 0x01
118 #define ALPHA_ELF_LINK_HASH_LU_MEM 0x02
119 #define ALPHA_ELF_LINK_HASH_LU_BYTE 0x04
120 #define ALPHA_ELF_LINK_HASH_LU_JSR 0x08
121 #define ALPHA_ELF_LINK_HASH_LU_TLSGD 0x10
122 #define ALPHA_ELF_LINK_HASH_LU_TLSLDM 0x20
123 #define ALPHA_ELF_LINK_HASH_LU_JSRDIRECT 0x40
124 #define ALPHA_ELF_LINK_HASH_LU_PLT 0x38
125 #define ALPHA_ELF_LINK_HASH_TLS_IE 0x80
127 /* Used to implement multiple .got subsections. */
128 struct alpha_elf_got_entry
130 struct alpha_elf_got_entry *next;
132 /* Which .got subsection? */
133 bfd *gotobj;
135 /* The addend in effect for this entry. */
136 bfd_vma addend;
138 /* The .got offset for this entry. */
139 int got_offset;
141 /* The .plt offset for this entry. */
142 int plt_offset;
144 /* How many references to this entry? */
145 int use_count;
147 /* The relocation type of this entry. */
148 unsigned char reloc_type;
150 /* How a LITERAL is used. */
151 unsigned char flags;
153 /* Have we initialized the dynamic relocation for this entry? */
154 unsigned char reloc_done;
156 /* Have we adjusted this entry for SEC_MERGE? */
157 unsigned char reloc_xlated;
158 } *got_entries;
160 /* Used to count non-got, non-plt relocations for delayed sizing
161 of relocation sections. */
162 struct alpha_elf_reloc_entry
164 struct alpha_elf_reloc_entry *next;
166 /* Which .reloc section? */
167 asection *srel;
169 /* What kind of relocation? */
170 unsigned int rtype;
172 /* Is this against read-only section? */
173 unsigned int reltext : 1;
175 /* How many did we find? */
176 unsigned long count;
177 } *reloc_entries;
180 /* Alpha ELF linker hash table. */
182 struct alpha_elf_link_hash_table
184 struct elf_link_hash_table root;
186 /* The head of a list of .got subsections linked through
187 alpha_elf_tdata(abfd)->got_link_next. */
188 bfd *got_list;
190 /* The most recent relax pass that we've seen. The GOTs
191 should be regenerated if this doesn't match. */
192 int relax_trip;
195 /* Look up an entry in a Alpha ELF linker hash table. */
197 #define alpha_elf_link_hash_lookup(table, string, create, copy, follow) \
198 ((struct alpha_elf_link_hash_entry *) \
199 elf_link_hash_lookup (&(table)->root, (string), (create), \
200 (copy), (follow)))
202 /* Traverse a Alpha ELF linker hash table. */
204 #define alpha_elf_link_hash_traverse(table, func, info) \
205 (elf_link_hash_traverse \
206 (&(table)->root, \
207 (bfd_boolean (*) (struct elf_link_hash_entry *, PTR)) (func), \
208 (info)))
210 /* Get the Alpha ELF linker hash table from a link_info structure. */
212 #define alpha_elf_hash_table(p) \
213 ((struct alpha_elf_link_hash_table *) ((p)->hash))
215 /* Get the object's symbols as our own entry type. */
217 #define alpha_elf_sym_hashes(abfd) \
218 ((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
220 /* Should we do dynamic things to this symbol? This differs from the
221 generic version in that we never need to consider function pointer
222 equality wrt PLT entries -- we don't create a PLT entry if a symbol's
223 address is ever taken. */
225 static inline bfd_boolean
226 alpha_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
227 struct bfd_link_info *info)
229 return _bfd_elf_dynamic_symbol_p (h, info, 0);
232 /* Create an entry in a Alpha ELF linker hash table. */
234 static struct bfd_hash_entry *
235 elf64_alpha_link_hash_newfunc (struct bfd_hash_entry *entry,
236 struct bfd_hash_table *table,
237 const char *string)
239 struct alpha_elf_link_hash_entry *ret =
240 (struct alpha_elf_link_hash_entry *) entry;
242 /* Allocate the structure if it has not already been allocated by a
243 subclass. */
244 if (ret == (struct alpha_elf_link_hash_entry *) NULL)
245 ret = ((struct alpha_elf_link_hash_entry *)
246 bfd_hash_allocate (table,
247 sizeof (struct alpha_elf_link_hash_entry)));
248 if (ret == (struct alpha_elf_link_hash_entry *) NULL)
249 return (struct bfd_hash_entry *) ret;
251 /* Call the allocation method of the superclass. */
252 ret = ((struct alpha_elf_link_hash_entry *)
253 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
254 table, string));
255 if (ret != (struct alpha_elf_link_hash_entry *) NULL)
257 /* Set local fields. */
258 memset (&ret->esym, 0, sizeof (EXTR));
259 /* We use -2 as a marker to indicate that the information has
260 not been set. -1 means there is no associated ifd. */
261 ret->esym.ifd = -2;
262 ret->flags = 0;
263 ret->got_entries = NULL;
264 ret->reloc_entries = NULL;
267 return (struct bfd_hash_entry *) ret;
270 /* Create a Alpha ELF linker hash table. */
272 static struct bfd_link_hash_table *
273 elf64_alpha_bfd_link_hash_table_create (bfd *abfd)
275 struct alpha_elf_link_hash_table *ret;
276 bfd_size_type amt = sizeof (struct alpha_elf_link_hash_table);
278 ret = (struct alpha_elf_link_hash_table *) bfd_zmalloc (amt);
279 if (ret == (struct alpha_elf_link_hash_table *) NULL)
280 return NULL;
282 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
283 elf64_alpha_link_hash_newfunc,
284 sizeof (struct alpha_elf_link_hash_entry)))
286 free (ret);
287 return NULL;
290 return &ret->root.root;
293 /* We have some private fields hanging off of the elf_tdata structure. */
295 struct alpha_elf_obj_tdata
297 struct elf_obj_tdata root;
299 /* For every input file, these are the got entries for that object's
300 local symbols. */
301 struct alpha_elf_got_entry ** local_got_entries;
303 /* For every input file, this is the object that owns the got that
304 this input file uses. */
305 bfd *gotobj;
307 /* For every got, this is a linked list through the objects using this got */
308 bfd *in_got_link_next;
310 /* For every got, this is a link to the next got subsegment. */
311 bfd *got_link_next;
313 /* For every got, this is the section. */
314 asection *got;
316 /* For every got, this is it's total number of words. */
317 int total_got_size;
319 /* For every got, this is the sum of the number of words required
320 to hold all of the member object's local got. */
321 int local_got_size;
324 #define alpha_elf_tdata(abfd) \
325 ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any)
327 static bfd_boolean
328 elf64_alpha_mkobject (bfd *abfd)
330 if (abfd->tdata.any == NULL)
332 bfd_size_type amt = sizeof (struct alpha_elf_obj_tdata);
333 abfd->tdata.any = bfd_zalloc (abfd, amt);
334 if (abfd->tdata.any == NULL)
335 return FALSE;
337 return bfd_elf_mkobject (abfd);
340 static bfd_boolean
341 elf64_alpha_object_p (bfd *abfd)
343 /* Set the right machine number for an Alpha ELF file. */
344 return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
347 /* A relocation function which doesn't do anything. */
349 static bfd_reloc_status_type
350 elf64_alpha_reloc_nil (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
351 asymbol *sym ATTRIBUTE_UNUSED,
352 PTR data ATTRIBUTE_UNUSED, asection *sec,
353 bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
355 if (output_bfd)
356 reloc->address += sec->output_offset;
357 return bfd_reloc_ok;
360 /* A relocation function used for an unsupported reloc. */
362 static bfd_reloc_status_type
363 elf64_alpha_reloc_bad (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
364 asymbol *sym ATTRIBUTE_UNUSED,
365 PTR data ATTRIBUTE_UNUSED, asection *sec,
366 bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
368 if (output_bfd)
369 reloc->address += sec->output_offset;
370 return bfd_reloc_notsupported;
373 /* Do the work of the GPDISP relocation. */
375 static bfd_reloc_status_type
376 elf64_alpha_do_reloc_gpdisp (bfd *abfd, bfd_vma gpdisp, bfd_byte *p_ldah,
377 bfd_byte *p_lda)
379 bfd_reloc_status_type ret = bfd_reloc_ok;
380 bfd_vma addend;
381 unsigned long i_ldah, i_lda;
383 i_ldah = bfd_get_32 (abfd, p_ldah);
384 i_lda = bfd_get_32 (abfd, p_lda);
386 /* Complain if the instructions are not correct. */
387 if (((i_ldah >> 26) & 0x3f) != 0x09
388 || ((i_lda >> 26) & 0x3f) != 0x08)
389 ret = bfd_reloc_dangerous;
391 /* Extract the user-supplied offset, mirroring the sign extensions
392 that the instructions perform. */
393 addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff);
394 addend = (addend ^ 0x80008000) - 0x80008000;
396 gpdisp += addend;
398 if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000
399 || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000)
400 ret = bfd_reloc_overflow;
402 /* compensate for the sign extension again. */
403 i_ldah = ((i_ldah & 0xffff0000)
404 | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff));
405 i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff);
407 bfd_put_32 (abfd, (bfd_vma) i_ldah, p_ldah);
408 bfd_put_32 (abfd, (bfd_vma) i_lda, p_lda);
410 return ret;
413 /* The special function for the GPDISP reloc. */
415 static bfd_reloc_status_type
416 elf64_alpha_reloc_gpdisp (bfd *abfd, arelent *reloc_entry,
417 asymbol *sym ATTRIBUTE_UNUSED, PTR data,
418 asection *input_section, bfd *output_bfd,
419 char **err_msg)
421 bfd_reloc_status_type ret;
422 bfd_vma gp, relocation;
423 bfd_vma high_address;
424 bfd_byte *p_ldah, *p_lda;
426 /* Don't do anything if we're not doing a final link. */
427 if (output_bfd)
429 reloc_entry->address += input_section->output_offset;
430 return bfd_reloc_ok;
433 high_address = bfd_get_section_limit (abfd, input_section);
434 if (reloc_entry->address > high_address
435 || reloc_entry->address + reloc_entry->addend > high_address)
436 return bfd_reloc_outofrange;
438 /* The gp used in the portion of the output object to which this
439 input object belongs is cached on the input bfd. */
440 gp = _bfd_get_gp_value (abfd);
442 relocation = (input_section->output_section->vma
443 + input_section->output_offset
444 + reloc_entry->address);
446 p_ldah = (bfd_byte *) data + reloc_entry->address;
447 p_lda = p_ldah + reloc_entry->addend;
449 ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda);
451 /* Complain if the instructions are not correct. */
452 if (ret == bfd_reloc_dangerous)
453 *err_msg = _("GPDISP relocation did not find ldah and lda instructions");
455 return ret;
458 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
459 from smaller values. Start with zero, widen, *then* decrement. */
460 #define MINUS_ONE (((bfd_vma)0) - 1)
462 #define SKIP_HOWTO(N) \
463 HOWTO(N, 0, 0, 0, 0, 0, 0, elf64_alpha_reloc_bad, 0, 0, 0, 0, 0)
465 static reloc_howto_type elf64_alpha_howto_table[] =
467 HOWTO (R_ALPHA_NONE, /* type */
468 0, /* rightshift */
469 0, /* size (0 = byte, 1 = short, 2 = long) */
470 8, /* bitsize */
471 TRUE, /* pc_relative */
472 0, /* bitpos */
473 complain_overflow_dont, /* complain_on_overflow */
474 elf64_alpha_reloc_nil, /* special_function */
475 "NONE", /* name */
476 FALSE, /* partial_inplace */
477 0, /* src_mask */
478 0, /* dst_mask */
479 TRUE), /* pcrel_offset */
481 /* A 32 bit reference to a symbol. */
482 HOWTO (R_ALPHA_REFLONG, /* type */
483 0, /* rightshift */
484 2, /* size (0 = byte, 1 = short, 2 = long) */
485 32, /* bitsize */
486 FALSE, /* pc_relative */
487 0, /* bitpos */
488 complain_overflow_bitfield, /* complain_on_overflow */
489 0, /* special_function */
490 "REFLONG", /* name */
491 FALSE, /* partial_inplace */
492 0xffffffff, /* src_mask */
493 0xffffffff, /* dst_mask */
494 FALSE), /* pcrel_offset */
496 /* A 64 bit reference to a symbol. */
497 HOWTO (R_ALPHA_REFQUAD, /* type */
498 0, /* rightshift */
499 4, /* size (0 = byte, 1 = short, 2 = long) */
500 64, /* bitsize */
501 FALSE, /* pc_relative */
502 0, /* bitpos */
503 complain_overflow_bitfield, /* complain_on_overflow */
504 0, /* special_function */
505 "REFQUAD", /* name */
506 FALSE, /* partial_inplace */
507 MINUS_ONE, /* src_mask */
508 MINUS_ONE, /* dst_mask */
509 FALSE), /* pcrel_offset */
511 /* A 32 bit GP relative offset. This is just like REFLONG except
512 that when the value is used the value of the gp register will be
513 added in. */
514 HOWTO (R_ALPHA_GPREL32, /* type */
515 0, /* rightshift */
516 2, /* size (0 = byte, 1 = short, 2 = long) */
517 32, /* bitsize */
518 FALSE, /* pc_relative */
519 0, /* bitpos */
520 complain_overflow_bitfield, /* complain_on_overflow */
521 0, /* special_function */
522 "GPREL32", /* name */
523 FALSE, /* partial_inplace */
524 0xffffffff, /* src_mask */
525 0xffffffff, /* dst_mask */
526 FALSE), /* pcrel_offset */
528 /* Used for an instruction that refers to memory off the GP register. */
529 HOWTO (R_ALPHA_LITERAL, /* type */
530 0, /* rightshift */
531 1, /* size (0 = byte, 1 = short, 2 = long) */
532 16, /* bitsize */
533 FALSE, /* pc_relative */
534 0, /* bitpos */
535 complain_overflow_signed, /* complain_on_overflow */
536 0, /* special_function */
537 "ELF_LITERAL", /* name */
538 FALSE, /* partial_inplace */
539 0xffff, /* src_mask */
540 0xffff, /* dst_mask */
541 FALSE), /* pcrel_offset */
543 /* This reloc only appears immediately following an ELF_LITERAL reloc.
544 It identifies a use of the literal. The symbol index is special:
545 1 means the literal address is in the base register of a memory
546 format instruction; 2 means the literal address is in the byte
547 offset register of a byte-manipulation instruction; 3 means the
548 literal address is in the target register of a jsr instruction.
549 This does not actually do any relocation. */
550 HOWTO (R_ALPHA_LITUSE, /* type */
551 0, /* rightshift */
552 1, /* size (0 = byte, 1 = short, 2 = long) */
553 32, /* bitsize */
554 FALSE, /* pc_relative */
555 0, /* bitpos */
556 complain_overflow_dont, /* complain_on_overflow */
557 elf64_alpha_reloc_nil, /* special_function */
558 "LITUSE", /* name */
559 FALSE, /* partial_inplace */
560 0, /* src_mask */
561 0, /* dst_mask */
562 FALSE), /* pcrel_offset */
564 /* Load the gp register. This is always used for a ldah instruction
565 which loads the upper 16 bits of the gp register. The symbol
566 index of the GPDISP instruction is an offset in bytes to the lda
567 instruction that loads the lower 16 bits. The value to use for
568 the relocation is the difference between the GP value and the
569 current location; the load will always be done against a register
570 holding the current address.
572 NOTE: Unlike ECOFF, partial in-place relocation is not done. If
573 any offset is present in the instructions, it is an offset from
574 the register to the ldah instruction. This lets us avoid any
575 stupid hackery like inventing a gp value to do partial relocation
576 against. Also unlike ECOFF, we do the whole relocation off of
577 the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair. An odd,
578 space consuming bit, that, since all the information was present
579 in the GPDISP_HI16 reloc. */
580 HOWTO (R_ALPHA_GPDISP, /* type */
581 16, /* rightshift */
582 2, /* size (0 = byte, 1 = short, 2 = long) */
583 16, /* bitsize */
584 FALSE, /* pc_relative */
585 0, /* bitpos */
586 complain_overflow_dont, /* complain_on_overflow */
587 elf64_alpha_reloc_gpdisp, /* special_function */
588 "GPDISP", /* name */
589 FALSE, /* partial_inplace */
590 0xffff, /* src_mask */
591 0xffff, /* dst_mask */
592 TRUE), /* pcrel_offset */
594 /* A 21 bit branch. */
595 HOWTO (R_ALPHA_BRADDR, /* type */
596 2, /* rightshift */
597 2, /* size (0 = byte, 1 = short, 2 = long) */
598 21, /* bitsize */
599 TRUE, /* pc_relative */
600 0, /* bitpos */
601 complain_overflow_signed, /* complain_on_overflow */
602 0, /* special_function */
603 "BRADDR", /* name */
604 FALSE, /* partial_inplace */
605 0x1fffff, /* src_mask */
606 0x1fffff, /* dst_mask */
607 TRUE), /* pcrel_offset */
609 /* A hint for a jump to a register. */
610 HOWTO (R_ALPHA_HINT, /* type */
611 2, /* rightshift */
612 1, /* size (0 = byte, 1 = short, 2 = long) */
613 14, /* bitsize */
614 TRUE, /* pc_relative */
615 0, /* bitpos */
616 complain_overflow_dont, /* complain_on_overflow */
617 0, /* special_function */
618 "HINT", /* name */
619 FALSE, /* partial_inplace */
620 0x3fff, /* src_mask */
621 0x3fff, /* dst_mask */
622 TRUE), /* pcrel_offset */
624 /* 16 bit PC relative offset. */
625 HOWTO (R_ALPHA_SREL16, /* type */
626 0, /* rightshift */
627 1, /* size (0 = byte, 1 = short, 2 = long) */
628 16, /* bitsize */
629 TRUE, /* pc_relative */
630 0, /* bitpos */
631 complain_overflow_signed, /* complain_on_overflow */
632 0, /* special_function */
633 "SREL16", /* name */
634 FALSE, /* partial_inplace */
635 0xffff, /* src_mask */
636 0xffff, /* dst_mask */
637 TRUE), /* pcrel_offset */
639 /* 32 bit PC relative offset. */
640 HOWTO (R_ALPHA_SREL32, /* type */
641 0, /* rightshift */
642 2, /* size (0 = byte, 1 = short, 2 = long) */
643 32, /* bitsize */
644 TRUE, /* pc_relative */
645 0, /* bitpos */
646 complain_overflow_signed, /* complain_on_overflow */
647 0, /* special_function */
648 "SREL32", /* name */
649 FALSE, /* partial_inplace */
650 0xffffffff, /* src_mask */
651 0xffffffff, /* dst_mask */
652 TRUE), /* pcrel_offset */
654 /* A 64 bit PC relative offset. */
655 HOWTO (R_ALPHA_SREL64, /* type */
656 0, /* rightshift */
657 4, /* size (0 = byte, 1 = short, 2 = long) */
658 64, /* bitsize */
659 TRUE, /* pc_relative */
660 0, /* bitpos */
661 complain_overflow_signed, /* complain_on_overflow */
662 0, /* special_function */
663 "SREL64", /* name */
664 FALSE, /* partial_inplace */
665 MINUS_ONE, /* src_mask */
666 MINUS_ONE, /* dst_mask */
667 TRUE), /* pcrel_offset */
669 /* Skip 12 - 16; deprecated ECOFF relocs. */
670 SKIP_HOWTO (12),
671 SKIP_HOWTO (13),
672 SKIP_HOWTO (14),
673 SKIP_HOWTO (15),
674 SKIP_HOWTO (16),
676 /* The high 16 bits of the displacement from GP to the target. */
677 HOWTO (R_ALPHA_GPRELHIGH,
678 0, /* rightshift */
679 1, /* size (0 = byte, 1 = short, 2 = long) */
680 16, /* bitsize */
681 FALSE, /* pc_relative */
682 0, /* bitpos */
683 complain_overflow_signed, /* complain_on_overflow */
684 0, /* special_function */
685 "GPRELHIGH", /* name */
686 FALSE, /* partial_inplace */
687 0xffff, /* src_mask */
688 0xffff, /* dst_mask */
689 FALSE), /* pcrel_offset */
691 /* The low 16 bits of the displacement from GP to the target. */
692 HOWTO (R_ALPHA_GPRELLOW,
693 0, /* rightshift */
694 1, /* size (0 = byte, 1 = short, 2 = long) */
695 16, /* bitsize */
696 FALSE, /* pc_relative */
697 0, /* bitpos */
698 complain_overflow_dont, /* complain_on_overflow */
699 0, /* special_function */
700 "GPRELLOW", /* name */
701 FALSE, /* partial_inplace */
702 0xffff, /* src_mask */
703 0xffff, /* dst_mask */
704 FALSE), /* pcrel_offset */
706 /* A 16-bit displacement from the GP to the target. */
707 HOWTO (R_ALPHA_GPREL16,
708 0, /* rightshift */
709 1, /* size (0 = byte, 1 = short, 2 = long) */
710 16, /* bitsize */
711 FALSE, /* pc_relative */
712 0, /* bitpos */
713 complain_overflow_signed, /* complain_on_overflow */
714 0, /* special_function */
715 "GPREL16", /* name */
716 FALSE, /* partial_inplace */
717 0xffff, /* src_mask */
718 0xffff, /* dst_mask */
719 FALSE), /* pcrel_offset */
721 /* Skip 20 - 23; deprecated ECOFF relocs. */
722 SKIP_HOWTO (20),
723 SKIP_HOWTO (21),
724 SKIP_HOWTO (22),
725 SKIP_HOWTO (23),
727 /* Misc ELF relocations. */
729 /* A dynamic relocation to copy the target into our .dynbss section. */
730 /* Not generated, as all Alpha objects use PIC, so it is not needed. It
731 is present because every other ELF has one, but should not be used
732 because .dynbss is an ugly thing. */
733 HOWTO (R_ALPHA_COPY,
737 FALSE,
739 complain_overflow_dont,
740 bfd_elf_generic_reloc,
741 "COPY",
742 FALSE,
745 TRUE),
747 /* A dynamic relocation for a .got entry. */
748 HOWTO (R_ALPHA_GLOB_DAT,
752 FALSE,
754 complain_overflow_dont,
755 bfd_elf_generic_reloc,
756 "GLOB_DAT",
757 FALSE,
760 TRUE),
762 /* A dynamic relocation for a .plt entry. */
763 HOWTO (R_ALPHA_JMP_SLOT,
767 FALSE,
769 complain_overflow_dont,
770 bfd_elf_generic_reloc,
771 "JMP_SLOT",
772 FALSE,
775 TRUE),
777 /* A dynamic relocation to add the base of the DSO to a 64-bit field. */
778 HOWTO (R_ALPHA_RELATIVE,
782 FALSE,
784 complain_overflow_dont,
785 bfd_elf_generic_reloc,
786 "RELATIVE",
787 FALSE,
790 TRUE),
792 /* A 21 bit branch that adjusts for gp loads. */
793 HOWTO (R_ALPHA_BRSGP, /* type */
794 2, /* rightshift */
795 2, /* size (0 = byte, 1 = short, 2 = long) */
796 21, /* bitsize */
797 TRUE, /* pc_relative */
798 0, /* bitpos */
799 complain_overflow_signed, /* complain_on_overflow */
800 0, /* special_function */
801 "BRSGP", /* name */
802 FALSE, /* partial_inplace */
803 0x1fffff, /* src_mask */
804 0x1fffff, /* dst_mask */
805 TRUE), /* pcrel_offset */
807 /* Creates a tls_index for the symbol in the got. */
808 HOWTO (R_ALPHA_TLSGD, /* type */
809 0, /* rightshift */
810 1, /* size (0 = byte, 1 = short, 2 = long) */
811 16, /* bitsize */
812 FALSE, /* pc_relative */
813 0, /* bitpos */
814 complain_overflow_signed, /* complain_on_overflow */
815 0, /* special_function */
816 "TLSGD", /* name */
817 FALSE, /* partial_inplace */
818 0xffff, /* src_mask */
819 0xffff, /* dst_mask */
820 FALSE), /* pcrel_offset */
822 /* Creates a tls_index for the (current) module in the got. */
823 HOWTO (R_ALPHA_TLSLDM, /* type */
824 0, /* rightshift */
825 1, /* size (0 = byte, 1 = short, 2 = long) */
826 16, /* bitsize */
827 FALSE, /* pc_relative */
828 0, /* bitpos */
829 complain_overflow_signed, /* complain_on_overflow */
830 0, /* special_function */
831 "TLSLDM", /* name */
832 FALSE, /* partial_inplace */
833 0xffff, /* src_mask */
834 0xffff, /* dst_mask */
835 FALSE), /* pcrel_offset */
837 /* A dynamic relocation for a DTP module entry. */
838 HOWTO (R_ALPHA_DTPMOD64, /* type */
839 0, /* rightshift */
840 4, /* size (0 = byte, 1 = short, 2 = long) */
841 64, /* bitsize */
842 FALSE, /* pc_relative */
843 0, /* bitpos */
844 complain_overflow_bitfield, /* complain_on_overflow */
845 0, /* special_function */
846 "DTPMOD64", /* name */
847 FALSE, /* partial_inplace */
848 MINUS_ONE, /* src_mask */
849 MINUS_ONE, /* dst_mask */
850 FALSE), /* pcrel_offset */
852 /* Creates a 64-bit offset in the got for the displacement
853 from DTP to the target. */
854 HOWTO (R_ALPHA_GOTDTPREL, /* type */
855 0, /* rightshift */
856 1, /* size (0 = byte, 1 = short, 2 = long) */
857 16, /* bitsize */
858 FALSE, /* pc_relative */
859 0, /* bitpos */
860 complain_overflow_signed, /* complain_on_overflow */
861 0, /* special_function */
862 "GOTDTPREL", /* name */
863 FALSE, /* partial_inplace */
864 0xffff, /* src_mask */
865 0xffff, /* dst_mask */
866 FALSE), /* pcrel_offset */
868 /* A dynamic relocation for a displacement from DTP to the target. */
869 HOWTO (R_ALPHA_DTPREL64, /* type */
870 0, /* rightshift */
871 4, /* size (0 = byte, 1 = short, 2 = long) */
872 64, /* bitsize */
873 FALSE, /* pc_relative */
874 0, /* bitpos */
875 complain_overflow_bitfield, /* complain_on_overflow */
876 0, /* special_function */
877 "DTPREL64", /* name */
878 FALSE, /* partial_inplace */
879 MINUS_ONE, /* src_mask */
880 MINUS_ONE, /* dst_mask */
881 FALSE), /* pcrel_offset */
883 /* The high 16 bits of the displacement from DTP to the target. */
884 HOWTO (R_ALPHA_DTPRELHI, /* type */
885 0, /* rightshift */
886 1, /* size (0 = byte, 1 = short, 2 = long) */
887 16, /* bitsize */
888 FALSE, /* pc_relative */
889 0, /* bitpos */
890 complain_overflow_signed, /* complain_on_overflow */
891 0, /* special_function */
892 "DTPRELHI", /* name */
893 FALSE, /* partial_inplace */
894 0xffff, /* src_mask */
895 0xffff, /* dst_mask */
896 FALSE), /* pcrel_offset */
898 /* The low 16 bits of the displacement from DTP to the target. */
899 HOWTO (R_ALPHA_DTPRELLO, /* type */
900 0, /* rightshift */
901 1, /* size (0 = byte, 1 = short, 2 = long) */
902 16, /* bitsize */
903 FALSE, /* pc_relative */
904 0, /* bitpos */
905 complain_overflow_dont, /* complain_on_overflow */
906 0, /* special_function */
907 "DTPRELLO", /* name */
908 FALSE, /* partial_inplace */
909 0xffff, /* src_mask */
910 0xffff, /* dst_mask */
911 FALSE), /* pcrel_offset */
913 /* A 16-bit displacement from DTP to the target. */
914 HOWTO (R_ALPHA_DTPREL16, /* type */
915 0, /* rightshift */
916 1, /* size (0 = byte, 1 = short, 2 = long) */
917 16, /* bitsize */
918 FALSE, /* pc_relative */
919 0, /* bitpos */
920 complain_overflow_signed, /* complain_on_overflow */
921 0, /* special_function */
922 "DTPREL16", /* name */
923 FALSE, /* partial_inplace */
924 0xffff, /* src_mask */
925 0xffff, /* dst_mask */
926 FALSE), /* pcrel_offset */
928 /* Creates a 64-bit offset in the got for the displacement
929 from TP to the target. */
930 HOWTO (R_ALPHA_GOTTPREL, /* type */
931 0, /* rightshift */
932 1, /* size (0 = byte, 1 = short, 2 = long) */
933 16, /* bitsize */
934 FALSE, /* pc_relative */
935 0, /* bitpos */
936 complain_overflow_signed, /* complain_on_overflow */
937 0, /* special_function */
938 "GOTTPREL", /* name */
939 FALSE, /* partial_inplace */
940 0xffff, /* src_mask */
941 0xffff, /* dst_mask */
942 FALSE), /* pcrel_offset */
944 /* A dynamic relocation for a displacement from TP to the target. */
945 HOWTO (R_ALPHA_TPREL64, /* type */
946 0, /* rightshift */
947 4, /* size (0 = byte, 1 = short, 2 = long) */
948 64, /* bitsize */
949 FALSE, /* pc_relative */
950 0, /* bitpos */
951 complain_overflow_bitfield, /* complain_on_overflow */
952 0, /* special_function */
953 "TPREL64", /* name */
954 FALSE, /* partial_inplace */
955 MINUS_ONE, /* src_mask */
956 MINUS_ONE, /* dst_mask */
957 FALSE), /* pcrel_offset */
959 /* The high 16 bits of the displacement from TP to the target. */
960 HOWTO (R_ALPHA_TPRELHI, /* type */
961 0, /* rightshift */
962 1, /* size (0 = byte, 1 = short, 2 = long) */
963 16, /* bitsize */
964 FALSE, /* pc_relative */
965 0, /* bitpos */
966 complain_overflow_signed, /* complain_on_overflow */
967 0, /* special_function */
968 "TPRELHI", /* name */
969 FALSE, /* partial_inplace */
970 0xffff, /* src_mask */
971 0xffff, /* dst_mask */
972 FALSE), /* pcrel_offset */
974 /* The low 16 bits of the displacement from TP to the target. */
975 HOWTO (R_ALPHA_TPRELLO, /* type */
976 0, /* rightshift */
977 1, /* size (0 = byte, 1 = short, 2 = long) */
978 16, /* bitsize */
979 FALSE, /* pc_relative */
980 0, /* bitpos */
981 complain_overflow_dont, /* complain_on_overflow */
982 0, /* special_function */
983 "TPRELLO", /* name */
984 FALSE, /* partial_inplace */
985 0xffff, /* src_mask */
986 0xffff, /* dst_mask */
987 FALSE), /* pcrel_offset */
989 /* A 16-bit displacement from TP to the target. */
990 HOWTO (R_ALPHA_TPREL16, /* type */
991 0, /* rightshift */
992 1, /* size (0 = byte, 1 = short, 2 = long) */
993 16, /* bitsize */
994 FALSE, /* pc_relative */
995 0, /* bitpos */
996 complain_overflow_signed, /* complain_on_overflow */
997 0, /* special_function */
998 "TPREL16", /* name */
999 FALSE, /* partial_inplace */
1000 0xffff, /* src_mask */
1001 0xffff, /* dst_mask */
1002 FALSE), /* pcrel_offset */
1005 /* A mapping from BFD reloc types to Alpha ELF reloc types. */
1007 struct elf_reloc_map
1009 bfd_reloc_code_real_type bfd_reloc_val;
1010 int elf_reloc_val;
1013 static const struct elf_reloc_map elf64_alpha_reloc_map[] =
1015 {BFD_RELOC_NONE, R_ALPHA_NONE},
1016 {BFD_RELOC_32, R_ALPHA_REFLONG},
1017 {BFD_RELOC_64, R_ALPHA_REFQUAD},
1018 {BFD_RELOC_CTOR, R_ALPHA_REFQUAD},
1019 {BFD_RELOC_GPREL32, R_ALPHA_GPREL32},
1020 {BFD_RELOC_ALPHA_ELF_LITERAL, R_ALPHA_LITERAL},
1021 {BFD_RELOC_ALPHA_LITUSE, R_ALPHA_LITUSE},
1022 {BFD_RELOC_ALPHA_GPDISP, R_ALPHA_GPDISP},
1023 {BFD_RELOC_23_PCREL_S2, R_ALPHA_BRADDR},
1024 {BFD_RELOC_ALPHA_HINT, R_ALPHA_HINT},
1025 {BFD_RELOC_16_PCREL, R_ALPHA_SREL16},
1026 {BFD_RELOC_32_PCREL, R_ALPHA_SREL32},
1027 {BFD_RELOC_64_PCREL, R_ALPHA_SREL64},
1028 {BFD_RELOC_ALPHA_GPREL_HI16, R_ALPHA_GPRELHIGH},
1029 {BFD_RELOC_ALPHA_GPREL_LO16, R_ALPHA_GPRELLOW},
1030 {BFD_RELOC_GPREL16, R_ALPHA_GPREL16},
1031 {BFD_RELOC_ALPHA_BRSGP, R_ALPHA_BRSGP},
1032 {BFD_RELOC_ALPHA_TLSGD, R_ALPHA_TLSGD},
1033 {BFD_RELOC_ALPHA_TLSLDM, R_ALPHA_TLSLDM},
1034 {BFD_RELOC_ALPHA_DTPMOD64, R_ALPHA_DTPMOD64},
1035 {BFD_RELOC_ALPHA_GOTDTPREL16, R_ALPHA_GOTDTPREL},
1036 {BFD_RELOC_ALPHA_DTPREL64, R_ALPHA_DTPREL64},
1037 {BFD_RELOC_ALPHA_DTPREL_HI16, R_ALPHA_DTPRELHI},
1038 {BFD_RELOC_ALPHA_DTPREL_LO16, R_ALPHA_DTPRELLO},
1039 {BFD_RELOC_ALPHA_DTPREL16, R_ALPHA_DTPREL16},
1040 {BFD_RELOC_ALPHA_GOTTPREL16, R_ALPHA_GOTTPREL},
1041 {BFD_RELOC_ALPHA_TPREL64, R_ALPHA_TPREL64},
1042 {BFD_RELOC_ALPHA_TPREL_HI16, R_ALPHA_TPRELHI},
1043 {BFD_RELOC_ALPHA_TPREL_LO16, R_ALPHA_TPRELLO},
1044 {BFD_RELOC_ALPHA_TPREL16, R_ALPHA_TPREL16},
1047 /* Given a BFD reloc type, return a HOWTO structure. */
1049 static reloc_howto_type *
1050 elf64_alpha_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1051 bfd_reloc_code_real_type code)
1053 const struct elf_reloc_map *i, *e;
1054 i = e = elf64_alpha_reloc_map;
1055 e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map);
1056 for (; i != e; ++i)
1058 if (i->bfd_reloc_val == code)
1059 return &elf64_alpha_howto_table[i->elf_reloc_val];
1061 return 0;
1064 static reloc_howto_type *
1065 elf64_alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1066 const char *r_name)
1068 unsigned int i;
1070 for (i = 0;
1071 i < (sizeof (elf64_alpha_howto_table)
1072 / sizeof (elf64_alpha_howto_table[0]));
1073 i++)
1074 if (elf64_alpha_howto_table[i].name != NULL
1075 && strcasecmp (elf64_alpha_howto_table[i].name, r_name) == 0)
1076 return &elf64_alpha_howto_table[i];
1078 return NULL;
1081 /* Given an Alpha ELF reloc type, fill in an arelent structure. */
1083 static void
1084 elf64_alpha_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
1085 Elf_Internal_Rela *dst)
1087 unsigned r_type = ELF64_R_TYPE(dst->r_info);
1088 BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max);
1089 cache_ptr->howto = &elf64_alpha_howto_table[r_type];
1092 /* These two relocations create a two-word entry in the got. */
1093 #define alpha_got_entry_size(r_type) \
1094 (r_type == R_ALPHA_TLSGD || r_type == R_ALPHA_TLSLDM ? 16 : 8)
1096 /* This is PT_TLS segment p_vaddr. */
1097 #define alpha_get_dtprel_base(info) \
1098 (elf_hash_table (info)->tls_sec->vma)
1100 /* Main program TLS (whose template starts at PT_TLS p_vaddr)
1101 is assigned offset round(16, PT_TLS p_align). */
1102 #define alpha_get_tprel_base(info) \
1103 (elf_hash_table (info)->tls_sec->vma \
1104 - align_power ((bfd_vma) 16, \
1105 elf_hash_table (info)->tls_sec->alignment_power))
1107 /* Handle an Alpha specific section when reading an object file. This
1108 is called when bfd_section_from_shdr finds a section with an unknown
1109 type.
1110 FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure
1111 how to. */
1113 static bfd_boolean
1114 elf64_alpha_section_from_shdr (bfd *abfd,
1115 Elf_Internal_Shdr *hdr,
1116 const char *name,
1117 int shindex)
1119 asection *newsect;
1121 /* There ought to be a place to keep ELF backend specific flags, but
1122 at the moment there isn't one. We just keep track of the
1123 sections by their name, instead. Fortunately, the ABI gives
1124 suggested names for all the MIPS specific sections, so we will
1125 probably get away with this. */
1126 switch (hdr->sh_type)
1128 case SHT_ALPHA_DEBUG:
1129 if (strcmp (name, ".mdebug") != 0)
1130 return FALSE;
1131 break;
1132 default:
1133 return FALSE;
1136 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
1137 return FALSE;
1138 newsect = hdr->bfd_section;
1140 if (hdr->sh_type == SHT_ALPHA_DEBUG)
1142 if (! bfd_set_section_flags (abfd, newsect,
1143 (bfd_get_section_flags (abfd, newsect)
1144 | SEC_DEBUGGING)))
1145 return FALSE;
1148 return TRUE;
1151 /* Convert Alpha specific section flags to bfd internal section flags. */
1153 static bfd_boolean
1154 elf64_alpha_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
1156 if (hdr->sh_flags & SHF_ALPHA_GPREL)
1157 *flags |= SEC_SMALL_DATA;
1159 return TRUE;
1162 /* Set the correct type for an Alpha ELF section. We do this by the
1163 section name, which is a hack, but ought to work. */
1165 static bfd_boolean
1166 elf64_alpha_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
1168 register const char *name;
1170 name = bfd_get_section_name (abfd, sec);
1172 if (strcmp (name, ".mdebug") == 0)
1174 hdr->sh_type = SHT_ALPHA_DEBUG;
1175 /* In a shared object on Irix 5.3, the .mdebug section has an
1176 entsize of 0. FIXME: Does this matter? */
1177 if ((abfd->flags & DYNAMIC) != 0 )
1178 hdr->sh_entsize = 0;
1179 else
1180 hdr->sh_entsize = 1;
1182 else if ((sec->flags & SEC_SMALL_DATA)
1183 || strcmp (name, ".sdata") == 0
1184 || strcmp (name, ".sbss") == 0
1185 || strcmp (name, ".lit4") == 0
1186 || strcmp (name, ".lit8") == 0)
1187 hdr->sh_flags |= SHF_ALPHA_GPREL;
1189 return TRUE;
1192 /* Hook called by the linker routine which adds symbols from an object
1193 file. We use it to put .comm items in .sbss, and not .bss. */
1195 static bfd_boolean
1196 elf64_alpha_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
1197 Elf_Internal_Sym *sym,
1198 const char **namep ATTRIBUTE_UNUSED,
1199 flagword *flagsp ATTRIBUTE_UNUSED,
1200 asection **secp, bfd_vma *valp)
1202 if (sym->st_shndx == SHN_COMMON
1203 && !info->relocatable
1204 && sym->st_size <= elf_gp_size (abfd))
1206 /* Common symbols less than or equal to -G nn bytes are
1207 automatically put into .sbss. */
1209 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1211 if (scomm == NULL)
1213 scomm = bfd_make_section_with_flags (abfd, ".scommon",
1214 (SEC_ALLOC
1215 | SEC_IS_COMMON
1216 | SEC_LINKER_CREATED));
1217 if (scomm == NULL)
1218 return FALSE;
1221 *secp = scomm;
1222 *valp = sym->st_size;
1225 return TRUE;
1228 /* Create the .got section. */
1230 static bfd_boolean
1231 elf64_alpha_create_got_section (bfd *abfd,
1232 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1234 flagword flags;
1235 asection *s;
1237 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1238 | SEC_LINKER_CREATED);
1239 s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
1240 if (s == NULL
1241 || !bfd_set_section_alignment (abfd, s, 3))
1242 return FALSE;
1244 alpha_elf_tdata (abfd)->got = s;
1246 /* Make sure the object's gotobj is set to itself so that we default
1247 to every object with its own .got. We'll merge .gots later once
1248 we've collected each object's info. */
1249 alpha_elf_tdata (abfd)->gotobj = abfd;
1251 return TRUE;
1254 /* Create all the dynamic sections. */
1256 static bfd_boolean
1257 elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
1259 asection *s;
1260 flagword flags;
1261 struct elf_link_hash_entry *h;
1263 /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */
1265 flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1266 | SEC_LINKER_CREATED
1267 | (elf64_alpha_use_secureplt ? SEC_READONLY : 0));
1268 s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags);
1269 if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4))
1270 return FALSE;
1272 /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
1273 .plt section. */
1274 h = _bfd_elf_define_linkage_sym (abfd, info, s,
1275 "_PROCEDURE_LINKAGE_TABLE_");
1276 elf_hash_table (info)->hplt = h;
1277 if (h == NULL)
1278 return FALSE;
1280 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1281 | SEC_LINKER_CREATED | SEC_READONLY);
1282 s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags);
1283 if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
1284 return FALSE;
1286 if (elf64_alpha_use_secureplt)
1288 flags = SEC_ALLOC | SEC_LINKER_CREATED;
1289 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
1290 if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
1291 return FALSE;
1294 /* We may or may not have created a .got section for this object, but
1295 we definitely havn't done the rest of the work. */
1297 if (alpha_elf_tdata(abfd)->gotobj == NULL)
1299 if (!elf64_alpha_create_got_section (abfd, info))
1300 return FALSE;
1303 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1304 | SEC_LINKER_CREATED | SEC_READONLY);
1305 s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags);
1306 if (s == NULL
1307 || !bfd_set_section_alignment (abfd, s, 3))
1308 return FALSE;
1310 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
1311 dynobj's .got section. We don't do this in the linker script
1312 because we don't want to define the symbol if we are not creating
1313 a global offset table. */
1314 h = _bfd_elf_define_linkage_sym (abfd, info, alpha_elf_tdata(abfd)->got,
1315 "_GLOBAL_OFFSET_TABLE_");
1316 elf_hash_table (info)->hgot = h;
1317 if (h == NULL)
1318 return FALSE;
1320 return TRUE;
1323 /* Read ECOFF debugging information from a .mdebug section into a
1324 ecoff_debug_info structure. */
1326 static bfd_boolean
1327 elf64_alpha_read_ecoff_info (bfd *abfd, asection *section,
1328 struct ecoff_debug_info *debug)
1330 HDRR *symhdr;
1331 const struct ecoff_debug_swap *swap;
1332 char *ext_hdr = NULL;
1334 swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
1335 memset (debug, 0, sizeof (*debug));
1337 ext_hdr = (char *) bfd_malloc (swap->external_hdr_size);
1338 if (ext_hdr == NULL && swap->external_hdr_size != 0)
1339 goto error_return;
1341 if (! bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
1342 swap->external_hdr_size))
1343 goto error_return;
1345 symhdr = &debug->symbolic_header;
1346 (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);
1348 /* The symbolic header contains absolute file offsets and sizes to
1349 read. */
1350 #define READ(ptr, offset, count, size, type) \
1351 if (symhdr->count == 0) \
1352 debug->ptr = NULL; \
1353 else \
1355 bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
1356 debug->ptr = (type) bfd_malloc (amt); \
1357 if (debug->ptr == NULL) \
1358 goto error_return; \
1359 if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
1360 || bfd_bread (debug->ptr, amt, abfd) != amt) \
1361 goto error_return; \
1364 READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
1365 READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
1366 READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
1367 READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
1368 READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
1369 READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
1370 union aux_ext *);
1371 READ (ss, cbSsOffset, issMax, sizeof (char), char *);
1372 READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
1373 READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
1374 READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
1375 READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
1376 #undef READ
1378 debug->fdr = NULL;
1380 return TRUE;
1382 error_return:
1383 if (ext_hdr != NULL)
1384 free (ext_hdr);
1385 if (debug->line != NULL)
1386 free (debug->line);
1387 if (debug->external_dnr != NULL)
1388 free (debug->external_dnr);
1389 if (debug->external_pdr != NULL)
1390 free (debug->external_pdr);
1391 if (debug->external_sym != NULL)
1392 free (debug->external_sym);
1393 if (debug->external_opt != NULL)
1394 free (debug->external_opt);
1395 if (debug->external_aux != NULL)
1396 free (debug->external_aux);
1397 if (debug->ss != NULL)
1398 free (debug->ss);
1399 if (debug->ssext != NULL)
1400 free (debug->ssext);
1401 if (debug->external_fdr != NULL)
1402 free (debug->external_fdr);
1403 if (debug->external_rfd != NULL)
1404 free (debug->external_rfd);
1405 if (debug->external_ext != NULL)
1406 free (debug->external_ext);
1407 return FALSE;
1410 /* Alpha ELF local labels start with '$'. */
1412 static bfd_boolean
1413 elf64_alpha_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
1415 return name[0] == '$';
1418 /* Alpha ELF follows MIPS ELF in using a special find_nearest_line
1419 routine in order to handle the ECOFF debugging information. We
1420 still call this mips_elf_find_line because of the slot
1421 find_line_info in elf_obj_tdata is declared that way. */
1423 struct mips_elf_find_line
1425 struct ecoff_debug_info d;
1426 struct ecoff_find_line i;
1429 static bfd_boolean
1430 elf64_alpha_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols,
1431 bfd_vma offset, const char **filename_ptr,
1432 const char **functionname_ptr,
1433 unsigned int *line_ptr)
1435 asection *msec;
1437 if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
1438 filename_ptr, functionname_ptr,
1439 line_ptr, 0,
1440 &elf_tdata (abfd)->dwarf2_find_line_info))
1441 return TRUE;
1443 msec = bfd_get_section_by_name (abfd, ".mdebug");
1444 if (msec != NULL)
1446 flagword origflags;
1447 struct mips_elf_find_line *fi;
1448 const struct ecoff_debug_swap * const swap =
1449 get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
1451 /* If we are called during a link, alpha_elf_final_link may have
1452 cleared the SEC_HAS_CONTENTS field. We force it back on here
1453 if appropriate (which it normally will be). */
1454 origflags = msec->flags;
1455 if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
1456 msec->flags |= SEC_HAS_CONTENTS;
1458 fi = elf_tdata (abfd)->find_line_info;
1459 if (fi == NULL)
1461 bfd_size_type external_fdr_size;
1462 char *fraw_src;
1463 char *fraw_end;
1464 struct fdr *fdr_ptr;
1465 bfd_size_type amt = sizeof (struct mips_elf_find_line);
1467 fi = (struct mips_elf_find_line *) bfd_zalloc (abfd, amt);
1468 if (fi == NULL)
1470 msec->flags = origflags;
1471 return FALSE;
1474 if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d))
1476 msec->flags = origflags;
1477 return FALSE;
1480 /* Swap in the FDR information. */
1481 amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
1482 fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt);
1483 if (fi->d.fdr == NULL)
1485 msec->flags = origflags;
1486 return FALSE;
1488 external_fdr_size = swap->external_fdr_size;
1489 fdr_ptr = fi->d.fdr;
1490 fraw_src = (char *) fi->d.external_fdr;
1491 fraw_end = (fraw_src
1492 + fi->d.symbolic_header.ifdMax * external_fdr_size);
1493 for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
1494 (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
1496 elf_tdata (abfd)->find_line_info = fi;
1498 /* Note that we don't bother to ever free this information.
1499 find_nearest_line is either called all the time, as in
1500 objdump -l, so the information should be saved, or it is
1501 rarely called, as in ld error messages, so the memory
1502 wasted is unimportant. Still, it would probably be a
1503 good idea for free_cached_info to throw it away. */
1506 if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap,
1507 &fi->i, filename_ptr, functionname_ptr,
1508 line_ptr))
1510 msec->flags = origflags;
1511 return TRUE;
1514 msec->flags = origflags;
1517 /* Fall back on the generic ELF find_nearest_line routine. */
1519 return _bfd_elf_find_nearest_line (abfd, section, symbols, offset,
1520 filename_ptr, functionname_ptr,
1521 line_ptr);
1524 /* Structure used to pass information to alpha_elf_output_extsym. */
1526 struct extsym_info
1528 bfd *abfd;
1529 struct bfd_link_info *info;
1530 struct ecoff_debug_info *debug;
1531 const struct ecoff_debug_swap *swap;
1532 bfd_boolean failed;
1535 static bfd_boolean
1536 elf64_alpha_output_extsym (struct alpha_elf_link_hash_entry *h, PTR data)
1538 struct extsym_info *einfo = (struct extsym_info *) data;
1539 bfd_boolean strip;
1540 asection *sec, *output_section;
1542 if (h->root.root.type == bfd_link_hash_warning)
1543 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
1545 if (h->root.indx == -2)
1546 strip = FALSE;
1547 else if ((h->root.def_dynamic
1548 || h->root.ref_dynamic
1549 || h->root.root.type == bfd_link_hash_new)
1550 && !h->root.def_regular
1551 && !h->root.ref_regular)
1552 strip = TRUE;
1553 else if (einfo->info->strip == strip_all
1554 || (einfo->info->strip == strip_some
1555 && bfd_hash_lookup (einfo->info->keep_hash,
1556 h->root.root.root.string,
1557 FALSE, FALSE) == NULL))
1558 strip = TRUE;
1559 else
1560 strip = FALSE;
1562 if (strip)
1563 return TRUE;
1565 if (h->esym.ifd == -2)
1567 h->esym.jmptbl = 0;
1568 h->esym.cobol_main = 0;
1569 h->esym.weakext = 0;
1570 h->esym.reserved = 0;
1571 h->esym.ifd = ifdNil;
1572 h->esym.asym.value = 0;
1573 h->esym.asym.st = stGlobal;
1575 if (h->root.root.type != bfd_link_hash_defined
1576 && h->root.root.type != bfd_link_hash_defweak)
1577 h->esym.asym.sc = scAbs;
1578 else
1580 const char *name;
1582 sec = h->root.root.u.def.section;
1583 output_section = sec->output_section;
1585 /* When making a shared library and symbol h is the one from
1586 the another shared library, OUTPUT_SECTION may be null. */
1587 if (output_section == NULL)
1588 h->esym.asym.sc = scUndefined;
1589 else
1591 name = bfd_section_name (output_section->owner, output_section);
1593 if (strcmp (name, ".text") == 0)
1594 h->esym.asym.sc = scText;
1595 else if (strcmp (name, ".data") == 0)
1596 h->esym.asym.sc = scData;
1597 else if (strcmp (name, ".sdata") == 0)
1598 h->esym.asym.sc = scSData;
1599 else if (strcmp (name, ".rodata") == 0
1600 || strcmp (name, ".rdata") == 0)
1601 h->esym.asym.sc = scRData;
1602 else if (strcmp (name, ".bss") == 0)
1603 h->esym.asym.sc = scBss;
1604 else if (strcmp (name, ".sbss") == 0)
1605 h->esym.asym.sc = scSBss;
1606 else if (strcmp (name, ".init") == 0)
1607 h->esym.asym.sc = scInit;
1608 else if (strcmp (name, ".fini") == 0)
1609 h->esym.asym.sc = scFini;
1610 else
1611 h->esym.asym.sc = scAbs;
1615 h->esym.asym.reserved = 0;
1616 h->esym.asym.index = indexNil;
1619 if (h->root.root.type == bfd_link_hash_common)
1620 h->esym.asym.value = h->root.root.u.c.size;
1621 else if (h->root.root.type == bfd_link_hash_defined
1622 || h->root.root.type == bfd_link_hash_defweak)
1624 if (h->esym.asym.sc == scCommon)
1625 h->esym.asym.sc = scBss;
1626 else if (h->esym.asym.sc == scSCommon)
1627 h->esym.asym.sc = scSBss;
1629 sec = h->root.root.u.def.section;
1630 output_section = sec->output_section;
1631 if (output_section != NULL)
1632 h->esym.asym.value = (h->root.root.u.def.value
1633 + sec->output_offset
1634 + output_section->vma);
1635 else
1636 h->esym.asym.value = 0;
1639 if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
1640 h->root.root.root.string,
1641 &h->esym))
1643 einfo->failed = TRUE;
1644 return FALSE;
1647 return TRUE;
1650 /* Search for and possibly create a got entry. */
1652 static struct alpha_elf_got_entry *
1653 get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h,
1654 unsigned long r_type, unsigned long r_symndx,
1655 bfd_vma r_addend)
1657 struct alpha_elf_got_entry *gotent;
1658 struct alpha_elf_got_entry **slot;
1660 if (h)
1661 slot = &h->got_entries;
1662 else
1664 /* This is a local .got entry -- record for merge. */
1666 struct alpha_elf_got_entry **local_got_entries;
1668 local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
1669 if (!local_got_entries)
1671 bfd_size_type size;
1672 Elf_Internal_Shdr *symtab_hdr;
1674 symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
1675 size = symtab_hdr->sh_info;
1676 size *= sizeof (struct alpha_elf_got_entry *);
1678 local_got_entries
1679 = (struct alpha_elf_got_entry **) bfd_zalloc (abfd, size);
1680 if (!local_got_entries)
1681 return NULL;
1683 alpha_elf_tdata (abfd)->local_got_entries = local_got_entries;
1686 slot = &local_got_entries[r_symndx];
1689 for (gotent = *slot; gotent ; gotent = gotent->next)
1690 if (gotent->gotobj == abfd
1691 && gotent->reloc_type == r_type
1692 && gotent->addend == r_addend)
1693 break;
1695 if (!gotent)
1697 int entry_size;
1698 bfd_size_type amt;
1700 amt = sizeof (struct alpha_elf_got_entry);
1701 gotent = (struct alpha_elf_got_entry *) bfd_alloc (abfd, amt);
1702 if (!gotent)
1703 return NULL;
1705 gotent->gotobj = abfd;
1706 gotent->addend = r_addend;
1707 gotent->got_offset = -1;
1708 gotent->plt_offset = -1;
1709 gotent->use_count = 1;
1710 gotent->reloc_type = r_type;
1711 gotent->reloc_done = 0;
1712 gotent->reloc_xlated = 0;
1714 gotent->next = *slot;
1715 *slot = gotent;
1717 entry_size = alpha_got_entry_size (r_type);
1718 alpha_elf_tdata (abfd)->total_got_size += entry_size;
1719 if (!h)
1720 alpha_elf_tdata(abfd)->local_got_size += entry_size;
1722 else
1723 gotent->use_count += 1;
1725 return gotent;
1728 static bfd_boolean
1729 elf64_alpha_want_plt (struct alpha_elf_link_hash_entry *ah)
1731 return ((ah->root.type == STT_FUNC
1732 || ah->root.root.type == bfd_link_hash_undefweak
1733 || ah->root.root.type == bfd_link_hash_undefined)
1734 && (ah->flags & ALPHA_ELF_LINK_HASH_LU_PLT) != 0
1735 && (ah->flags & ~ALPHA_ELF_LINK_HASH_LU_PLT) == 0);
1738 /* Handle dynamic relocations when doing an Alpha ELF link. */
1740 static bfd_boolean
1741 elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
1742 asection *sec, const Elf_Internal_Rela *relocs)
1744 bfd *dynobj;
1745 asection *sreloc;
1746 const char *rel_sec_name;
1747 Elf_Internal_Shdr *symtab_hdr;
1748 struct alpha_elf_link_hash_entry **sym_hashes;
1749 const Elf_Internal_Rela *rel, *relend;
1750 bfd_size_type amt;
1752 if (info->relocatable)
1753 return TRUE;
1755 /* Don't do anything special with non-loaded, non-alloced sections.
1756 In particular, any relocs in such sections should not affect GOT
1757 and PLT reference counting (ie. we don't allow them to create GOT
1758 or PLT entries), there's no possibility or desire to optimize TLS
1759 relocs, and there's not much point in propagating relocs to shared
1760 libs that the dynamic linker won't relocate. */
1761 if ((sec->flags & SEC_ALLOC) == 0)
1762 return TRUE;
1764 dynobj = elf_hash_table(info)->dynobj;
1765 if (dynobj == NULL)
1766 elf_hash_table(info)->dynobj = dynobj = abfd;
1768 sreloc = NULL;
1769 rel_sec_name = NULL;
1770 symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
1771 sym_hashes = alpha_elf_sym_hashes(abfd);
1773 relend = relocs + sec->reloc_count;
1774 for (rel = relocs; rel < relend; ++rel)
1776 enum {
1777 NEED_GOT = 1,
1778 NEED_GOT_ENTRY = 2,
1779 NEED_DYNREL = 4
1782 unsigned long r_symndx, r_type;
1783 struct alpha_elf_link_hash_entry *h;
1784 unsigned int gotent_flags;
1785 bfd_boolean maybe_dynamic;
1786 unsigned int need;
1787 bfd_vma addend;
1789 r_symndx = ELF64_R_SYM (rel->r_info);
1790 if (r_symndx < symtab_hdr->sh_info)
1791 h = NULL;
1792 else
1794 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1796 while (h->root.root.type == bfd_link_hash_indirect
1797 || h->root.root.type == bfd_link_hash_warning)
1798 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
1800 h->root.ref_regular = 1;
1803 /* We can only get preliminary data on whether a symbol is
1804 locally or externally defined, as not all of the input files
1805 have yet been processed. Do something with what we know, as
1806 this may help reduce memory usage and processing time later. */
1807 maybe_dynamic = FALSE;
1808 if (h && ((info->shared
1809 && (!info->symbolic
1810 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
1811 || !h->root.def_regular
1812 || h->root.root.type == bfd_link_hash_defweak))
1813 maybe_dynamic = TRUE;
1815 need = 0;
1816 gotent_flags = 0;
1817 r_type = ELF64_R_TYPE (rel->r_info);
1818 addend = rel->r_addend;
1820 switch (r_type)
1822 case R_ALPHA_LITERAL:
1823 need = NEED_GOT | NEED_GOT_ENTRY;
1825 /* Remember how this literal is used from its LITUSEs.
1826 This will be important when it comes to decide if we can
1827 create a .plt entry for a function symbol. */
1828 while (++rel < relend && ELF64_R_TYPE (rel->r_info) == R_ALPHA_LITUSE)
1829 if (rel->r_addend >= 1 && rel->r_addend <= 6)
1830 gotent_flags |= 1 << rel->r_addend;
1831 --rel;
1833 /* No LITUSEs -- presumably the address is used somehow. */
1834 if (gotent_flags == 0)
1835 gotent_flags = ALPHA_ELF_LINK_HASH_LU_ADDR;
1836 break;
1838 case R_ALPHA_GPDISP:
1839 case R_ALPHA_GPREL16:
1840 case R_ALPHA_GPREL32:
1841 case R_ALPHA_GPRELHIGH:
1842 case R_ALPHA_GPRELLOW:
1843 case R_ALPHA_BRSGP:
1844 need = NEED_GOT;
1845 break;
1847 case R_ALPHA_REFLONG:
1848 case R_ALPHA_REFQUAD:
1849 if (info->shared || maybe_dynamic)
1850 need = NEED_DYNREL;
1851 break;
1853 case R_ALPHA_TLSLDM:
1854 /* The symbol for a TLSLDM reloc is ignored. Collapse the
1855 reloc to the 0 symbol so that they all match. */
1856 r_symndx = 0;
1857 h = 0;
1858 maybe_dynamic = FALSE;
1859 /* FALLTHRU */
1861 case R_ALPHA_TLSGD:
1862 case R_ALPHA_GOTDTPREL:
1863 need = NEED_GOT | NEED_GOT_ENTRY;
1864 break;
1866 case R_ALPHA_GOTTPREL:
1867 need = NEED_GOT | NEED_GOT_ENTRY;
1868 gotent_flags = ALPHA_ELF_LINK_HASH_TLS_IE;
1869 if (info->shared)
1870 info->flags |= DF_STATIC_TLS;
1871 break;
1873 case R_ALPHA_TPREL64:
1874 if (info->shared || maybe_dynamic)
1875 need = NEED_DYNREL;
1876 if (info->shared)
1877 info->flags |= DF_STATIC_TLS;
1878 break;
1881 if (need & NEED_GOT)
1883 if (alpha_elf_tdata(abfd)->gotobj == NULL)
1885 if (!elf64_alpha_create_got_section (abfd, info))
1886 return FALSE;
1890 if (need & NEED_GOT_ENTRY)
1892 struct alpha_elf_got_entry *gotent;
1894 gotent = get_got_entry (abfd, h, r_type, r_symndx, addend);
1895 if (!gotent)
1896 return FALSE;
1898 if (gotent_flags)
1900 gotent->flags |= gotent_flags;
1901 if (h)
1903 gotent_flags |= h->flags;
1904 h->flags = gotent_flags;
1906 /* Make a guess as to whether a .plt entry is needed. */
1907 /* ??? It appears that we won't make it into
1908 adjust_dynamic_symbol for symbols that remain
1909 totally undefined. Copying this check here means
1910 we can create a plt entry for them too. */
1911 h->root.needs_plt
1912 = (maybe_dynamic && elf64_alpha_want_plt (h));
1917 if (need & NEED_DYNREL)
1919 if (rel_sec_name == NULL)
1921 rel_sec_name = (bfd_elf_string_from_elf_section
1922 (abfd, elf_elfheader(abfd)->e_shstrndx,
1923 elf_section_data(sec)->rel_hdr.sh_name));
1924 if (rel_sec_name == NULL)
1925 return FALSE;
1927 BFD_ASSERT (CONST_STRNEQ (rel_sec_name, ".rela")
1928 && strcmp (bfd_get_section_name (abfd, sec),
1929 rel_sec_name+5) == 0);
1932 /* We need to create the section here now whether we eventually
1933 use it or not so that it gets mapped to an output section by
1934 the linker. If not used, we'll kill it in
1935 size_dynamic_sections. */
1936 if (sreloc == NULL)
1938 sreloc = bfd_get_section_by_name (dynobj, rel_sec_name);
1939 if (sreloc == NULL)
1941 flagword flags;
1943 flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
1944 | SEC_LINKER_CREATED | SEC_READONLY);
1945 if (sec->flags & SEC_ALLOC)
1946 flags |= SEC_ALLOC | SEC_LOAD;
1947 sreloc = bfd_make_section_with_flags (dynobj,
1948 rel_sec_name,
1949 flags);
1950 if (sreloc == NULL
1951 || !bfd_set_section_alignment (dynobj, sreloc, 3))
1952 return FALSE;
1956 if (h)
1958 /* Since we havn't seen all of the input symbols yet, we
1959 don't know whether we'll actually need a dynamic relocation
1960 entry for this reloc. So make a record of it. Once we
1961 find out if this thing needs dynamic relocation we'll
1962 expand the relocation sections by the appropriate amount. */
1964 struct alpha_elf_reloc_entry *rent;
1966 for (rent = h->reloc_entries; rent; rent = rent->next)
1967 if (rent->rtype == r_type && rent->srel == sreloc)
1968 break;
1970 if (!rent)
1972 amt = sizeof (struct alpha_elf_reloc_entry);
1973 rent = (struct alpha_elf_reloc_entry *) bfd_alloc (abfd, amt);
1974 if (!rent)
1975 return FALSE;
1977 rent->srel = sreloc;
1978 rent->rtype = r_type;
1979 rent->count = 1;
1980 rent->reltext = (sec->flags & SEC_READONLY) != 0;
1982 rent->next = h->reloc_entries;
1983 h->reloc_entries = rent;
1985 else
1986 rent->count++;
1988 else if (info->shared)
1990 /* If this is a shared library, and the section is to be
1991 loaded into memory, we need a RELATIVE reloc. */
1992 sreloc->size += sizeof (Elf64_External_Rela);
1993 if (sec->flags & SEC_READONLY)
1994 info->flags |= DF_TEXTREL;
1999 return TRUE;
2002 /* Adjust a symbol defined by a dynamic object and referenced by a
2003 regular object. The current definition is in some section of the
2004 dynamic object, but we're not including those sections. We have to
2005 change the definition to something the rest of the link can
2006 understand. */
2008 static bfd_boolean
2009 elf64_alpha_adjust_dynamic_symbol (struct bfd_link_info *info,
2010 struct elf_link_hash_entry *h)
2012 bfd *dynobj;
2013 asection *s;
2014 struct alpha_elf_link_hash_entry *ah;
2016 dynobj = elf_hash_table(info)->dynobj;
2017 ah = (struct alpha_elf_link_hash_entry *)h;
2019 /* Now that we've seen all of the input symbols, finalize our decision
2020 about whether this symbol should get a .plt entry. Irritatingly, it
2021 is common for folk to leave undefined symbols in shared libraries,
2022 and they still expect lazy binding; accept undefined symbols in lieu
2023 of STT_FUNC. */
2024 if (alpha_elf_dynamic_symbol_p (h, info) && elf64_alpha_want_plt (ah))
2026 h->needs_plt = TRUE;
2028 s = bfd_get_section_by_name(dynobj, ".plt");
2029 if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
2030 return FALSE;
2032 /* We need one plt entry per got subsection. Delay allocation of
2033 the actual plt entries until size_plt_section, called from
2034 size_dynamic_sections or during relaxation. */
2036 return TRUE;
2038 else
2039 h->needs_plt = FALSE;
2041 /* If this is a weak symbol, and there is a real definition, the
2042 processor independent code will have arranged for us to see the
2043 real definition first, and we can just use the same value. */
2044 if (h->u.weakdef != NULL)
2046 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2047 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2048 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2049 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2050 return TRUE;
2053 /* This is a reference to a symbol defined by a dynamic object which
2054 is not a function. The Alpha, since it uses .got entries for all
2055 symbols even in regular objects, does not need the hackery of a
2056 .dynbss section and COPY dynamic relocations. */
2058 return TRUE;
2061 /* Record STO_ALPHA_NOPV and STO_ALPHA_STD_GPLOAD. */
2063 static void
2064 elf64_alpha_merge_symbol_attribute (struct elf_link_hash_entry *h,
2065 const Elf_Internal_Sym *isym,
2066 bfd_boolean definition,
2067 bfd_boolean dynamic)
2069 if (!dynamic && definition)
2070 h->other = ((h->other & ELF_ST_VISIBILITY (-1))
2071 | (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
2074 /* Symbol versioning can create new symbols, and make our old symbols
2075 indirect to the new ones. Consolidate the got and reloc information
2076 in these situations. */
2078 static bfd_boolean
2079 elf64_alpha_merge_ind_symbols (struct alpha_elf_link_hash_entry *hi,
2080 PTR dummy ATTRIBUTE_UNUSED)
2082 struct alpha_elf_link_hash_entry *hs;
2084 if (hi->root.root.type != bfd_link_hash_indirect)
2085 return TRUE;
2086 hs = hi;
2087 do {
2088 hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link;
2089 } while (hs->root.root.type == bfd_link_hash_indirect);
2091 /* Merge the flags. Whee. */
2093 hs->flags |= hi->flags;
2095 /* Merge the .got entries. Cannibalize the old symbol's list in
2096 doing so, since we don't need it anymore. */
2098 if (hs->got_entries == NULL)
2099 hs->got_entries = hi->got_entries;
2100 else
2102 struct alpha_elf_got_entry *gi, *gs, *gin, *gsh;
2104 gsh = hs->got_entries;
2105 for (gi = hi->got_entries; gi ; gi = gin)
2107 gin = gi->next;
2108 for (gs = gsh; gs ; gs = gs->next)
2109 if (gi->gotobj == gs->gotobj
2110 && gi->reloc_type == gs->reloc_type
2111 && gi->addend == gs->addend)
2113 gi->use_count += gs->use_count;
2114 goto got_found;
2116 gi->next = hs->got_entries;
2117 hs->got_entries = gi;
2118 got_found:;
2121 hi->got_entries = NULL;
2123 /* And similar for the reloc entries. */
2125 if (hs->reloc_entries == NULL)
2126 hs->reloc_entries = hi->reloc_entries;
2127 else
2129 struct alpha_elf_reloc_entry *ri, *rs, *rin, *rsh;
2131 rsh = hs->reloc_entries;
2132 for (ri = hi->reloc_entries; ri ; ri = rin)
2134 rin = ri->next;
2135 for (rs = rsh; rs ; rs = rs->next)
2136 if (ri->rtype == rs->rtype && ri->srel == rs->srel)
2138 rs->count += ri->count;
2139 goto found_reloc;
2141 ri->next = hs->reloc_entries;
2142 hs->reloc_entries = ri;
2143 found_reloc:;
2146 hi->reloc_entries = NULL;
2148 return TRUE;
2151 /* Is it possible to merge two object file's .got tables? */
2153 static bfd_boolean
2154 elf64_alpha_can_merge_gots (bfd *a, bfd *b)
2156 int total = alpha_elf_tdata (a)->total_got_size;
2157 bfd *bsub;
2159 /* Trivial quick fallout test. */
2160 if (total + alpha_elf_tdata (b)->total_got_size <= MAX_GOT_SIZE)
2161 return TRUE;
2163 /* By their nature, local .got entries cannot be merged. */
2164 if ((total += alpha_elf_tdata (b)->local_got_size) > MAX_GOT_SIZE)
2165 return FALSE;
2167 /* Failing the common trivial comparison, we must effectively
2168 perform the merge. Not actually performing the merge means that
2169 we don't have to store undo information in case we fail. */
2170 for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
2172 struct alpha_elf_link_hash_entry **hashes = alpha_elf_sym_hashes (bsub);
2173 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
2174 int i, n;
2176 n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
2177 for (i = 0; i < n; ++i)
2179 struct alpha_elf_got_entry *ae, *be;
2180 struct alpha_elf_link_hash_entry *h;
2182 h = hashes[i];
2183 while (h->root.root.type == bfd_link_hash_indirect
2184 || h->root.root.type == bfd_link_hash_warning)
2185 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
2187 for (be = h->got_entries; be ; be = be->next)
2189 if (be->use_count == 0)
2190 continue;
2191 if (be->gotobj != b)
2192 continue;
2194 for (ae = h->got_entries; ae ; ae = ae->next)
2195 if (ae->gotobj == a
2196 && ae->reloc_type == be->reloc_type
2197 && ae->addend == be->addend)
2198 goto global_found;
2200 total += alpha_got_entry_size (be->reloc_type);
2201 if (total > MAX_GOT_SIZE)
2202 return FALSE;
2203 global_found:;
2208 return TRUE;
2211 /* Actually merge two .got tables. */
2213 static void
2214 elf64_alpha_merge_gots (bfd *a, bfd *b)
2216 int total = alpha_elf_tdata (a)->total_got_size;
2217 bfd *bsub;
2219 /* Remember local expansion. */
2221 int e = alpha_elf_tdata (b)->local_got_size;
2222 total += e;
2223 alpha_elf_tdata (a)->local_got_size += e;
2226 for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
2228 struct alpha_elf_got_entry **local_got_entries;
2229 struct alpha_elf_link_hash_entry **hashes;
2230 Elf_Internal_Shdr *symtab_hdr;
2231 int i, n;
2233 /* Let the local .got entries know they are part of a new subsegment. */
2234 local_got_entries = alpha_elf_tdata (bsub)->local_got_entries;
2235 if (local_got_entries)
2237 n = elf_tdata (bsub)->symtab_hdr.sh_info;
2238 for (i = 0; i < n; ++i)
2240 struct alpha_elf_got_entry *ent;
2241 for (ent = local_got_entries[i]; ent; ent = ent->next)
2242 ent->gotobj = a;
2246 /* Merge the global .got entries. */
2247 hashes = alpha_elf_sym_hashes (bsub);
2248 symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
2250 n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
2251 for (i = 0; i < n; ++i)
2253 struct alpha_elf_got_entry *ae, *be, **pbe, **start;
2254 struct alpha_elf_link_hash_entry *h;
2256 h = hashes[i];
2257 while (h->root.root.type == bfd_link_hash_indirect
2258 || h->root.root.type == bfd_link_hash_warning)
2259 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
2261 pbe = start = &h->got_entries;
2262 while ((be = *pbe) != NULL)
2264 if (be->use_count == 0)
2266 *pbe = be->next;
2267 memset (be, 0xa5, sizeof (*be));
2268 goto kill;
2270 if (be->gotobj != b)
2271 goto next;
2273 for (ae = *start; ae ; ae = ae->next)
2274 if (ae->gotobj == a
2275 && ae->reloc_type == be->reloc_type
2276 && ae->addend == be->addend)
2278 ae->flags |= be->flags;
2279 ae->use_count += be->use_count;
2280 *pbe = be->next;
2281 memset (be, 0xa5, sizeof (*be));
2282 goto kill;
2284 be->gotobj = a;
2285 total += alpha_got_entry_size (be->reloc_type);
2287 next:;
2288 pbe = &be->next;
2289 kill:;
2293 alpha_elf_tdata (bsub)->gotobj = a;
2295 alpha_elf_tdata (a)->total_got_size = total;
2297 /* Merge the two in_got chains. */
2299 bfd *next;
2301 bsub = a;
2302 while ((next = alpha_elf_tdata (bsub)->in_got_link_next) != NULL)
2303 bsub = next;
2305 alpha_elf_tdata (bsub)->in_got_link_next = b;
2309 /* Calculate the offsets for the got entries. */
2311 static bfd_boolean
2312 elf64_alpha_calc_got_offsets_for_symbol (struct alpha_elf_link_hash_entry *h,
2313 PTR arg ATTRIBUTE_UNUSED)
2315 struct alpha_elf_got_entry *gotent;
2317 if (h->root.root.type == bfd_link_hash_warning)
2318 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
2320 for (gotent = h->got_entries; gotent; gotent = gotent->next)
2321 if (gotent->use_count > 0)
2323 struct alpha_elf_obj_tdata *td;
2324 bfd_size_type *plge;
2326 td = alpha_elf_tdata (gotent->gotobj);
2327 plge = &td->got->size;
2328 gotent->got_offset = *plge;
2329 *plge += alpha_got_entry_size (gotent->reloc_type);
2332 return TRUE;
2335 static void
2336 elf64_alpha_calc_got_offsets (struct bfd_link_info *info)
2338 bfd *i, *got_list = alpha_elf_hash_table(info)->got_list;
2340 /* First, zero out the .got sizes, as we may be recalculating the
2341 .got after optimizing it. */
2342 for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
2343 alpha_elf_tdata(i)->got->size = 0;
2345 /* Next, fill in the offsets for all the global entries. */
2346 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2347 elf64_alpha_calc_got_offsets_for_symbol,
2348 NULL);
2350 /* Finally, fill in the offsets for the local entries. */
2351 for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
2353 bfd_size_type got_offset = alpha_elf_tdata(i)->got->size;
2354 bfd *j;
2356 for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
2358 struct alpha_elf_got_entry **local_got_entries, *gotent;
2359 int k, n;
2361 local_got_entries = alpha_elf_tdata(j)->local_got_entries;
2362 if (!local_got_entries)
2363 continue;
2365 for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
2366 for (gotent = local_got_entries[k]; gotent; gotent = gotent->next)
2367 if (gotent->use_count > 0)
2369 gotent->got_offset = got_offset;
2370 got_offset += alpha_got_entry_size (gotent->reloc_type);
2374 alpha_elf_tdata(i)->got->size = got_offset;
2378 /* Constructs the gots. */
2380 static bfd_boolean
2381 elf64_alpha_size_got_sections (struct bfd_link_info *info)
2383 bfd *i, *got_list, *cur_got_obj = NULL;
2385 got_list = alpha_elf_hash_table (info)->got_list;
2387 /* On the first time through, pretend we have an existing got list
2388 consisting of all of the input files. */
2389 if (got_list == NULL)
2391 for (i = info->input_bfds; i ; i = i->link_next)
2393 bfd *this_got = alpha_elf_tdata (i)->gotobj;
2394 if (this_got == NULL)
2395 continue;
2397 /* We are assuming no merging has yet occurred. */
2398 BFD_ASSERT (this_got == i);
2400 if (alpha_elf_tdata (this_got)->total_got_size > MAX_GOT_SIZE)
2402 /* Yikes! A single object file has too many entries. */
2403 (*_bfd_error_handler)
2404 (_("%B: .got subsegment exceeds 64K (size %d)"),
2405 i, alpha_elf_tdata (this_got)->total_got_size);
2406 return FALSE;
2409 if (got_list == NULL)
2410 got_list = this_got;
2411 else
2412 alpha_elf_tdata(cur_got_obj)->got_link_next = this_got;
2413 cur_got_obj = this_got;
2416 /* Strange degenerate case of no got references. */
2417 if (got_list == NULL)
2418 return TRUE;
2420 alpha_elf_hash_table (info)->got_list = got_list;
2423 cur_got_obj = got_list;
2424 i = alpha_elf_tdata(cur_got_obj)->got_link_next;
2425 while (i != NULL)
2427 if (elf64_alpha_can_merge_gots (cur_got_obj, i))
2429 elf64_alpha_merge_gots (cur_got_obj, i);
2431 alpha_elf_tdata(i)->got->size = 0;
2432 i = alpha_elf_tdata(i)->got_link_next;
2433 alpha_elf_tdata(cur_got_obj)->got_link_next = i;
2435 else
2437 cur_got_obj = i;
2438 i = alpha_elf_tdata(i)->got_link_next;
2442 /* Once the gots have been merged, fill in the got offsets for
2443 everything therein. */
2444 elf64_alpha_calc_got_offsets (info);
2446 return TRUE;
2449 static bfd_boolean
2450 elf64_alpha_size_plt_section_1 (struct alpha_elf_link_hash_entry *h, PTR data)
2452 asection *splt = (asection *) data;
2453 struct alpha_elf_got_entry *gotent;
2454 bfd_boolean saw_one = FALSE;
2456 /* If we didn't need an entry before, we still don't. */
2457 if (!h->root.needs_plt)
2458 return TRUE;
2460 /* For each LITERAL got entry still in use, allocate a plt entry. */
2461 for (gotent = h->got_entries; gotent ; gotent = gotent->next)
2462 if (gotent->reloc_type == R_ALPHA_LITERAL
2463 && gotent->use_count > 0)
2465 if (splt->size == 0)
2466 splt->size = PLT_HEADER_SIZE;
2467 gotent->plt_offset = splt->size;
2468 splt->size += PLT_ENTRY_SIZE;
2469 saw_one = TRUE;
2472 /* If there weren't any, there's no longer a need for the PLT entry. */
2473 if (!saw_one)
2474 h->root.needs_plt = FALSE;
2476 return TRUE;
2479 /* Called from relax_section to rebuild the PLT in light of potential changes
2480 in the function's status. */
2482 static void
2483 elf64_alpha_size_plt_section (struct bfd_link_info *info)
2485 asection *splt, *spltrel, *sgotplt;
2486 unsigned long entries;
2487 bfd *dynobj;
2489 dynobj = elf_hash_table(info)->dynobj;
2490 splt = bfd_get_section_by_name (dynobj, ".plt");
2491 if (splt == NULL)
2492 return;
2494 splt->size = 0;
2496 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2497 elf64_alpha_size_plt_section_1, splt);
2499 /* Every plt entry requires a JMP_SLOT relocation. */
2500 spltrel = bfd_get_section_by_name (dynobj, ".rela.plt");
2501 entries = 0;
2502 if (splt->size)
2504 if (elf64_alpha_use_secureplt)
2505 entries = (splt->size - NEW_PLT_HEADER_SIZE) / NEW_PLT_ENTRY_SIZE;
2506 else
2507 entries = (splt->size - OLD_PLT_HEADER_SIZE) / OLD_PLT_ENTRY_SIZE;
2509 spltrel->size = entries * sizeof (Elf64_External_Rela);
2511 /* When using the secureplt, we need two words somewhere in the data
2512 segment for the dynamic linker to tell us where to go. This is the
2513 entire contents of the .got.plt section. */
2514 if (elf64_alpha_use_secureplt)
2516 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
2517 sgotplt->size = entries ? 16 : 0;
2521 static bfd_boolean
2522 elf64_alpha_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2523 struct bfd_link_info *info)
2525 bfd *i;
2527 if (info->relocatable)
2528 return TRUE;
2530 /* First, take care of the indirect symbols created by versioning. */
2531 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2532 elf64_alpha_merge_ind_symbols,
2533 NULL);
2535 if (!elf64_alpha_size_got_sections (info))
2536 return FALSE;
2538 /* Allocate space for all of the .got subsections. */
2539 i = alpha_elf_hash_table (info)->got_list;
2540 for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
2542 asection *s = alpha_elf_tdata(i)->got;
2543 if (s->size > 0)
2545 s->contents = (bfd_byte *) bfd_zalloc (i, s->size);
2546 if (s->contents == NULL)
2547 return FALSE;
2551 return TRUE;
2554 /* The number of dynamic relocations required by a static relocation. */
2556 static int
2557 alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared)
2559 switch (r_type)
2561 /* May appear in GOT entries. */
2562 case R_ALPHA_TLSGD:
2563 return (dynamic ? 2 : shared ? 1 : 0);
2564 case R_ALPHA_TLSLDM:
2565 return shared;
2566 case R_ALPHA_LITERAL:
2567 case R_ALPHA_GOTTPREL:
2568 return dynamic || shared;
2569 case R_ALPHA_GOTDTPREL:
2570 return dynamic;
2572 /* May appear in data sections. */
2573 case R_ALPHA_REFLONG:
2574 case R_ALPHA_REFQUAD:
2575 case R_ALPHA_TPREL64:
2576 return dynamic || shared;
2578 /* Everything else is illegal. We'll issue an error during
2579 relocate_section. */
2580 default:
2581 return 0;
2585 /* Work out the sizes of the dynamic relocation entries. */
2587 static bfd_boolean
2588 elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h,
2589 struct bfd_link_info *info)
2591 bfd_boolean dynamic;
2592 struct alpha_elf_reloc_entry *relent;
2593 unsigned long entries;
2595 if (h->root.root.type == bfd_link_hash_warning)
2596 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
2598 /* If the symbol was defined as a common symbol in a regular object
2599 file, and there was no definition in any dynamic object, then the
2600 linker will have allocated space for the symbol in a common
2601 section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been
2602 set. This is done for dynamic symbols in
2603 elf_adjust_dynamic_symbol but this is not done for non-dynamic
2604 symbols, somehow. */
2605 if (!h->root.def_regular
2606 && h->root.ref_regular
2607 && !h->root.def_dynamic
2608 && (h->root.root.type == bfd_link_hash_defined
2609 || h->root.root.type == bfd_link_hash_defweak)
2610 && !(h->root.root.u.def.section->owner->flags & DYNAMIC))
2611 h->root.def_regular = 1;
2613 /* If the symbol is dynamic, we'll need all the relocations in their
2614 natural form. If this is a shared object, and it has been forced
2615 local, we'll need the same number of RELATIVE relocations. */
2616 dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
2618 /* If the symbol is a hidden undefined weak, then we never have any
2619 relocations. Avoid the loop which may want to add RELATIVE relocs
2620 based on info->shared. */
2621 if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
2622 return TRUE;
2624 for (relent = h->reloc_entries; relent; relent = relent->next)
2626 entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
2627 info->shared);
2628 if (entries)
2630 relent->srel->size +=
2631 entries * sizeof (Elf64_External_Rela) * relent->count;
2632 if (relent->reltext)
2633 info->flags |= DT_TEXTREL;
2637 return TRUE;
2640 /* Subroutine of elf64_alpha_size_rela_got_section for doing the
2641 global symbols. */
2643 static bfd_boolean
2644 elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h,
2645 struct bfd_link_info *info)
2647 bfd_boolean dynamic;
2648 struct alpha_elf_got_entry *gotent;
2649 unsigned long entries;
2651 if (h->root.root.type == bfd_link_hash_warning)
2652 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
2654 /* If we're using a plt for this symbol, then all of its relocations
2655 for its got entries go into .rela.plt. */
2656 if (h->root.needs_plt)
2657 return TRUE;
2659 /* If the symbol is dynamic, we'll need all the relocations in their
2660 natural form. If this is a shared object, and it has been forced
2661 local, we'll need the same number of RELATIVE relocations. */
2662 dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
2664 /* If the symbol is a hidden undefined weak, then we never have any
2665 relocations. Avoid the loop which may want to add RELATIVE relocs
2666 based on info->shared. */
2667 if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
2668 return TRUE;
2670 entries = 0;
2671 for (gotent = h->got_entries; gotent ; gotent = gotent->next)
2672 if (gotent->use_count > 0)
2673 entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type,
2674 dynamic, info->shared);
2676 if (entries > 0)
2678 bfd *dynobj = elf_hash_table(info)->dynobj;
2679 asection *srel = bfd_get_section_by_name (dynobj, ".rela.got");
2680 BFD_ASSERT (srel != NULL);
2681 srel->size += sizeof (Elf64_External_Rela) * entries;
2684 return TRUE;
2687 /* Set the sizes of the dynamic relocation sections. */
2689 static void
2690 elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
2692 unsigned long entries;
2693 bfd *i, *dynobj;
2694 asection *srel;
2696 /* Shared libraries often require RELATIVE relocs, and some relocs
2697 require attention for the main application as well. */
2699 entries = 0;
2700 for (i = alpha_elf_hash_table(info)->got_list;
2701 i ; i = alpha_elf_tdata(i)->got_link_next)
2703 bfd *j;
2705 for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
2707 struct alpha_elf_got_entry **local_got_entries, *gotent;
2708 int k, n;
2710 local_got_entries = alpha_elf_tdata(j)->local_got_entries;
2711 if (!local_got_entries)
2712 continue;
2714 for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
2715 for (gotent = local_got_entries[k];
2716 gotent ; gotent = gotent->next)
2717 if (gotent->use_count > 0)
2718 entries += (alpha_dynamic_entries_for_reloc
2719 (gotent->reloc_type, 0, info->shared));
2723 dynobj = elf_hash_table(info)->dynobj;
2724 srel = bfd_get_section_by_name (dynobj, ".rela.got");
2725 if (!srel)
2727 BFD_ASSERT (entries == 0);
2728 return;
2730 srel->size = sizeof (Elf64_External_Rela) * entries;
2732 /* Now do the non-local symbols. */
2733 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2734 elf64_alpha_size_rela_got_1, info);
2737 /* Set the sizes of the dynamic sections. */
2739 static bfd_boolean
2740 elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2741 struct bfd_link_info *info)
2743 bfd *dynobj;
2744 asection *s;
2745 bfd_boolean relplt;
2747 dynobj = elf_hash_table(info)->dynobj;
2748 BFD_ASSERT(dynobj != NULL);
2750 if (elf_hash_table (info)->dynamic_sections_created)
2752 /* Set the contents of the .interp section to the interpreter. */
2753 if (info->executable)
2755 s = bfd_get_section_by_name (dynobj, ".interp");
2756 BFD_ASSERT (s != NULL);
2757 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2758 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2761 /* Now that we've seen all of the input files, we can decide which
2762 symbols need dynamic relocation entries and which don't. We've
2763 collected information in check_relocs that we can now apply to
2764 size the dynamic relocation sections. */
2765 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2766 elf64_alpha_calc_dynrel_sizes, info);
2768 elf64_alpha_size_rela_got_section (info);
2769 elf64_alpha_size_plt_section (info);
2771 /* else we're not dynamic and by definition we don't need such things. */
2773 /* The check_relocs and adjust_dynamic_symbol entry points have
2774 determined the sizes of the various dynamic sections. Allocate
2775 memory for them. */
2776 relplt = FALSE;
2777 for (s = dynobj->sections; s != NULL; s = s->next)
2779 const char *name;
2781 if (!(s->flags & SEC_LINKER_CREATED))
2782 continue;
2784 /* It's OK to base decisions on the section name, because none
2785 of the dynobj section names depend upon the input files. */
2786 name = bfd_get_section_name (dynobj, s);
2788 if (CONST_STRNEQ (name, ".rela"))
2790 if (s->size != 0)
2792 if (strcmp (name, ".rela.plt") == 0)
2793 relplt = TRUE;
2795 /* We use the reloc_count field as a counter if we need
2796 to copy relocs into the output file. */
2797 s->reloc_count = 0;
2800 else if (! CONST_STRNEQ (name, ".got")
2801 && strcmp (name, ".plt") != 0
2802 && strcmp (name, ".dynbss") != 0)
2804 /* It's not one of our dynamic sections, so don't allocate space. */
2805 continue;
2808 if (s->size == 0)
2810 /* If we don't need this section, strip it from the output file.
2811 This is to handle .rela.bss and .rela.plt. We must create it
2812 in create_dynamic_sections, because it must be created before
2813 the linker maps input sections to output sections. The
2814 linker does that before adjust_dynamic_symbol is called, and
2815 it is that function which decides whether anything needs to
2816 go into these sections. */
2817 s->flags |= SEC_EXCLUDE;
2819 else if ((s->flags & SEC_HAS_CONTENTS) != 0)
2821 /* Allocate memory for the section contents. */
2822 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2823 if (s->contents == NULL)
2824 return FALSE;
2828 if (elf_hash_table (info)->dynamic_sections_created)
2830 /* Add some entries to the .dynamic section. We fill in the
2831 values later, in elf64_alpha_finish_dynamic_sections, but we
2832 must add the entries now so that we get the correct size for
2833 the .dynamic section. The DT_DEBUG entry is filled in by the
2834 dynamic linker and used by the debugger. */
2835 #define add_dynamic_entry(TAG, VAL) \
2836 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2838 if (info->executable)
2840 if (!add_dynamic_entry (DT_DEBUG, 0))
2841 return FALSE;
2844 if (relplt)
2846 if (!add_dynamic_entry (DT_PLTGOT, 0)
2847 || !add_dynamic_entry (DT_PLTRELSZ, 0)
2848 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2849 || !add_dynamic_entry (DT_JMPREL, 0))
2850 return FALSE;
2852 if (elf64_alpha_use_secureplt
2853 && !add_dynamic_entry (DT_ALPHA_PLTRO, 1))
2854 return FALSE;
2857 if (!add_dynamic_entry (DT_RELA, 0)
2858 || !add_dynamic_entry (DT_RELASZ, 0)
2859 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
2860 return FALSE;
2862 if (info->flags & DF_TEXTREL)
2864 if (!add_dynamic_entry (DT_TEXTREL, 0))
2865 return FALSE;
2868 #undef add_dynamic_entry
2870 return TRUE;
2873 /* These functions do relaxation for Alpha ELF.
2875 Currently I'm only handling what I can do with existing compiler
2876 and assembler support, which means no instructions are removed,
2877 though some may be nopped. At this time GCC does not emit enough
2878 information to do all of the relaxing that is possible. It will
2879 take some not small amount of work for that to happen.
2881 There are a couple of interesting papers that I once read on this
2882 subject, that I cannot find references to at the moment, that
2883 related to Alpha in particular. They are by David Wall, then of
2884 DEC WRL. */
2886 struct alpha_relax_info
2888 bfd *abfd;
2889 asection *sec;
2890 bfd_byte *contents;
2891 Elf_Internal_Shdr *symtab_hdr;
2892 Elf_Internal_Rela *relocs, *relend;
2893 struct bfd_link_info *link_info;
2894 bfd_vma gp;
2895 bfd *gotobj;
2896 asection *tsec;
2897 struct alpha_elf_link_hash_entry *h;
2898 struct alpha_elf_got_entry **first_gotent;
2899 struct alpha_elf_got_entry *gotent;
2900 bfd_boolean changed_contents;
2901 bfd_boolean changed_relocs;
2902 unsigned char other;
2905 static Elf_Internal_Rela *
2906 elf64_alpha_find_reloc_at_ofs (Elf_Internal_Rela *rel,
2907 Elf_Internal_Rela *relend,
2908 bfd_vma offset, int type)
2910 while (rel < relend)
2912 if (rel->r_offset == offset
2913 && ELF64_R_TYPE (rel->r_info) == (unsigned int) type)
2914 return rel;
2915 ++rel;
2917 return NULL;
2920 static bfd_boolean
2921 elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
2922 Elf_Internal_Rela *irel, unsigned long r_type)
2924 unsigned int insn;
2925 bfd_signed_vma disp;
2927 /* Get the instruction. */
2928 insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
2930 if (insn >> 26 != OP_LDQ)
2932 reloc_howto_type *howto = elf64_alpha_howto_table + r_type;
2933 ((*_bfd_error_handler)
2934 ("%B: %A+0x%lx: warning: %s relocation against unexpected insn",
2935 info->abfd, info->sec,
2936 (unsigned long) irel->r_offset, howto->name));
2937 return TRUE;
2940 /* Can't relax dynamic symbols. */
2941 if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
2942 return TRUE;
2944 /* Can't use local-exec relocations in shared libraries. */
2945 if (r_type == R_ALPHA_GOTTPREL && info->link_info->shared)
2946 return TRUE;
2948 if (r_type == R_ALPHA_LITERAL)
2950 /* Look for nice constant addresses. This includes the not-uncommon
2951 special case of 0 for undefweak symbols. */
2952 if ((info->h && info->h->root.root.type == bfd_link_hash_undefweak)
2953 || (!info->link_info->shared
2954 && (symval >= (bfd_vma)-0x8000 || symval < 0x8000)))
2956 disp = 0;
2957 insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
2958 insn |= (symval & 0xffff);
2959 r_type = R_ALPHA_NONE;
2961 else
2963 disp = symval - info->gp;
2964 insn = (OP_LDA << 26) | (insn & 0x03ff0000);
2965 r_type = R_ALPHA_GPREL16;
2968 else
2970 bfd_vma dtp_base, tp_base;
2972 BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
2973 dtp_base = alpha_get_dtprel_base (info->link_info);
2974 tp_base = alpha_get_tprel_base (info->link_info);
2975 disp = symval - (r_type == R_ALPHA_GOTDTPREL ? dtp_base : tp_base);
2977 insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
2979 switch (r_type)
2981 case R_ALPHA_GOTDTPREL:
2982 r_type = R_ALPHA_DTPREL16;
2983 break;
2984 case R_ALPHA_GOTTPREL:
2985 r_type = R_ALPHA_TPREL16;
2986 break;
2987 default:
2988 BFD_ASSERT (0);
2989 return FALSE;
2993 if (disp < -0x8000 || disp >= 0x8000)
2994 return TRUE;
2996 bfd_put_32 (info->abfd, (bfd_vma) insn, info->contents + irel->r_offset);
2997 info->changed_contents = TRUE;
2999 /* Reduce the use count on this got entry by one, possibly
3000 eliminating it. */
3001 if (--info->gotent->use_count == 0)
3003 int sz = alpha_got_entry_size (r_type);
3004 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3005 if (!info->h)
3006 alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
3009 /* Smash the existing GOT relocation for its 16-bit immediate pair. */
3010 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), r_type);
3011 info->changed_relocs = TRUE;
3013 /* ??? Search forward through this basic block looking for insns
3014 that use the target register. Stop after an insn modifying the
3015 register is seen, or after a branch or call.
3017 Any such memory load insn may be substituted by a load directly
3018 off the GP. This allows the memory load insn to be issued before
3019 the calculated GP register would otherwise be ready.
3021 Any such jsr insn can be replaced by a bsr if it is in range.
3023 This would mean that we'd have to _add_ relocations, the pain of
3024 which gives one pause. */
3026 return TRUE;
3029 static bfd_vma
3030 elf64_alpha_relax_opt_call (struct alpha_relax_info *info, bfd_vma symval)
3032 /* If the function has the same gp, and we can identify that the
3033 function does not use its function pointer, we can eliminate the
3034 address load. */
3036 /* If the symbol is marked NOPV, we are being told the function never
3037 needs its procedure value. */
3038 if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV)
3039 return symval;
3041 /* If the symbol is marked STD_GP, we are being told the function does
3042 a normal ldgp in the first two words. */
3043 else if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD)
3046 /* Otherwise, we may be able to identify a GP load in the first two
3047 words, which we can then skip. */
3048 else
3050 Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp;
3051 bfd_vma ofs;
3053 /* Load the relocations from the section that the target symbol is in. */
3054 if (info->sec == info->tsec)
3056 tsec_relocs = info->relocs;
3057 tsec_relend = info->relend;
3058 tsec_free = NULL;
3060 else
3062 tsec_relocs = (_bfd_elf_link_read_relocs
3063 (info->abfd, info->tsec, (PTR) NULL,
3064 (Elf_Internal_Rela *) NULL,
3065 info->link_info->keep_memory));
3066 if (tsec_relocs == NULL)
3067 return 0;
3068 tsec_relend = tsec_relocs + info->tsec->reloc_count;
3069 tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs);
3072 /* Recover the symbol's offset within the section. */
3073 ofs = (symval - info->tsec->output_section->vma
3074 - info->tsec->output_offset);
3076 /* Look for a GPDISP reloc. */
3077 gpdisp = (elf64_alpha_find_reloc_at_ofs
3078 (tsec_relocs, tsec_relend, ofs, R_ALPHA_GPDISP));
3080 if (!gpdisp || gpdisp->r_addend != 4)
3082 if (tsec_free)
3083 free (tsec_free);
3084 return 0;
3086 if (tsec_free)
3087 free (tsec_free);
3090 /* We've now determined that we can skip an initial gp load. Verify
3091 that the call and the target use the same gp. */
3092 if (info->link_info->hash->creator != info->tsec->owner->xvec
3093 || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
3094 return 0;
3096 return symval + 8;
3099 static bfd_boolean
3100 elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
3101 bfd_vma symval, Elf_Internal_Rela *irel)
3103 Elf_Internal_Rela *urel, *irelend = info->relend;
3104 int flags, count, i;
3105 bfd_signed_vma disp;
3106 bfd_boolean fits16;
3107 bfd_boolean fits32;
3108 bfd_boolean lit_reused = FALSE;
3109 bfd_boolean all_optimized = TRUE;
3110 unsigned int lit_insn;
3112 lit_insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
3113 if (lit_insn >> 26 != OP_LDQ)
3115 ((*_bfd_error_handler)
3116 ("%B: %A+0x%lx: warning: LITERAL relocation against unexpected insn",
3117 info->abfd, info->sec,
3118 (unsigned long) irel->r_offset));
3119 return TRUE;
3122 /* Can't relax dynamic symbols. */
3123 if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
3124 return TRUE;
3126 /* Summarize how this particular LITERAL is used. */
3127 for (urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count)
3129 if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE)
3130 break;
3131 if (urel->r_addend <= 6)
3132 flags |= 1 << urel->r_addend;
3135 /* A little preparation for the loop... */
3136 disp = symval - info->gp;
3138 for (urel = irel+1, i = 0; i < count; ++i, ++urel)
3140 unsigned int insn;
3141 int insn_disp;
3142 bfd_signed_vma xdisp;
3144 insn = bfd_get_32 (info->abfd, info->contents + urel->r_offset);
3146 switch (urel->r_addend)
3148 case LITUSE_ALPHA_ADDR:
3149 default:
3150 /* This type is really just a placeholder to note that all
3151 uses cannot be optimized, but to still allow some. */
3152 all_optimized = FALSE;
3153 break;
3155 case LITUSE_ALPHA_BASE:
3156 /* We can always optimize 16-bit displacements. */
3158 /* Extract the displacement from the instruction, sign-extending
3159 it if necessary, then test whether it is within 16 or 32 bits
3160 displacement from GP. */
3161 insn_disp = ((insn & 0xffff) ^ 0x8000) - 0x8000;
3163 xdisp = disp + insn_disp;
3164 fits16 = (xdisp >= - (bfd_signed_vma) 0x8000 && xdisp < 0x8000);
3165 fits32 = (xdisp >= - (bfd_signed_vma) 0x80000000
3166 && xdisp < 0x7fff8000);
3168 if (fits16)
3170 /* Take the op code and dest from this insn, take the base
3171 register from the literal insn. Leave the offset alone. */
3172 insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
3173 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3174 R_ALPHA_GPREL16);
3175 urel->r_addend = irel->r_addend;
3176 info->changed_relocs = TRUE;
3178 bfd_put_32 (info->abfd, (bfd_vma) insn,
3179 info->contents + urel->r_offset);
3180 info->changed_contents = TRUE;
3183 /* If all mem+byte, we can optimize 32-bit mem displacements. */
3184 else if (fits32 && !(flags & ~6))
3186 /* FIXME: sanity check that lit insn Ra is mem insn Rb. */
3188 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3189 R_ALPHA_GPRELHIGH);
3190 lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
3191 bfd_put_32 (info->abfd, (bfd_vma) lit_insn,
3192 info->contents + irel->r_offset);
3193 lit_reused = TRUE;
3194 info->changed_contents = TRUE;
3196 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3197 R_ALPHA_GPRELLOW);
3198 urel->r_addend = irel->r_addend;
3199 info->changed_relocs = TRUE;
3201 else
3202 all_optimized = FALSE;
3203 break;
3205 case LITUSE_ALPHA_BYTOFF:
3206 /* We can always optimize byte instructions. */
3208 /* FIXME: sanity check the insn for byte op. Check that the
3209 literal dest reg is indeed Rb in the byte insn. */
3211 insn &= ~ (unsigned) 0x001ff000;
3212 insn |= ((symval & 7) << 13) | 0x1000;
3214 urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3215 urel->r_addend = 0;
3216 info->changed_relocs = TRUE;
3218 bfd_put_32 (info->abfd, (bfd_vma) insn,
3219 info->contents + urel->r_offset);
3220 info->changed_contents = TRUE;
3221 break;
3223 case LITUSE_ALPHA_JSR:
3224 case LITUSE_ALPHA_TLSGD:
3225 case LITUSE_ALPHA_TLSLDM:
3226 case LITUSE_ALPHA_JSRDIRECT:
3228 bfd_vma optdest, org;
3229 bfd_signed_vma odisp;
3231 /* For undefined weak symbols, we're mostly interested in getting
3232 rid of the got entry whenever possible, so optimize this to a
3233 use of the zero register. */
3234 if (info->h && info->h->root.root.type == bfd_link_hash_undefweak)
3236 insn |= 31 << 16;
3237 bfd_put_32 (info->abfd, (bfd_vma) insn,
3238 info->contents + urel->r_offset);
3240 info->changed_contents = TRUE;
3241 break;
3244 /* If not zero, place to jump without needing pv. */
3245 optdest = elf64_alpha_relax_opt_call (info, symval);
3246 org = (info->sec->output_section->vma
3247 + info->sec->output_offset
3248 + urel->r_offset + 4);
3249 odisp = (optdest ? optdest : symval) - org;
3251 if (odisp >= -0x400000 && odisp < 0x400000)
3253 Elf_Internal_Rela *xrel;
3255 /* Preserve branch prediction call stack when possible. */
3256 if ((insn & INSN_JSR_MASK) == INSN_JSR)
3257 insn = (OP_BSR << 26) | (insn & 0x03e00000);
3258 else
3259 insn = (OP_BR << 26) | (insn & 0x03e00000);
3261 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3262 R_ALPHA_BRADDR);
3263 urel->r_addend = irel->r_addend;
3265 if (optdest)
3266 urel->r_addend += optdest - symval;
3267 else
3268 all_optimized = FALSE;
3270 bfd_put_32 (info->abfd, (bfd_vma) insn,
3271 info->contents + urel->r_offset);
3273 /* Kill any HINT reloc that might exist for this insn. */
3274 xrel = (elf64_alpha_find_reloc_at_ofs
3275 (info->relocs, info->relend, urel->r_offset,
3276 R_ALPHA_HINT));
3277 if (xrel)
3278 xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3280 info->changed_contents = TRUE;
3281 info->changed_relocs = TRUE;
3283 else
3284 all_optimized = FALSE;
3286 /* Even if the target is not in range for a direct branch,
3287 if we share a GP, we can eliminate the gp reload. */
3288 if (optdest)
3290 Elf_Internal_Rela *gpdisp
3291 = (elf64_alpha_find_reloc_at_ofs
3292 (info->relocs, irelend, urel->r_offset + 4,
3293 R_ALPHA_GPDISP));
3294 if (gpdisp)
3296 bfd_byte *p_ldah = info->contents + gpdisp->r_offset;
3297 bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
3298 unsigned int ldah = bfd_get_32 (info->abfd, p_ldah);
3299 unsigned int lda = bfd_get_32 (info->abfd, p_lda);
3301 /* Verify that the instruction is "ldah $29,0($26)".
3302 Consider a function that ends in a noreturn call,
3303 and that the next function begins with an ldgp,
3304 and that by accident there is no padding between.
3305 In that case the insn would use $27 as the base. */
3306 if (ldah == 0x27ba0000 && lda == 0x23bd0000)
3308 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_ldah);
3309 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_lda);
3311 gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3312 info->changed_contents = TRUE;
3313 info->changed_relocs = TRUE;
3318 break;
3322 /* If all cases were optimized, we can reduce the use count on this
3323 got entry by one, possibly eliminating it. */
3324 if (all_optimized)
3326 if (--info->gotent->use_count == 0)
3328 int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
3329 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3330 if (!info->h)
3331 alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
3334 /* If the literal instruction is no longer needed (it may have been
3335 reused. We can eliminate it. */
3336 /* ??? For now, I don't want to deal with compacting the section,
3337 so just nop it out. */
3338 if (!lit_reused)
3340 irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3341 info->changed_relocs = TRUE;
3343 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP,
3344 info->contents + irel->r_offset);
3345 info->changed_contents = TRUE;
3348 return TRUE;
3350 else
3351 return elf64_alpha_relax_got_load (info, symval, irel, R_ALPHA_LITERAL);
3354 static bfd_boolean
3355 elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval,
3356 Elf_Internal_Rela *irel, bfd_boolean is_gd)
3358 bfd_byte *pos[5];
3359 unsigned int insn;
3360 Elf_Internal_Rela *gpdisp, *hint;
3361 bfd_boolean dynamic, use_gottprel, pos1_unusable;
3362 unsigned long new_symndx;
3364 dynamic = alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info);
3366 /* If a TLS symbol is accessed using IE at least once, there is no point
3367 to use dynamic model for it. */
3368 if (is_gd && info->h && (info->h->flags & ALPHA_ELF_LINK_HASH_TLS_IE))
3371 /* If the symbol is local, and we've already committed to DF_STATIC_TLS,
3372 then we might as well relax to IE. */
3373 else if (info->link_info->shared && !dynamic
3374 && (info->link_info->flags & DF_STATIC_TLS))
3377 /* Otherwise we must be building an executable to do anything. */
3378 else if (info->link_info->shared)
3379 return TRUE;
3381 /* The TLSGD/TLSLDM relocation must be followed by a LITERAL and
3382 the matching LITUSE_TLS relocations. */
3383 if (irel + 2 >= info->relend)
3384 return TRUE;
3385 if (ELF64_R_TYPE (irel[1].r_info) != R_ALPHA_LITERAL
3386 || ELF64_R_TYPE (irel[2].r_info) != R_ALPHA_LITUSE
3387 || irel[2].r_addend != (is_gd ? LITUSE_ALPHA_TLSGD : LITUSE_ALPHA_TLSLDM))
3388 return TRUE;
3390 /* There must be a GPDISP relocation positioned immediately after the
3391 LITUSE relocation. */
3392 gpdisp = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
3393 irel[2].r_offset + 4, R_ALPHA_GPDISP);
3394 if (!gpdisp)
3395 return TRUE;
3397 pos[0] = info->contents + irel[0].r_offset;
3398 pos[1] = info->contents + irel[1].r_offset;
3399 pos[2] = info->contents + irel[2].r_offset;
3400 pos[3] = info->contents + gpdisp->r_offset;
3401 pos[4] = pos[3] + gpdisp->r_addend;
3402 pos1_unusable = FALSE;
3404 /* Generally, the positions are not allowed to be out of order, lest the
3405 modified insn sequence have different register lifetimes. We can make
3406 an exception when pos 1 is adjacent to pos 0. */
3407 if (pos[1] + 4 == pos[0])
3409 bfd_byte *tmp = pos[0];
3410 pos[0] = pos[1];
3411 pos[1] = tmp;
3413 else if (pos[1] < pos[0])
3414 pos1_unusable = TRUE;
3415 if (pos[1] >= pos[2] || pos[2] >= pos[3])
3416 return TRUE;
3418 /* Reduce the use count on the LITERAL relocation. Do this before we
3419 smash the symndx when we adjust the relocations below. */
3421 struct alpha_elf_got_entry *lit_gotent;
3422 struct alpha_elf_link_hash_entry *lit_h;
3423 unsigned long indx;
3425 BFD_ASSERT (ELF64_R_SYM (irel[1].r_info) >= info->symtab_hdr->sh_info);
3426 indx = ELF64_R_SYM (irel[1].r_info) - info->symtab_hdr->sh_info;
3427 lit_h = alpha_elf_sym_hashes (info->abfd)[indx];
3429 while (lit_h->root.root.type == bfd_link_hash_indirect
3430 || lit_h->root.root.type == bfd_link_hash_warning)
3431 lit_h = (struct alpha_elf_link_hash_entry *) lit_h->root.root.u.i.link;
3433 for (lit_gotent = lit_h->got_entries; lit_gotent ;
3434 lit_gotent = lit_gotent->next)
3435 if (lit_gotent->gotobj == info->gotobj
3436 && lit_gotent->reloc_type == R_ALPHA_LITERAL
3437 && lit_gotent->addend == irel[1].r_addend)
3438 break;
3439 BFD_ASSERT (lit_gotent);
3441 if (--lit_gotent->use_count == 0)
3443 int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
3444 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3448 /* Change
3450 lda $16,x($gp) !tlsgd!1
3451 ldq $27,__tls_get_addr($gp) !literal!1
3452 jsr $26,($27),__tls_get_addr !lituse_tlsgd!1
3453 ldah $29,0($26) !gpdisp!2
3454 lda $29,0($29) !gpdisp!2
3456 ldq $16,x($gp) !gottprel
3457 unop
3458 call_pal rduniq
3459 addq $16,$0,$0
3460 unop
3461 or the first pair to
3462 lda $16,x($gp) !tprel
3463 unop
3465 ldah $16,x($gp) !tprelhi
3466 lda $16,x($16) !tprello
3468 as appropriate. */
3470 use_gottprel = FALSE;
3471 new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : 0;
3472 switch (!dynamic && !info->link_info->shared)
3474 case 1:
3476 bfd_vma tp_base;
3477 bfd_signed_vma disp;
3479 BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
3480 tp_base = alpha_get_tprel_base (info->link_info);
3481 disp = symval - tp_base;
3483 if (disp >= -0x8000 && disp < 0x8000)
3485 insn = (OP_LDA << 26) | (16 << 21) | (31 << 16);
3486 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
3487 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
3489 irel[0].r_offset = pos[0] - info->contents;
3490 irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPREL16);
3491 irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3492 break;
3494 else if (disp >= -(bfd_signed_vma) 0x80000000
3495 && disp < (bfd_signed_vma) 0x7fff8000
3496 && !pos1_unusable)
3498 insn = (OP_LDAH << 26) | (16 << 21) | (31 << 16);
3499 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
3500 insn = (OP_LDA << 26) | (16 << 21) | (16 << 16);
3501 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[1]);
3503 irel[0].r_offset = pos[0] - info->contents;
3504 irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELHI);
3505 irel[1].r_offset = pos[1] - info->contents;
3506 irel[1].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELLO);
3507 break;
3510 /* FALLTHRU */
3512 default:
3513 use_gottprel = TRUE;
3515 insn = (OP_LDQ << 26) | (16 << 21) | (29 << 16);
3516 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
3517 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
3519 irel[0].r_offset = pos[0] - info->contents;
3520 irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_GOTTPREL);
3521 irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3522 break;
3525 bfd_put_32 (info->abfd, (bfd_vma) INSN_RDUNIQ, pos[2]);
3527 insn = INSN_ADDQ | (16 << 21) | (0 << 16) | (0 << 0);
3528 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[3]);
3530 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[4]);
3532 irel[2].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3533 gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3535 hint = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
3536 irel[2].r_offset, R_ALPHA_HINT);
3537 if (hint)
3538 hint->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3540 info->changed_contents = TRUE;
3541 info->changed_relocs = TRUE;
3543 /* Reduce the use count on the TLSGD/TLSLDM relocation. */
3544 if (--info->gotent->use_count == 0)
3546 int sz = alpha_got_entry_size (info->gotent->reloc_type);
3547 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3548 if (!info->h)
3549 alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
3552 /* If we've switched to a GOTTPREL relocation, increment the reference
3553 count on that got entry. */
3554 if (use_gottprel)
3556 struct alpha_elf_got_entry *tprel_gotent;
3558 for (tprel_gotent = *info->first_gotent; tprel_gotent ;
3559 tprel_gotent = tprel_gotent->next)
3560 if (tprel_gotent->gotobj == info->gotobj
3561 && tprel_gotent->reloc_type == R_ALPHA_GOTTPREL
3562 && tprel_gotent->addend == irel->r_addend)
3563 break;
3564 if (tprel_gotent)
3565 tprel_gotent->use_count++;
3566 else
3568 if (info->gotent->use_count == 0)
3569 tprel_gotent = info->gotent;
3570 else
3572 tprel_gotent = (struct alpha_elf_got_entry *)
3573 bfd_alloc (info->abfd, sizeof (struct alpha_elf_got_entry));
3574 if (!tprel_gotent)
3575 return FALSE;
3577 tprel_gotent->next = *info->first_gotent;
3578 *info->first_gotent = tprel_gotent;
3580 tprel_gotent->gotobj = info->gotobj;
3581 tprel_gotent->addend = irel->r_addend;
3582 tprel_gotent->got_offset = -1;
3583 tprel_gotent->reloc_done = 0;
3584 tprel_gotent->reloc_xlated = 0;
3587 tprel_gotent->use_count = 1;
3588 tprel_gotent->reloc_type = R_ALPHA_GOTTPREL;
3592 return TRUE;
3595 static bfd_boolean
3596 elf64_alpha_relax_section (bfd *abfd, asection *sec,
3597 struct bfd_link_info *link_info, bfd_boolean *again)
3599 Elf_Internal_Shdr *symtab_hdr;
3600 Elf_Internal_Rela *internal_relocs;
3601 Elf_Internal_Rela *irel, *irelend;
3602 Elf_Internal_Sym *isymbuf = NULL;
3603 struct alpha_elf_got_entry **local_got_entries;
3604 struct alpha_relax_info info;
3606 /* There's nothing to change, yet. */
3607 *again = FALSE;
3609 if (link_info->relocatable
3610 || ((sec->flags & (SEC_CODE | SEC_RELOC | SEC_ALLOC))
3611 != (SEC_CODE | SEC_RELOC | SEC_ALLOC))
3612 || sec->reloc_count == 0)
3613 return TRUE;
3615 /* Make sure our GOT and PLT tables are up-to-date. */
3616 if (alpha_elf_hash_table(link_info)->relax_trip != link_info->relax_trip)
3618 alpha_elf_hash_table(link_info)->relax_trip = link_info->relax_trip;
3620 /* This should never fail after the initial round, since the only
3621 error is GOT overflow, and relaxation only shrinks the table. */
3622 if (!elf64_alpha_size_got_sections (link_info))
3623 abort ();
3624 if (elf_hash_table (link_info)->dynamic_sections_created)
3626 elf64_alpha_size_plt_section (link_info);
3627 elf64_alpha_size_rela_got_section (link_info);
3631 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3632 local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
3634 /* Load the relocations for this section. */
3635 internal_relocs = (_bfd_elf_link_read_relocs
3636 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
3637 link_info->keep_memory));
3638 if (internal_relocs == NULL)
3639 return FALSE;
3641 memset(&info, 0, sizeof (info));
3642 info.abfd = abfd;
3643 info.sec = sec;
3644 info.link_info = link_info;
3645 info.symtab_hdr = symtab_hdr;
3646 info.relocs = internal_relocs;
3647 info.relend = irelend = internal_relocs + sec->reloc_count;
3649 /* Find the GP for this object. Do not store the result back via
3650 _bfd_set_gp_value, since this could change again before final. */
3651 info.gotobj = alpha_elf_tdata (abfd)->gotobj;
3652 if (info.gotobj)
3654 asection *sgot = alpha_elf_tdata (info.gotobj)->got;
3655 info.gp = (sgot->output_section->vma
3656 + sgot->output_offset
3657 + 0x8000);
3660 /* Get the section contents. */
3661 if (elf_section_data (sec)->this_hdr.contents != NULL)
3662 info.contents = elf_section_data (sec)->this_hdr.contents;
3663 else
3665 if (!bfd_malloc_and_get_section (abfd, sec, &info.contents))
3666 goto error_return;
3669 for (irel = internal_relocs; irel < irelend; irel++)
3671 bfd_vma symval;
3672 struct alpha_elf_got_entry *gotent;
3673 unsigned long r_type = ELF64_R_TYPE (irel->r_info);
3674 unsigned long r_symndx = ELF64_R_SYM (irel->r_info);
3676 /* Early exit for unhandled or unrelaxable relocations. */
3677 switch (r_type)
3679 case R_ALPHA_LITERAL:
3680 case R_ALPHA_GPRELHIGH:
3681 case R_ALPHA_GPRELLOW:
3682 case R_ALPHA_GOTDTPREL:
3683 case R_ALPHA_GOTTPREL:
3684 case R_ALPHA_TLSGD:
3685 break;
3687 case R_ALPHA_TLSLDM:
3688 /* The symbol for a TLSLDM reloc is ignored. Collapse the
3689 reloc to the 0 symbol so that they all match. */
3690 r_symndx = 0;
3691 break;
3693 default:
3694 continue;
3697 /* Get the value of the symbol referred to by the reloc. */
3698 if (r_symndx < symtab_hdr->sh_info)
3700 /* A local symbol. */
3701 Elf_Internal_Sym *isym;
3703 /* Read this BFD's local symbols. */
3704 if (isymbuf == NULL)
3706 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
3707 if (isymbuf == NULL)
3708 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
3709 symtab_hdr->sh_info, 0,
3710 NULL, NULL, NULL);
3711 if (isymbuf == NULL)
3712 goto error_return;
3715 isym = isymbuf + r_symndx;
3717 /* Given the symbol for a TLSLDM reloc is ignored, this also
3718 means forcing the symbol value to the tp base. */
3719 if (r_type == R_ALPHA_TLSLDM)
3721 info.tsec = bfd_abs_section_ptr;
3722 symval = alpha_get_tprel_base (info.link_info);
3724 else
3726 symval = isym->st_value;
3727 if (isym->st_shndx == SHN_UNDEF)
3728 continue;
3729 else if (isym->st_shndx == SHN_ABS)
3730 info.tsec = bfd_abs_section_ptr;
3731 else if (isym->st_shndx == SHN_COMMON)
3732 info.tsec = bfd_com_section_ptr;
3733 else
3734 info.tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3737 info.h = NULL;
3738 info.other = isym->st_other;
3739 if (local_got_entries)
3740 info.first_gotent = &local_got_entries[r_symndx];
3741 else
3743 info.first_gotent = &info.gotent;
3744 info.gotent = NULL;
3747 else
3749 unsigned long indx;
3750 struct alpha_elf_link_hash_entry *h;
3752 indx = r_symndx - symtab_hdr->sh_info;
3753 h = alpha_elf_sym_hashes (abfd)[indx];
3754 BFD_ASSERT (h != NULL);
3756 while (h->root.root.type == bfd_link_hash_indirect
3757 || h->root.root.type == bfd_link_hash_warning)
3758 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
3760 /* If the symbol is undefined, we can't do anything with it. */
3761 if (h->root.root.type == bfd_link_hash_undefined)
3762 continue;
3764 /* If the symbol isn't defined in the current module,
3765 again we can't do anything. */
3766 if (h->root.root.type == bfd_link_hash_undefweak)
3768 info.tsec = bfd_abs_section_ptr;
3769 symval = 0;
3771 else if (!h->root.def_regular)
3773 /* Except for TLSGD relocs, which can sometimes be
3774 relaxed to GOTTPREL relocs. */
3775 if (r_type != R_ALPHA_TLSGD)
3776 continue;
3777 info.tsec = bfd_abs_section_ptr;
3778 symval = 0;
3780 else
3782 info.tsec = h->root.root.u.def.section;
3783 symval = h->root.root.u.def.value;
3786 info.h = h;
3787 info.other = h->root.other;
3788 info.first_gotent = &h->got_entries;
3791 /* Search for the got entry to be used by this relocation. */
3792 for (gotent = *info.first_gotent; gotent ; gotent = gotent->next)
3793 if (gotent->gotobj == info.gotobj
3794 && gotent->reloc_type == r_type
3795 && gotent->addend == irel->r_addend)
3796 break;
3797 info.gotent = gotent;
3799 symval += info.tsec->output_section->vma + info.tsec->output_offset;
3800 symval += irel->r_addend;
3802 switch (r_type)
3804 case R_ALPHA_LITERAL:
3805 BFD_ASSERT(info.gotent != NULL);
3807 /* If there exist LITUSE relocations immediately following, this
3808 opens up all sorts of interesting optimizations, because we
3809 now know every location that this address load is used. */
3810 if (irel+1 < irelend
3811 && ELF64_R_TYPE (irel[1].r_info) == R_ALPHA_LITUSE)
3813 if (!elf64_alpha_relax_with_lituse (&info, symval, irel))
3814 goto error_return;
3816 else
3818 if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
3819 goto error_return;
3821 break;
3823 case R_ALPHA_GOTDTPREL:
3824 case R_ALPHA_GOTTPREL:
3825 BFD_ASSERT(info.gotent != NULL);
3826 if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
3827 goto error_return;
3828 break;
3830 case R_ALPHA_TLSGD:
3831 case R_ALPHA_TLSLDM:
3832 BFD_ASSERT(info.gotent != NULL);
3833 if (!elf64_alpha_relax_tls_get_addr (&info, symval, irel,
3834 r_type == R_ALPHA_TLSGD))
3835 goto error_return;
3836 break;
3840 if (isymbuf != NULL
3841 && symtab_hdr->contents != (unsigned char *) isymbuf)
3843 if (!link_info->keep_memory)
3844 free (isymbuf);
3845 else
3847 /* Cache the symbols for elf_link_input_bfd. */
3848 symtab_hdr->contents = (unsigned char *) isymbuf;
3852 if (info.contents != NULL
3853 && elf_section_data (sec)->this_hdr.contents != info.contents)
3855 if (!info.changed_contents && !link_info->keep_memory)
3856 free (info.contents);
3857 else
3859 /* Cache the section contents for elf_link_input_bfd. */
3860 elf_section_data (sec)->this_hdr.contents = info.contents;
3864 if (elf_section_data (sec)->relocs != internal_relocs)
3866 if (!info.changed_relocs)
3867 free (internal_relocs);
3868 else
3869 elf_section_data (sec)->relocs = internal_relocs;
3872 *again = info.changed_contents || info.changed_relocs;
3874 return TRUE;
3876 error_return:
3877 if (isymbuf != NULL
3878 && symtab_hdr->contents != (unsigned char *) isymbuf)
3879 free (isymbuf);
3880 if (info.contents != NULL
3881 && elf_section_data (sec)->this_hdr.contents != info.contents)
3882 free (info.contents);
3883 if (internal_relocs != NULL
3884 && elf_section_data (sec)->relocs != internal_relocs)
3885 free (internal_relocs);
3886 return FALSE;
3889 /* Emit a dynamic relocation for (DYNINDX, RTYPE, ADDEND) at (SEC, OFFSET)
3890 into the next available slot in SREL. */
3892 static void
3893 elf64_alpha_emit_dynrel (bfd *abfd, struct bfd_link_info *info,
3894 asection *sec, asection *srel, bfd_vma offset,
3895 long dynindx, long rtype, bfd_vma addend)
3897 Elf_Internal_Rela outrel;
3898 bfd_byte *loc;
3900 BFD_ASSERT (srel != NULL);
3902 outrel.r_info = ELF64_R_INFO (dynindx, rtype);
3903 outrel.r_addend = addend;
3905 offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3906 if ((offset | 1) != (bfd_vma) -1)
3907 outrel.r_offset = sec->output_section->vma + sec->output_offset + offset;
3908 else
3909 memset (&outrel, 0, sizeof (outrel));
3911 loc = srel->contents;
3912 loc += srel->reloc_count++ * sizeof (Elf64_External_Rela);
3913 bfd_elf64_swap_reloca_out (abfd, &outrel, loc);
3914 BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count <= srel->size);
3917 /* Relocate an Alpha ELF section for a relocatable link.
3919 We don't have to change anything unless the reloc is against a section
3920 symbol, in which case we have to adjust according to where the section
3921 symbol winds up in the output section. */
3923 static bfd_boolean
3924 elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED,
3925 struct bfd_link_info *info ATTRIBUTE_UNUSED,
3926 bfd *input_bfd, asection *input_section,
3927 bfd_byte *contents ATTRIBUTE_UNUSED,
3928 Elf_Internal_Rela *relocs,
3929 Elf_Internal_Sym *local_syms,
3930 asection **local_sections)
3932 unsigned long symtab_hdr_sh_info;
3933 Elf_Internal_Rela *rel;
3934 Elf_Internal_Rela *relend;
3935 struct elf_link_hash_entry **sym_hashes;
3936 bfd_boolean ret_val = TRUE;
3938 symtab_hdr_sh_info = elf_tdata (input_bfd)->symtab_hdr.sh_info;
3939 sym_hashes = elf_sym_hashes (input_bfd);
3941 relend = relocs + input_section->reloc_count;
3942 for (rel = relocs; rel < relend; rel++)
3944 unsigned long r_symndx;
3945 Elf_Internal_Sym *sym;
3946 asection *sec;
3947 unsigned long r_type;
3949 r_type = ELF64_R_TYPE (rel->r_info);
3950 if (r_type >= R_ALPHA_max)
3952 (*_bfd_error_handler)
3953 (_("%B: unknown relocation type %d"),
3954 input_bfd, (int) r_type);
3955 bfd_set_error (bfd_error_bad_value);
3956 ret_val = FALSE;
3957 continue;
3960 /* The symbol associated with GPDISP and LITUSE is
3961 immaterial. Only the addend is significant. */
3962 if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE)
3963 continue;
3965 r_symndx = ELF64_R_SYM (rel->r_info);
3966 if (r_symndx < symtab_hdr_sh_info)
3968 sym = local_syms + r_symndx;
3969 sec = local_sections[r_symndx];
3971 else
3973 struct elf_link_hash_entry *h;
3975 h = sym_hashes[r_symndx - symtab_hdr_sh_info];
3977 while (h->root.type == bfd_link_hash_indirect
3978 || h->root.type == bfd_link_hash_warning)
3979 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3981 if (h->root.type != bfd_link_hash_defined
3982 && h->root.type != bfd_link_hash_defweak)
3983 continue;
3985 sym = NULL;
3986 sec = h->root.u.def.section;
3989 if (sec != NULL && elf_discarded_section (sec))
3991 /* For relocs against symbols from removed linkonce sections,
3992 or sections discarded by a linker script, we just want the
3993 section contents zeroed. */
3994 _bfd_clear_contents (elf64_alpha_howto_table + r_type,
3995 input_bfd, contents + rel->r_offset);
3996 rel->r_info = 0;
3997 rel->r_addend = 0;
3998 continue;
4001 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4002 rel->r_addend += sec->output_offset;
4005 return ret_val;
4008 /* Relocate an Alpha ELF section. */
4010 static bfd_boolean
4011 elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
4012 bfd *input_bfd, asection *input_section,
4013 bfd_byte *contents, Elf_Internal_Rela *relocs,
4014 Elf_Internal_Sym *local_syms,
4015 asection **local_sections)
4017 Elf_Internal_Shdr *symtab_hdr;
4018 Elf_Internal_Rela *rel;
4019 Elf_Internal_Rela *relend;
4020 asection *sgot, *srel, *srelgot;
4021 bfd *dynobj, *gotobj;
4022 bfd_vma gp, tp_base, dtp_base;
4023 struct alpha_elf_got_entry **local_got_entries;
4024 bfd_boolean ret_val;
4026 /* Handle relocatable links with a smaller loop. */
4027 if (info->relocatable)
4028 return elf64_alpha_relocate_section_r (output_bfd, info, input_bfd,
4029 input_section, contents, relocs,
4030 local_syms, local_sections);
4032 /* This is a final link. */
4034 ret_val = TRUE;
4036 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4038 dynobj = elf_hash_table (info)->dynobj;
4039 if (dynobj)
4040 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
4041 else
4042 srelgot = NULL;
4044 if (input_section->flags & SEC_ALLOC)
4046 const char *section_name;
4047 section_name = (bfd_elf_string_from_elf_section
4048 (input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
4049 elf_section_data(input_section)->rel_hdr.sh_name));
4050 BFD_ASSERT(section_name != NULL);
4051 srel = bfd_get_section_by_name (dynobj, section_name);
4053 else
4054 srel = NULL;
4056 /* Find the gp value for this input bfd. */
4057 gotobj = alpha_elf_tdata (input_bfd)->gotobj;
4058 if (gotobj)
4060 sgot = alpha_elf_tdata (gotobj)->got;
4061 gp = _bfd_get_gp_value (gotobj);
4062 if (gp == 0)
4064 gp = (sgot->output_section->vma
4065 + sgot->output_offset
4066 + 0x8000);
4067 _bfd_set_gp_value (gotobj, gp);
4070 else
4072 sgot = NULL;
4073 gp = 0;
4076 local_got_entries = alpha_elf_tdata(input_bfd)->local_got_entries;
4078 if (elf_hash_table (info)->tls_sec != NULL)
4080 dtp_base = alpha_get_dtprel_base (info);
4081 tp_base = alpha_get_tprel_base (info);
4083 else
4084 dtp_base = tp_base = 0;
4086 relend = relocs + input_section->reloc_count;
4087 for (rel = relocs; rel < relend; rel++)
4089 struct alpha_elf_link_hash_entry *h = NULL;
4090 struct alpha_elf_got_entry *gotent;
4091 bfd_reloc_status_type r;
4092 reloc_howto_type *howto;
4093 unsigned long r_symndx;
4094 Elf_Internal_Sym *sym = NULL;
4095 asection *sec = NULL;
4096 bfd_vma value;
4097 bfd_vma addend;
4098 bfd_boolean dynamic_symbol_p;
4099 bfd_boolean undef_weak_ref = FALSE;
4100 unsigned long r_type;
4102 r_type = ELF64_R_TYPE(rel->r_info);
4103 if (r_type >= R_ALPHA_max)
4105 (*_bfd_error_handler)
4106 (_("%B: unknown relocation type %d"),
4107 input_bfd, (int) r_type);
4108 bfd_set_error (bfd_error_bad_value);
4109 ret_val = FALSE;
4110 continue;
4113 howto = elf64_alpha_howto_table + r_type;
4114 r_symndx = ELF64_R_SYM(rel->r_info);
4116 /* The symbol for a TLSLDM reloc is ignored. Collapse the
4117 reloc to the 0 symbol so that they all match. */
4118 if (r_type == R_ALPHA_TLSLDM)
4119 r_symndx = 0;
4121 if (r_symndx < symtab_hdr->sh_info)
4123 asection *msec;
4124 sym = local_syms + r_symndx;
4125 sec = local_sections[r_symndx];
4126 msec = sec;
4127 value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
4129 /* If this is a tp-relative relocation against sym 0,
4130 this is hackery from relax_section. Force the value to
4131 be the tls module base. */
4132 if (r_symndx == 0
4133 && (r_type == R_ALPHA_TLSLDM
4134 || r_type == R_ALPHA_GOTTPREL
4135 || r_type == R_ALPHA_TPREL64
4136 || r_type == R_ALPHA_TPRELHI
4137 || r_type == R_ALPHA_TPRELLO
4138 || r_type == R_ALPHA_TPREL16))
4139 value = dtp_base;
4141 if (local_got_entries)
4142 gotent = local_got_entries[r_symndx];
4143 else
4144 gotent = NULL;
4146 /* Need to adjust local GOT entries' addends for SEC_MERGE
4147 unless it has been done already. */
4148 if ((sec->flags & SEC_MERGE)
4149 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
4150 && sec->sec_info_type == ELF_INFO_TYPE_MERGE
4151 && gotent
4152 && !gotent->reloc_xlated)
4154 struct alpha_elf_got_entry *ent;
4156 for (ent = gotent; ent; ent = ent->next)
4158 ent->reloc_xlated = 1;
4159 if (ent->use_count == 0)
4160 continue;
4161 msec = sec;
4162 ent->addend =
4163 _bfd_merged_section_offset (output_bfd, &msec,
4164 elf_section_data (sec)->
4165 sec_info,
4166 sym->st_value + ent->addend);
4167 ent->addend -= sym->st_value;
4168 ent->addend += msec->output_section->vma
4169 + msec->output_offset
4170 - sec->output_section->vma
4171 - sec->output_offset;
4175 dynamic_symbol_p = FALSE;
4177 else
4179 bfd_boolean warned;
4180 bfd_boolean unresolved_reloc;
4181 struct elf_link_hash_entry *hh;
4182 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
4184 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4185 r_symndx, symtab_hdr, sym_hashes,
4186 hh, sec, value,
4187 unresolved_reloc, warned);
4189 if (warned)
4190 continue;
4192 if (value == 0
4193 && ! unresolved_reloc
4194 && hh->root.type == bfd_link_hash_undefweak)
4195 undef_weak_ref = TRUE;
4197 h = (struct alpha_elf_link_hash_entry *) hh;
4198 dynamic_symbol_p = alpha_elf_dynamic_symbol_p (&h->root, info);
4199 gotent = h->got_entries;
4202 if (sec != NULL && elf_discarded_section (sec))
4204 /* For relocs against symbols from removed linkonce sections,
4205 or sections discarded by a linker script, we just want the
4206 section contents zeroed. Avoid any special processing. */
4207 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
4208 rel->r_info = 0;
4209 rel->r_addend = 0;
4210 continue;
4213 addend = rel->r_addend;
4214 value += addend;
4216 /* Search for the proper got entry. */
4217 for (; gotent ; gotent = gotent->next)
4218 if (gotent->gotobj == gotobj
4219 && gotent->reloc_type == r_type
4220 && gotent->addend == addend)
4221 break;
4223 switch (r_type)
4225 case R_ALPHA_GPDISP:
4227 bfd_byte *p_ldah, *p_lda;
4229 BFD_ASSERT(gp != 0);
4231 value = (input_section->output_section->vma
4232 + input_section->output_offset
4233 + rel->r_offset);
4235 p_ldah = contents + rel->r_offset;
4236 p_lda = p_ldah + rel->r_addend;
4238 r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - value,
4239 p_ldah, p_lda);
4241 break;
4243 case R_ALPHA_LITERAL:
4244 BFD_ASSERT(sgot != NULL);
4245 BFD_ASSERT(gp != 0);
4246 BFD_ASSERT(gotent != NULL);
4247 BFD_ASSERT(gotent->use_count >= 1);
4249 if (!gotent->reloc_done)
4251 gotent->reloc_done = 1;
4253 bfd_put_64 (output_bfd, value,
4254 sgot->contents + gotent->got_offset);
4256 /* If the symbol has been forced local, output a
4257 RELATIVE reloc, otherwise it will be handled in
4258 finish_dynamic_symbol. */
4259 if (info->shared && !dynamic_symbol_p && !undef_weak_ref)
4260 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
4261 gotent->got_offset, 0,
4262 R_ALPHA_RELATIVE, value);
4265 value = (sgot->output_section->vma
4266 + sgot->output_offset
4267 + gotent->got_offset);
4268 value -= gp;
4269 goto default_reloc;
4271 case R_ALPHA_GPREL32:
4272 case R_ALPHA_GPREL16:
4273 case R_ALPHA_GPRELLOW:
4274 if (dynamic_symbol_p)
4276 (*_bfd_error_handler)
4277 (_("%B: gp-relative relocation against dynamic symbol %s"),
4278 input_bfd, h->root.root.root.string);
4279 ret_val = FALSE;
4281 BFD_ASSERT(gp != 0);
4282 value -= gp;
4283 goto default_reloc;
4285 case R_ALPHA_GPRELHIGH:
4286 if (dynamic_symbol_p)
4288 (*_bfd_error_handler)
4289 (_("%B: gp-relative relocation against dynamic symbol %s"),
4290 input_bfd, h->root.root.root.string);
4291 ret_val = FALSE;
4293 BFD_ASSERT(gp != 0);
4294 value -= gp;
4295 value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
4296 goto default_reloc;
4298 case R_ALPHA_HINT:
4299 /* A call to a dynamic symbol is definitely out of range of
4300 the 16-bit displacement. Don't bother writing anything. */
4301 if (dynamic_symbol_p)
4303 r = bfd_reloc_ok;
4304 break;
4306 /* The regular PC-relative stuff measures from the start of
4307 the instruction rather than the end. */
4308 value -= 4;
4309 goto default_reloc;
4311 case R_ALPHA_BRADDR:
4312 if (dynamic_symbol_p)
4314 (*_bfd_error_handler)
4315 (_("%B: pc-relative relocation against dynamic symbol %s"),
4316 input_bfd, h->root.root.root.string);
4317 ret_val = FALSE;
4319 /* The regular PC-relative stuff measures from the start of
4320 the instruction rather than the end. */
4321 value -= 4;
4322 goto default_reloc;
4324 case R_ALPHA_BRSGP:
4326 int other;
4327 const char *name;
4329 /* The regular PC-relative stuff measures from the start of
4330 the instruction rather than the end. */
4331 value -= 4;
4333 /* The source and destination gp must be the same. Note that
4334 the source will always have an assigned gp, since we forced
4335 one in check_relocs, but that the destination may not, as
4336 it might not have had any relocations at all. Also take
4337 care not to crash if H is an undefined symbol. */
4338 if (h != NULL && sec != NULL
4339 && alpha_elf_tdata (sec->owner)->gotobj
4340 && gotobj != alpha_elf_tdata (sec->owner)->gotobj)
4342 (*_bfd_error_handler)
4343 (_("%B: change in gp: BRSGP %s"),
4344 input_bfd, h->root.root.root.string);
4345 ret_val = FALSE;
4348 /* The symbol should be marked either NOPV or STD_GPLOAD. */
4349 if (h != NULL)
4350 other = h->root.other;
4351 else
4352 other = sym->st_other;
4353 switch (other & STO_ALPHA_STD_GPLOAD)
4355 case STO_ALPHA_NOPV:
4356 break;
4357 case STO_ALPHA_STD_GPLOAD:
4358 value += 8;
4359 break;
4360 default:
4361 if (h != NULL)
4362 name = h->root.root.root.string;
4363 else
4365 name = (bfd_elf_string_from_elf_section
4366 (input_bfd, symtab_hdr->sh_link, sym->st_name));
4367 if (name == NULL)
4368 name = _("<unknown>");
4369 else if (name[0] == 0)
4370 name = bfd_section_name (input_bfd, sec);
4372 (*_bfd_error_handler)
4373 (_("%B: !samegp reloc against symbol without .prologue: %s"),
4374 input_bfd, name);
4375 ret_val = FALSE;
4376 break;
4379 goto default_reloc;
4382 case R_ALPHA_REFLONG:
4383 case R_ALPHA_REFQUAD:
4384 case R_ALPHA_DTPREL64:
4385 case R_ALPHA_TPREL64:
4387 long dynindx, dyntype = r_type;
4388 bfd_vma dynaddend;
4390 /* Careful here to remember RELATIVE relocations for global
4391 variables for symbolic shared objects. */
4393 if (dynamic_symbol_p)
4395 BFD_ASSERT(h->root.dynindx != -1);
4396 dynindx = h->root.dynindx;
4397 dynaddend = addend;
4398 addend = 0, value = 0;
4400 else if (r_type == R_ALPHA_DTPREL64)
4402 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4403 value -= dtp_base;
4404 goto default_reloc;
4406 else if (r_type == R_ALPHA_TPREL64)
4408 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4409 if (!info->shared)
4411 value -= tp_base;
4412 goto default_reloc;
4414 dynindx = 0;
4415 dynaddend = value - dtp_base;
4417 else if (info->shared
4418 && r_symndx != 0
4419 && (input_section->flags & SEC_ALLOC)
4420 && !undef_weak_ref)
4422 if (r_type == R_ALPHA_REFLONG)
4424 (*_bfd_error_handler)
4425 (_("%B: unhandled dynamic relocation against %s"),
4426 input_bfd,
4427 h->root.root.root.string);
4428 ret_val = FALSE;
4430 dynindx = 0;
4431 dyntype = R_ALPHA_RELATIVE;
4432 dynaddend = value;
4434 else
4435 goto default_reloc;
4437 if (input_section->flags & SEC_ALLOC)
4438 elf64_alpha_emit_dynrel (output_bfd, info, input_section,
4439 srel, rel->r_offset, dynindx,
4440 dyntype, dynaddend);
4442 goto default_reloc;
4444 case R_ALPHA_SREL16:
4445 case R_ALPHA_SREL32:
4446 case R_ALPHA_SREL64:
4447 if (dynamic_symbol_p)
4449 (*_bfd_error_handler)
4450 (_("%B: pc-relative relocation against dynamic symbol %s"),
4451 input_bfd, h->root.root.root.string);
4452 ret_val = FALSE;
4454 else if ((info->shared || info->pie) && undef_weak_ref)
4456 (*_bfd_error_handler)
4457 (_("%B: pc-relative relocation against undefined weak symbol %s"),
4458 input_bfd, h->root.root.root.string);
4459 ret_val = FALSE;
4463 /* ??? .eh_frame references to discarded sections will be smashed
4464 to relocations against SHN_UNDEF. The .eh_frame format allows
4465 NULL to be encoded as 0 in any format, so this works here. */
4466 if (r_symndx == 0)
4467 howto = (elf64_alpha_howto_table
4468 + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG));
4469 goto default_reloc;
4471 case R_ALPHA_TLSLDM:
4472 /* Ignore the symbol for the relocation. The result is always
4473 the current module. */
4474 dynamic_symbol_p = 0;
4475 /* FALLTHRU */
4477 case R_ALPHA_TLSGD:
4478 if (!gotent->reloc_done)
4480 gotent->reloc_done = 1;
4482 /* Note that the module index for the main program is 1. */
4483 bfd_put_64 (output_bfd, !info->shared && !dynamic_symbol_p,
4484 sgot->contents + gotent->got_offset);
4486 /* If the symbol has been forced local, output a
4487 DTPMOD64 reloc, otherwise it will be handled in
4488 finish_dynamic_symbol. */
4489 if (info->shared && !dynamic_symbol_p)
4490 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
4491 gotent->got_offset, 0,
4492 R_ALPHA_DTPMOD64, 0);
4494 if (dynamic_symbol_p || r_type == R_ALPHA_TLSLDM)
4495 value = 0;
4496 else
4498 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4499 value -= dtp_base;
4501 bfd_put_64 (output_bfd, value,
4502 sgot->contents + gotent->got_offset + 8);
4505 value = (sgot->output_section->vma
4506 + sgot->output_offset
4507 + gotent->got_offset);
4508 value -= gp;
4509 goto default_reloc;
4511 case R_ALPHA_DTPRELHI:
4512 case R_ALPHA_DTPRELLO:
4513 case R_ALPHA_DTPREL16:
4514 if (dynamic_symbol_p)
4516 (*_bfd_error_handler)
4517 (_("%B: dtp-relative relocation against dynamic symbol %s"),
4518 input_bfd, h->root.root.root.string);
4519 ret_val = FALSE;
4521 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4522 value -= dtp_base;
4523 if (r_type == R_ALPHA_DTPRELHI)
4524 value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
4525 goto default_reloc;
4527 case R_ALPHA_TPRELHI:
4528 case R_ALPHA_TPRELLO:
4529 case R_ALPHA_TPREL16:
4530 if (info->shared)
4532 (*_bfd_error_handler)
4533 (_("%B: TLS local exec code cannot be linked into shared objects"),
4534 input_bfd);
4535 ret_val = FALSE;
4537 else if (dynamic_symbol_p)
4539 (*_bfd_error_handler)
4540 (_("%B: tp-relative relocation against dynamic symbol %s"),
4541 input_bfd, h->root.root.root.string);
4542 ret_val = FALSE;
4544 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4545 value -= tp_base;
4546 if (r_type == R_ALPHA_TPRELHI)
4547 value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
4548 goto default_reloc;
4550 case R_ALPHA_GOTDTPREL:
4551 case R_ALPHA_GOTTPREL:
4552 BFD_ASSERT(sgot != NULL);
4553 BFD_ASSERT(gp != 0);
4554 BFD_ASSERT(gotent != NULL);
4555 BFD_ASSERT(gotent->use_count >= 1);
4557 if (!gotent->reloc_done)
4559 gotent->reloc_done = 1;
4561 if (dynamic_symbol_p)
4562 value = 0;
4563 else
4565 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4566 if (r_type == R_ALPHA_GOTDTPREL)
4567 value -= dtp_base;
4568 else if (!info->shared)
4569 value -= tp_base;
4570 else
4572 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
4573 gotent->got_offset, 0,
4574 R_ALPHA_TPREL64,
4575 value - dtp_base);
4576 value = 0;
4579 bfd_put_64 (output_bfd, value,
4580 sgot->contents + gotent->got_offset);
4583 value = (sgot->output_section->vma
4584 + sgot->output_offset
4585 + gotent->got_offset);
4586 value -= gp;
4587 goto default_reloc;
4589 default:
4590 default_reloc:
4591 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
4592 contents, rel->r_offset, value, 0);
4593 break;
4596 switch (r)
4598 case bfd_reloc_ok:
4599 break;
4601 case bfd_reloc_overflow:
4603 const char *name;
4605 /* Don't warn if the overflow is due to pc relative reloc
4606 against discarded section. Section optimization code should
4607 handle it. */
4609 if (r_symndx < symtab_hdr->sh_info
4610 && sec != NULL && howto->pc_relative
4611 && elf_discarded_section (sec))
4612 break;
4614 if (h != NULL)
4615 name = NULL;
4616 else
4618 name = (bfd_elf_string_from_elf_section
4619 (input_bfd, symtab_hdr->sh_link, sym->st_name));
4620 if (name == NULL)
4621 return FALSE;
4622 if (*name == '\0')
4623 name = bfd_section_name (input_bfd, sec);
4625 if (! ((*info->callbacks->reloc_overflow)
4626 (info, (h ? &h->root.root : NULL), name, howto->name,
4627 (bfd_vma) 0, input_bfd, input_section,
4628 rel->r_offset)))
4629 ret_val = FALSE;
4631 break;
4633 default:
4634 case bfd_reloc_outofrange:
4635 abort ();
4639 return ret_val;
4642 /* Finish up dynamic symbol handling. We set the contents of various
4643 dynamic sections here. */
4645 static bfd_boolean
4646 elf64_alpha_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
4647 struct elf_link_hash_entry *h,
4648 Elf_Internal_Sym *sym)
4650 struct alpha_elf_link_hash_entry *ah = (struct alpha_elf_link_hash_entry *)h;
4651 bfd *dynobj = elf_hash_table(info)->dynobj;
4653 if (h->needs_plt)
4655 /* Fill in the .plt entry for this symbol. */
4656 asection *splt, *sgot, *srel;
4657 Elf_Internal_Rela outrel;
4658 bfd_byte *loc;
4659 bfd_vma got_addr, plt_addr;
4660 bfd_vma plt_index;
4661 struct alpha_elf_got_entry *gotent;
4663 BFD_ASSERT (h->dynindx != -1);
4665 splt = bfd_get_section_by_name (dynobj, ".plt");
4666 BFD_ASSERT (splt != NULL);
4667 srel = bfd_get_section_by_name (dynobj, ".rela.plt");
4668 BFD_ASSERT (srel != NULL);
4670 for (gotent = ah->got_entries; gotent ; gotent = gotent->next)
4671 if (gotent->reloc_type == R_ALPHA_LITERAL
4672 && gotent->use_count > 0)
4674 unsigned int insn;
4675 int disp;
4677 sgot = alpha_elf_tdata (gotent->gotobj)->got;
4678 BFD_ASSERT (sgot != NULL);
4680 BFD_ASSERT (gotent->got_offset != -1);
4681 BFD_ASSERT (gotent->plt_offset != -1);
4683 got_addr = (sgot->output_section->vma
4684 + sgot->output_offset
4685 + gotent->got_offset);
4686 plt_addr = (splt->output_section->vma
4687 + splt->output_offset
4688 + gotent->plt_offset);
4690 plt_index = (gotent->plt_offset-PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
4692 /* Fill in the entry in the procedure linkage table. */
4693 if (elf64_alpha_use_secureplt)
4695 disp = (PLT_HEADER_SIZE - 4) - (gotent->plt_offset + 4);
4696 insn = INSN_AD (INSN_BR, 31, disp);
4697 bfd_put_32 (output_bfd, insn,
4698 splt->contents + gotent->plt_offset);
4700 plt_index = ((gotent->plt_offset - NEW_PLT_HEADER_SIZE)
4701 / NEW_PLT_ENTRY_SIZE);
4703 else
4705 disp = -(gotent->plt_offset + 4);
4706 insn = INSN_AD (INSN_BR, 28, disp);
4707 bfd_put_32 (output_bfd, insn,
4708 splt->contents + gotent->plt_offset);
4709 bfd_put_32 (output_bfd, INSN_UNOP,
4710 splt->contents + gotent->plt_offset + 4);
4711 bfd_put_32 (output_bfd, INSN_UNOP,
4712 splt->contents + gotent->plt_offset + 8);
4714 plt_index = ((gotent->plt_offset - OLD_PLT_HEADER_SIZE)
4715 / OLD_PLT_ENTRY_SIZE);
4718 /* Fill in the entry in the .rela.plt section. */
4719 outrel.r_offset = got_addr;
4720 outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT);
4721 outrel.r_addend = 0;
4723 loc = srel->contents + plt_index * sizeof (Elf64_External_Rela);
4724 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
4726 /* Fill in the entry in the .got. */
4727 bfd_put_64 (output_bfd, plt_addr,
4728 sgot->contents + gotent->got_offset);
4731 else if (alpha_elf_dynamic_symbol_p (h, info))
4733 /* Fill in the dynamic relocations for this symbol's .got entries. */
4734 asection *srel;
4735 struct alpha_elf_got_entry *gotent;
4737 srel = bfd_get_section_by_name (dynobj, ".rela.got");
4738 BFD_ASSERT (srel != NULL);
4740 for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
4741 gotent != NULL;
4742 gotent = gotent->next)
4744 asection *sgot;
4745 long r_type;
4747 if (gotent->use_count == 0)
4748 continue;
4750 sgot = alpha_elf_tdata (gotent->gotobj)->got;
4752 r_type = gotent->reloc_type;
4753 switch (r_type)
4755 case R_ALPHA_LITERAL:
4756 r_type = R_ALPHA_GLOB_DAT;
4757 break;
4758 case R_ALPHA_TLSGD:
4759 r_type = R_ALPHA_DTPMOD64;
4760 break;
4761 case R_ALPHA_GOTDTPREL:
4762 r_type = R_ALPHA_DTPREL64;
4763 break;
4764 case R_ALPHA_GOTTPREL:
4765 r_type = R_ALPHA_TPREL64;
4766 break;
4767 case R_ALPHA_TLSLDM:
4768 default:
4769 abort ();
4772 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
4773 gotent->got_offset, h->dynindx,
4774 r_type, gotent->addend);
4776 if (gotent->reloc_type == R_ALPHA_TLSGD)
4777 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
4778 gotent->got_offset + 8, h->dynindx,
4779 R_ALPHA_DTPREL64, gotent->addend);
4783 /* Mark some specially defined symbols as absolute. */
4784 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4785 || h == elf_hash_table (info)->hgot
4786 || h == elf_hash_table (info)->hplt)
4787 sym->st_shndx = SHN_ABS;
4789 return TRUE;
4792 /* Finish up the dynamic sections. */
4794 static bfd_boolean
4795 elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
4796 struct bfd_link_info *info)
4798 bfd *dynobj;
4799 asection *sdyn;
4801 dynobj = elf_hash_table (info)->dynobj;
4802 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4804 if (elf_hash_table (info)->dynamic_sections_created)
4806 asection *splt, *sgotplt, *srelaplt;
4807 Elf64_External_Dyn *dyncon, *dynconend;
4808 bfd_vma plt_vma, gotplt_vma;
4810 splt = bfd_get_section_by_name (dynobj, ".plt");
4811 srelaplt = bfd_get_section_by_name (output_bfd, ".rela.plt");
4812 BFD_ASSERT (splt != NULL && sdyn != NULL);
4814 plt_vma = splt->output_section->vma + splt->output_offset;
4816 gotplt_vma = 0;
4817 if (elf64_alpha_use_secureplt)
4819 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4820 BFD_ASSERT (sgotplt != NULL);
4821 if (sgotplt->size > 0)
4822 gotplt_vma = sgotplt->output_section->vma + sgotplt->output_offset;
4825 dyncon = (Elf64_External_Dyn *) sdyn->contents;
4826 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
4827 for (; dyncon < dynconend; dyncon++)
4829 Elf_Internal_Dyn dyn;
4831 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
4833 switch (dyn.d_tag)
4835 case DT_PLTGOT:
4836 dyn.d_un.d_ptr
4837 = elf64_alpha_use_secureplt ? gotplt_vma : plt_vma;
4838 break;
4839 case DT_PLTRELSZ:
4840 dyn.d_un.d_val = srelaplt ? srelaplt->size : 0;
4841 break;
4842 case DT_JMPREL:
4843 dyn.d_un.d_ptr = srelaplt ? srelaplt->vma : 0;
4844 break;
4846 case DT_RELASZ:
4847 /* My interpretation of the TIS v1.1 ELF document indicates
4848 that RELASZ should not include JMPREL. This is not what
4849 the rest of the BFD does. It is, however, what the
4850 glibc ld.so wants. Do this fixup here until we found
4851 out who is right. */
4852 if (srelaplt)
4853 dyn.d_un.d_val -= srelaplt->size;
4854 break;
4857 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
4860 /* Initialize the plt header. */
4861 if (splt->size > 0)
4863 unsigned int insn;
4864 int ofs;
4866 if (elf64_alpha_use_secureplt)
4868 ofs = gotplt_vma - (plt_vma + PLT_HEADER_SIZE);
4870 insn = INSN_ABC (INSN_SUBQ, 27, 28, 25);
4871 bfd_put_32 (output_bfd, insn, splt->contents);
4873 insn = INSN_ABO (INSN_LDAH, 28, 28, (ofs + 0x8000) >> 16);
4874 bfd_put_32 (output_bfd, insn, splt->contents + 4);
4876 insn = INSN_ABC (INSN_S4SUBQ, 25, 25, 25);
4877 bfd_put_32 (output_bfd, insn, splt->contents + 8);
4879 insn = INSN_ABO (INSN_LDA, 28, 28, ofs);
4880 bfd_put_32 (output_bfd, insn, splt->contents + 12);
4882 insn = INSN_ABO (INSN_LDQ, 27, 28, 0);
4883 bfd_put_32 (output_bfd, insn, splt->contents + 16);
4885 insn = INSN_ABC (INSN_ADDQ, 25, 25, 25);
4886 bfd_put_32 (output_bfd, insn, splt->contents + 20);
4888 insn = INSN_ABO (INSN_LDQ, 28, 28, 8);
4889 bfd_put_32 (output_bfd, insn, splt->contents + 24);
4891 insn = INSN_AB (INSN_JMP, 31, 27);
4892 bfd_put_32 (output_bfd, insn, splt->contents + 28);
4894 insn = INSN_AD (INSN_BR, 28, -PLT_HEADER_SIZE);
4895 bfd_put_32 (output_bfd, insn, splt->contents + 32);
4897 else
4899 insn = INSN_AD (INSN_BR, 27, 0); /* br $27, .+4 */
4900 bfd_put_32 (output_bfd, insn, splt->contents);
4902 insn = INSN_ABO (INSN_LDQ, 27, 27, 12);
4903 bfd_put_32 (output_bfd, insn, splt->contents + 4);
4905 insn = INSN_UNOP;
4906 bfd_put_32 (output_bfd, insn, splt->contents + 8);
4908 insn = INSN_AB (INSN_JMP, 27, 27);
4909 bfd_put_32 (output_bfd, insn, splt->contents + 12);
4911 /* The next two words will be filled in by ld.so. */
4912 bfd_put_64 (output_bfd, 0, splt->contents + 16);
4913 bfd_put_64 (output_bfd, 0, splt->contents + 24);
4916 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 0;
4920 return TRUE;
4923 /* We need to use a special link routine to handle the .mdebug section.
4924 We need to merge all instances of these sections together, not write
4925 them all out sequentially. */
4927 static bfd_boolean
4928 elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info)
4930 asection *o;
4931 struct bfd_link_order *p;
4932 asection *mdebug_sec;
4933 struct ecoff_debug_info debug;
4934 const struct ecoff_debug_swap *swap
4935 = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
4936 HDRR *symhdr = &debug.symbolic_header;
4937 PTR mdebug_handle = NULL;
4939 /* Go through the sections and collect the mdebug information. */
4940 mdebug_sec = NULL;
4941 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
4943 if (strcmp (o->name, ".mdebug") == 0)
4945 struct extsym_info einfo;
4947 /* We have found the .mdebug section in the output file.
4948 Look through all the link_orders comprising it and merge
4949 the information together. */
4950 symhdr->magic = swap->sym_magic;
4951 /* FIXME: What should the version stamp be? */
4952 symhdr->vstamp = 0;
4953 symhdr->ilineMax = 0;
4954 symhdr->cbLine = 0;
4955 symhdr->idnMax = 0;
4956 symhdr->ipdMax = 0;
4957 symhdr->isymMax = 0;
4958 symhdr->ioptMax = 0;
4959 symhdr->iauxMax = 0;
4960 symhdr->issMax = 0;
4961 symhdr->issExtMax = 0;
4962 symhdr->ifdMax = 0;
4963 symhdr->crfd = 0;
4964 symhdr->iextMax = 0;
4966 /* We accumulate the debugging information itself in the
4967 debug_info structure. */
4968 debug.line = NULL;
4969 debug.external_dnr = NULL;
4970 debug.external_pdr = NULL;
4971 debug.external_sym = NULL;
4972 debug.external_opt = NULL;
4973 debug.external_aux = NULL;
4974 debug.ss = NULL;
4975 debug.ssext = debug.ssext_end = NULL;
4976 debug.external_fdr = NULL;
4977 debug.external_rfd = NULL;
4978 debug.external_ext = debug.external_ext_end = NULL;
4980 mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
4981 if (mdebug_handle == (PTR) NULL)
4982 return FALSE;
4984 if (1)
4986 asection *s;
4987 EXTR esym;
4988 bfd_vma last = 0;
4989 unsigned int i;
4990 static const char * const name[] =
4992 ".text", ".init", ".fini", ".data",
4993 ".rodata", ".sdata", ".sbss", ".bss"
4995 static const int sc[] = { scText, scInit, scFini, scData,
4996 scRData, scSData, scSBss, scBss };
4998 esym.jmptbl = 0;
4999 esym.cobol_main = 0;
5000 esym.weakext = 0;
5001 esym.reserved = 0;
5002 esym.ifd = ifdNil;
5003 esym.asym.iss = issNil;
5004 esym.asym.st = stLocal;
5005 esym.asym.reserved = 0;
5006 esym.asym.index = indexNil;
5007 for (i = 0; i < 8; i++)
5009 esym.asym.sc = sc[i];
5010 s = bfd_get_section_by_name (abfd, name[i]);
5011 if (s != NULL)
5013 esym.asym.value = s->vma;
5014 last = s->vma + s->size;
5016 else
5017 esym.asym.value = last;
5019 if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
5020 name[i], &esym))
5021 return FALSE;
5025 for (p = o->map_head.link_order;
5026 p != (struct bfd_link_order *) NULL;
5027 p = p->next)
5029 asection *input_section;
5030 bfd *input_bfd;
5031 const struct ecoff_debug_swap *input_swap;
5032 struct ecoff_debug_info input_debug;
5033 char *eraw_src;
5034 char *eraw_end;
5036 if (p->type != bfd_indirect_link_order)
5038 if (p->type == bfd_data_link_order)
5039 continue;
5040 abort ();
5043 input_section = p->u.indirect.section;
5044 input_bfd = input_section->owner;
5046 if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour
5047 || (get_elf_backend_data (input_bfd)
5048 ->elf_backend_ecoff_debug_swap) == NULL)
5050 /* I don't know what a non ALPHA ELF bfd would be
5051 doing with a .mdebug section, but I don't really
5052 want to deal with it. */
5053 continue;
5056 input_swap = (get_elf_backend_data (input_bfd)
5057 ->elf_backend_ecoff_debug_swap);
5059 BFD_ASSERT (p->size == input_section->size);
5061 /* The ECOFF linking code expects that we have already
5062 read in the debugging information and set up an
5063 ecoff_debug_info structure, so we do that now. */
5064 if (!elf64_alpha_read_ecoff_info (input_bfd, input_section,
5065 &input_debug))
5066 return FALSE;
5068 if (! (bfd_ecoff_debug_accumulate
5069 (mdebug_handle, abfd, &debug, swap, input_bfd,
5070 &input_debug, input_swap, info)))
5071 return FALSE;
5073 /* Loop through the external symbols. For each one with
5074 interesting information, try to find the symbol in
5075 the linker global hash table and save the information
5076 for the output external symbols. */
5077 eraw_src = input_debug.external_ext;
5078 eraw_end = (eraw_src
5079 + (input_debug.symbolic_header.iextMax
5080 * input_swap->external_ext_size));
5081 for (;
5082 eraw_src < eraw_end;
5083 eraw_src += input_swap->external_ext_size)
5085 EXTR ext;
5086 const char *name;
5087 struct alpha_elf_link_hash_entry *h;
5089 (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
5090 if (ext.asym.sc == scNil
5091 || ext.asym.sc == scUndefined
5092 || ext.asym.sc == scSUndefined)
5093 continue;
5095 name = input_debug.ssext + ext.asym.iss;
5096 h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info),
5097 name, FALSE, FALSE, TRUE);
5098 if (h == NULL || h->esym.ifd != -2)
5099 continue;
5101 if (ext.ifd != -1)
5103 BFD_ASSERT (ext.ifd
5104 < input_debug.symbolic_header.ifdMax);
5105 ext.ifd = input_debug.ifdmap[ext.ifd];
5108 h->esym = ext;
5111 /* Free up the information we just read. */
5112 free (input_debug.line);
5113 free (input_debug.external_dnr);
5114 free (input_debug.external_pdr);
5115 free (input_debug.external_sym);
5116 free (input_debug.external_opt);
5117 free (input_debug.external_aux);
5118 free (input_debug.ss);
5119 free (input_debug.ssext);
5120 free (input_debug.external_fdr);
5121 free (input_debug.external_rfd);
5122 free (input_debug.external_ext);
5124 /* Hack: reset the SEC_HAS_CONTENTS flag so that
5125 elf_link_input_bfd ignores this section. */
5126 input_section->flags &=~ SEC_HAS_CONTENTS;
5129 /* Build the external symbol information. */
5130 einfo.abfd = abfd;
5131 einfo.info = info;
5132 einfo.debug = &debug;
5133 einfo.swap = swap;
5134 einfo.failed = FALSE;
5135 elf_link_hash_traverse (elf_hash_table (info),
5136 elf64_alpha_output_extsym,
5137 (PTR) &einfo);
5138 if (einfo.failed)
5139 return FALSE;
5141 /* Set the size of the .mdebug section. */
5142 o->size = bfd_ecoff_debug_size (abfd, &debug, swap);
5144 /* Skip this section later on (I don't think this currently
5145 matters, but someday it might). */
5146 o->map_head.link_order = (struct bfd_link_order *) NULL;
5148 mdebug_sec = o;
5152 /* Invoke the regular ELF backend linker to do all the work. */
5153 if (! bfd_elf_final_link (abfd, info))
5154 return FALSE;
5156 /* Now write out the computed sections. */
5158 /* The .got subsections... */
5160 bfd *i, *dynobj = elf_hash_table(info)->dynobj;
5161 for (i = alpha_elf_hash_table(info)->got_list;
5162 i != NULL;
5163 i = alpha_elf_tdata(i)->got_link_next)
5165 asection *sgot;
5167 /* elf_bfd_final_link already did everything in dynobj. */
5168 if (i == dynobj)
5169 continue;
5171 sgot = alpha_elf_tdata(i)->got;
5172 if (! bfd_set_section_contents (abfd, sgot->output_section,
5173 sgot->contents,
5174 (file_ptr) sgot->output_offset,
5175 sgot->size))
5176 return FALSE;
5180 if (mdebug_sec != (asection *) NULL)
5182 BFD_ASSERT (abfd->output_has_begun);
5183 if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
5184 swap, info,
5185 mdebug_sec->filepos))
5186 return FALSE;
5188 bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
5191 return TRUE;
5194 static enum elf_reloc_type_class
5195 elf64_alpha_reloc_type_class (const Elf_Internal_Rela *rela)
5197 switch ((int) ELF64_R_TYPE (rela->r_info))
5199 case R_ALPHA_RELATIVE:
5200 return reloc_class_relative;
5201 case R_ALPHA_JMP_SLOT:
5202 return reloc_class_plt;
5203 case R_ALPHA_COPY:
5204 return reloc_class_copy;
5205 default:
5206 return reloc_class_normal;
5210 static const struct bfd_elf_special_section elf64_alpha_special_sections[] =
5212 { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
5213 { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
5214 { NULL, 0, 0, 0, 0 }
5217 /* ECOFF swapping routines. These are used when dealing with the
5218 .mdebug section, which is in the ECOFF debugging format. Copied
5219 from elf32-mips.c. */
5220 static const struct ecoff_debug_swap
5221 elf64_alpha_ecoff_debug_swap =
5223 /* Symbol table magic number. */
5224 magicSym2,
5225 /* Alignment of debugging information. E.g., 4. */
5227 /* Sizes of external symbolic information. */
5228 sizeof (struct hdr_ext),
5229 sizeof (struct dnr_ext),
5230 sizeof (struct pdr_ext),
5231 sizeof (struct sym_ext),
5232 sizeof (struct opt_ext),
5233 sizeof (struct fdr_ext),
5234 sizeof (struct rfd_ext),
5235 sizeof (struct ext_ext),
5236 /* Functions to swap in external symbolic data. */
5237 ecoff_swap_hdr_in,
5238 ecoff_swap_dnr_in,
5239 ecoff_swap_pdr_in,
5240 ecoff_swap_sym_in,
5241 ecoff_swap_opt_in,
5242 ecoff_swap_fdr_in,
5243 ecoff_swap_rfd_in,
5244 ecoff_swap_ext_in,
5245 _bfd_ecoff_swap_tir_in,
5246 _bfd_ecoff_swap_rndx_in,
5247 /* Functions to swap out external symbolic data. */
5248 ecoff_swap_hdr_out,
5249 ecoff_swap_dnr_out,
5250 ecoff_swap_pdr_out,
5251 ecoff_swap_sym_out,
5252 ecoff_swap_opt_out,
5253 ecoff_swap_fdr_out,
5254 ecoff_swap_rfd_out,
5255 ecoff_swap_ext_out,
5256 _bfd_ecoff_swap_tir_out,
5257 _bfd_ecoff_swap_rndx_out,
5258 /* Function to read in symbolic data. */
5259 elf64_alpha_read_ecoff_info
5262 /* Use a non-standard hash bucket size of 8. */
5264 static const struct elf_size_info alpha_elf_size_info =
5266 sizeof (Elf64_External_Ehdr),
5267 sizeof (Elf64_External_Phdr),
5268 sizeof (Elf64_External_Shdr),
5269 sizeof (Elf64_External_Rel),
5270 sizeof (Elf64_External_Rela),
5271 sizeof (Elf64_External_Sym),
5272 sizeof (Elf64_External_Dyn),
5273 sizeof (Elf_External_Note),
5276 64, 3,
5277 ELFCLASS64, EV_CURRENT,
5278 bfd_elf64_write_out_phdrs,
5279 bfd_elf64_write_shdrs_and_ehdr,
5280 bfd_elf64_checksum_contents,
5281 bfd_elf64_write_relocs,
5282 bfd_elf64_swap_symbol_in,
5283 bfd_elf64_swap_symbol_out,
5284 bfd_elf64_slurp_reloc_table,
5285 bfd_elf64_slurp_symbol_table,
5286 bfd_elf64_swap_dyn_in,
5287 bfd_elf64_swap_dyn_out,
5288 bfd_elf64_swap_reloc_in,
5289 bfd_elf64_swap_reloc_out,
5290 bfd_elf64_swap_reloca_in,
5291 bfd_elf64_swap_reloca_out
5294 #define TARGET_LITTLE_SYM bfd_elf64_alpha_vec
5295 #define TARGET_LITTLE_NAME "elf64-alpha"
5296 #define ELF_ARCH bfd_arch_alpha
5297 #define ELF_MACHINE_CODE EM_ALPHA
5298 #define ELF_MAXPAGESIZE 0x10000
5299 #define ELF_COMMONPAGESIZE 0x2000
5301 #define bfd_elf64_bfd_link_hash_table_create \
5302 elf64_alpha_bfd_link_hash_table_create
5304 #define bfd_elf64_bfd_reloc_type_lookup \
5305 elf64_alpha_bfd_reloc_type_lookup
5306 #define bfd_elf64_bfd_reloc_name_lookup \
5307 elf64_alpha_bfd_reloc_name_lookup
5308 #define elf_info_to_howto \
5309 elf64_alpha_info_to_howto
5311 #define bfd_elf64_mkobject \
5312 elf64_alpha_mkobject
5313 #define elf_backend_object_p \
5314 elf64_alpha_object_p
5316 #define elf_backend_section_from_shdr \
5317 elf64_alpha_section_from_shdr
5318 #define elf_backend_section_flags \
5319 elf64_alpha_section_flags
5320 #define elf_backend_fake_sections \
5321 elf64_alpha_fake_sections
5323 #define bfd_elf64_bfd_is_local_label_name \
5324 elf64_alpha_is_local_label_name
5325 #define bfd_elf64_find_nearest_line \
5326 elf64_alpha_find_nearest_line
5327 #define bfd_elf64_bfd_relax_section \
5328 elf64_alpha_relax_section
5330 #define elf_backend_add_symbol_hook \
5331 elf64_alpha_add_symbol_hook
5332 #define elf_backend_check_relocs \
5333 elf64_alpha_check_relocs
5334 #define elf_backend_create_dynamic_sections \
5335 elf64_alpha_create_dynamic_sections
5336 #define elf_backend_adjust_dynamic_symbol \
5337 elf64_alpha_adjust_dynamic_symbol
5338 #define elf_backend_merge_symbol_attribute \
5339 elf64_alpha_merge_symbol_attribute
5340 #define elf_backend_always_size_sections \
5341 elf64_alpha_always_size_sections
5342 #define elf_backend_size_dynamic_sections \
5343 elf64_alpha_size_dynamic_sections
5344 #define elf_backend_omit_section_dynsym \
5345 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5346 #define elf_backend_relocate_section \
5347 elf64_alpha_relocate_section
5348 #define elf_backend_finish_dynamic_symbol \
5349 elf64_alpha_finish_dynamic_symbol
5350 #define elf_backend_finish_dynamic_sections \
5351 elf64_alpha_finish_dynamic_sections
5352 #define bfd_elf64_bfd_final_link \
5353 elf64_alpha_final_link
5354 #define elf_backend_reloc_type_class \
5355 elf64_alpha_reloc_type_class
5357 #define elf_backend_ecoff_debug_swap \
5358 &elf64_alpha_ecoff_debug_swap
5360 #define elf_backend_size_info \
5361 alpha_elf_size_info
5363 #define elf_backend_special_sections \
5364 elf64_alpha_special_sections
5366 /* A few constants that determine how the .plt section is set up. */
5367 #define elf_backend_want_got_plt 0
5368 #define elf_backend_plt_readonly 0
5369 #define elf_backend_want_plt_sym 1
5370 #define elf_backend_got_header_size 0
5372 #include "elf64-target.h"
5374 /* FreeBSD support. */
5376 #undef TARGET_LITTLE_SYM
5377 #define TARGET_LITTLE_SYM bfd_elf64_alpha_freebsd_vec
5378 #undef TARGET_LITTLE_NAME
5379 #define TARGET_LITTLE_NAME "elf64-alpha-freebsd"
5380 #undef ELF_OSABI
5381 #define ELF_OSABI ELFOSABI_FREEBSD
5383 /* The kernel recognizes executables as valid only if they carry a
5384 "FreeBSD" label in the ELF header. So we put this label on all
5385 executables and (for simplicity) also all other object files. */
5387 static void
5388 elf64_alpha_fbsd_post_process_headers (bfd * abfd,
5389 struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
5391 Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */
5393 i_ehdrp = elf_elfheader (abfd);
5395 /* Put an ABI label supported by FreeBSD >= 4.1. */
5396 i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
5397 #ifdef OLD_FREEBSD_ABI_LABEL
5398 /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */
5399 memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
5400 #endif
5403 #undef elf_backend_post_process_headers
5404 #define elf_backend_post_process_headers \
5405 elf64_alpha_fbsd_post_process_headers
5407 #undef elf64_bed
5408 #define elf64_bed elf64_alpha_fbsd_bed
5410 #include "elf64-target.h"