]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elf64-alpha.c
*** empty log message ***
[thirdparty/binutils-gdb.git] / bfd / elf64-alpha.c
CommitLineData
252b5132 1/* Alpha specific support for 64-bit ELF
66eb6687 2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
0ffa91dd 3 2006, 2007, 2008 Free Software Foundation, Inc.
252b5132
RH
4 Contributed by Richard Henderson <rth@tamu.edu>.
5
571fe01f 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
571fe01f
NC
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
cd123cb7 10 the Free Software Foundation; either version 3 of the License, or
571fe01f 11 (at your option) any later version.
252b5132 12
571fe01f
NC
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.
252b5132 17
571fe01f
NC
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
cd123cb7
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
252b5132
RH
23
24/* We need a published ABI spec for this. Until one comes out, don't
25 assume this'll remain unchanged forever. */
26
252b5132 27#include "sysdep.h"
3db64b00 28#include "bfd.h"
252b5132
RH
29#include "libbfd.h"
30#include "elf-bfd.h"
31
32#include "elf/alpha.h"
33
34#define ALPHAECOFF
35
36#define NO_COFF_RELOCS
37#define NO_COFF_SYMBOLS
38#define NO_COFF_LINENOS
39
fe8bc63d 40/* Get the ECOFF swapping routines. Needed for the debug information. */
252b5132
RH
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"
51
6ec7057a
RH
52\f
53/* Instruction data for plt generation and relaxation. */
54
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
60
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)
65
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
71
72#define INSN_JSR 0x68004000
73#define INSN_JMP 0x68000000
74#define INSN_JSR_MASK 0xfc00c000
75
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))
81
82/* PLT/GOT Stuff */
83
84/* Set by ld emulation. Putting this into the link_info or hash structure
85 is simply working too hard. */
86#ifdef USE_SECUREPLT
87bfd_boolean elf64_alpha_use_secureplt = TRUE;
88#else
89bfd_boolean elf64_alpha_use_secureplt = FALSE;
90#endif
91
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
96
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)
101
102#define MAX_GOT_SIZE (64*1024)
103
104#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so"
252b5132
RH
105\f
106struct alpha_elf_link_hash_entry
107{
108 struct elf_link_hash_entry root;
109
110 /* External symbol information. */
111 EXTR esym;
112
113 /* Cumulative flags for all the .got entries. */
114 int flags;
115
9e756d64 116 /* Contexts in which a literal was referenced. */
8288a39e
RH
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
cc03ec80 126
252b5132
RH
127 /* Used to implement multiple .got subsections. */
128 struct alpha_elf_got_entry
129 {
130 struct alpha_elf_got_entry *next;
131
571fe01f 132 /* Which .got subsection? */
252b5132
RH
133 bfd *gotobj;
134
571fe01f 135 /* The addend in effect for this entry. */
dc810e39 136 bfd_vma addend;
252b5132 137
571fe01f 138 /* The .got offset for this entry. */
252b5132
RH
139 int got_offset;
140
6ec7057a
RH
141 /* The .plt offset for this entry. */
142 int plt_offset;
143
3765b1be
RH
144 /* How many references to this entry? */
145 int use_count;
252b5132 146
3765b1be
RH
147 /* The relocation type of this entry. */
148 unsigned char reloc_type;
252b5132 149
3765b1be
RH
150 /* How a LITERAL is used. */
151 unsigned char flags;
152
153 /* Have we initialized the dynamic relocation for this entry? */
154 unsigned char reloc_done;
155
156 /* Have we adjusted this entry for SEC_MERGE? */
157 unsigned char reloc_xlated;
252b5132
RH
158 } *got_entries;
159
571fe01f 160 /* Used to count non-got, non-plt relocations for delayed sizing
252b5132
RH
161 of relocation sections. */
162 struct alpha_elf_reloc_entry
163 {
164 struct alpha_elf_reloc_entry *next;
165
571fe01f 166 /* Which .reloc section? */
252b5132
RH
167 asection *srel;
168
571fe01f 169 /* What kind of relocation? */
fcfbdf31
JJ
170 unsigned int rtype;
171
571fe01f 172 /* Is this against read-only section? */
fcfbdf31 173 unsigned int reltext : 1;
252b5132 174
571fe01f 175 /* How many did we find? */
252b5132
RH
176 unsigned long count;
177 } *reloc_entries;
178};
179
180/* Alpha ELF linker hash table. */
181
182struct alpha_elf_link_hash_table
183{
184 struct elf_link_hash_table root;
185
186 /* The head of a list of .got subsections linked through
187 alpha_elf_tdata(abfd)->got_link_next. */
188 bfd *got_list;
4a828aab
RH
189
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;
252b5132
RH
193};
194
195/* Look up an entry in a Alpha ELF linker hash table. */
196
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)))
201
202/* Traverse a Alpha ELF linker hash table. */
203
204#define alpha_elf_link_hash_traverse(table, func, info) \
205 (elf_link_hash_traverse \
206 (&(table)->root, \
a7519a3c 207 (bfd_boolean (*) (struct elf_link_hash_entry *, PTR)) (func), \
252b5132
RH
208 (info)))
209
210/* Get the Alpha ELF linker hash table from a link_info structure. */
211
212#define alpha_elf_hash_table(p) \
213 ((struct alpha_elf_link_hash_table *) ((p)->hash))
214
215/* Get the object's symbols as our own entry type. */
216
217#define alpha_elf_sym_hashes(abfd) \
218 ((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
219
986a241f
RH
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. */
252b5132 224
986a241f 225static inline bfd_boolean
a7519a3c
RH
226alpha_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
227 struct bfd_link_info *info)
8fb35fed 228{
986a241f 229 return _bfd_elf_dynamic_symbol_p (h, info, 0);
8fb35fed 230}
252b5132
RH
231
232/* Create an entry in a Alpha ELF linker hash table. */
233
234static struct bfd_hash_entry *
a7519a3c
RH
235elf64_alpha_link_hash_newfunc (struct bfd_hash_entry *entry,
236 struct bfd_hash_table *table,
237 const char *string)
252b5132
RH
238{
239 struct alpha_elf_link_hash_entry *ret =
240 (struct alpha_elf_link_hash_entry *) entry;
241
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;
250
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)
256 {
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;
265 }
266
267 return (struct bfd_hash_entry *) ret;
268}
269
270/* Create a Alpha ELF linker hash table. */
271
272static struct bfd_link_hash_table *
a7519a3c 273elf64_alpha_bfd_link_hash_table_create (bfd *abfd)
252b5132
RH
274{
275 struct alpha_elf_link_hash_table *ret;
dc810e39 276 bfd_size_type amt = sizeof (struct alpha_elf_link_hash_table);
252b5132 277
e2d34d7d 278 ret = (struct alpha_elf_link_hash_table *) bfd_zmalloc (amt);
252b5132
RH
279 if (ret == (struct alpha_elf_link_hash_table *) NULL)
280 return NULL;
281
66eb6687
AM
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)))
252b5132 285 {
e2d34d7d 286 free (ret);
252b5132
RH
287 return NULL;
288 }
289
290 return &ret->root.root;
291}
292\f
293/* We have some private fields hanging off of the elf_tdata structure. */
294
295struct alpha_elf_obj_tdata
296{
297 struct elf_obj_tdata root;
298
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;
302
303 /* For every input file, this is the object that owns the got that
304 this input file uses. */
305 bfd *gotobj;
306
307 /* For every got, this is a linked list through the objects using this got */
308 bfd *in_got_link_next;
309
310 /* For every got, this is a link to the next got subsegment. */
311 bfd *got_link_next;
312
313 /* For every got, this is the section. */
314 asection *got;
315
3765b1be
RH
316 /* For every got, this is it's total number of words. */
317 int total_got_size;
252b5132 318
3765b1be 319 /* For every got, this is the sum of the number of words required
252b5132 320 to hold all of the member object's local got. */
3765b1be 321 int local_got_size;
252b5132
RH
322};
323
324#define alpha_elf_tdata(abfd) \
325 ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any)
326
0ffa91dd
NC
327#define is_alpha_elf(bfd) \
328 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
329 && elf_tdata (bfd) != NULL \
330 && elf_object_id (bfd) == ALPHA_ELF_TDATA)
331
b34976b6 332static bfd_boolean
a7519a3c 333elf64_alpha_mkobject (bfd *abfd)
252b5132 334{
0ffa91dd
NC
335 return bfd_elf_allocate_object (abfd, sizeof (struct alpha_elf_obj_tdata),
336 ALPHA_ELF_TDATA);
252b5132
RH
337}
338
b34976b6 339static bfd_boolean
a7519a3c 340elf64_alpha_object_p (bfd *abfd)
252b5132 341{
252b5132
RH
342 /* Set the right machine number for an Alpha ELF file. */
343 return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
344}
345\f
a7519a3c
RH
346/* A relocation function which doesn't do anything. */
347
348static bfd_reloc_status_type
349elf64_alpha_reloc_nil (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
350 asymbol *sym ATTRIBUTE_UNUSED,
351 PTR data ATTRIBUTE_UNUSED, asection *sec,
352 bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
353{
354 if (output_bfd)
355 reloc->address += sec->output_offset;
356 return bfd_reloc_ok;
357}
358
359/* A relocation function used for an unsupported reloc. */
360
361static bfd_reloc_status_type
362elf64_alpha_reloc_bad (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
363 asymbol *sym ATTRIBUTE_UNUSED,
364 PTR data ATTRIBUTE_UNUSED, asection *sec,
365 bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
366{
367 if (output_bfd)
368 reloc->address += sec->output_offset;
369 return bfd_reloc_notsupported;
370}
371
372/* Do the work of the GPDISP relocation. */
373
374static bfd_reloc_status_type
375elf64_alpha_do_reloc_gpdisp (bfd *abfd, bfd_vma gpdisp, bfd_byte *p_ldah,
376 bfd_byte *p_lda)
377{
378 bfd_reloc_status_type ret = bfd_reloc_ok;
379 bfd_vma addend;
380 unsigned long i_ldah, i_lda;
381
382 i_ldah = bfd_get_32 (abfd, p_ldah);
383 i_lda = bfd_get_32 (abfd, p_lda);
384
385 /* Complain if the instructions are not correct. */
386 if (((i_ldah >> 26) & 0x3f) != 0x09
387 || ((i_lda >> 26) & 0x3f) != 0x08)
388 ret = bfd_reloc_dangerous;
389
390 /* Extract the user-supplied offset, mirroring the sign extensions
391 that the instructions perform. */
392 addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff);
393 addend = (addend ^ 0x80008000) - 0x80008000;
394
395 gpdisp += addend;
396
397 if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000
398 || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000)
399 ret = bfd_reloc_overflow;
400
401 /* compensate for the sign extension again. */
402 i_ldah = ((i_ldah & 0xffff0000)
403 | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff));
404 i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff);
405
406 bfd_put_32 (abfd, (bfd_vma) i_ldah, p_ldah);
407 bfd_put_32 (abfd, (bfd_vma) i_lda, p_lda);
408
409 return ret;
410}
411
412/* The special function for the GPDISP reloc. */
413
414static bfd_reloc_status_type
415elf64_alpha_reloc_gpdisp (bfd *abfd, arelent *reloc_entry,
416 asymbol *sym ATTRIBUTE_UNUSED, PTR data,
417 asection *input_section, bfd *output_bfd,
418 char **err_msg)
419{
420 bfd_reloc_status_type ret;
421 bfd_vma gp, relocation;
422 bfd_vma high_address;
423 bfd_byte *p_ldah, *p_lda;
424
425 /* Don't do anything if we're not doing a final link. */
426 if (output_bfd)
427 {
428 reloc_entry->address += input_section->output_offset;
429 return bfd_reloc_ok;
430 }
431
432 high_address = bfd_get_section_limit (abfd, input_section);
433 if (reloc_entry->address > high_address
434 || reloc_entry->address + reloc_entry->addend > high_address)
435 return bfd_reloc_outofrange;
436
437 /* The gp used in the portion of the output object to which this
438 input object belongs is cached on the input bfd. */
439 gp = _bfd_get_gp_value (abfd);
440
441 relocation = (input_section->output_section->vma
442 + input_section->output_offset
443 + reloc_entry->address);
444
445 p_ldah = (bfd_byte *) data + reloc_entry->address;
446 p_lda = p_ldah + reloc_entry->addend;
447
448 ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda);
449
450 /* Complain if the instructions are not correct. */
451 if (ret == bfd_reloc_dangerous)
452 *err_msg = _("GPDISP relocation did not find ldah and lda instructions");
453
454 return ret;
455}
456
252b5132
RH
457/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
458 from smaller values. Start with zero, widen, *then* decrement. */
459#define MINUS_ONE (((bfd_vma)0) - 1)
460
dfe57ca0
RH
461#define SKIP_HOWTO(N) \
462 HOWTO(N, 0, 0, 0, 0, 0, 0, elf64_alpha_reloc_bad, 0, 0, 0, 0, 0)
463
252b5132
RH
464static reloc_howto_type elf64_alpha_howto_table[] =
465{
466 HOWTO (R_ALPHA_NONE, /* type */
467 0, /* rightshift */
468 0, /* size (0 = byte, 1 = short, 2 = long) */
469 8, /* bitsize */
b34976b6 470 TRUE, /* pc_relative */
252b5132
RH
471 0, /* bitpos */
472 complain_overflow_dont, /* complain_on_overflow */
473 elf64_alpha_reloc_nil, /* special_function */
474 "NONE", /* name */
b34976b6 475 FALSE, /* partial_inplace */
252b5132
RH
476 0, /* src_mask */
477 0, /* dst_mask */
b34976b6 478 TRUE), /* pcrel_offset */
252b5132
RH
479
480 /* A 32 bit reference to a symbol. */
481 HOWTO (R_ALPHA_REFLONG, /* type */
482 0, /* rightshift */
483 2, /* size (0 = byte, 1 = short, 2 = long) */
484 32, /* bitsize */
b34976b6 485 FALSE, /* pc_relative */
252b5132
RH
486 0, /* bitpos */
487 complain_overflow_bitfield, /* complain_on_overflow */
488 0, /* special_function */
489 "REFLONG", /* name */
b34976b6 490 FALSE, /* partial_inplace */
252b5132
RH
491 0xffffffff, /* src_mask */
492 0xffffffff, /* dst_mask */
b34976b6 493 FALSE), /* pcrel_offset */
252b5132
RH
494
495 /* A 64 bit reference to a symbol. */
496 HOWTO (R_ALPHA_REFQUAD, /* type */
497 0, /* rightshift */
498 4, /* size (0 = byte, 1 = short, 2 = long) */
499 64, /* bitsize */
b34976b6 500 FALSE, /* pc_relative */
252b5132
RH
501 0, /* bitpos */
502 complain_overflow_bitfield, /* complain_on_overflow */
503 0, /* special_function */
504 "REFQUAD", /* name */
b34976b6 505 FALSE, /* partial_inplace */
252b5132
RH
506 MINUS_ONE, /* src_mask */
507 MINUS_ONE, /* dst_mask */
b34976b6 508 FALSE), /* pcrel_offset */
252b5132
RH
509
510 /* A 32 bit GP relative offset. This is just like REFLONG except
511 that when the value is used the value of the gp register will be
512 added in. */
513 HOWTO (R_ALPHA_GPREL32, /* type */
514 0, /* rightshift */
515 2, /* size (0 = byte, 1 = short, 2 = long) */
516 32, /* bitsize */
b34976b6 517 FALSE, /* pc_relative */
252b5132
RH
518 0, /* bitpos */
519 complain_overflow_bitfield, /* complain_on_overflow */
520 0, /* special_function */
521 "GPREL32", /* name */
b34976b6 522 FALSE, /* partial_inplace */
252b5132
RH
523 0xffffffff, /* src_mask */
524 0xffffffff, /* dst_mask */
b34976b6 525 FALSE), /* pcrel_offset */
252b5132
RH
526
527 /* Used for an instruction that refers to memory off the GP register. */
528 HOWTO (R_ALPHA_LITERAL, /* type */
529 0, /* rightshift */
dfe57ca0 530 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132 531 16, /* bitsize */
b34976b6 532 FALSE, /* pc_relative */
252b5132
RH
533 0, /* bitpos */
534 complain_overflow_signed, /* complain_on_overflow */
535 0, /* special_function */
536 "ELF_LITERAL", /* name */
b34976b6 537 FALSE, /* partial_inplace */
252b5132
RH
538 0xffff, /* src_mask */
539 0xffff, /* dst_mask */
b34976b6 540 FALSE), /* pcrel_offset */
252b5132
RH
541
542 /* This reloc only appears immediately following an ELF_LITERAL reloc.
543 It identifies a use of the literal. The symbol index is special:
544 1 means the literal address is in the base register of a memory
545 format instruction; 2 means the literal address is in the byte
546 offset register of a byte-manipulation instruction; 3 means the
547 literal address is in the target register of a jsr instruction.
548 This does not actually do any relocation. */
549 HOWTO (R_ALPHA_LITUSE, /* type */
550 0, /* rightshift */
dfe57ca0 551 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132 552 32, /* bitsize */
b34976b6 553 FALSE, /* pc_relative */
252b5132
RH
554 0, /* bitpos */
555 complain_overflow_dont, /* complain_on_overflow */
556 elf64_alpha_reloc_nil, /* special_function */
557 "LITUSE", /* name */
b34976b6 558 FALSE, /* partial_inplace */
252b5132
RH
559 0, /* src_mask */
560 0, /* dst_mask */
b34976b6 561 FALSE), /* pcrel_offset */
252b5132
RH
562
563 /* Load the gp register. This is always used for a ldah instruction
564 which loads the upper 16 bits of the gp register. The symbol
565 index of the GPDISP instruction is an offset in bytes to the lda
566 instruction that loads the lower 16 bits. The value to use for
567 the relocation is the difference between the GP value and the
568 current location; the load will always be done against a register
569 holding the current address.
570
571 NOTE: Unlike ECOFF, partial in-place relocation is not done. If
572 any offset is present in the instructions, it is an offset from
573 the register to the ldah instruction. This lets us avoid any
574 stupid hackery like inventing a gp value to do partial relocation
575 against. Also unlike ECOFF, we do the whole relocation off of
576 the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair. An odd,
577 space consuming bit, that, since all the information was present
578 in the GPDISP_HI16 reloc. */
579 HOWTO (R_ALPHA_GPDISP, /* type */
580 16, /* rightshift */
581 2, /* size (0 = byte, 1 = short, 2 = long) */
582 16, /* bitsize */
b34976b6 583 FALSE, /* pc_relative */
252b5132
RH
584 0, /* bitpos */
585 complain_overflow_dont, /* complain_on_overflow */
586 elf64_alpha_reloc_gpdisp, /* special_function */
587 "GPDISP", /* name */
b34976b6 588 FALSE, /* partial_inplace */
252b5132
RH
589 0xffff, /* src_mask */
590 0xffff, /* dst_mask */
b34976b6 591 TRUE), /* pcrel_offset */
252b5132
RH
592
593 /* A 21 bit branch. */
594 HOWTO (R_ALPHA_BRADDR, /* type */
595 2, /* rightshift */
596 2, /* size (0 = byte, 1 = short, 2 = long) */
597 21, /* bitsize */
b34976b6 598 TRUE, /* pc_relative */
252b5132
RH
599 0, /* bitpos */
600 complain_overflow_signed, /* complain_on_overflow */
601 0, /* special_function */
602 "BRADDR", /* name */
b34976b6 603 FALSE, /* partial_inplace */
252b5132
RH
604 0x1fffff, /* src_mask */
605 0x1fffff, /* dst_mask */
b34976b6 606 TRUE), /* pcrel_offset */
252b5132
RH
607
608 /* A hint for a jump to a register. */
609 HOWTO (R_ALPHA_HINT, /* type */
610 2, /* rightshift */
dfe57ca0 611 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132 612 14, /* bitsize */
b34976b6 613 TRUE, /* pc_relative */
252b5132
RH
614 0, /* bitpos */
615 complain_overflow_dont, /* complain_on_overflow */
616 0, /* special_function */
617 "HINT", /* name */
b34976b6 618 FALSE, /* partial_inplace */
252b5132
RH
619 0x3fff, /* src_mask */
620 0x3fff, /* dst_mask */
b34976b6 621 TRUE), /* pcrel_offset */
252b5132
RH
622
623 /* 16 bit PC relative offset. */
624 HOWTO (R_ALPHA_SREL16, /* type */
625 0, /* rightshift */
626 1, /* size (0 = byte, 1 = short, 2 = long) */
627 16, /* bitsize */
b34976b6 628 TRUE, /* pc_relative */
252b5132
RH
629 0, /* bitpos */
630 complain_overflow_signed, /* complain_on_overflow */
631 0, /* special_function */
632 "SREL16", /* name */
b34976b6 633 FALSE, /* partial_inplace */
252b5132
RH
634 0xffff, /* src_mask */
635 0xffff, /* dst_mask */
b34976b6 636 TRUE), /* pcrel_offset */
252b5132
RH
637
638 /* 32 bit PC relative offset. */
639 HOWTO (R_ALPHA_SREL32, /* type */
640 0, /* rightshift */
641 2, /* size (0 = byte, 1 = short, 2 = long) */
642 32, /* bitsize */
b34976b6 643 TRUE, /* pc_relative */
252b5132
RH
644 0, /* bitpos */
645 complain_overflow_signed, /* complain_on_overflow */
646 0, /* special_function */
647 "SREL32", /* name */
b34976b6 648 FALSE, /* partial_inplace */
252b5132
RH
649 0xffffffff, /* src_mask */
650 0xffffffff, /* dst_mask */
b34976b6 651 TRUE), /* pcrel_offset */
252b5132
RH
652
653 /* A 64 bit PC relative offset. */
654 HOWTO (R_ALPHA_SREL64, /* type */
655 0, /* rightshift */
656 4, /* size (0 = byte, 1 = short, 2 = long) */
657 64, /* bitsize */
b34976b6 658 TRUE, /* pc_relative */
252b5132
RH
659 0, /* bitpos */
660 complain_overflow_signed, /* complain_on_overflow */
661 0, /* special_function */
662 "SREL64", /* name */
b34976b6 663 FALSE, /* partial_inplace */
252b5132
RH
664 MINUS_ONE, /* src_mask */
665 MINUS_ONE, /* dst_mask */
b34976b6 666 TRUE), /* pcrel_offset */
252b5132 667
dfe57ca0
RH
668 /* Skip 12 - 16; deprecated ECOFF relocs. */
669 SKIP_HOWTO (12),
670 SKIP_HOWTO (13),
671 SKIP_HOWTO (14),
672 SKIP_HOWTO (15),
673 SKIP_HOWTO (16),
252b5132
RH
674
675 /* The high 16 bits of the displacement from GP to the target. */
676 HOWTO (R_ALPHA_GPRELHIGH,
677 0, /* rightshift */
dfe57ca0 678 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132 679 16, /* bitsize */
b34976b6 680 FALSE, /* pc_relative */
252b5132
RH
681 0, /* bitpos */
682 complain_overflow_signed, /* complain_on_overflow */
dfe57ca0 683 0, /* special_function */
252b5132 684 "GPRELHIGH", /* name */
b34976b6 685 FALSE, /* partial_inplace */
252b5132
RH
686 0xffff, /* src_mask */
687 0xffff, /* dst_mask */
b34976b6 688 FALSE), /* pcrel_offset */
252b5132
RH
689
690 /* The low 16 bits of the displacement from GP to the target. */
691 HOWTO (R_ALPHA_GPRELLOW,
692 0, /* rightshift */
dfe57ca0 693 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132 694 16, /* bitsize */
b34976b6 695 FALSE, /* pc_relative */
252b5132
RH
696 0, /* bitpos */
697 complain_overflow_dont, /* complain_on_overflow */
dfe57ca0 698 0, /* special_function */
252b5132 699 "GPRELLOW", /* name */
b34976b6 700 FALSE, /* partial_inplace */
252b5132
RH
701 0xffff, /* src_mask */
702 0xffff, /* dst_mask */
b34976b6 703 FALSE), /* pcrel_offset */
252b5132
RH
704
705 /* A 16-bit displacement from the GP to the target. */
dfe57ca0 706 HOWTO (R_ALPHA_GPREL16,
252b5132 707 0, /* rightshift */
dfe57ca0 708 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132 709 16, /* bitsize */
b34976b6 710 FALSE, /* pc_relative */
252b5132
RH
711 0, /* bitpos */
712 complain_overflow_signed, /* complain_on_overflow */
713 0, /* special_function */
dfe57ca0 714 "GPREL16", /* name */
b34976b6 715 FALSE, /* partial_inplace */
252b5132
RH
716 0xffff, /* src_mask */
717 0xffff, /* dst_mask */
b34976b6 718 FALSE), /* pcrel_offset */
252b5132 719
dfe57ca0
RH
720 /* Skip 20 - 23; deprecated ECOFF relocs. */
721 SKIP_HOWTO (20),
722 SKIP_HOWTO (21),
723 SKIP_HOWTO (22),
724 SKIP_HOWTO (23),
252b5132 725
fe8bc63d 726 /* Misc ELF relocations. */
252b5132
RH
727
728 /* A dynamic relocation to copy the target into our .dynbss section. */
729 /* Not generated, as all Alpha objects use PIC, so it is not needed. It
730 is present because every other ELF has one, but should not be used
731 because .dynbss is an ugly thing. */
732 HOWTO (R_ALPHA_COPY,
733 0,
734 0,
735 0,
b34976b6 736 FALSE,
252b5132
RH
737 0,
738 complain_overflow_dont,
739 bfd_elf_generic_reloc,
740 "COPY",
b34976b6 741 FALSE,
252b5132
RH
742 0,
743 0,
b34976b6 744 TRUE),
252b5132
RH
745
746 /* A dynamic relocation for a .got entry. */
747 HOWTO (R_ALPHA_GLOB_DAT,
748 0,
749 0,
750 0,
b34976b6 751 FALSE,
252b5132
RH
752 0,
753 complain_overflow_dont,
754 bfd_elf_generic_reloc,
755 "GLOB_DAT",
b34976b6 756 FALSE,
252b5132
RH
757 0,
758 0,
b34976b6 759 TRUE),
252b5132
RH
760
761 /* A dynamic relocation for a .plt entry. */
762 HOWTO (R_ALPHA_JMP_SLOT,
763 0,
764 0,
765 0,
b34976b6 766 FALSE,
252b5132
RH
767 0,
768 complain_overflow_dont,
769 bfd_elf_generic_reloc,
770 "JMP_SLOT",
b34976b6 771 FALSE,
252b5132
RH
772 0,
773 0,
b34976b6 774 TRUE),
252b5132
RH
775
776 /* A dynamic relocation to add the base of the DSO to a 64-bit field. */
777 HOWTO (R_ALPHA_RELATIVE,
778 0,
779 0,
780 0,
b34976b6 781 FALSE,
252b5132
RH
782 0,
783 complain_overflow_dont,
784 bfd_elf_generic_reloc,
785 "RELATIVE",
b34976b6 786 FALSE,
252b5132
RH
787 0,
788 0,
b34976b6 789 TRUE),
7793f4d0
RH
790
791 /* A 21 bit branch that adjusts for gp loads. */
792 HOWTO (R_ALPHA_BRSGP, /* type */
793 2, /* rightshift */
794 2, /* size (0 = byte, 1 = short, 2 = long) */
795 21, /* bitsize */
b34976b6 796 TRUE, /* pc_relative */
7793f4d0
RH
797 0, /* bitpos */
798 complain_overflow_signed, /* complain_on_overflow */
799 0, /* special_function */
800 "BRSGP", /* name */
b34976b6 801 FALSE, /* partial_inplace */
7793f4d0
RH
802 0x1fffff, /* src_mask */
803 0x1fffff, /* dst_mask */
b34976b6 804 TRUE), /* pcrel_offset */
3765b1be
RH
805
806 /* Creates a tls_index for the symbol in the got. */
807 HOWTO (R_ALPHA_TLSGD, /* type */
808 0, /* rightshift */
809 1, /* size (0 = byte, 1 = short, 2 = long) */
810 16, /* bitsize */
b34976b6 811 FALSE, /* pc_relative */
3765b1be
RH
812 0, /* bitpos */
813 complain_overflow_signed, /* complain_on_overflow */
814 0, /* special_function */
815 "TLSGD", /* name */
b34976b6 816 FALSE, /* partial_inplace */
3765b1be
RH
817 0xffff, /* src_mask */
818 0xffff, /* dst_mask */
b34976b6 819 FALSE), /* pcrel_offset */
3765b1be
RH
820
821 /* Creates a tls_index for the (current) module in the got. */
822 HOWTO (R_ALPHA_TLSLDM, /* type */
823 0, /* rightshift */
824 1, /* size (0 = byte, 1 = short, 2 = long) */
825 16, /* bitsize */
b34976b6 826 FALSE, /* pc_relative */
3765b1be
RH
827 0, /* bitpos */
828 complain_overflow_signed, /* complain_on_overflow */
829 0, /* special_function */
830 "TLSLDM", /* name */
b34976b6 831 FALSE, /* partial_inplace */
3765b1be
RH
832 0xffff, /* src_mask */
833 0xffff, /* dst_mask */
b34976b6 834 FALSE), /* pcrel_offset */
3765b1be
RH
835
836 /* A dynamic relocation for a DTP module entry. */
837 HOWTO (R_ALPHA_DTPMOD64, /* type */
838 0, /* rightshift */
839 4, /* size (0 = byte, 1 = short, 2 = long) */
840 64, /* bitsize */
b34976b6 841 FALSE, /* pc_relative */
3765b1be
RH
842 0, /* bitpos */
843 complain_overflow_bitfield, /* complain_on_overflow */
844 0, /* special_function */
845 "DTPMOD64", /* name */
b34976b6 846 FALSE, /* partial_inplace */
3765b1be
RH
847 MINUS_ONE, /* src_mask */
848 MINUS_ONE, /* dst_mask */
b34976b6 849 FALSE), /* pcrel_offset */
3765b1be
RH
850
851 /* Creates a 64-bit offset in the got for the displacement
852 from DTP to the target. */
853 HOWTO (R_ALPHA_GOTDTPREL, /* type */
854 0, /* rightshift */
855 1, /* size (0 = byte, 1 = short, 2 = long) */
856 16, /* bitsize */
b34976b6 857 FALSE, /* pc_relative */
3765b1be
RH
858 0, /* bitpos */
859 complain_overflow_signed, /* complain_on_overflow */
860 0, /* special_function */
861 "GOTDTPREL", /* name */
b34976b6 862 FALSE, /* partial_inplace */
3765b1be
RH
863 0xffff, /* src_mask */
864 0xffff, /* dst_mask */
b34976b6 865 FALSE), /* pcrel_offset */
3765b1be
RH
866
867 /* A dynamic relocation for a displacement from DTP to the target. */
868 HOWTO (R_ALPHA_DTPREL64, /* type */
869 0, /* rightshift */
870 4, /* size (0 = byte, 1 = short, 2 = long) */
871 64, /* bitsize */
b34976b6 872 FALSE, /* pc_relative */
3765b1be
RH
873 0, /* bitpos */
874 complain_overflow_bitfield, /* complain_on_overflow */
875 0, /* special_function */
876 "DTPREL64", /* name */
b34976b6 877 FALSE, /* partial_inplace */
3765b1be
RH
878 MINUS_ONE, /* src_mask */
879 MINUS_ONE, /* dst_mask */
b34976b6 880 FALSE), /* pcrel_offset */
3765b1be
RH
881
882 /* The high 16 bits of the displacement from DTP to the target. */
883 HOWTO (R_ALPHA_DTPRELHI, /* type */
884 0, /* rightshift */
885 1, /* size (0 = byte, 1 = short, 2 = long) */
886 16, /* bitsize */
b34976b6 887 FALSE, /* pc_relative */
3765b1be
RH
888 0, /* bitpos */
889 complain_overflow_signed, /* complain_on_overflow */
890 0, /* special_function */
891 "DTPRELHI", /* name */
b34976b6 892 FALSE, /* partial_inplace */
3765b1be
RH
893 0xffff, /* src_mask */
894 0xffff, /* dst_mask */
b34976b6 895 FALSE), /* pcrel_offset */
3765b1be
RH
896
897 /* The low 16 bits of the displacement from DTP to the target. */
898 HOWTO (R_ALPHA_DTPRELLO, /* type */
899 0, /* rightshift */
900 1, /* size (0 = byte, 1 = short, 2 = long) */
901 16, /* bitsize */
b34976b6 902 FALSE, /* pc_relative */
3765b1be
RH
903 0, /* bitpos */
904 complain_overflow_dont, /* complain_on_overflow */
905 0, /* special_function */
906 "DTPRELLO", /* name */
b34976b6 907 FALSE, /* partial_inplace */
3765b1be
RH
908 0xffff, /* src_mask */
909 0xffff, /* dst_mask */
b34976b6 910 FALSE), /* pcrel_offset */
3765b1be
RH
911
912 /* A 16-bit displacement from DTP to the target. */
913 HOWTO (R_ALPHA_DTPREL16, /* type */
914 0, /* rightshift */
915 1, /* size (0 = byte, 1 = short, 2 = long) */
916 16, /* bitsize */
b34976b6 917 FALSE, /* pc_relative */
3765b1be
RH
918 0, /* bitpos */
919 complain_overflow_signed, /* complain_on_overflow */
920 0, /* special_function */
921 "DTPREL16", /* name */
b34976b6 922 FALSE, /* partial_inplace */
3765b1be
RH
923 0xffff, /* src_mask */
924 0xffff, /* dst_mask */
b34976b6 925 FALSE), /* pcrel_offset */
3765b1be
RH
926
927 /* Creates a 64-bit offset in the got for the displacement
928 from TP to the target. */
929 HOWTO (R_ALPHA_GOTTPREL, /* type */
930 0, /* rightshift */
931 1, /* size (0 = byte, 1 = short, 2 = long) */
932 16, /* bitsize */
b34976b6 933 FALSE, /* pc_relative */
3765b1be
RH
934 0, /* bitpos */
935 complain_overflow_signed, /* complain_on_overflow */
936 0, /* special_function */
937 "GOTTPREL", /* name */
b34976b6 938 FALSE, /* partial_inplace */
3765b1be
RH
939 0xffff, /* src_mask */
940 0xffff, /* dst_mask */
b34976b6 941 FALSE), /* pcrel_offset */
3765b1be
RH
942
943 /* A dynamic relocation for a displacement from TP to the target. */
944 HOWTO (R_ALPHA_TPREL64, /* type */
945 0, /* rightshift */
946 4, /* size (0 = byte, 1 = short, 2 = long) */
947 64, /* bitsize */
b34976b6 948 FALSE, /* pc_relative */
3765b1be
RH
949 0, /* bitpos */
950 complain_overflow_bitfield, /* complain_on_overflow */
951 0, /* special_function */
952 "TPREL64", /* name */
b34976b6 953 FALSE, /* partial_inplace */
3765b1be
RH
954 MINUS_ONE, /* src_mask */
955 MINUS_ONE, /* dst_mask */
b34976b6 956 FALSE), /* pcrel_offset */
3765b1be
RH
957
958 /* The high 16 bits of the displacement from TP to the target. */
959 HOWTO (R_ALPHA_TPRELHI, /* type */
960 0, /* rightshift */
961 1, /* size (0 = byte, 1 = short, 2 = long) */
962 16, /* bitsize */
b34976b6 963 FALSE, /* pc_relative */
3765b1be
RH
964 0, /* bitpos */
965 complain_overflow_signed, /* complain_on_overflow */
966 0, /* special_function */
967 "TPRELHI", /* name */
b34976b6 968 FALSE, /* partial_inplace */
3765b1be
RH
969 0xffff, /* src_mask */
970 0xffff, /* dst_mask */
b34976b6 971 FALSE), /* pcrel_offset */
3765b1be
RH
972
973 /* The low 16 bits of the displacement from TP to the target. */
974 HOWTO (R_ALPHA_TPRELLO, /* type */
975 0, /* rightshift */
976 1, /* size (0 = byte, 1 = short, 2 = long) */
977 16, /* bitsize */
b34976b6 978 FALSE, /* pc_relative */
3765b1be
RH
979 0, /* bitpos */
980 complain_overflow_dont, /* complain_on_overflow */
981 0, /* special_function */
982 "TPRELLO", /* name */
b34976b6 983 FALSE, /* partial_inplace */
3765b1be
RH
984 0xffff, /* src_mask */
985 0xffff, /* dst_mask */
b34976b6 986 FALSE), /* pcrel_offset */
3765b1be
RH
987
988 /* A 16-bit displacement from TP to the target. */
989 HOWTO (R_ALPHA_TPREL16, /* type */
990 0, /* rightshift */
991 1, /* size (0 = byte, 1 = short, 2 = long) */
992 16, /* bitsize */
b34976b6 993 FALSE, /* pc_relative */
3765b1be
RH
994 0, /* bitpos */
995 complain_overflow_signed, /* complain_on_overflow */
996 0, /* special_function */
997 "TPREL16", /* name */
b34976b6 998 FALSE, /* partial_inplace */
3765b1be
RH
999 0xffff, /* src_mask */
1000 0xffff, /* dst_mask */
b34976b6 1001 FALSE), /* pcrel_offset */
252b5132
RH
1002};
1003
252b5132
RH
1004/* A mapping from BFD reloc types to Alpha ELF reloc types. */
1005
1006struct elf_reloc_map
1007{
1008 bfd_reloc_code_real_type bfd_reloc_val;
1009 int elf_reloc_val;
1010};
1011
1012static const struct elf_reloc_map elf64_alpha_reloc_map[] =
1013{
dfe57ca0
RH
1014 {BFD_RELOC_NONE, R_ALPHA_NONE},
1015 {BFD_RELOC_32, R_ALPHA_REFLONG},
1016 {BFD_RELOC_64, R_ALPHA_REFQUAD},
1017 {BFD_RELOC_CTOR, R_ALPHA_REFQUAD},
1018 {BFD_RELOC_GPREL32, R_ALPHA_GPREL32},
1019 {BFD_RELOC_ALPHA_ELF_LITERAL, R_ALPHA_LITERAL},
1020 {BFD_RELOC_ALPHA_LITUSE, R_ALPHA_LITUSE},
1021 {BFD_RELOC_ALPHA_GPDISP, R_ALPHA_GPDISP},
1022 {BFD_RELOC_23_PCREL_S2, R_ALPHA_BRADDR},
1023 {BFD_RELOC_ALPHA_HINT, R_ALPHA_HINT},
1024 {BFD_RELOC_16_PCREL, R_ALPHA_SREL16},
1025 {BFD_RELOC_32_PCREL, R_ALPHA_SREL32},
1026 {BFD_RELOC_64_PCREL, R_ALPHA_SREL64},
1027 {BFD_RELOC_ALPHA_GPREL_HI16, R_ALPHA_GPRELHIGH},
1028 {BFD_RELOC_ALPHA_GPREL_LO16, R_ALPHA_GPRELLOW},
1029 {BFD_RELOC_GPREL16, R_ALPHA_GPREL16},
7793f4d0 1030 {BFD_RELOC_ALPHA_BRSGP, R_ALPHA_BRSGP},
3765b1be
RH
1031 {BFD_RELOC_ALPHA_TLSGD, R_ALPHA_TLSGD},
1032 {BFD_RELOC_ALPHA_TLSLDM, R_ALPHA_TLSLDM},
1033 {BFD_RELOC_ALPHA_DTPMOD64, R_ALPHA_DTPMOD64},
1034 {BFD_RELOC_ALPHA_GOTDTPREL16, R_ALPHA_GOTDTPREL},
1035 {BFD_RELOC_ALPHA_DTPREL64, R_ALPHA_DTPREL64},
1036 {BFD_RELOC_ALPHA_DTPREL_HI16, R_ALPHA_DTPRELHI},
1037 {BFD_RELOC_ALPHA_DTPREL_LO16, R_ALPHA_DTPRELLO},
1038 {BFD_RELOC_ALPHA_DTPREL16, R_ALPHA_DTPREL16},
1039 {BFD_RELOC_ALPHA_GOTTPREL16, R_ALPHA_GOTTPREL},
1040 {BFD_RELOC_ALPHA_TPREL64, R_ALPHA_TPREL64},
1041 {BFD_RELOC_ALPHA_TPREL_HI16, R_ALPHA_TPRELHI},
1042 {BFD_RELOC_ALPHA_TPREL_LO16, R_ALPHA_TPRELLO},
1043 {BFD_RELOC_ALPHA_TPREL16, R_ALPHA_TPREL16},
252b5132
RH
1044};
1045
1046/* Given a BFD reloc type, return a HOWTO structure. */
1047
1048static reloc_howto_type *
a7519a3c
RH
1049elf64_alpha_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1050 bfd_reloc_code_real_type code)
252b5132
RH
1051{
1052 const struct elf_reloc_map *i, *e;
1053 i = e = elf64_alpha_reloc_map;
1054 e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map);
1055 for (; i != e; ++i)
1056 {
1057 if (i->bfd_reloc_val == code)
1058 return &elf64_alpha_howto_table[i->elf_reloc_val];
1059 }
1060 return 0;
1061}
1062
157090f7
AM
1063static reloc_howto_type *
1064elf64_alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1065 const char *r_name)
1066{
1067 unsigned int i;
1068
1069 for (i = 0;
1070 i < (sizeof (elf64_alpha_howto_table)
1071 / sizeof (elf64_alpha_howto_table[0]));
1072 i++)
1073 if (elf64_alpha_howto_table[i].name != NULL
1074 && strcasecmp (elf64_alpha_howto_table[i].name, r_name) == 0)
1075 return &elf64_alpha_howto_table[i];
1076
1077 return NULL;
1078}
1079
252b5132
RH
1080/* Given an Alpha ELF reloc type, fill in an arelent structure. */
1081
1082static void
a7519a3c
RH
1083elf64_alpha_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
1084 Elf_Internal_Rela *dst)
252b5132 1085{
a7519a3c 1086 unsigned r_type = ELF64_R_TYPE(dst->r_info);
252b5132
RH
1087 BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max);
1088 cache_ptr->howto = &elf64_alpha_howto_table[r_type];
1089}
3765b1be
RH
1090
1091/* These two relocations create a two-word entry in the got. */
1092#define alpha_got_entry_size(r_type) \
1093 (r_type == R_ALPHA_TLSGD || r_type == R_ALPHA_TLSLDM ? 16 : 8)
9e756d64
RH
1094
1095/* This is PT_TLS segment p_vaddr. */
e1918d23
AM
1096#define alpha_get_dtprel_base(info) \
1097 (elf_hash_table (info)->tls_sec->vma)
9e756d64
RH
1098
1099/* Main program TLS (whose template starts at PT_TLS p_vaddr)
1100 is assigned offset round(16, PT_TLS p_align). */
e1918d23
AM
1101#define alpha_get_tprel_base(info) \
1102 (elf_hash_table (info)->tls_sec->vma \
1103 - align_power ((bfd_vma) 16, \
1104 elf_hash_table (info)->tls_sec->alignment_power))
252b5132 1105\f
a7519a3c
RH
1106/* Handle an Alpha specific section when reading an object file. This
1107 is called when bfd_section_from_shdr finds a section with an unknown
1108 type.
1109 FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure
1110 how to. */
252b5132 1111
a7519a3c
RH
1112static bfd_boolean
1113elf64_alpha_section_from_shdr (bfd *abfd,
1114 Elf_Internal_Shdr *hdr,
1115 const char *name,
1116 int shindex)
252b5132 1117{
a7519a3c
RH
1118 asection *newsect;
1119
1120 /* There ought to be a place to keep ELF backend specific flags, but
1121 at the moment there isn't one. We just keep track of the
1122 sections by their name, instead. Fortunately, the ABI gives
1123 suggested names for all the MIPS specific sections, so we will
1124 probably get away with this. */
1125 switch (hdr->sh_type)
1126 {
1127 case SHT_ALPHA_DEBUG:
1128 if (strcmp (name, ".mdebug") != 0)
1129 return FALSE;
1130 break;
1131 default:
1132 return FALSE;
1133 }
252b5132 1134
a7519a3c
RH
1135 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
1136 return FALSE;
1137 newsect = hdr->bfd_section;
252b5132 1138
a7519a3c 1139 if (hdr->sh_type == SHT_ALPHA_DEBUG)
252b5132 1140 {
a7519a3c
RH
1141 if (! bfd_set_section_flags (abfd, newsect,
1142 (bfd_get_section_flags (abfd, newsect)
1143 | SEC_DEBUGGING)))
1144 return FALSE;
252b5132 1145 }
a7519a3c
RH
1146
1147 return TRUE;
252b5132
RH
1148}
1149
a7519a3c
RH
1150/* Convert Alpha specific section flags to bfd internal section flags. */
1151
b34976b6 1152static bfd_boolean
a7519a3c 1153elf64_alpha_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
252b5132 1154{
a7519a3c
RH
1155 if (hdr->sh_flags & SHF_ALPHA_GPREL)
1156 *flags |= SEC_SMALL_DATA;
252b5132 1157
a7519a3c
RH
1158 return TRUE;
1159}
252b5132 1160
a7519a3c
RH
1161/* Set the correct type for an Alpha ELF section. We do this by the
1162 section name, which is a hack, but ought to work. */
9e756d64 1163
a7519a3c
RH
1164static bfd_boolean
1165elf64_alpha_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
1166{
1167 register const char *name;
1168
1169 name = bfd_get_section_name (abfd, sec);
1170
1171 if (strcmp (name, ".mdebug") == 0)
252b5132 1172 {
a7519a3c
RH
1173 hdr->sh_type = SHT_ALPHA_DEBUG;
1174 /* In a shared object on Irix 5.3, the .mdebug section has an
1175 entsize of 0. FIXME: Does this matter? */
1176 if ((abfd->flags & DYNAMIC) != 0 )
1177 hdr->sh_entsize = 0;
1178 else
1179 hdr->sh_entsize = 1;
252b5132 1180 }
a7519a3c
RH
1181 else if ((sec->flags & SEC_SMALL_DATA)
1182 || strcmp (name, ".sdata") == 0
1183 || strcmp (name, ".sbss") == 0
1184 || strcmp (name, ".lit4") == 0
1185 || strcmp (name, ".lit8") == 0)
1186 hdr->sh_flags |= SHF_ALPHA_GPREL;
252b5132 1187
a7519a3c
RH
1188 return TRUE;
1189}
252b5132 1190
a7519a3c
RH
1191/* Hook called by the linker routine which adds symbols from an object
1192 file. We use it to put .comm items in .sbss, and not .bss. */
1193
1194static bfd_boolean
1195elf64_alpha_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
1196 Elf_Internal_Sym *sym,
1197 const char **namep ATTRIBUTE_UNUSED,
1198 flagword *flagsp ATTRIBUTE_UNUSED,
1199 asection **secp, bfd_vma *valp)
1200{
1201 if (sym->st_shndx == SHN_COMMON
1202 && !info->relocatable
1203 && sym->st_size <= elf_gp_size (abfd))
252b5132 1204 {
a7519a3c
RH
1205 /* Common symbols less than or equal to -G nn bytes are
1206 automatically put into .sbss. */
ffcb7aff 1207
a7519a3c 1208 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
252b5132 1209
a7519a3c 1210 if (scomm == NULL)
252b5132 1211 {
a7519a3c
RH
1212 scomm = bfd_make_section_with_flags (abfd, ".scommon",
1213 (SEC_ALLOC
1214 | SEC_IS_COMMON
1215 | SEC_LINKER_CREATED));
1216 if (scomm == NULL)
1217 return FALSE;
1218 }
ffcb7aff 1219
a7519a3c
RH
1220 *secp = scomm;
1221 *valp = sym->st_size;
1222 }
ffcb7aff 1223
a7519a3c
RH
1224 return TRUE;
1225}
252b5132 1226
a7519a3c 1227/* Create the .got section. */
252b5132 1228
a7519a3c
RH
1229static bfd_boolean
1230elf64_alpha_create_got_section (bfd *abfd,
1231 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1232{
85d162e6 1233 flagword flags;
a7519a3c 1234 asection *s;
252b5132 1235
0ffa91dd
NC
1236 if (! is_alpha_elf (abfd))
1237 return FALSE;
1238
85d162e6
AM
1239 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1240 | SEC_LINKER_CREATED);
1241 s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
a7519a3c
RH
1242 if (s == NULL
1243 || !bfd_set_section_alignment (abfd, s, 3))
1244 return FALSE;
252b5132 1245
a7519a3c 1246 alpha_elf_tdata (abfd)->got = s;
252b5132 1247
85d162e6
AM
1248 /* Make sure the object's gotobj is set to itself so that we default
1249 to every object with its own .got. We'll merge .gots later once
1250 we've collected each object's info. */
1251 alpha_elf_tdata (abfd)->gotobj = abfd;
1252
a7519a3c
RH
1253 return TRUE;
1254}
252b5132 1255
a7519a3c 1256/* Create all the dynamic sections. */
252b5132 1257
a7519a3c
RH
1258static bfd_boolean
1259elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
1260{
1261 asection *s;
85d162e6 1262 flagword flags;
a7519a3c 1263 struct elf_link_hash_entry *h;
252b5132 1264
0ffa91dd
NC
1265 if (! is_alpha_elf (abfd))
1266 return FALSE;
1267
a7519a3c 1268 /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */
252b5132 1269
85d162e6
AM
1270 flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1271 | SEC_LINKER_CREATED
1272 | (elf64_alpha_use_secureplt ? SEC_READONLY : 0));
1273 s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags);
6ec7057a 1274 if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4))
a7519a3c 1275 return FALSE;
252b5132 1276
a7519a3c
RH
1277 /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
1278 .plt section. */
7325306f
RS
1279 h = _bfd_elf_define_linkage_sym (abfd, info, s,
1280 "_PROCEDURE_LINKAGE_TABLE_");
1281 elf_hash_table (info)->hplt = h;
1282 if (h == NULL)
a7519a3c 1283 return FALSE;
d6ad34f6 1284
85d162e6
AM
1285 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1286 | SEC_LINKER_CREATED | SEC_READONLY);
1287 s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags);
6ec7057a 1288 if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
a7519a3c 1289 return FALSE;
252b5132 1290
6ec7057a
RH
1291 if (elf64_alpha_use_secureplt)
1292 {
85d162e6
AM
1293 flags = SEC_ALLOC | SEC_LINKER_CREATED;
1294 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
6ec7057a
RH
1295 if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
1296 return FALSE;
1297 }
1298
a7519a3c
RH
1299 /* We may or may not have created a .got section for this object, but
1300 we definitely havn't done the rest of the work. */
1cd6895c 1301
85d162e6
AM
1302 if (alpha_elf_tdata(abfd)->gotobj == NULL)
1303 {
1304 if (!elf64_alpha_create_got_section (abfd, info))
1305 return FALSE;
1306 }
1cd6895c 1307
85d162e6
AM
1308 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1309 | SEC_LINKER_CREATED | SEC_READONLY);
1310 s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags);
a7519a3c
RH
1311 if (s == NULL
1312 || !bfd_set_section_alignment (abfd, s, 3))
1313 return FALSE;
252b5132 1314
a7519a3c
RH
1315 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
1316 dynobj's .got section. We don't do this in the linker script
1317 because we don't want to define the symbol if we are not creating
1318 a global offset table. */
d98685ac
AM
1319 h = _bfd_elf_define_linkage_sym (abfd, info, alpha_elf_tdata(abfd)->got,
1320 "_GLOBAL_OFFSET_TABLE_");
a7519a3c 1321 elf_hash_table (info)->hgot = h;
d98685ac
AM
1322 if (h == NULL)
1323 return FALSE;
252b5132 1324
a7519a3c 1325 return TRUE;
252b5132 1326}
a7519a3c
RH
1327\f
1328/* Read ECOFF debugging information from a .mdebug section into a
1329 ecoff_debug_info structure. */
252b5132 1330
a7519a3c
RH
1331static bfd_boolean
1332elf64_alpha_read_ecoff_info (bfd *abfd, asection *section,
1333 struct ecoff_debug_info *debug)
252b5132 1334{
a7519a3c
RH
1335 HDRR *symhdr;
1336 const struct ecoff_debug_swap *swap;
1337 char *ext_hdr = NULL;
252b5132 1338
a7519a3c
RH
1339 swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
1340 memset (debug, 0, sizeof (*debug));
252b5132 1341
a7519a3c
RH
1342 ext_hdr = (char *) bfd_malloc (swap->external_hdr_size);
1343 if (ext_hdr == NULL && swap->external_hdr_size != 0)
1344 goto error_return;
252b5132 1345
a7519a3c
RH
1346 if (! bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
1347 swap->external_hdr_size))
1348 goto error_return;
252b5132 1349
a7519a3c
RH
1350 symhdr = &debug->symbolic_header;
1351 (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);
252b5132 1352
a7519a3c
RH
1353 /* The symbolic header contains absolute file offsets and sizes to
1354 read. */
1355#define READ(ptr, offset, count, size, type) \
1356 if (symhdr->count == 0) \
1357 debug->ptr = NULL; \
1358 else \
1359 { \
1360 bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
1361 debug->ptr = (type) bfd_malloc (amt); \
1362 if (debug->ptr == NULL) \
1363 goto error_return; \
1364 if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
1365 || bfd_bread (debug->ptr, amt, abfd) != amt) \
1366 goto error_return; \
1367 }
fe8bc63d 1368
a7519a3c
RH
1369 READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
1370 READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
1371 READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
1372 READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
1373 READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
1374 READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
1375 union aux_ext *);
1376 READ (ss, cbSsOffset, issMax, sizeof (char), char *);
1377 READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
1378 READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
1379 READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
1380 READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
1381#undef READ
252b5132 1382
a7519a3c 1383 debug->fdr = NULL;
252b5132 1384
a7519a3c 1385 return TRUE;
252b5132 1386
a7519a3c
RH
1387 error_return:
1388 if (ext_hdr != NULL)
1389 free (ext_hdr);
1390 if (debug->line != NULL)
1391 free (debug->line);
1392 if (debug->external_dnr != NULL)
1393 free (debug->external_dnr);
1394 if (debug->external_pdr != NULL)
1395 free (debug->external_pdr);
1396 if (debug->external_sym != NULL)
1397 free (debug->external_sym);
1398 if (debug->external_opt != NULL)
1399 free (debug->external_opt);
1400 if (debug->external_aux != NULL)
1401 free (debug->external_aux);
1402 if (debug->ss != NULL)
1403 free (debug->ss);
1404 if (debug->ssext != NULL)
1405 free (debug->ssext);
1406 if (debug->external_fdr != NULL)
1407 free (debug->external_fdr);
1408 if (debug->external_rfd != NULL)
1409 free (debug->external_rfd);
1410 if (debug->external_ext != NULL)
1411 free (debug->external_ext);
1412 return FALSE;
252b5132
RH
1413}
1414
a7519a3c
RH
1415/* Alpha ELF local labels start with '$'. */
1416
b34976b6 1417static bfd_boolean
a7519a3c 1418elf64_alpha_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
252b5132 1419{
a7519a3c
RH
1420 return name[0] == '$';
1421}
9e756d64 1422
a7519a3c
RH
1423/* Alpha ELF follows MIPS ELF in using a special find_nearest_line
1424 routine in order to handle the ECOFF debugging information. We
1425 still call this mips_elf_find_line because of the slot
1426 find_line_info in elf_obj_tdata is declared that way. */
d6ad34f6 1427
a7519a3c
RH
1428struct mips_elf_find_line
1429{
1430 struct ecoff_debug_info d;
1431 struct ecoff_find_line i;
1432};
d6ad34f6 1433
a7519a3c
RH
1434static bfd_boolean
1435elf64_alpha_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols,
1436 bfd_vma offset, const char **filename_ptr,
1437 const char **functionname_ptr,
1438 unsigned int *line_ptr)
1439{
1440 asection *msec;
252b5132 1441
a7519a3c
RH
1442 if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
1443 filename_ptr, functionname_ptr,
1444 line_ptr, 0,
1445 &elf_tdata (abfd)->dwarf2_find_line_info))
b34976b6 1446 return TRUE;
9e756d64 1447
a7519a3c
RH
1448 msec = bfd_get_section_by_name (abfd, ".mdebug");
1449 if (msec != NULL)
1bbc9cec 1450 {
a7519a3c
RH
1451 flagword origflags;
1452 struct mips_elf_find_line *fi;
1453 const struct ecoff_debug_swap * const swap =
1454 get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
252b5132 1455
a7519a3c
RH
1456 /* If we are called during a link, alpha_elf_final_link may have
1457 cleared the SEC_HAS_CONTENTS field. We force it back on here
1458 if appropriate (which it normally will be). */
1459 origflags = msec->flags;
1460 if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
1461 msec->flags |= SEC_HAS_CONTENTS;
9e756d64 1462
a7519a3c
RH
1463 fi = elf_tdata (abfd)->find_line_info;
1464 if (fi == NULL)
1465 {
1466 bfd_size_type external_fdr_size;
1467 char *fraw_src;
1468 char *fraw_end;
1469 struct fdr *fdr_ptr;
1470 bfd_size_type amt = sizeof (struct mips_elf_find_line);
9e756d64 1471
a7519a3c
RH
1472 fi = (struct mips_elf_find_line *) bfd_zalloc (abfd, amt);
1473 if (fi == NULL)
1474 {
1475 msec->flags = origflags;
1476 return FALSE;
1477 }
9e756d64 1478
a7519a3c
RH
1479 if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d))
1480 {
1481 msec->flags = origflags;
1482 return FALSE;
1483 }
9e756d64 1484
a7519a3c
RH
1485 /* Swap in the FDR information. */
1486 amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
1487 fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt);
1488 if (fi->d.fdr == NULL)
1489 {
1490 msec->flags = origflags;
1491 return FALSE;
1492 }
1493 external_fdr_size = swap->external_fdr_size;
1494 fdr_ptr = fi->d.fdr;
1495 fraw_src = (char *) fi->d.external_fdr;
1496 fraw_end = (fraw_src
1497 + fi->d.symbolic_header.ifdMax * external_fdr_size);
1498 for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
1499 (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
9e756d64 1500
a7519a3c 1501 elf_tdata (abfd)->find_line_info = fi;
9e756d64 1502
a7519a3c
RH
1503 /* Note that we don't bother to ever free this information.
1504 find_nearest_line is either called all the time, as in
1505 objdump -l, so the information should be saved, or it is
1506 rarely called, as in ld error messages, so the memory
1507 wasted is unimportant. Still, it would probably be a
1508 good idea for free_cached_info to throw it away. */
1509 }
9e756d64 1510
a7519a3c
RH
1511 if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap,
1512 &fi->i, filename_ptr, functionname_ptr,
1513 line_ptr))
1514 {
1515 msec->flags = origflags;
1516 return TRUE;
1517 }
9e756d64 1518
a7519a3c 1519 msec->flags = origflags;
9e756d64 1520 }
9e756d64 1521
a7519a3c 1522 /* Fall back on the generic ELF find_nearest_line routine. */
9e756d64 1523
a7519a3c
RH
1524 return _bfd_elf_find_nearest_line (abfd, section, symbols, offset,
1525 filename_ptr, functionname_ptr,
1526 line_ptr);
9e756d64 1527}
a7519a3c
RH
1528\f
1529/* Structure used to pass information to alpha_elf_output_extsym. */
9e756d64 1530
a7519a3c 1531struct extsym_info
9e756d64 1532{
a7519a3c
RH
1533 bfd *abfd;
1534 struct bfd_link_info *info;
1535 struct ecoff_debug_info *debug;
1536 const struct ecoff_debug_swap *swap;
1537 bfd_boolean failed;
1538};
9e756d64 1539
a7519a3c
RH
1540static bfd_boolean
1541elf64_alpha_output_extsym (struct alpha_elf_link_hash_entry *h, PTR data)
1542{
1543 struct extsym_info *einfo = (struct extsym_info *) data;
1544 bfd_boolean strip;
1545 asection *sec, *output_section;
9e756d64 1546
a7519a3c
RH
1547 if (h->root.root.type == bfd_link_hash_warning)
1548 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
9e756d64 1549
a7519a3c
RH
1550 if (h->root.indx == -2)
1551 strip = FALSE;
1552 else if ((h->root.def_dynamic
1553 || h->root.ref_dynamic
1554 || h->root.root.type == bfd_link_hash_new)
1555 && !h->root.def_regular
1556 && !h->root.ref_regular)
1557 strip = TRUE;
1558 else if (einfo->info->strip == strip_all
1559 || (einfo->info->strip == strip_some
1560 && bfd_hash_lookup (einfo->info->keep_hash,
1561 h->root.root.root.string,
1562 FALSE, FALSE) == NULL))
1563 strip = TRUE;
1564 else
1565 strip = FALSE;
9e756d64 1566
a7519a3c 1567 if (strip)
b34976b6 1568 return TRUE;
9e756d64 1569
a7519a3c 1570 if (h->esym.ifd == -2)
9e756d64 1571 {
a7519a3c
RH
1572 h->esym.jmptbl = 0;
1573 h->esym.cobol_main = 0;
1574 h->esym.weakext = 0;
1575 h->esym.reserved = 0;
1576 h->esym.ifd = ifdNil;
1577 h->esym.asym.value = 0;
1578 h->esym.asym.st = stGlobal;
9e756d64 1579
a7519a3c
RH
1580 if (h->root.root.type != bfd_link_hash_defined
1581 && h->root.root.type != bfd_link_hash_defweak)
1582 h->esym.asym.sc = scAbs;
1583 else
1584 {
1585 const char *name;
9e756d64 1586
a7519a3c
RH
1587 sec = h->root.root.u.def.section;
1588 output_section = sec->output_section;
9e756d64 1589
a7519a3c
RH
1590 /* When making a shared library and symbol h is the one from
1591 the another shared library, OUTPUT_SECTION may be null. */
1592 if (output_section == NULL)
1593 h->esym.asym.sc = scUndefined;
1594 else
1595 {
1596 name = bfd_section_name (output_section->owner, output_section);
9e756d64 1597
a7519a3c
RH
1598 if (strcmp (name, ".text") == 0)
1599 h->esym.asym.sc = scText;
1600 else if (strcmp (name, ".data") == 0)
1601 h->esym.asym.sc = scData;
1602 else if (strcmp (name, ".sdata") == 0)
1603 h->esym.asym.sc = scSData;
1604 else if (strcmp (name, ".rodata") == 0
1605 || strcmp (name, ".rdata") == 0)
1606 h->esym.asym.sc = scRData;
1607 else if (strcmp (name, ".bss") == 0)
1608 h->esym.asym.sc = scBss;
1609 else if (strcmp (name, ".sbss") == 0)
1610 h->esym.asym.sc = scSBss;
1611 else if (strcmp (name, ".init") == 0)
1612 h->esym.asym.sc = scInit;
1613 else if (strcmp (name, ".fini") == 0)
1614 h->esym.asym.sc = scFini;
1615 else
1616 h->esym.asym.sc = scAbs;
1617 }
1618 }
9e756d64 1619
a7519a3c
RH
1620 h->esym.asym.reserved = 0;
1621 h->esym.asym.index = indexNil;
1622 }
9e756d64 1623
a7519a3c
RH
1624 if (h->root.root.type == bfd_link_hash_common)
1625 h->esym.asym.value = h->root.root.u.c.size;
1626 else if (h->root.root.type == bfd_link_hash_defined
1627 || h->root.root.type == bfd_link_hash_defweak)
1628 {
1629 if (h->esym.asym.sc == scCommon)
1630 h->esym.asym.sc = scBss;
1631 else if (h->esym.asym.sc == scSCommon)
1632 h->esym.asym.sc = scSBss;
9e756d64 1633
a7519a3c
RH
1634 sec = h->root.root.u.def.section;
1635 output_section = sec->output_section;
1636 if (output_section != NULL)
1637 h->esym.asym.value = (h->root.root.u.def.value
1638 + sec->output_offset
1639 + output_section->vma);
1640 else
1641 h->esym.asym.value = 0;
1642 }
9e756d64 1643
a7519a3c
RH
1644 if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
1645 h->root.root.root.string,
1646 &h->esym))
1647 {
1648 einfo->failed = TRUE;
1649 return FALSE;
9e756d64
RH
1650 }
1651
a7519a3c
RH
1652 return TRUE;
1653}
1654\f
1655/* Search for and possibly create a got entry. */
9e756d64 1656
a7519a3c
RH
1657static struct alpha_elf_got_entry *
1658get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h,
1659 unsigned long r_type, unsigned long r_symndx,
1660 bfd_vma r_addend)
1661{
1662 struct alpha_elf_got_entry *gotent;
1663 struct alpha_elf_got_entry **slot;
9e756d64 1664
a7519a3c
RH
1665 if (h)
1666 slot = &h->got_entries;
1667 else
1668 {
1669 /* This is a local .got entry -- record for merge. */
9e756d64 1670
a7519a3c 1671 struct alpha_elf_got_entry **local_got_entries;
9e756d64 1672
a7519a3c
RH
1673 local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
1674 if (!local_got_entries)
1675 {
1676 bfd_size_type size;
1677 Elf_Internal_Shdr *symtab_hdr;
9e756d64 1678
a7519a3c
RH
1679 symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
1680 size = symtab_hdr->sh_info;
1681 size *= sizeof (struct alpha_elf_got_entry *);
9e756d64 1682
a7519a3c
RH
1683 local_got_entries
1684 = (struct alpha_elf_got_entry **) bfd_zalloc (abfd, size);
1685 if (!local_got_entries)
1686 return NULL;
1687
1688 alpha_elf_tdata (abfd)->local_got_entries = local_got_entries;
1689 }
1690
1691 slot = &local_got_entries[r_symndx];
9e756d64
RH
1692 }
1693
a7519a3c
RH
1694 for (gotent = *slot; gotent ; gotent = gotent->next)
1695 if (gotent->gotobj == abfd
1696 && gotent->reloc_type == r_type
1697 && gotent->addend == r_addend)
1698 break;
1699
1700 if (!gotent)
9e756d64 1701 {
a7519a3c
RH
1702 int entry_size;
1703 bfd_size_type amt;
9e756d64 1704
a7519a3c
RH
1705 amt = sizeof (struct alpha_elf_got_entry);
1706 gotent = (struct alpha_elf_got_entry *) bfd_alloc (abfd, amt);
1707 if (!gotent)
1708 return NULL;
9e756d64 1709
a7519a3c
RH
1710 gotent->gotobj = abfd;
1711 gotent->addend = r_addend;
1712 gotent->got_offset = -1;
6ec7057a 1713 gotent->plt_offset = -1;
a7519a3c
RH
1714 gotent->use_count = 1;
1715 gotent->reloc_type = r_type;
1716 gotent->reloc_done = 0;
1717 gotent->reloc_xlated = 0;
9e756d64 1718
a7519a3c
RH
1719 gotent->next = *slot;
1720 *slot = gotent;
9e756d64 1721
a7519a3c
RH
1722 entry_size = alpha_got_entry_size (r_type);
1723 alpha_elf_tdata (abfd)->total_got_size += entry_size;
1724 if (!h)
1725 alpha_elf_tdata(abfd)->local_got_size += entry_size;
9e756d64 1726 }
a7519a3c
RH
1727 else
1728 gotent->use_count += 1;
9e756d64 1729
a7519a3c 1730 return gotent;
9e756d64
RH
1731}
1732
6ec7057a
RH
1733static bfd_boolean
1734elf64_alpha_want_plt (struct alpha_elf_link_hash_entry *ah)
1735{
1736 return ((ah->root.type == STT_FUNC
1737 || ah->root.root.type == bfd_link_hash_undefweak
1738 || ah->root.root.type == bfd_link_hash_undefined)
8288a39e
RH
1739 && (ah->flags & ALPHA_ELF_LINK_HASH_LU_PLT) != 0
1740 && (ah->flags & ~ALPHA_ELF_LINK_HASH_LU_PLT) == 0);
6ec7057a
RH
1741}
1742
a7519a3c
RH
1743/* Handle dynamic relocations when doing an Alpha ELF link. */
1744
b34976b6 1745static bfd_boolean
a7519a3c
RH
1746elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
1747 asection *sec, const Elf_Internal_Rela *relocs)
252b5132 1748{
a7519a3c
RH
1749 bfd *dynobj;
1750 asection *sreloc;
1751 const char *rel_sec_name;
252b5132 1752 Elf_Internal_Shdr *symtab_hdr;
a7519a3c
RH
1753 struct alpha_elf_link_hash_entry **sym_hashes;
1754 const Elf_Internal_Rela *rel, *relend;
a7519a3c 1755 bfd_size_type amt;
252b5132 1756
a7519a3c
RH
1757 if (info->relocatable)
1758 return TRUE;
252b5132 1759
a7519a3c
RH
1760 /* Don't do anything special with non-loaded, non-alloced sections.
1761 In particular, any relocs in such sections should not affect GOT
1762 and PLT reference counting (ie. we don't allow them to create GOT
1763 or PLT entries), there's no possibility or desire to optimize TLS
1764 relocs, and there's not much point in propagating relocs to shared
1765 libs that the dynamic linker won't relocate. */
1766 if ((sec->flags & SEC_ALLOC) == 0)
b34976b6 1767 return TRUE;
252b5132 1768
0ffa91dd
NC
1769 BFD_ASSERT (is_alpha_elf (abfd));
1770
1771 dynobj = elf_hash_table (info)->dynobj;
a7519a3c 1772 if (dynobj == NULL)
0ffa91dd 1773 elf_hash_table (info)->dynobj = dynobj = abfd;
252b5132 1774
a7519a3c
RH
1775 sreloc = NULL;
1776 rel_sec_name = NULL;
0ffa91dd
NC
1777 symtab_hdr = &elf_symtab_hdr (abfd);
1778 sym_hashes = alpha_elf_sym_hashes (abfd);
a7519a3c
RH
1779
1780 relend = relocs + sec->reloc_count;
1781 for (rel = relocs; rel < relend; ++rel)
1782 {
1783 enum {
1784 NEED_GOT = 1,
1785 NEED_GOT_ENTRY = 2,
1786 NEED_DYNREL = 4
1787 };
1788
1789 unsigned long r_symndx, r_type;
1790 struct alpha_elf_link_hash_entry *h;
1791 unsigned int gotent_flags;
1792 bfd_boolean maybe_dynamic;
1793 unsigned int need;
1794 bfd_vma addend;
1795
1796 r_symndx = ELF64_R_SYM (rel->r_info);
1797 if (r_symndx < symtab_hdr->sh_info)
1798 h = NULL;
1799 else
1800 {
1801 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
252b5132 1802
a7519a3c
RH
1803 while (h->root.root.type == bfd_link_hash_indirect
1804 || h->root.root.type == bfd_link_hash_warning)
1805 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
252b5132 1806
a7519a3c
RH
1807 h->root.ref_regular = 1;
1808 }
252b5132 1809
a7519a3c
RH
1810 /* We can only get preliminary data on whether a symbol is
1811 locally or externally defined, as not all of the input files
1812 have yet been processed. Do something with what we know, as
1813 this may help reduce memory usage and processing time later. */
1814 maybe_dynamic = FALSE;
1815 if (h && ((info->shared
1816 && (!info->symbolic
1817 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
1818 || !h->root.def_regular
1819 || h->root.root.type == bfd_link_hash_defweak))
1820 maybe_dynamic = TRUE;
252b5132 1821
a7519a3c
RH
1822 need = 0;
1823 gotent_flags = 0;
1824 r_type = ELF64_R_TYPE (rel->r_info);
1825 addend = rel->r_addend;
9e756d64 1826
9e756d64
RH
1827 switch (r_type)
1828 {
1829 case R_ALPHA_LITERAL:
a7519a3c
RH
1830 need = NEED_GOT | NEED_GOT_ENTRY;
1831
1832 /* Remember how this literal is used from its LITUSEs.
1833 This will be important when it comes to decide if we can
1834 create a .plt entry for a function symbol. */
1835 while (++rel < relend && ELF64_R_TYPE (rel->r_info) == R_ALPHA_LITUSE)
8288a39e 1836 if (rel->r_addend >= 1 && rel->r_addend <= 6)
a7519a3c
RH
1837 gotent_flags |= 1 << rel->r_addend;
1838 --rel;
1839
1840 /* No LITUSEs -- presumably the address is used somehow. */
1841 if (gotent_flags == 0)
1842 gotent_flags = ALPHA_ELF_LINK_HASH_LU_ADDR;
1843 break;
1844
1845 case R_ALPHA_GPDISP:
1846 case R_ALPHA_GPREL16:
1847 case R_ALPHA_GPREL32:
9e756d64
RH
1848 case R_ALPHA_GPRELHIGH:
1849 case R_ALPHA_GPRELLOW:
a7519a3c
RH
1850 case R_ALPHA_BRSGP:
1851 need = NEED_GOT;
1852 break;
1853
1854 case R_ALPHA_REFLONG:
1855 case R_ALPHA_REFQUAD:
1856 if (info->shared || maybe_dynamic)
1857 need = NEED_DYNREL;
cc03ec80
RH
1858 break;
1859
9e756d64 1860 case R_ALPHA_TLSLDM:
cc03ec80 1861 /* The symbol for a TLSLDM reloc is ignored. Collapse the
a7519a3c 1862 reloc to the 0 symbol so that they all match. */
cc03ec80 1863 r_symndx = 0;
a7519a3c
RH
1864 h = 0;
1865 maybe_dynamic = FALSE;
1866 /* FALLTHRU */
1867
1868 case R_ALPHA_TLSGD:
1869 case R_ALPHA_GOTDTPREL:
1870 need = NEED_GOT | NEED_GOT_ENTRY;
9e756d64 1871 break;
cc03ec80 1872
a7519a3c
RH
1873 case R_ALPHA_GOTTPREL:
1874 need = NEED_GOT | NEED_GOT_ENTRY;
1875 gotent_flags = ALPHA_ELF_LINK_HASH_TLS_IE;
1876 if (info->shared)
1877 info->flags |= DF_STATIC_TLS;
1878 break;
1879
1880 case R_ALPHA_TPREL64:
1881 if (info->shared || maybe_dynamic)
1882 need = NEED_DYNREL;
1883 if (info->shared)
1884 info->flags |= DF_STATIC_TLS;
1885 break;
252b5132
RH
1886 }
1887
a7519a3c 1888 if (need & NEED_GOT)
252b5132 1889 {
85d162e6 1890 if (alpha_elf_tdata(abfd)->gotobj == NULL)
6cdc0ccc 1891 {
a7519a3c
RH
1892 if (!elf64_alpha_create_got_section (abfd, info))
1893 return FALSE;
c328dc3f 1894 }
252b5132 1895 }
252b5132 1896
a7519a3c
RH
1897 if (need & NEED_GOT_ENTRY)
1898 {
1899 struct alpha_elf_got_entry *gotent;
252b5132 1900
a7519a3c
RH
1901 gotent = get_got_entry (abfd, h, r_type, r_symndx, addend);
1902 if (!gotent)
1903 return FALSE;
4a67a098 1904
a7519a3c 1905 if (gotent_flags)
cc03ec80 1906 {
a7519a3c
RH
1907 gotent->flags |= gotent_flags;
1908 if (h)
1909 {
1910 gotent_flags |= h->flags;
1911 h->flags = gotent_flags;
4a67a098 1912
a7519a3c 1913 /* Make a guess as to whether a .plt entry is needed. */
6ec7057a
RH
1914 /* ??? It appears that we won't make it into
1915 adjust_dynamic_symbol for symbols that remain
1916 totally undefined. Copying this check here means
1917 we can create a plt entry for them too. */
1918 h->root.needs_plt
1919 = (maybe_dynamic && elf64_alpha_want_plt (h));
1920 }
a7519a3c 1921 }
252b5132
RH
1922 }
1923
a7519a3c 1924 if (need & NEED_DYNREL)
9e756d64 1925 {
a7519a3c 1926 if (rel_sec_name == NULL)
9e756d64 1927 {
a7519a3c
RH
1928 rel_sec_name = (bfd_elf_string_from_elf_section
1929 (abfd, elf_elfheader(abfd)->e_shstrndx,
1930 elf_section_data(sec)->rel_hdr.sh_name));
1931 if (rel_sec_name == NULL)
1932 return FALSE;
1933
0112cd26 1934 BFD_ASSERT (CONST_STRNEQ (rel_sec_name, ".rela")
a7519a3c
RH
1935 && strcmp (bfd_get_section_name (abfd, sec),
1936 rel_sec_name+5) == 0);
9e756d64 1937 }
a7519a3c
RH
1938
1939 /* We need to create the section here now whether we eventually
1940 use it or not so that it gets mapped to an output section by
1941 the linker. If not used, we'll kill it in
1942 size_dynamic_sections. */
1943 if (sreloc == NULL)
9e756d64 1944 {
a7519a3c
RH
1945 sreloc = bfd_get_section_by_name (dynobj, rel_sec_name);
1946 if (sreloc == NULL)
1947 {
1948 flagword flags;
1949
1950 flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
1951 | SEC_LINKER_CREATED | SEC_READONLY);
1952 if (sec->flags & SEC_ALLOC)
1953 flags |= SEC_ALLOC | SEC_LOAD;
1954 sreloc = bfd_make_section_with_flags (dynobj,
1955 rel_sec_name,
1956 flags);
1957 if (sreloc == NULL
1958 || !bfd_set_section_alignment (dynobj, sreloc, 3))
1959 return FALSE;
1960 }
9e756d64 1961 }
252b5132 1962
a7519a3c
RH
1963 if (h)
1964 {
1965 /* Since we havn't seen all of the input symbols yet, we
1966 don't know whether we'll actually need a dynamic relocation
1967 entry for this reloc. So make a record of it. Once we
1968 find out if this thing needs dynamic relocation we'll
1969 expand the relocation sections by the appropriate amount. */
9e756d64 1970
a7519a3c 1971 struct alpha_elf_reloc_entry *rent;
9e756d64 1972
a7519a3c
RH
1973 for (rent = h->reloc_entries; rent; rent = rent->next)
1974 if (rent->rtype == r_type && rent->srel == sreloc)
1975 break;
252b5132 1976
a7519a3c
RH
1977 if (!rent)
1978 {
1979 amt = sizeof (struct alpha_elf_reloc_entry);
1980 rent = (struct alpha_elf_reloc_entry *) bfd_alloc (abfd, amt);
1981 if (!rent)
1982 return FALSE;
252b5132 1983
a7519a3c
RH
1984 rent->srel = sreloc;
1985 rent->rtype = r_type;
1986 rent->count = 1;
1987 rent->reltext = (sec->flags & SEC_READONLY) != 0;
252b5132 1988
a7519a3c
RH
1989 rent->next = h->reloc_entries;
1990 h->reloc_entries = rent;
1991 }
1992 else
1993 rent->count++;
1994 }
1995 else if (info->shared)
1996 {
1997 /* If this is a shared library, and the section is to be
1998 loaded into memory, we need a RELATIVE reloc. */
1999 sreloc->size += sizeof (Elf64_External_Rela);
2000 if (sec->flags & SEC_READONLY)
2001 info->flags |= DF_TEXTREL;
2002 }
252b5132
RH
2003 }
2004 }
2005
b34976b6 2006 return TRUE;
252b5132 2007}
252b5132 2008
a7519a3c
RH
2009/* Adjust a symbol defined by a dynamic object and referenced by a
2010 regular object. The current definition is in some section of the
2011 dynamic object, but we're not including those sections. We have to
2012 change the definition to something the rest of the link can
2013 understand. */
252b5132 2014
b34976b6 2015static bfd_boolean
a7519a3c
RH
2016elf64_alpha_adjust_dynamic_symbol (struct bfd_link_info *info,
2017 struct elf_link_hash_entry *h)
252b5132 2018{
a7519a3c
RH
2019 bfd *dynobj;
2020 asection *s;
2021 struct alpha_elf_link_hash_entry *ah;
252b5132 2022
a7519a3c
RH
2023 dynobj = elf_hash_table(info)->dynobj;
2024 ah = (struct alpha_elf_link_hash_entry *)h;
252b5132 2025
a7519a3c 2026 /* Now that we've seen all of the input symbols, finalize our decision
6ec7057a
RH
2027 about whether this symbol should get a .plt entry. Irritatingly, it
2028 is common for folk to leave undefined symbols in shared libraries,
2029 and they still expect lazy binding; accept undefined symbols in lieu
2030 of STT_FUNC. */
2031 if (alpha_elf_dynamic_symbol_p (h, info) && elf64_alpha_want_plt (ah))
252b5132 2032 {
6ec7057a 2033 h->needs_plt = TRUE;
252b5132 2034
a7519a3c
RH
2035 s = bfd_get_section_by_name(dynobj, ".plt");
2036 if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
2037 return FALSE;
204692d7 2038
6ec7057a
RH
2039 /* We need one plt entry per got subsection. Delay allocation of
2040 the actual plt entries until size_plt_section, called from
2041 size_dynamic_sections or during relaxation. */
252b5132 2042
a7519a3c
RH
2043 return TRUE;
2044 }
2045 else
6ec7057a 2046 h->needs_plt = FALSE;
252b5132 2047
a7519a3c
RH
2048 /* If this is a weak symbol, and there is a real definition, the
2049 processor independent code will have arranged for us to see the
2050 real definition first, and we can just use the same value. */
2051 if (h->u.weakdef != NULL)
252b5132 2052 {
a7519a3c
RH
2053 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2054 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2055 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2056 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2057 return TRUE;
252b5132 2058 }
a7519a3c
RH
2059
2060 /* This is a reference to a symbol defined by a dynamic object which
2061 is not a function. The Alpha, since it uses .got entries for all
2062 symbols even in regular objects, does not need the hackery of a
2063 .dynbss section and COPY dynamic relocations. */
252b5132 2064
b34976b6 2065 return TRUE;
252b5132
RH
2066}
2067
747ffa7b
AM
2068/* Record STO_ALPHA_NOPV and STO_ALPHA_STD_GPLOAD. */
2069
2070static void
2071elf64_alpha_merge_symbol_attribute (struct elf_link_hash_entry *h,
2072 const Elf_Internal_Sym *isym,
2073 bfd_boolean definition,
2074 bfd_boolean dynamic)
2075{
2076 if (!dynamic && definition)
2077 h->other = ((h->other & ELF_ST_VISIBILITY (-1))
2078 | (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
2079}
2080
a7519a3c
RH
2081/* Symbol versioning can create new symbols, and make our old symbols
2082 indirect to the new ones. Consolidate the got and reloc information
2083 in these situations. */
252b5132 2084
b34976b6 2085static bfd_boolean
a7519a3c
RH
2086elf64_alpha_merge_ind_symbols (struct alpha_elf_link_hash_entry *hi,
2087 PTR dummy ATTRIBUTE_UNUSED)
252b5132 2088{
a7519a3c 2089 struct alpha_elf_link_hash_entry *hs;
252b5132 2090
a7519a3c
RH
2091 if (hi->root.root.type != bfd_link_hash_indirect)
2092 return TRUE;
2093 hs = hi;
2094 do {
2095 hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link;
2096 } while (hs->root.root.type == bfd_link_hash_indirect);
252b5132 2097
a7519a3c
RH
2098 /* Merge the flags. Whee. */
2099
2100 hs->flags |= hi->flags;
2101
2102 /* Merge the .got entries. Cannibalize the old symbol's list in
2103 doing so, since we don't need it anymore. */
2104
2105 if (hs->got_entries == NULL)
2106 hs->got_entries = hi->got_entries;
2107 else
2108 {
2109 struct alpha_elf_got_entry *gi, *gs, *gin, *gsh;
2110
2111 gsh = hs->got_entries;
2112 for (gi = hi->got_entries; gi ; gi = gin)
252b5132 2113 {
a7519a3c
RH
2114 gin = gi->next;
2115 for (gs = gsh; gs ; gs = gs->next)
2116 if (gi->gotobj == gs->gotobj
2117 && gi->reloc_type == gs->reloc_type
2118 && gi->addend == gs->addend)
2119 {
2120 gi->use_count += gs->use_count;
2121 goto got_found;
2122 }
2123 gi->next = hs->got_entries;
2124 hs->got_entries = gi;
2125 got_found:;
252b5132 2126 }
a7519a3c
RH
2127 }
2128 hi->got_entries = NULL;
252b5132 2129
a7519a3c
RH
2130 /* And similar for the reloc entries. */
2131
2132 if (hs->reloc_entries == NULL)
2133 hs->reloc_entries = hi->reloc_entries;
2134 else
2135 {
2136 struct alpha_elf_reloc_entry *ri, *rs, *rin, *rsh;
2137
2138 rsh = hs->reloc_entries;
2139 for (ri = hi->reloc_entries; ri ; ri = rin)
2140 {
2141 rin = ri->next;
2142 for (rs = rsh; rs ; rs = rs->next)
2143 if (ri->rtype == rs->rtype && ri->srel == rs->srel)
2144 {
2145 rs->count += ri->count;
2146 goto found_reloc;
2147 }
2148 ri->next = hs->reloc_entries;
2149 hs->reloc_entries = ri;
2150 found_reloc:;
2151 }
252b5132 2152 }
a7519a3c 2153 hi->reloc_entries = NULL;
252b5132 2154
b34976b6 2155 return TRUE;
252b5132
RH
2156}
2157
a7519a3c 2158/* Is it possible to merge two object file's .got tables? */
252b5132 2159
b34976b6 2160static bfd_boolean
a7519a3c 2161elf64_alpha_can_merge_gots (bfd *a, bfd *b)
252b5132 2162{
a7519a3c
RH
2163 int total = alpha_elf_tdata (a)->total_got_size;
2164 bfd *bsub;
252b5132 2165
a7519a3c
RH
2166 /* Trivial quick fallout test. */
2167 if (total + alpha_elf_tdata (b)->total_got_size <= MAX_GOT_SIZE)
2168 return TRUE;
252b5132 2169
a7519a3c
RH
2170 /* By their nature, local .got entries cannot be merged. */
2171 if ((total += alpha_elf_tdata (b)->local_got_size) > MAX_GOT_SIZE)
b34976b6 2172 return FALSE;
252b5132 2173
a7519a3c
RH
2174 /* Failing the common trivial comparison, we must effectively
2175 perform the merge. Not actually performing the merge means that
2176 we don't have to store undo information in case we fail. */
2177 for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
2178 {
2179 struct alpha_elf_link_hash_entry **hashes = alpha_elf_sym_hashes (bsub);
2180 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
2181 int i, n;
2182
2183 n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
2184 for (i = 0; i < n; ++i)
2185 {
2186 struct alpha_elf_got_entry *ae, *be;
2187 struct alpha_elf_link_hash_entry *h;
2188
2189 h = hashes[i];
2190 while (h->root.root.type == bfd_link_hash_indirect
2191 || h->root.root.type == bfd_link_hash_warning)
2192 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
2193
2194 for (be = h->got_entries; be ; be = be->next)
2195 {
2196 if (be->use_count == 0)
2197 continue;
2198 if (be->gotobj != b)
2199 continue;
2200
2201 for (ae = h->got_entries; ae ; ae = ae->next)
2202 if (ae->gotobj == a
2203 && ae->reloc_type == be->reloc_type
2204 && ae->addend == be->addend)
2205 goto global_found;
2206
2207 total += alpha_got_entry_size (be->reloc_type);
2208 if (total > MAX_GOT_SIZE)
2209 return FALSE;
2210 global_found:;
2211 }
2212 }
2213 }
252b5132 2214
b34976b6 2215 return TRUE;
252b5132
RH
2216}
2217
a7519a3c 2218/* Actually merge two .got tables. */
252b5132 2219
a7519a3c
RH
2220static void
2221elf64_alpha_merge_gots (bfd *a, bfd *b)
252b5132 2222{
a7519a3c
RH
2223 int total = alpha_elf_tdata (a)->total_got_size;
2224 bfd *bsub;
252b5132 2225
a7519a3c
RH
2226 /* Remember local expansion. */
2227 {
2228 int e = alpha_elf_tdata (b)->local_got_size;
2229 total += e;
2230 alpha_elf_tdata (a)->local_got_size += e;
2231 }
252b5132 2232
a7519a3c
RH
2233 for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
2234 {
2235 struct alpha_elf_got_entry **local_got_entries;
2236 struct alpha_elf_link_hash_entry **hashes;
2237 Elf_Internal_Shdr *symtab_hdr;
2238 int i, n;
252b5132 2239
a7519a3c
RH
2240 /* Let the local .got entries know they are part of a new subsegment. */
2241 local_got_entries = alpha_elf_tdata (bsub)->local_got_entries;
2242 if (local_got_entries)
2243 {
2244 n = elf_tdata (bsub)->symtab_hdr.sh_info;
2245 for (i = 0; i < n; ++i)
2246 {
2247 struct alpha_elf_got_entry *ent;
2248 for (ent = local_got_entries[i]; ent; ent = ent->next)
2249 ent->gotobj = a;
2250 }
2251 }
252b5132 2252
a7519a3c
RH
2253 /* Merge the global .got entries. */
2254 hashes = alpha_elf_sym_hashes (bsub);
2255 symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
252b5132 2256
a7519a3c
RH
2257 n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
2258 for (i = 0; i < n; ++i)
2259 {
2260 struct alpha_elf_got_entry *ae, *be, **pbe, **start;
2261 struct alpha_elf_link_hash_entry *h;
252b5132 2262
a7519a3c
RH
2263 h = hashes[i];
2264 while (h->root.root.type == bfd_link_hash_indirect
2265 || h->root.root.type == bfd_link_hash_warning)
2266 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
252b5132 2267
a7519a3c
RH
2268 pbe = start = &h->got_entries;
2269 while ((be = *pbe) != NULL)
2270 {
2271 if (be->use_count == 0)
2272 {
2273 *pbe = be->next;
2274 memset (be, 0xa5, sizeof (*be));
2275 goto kill;
2276 }
2277 if (be->gotobj != b)
2278 goto next;
2279
2280 for (ae = *start; ae ; ae = ae->next)
2281 if (ae->gotobj == a
2282 && ae->reloc_type == be->reloc_type
2283 && ae->addend == be->addend)
2284 {
2285 ae->flags |= be->flags;
2286 ae->use_count += be->use_count;
2287 *pbe = be->next;
2288 memset (be, 0xa5, sizeof (*be));
2289 goto kill;
2290 }
2291 be->gotobj = a;
2292 total += alpha_got_entry_size (be->reloc_type);
252b5132 2293
a7519a3c
RH
2294 next:;
2295 pbe = &be->next;
2296 kill:;
2297 }
2298 }
252b5132 2299
a7519a3c
RH
2300 alpha_elf_tdata (bsub)->gotobj = a;
2301 }
2302 alpha_elf_tdata (a)->total_got_size = total;
252b5132 2303
a7519a3c
RH
2304 /* Merge the two in_got chains. */
2305 {
2306 bfd *next;
252b5132 2307
a7519a3c
RH
2308 bsub = a;
2309 while ((next = alpha_elf_tdata (bsub)->in_got_link_next) != NULL)
2310 bsub = next;
252b5132 2311
a7519a3c
RH
2312 alpha_elf_tdata (bsub)->in_got_link_next = b;
2313 }
252b5132 2314}
a7519a3c
RH
2315
2316/* Calculate the offsets for the got entries. */
252b5132 2317
b34976b6 2318static bfd_boolean
a7519a3c
RH
2319elf64_alpha_calc_got_offsets_for_symbol (struct alpha_elf_link_hash_entry *h,
2320 PTR arg ATTRIBUTE_UNUSED)
252b5132 2321{
a7519a3c 2322 struct alpha_elf_got_entry *gotent;
252b5132 2323
a7519a3c
RH
2324 if (h->root.root.type == bfd_link_hash_warning)
2325 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
252b5132 2326
a7519a3c
RH
2327 for (gotent = h->got_entries; gotent; gotent = gotent->next)
2328 if (gotent->use_count > 0)
2329 {
2330 struct alpha_elf_obj_tdata *td;
2331 bfd_size_type *plge;
252b5132 2332
a7519a3c 2333 td = alpha_elf_tdata (gotent->gotobj);
a7519a3c
RH
2334 plge = &td->got->size;
2335 gotent->got_offset = *plge;
2336 *plge += alpha_got_entry_size (gotent->reloc_type);
2337 }
252b5132 2338
6ec7057a 2339 return TRUE;
a7519a3c 2340}
252b5132 2341
a7519a3c
RH
2342static void
2343elf64_alpha_calc_got_offsets (struct bfd_link_info *info)
2344{
2345 bfd *i, *got_list = alpha_elf_hash_table(info)->got_list;
252b5132 2346
a7519a3c
RH
2347 /* First, zero out the .got sizes, as we may be recalculating the
2348 .got after optimizing it. */
2349 for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
2350 alpha_elf_tdata(i)->got->size = 0;
252b5132 2351
a7519a3c
RH
2352 /* Next, fill in the offsets for all the global entries. */
2353 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2354 elf64_alpha_calc_got_offsets_for_symbol,
2355 NULL);
252b5132 2356
a7519a3c
RH
2357 /* Finally, fill in the offsets for the local entries. */
2358 for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
2359 {
2360 bfd_size_type got_offset = alpha_elf_tdata(i)->got->size;
2361 bfd *j;
252b5132 2362
a7519a3c
RH
2363 for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
2364 {
2365 struct alpha_elf_got_entry **local_got_entries, *gotent;
2366 int k, n;
252b5132 2367
a7519a3c
RH
2368 local_got_entries = alpha_elf_tdata(j)->local_got_entries;
2369 if (!local_got_entries)
2370 continue;
252b5132 2371
a7519a3c
RH
2372 for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
2373 for (gotent = local_got_entries[k]; gotent; gotent = gotent->next)
2374 if (gotent->use_count > 0)
2375 {
2376 gotent->got_offset = got_offset;
2377 got_offset += alpha_got_entry_size (gotent->reloc_type);
2378 }
2379 }
252b5132 2380
a7519a3c
RH
2381 alpha_elf_tdata(i)->got->size = got_offset;
2382 }
2383}
252b5132 2384
a7519a3c 2385/* Constructs the gots. */
252b5132 2386
b34976b6 2387static bfd_boolean
a7519a3c 2388elf64_alpha_size_got_sections (struct bfd_link_info *info)
252b5132 2389{
a7519a3c 2390 bfd *i, *got_list, *cur_got_obj = NULL;
252b5132 2391
a7519a3c 2392 got_list = alpha_elf_hash_table (info)->got_list;
95404643 2393
a7519a3c
RH
2394 /* On the first time through, pretend we have an existing got list
2395 consisting of all of the input files. */
2396 if (got_list == NULL)
252b5132 2397 {
a7519a3c 2398 for (i = info->input_bfds; i ; i = i->link_next)
252b5132 2399 {
0ffa91dd
NC
2400 bfd *this_got;
2401
2402 if (! is_alpha_elf (i))
2403 continue;
2404
2405 this_got = alpha_elf_tdata (i)->gotobj;
a7519a3c
RH
2406 if (this_got == NULL)
2407 continue;
252b5132 2408
a7519a3c
RH
2409 /* We are assuming no merging has yet occurred. */
2410 BFD_ASSERT (this_got == i);
252b5132 2411
a7519a3c 2412 if (alpha_elf_tdata (this_got)->total_got_size > MAX_GOT_SIZE)
252b5132 2413 {
a7519a3c
RH
2414 /* Yikes! A single object file has too many entries. */
2415 (*_bfd_error_handler)
2416 (_("%B: .got subsegment exceeds 64K (size %d)"),
2417 i, alpha_elf_tdata (this_got)->total_got_size);
b34976b6 2418 return FALSE;
252b5132 2419 }
252b5132 2420
a7519a3c
RH
2421 if (got_list == NULL)
2422 got_list = this_got;
2423 else
2424 alpha_elf_tdata(cur_got_obj)->got_link_next = this_got;
2425 cur_got_obj = this_got;
252b5132
RH
2426 }
2427
a7519a3c
RH
2428 /* Strange degenerate case of no got references. */
2429 if (got_list == NULL)
2430 return TRUE;
2431
2432 alpha_elf_hash_table (info)->got_list = got_list;
a7519a3c
RH
2433 }
2434
2435 cur_got_obj = got_list;
0ffa91dd
NC
2436 if (cur_got_obj == NULL)
2437 return FALSE;
2438
a7519a3c
RH
2439 i = alpha_elf_tdata(cur_got_obj)->got_link_next;
2440 while (i != NULL)
2441 {
2442 if (elf64_alpha_can_merge_gots (cur_got_obj, i))
252b5132 2443 {
a7519a3c 2444 elf64_alpha_merge_gots (cur_got_obj, i);
252b5132 2445
a7519a3c
RH
2446 alpha_elf_tdata(i)->got->size = 0;
2447 i = alpha_elf_tdata(i)->got_link_next;
2448 alpha_elf_tdata(cur_got_obj)->got_link_next = i;
a7519a3c
RH
2449 }
2450 else
2451 {
2452 cur_got_obj = i;
2453 i = alpha_elf_tdata(i)->got_link_next;
2454 }
252b5132
RH
2455 }
2456
a7519a3c
RH
2457 /* Once the gots have been merged, fill in the got offsets for
2458 everything therein. */
4a828aab 2459 elf64_alpha_calc_got_offsets (info);
252b5132 2460
a7519a3c 2461 return TRUE;
252b5132 2462}
252b5132 2463
b34976b6 2464static bfd_boolean
a7519a3c 2465elf64_alpha_size_plt_section_1 (struct alpha_elf_link_hash_entry *h, PTR data)
252b5132 2466{
a7519a3c
RH
2467 asection *splt = (asection *) data;
2468 struct alpha_elf_got_entry *gotent;
6ec7057a 2469 bfd_boolean saw_one = FALSE;
252b5132 2470
a7519a3c
RH
2471 /* If we didn't need an entry before, we still don't. */
2472 if (!h->root.needs_plt)
2473 return TRUE;
e92d460e 2474
6ec7057a 2475 /* For each LITERAL got entry still in use, allocate a plt entry. */
a7519a3c
RH
2476 for (gotent = h->got_entries; gotent ; gotent = gotent->next)
2477 if (gotent->reloc_type == R_ALPHA_LITERAL
2478 && gotent->use_count > 0)
6ec7057a
RH
2479 {
2480 if (splt->size == 0)
2481 splt->size = PLT_HEADER_SIZE;
2482 gotent->plt_offset = splt->size;
2483 splt->size += PLT_ENTRY_SIZE;
2484 saw_one = TRUE;
2485 }
a7519a3c 2486
6ec7057a
RH
2487 /* If there weren't any, there's no longer a need for the PLT entry. */
2488 if (!saw_one)
2489 h->root.needs_plt = FALSE;
a7519a3c
RH
2490
2491 return TRUE;
2492}
2493
4a828aab
RH
2494/* Called from relax_section to rebuild the PLT in light of potential changes
2495 in the function's status. */
a7519a3c 2496
4a828aab 2497static void
a7519a3c
RH
2498elf64_alpha_size_plt_section (struct bfd_link_info *info)
2499{
6ec7057a 2500 asection *splt, *spltrel, *sgotplt;
a7519a3c
RH
2501 unsigned long entries;
2502 bfd *dynobj;
2503
2504 dynobj = elf_hash_table(info)->dynobj;
6ec7057a 2505 splt = bfd_get_section_by_name (dynobj, ".plt");
a7519a3c 2506 if (splt == NULL)
4a828aab 2507 return;
252b5132 2508
a7519a3c 2509 splt->size = 0;
252b5132 2510
a7519a3c
RH
2511 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2512 elf64_alpha_size_plt_section_1, splt);
e92d460e 2513
a7519a3c
RH
2514 /* Every plt entry requires a JMP_SLOT relocation. */
2515 spltrel = bfd_get_section_by_name (dynobj, ".rela.plt");
4a828aab 2516 entries = 0;
a7519a3c 2517 if (splt->size)
6ec7057a
RH
2518 {
2519 if (elf64_alpha_use_secureplt)
2520 entries = (splt->size - NEW_PLT_HEADER_SIZE) / NEW_PLT_ENTRY_SIZE;
2521 else
2522 entries = (splt->size - OLD_PLT_HEADER_SIZE) / OLD_PLT_ENTRY_SIZE;
2523 }
a7519a3c 2524 spltrel->size = entries * sizeof (Elf64_External_Rela);
e92d460e 2525
6ec7057a
RH
2526 /* When using the secureplt, we need two words somewhere in the data
2527 segment for the dynamic linker to tell us where to go. This is the
2528 entire contents of the .got.plt section. */
2529 if (elf64_alpha_use_secureplt)
2530 {
2531 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
2532 sgotplt->size = entries ? 16 : 0;
2533 }
a7519a3c 2534}
e92d460e 2535
a7519a3c
RH
2536static bfd_boolean
2537elf64_alpha_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2538 struct bfd_link_info *info)
2539{
2540 bfd *i;
252b5132 2541
a7519a3c
RH
2542 if (info->relocatable)
2543 return TRUE;
252b5132 2544
a7519a3c
RH
2545 /* First, take care of the indirect symbols created by versioning. */
2546 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2547 elf64_alpha_merge_ind_symbols,
2548 NULL);
252b5132 2549
a7519a3c
RH
2550 if (!elf64_alpha_size_got_sections (info))
2551 return FALSE;
252b5132 2552
a7519a3c
RH
2553 /* Allocate space for all of the .got subsections. */
2554 i = alpha_elf_hash_table (info)->got_list;
2555 for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
252b5132 2556 {
a7519a3c
RH
2557 asection *s = alpha_elf_tdata(i)->got;
2558 if (s->size > 0)
2559 {
2560 s->contents = (bfd_byte *) bfd_zalloc (i, s->size);
2561 if (s->contents == NULL)
2562 return FALSE;
2563 }
252b5132
RH
2564 }
2565
b34976b6 2566 return TRUE;
252b5132 2567}
3765b1be 2568
a7519a3c 2569/* The number of dynamic relocations required by a static relocation. */
3765b1be 2570
a7519a3c
RH
2571static int
2572alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared)
2573{
2574 switch (r_type)
3765b1be 2575 {
a7519a3c
RH
2576 /* May appear in GOT entries. */
2577 case R_ALPHA_TLSGD:
2578 return (dynamic ? 2 : shared ? 1 : 0);
2579 case R_ALPHA_TLSLDM:
2580 return shared;
2581 case R_ALPHA_LITERAL:
2582 case R_ALPHA_GOTTPREL:
2583 return dynamic || shared;
2584 case R_ALPHA_GOTDTPREL:
2585 return dynamic;
3765b1be 2586
a7519a3c
RH
2587 /* May appear in data sections. */
2588 case R_ALPHA_REFLONG:
2589 case R_ALPHA_REFQUAD:
2590 case R_ALPHA_TPREL64:
2591 return dynamic || shared;
3765b1be 2592
a7519a3c
RH
2593 /* Everything else is illegal. We'll issue an error during
2594 relocate_section. */
2595 default:
2596 return 0;
2597 }
2598}
3765b1be 2599
a7519a3c 2600/* Work out the sizes of the dynamic relocation entries. */
3765b1be 2601
a7519a3c
RH
2602static bfd_boolean
2603elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h,
2604 struct bfd_link_info *info)
2605{
2606 bfd_boolean dynamic;
2607 struct alpha_elf_reloc_entry *relent;
2608 unsigned long entries;
3765b1be 2609
a7519a3c
RH
2610 if (h->root.root.type == bfd_link_hash_warning)
2611 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
3765b1be 2612
a7519a3c
RH
2613 /* If the symbol was defined as a common symbol in a regular object
2614 file, and there was no definition in any dynamic object, then the
2615 linker will have allocated space for the symbol in a common
2616 section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been
2617 set. This is done for dynamic symbols in
2618 elf_adjust_dynamic_symbol but this is not done for non-dynamic
2619 symbols, somehow. */
2620 if (!h->root.def_regular
2621 && h->root.ref_regular
2622 && !h->root.def_dynamic
2623 && (h->root.root.type == bfd_link_hash_defined
2624 || h->root.root.type == bfd_link_hash_defweak)
2625 && !(h->root.root.u.def.section->owner->flags & DYNAMIC))
2626 h->root.def_regular = 1;
3765b1be 2627
a7519a3c
RH
2628 /* If the symbol is dynamic, we'll need all the relocations in their
2629 natural form. If this is a shared object, and it has been forced
2630 local, we'll need the same number of RELATIVE relocations. */
2631 dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
3765b1be 2632
a7519a3c
RH
2633 /* If the symbol is a hidden undefined weak, then we never have any
2634 relocations. Avoid the loop which may want to add RELATIVE relocs
2635 based on info->shared. */
2636 if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
2637 return TRUE;
2638
2639 for (relent = h->reloc_entries; relent; relent = relent->next)
3765b1be 2640 {
a7519a3c
RH
2641 entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
2642 info->shared);
2643 if (entries)
2644 {
2645 relent->srel->size +=
2646 entries * sizeof (Elf64_External_Rela) * relent->count;
2647 if (relent->reltext)
2648 info->flags |= DT_TEXTREL;
2649 }
2650 }
3765b1be 2651
a7519a3c
RH
2652 return TRUE;
2653}
3765b1be 2654
a7519a3c
RH
2655/* Subroutine of elf64_alpha_size_rela_got_section for doing the
2656 global symbols. */
3765b1be 2657
a7519a3c
RH
2658static bfd_boolean
2659elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h,
2660 struct bfd_link_info *info)
2661{
2662 bfd_boolean dynamic;
2663 struct alpha_elf_got_entry *gotent;
2664 unsigned long entries;
3765b1be 2665
a7519a3c
RH
2666 if (h->root.root.type == bfd_link_hash_warning)
2667 h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
2668
6ec7057a
RH
2669 /* If we're using a plt for this symbol, then all of its relocations
2670 for its got entries go into .rela.plt. */
2671 if (h->root.needs_plt)
2672 return TRUE;
2673
a7519a3c
RH
2674 /* If the symbol is dynamic, we'll need all the relocations in their
2675 natural form. If this is a shared object, and it has been forced
2676 local, we'll need the same number of RELATIVE relocations. */
2677 dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
2678
2679 /* If the symbol is a hidden undefined weak, then we never have any
2680 relocations. Avoid the loop which may want to add RELATIVE relocs
2681 based on info->shared. */
2682 if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
2683 return TRUE;
2684
2685 entries = 0;
2686 for (gotent = h->got_entries; gotent ; gotent = gotent->next)
2687 if (gotent->use_count > 0)
2688 entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type,
2689 dynamic, info->shared);
2690
a7519a3c
RH
2691 if (entries > 0)
2692 {
2693 bfd *dynobj = elf_hash_table(info)->dynobj;
2694 asection *srel = bfd_get_section_by_name (dynobj, ".rela.got");
2695 BFD_ASSERT (srel != NULL);
2696 srel->size += sizeof (Elf64_External_Rela) * entries;
3765b1be 2697 }
3765b1be 2698
a7519a3c 2699 return TRUE;
3765b1be
RH
2700}
2701
a7519a3c 2702/* Set the sizes of the dynamic relocation sections. */
252b5132 2703
4a828aab 2704static void
a7519a3c 2705elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
252b5132 2706{
a7519a3c
RH
2707 unsigned long entries;
2708 bfd *i, *dynobj;
2709 asection *srel;
252b5132 2710
a7519a3c
RH
2711 /* Shared libraries often require RELATIVE relocs, and some relocs
2712 require attention for the main application as well. */
252b5132 2713
a7519a3c
RH
2714 entries = 0;
2715 for (i = alpha_elf_hash_table(info)->got_list;
2716 i ; i = alpha_elf_tdata(i)->got_link_next)
2717 {
2718 bfd *j;
3241278a 2719
a7519a3c
RH
2720 for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
2721 {
2722 struct alpha_elf_got_entry **local_got_entries, *gotent;
2723 int k, n;
252b5132 2724
a7519a3c
RH
2725 local_got_entries = alpha_elf_tdata(j)->local_got_entries;
2726 if (!local_got_entries)
2727 continue;
252b5132 2728
a7519a3c
RH
2729 for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
2730 for (gotent = local_got_entries[k];
2731 gotent ; gotent = gotent->next)
2732 if (gotent->use_count > 0)
2733 entries += (alpha_dynamic_entries_for_reloc
2734 (gotent->reloc_type, 0, info->shared));
2735 }
2736 }
3765b1be 2737
a7519a3c
RH
2738 dynobj = elf_hash_table(info)->dynobj;
2739 srel = bfd_get_section_by_name (dynobj, ".rela.got");
2740 if (!srel)
2741 {
2742 BFD_ASSERT (entries == 0);
4a828aab 2743 return;
a7519a3c
RH
2744 }
2745 srel->size = sizeof (Elf64_External_Rela) * entries;
252b5132 2746
a7519a3c
RH
2747 /* Now do the non-local symbols. */
2748 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2749 elf64_alpha_size_rela_got_1, info);
a7519a3c 2750}
252b5132 2751
a7519a3c 2752/* Set the sizes of the dynamic sections. */
3765b1be 2753
a7519a3c
RH
2754static bfd_boolean
2755elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2756 struct bfd_link_info *info)
2757{
2758 bfd *dynobj;
2759 asection *s;
2760 bfd_boolean relplt;
3765b1be 2761
a7519a3c
RH
2762 dynobj = elf_hash_table(info)->dynobj;
2763 BFD_ASSERT(dynobj != NULL);
252b5132 2764
a7519a3c
RH
2765 if (elf_hash_table (info)->dynamic_sections_created)
2766 {
2767 /* Set the contents of the .interp section to the interpreter. */
2768 if (info->executable)
252b5132 2769 {
a7519a3c
RH
2770 s = bfd_get_section_by_name (dynobj, ".interp");
2771 BFD_ASSERT (s != NULL);
2772 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2773 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2774 }
3765b1be 2775
a7519a3c
RH
2776 /* Now that we've seen all of the input files, we can decide which
2777 symbols need dynamic relocation entries and which don't. We've
2778 collected information in check_relocs that we can now apply to
2779 size the dynamic relocation sections. */
2780 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2781 elf64_alpha_calc_dynrel_sizes, info);
252b5132 2782
a7519a3c 2783 elf64_alpha_size_rela_got_section (info);
6ec7057a 2784 elf64_alpha_size_plt_section (info);
a7519a3c
RH
2785 }
2786 /* else we're not dynamic and by definition we don't need such things. */
3765b1be 2787
a7519a3c
RH
2788 /* The check_relocs and adjust_dynamic_symbol entry points have
2789 determined the sizes of the various dynamic sections. Allocate
2790 memory for them. */
2791 relplt = FALSE;
2792 for (s = dynobj->sections; s != NULL; s = s->next)
2793 {
2794 const char *name;
3765b1be 2795
a7519a3c
RH
2796 if (!(s->flags & SEC_LINKER_CREATED))
2797 continue;
cc03ec80 2798
a7519a3c
RH
2799 /* It's OK to base decisions on the section name, because none
2800 of the dynobj section names depend upon the input files. */
2801 name = bfd_get_section_name (dynobj, s);
3765b1be 2802
0112cd26 2803 if (CONST_STRNEQ (name, ".rela"))
3765b1be 2804 {
c456f082 2805 if (s->size != 0)
a7519a3c 2806 {
c456f082 2807 if (strcmp (name, ".rela.plt") == 0)
a7519a3c 2808 relplt = TRUE;
252b5132 2809
a7519a3c
RH
2810 /* We use the reloc_count field as a counter if we need
2811 to copy relocs into the output file. */
2812 s->reloc_count = 0;
252b5132 2813 }
3765b1be 2814 }
0112cd26 2815 else if (! CONST_STRNEQ (name, ".got")
c456f082
AM
2816 && strcmp (name, ".plt") != 0
2817 && strcmp (name, ".dynbss") != 0)
3765b1be 2818 {
a7519a3c
RH
2819 /* It's not one of our dynamic sections, so don't allocate space. */
2820 continue;
2821 }
252b5132 2822
c456f082
AM
2823 if (s->size == 0)
2824 {
2825 /* If we don't need this section, strip it from the output file.
2826 This is to handle .rela.bss and .rela.plt. We must create it
2827 in create_dynamic_sections, because it must be created before
2828 the linker maps input sections to output sections. The
2829 linker does that before adjust_dynamic_symbol is called, and
2830 it is that function which decides whether anything needs to
2831 go into these sections. */
2832 s->flags |= SEC_EXCLUDE;
2833 }
2834 else if ((s->flags & SEC_HAS_CONTENTS) != 0)
a7519a3c
RH
2835 {
2836 /* Allocate memory for the section contents. */
2837 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
c456f082 2838 if (s->contents == NULL)
b34976b6 2839 return FALSE;
a7519a3c
RH
2840 }
2841 }
3765b1be 2842
a7519a3c
RH
2843 if (elf_hash_table (info)->dynamic_sections_created)
2844 {
2845 /* Add some entries to the .dynamic section. We fill in the
2846 values later, in elf64_alpha_finish_dynamic_sections, but we
2847 must add the entries now so that we get the correct size for
2848 the .dynamic section. The DT_DEBUG entry is filled in by the
2849 dynamic linker and used by the debugger. */
2850#define add_dynamic_entry(TAG, VAL) \
2851 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3765b1be 2852
a7519a3c
RH
2853 if (info->executable)
2854 {
2855 if (!add_dynamic_entry (DT_DEBUG, 0))
2856 return FALSE;
3765b1be
RH
2857 }
2858
a7519a3c 2859 if (relplt)
3765b1be 2860 {
a7519a3c
RH
2861 if (!add_dynamic_entry (DT_PLTGOT, 0)
2862 || !add_dynamic_entry (DT_PLTRELSZ, 0)
2863 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2864 || !add_dynamic_entry (DT_JMPREL, 0))
2865 return FALSE;
6ec7057a
RH
2866
2867 if (elf64_alpha_use_secureplt
2868 && !add_dynamic_entry (DT_ALPHA_PLTRO, 1))
2869 return FALSE;
a7519a3c 2870 }
252b5132 2871
a7519a3c
RH
2872 if (!add_dynamic_entry (DT_RELA, 0)
2873 || !add_dynamic_entry (DT_RELASZ, 0)
2874 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
2875 return FALSE;
2876
2877 if (info->flags & DF_TEXTREL)
2878 {
2879 if (!add_dynamic_entry (DT_TEXTREL, 0))
2880 return FALSE;
252b5132
RH
2881 }
2882 }
a7519a3c 2883#undef add_dynamic_entry
252b5132 2884
b34976b6 2885 return TRUE;
252b5132 2886}
a7519a3c
RH
2887\f
2888/* These functions do relaxation for Alpha ELF.
252b5132 2889
a7519a3c
RH
2890 Currently I'm only handling what I can do with existing compiler
2891 and assembler support, which means no instructions are removed,
2892 though some may be nopped. At this time GCC does not emit enough
2893 information to do all of the relaxing that is possible. It will
2894 take some not small amount of work for that to happen.
252b5132 2895
a7519a3c
RH
2896 There are a couple of interesting papers that I once read on this
2897 subject, that I cannot find references to at the moment, that
2898 related to Alpha in particular. They are by David Wall, then of
2899 DEC WRL. */
252b5132 2900
a7519a3c
RH
2901struct alpha_relax_info
2902{
2903 bfd *abfd;
2904 asection *sec;
2905 bfd_byte *contents;
2906 Elf_Internal_Shdr *symtab_hdr;
2907 Elf_Internal_Rela *relocs, *relend;
2908 struct bfd_link_info *link_info;
2909 bfd_vma gp;
2910 bfd *gotobj;
2911 asection *tsec;
2912 struct alpha_elf_link_hash_entry *h;
2913 struct alpha_elf_got_entry **first_gotent;
2914 struct alpha_elf_got_entry *gotent;
2915 bfd_boolean changed_contents;
2916 bfd_boolean changed_relocs;
2917 unsigned char other;
2918};
252b5132 2919
a7519a3c
RH
2920static Elf_Internal_Rela *
2921elf64_alpha_find_reloc_at_ofs (Elf_Internal_Rela *rel,
2922 Elf_Internal_Rela *relend,
2923 bfd_vma offset, int type)
2924{
2925 while (rel < relend)
252b5132 2926 {
a7519a3c
RH
2927 if (rel->r_offset == offset
2928 && ELF64_R_TYPE (rel->r_info) == (unsigned int) type)
2929 return rel;
2930 ++rel;
2931 }
2932 return NULL;
2933}
252b5132 2934
a7519a3c
RH
2935static bfd_boolean
2936elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
2937 Elf_Internal_Rela *irel, unsigned long r_type)
2938{
2939 unsigned int insn;
2940 bfd_signed_vma disp;
252b5132 2941
a7519a3c
RH
2942 /* Get the instruction. */
2943 insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
252b5132 2944
a7519a3c
RH
2945 if (insn >> 26 != OP_LDQ)
2946 {
2947 reloc_howto_type *howto = elf64_alpha_howto_table + r_type;
2948 ((*_bfd_error_handler)
2949 ("%B: %A+0x%lx: warning: %s relocation against unexpected insn",
2950 info->abfd, info->sec,
2951 (unsigned long) irel->r_offset, howto->name));
2952 return TRUE;
2953 }
252b5132 2954
a7519a3c
RH
2955 /* Can't relax dynamic symbols. */
2956 if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
2957 return TRUE;
252b5132 2958
a7519a3c
RH
2959 /* Can't use local-exec relocations in shared libraries. */
2960 if (r_type == R_ALPHA_GOTTPREL && info->link_info->shared)
2961 return TRUE;
252b5132 2962
a7519a3c
RH
2963 if (r_type == R_ALPHA_LITERAL)
2964 {
2965 /* Look for nice constant addresses. This includes the not-uncommon
2966 special case of 0 for undefweak symbols. */
2967 if ((info->h && info->h->root.root.type == bfd_link_hash_undefweak)
2968 || (!info->link_info->shared
2969 && (symval >= (bfd_vma)-0x8000 || symval < 0x8000)))
2970 {
2971 disp = 0;
2972 insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
2973 insn |= (symval & 0xffff);
2974 r_type = R_ALPHA_NONE;
2975 }
2976 else
2977 {
2978 disp = symval - info->gp;
2979 insn = (OP_LDA << 26) | (insn & 0x03ff0000);
2980 r_type = R_ALPHA_GPREL16;
2981 }
252b5132
RH
2982 }
2983 else
252b5132 2984 {
a7519a3c 2985 bfd_vma dtp_base, tp_base;
252b5132 2986
a7519a3c
RH
2987 BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
2988 dtp_base = alpha_get_dtprel_base (info->link_info);
2989 tp_base = alpha_get_tprel_base (info->link_info);
2990 disp = symval - (r_type == R_ALPHA_GOTDTPREL ? dtp_base : tp_base);
252b5132 2991
a7519a3c 2992 insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
252b5132 2993
a7519a3c
RH
2994 switch (r_type)
2995 {
2996 case R_ALPHA_GOTDTPREL:
2997 r_type = R_ALPHA_DTPREL16;
2998 break;
2999 case R_ALPHA_GOTTPREL:
3000 r_type = R_ALPHA_TPREL16;
3001 break;
3002 default:
3003 BFD_ASSERT (0);
3004 return FALSE;
3005 }
3006 }
252b5132 3007
a7519a3c 3008 if (disp < -0x8000 || disp >= 0x8000)
b34976b6 3009 return TRUE;
252b5132 3010
a7519a3c
RH
3011 bfd_put_32 (info->abfd, (bfd_vma) insn, info->contents + irel->r_offset);
3012 info->changed_contents = TRUE;
252b5132 3013
a7519a3c
RH
3014 /* Reduce the use count on this got entry by one, possibly
3015 eliminating it. */
3016 if (--info->gotent->use_count == 0)
252b5132 3017 {
a7519a3c
RH
3018 int sz = alpha_got_entry_size (r_type);
3019 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3020 if (!info->h)
3021 alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
252b5132 3022 }
252b5132 3023
a7519a3c
RH
3024 /* Smash the existing GOT relocation for its 16-bit immediate pair. */
3025 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), r_type);
3026 info->changed_relocs = TRUE;
3027
3028 /* ??? Search forward through this basic block looking for insns
3029 that use the target register. Stop after an insn modifying the
3030 register is seen, or after a branch or call.
252b5132 3031
a7519a3c
RH
3032 Any such memory load insn may be substituted by a load directly
3033 off the GP. This allows the memory load insn to be issued before
3034 the calculated GP register would otherwise be ready.
252b5132 3035
a7519a3c
RH
3036 Any such jsr insn can be replaced by a bsr if it is in range.
3037
3038 This would mean that we'd have to _add_ relocations, the pain of
3039 which gives one pause. */
252b5132 3040
b34976b6 3041 return TRUE;
252b5132
RH
3042}
3043
a7519a3c
RH
3044static bfd_vma
3045elf64_alpha_relax_opt_call (struct alpha_relax_info *info, bfd_vma symval)
252b5132 3046{
a7519a3c
RH
3047 /* If the function has the same gp, and we can identify that the
3048 function does not use its function pointer, we can eliminate the
3049 address load. */
252b5132 3050
a7519a3c
RH
3051 /* If the symbol is marked NOPV, we are being told the function never
3052 needs its procedure value. */
3053 if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV)
3054 return symval;
252b5132 3055
a7519a3c
RH
3056 /* If the symbol is marked STD_GP, we are being told the function does
3057 a normal ldgp in the first two words. */
3058 else if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD)
3059 ;
252b5132 3060
a7519a3c
RH
3061 /* Otherwise, we may be able to identify a GP load in the first two
3062 words, which we can then skip. */
3063 else
252b5132 3064 {
a7519a3c
RH
3065 Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp;
3066 bfd_vma ofs;
252b5132 3067
a7519a3c
RH
3068 /* Load the relocations from the section that the target symbol is in. */
3069 if (info->sec == info->tsec)
252b5132 3070 {
a7519a3c
RH
3071 tsec_relocs = info->relocs;
3072 tsec_relend = info->relend;
3073 tsec_free = NULL;
3074 }
3075 else
3076 {
3077 tsec_relocs = (_bfd_elf_link_read_relocs
3078 (info->abfd, info->tsec, (PTR) NULL,
3079 (Elf_Internal_Rela *) NULL,
3080 info->link_info->keep_memory));
3081 if (tsec_relocs == NULL)
3082 return 0;
3083 tsec_relend = tsec_relocs + info->tsec->reloc_count;
3084 tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs);
3085 }
252b5132 3086
a7519a3c
RH
3087 /* Recover the symbol's offset within the section. */
3088 ofs = (symval - info->tsec->output_section->vma
3089 - info->tsec->output_offset);
252b5132 3090
a7519a3c
RH
3091 /* Look for a GPDISP reloc. */
3092 gpdisp = (elf64_alpha_find_reloc_at_ofs
3093 (tsec_relocs, tsec_relend, ofs, R_ALPHA_GPDISP));
252b5132 3094
a7519a3c
RH
3095 if (!gpdisp || gpdisp->r_addend != 4)
3096 {
3097 if (tsec_free)
3098 free (tsec_free);
3099 return 0;
252b5132 3100 }
a7519a3c
RH
3101 if (tsec_free)
3102 free (tsec_free);
252b5132
RH
3103 }
3104
a7519a3c
RH
3105 /* We've now determined that we can skip an initial gp load. Verify
3106 that the call and the target use the same gp. */
3107 if (info->link_info->hash->creator != info->tsec->owner->xvec
3108 || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
3109 return 0;
252b5132 3110
a7519a3c
RH
3111 return symval + 8;
3112}
252b5132 3113
a7519a3c
RH
3114static bfd_boolean
3115elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
3116 bfd_vma symval, Elf_Internal_Rela *irel)
252b5132 3117{
a7519a3c
RH
3118 Elf_Internal_Rela *urel, *irelend = info->relend;
3119 int flags, count, i;
3120 bfd_signed_vma disp;
3121 bfd_boolean fits16;
3122 bfd_boolean fits32;
3123 bfd_boolean lit_reused = FALSE;
3124 bfd_boolean all_optimized = TRUE;
3125 unsigned int lit_insn;
252b5132 3126
a7519a3c
RH
3127 lit_insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
3128 if (lit_insn >> 26 != OP_LDQ)
3129 {
3130 ((*_bfd_error_handler)
3131 ("%B: %A+0x%lx: warning: LITERAL relocation against unexpected insn",
3132 info->abfd, info->sec,
3133 (unsigned long) irel->r_offset));
3134 return TRUE;
3135 }
252b5132 3136
a7519a3c
RH
3137 /* Can't relax dynamic symbols. */
3138 if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
3139 return TRUE;
3140
3141 /* Summarize how this particular LITERAL is used. */
3142 for (urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count)
252b5132 3143 {
a7519a3c
RH
3144 if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE)
3145 break;
8288a39e 3146 if (urel->r_addend <= 6)
a7519a3c
RH
3147 flags |= 1 << urel->r_addend;
3148 }
252b5132 3149
a7519a3c
RH
3150 /* A little preparation for the loop... */
3151 disp = symval - info->gp;
252b5132 3152
a7519a3c
RH
3153 for (urel = irel+1, i = 0; i < count; ++i, ++urel)
3154 {
3155 unsigned int insn;
3156 int insn_disp;
3157 bfd_signed_vma xdisp;
252b5132 3158
a7519a3c 3159 insn = bfd_get_32 (info->abfd, info->contents + urel->r_offset);
252b5132 3160
a7519a3c
RH
3161 switch (urel->r_addend)
3162 {
3163 case LITUSE_ALPHA_ADDR:
3164 default:
3165 /* This type is really just a placeholder to note that all
3166 uses cannot be optimized, but to still allow some. */
3167 all_optimized = FALSE;
3168 break;
252b5132 3169
a7519a3c
RH
3170 case LITUSE_ALPHA_BASE:
3171 /* We can always optimize 16-bit displacements. */
252b5132 3172
a7519a3c
RH
3173 /* Extract the displacement from the instruction, sign-extending
3174 it if necessary, then test whether it is within 16 or 32 bits
3175 displacement from GP. */
3176 insn_disp = ((insn & 0xffff) ^ 0x8000) - 0x8000;
3177
3178 xdisp = disp + insn_disp;
3179 fits16 = (xdisp >= - (bfd_signed_vma) 0x8000 && xdisp < 0x8000);
3180 fits32 = (xdisp >= - (bfd_signed_vma) 0x80000000
3181 && xdisp < 0x7fff8000);
3182
3183 if (fits16)
3184 {
3185 /* Take the op code and dest from this insn, take the base
3186 register from the literal insn. Leave the offset alone. */
3187 insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
3188 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3189 R_ALPHA_GPREL16);
3190 urel->r_addend = irel->r_addend;
3191 info->changed_relocs = TRUE;
252b5132 3192
a7519a3c
RH
3193 bfd_put_32 (info->abfd, (bfd_vma) insn,
3194 info->contents + urel->r_offset);
3195 info->changed_contents = TRUE;
252b5132 3196 }
252b5132 3197
a7519a3c
RH
3198 /* If all mem+byte, we can optimize 32-bit mem displacements. */
3199 else if (fits32 && !(flags & ~6))
3200 {
3201 /* FIXME: sanity check that lit insn Ra is mem insn Rb. */
252b5132 3202
a7519a3c
RH
3203 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3204 R_ALPHA_GPRELHIGH);
3205 lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
3206 bfd_put_32 (info->abfd, (bfd_vma) lit_insn,
3207 info->contents + irel->r_offset);
3208 lit_reused = TRUE;
3209 info->changed_contents = TRUE;
252b5132 3210
a7519a3c
RH
3211 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3212 R_ALPHA_GPRELLOW);
3213 urel->r_addend = irel->r_addend;
3214 info->changed_relocs = TRUE;
3215 }
3216 else
3217 all_optimized = FALSE;
3218 break;
252b5132 3219
a7519a3c
RH
3220 case LITUSE_ALPHA_BYTOFF:
3221 /* We can always optimize byte instructions. */
252b5132 3222
a7519a3c
RH
3223 /* FIXME: sanity check the insn for byte op. Check that the
3224 literal dest reg is indeed Rb in the byte insn. */
252b5132 3225
a7519a3c
RH
3226 insn &= ~ (unsigned) 0x001ff000;
3227 insn |= ((symval & 7) << 13) | 0x1000;
252b5132 3228
a7519a3c
RH
3229 urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3230 urel->r_addend = 0;
3231 info->changed_relocs = TRUE;
e92d460e 3232
a7519a3c
RH
3233 bfd_put_32 (info->abfd, (bfd_vma) insn,
3234 info->contents + urel->r_offset);
3235 info->changed_contents = TRUE;
3236 break;
252b5132 3237
a7519a3c
RH
3238 case LITUSE_ALPHA_JSR:
3239 case LITUSE_ALPHA_TLSGD:
3240 case LITUSE_ALPHA_TLSLDM:
8288a39e 3241 case LITUSE_ALPHA_JSRDIRECT:
0d5f9994 3242 {
a7519a3c
RH
3243 bfd_vma optdest, org;
3244 bfd_signed_vma odisp;
252b5132 3245
a7519a3c
RH
3246 /* For undefined weak symbols, we're mostly interested in getting
3247 rid of the got entry whenever possible, so optimize this to a
3248 use of the zero register. */
3249 if (info->h && info->h->root.root.type == bfd_link_hash_undefweak)
3250 {
3251 insn |= 31 << 16;
3252 bfd_put_32 (info->abfd, (bfd_vma) insn,
3253 info->contents + urel->r_offset);
252b5132 3254
a7519a3c
RH
3255 info->changed_contents = TRUE;
3256 break;
3257 }
252b5132 3258
a7519a3c
RH
3259 /* If not zero, place to jump without needing pv. */
3260 optdest = elf64_alpha_relax_opt_call (info, symval);
3261 org = (info->sec->output_section->vma
3262 + info->sec->output_offset
3263 + urel->r_offset + 4);
3264 odisp = (optdest ? optdest : symval) - org;
252b5132 3265
a7519a3c
RH
3266 if (odisp >= -0x400000 && odisp < 0x400000)
3267 {
3268 Elf_Internal_Rela *xrel;
252b5132 3269
a7519a3c
RH
3270 /* Preserve branch prediction call stack when possible. */
3271 if ((insn & INSN_JSR_MASK) == INSN_JSR)
3272 insn = (OP_BSR << 26) | (insn & 0x03e00000);
3273 else
3274 insn = (OP_BR << 26) | (insn & 0x03e00000);
252b5132 3275
a7519a3c
RH
3276 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3277 R_ALPHA_BRADDR);
3278 urel->r_addend = irel->r_addend;
252b5132 3279
a7519a3c
RH
3280 if (optdest)
3281 urel->r_addend += optdest - symval;
3282 else
3283 all_optimized = FALSE;
252b5132 3284
a7519a3c
RH
3285 bfd_put_32 (info->abfd, (bfd_vma) insn,
3286 info->contents + urel->r_offset);
252b5132 3287
a7519a3c
RH
3288 /* Kill any HINT reloc that might exist for this insn. */
3289 xrel = (elf64_alpha_find_reloc_at_ofs
3290 (info->relocs, info->relend, urel->r_offset,
3291 R_ALPHA_HINT));
3292 if (xrel)
3293 xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
252b5132 3294
a7519a3c
RH
3295 info->changed_contents = TRUE;
3296 info->changed_relocs = TRUE;
3297 }
3298 else
3299 all_optimized = FALSE;
252b5132 3300
a7519a3c
RH
3301 /* Even if the target is not in range for a direct branch,
3302 if we share a GP, we can eliminate the gp reload. */
3303 if (optdest)
3304 {
3305 Elf_Internal_Rela *gpdisp
3306 = (elf64_alpha_find_reloc_at_ofs
3307 (info->relocs, irelend, urel->r_offset + 4,
3308 R_ALPHA_GPDISP));
3309 if (gpdisp)
3310 {
3311 bfd_byte *p_ldah = info->contents + gpdisp->r_offset;
3312 bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
3313 unsigned int ldah = bfd_get_32 (info->abfd, p_ldah);
3314 unsigned int lda = bfd_get_32 (info->abfd, p_lda);
252b5132 3315
a7519a3c
RH
3316 /* Verify that the instruction is "ldah $29,0($26)".
3317 Consider a function that ends in a noreturn call,
3318 and that the next function begins with an ldgp,
3319 and that by accident there is no padding between.
3320 In that case the insn would use $27 as the base. */
3321 if (ldah == 0x27ba0000 && lda == 0x23bd0000)
3322 {
3323 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_ldah);
3324 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_lda);
252b5132 3325
a7519a3c
RH
3326 gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3327 info->changed_contents = TRUE;
3328 info->changed_relocs = TRUE;
3329 }
3330 }
3331 }
3332 }
3333 break;
252b5132 3334 }
252b5132
RH
3335 }
3336
a7519a3c
RH
3337 /* If all cases were optimized, we can reduce the use count on this
3338 got entry by one, possibly eliminating it. */
3339 if (all_optimized)
252b5132 3340 {
a7519a3c 3341 if (--info->gotent->use_count == 0)
252b5132 3342 {
a7519a3c
RH
3343 int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
3344 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3345 if (!info->h)
3346 alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
252b5132 3347 }
a7519a3c
RH
3348
3349 /* If the literal instruction is no longer needed (it may have been
3350 reused. We can eliminate it. */
3351 /* ??? For now, I don't want to deal with compacting the section,
3352 so just nop it out. */
3353 if (!lit_reused)
252b5132 3354 {
a7519a3c
RH
3355 irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3356 info->changed_relocs = TRUE;
252b5132 3357
a7519a3c
RH
3358 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP,
3359 info->contents + irel->r_offset);
3360 info->changed_contents = TRUE;
3361 }
252b5132 3362
a7519a3c
RH
3363 return TRUE;
3364 }
3365 else
3366 return elf64_alpha_relax_got_load (info, symval, irel, R_ALPHA_LITERAL);
252b5132
RH
3367}
3368
b34976b6 3369static bfd_boolean
a7519a3c
RH
3370elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval,
3371 Elf_Internal_Rela *irel, bfd_boolean is_gd)
f44f99a5 3372{
a7519a3c
RH
3373 bfd_byte *pos[5];
3374 unsigned int insn;
3375 Elf_Internal_Rela *gpdisp, *hint;
3376 bfd_boolean dynamic, use_gottprel, pos1_unusable;
3377 unsigned long new_symndx;
f44f99a5 3378
a7519a3c 3379 dynamic = alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info);
f44f99a5 3380
a7519a3c
RH
3381 /* If a TLS symbol is accessed using IE at least once, there is no point
3382 to use dynamic model for it. */
3383 if (is_gd && info->h && (info->h->flags & ALPHA_ELF_LINK_HASH_TLS_IE))
3384 ;
f44f99a5 3385
a7519a3c
RH
3386 /* If the symbol is local, and we've already committed to DF_STATIC_TLS,
3387 then we might as well relax to IE. */
3388 else if (info->link_info->shared && !dynamic
3389 && (info->link_info->flags & DF_STATIC_TLS))
3390 ;
f44f99a5 3391
a7519a3c
RH
3392 /* Otherwise we must be building an executable to do anything. */
3393 else if (info->link_info->shared)
3394 return TRUE;
f44f99a5 3395
a7519a3c
RH
3396 /* The TLSGD/TLSLDM relocation must be followed by a LITERAL and
3397 the matching LITUSE_TLS relocations. */
3398 if (irel + 2 >= info->relend)
3399 return TRUE;
3400 if (ELF64_R_TYPE (irel[1].r_info) != R_ALPHA_LITERAL
3401 || ELF64_R_TYPE (irel[2].r_info) != R_ALPHA_LITUSE
3402 || irel[2].r_addend != (is_gd ? LITUSE_ALPHA_TLSGD : LITUSE_ALPHA_TLSLDM))
3403 return TRUE;
f44f99a5 3404
a7519a3c
RH
3405 /* There must be a GPDISP relocation positioned immediately after the
3406 LITUSE relocation. */
3407 gpdisp = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
3408 irel[2].r_offset + 4, R_ALPHA_GPDISP);
3409 if (!gpdisp)
b34976b6 3410 return TRUE;
f44f99a5 3411
a7519a3c
RH
3412 pos[0] = info->contents + irel[0].r_offset;
3413 pos[1] = info->contents + irel[1].r_offset;
3414 pos[2] = info->contents + irel[2].r_offset;
3415 pos[3] = info->contents + gpdisp->r_offset;
3416 pos[4] = pos[3] + gpdisp->r_addend;
3417 pos1_unusable = FALSE;
f44f99a5 3418
a7519a3c
RH
3419 /* Generally, the positions are not allowed to be out of order, lest the
3420 modified insn sequence have different register lifetimes. We can make
3421 an exception when pos 1 is adjacent to pos 0. */
3422 if (pos[1] + 4 == pos[0])
f44f99a5 3423 {
a7519a3c
RH
3424 bfd_byte *tmp = pos[0];
3425 pos[0] = pos[1];
3426 pos[1] = tmp;
f44f99a5 3427 }
a7519a3c
RH
3428 else if (pos[1] < pos[0])
3429 pos1_unusable = TRUE;
3430 if (pos[1] >= pos[2] || pos[2] >= pos[3])
3431 return TRUE;
cc03ec80 3432
a7519a3c
RH
3433 /* Reduce the use count on the LITERAL relocation. Do this before we
3434 smash the symndx when we adjust the relocations below. */
3435 {
3436 struct alpha_elf_got_entry *lit_gotent;
3437 struct alpha_elf_link_hash_entry *lit_h;
3438 unsigned long indx;
f44f99a5 3439
a7519a3c
RH
3440 BFD_ASSERT (ELF64_R_SYM (irel[1].r_info) >= info->symtab_hdr->sh_info);
3441 indx = ELF64_R_SYM (irel[1].r_info) - info->symtab_hdr->sh_info;
3442 lit_h = alpha_elf_sym_hashes (info->abfd)[indx];
f44f99a5 3443
a7519a3c
RH
3444 while (lit_h->root.root.type == bfd_link_hash_indirect
3445 || lit_h->root.root.type == bfd_link_hash_warning)
3446 lit_h = (struct alpha_elf_link_hash_entry *) lit_h->root.root.u.i.link;
252b5132 3447
a7519a3c
RH
3448 for (lit_gotent = lit_h->got_entries; lit_gotent ;
3449 lit_gotent = lit_gotent->next)
3450 if (lit_gotent->gotobj == info->gotobj
3451 && lit_gotent->reloc_type == R_ALPHA_LITERAL
3452 && lit_gotent->addend == irel[1].r_addend)
3453 break;
3454 BFD_ASSERT (lit_gotent);
252b5132 3455
a7519a3c
RH
3456 if (--lit_gotent->use_count == 0)
3457 {
3458 int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
3459 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3460 }
3461 }
252b5132 3462
a7519a3c 3463 /* Change
252b5132 3464
a7519a3c
RH
3465 lda $16,x($gp) !tlsgd!1
3466 ldq $27,__tls_get_addr($gp) !literal!1
3467 jsr $26,($27),__tls_get_addr !lituse_tlsgd!1
3468 ldah $29,0($26) !gpdisp!2
3469 lda $29,0($29) !gpdisp!2
3470 to
3471 ldq $16,x($gp) !gottprel
3472 unop
3473 call_pal rduniq
3474 addq $16,$0,$0
3475 unop
3476 or the first pair to
3477 lda $16,x($gp) !tprel
3478 unop
3479 or
3480 ldah $16,x($gp) !tprelhi
3481 lda $16,x($16) !tprello
3482
3483 as appropriate. */
3484
3485 use_gottprel = FALSE;
3486 new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : 0;
3487 switch (!dynamic && !info->link_info->shared)
252b5132 3488 {
a7519a3c
RH
3489 case 1:
3490 {
3491 bfd_vma tp_base;
3492 bfd_signed_vma disp;
252b5132 3493
a7519a3c
RH
3494 BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
3495 tp_base = alpha_get_tprel_base (info->link_info);
3496 disp = symval - tp_base;
252b5132 3497
a7519a3c
RH
3498 if (disp >= -0x8000 && disp < 0x8000)
3499 {
3500 insn = (OP_LDA << 26) | (16 << 21) | (31 << 16);
3501 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
3502 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
3765b1be 3503
a7519a3c
RH
3504 irel[0].r_offset = pos[0] - info->contents;
3505 irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPREL16);
3506 irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3507 break;
3508 }
3509 else if (disp >= -(bfd_signed_vma) 0x80000000
3510 && disp < (bfd_signed_vma) 0x7fff8000
3511 && !pos1_unusable)
3512 {
3513 insn = (OP_LDAH << 26) | (16 << 21) | (31 << 16);
3514 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
3515 insn = (OP_LDA << 26) | (16 << 21) | (16 << 16);
3516 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[1]);
3765b1be 3517
a7519a3c
RH
3518 irel[0].r_offset = pos[0] - info->contents;
3519 irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELHI);
3520 irel[1].r_offset = pos[1] - info->contents;
3521 irel[1].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELLO);
3522 break;
3523 }
3524 }
3525 /* FALLTHRU */
3765b1be 3526
3765b1be 3527 default:
a7519a3c
RH
3528 use_gottprel = TRUE;
3529
3530 insn = (OP_LDQ << 26) | (16 << 21) | (29 << 16);
3531 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
3532 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
3533
3534 irel[0].r_offset = pos[0] - info->contents;
3535 irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_GOTTPREL);
3536 irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3537 break;
3765b1be 3538 }
3765b1be 3539
a7519a3c 3540 bfd_put_32 (info->abfd, (bfd_vma) INSN_RDUNIQ, pos[2]);
252b5132 3541
a7519a3c
RH
3542 insn = INSN_ADDQ | (16 << 21) | (0 << 16) | (0 << 0);
3543 bfd_put_32 (info->abfd, (bfd_vma) insn, pos[3]);
3765b1be 3544
a7519a3c 3545 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[4]);
e92d460e 3546
a7519a3c
RH
3547 irel[2].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3548 gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
252b5132 3549
a7519a3c
RH
3550 hint = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
3551 irel[2].r_offset, R_ALPHA_HINT);
3552 if (hint)
3553 hint->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
252b5132 3554
a7519a3c
RH
3555 info->changed_contents = TRUE;
3556 info->changed_relocs = TRUE;
d6ad34f6 3557
a7519a3c
RH
3558 /* Reduce the use count on the TLSGD/TLSLDM relocation. */
3559 if (--info->gotent->use_count == 0)
3765b1be 3560 {
a7519a3c
RH
3561 int sz = alpha_got_entry_size (info->gotent->reloc_type);
3562 alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3563 if (!info->h)
3564 alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
3765b1be 3565 }
252b5132 3566
a7519a3c
RH
3567 /* If we've switched to a GOTTPREL relocation, increment the reference
3568 count on that got entry. */
3569 if (use_gottprel)
f44f99a5 3570 {
a7519a3c 3571 struct alpha_elf_got_entry *tprel_gotent;
f44f99a5 3572
a7519a3c
RH
3573 for (tprel_gotent = *info->first_gotent; tprel_gotent ;
3574 tprel_gotent = tprel_gotent->next)
3575 if (tprel_gotent->gotobj == info->gotobj
3576 && tprel_gotent->reloc_type == R_ALPHA_GOTTPREL
3577 && tprel_gotent->addend == irel->r_addend)
3578 break;
3579 if (tprel_gotent)
3580 tprel_gotent->use_count++;
3581 else
f44f99a5 3582 {
a7519a3c
RH
3583 if (info->gotent->use_count == 0)
3584 tprel_gotent = info->gotent;
3585 else
3586 {
3587 tprel_gotent = (struct alpha_elf_got_entry *)
3588 bfd_alloc (info->abfd, sizeof (struct alpha_elf_got_entry));
3589 if (!tprel_gotent)
3590 return FALSE;
f44f99a5 3591
a7519a3c
RH
3592 tprel_gotent->next = *info->first_gotent;
3593 *info->first_gotent = tprel_gotent;
f44f99a5 3594
a7519a3c
RH
3595 tprel_gotent->gotobj = info->gotobj;
3596 tprel_gotent->addend = irel->r_addend;
3597 tprel_gotent->got_offset = -1;
3598 tprel_gotent->reloc_done = 0;
3599 tprel_gotent->reloc_xlated = 0;
3600 }
f44f99a5 3601
a7519a3c
RH
3602 tprel_gotent->use_count = 1;
3603 tprel_gotent->reloc_type = R_ALPHA_GOTTPREL;
3604 }
f44f99a5 3605 }
f44f99a5 3606
b34976b6 3607 return TRUE;
f44f99a5
RH
3608}
3609
b34976b6 3610static bfd_boolean
a7519a3c
RH
3611elf64_alpha_relax_section (bfd *abfd, asection *sec,
3612 struct bfd_link_info *link_info, bfd_boolean *again)
f44f99a5 3613{
a7519a3c
RH
3614 Elf_Internal_Shdr *symtab_hdr;
3615 Elf_Internal_Rela *internal_relocs;
3616 Elf_Internal_Rela *irel, *irelend;
3617 Elf_Internal_Sym *isymbuf = NULL;
3618 struct alpha_elf_got_entry **local_got_entries;
3619 struct alpha_relax_info info;
f44f99a5 3620
4a828aab 3621 /* There's nothing to change, yet. */
a7519a3c 3622 *again = FALSE;
f44f99a5 3623
a7519a3c
RH
3624 if (link_info->relocatable
3625 || ((sec->flags & (SEC_CODE | SEC_RELOC | SEC_ALLOC))
3626 != (SEC_CODE | SEC_RELOC | SEC_ALLOC))
3627 || sec->reloc_count == 0)
d6ad34f6
RH
3628 return TRUE;
3629
0ffa91dd
NC
3630 BFD_ASSERT (is_alpha_elf (abfd));
3631
4a828aab
RH
3632 /* Make sure our GOT and PLT tables are up-to-date. */
3633 if (alpha_elf_hash_table(link_info)->relax_trip != link_info->relax_trip)
3634 {
3635 alpha_elf_hash_table(link_info)->relax_trip = link_info->relax_trip;
3636
3637 /* This should never fail after the initial round, since the only
3638 error is GOT overflow, and relaxation only shrinks the table. */
3639 if (!elf64_alpha_size_got_sections (link_info))
3640 abort ();
3641 if (elf_hash_table (link_info)->dynamic_sections_created)
3642 {
3643 elf64_alpha_size_plt_section (link_info);
3644 elf64_alpha_size_rela_got_section (link_info);
3645 }
3646 }
3647
0ffa91dd 3648 symtab_hdr = &elf_symtab_hdr (abfd);
a7519a3c 3649 local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
252b5132 3650
a7519a3c
RH
3651 /* Load the relocations for this section. */
3652 internal_relocs = (_bfd_elf_link_read_relocs
3653 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
3654 link_info->keep_memory));
3655 if (internal_relocs == NULL)
3656 return FALSE;
252b5132 3657
a7519a3c
RH
3658 memset(&info, 0, sizeof (info));
3659 info.abfd = abfd;
3660 info.sec = sec;
3661 info.link_info = link_info;
3662 info.symtab_hdr = symtab_hdr;
3663 info.relocs = internal_relocs;
3664 info.relend = irelend = internal_relocs + sec->reloc_count;
3665
3666 /* Find the GP for this object. Do not store the result back via
3667 _bfd_set_gp_value, since this could change again before final. */
3668 info.gotobj = alpha_elf_tdata (abfd)->gotobj;
3669 if (info.gotobj)
3765b1be 3670 {
a7519a3c
RH
3671 asection *sgot = alpha_elf_tdata (info.gotobj)->got;
3672 info.gp = (sgot->output_section->vma
3673 + sgot->output_offset
3674 + 0x8000);
252b5132
RH
3675 }
3676
a7519a3c
RH
3677 /* Get the section contents. */
3678 if (elf_section_data (sec)->this_hdr.contents != NULL)
3679 info.contents = elf_section_data (sec)->this_hdr.contents;
3680 else
3681 {
3682 if (!bfd_malloc_and_get_section (abfd, sec, &info.contents))
3683 goto error_return;
3684 }
252b5132 3685
a7519a3c
RH
3686 for (irel = internal_relocs; irel < irelend; irel++)
3687 {
3688 bfd_vma symval;
3689 struct alpha_elf_got_entry *gotent;
3690 unsigned long r_type = ELF64_R_TYPE (irel->r_info);
3691 unsigned long r_symndx = ELF64_R_SYM (irel->r_info);
3692
3693 /* Early exit for unhandled or unrelaxable relocations. */
3694 switch (r_type)
3695 {
3696 case R_ALPHA_LITERAL:
3697 case R_ALPHA_GPRELHIGH:
3698 case R_ALPHA_GPRELLOW:
3699 case R_ALPHA_GOTDTPREL:
3700 case R_ALPHA_GOTTPREL:
3701 case R_ALPHA_TLSGD:
3702 break;
3703
3704 case R_ALPHA_TLSLDM:
3705 /* The symbol for a TLSLDM reloc is ignored. Collapse the
3706 reloc to the 0 symbol so that they all match. */
3707 r_symndx = 0;
3708 break;
3709
3710 default:
3711 continue;
3712 }
3713
3714 /* Get the value of the symbol referred to by the reloc. */
3715 if (r_symndx < symtab_hdr->sh_info)
3716 {
3717 /* A local symbol. */
3718 Elf_Internal_Sym *isym;
3719
3720 /* Read this BFD's local symbols. */
3721 if (isymbuf == NULL)
3722 {
3723 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
3724 if (isymbuf == NULL)
3725 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
3726 symtab_hdr->sh_info, 0,
3727 NULL, NULL, NULL);
3728 if (isymbuf == NULL)
3729 goto error_return;
3730 }
252b5132 3731
a7519a3c 3732 isym = isymbuf + r_symndx;
252b5132 3733
a7519a3c
RH
3734 /* Given the symbol for a TLSLDM reloc is ignored, this also
3735 means forcing the symbol value to the tp base. */
3736 if (r_type == R_ALPHA_TLSLDM)
3737 {
3738 info.tsec = bfd_abs_section_ptr;
3739 symval = alpha_get_tprel_base (info.link_info);
3740 }
3741 else
3742 {
3743 symval = isym->st_value;
3744 if (isym->st_shndx == SHN_UNDEF)
3745 continue;
3746 else if (isym->st_shndx == SHN_ABS)
3747 info.tsec = bfd_abs_section_ptr;
3748 else if (isym->st_shndx == SHN_COMMON)
3749 info.tsec = bfd_com_section_ptr;
3750 else
3751 info.tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3752 }
252b5132 3753
a7519a3c
RH
3754 info.h = NULL;
3755 info.other = isym->st_other;
3756 if (local_got_entries)
3757 info.first_gotent = &local_got_entries[r_symndx];
3758 else
3759 {
3760 info.first_gotent = &info.gotent;
3761 info.gotent = NULL;
3762 }
252b5132 3763 }
a7519a3c
RH
3764 else
3765 {
3766 unsigned long indx;
3767 struct alpha_elf_link_hash_entry *h;
252b5132 3768
a7519a3c
RH
3769 indx = r_symndx - symtab_hdr->sh_info;
3770 h = alpha_elf_sym_hashes (abfd)[indx];
3771 BFD_ASSERT (h != NULL);
252b5132 3772
a7519a3c
RH
3773 while (h->root.root.type == bfd_link_hash_indirect
3774 || h->root.root.type == bfd_link_hash_warning)
3775 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
252b5132 3776
a7519a3c
RH
3777 /* If the symbol is undefined, we can't do anything with it. */
3778 if (h->root.root.type == bfd_link_hash_undefined)
3779 continue;
252b5132 3780
a7519a3c
RH
3781 /* If the symbol isn't defined in the current module,
3782 again we can't do anything. */
3783 if (h->root.root.type == bfd_link_hash_undefweak)
3784 {
3785 info.tsec = bfd_abs_section_ptr;
3786 symval = 0;
3787 }
3788 else if (!h->root.def_regular)
3789 {
3790 /* Except for TLSGD relocs, which can sometimes be
3791 relaxed to GOTTPREL relocs. */
3792 if (r_type != R_ALPHA_TLSGD)
3793 continue;
3794 info.tsec = bfd_abs_section_ptr;
3795 symval = 0;
3796 }
3797 else
3798 {
3799 info.tsec = h->root.root.u.def.section;
3800 symval = h->root.root.u.def.value;
3801 }
252b5132 3802
a7519a3c
RH
3803 info.h = h;
3804 info.other = h->root.other;
3805 info.first_gotent = &h->got_entries;
3806 }
252b5132 3807
a7519a3c
RH
3808 /* Search for the got entry to be used by this relocation. */
3809 for (gotent = *info.first_gotent; gotent ; gotent = gotent->next)
3810 if (gotent->gotobj == info.gotobj
3811 && gotent->reloc_type == r_type
3812 && gotent->addend == irel->r_addend)
3813 break;
3814 info.gotent = gotent;
252b5132 3815
a7519a3c
RH
3816 symval += info.tsec->output_section->vma + info.tsec->output_offset;
3817 symval += irel->r_addend;
252b5132 3818
a7519a3c 3819 switch (r_type)
252b5132 3820 {
a7519a3c
RH
3821 case R_ALPHA_LITERAL:
3822 BFD_ASSERT(info.gotent != NULL);
252b5132 3823
a7519a3c
RH
3824 /* If there exist LITUSE relocations immediately following, this
3825 opens up all sorts of interesting optimizations, because we
3826 now know every location that this address load is used. */
3827 if (irel+1 < irelend
3828 && ELF64_R_TYPE (irel[1].r_info) == R_ALPHA_LITUSE)
252b5132 3829 {
a7519a3c
RH
3830 if (!elf64_alpha_relax_with_lituse (&info, symval, irel))
3831 goto error_return;
252b5132 3832 }
a7519a3c
RH
3833 else
3834 {
3835 if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
3836 goto error_return;
3837 }
3838 break;
252b5132 3839
a7519a3c
RH
3840 case R_ALPHA_GOTDTPREL:
3841 case R_ALPHA_GOTTPREL:
3842 BFD_ASSERT(info.gotent != NULL);
3843 if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
3844 goto error_return;
3845 break;
3846
3847 case R_ALPHA_TLSGD:
3848 case R_ALPHA_TLSLDM:
3849 BFD_ASSERT(info.gotent != NULL);
3850 if (!elf64_alpha_relax_tls_get_addr (&info, symval, irel,
3851 r_type == R_ALPHA_TLSGD))
3852 goto error_return;
3853 break;
252b5132
RH
3854 }
3855 }
3856
a7519a3c
RH
3857 if (isymbuf != NULL
3858 && symtab_hdr->contents != (unsigned char *) isymbuf)
3859 {
3860 if (!link_info->keep_memory)
3861 free (isymbuf);
3862 else
252b5132 3863 {
a7519a3c
RH
3864 /* Cache the symbols for elf_link_input_bfd. */
3865 symtab_hdr->contents = (unsigned char *) isymbuf;
252b5132 3866 }
a7519a3c 3867 }
252b5132 3868
a7519a3c
RH
3869 if (info.contents != NULL
3870 && elf_section_data (sec)->this_hdr.contents != info.contents)
3871 {
3872 if (!info.changed_contents && !link_info->keep_memory)
3873 free (info.contents);
3874 else
252b5132 3875 {
a7519a3c
RH
3876 /* Cache the section contents for elf_link_input_bfd. */
3877 elf_section_data (sec)->this_hdr.contents = info.contents;
252b5132 3878 }
a7519a3c 3879 }
252b5132 3880
a7519a3c
RH
3881 if (elf_section_data (sec)->relocs != internal_relocs)
3882 {
3883 if (!info.changed_relocs)
3884 free (internal_relocs);
3885 else
3886 elf_section_data (sec)->relocs = internal_relocs;
252b5132 3887 }
a7519a3c
RH
3888
3889 *again = info.changed_contents || info.changed_relocs;
252b5132 3890
b34976b6 3891 return TRUE;
252b5132 3892
a7519a3c
RH
3893 error_return:
3894 if (isymbuf != NULL
3895 && symtab_hdr->contents != (unsigned char *) isymbuf)
3896 free (isymbuf);
3897 if (info.contents != NULL
3898 && elf_section_data (sec)->this_hdr.contents != info.contents)
3899 free (info.contents);
3900 if (internal_relocs != NULL
3901 && elf_section_data (sec)->relocs != internal_relocs)
3902 free (internal_relocs);
3903 return FALSE;
3904}
3905\f
1bbc9cec
RH
3906/* Emit a dynamic relocation for (DYNINDX, RTYPE, ADDEND) at (SEC, OFFSET)
3907 into the next available slot in SREL. */
3908
3909static void
a7519a3c
RH
3910elf64_alpha_emit_dynrel (bfd *abfd, struct bfd_link_info *info,
3911 asection *sec, asection *srel, bfd_vma offset,
3912 long dynindx, long rtype, bfd_vma addend)
1bbc9cec
RH
3913{
3914 Elf_Internal_Rela outrel;
3915 bfd_byte *loc;
3916
3917 BFD_ASSERT (srel != NULL);
3918
3919 outrel.r_info = ELF64_R_INFO (dynindx, rtype);
3920 outrel.r_addend = addend;
3921
3922 offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3923 if ((offset | 1) != (bfd_vma) -1)
3924 outrel.r_offset = sec->output_section->vma + sec->output_offset + offset;
3925 else
3926 memset (&outrel, 0, sizeof (outrel));
3927
3928 loc = srel->contents;
3929 loc += srel->reloc_count++ * sizeof (Elf64_External_Rela);
3930 bfd_elf64_swap_reloca_out (abfd, &outrel, loc);
eea6121a 3931 BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count <= srel->size);
1bbc9cec
RH
3932}
3933
4a67a098
RH
3934/* Relocate an Alpha ELF section for a relocatable link.
3935
3936 We don't have to change anything unless the reloc is against a section
3937 symbol, in which case we have to adjust according to where the section
3938 symbol winds up in the output section. */
3939
b34976b6 3940static bfd_boolean
a7519a3c
RH
3941elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED,
3942 struct bfd_link_info *info ATTRIBUTE_UNUSED,
3943 bfd *input_bfd, asection *input_section,
3944 bfd_byte *contents ATTRIBUTE_UNUSED,
3945 Elf_Internal_Rela *relocs,
3946 Elf_Internal_Sym *local_syms,
3947 asection **local_sections)
4a67a098
RH
3948{
3949 unsigned long symtab_hdr_sh_info;
3950 Elf_Internal_Rela *rel;
3951 Elf_Internal_Rela *relend;
ab96bf03 3952 struct elf_link_hash_entry **sym_hashes;
b34976b6 3953 bfd_boolean ret_val = TRUE;
4a67a098 3954
0ffa91dd 3955 symtab_hdr_sh_info = elf_symtab_hdr (input_bfd).sh_info;
ab96bf03 3956 sym_hashes = elf_sym_hashes (input_bfd);
4a67a098
RH
3957
3958 relend = relocs + input_section->reloc_count;
3959 for (rel = relocs; rel < relend; rel++)
3960 {
3961 unsigned long r_symndx;
3962 Elf_Internal_Sym *sym;
3963 asection *sec;
3964 unsigned long r_type;
3965
ab96bf03 3966 r_type = ELF64_R_TYPE (rel->r_info);
4a67a098
RH
3967 if (r_type >= R_ALPHA_max)
3968 {
3969 (*_bfd_error_handler)
d003868e
AM
3970 (_("%B: unknown relocation type %d"),
3971 input_bfd, (int) r_type);
4a67a098 3972 bfd_set_error (bfd_error_bad_value);
b34976b6 3973 ret_val = FALSE;
4a67a098
RH
3974 continue;
3975 }
3976
4a67a098
RH
3977 /* The symbol associated with GPDISP and LITUSE is
3978 immaterial. Only the addend is significant. */
3979 if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE)
3980 continue;
3981
ab96bf03 3982 r_symndx = ELF64_R_SYM (rel->r_info);
4a67a098
RH
3983 if (r_symndx < symtab_hdr_sh_info)
3984 {
3985 sym = local_syms + r_symndx;
ab96bf03 3986 sec = local_sections[r_symndx];
4a67a098 3987 }
ab96bf03
AM
3988 else
3989 {
3990 struct elf_link_hash_entry *h;
3991
3992 h = sym_hashes[r_symndx - symtab_hdr_sh_info];
3993
3994 while (h->root.type == bfd_link_hash_indirect
3995 || h->root.type == bfd_link_hash_warning)
3996 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3997
3998 if (h->root.type != bfd_link_hash_defined
3999 && h->root.type != bfd_link_hash_defweak)
4000 continue;
4001
4002 sym = NULL;
4003 sec = h->root.u.def.section;
4004 }
4005
4006 if (sec != NULL && elf_discarded_section (sec))
4007 {
4008 /* For relocs against symbols from removed linkonce sections,
4009 or sections discarded by a linker script, we just want the
4010 section contents zeroed. */
4011 _bfd_clear_contents (elf64_alpha_howto_table + r_type,
4012 input_bfd, contents + rel->r_offset);
4013 rel->r_info = 0;
4014 rel->r_addend = 0;
4015 continue;
4016 }
4017
4018 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4019 rel->r_addend += sec->output_offset;
4a67a098
RH
4020 }
4021
4022 return ret_val;
4023}
4024
252b5132
RH
4025/* Relocate an Alpha ELF section. */
4026
b34976b6 4027static bfd_boolean
a7519a3c
RH
4028elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
4029 bfd *input_bfd, asection *input_section,
4030 bfd_byte *contents, Elf_Internal_Rela *relocs,
4031 Elf_Internal_Sym *local_syms,
4032 asection **local_sections)
252b5132 4033{
4a67a098 4034 Elf_Internal_Shdr *symtab_hdr;
252b5132
RH
4035 Elf_Internal_Rela *rel;
4036 Elf_Internal_Rela *relend;
4a67a098
RH
4037 asection *sgot, *srel, *srelgot;
4038 bfd *dynobj, *gotobj;
4039 bfd_vma gp, tp_base, dtp_base;
4040 struct alpha_elf_got_entry **local_got_entries;
b34976b6 4041 bfd_boolean ret_val;
252b5132 4042
0ffa91dd
NC
4043 BFD_ASSERT (is_alpha_elf (input_bfd));
4044
4a67a098 4045 /* Handle relocatable links with a smaller loop. */
1049f94e 4046 if (info->relocatable)
4a67a098
RH
4047 return elf64_alpha_relocate_section_r (output_bfd, info, input_bfd,
4048 input_section, contents, relocs,
4049 local_syms, local_sections);
4050
4051 /* This is a final link. */
4052
b34976b6 4053 ret_val = TRUE;
252b5132 4054
0ffa91dd 4055 symtab_hdr = &elf_symtab_hdr (input_bfd);
3765b1be 4056
4a67a098
RH
4057 dynobj = elf_hash_table (info)->dynobj;
4058 if (dynobj)
4059 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
4060 else
4061 srelgot = NULL;
4062
3241278a
RH
4063 if (input_section->flags & SEC_ALLOC)
4064 {
4065 const char *section_name;
4066 section_name = (bfd_elf_string_from_elf_section
4067 (input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
4068 elf_section_data(input_section)->rel_hdr.sh_name));
4069 BFD_ASSERT(section_name != NULL);
4070 srel = bfd_get_section_by_name (dynobj, section_name);
4071 }
4072 else
4073 srel = NULL;
3765b1be 4074
4a67a098
RH
4075 /* Find the gp value for this input bfd. */
4076 gotobj = alpha_elf_tdata (input_bfd)->gotobj;
4077 if (gotobj)
4078 {
4079 sgot = alpha_elf_tdata (gotobj)->got;
4080 gp = _bfd_get_gp_value (gotobj);
4081 if (gp == 0)
252b5132 4082 {
4a67a098
RH
4083 gp = (sgot->output_section->vma
4084 + sgot->output_offset
4085 + 0x8000);
4086 _bfd_set_gp_value (gotobj, gp);
4087 }
4088 }
4089 else
4090 {
4091 sgot = NULL;
4092 gp = 0;
4093 }
3765b1be 4094
4a67a098
RH
4095 local_got_entries = alpha_elf_tdata(input_bfd)->local_got_entries;
4096
e1918d23 4097 if (elf_hash_table (info)->tls_sec != NULL)
4a67a098 4098 {
e1918d23
AM
4099 dtp_base = alpha_get_dtprel_base (info);
4100 tp_base = alpha_get_tprel_base (info);
252b5132 4101 }
4a67a098
RH
4102 else
4103 dtp_base = tp_base = 0;
252b5132 4104
252b5132 4105 relend = relocs + input_section->reloc_count;
4a67a098 4106 for (rel = relocs; rel < relend; rel++)
252b5132 4107 {
4a67a098 4108 struct alpha_elf_link_hash_entry *h = NULL;
3765b1be
RH
4109 struct alpha_elf_got_entry *gotent;
4110 bfd_reloc_status_type r;
252b5132
RH
4111 reloc_howto_type *howto;
4112 unsigned long r_symndx;
4a67a098
RH
4113 Elf_Internal_Sym *sym = NULL;
4114 asection *sec = NULL;
3765b1be 4115 bfd_vma value;
dc810e39 4116 bfd_vma addend;
b34976b6
AM
4117 bfd_boolean dynamic_symbol_p;
4118 bfd_boolean undef_weak_ref = FALSE;
3765b1be 4119 unsigned long r_type;
252b5132
RH
4120
4121 r_type = ELF64_R_TYPE(rel->r_info);
3765b1be 4122 if (r_type >= R_ALPHA_max)
252b5132 4123 {
3765b1be 4124 (*_bfd_error_handler)
d003868e
AM
4125 (_("%B: unknown relocation type %d"),
4126 input_bfd, (int) r_type);
252b5132 4127 bfd_set_error (bfd_error_bad_value);
b34976b6 4128 ret_val = FALSE;
3765b1be 4129 continue;
252b5132 4130 }
252b5132 4131
3765b1be 4132 howto = elf64_alpha_howto_table + r_type;
252b5132
RH
4133 r_symndx = ELF64_R_SYM(rel->r_info);
4134
cc03ec80
RH
4135 /* The symbol for a TLSLDM reloc is ignored. Collapse the
4136 reloc to the 0 symbol so that they all match. */
4137 if (r_type == R_ALPHA_TLSLDM)
4138 r_symndx = 0;
4139
252b5132
RH
4140 if (r_symndx < symtab_hdr->sh_info)
4141 {
8517fae7 4142 asection *msec;
252b5132
RH
4143 sym = local_syms + r_symndx;
4144 sec = local_sections[r_symndx];
8517fae7
AM
4145 msec = sec;
4146 value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
3765b1be 4147
cc03ec80
RH
4148 /* If this is a tp-relative relocation against sym 0,
4149 this is hackery from relax_section. Force the value to
f915360b 4150 be the tls module base. */
cc03ec80
RH
4151 if (r_symndx == 0
4152 && (r_type == R_ALPHA_TLSLDM
4153 || r_type == R_ALPHA_GOTTPREL
4154 || r_type == R_ALPHA_TPREL64
4155 || r_type == R_ALPHA_TPRELHI
4156 || r_type == R_ALPHA_TPRELLO
4157 || r_type == R_ALPHA_TPREL16))
f915360b 4158 value = dtp_base;
cc03ec80 4159
4a67a098
RH
4160 if (local_got_entries)
4161 gotent = local_got_entries[r_symndx];
4162 else
4163 gotent = NULL;
3765b1be
RH
4164
4165 /* Need to adjust local GOT entries' addends for SEC_MERGE
4166 unless it has been done already. */
4167 if ((sec->flags & SEC_MERGE)
048d873d 4168 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
68bfbfcc 4169 && sec->sec_info_type == ELF_INFO_TYPE_MERGE
048d873d
RH
4170 && gotent
4171 && !gotent->reloc_xlated)
3765b1be
RH
4172 {
4173 struct alpha_elf_got_entry *ent;
3765b1be
RH
4174
4175 for (ent = gotent; ent; ent = ent->next)
4176 {
4177 ent->reloc_xlated = 1;
4178 if (ent->use_count == 0)
4179 continue;
4180 msec = sec;
4181 ent->addend =
4182 _bfd_merged_section_offset (output_bfd, &msec,
4183 elf_section_data (sec)->
4184 sec_info,
753731ee 4185 sym->st_value + ent->addend);
3765b1be
RH
4186 ent->addend -= sym->st_value;
4187 ent->addend += msec->output_section->vma
4188 + msec->output_offset
4189 - sec->output_section->vma
4190 - sec->output_offset;
4191 }
4192 }
4193
b34976b6 4194 dynamic_symbol_p = FALSE;
252b5132
RH
4195 }
4196 else
4197 {
560e09e9
NC
4198 bfd_boolean warned;
4199 bfd_boolean unresolved_reloc;
4200 struct elf_link_hash_entry *hh;
b2a8e766
AM
4201 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
4202
4203 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4204 r_symndx, symtab_hdr, sym_hashes,
4205 hh, sec, value,
4206 unresolved_reloc, warned);
560e09e9
NC
4207
4208 if (warned)
4209 continue;
252b5132 4210
560e09e9
NC
4211 if (value == 0
4212 && ! unresolved_reloc
4213 && hh->root.type == bfd_link_hash_undefweak)
b34976b6 4214 undef_weak_ref = TRUE;
3765b1be 4215
560e09e9 4216 h = (struct alpha_elf_link_hash_entry *) hh;
3765b1be
RH
4217 dynamic_symbol_p = alpha_elf_dynamic_symbol_p (&h->root, info);
4218 gotent = h->got_entries;
252b5132 4219 }
3765b1be 4220
ab96bf03
AM
4221 if (sec != NULL && elf_discarded_section (sec))
4222 {
4223 /* For relocs against symbols from removed linkonce sections,
4224 or sections discarded by a linker script, we just want the
4225 section contents zeroed. Avoid any special processing. */
4226 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
4227 rel->r_info = 0;
4228 rel->r_addend = 0;
4229 continue;
4230 }
4231
252b5132 4232 addend = rel->r_addend;
3765b1be
RH
4233 value += addend;
4234
4235 /* Search for the proper got entry. */
4236 for (; gotent ; gotent = gotent->next)
4237 if (gotent->gotobj == gotobj
4238 && gotent->reloc_type == r_type
4239 && gotent->addend == addend)
4240 break;
252b5132
RH
4241
4242 switch (r_type)
4243 {
4244 case R_ALPHA_GPDISP:
4245 {
4246 bfd_byte *p_ldah, *p_lda;
4247
4248 BFD_ASSERT(gp != 0);
4249
3765b1be
RH
4250 value = (input_section->output_section->vma
4251 + input_section->output_offset
4252 + rel->r_offset);
252b5132 4253
3765b1be 4254 p_ldah = contents + rel->r_offset;
252b5132
RH
4255 p_lda = p_ldah + rel->r_addend;
4256
3765b1be 4257 r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - value,
252b5132
RH
4258 p_ldah, p_lda);
4259 }
4260 break;
4261
252b5132 4262 case R_ALPHA_LITERAL:
3765b1be
RH
4263 BFD_ASSERT(sgot != NULL);
4264 BFD_ASSERT(gp != 0);
4265 BFD_ASSERT(gotent != NULL);
4266 BFD_ASSERT(gotent->use_count >= 1);
f7460f5f 4267
3765b1be
RH
4268 if (!gotent->reloc_done)
4269 {
4270 gotent->reloc_done = 1;
252b5132 4271
3765b1be
RH
4272 bfd_put_64 (output_bfd, value,
4273 sgot->contents + gotent->got_offset);
252b5132 4274
3765b1be
RH
4275 /* If the symbol has been forced local, output a
4276 RELATIVE reloc, otherwise it will be handled in
4277 finish_dynamic_symbol. */
d6ad34f6 4278 if (info->shared && !dynamic_symbol_p && !undef_weak_ref)
1bbc9cec
RH
4279 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
4280 gotent->got_offset, 0,
4281 R_ALPHA_RELATIVE, value);
3765b1be 4282 }
252b5132 4283
3765b1be
RH
4284 value = (sgot->output_section->vma
4285 + sgot->output_offset
4286 + gotent->got_offset);
4287 value -= gp;
252b5132
RH
4288 goto default_reloc;
4289
4290 case R_ALPHA_GPREL32:
ec1659c8 4291 case R_ALPHA_GPREL16:
252b5132 4292 case R_ALPHA_GPRELLOW:
3765b1be 4293 if (dynamic_symbol_p)
f16fbd61
RH
4294 {
4295 (*_bfd_error_handler)
d003868e
AM
4296 (_("%B: gp-relative relocation against dynamic symbol %s"),
4297 input_bfd, h->root.root.root.string);
b34976b6 4298 ret_val = FALSE;
f16fbd61 4299 }
252b5132 4300 BFD_ASSERT(gp != 0);
3765b1be 4301 value -= gp;
252b5132
RH
4302 goto default_reloc;
4303
4304 case R_ALPHA_GPRELHIGH:
3765b1be 4305 if (dynamic_symbol_p)
f16fbd61
RH
4306 {
4307 (*_bfd_error_handler)
d003868e
AM
4308 (_("%B: gp-relative relocation against dynamic symbol %s"),
4309 input_bfd, h->root.root.root.string);
b34976b6 4310 ret_val = FALSE;
f16fbd61 4311 }
252b5132 4312 BFD_ASSERT(gp != 0);
3765b1be
RH
4313 value -= gp;
4314 value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
252b5132
RH
4315 goto default_reloc;
4316
252b5132 4317 case R_ALPHA_HINT:
f94952df
RH
4318 /* A call to a dynamic symbol is definitely out of range of
4319 the 16-bit displacement. Don't bother writing anything. */
3765b1be 4320 if (dynamic_symbol_p)
f94952df
RH
4321 {
4322 r = bfd_reloc_ok;
4323 break;
4324 }
3765b1be
RH
4325 /* The regular PC-relative stuff measures from the start of
4326 the instruction rather than the end. */
4327 value -= 4;
4328 goto default_reloc;
f94952df
RH
4329
4330 case R_ALPHA_BRADDR:
3765b1be
RH
4331 if (dynamic_symbol_p)
4332 {
4333 (*_bfd_error_handler)
d003868e
AM
4334 (_("%B: pc-relative relocation against dynamic symbol %s"),
4335 input_bfd, h->root.root.root.string);
b34976b6 4336 ret_val = FALSE;
3765b1be 4337 }
252b5132
RH
4338 /* The regular PC-relative stuff measures from the start of
4339 the instruction rather than the end. */
3765b1be 4340 value -= 4;
252b5132
RH
4341 goto default_reloc;
4342
7793f4d0
RH
4343 case R_ALPHA_BRSGP:
4344 {
4345 int other;
4346 const char *name;
4347
4348 /* The regular PC-relative stuff measures from the start of
4349 the instruction rather than the end. */
3765b1be 4350 value -= 4;
7793f4d0 4351
ccf00ab6
RH
4352 /* The source and destination gp must be the same. Note that
4353 the source will always have an assigned gp, since we forced
4354 one in check_relocs, but that the destination may not, as
cedb70c5 4355 it might not have had any relocations at all. Also take
ccf00ab6
RH
4356 care not to crash if H is an undefined symbol. */
4357 if (h != NULL && sec != NULL
4358 && alpha_elf_tdata (sec->owner)->gotobj
7793f4d0
RH
4359 && gotobj != alpha_elf_tdata (sec->owner)->gotobj)
4360 {
7793f4d0 4361 (*_bfd_error_handler)
d003868e
AM
4362 (_("%B: change in gp: BRSGP %s"),
4363 input_bfd, h->root.root.root.string);
b34976b6 4364 ret_val = FALSE;
7793f4d0
RH
4365 }
4366
4367 /* The symbol should be marked either NOPV or STD_GPLOAD. */
4368 if (h != NULL)
4369 other = h->root.other;
4370 else
4371 other = sym->st_other;
4372 switch (other & STO_ALPHA_STD_GPLOAD)
4373 {
4374 case STO_ALPHA_NOPV:
4375 break;
4376 case STO_ALPHA_STD_GPLOAD:
64e04ecd 4377 value += 8;
7793f4d0
RH
4378 break;
4379 default:
4380 if (h != NULL)
4381 name = h->root.root.root.string;
4382 else
4383 {
4384 name = (bfd_elf_string_from_elf_section
4385 (input_bfd, symtab_hdr->sh_link, sym->st_name));
4386 if (name == NULL)
4387 name = _("<unknown>");
4388 else if (name[0] == 0)
4389 name = bfd_section_name (input_bfd, sec);
4390 }
4391 (*_bfd_error_handler)
d003868e
AM
4392 (_("%B: !samegp reloc against symbol without .prologue: %s"),
4393 input_bfd, name);
b34976b6 4394 ret_val = FALSE;
7793f4d0
RH
4395 break;
4396 }
4397
4398 goto default_reloc;
4399 }
4400
252b5132
RH
4401 case R_ALPHA_REFLONG:
4402 case R_ALPHA_REFQUAD:
3765b1be
RH
4403 case R_ALPHA_DTPREL64:
4404 case R_ALPHA_TPREL64:
252b5132 4405 {
1bbc9cec
RH
4406 long dynindx, dyntype = r_type;
4407 bfd_vma dynaddend;
252b5132
RH
4408
4409 /* Careful here to remember RELATIVE relocations for global
4410 variables for symbolic shared objects. */
4411
3765b1be 4412 if (dynamic_symbol_p)
252b5132
RH
4413 {
4414 BFD_ASSERT(h->root.dynindx != -1);
1bbc9cec
RH
4415 dynindx = h->root.dynindx;
4416 dynaddend = addend;
3765b1be
RH
4417 addend = 0, value = 0;
4418 }
4419 else if (r_type == R_ALPHA_DTPREL64)
4420 {
e1918d23 4421 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3765b1be
RH
4422 value -= dtp_base;
4423 goto default_reloc;
4424 }
4425 else if (r_type == R_ALPHA_TPREL64)
4426 {
e1918d23 4427 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
1bbc9cec
RH
4428 if (!info->shared)
4429 {
4430 value -= tp_base;
4431 goto default_reloc;
4432 }
4433 dynindx = 0;
4434 dynaddend = value - dtp_base;
252b5132 4435 }
ec338859
AM
4436 else if (info->shared
4437 && r_symndx != 0
d6ad34f6
RH
4438 && (input_section->flags & SEC_ALLOC)
4439 && !undef_weak_ref)
252b5132 4440 {
3765b1be
RH
4441 if (r_type == R_ALPHA_REFLONG)
4442 {
4443 (*_bfd_error_handler)
d003868e
AM
4444 (_("%B: unhandled dynamic relocation against %s"),
4445 input_bfd,
3765b1be 4446 h->root.root.root.string);
b34976b6 4447 ret_val = FALSE;
3765b1be 4448 }
1bbc9cec
RH
4449 dynindx = 0;
4450 dyntype = R_ALPHA_RELATIVE;
4451 dynaddend = value;
252b5132
RH
4452 }
4453 else
4454 goto default_reloc;
4455
3241278a
RH
4456 if (input_section->flags & SEC_ALLOC)
4457 elf64_alpha_emit_dynrel (output_bfd, info, input_section,
4458 srel, rel->r_offset, dynindx,
4459 dyntype, dynaddend);
252b5132
RH
4460 }
4461 goto default_reloc;
4462
3765b1be 4463 case R_ALPHA_SREL16:
84de6048
RH
4464 case R_ALPHA_SREL32:
4465 case R_ALPHA_SREL64:
3765b1be
RH
4466 if (dynamic_symbol_p)
4467 {
4468 (*_bfd_error_handler)
d003868e
AM
4469 (_("%B: pc-relative relocation against dynamic symbol %s"),
4470 input_bfd, h->root.root.root.string);
b34976b6 4471 ret_val = FALSE;
3765b1be 4472 }
d6ad34f6
RH
4473 else if ((info->shared || info->pie) && undef_weak_ref)
4474 {
4475 (*_bfd_error_handler)
4476 (_("%B: pc-relative relocation against undefined weak symbol %s"),
4477 input_bfd, h->root.root.root.string);
4478 ret_val = FALSE;
4479 }
4480
3765b1be 4481
84de6048
RH
4482 /* ??? .eh_frame references to discarded sections will be smashed
4483 to relocations against SHN_UNDEF. The .eh_frame format allows
4484 NULL to be encoded as 0 in any format, so this works here. */
4485 if (r_symndx == 0)
4486 howto = (elf64_alpha_howto_table
4487 + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG));
4488 goto default_reloc;
4489
3765b1be
RH
4490 case R_ALPHA_TLSLDM:
4491 /* Ignore the symbol for the relocation. The result is always
4492 the current module. */
4493 dynamic_symbol_p = 0;
4494 /* FALLTHRU */
4495
4496 case R_ALPHA_TLSGD:
4497 if (!gotent->reloc_done)
4498 {
4499 gotent->reloc_done = 1;
4500
4501 /* Note that the module index for the main program is 1. */
4502 bfd_put_64 (output_bfd, !info->shared && !dynamic_symbol_p,
4503 sgot->contents + gotent->got_offset);
4504
4505 /* If the symbol has been forced local, output a
4506 DTPMOD64 reloc, otherwise it will be handled in
4507 finish_dynamic_symbol. */
4508 if (info->shared && !dynamic_symbol_p)
1bbc9cec
RH
4509 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
4510 gotent->got_offset, 0,
4511 R_ALPHA_DTPMOD64, 0);
3765b1be
RH
4512
4513 if (dynamic_symbol_p || r_type == R_ALPHA_TLSLDM)
4514 value = 0;
4515 else
4516 {
e1918d23 4517 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3765b1be
RH
4518 value -= dtp_base;
4519 }
4520 bfd_put_64 (output_bfd, value,
4521 sgot->contents + gotent->got_offset + 8);
4522 }
4523
4524 value = (sgot->output_section->vma
4525 + sgot->output_offset
4526 + gotent->got_offset);
4527 value -= gp;
4528 goto default_reloc;
4529
4530 case R_ALPHA_DTPRELHI:
4531 case R_ALPHA_DTPRELLO:
4532 case R_ALPHA_DTPREL16:
4533 if (dynamic_symbol_p)
4534 {
4535 (*_bfd_error_handler)
d003868e
AM
4536 (_("%B: dtp-relative relocation against dynamic symbol %s"),
4537 input_bfd, h->root.root.root.string);
b34976b6 4538 ret_val = FALSE;
3765b1be 4539 }
e1918d23 4540 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3765b1be 4541 value -= dtp_base;
9e756d64
RH
4542 if (r_type == R_ALPHA_DTPRELHI)
4543 value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
3765b1be
RH
4544 goto default_reloc;
4545
4546 case R_ALPHA_TPRELHI:
4547 case R_ALPHA_TPRELLO:
4548 case R_ALPHA_TPREL16:
9e756d64
RH
4549 if (info->shared)
4550 {
4551 (*_bfd_error_handler)
d003868e
AM
4552 (_("%B: TLS local exec code cannot be linked into shared objects"),
4553 input_bfd);
b34976b6 4554 ret_val = FALSE;
9e756d64
RH
4555 }
4556 else if (dynamic_symbol_p)
3765b1be
RH
4557 {
4558 (*_bfd_error_handler)
d003868e
AM
4559 (_("%B: tp-relative relocation against dynamic symbol %s"),
4560 input_bfd, h->root.root.root.string);
b34976b6 4561 ret_val = FALSE;
3765b1be 4562 }
e1918d23 4563 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3765b1be 4564 value -= tp_base;
9e756d64
RH
4565 if (r_type == R_ALPHA_TPRELHI)
4566 value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
3765b1be
RH
4567 goto default_reloc;
4568
4569 case R_ALPHA_GOTDTPREL:
4570 case R_ALPHA_GOTTPREL:
4571 BFD_ASSERT(sgot != NULL);
4572 BFD_ASSERT(gp != 0);
4573 BFD_ASSERT(gotent != NULL);
4574 BFD_ASSERT(gotent->use_count >= 1);
4575
4576 if (!gotent->reloc_done)
4577 {
4578 gotent->reloc_done = 1;
4579
4580 if (dynamic_symbol_p)
4581 value = 0;
4582 else
4583 {
e1918d23 4584 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
1bbc9cec
RH
4585 if (r_type == R_ALPHA_GOTDTPREL)
4586 value -= dtp_base;
4587 else if (!info->shared)
4588 value -= tp_base;
4589 else
4590 {
4591 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
4592 gotent->got_offset, 0,
4593 R_ALPHA_TPREL64,
4594 value - dtp_base);
4595 value = 0;
4596 }
3765b1be
RH
4597 }
4598 bfd_put_64 (output_bfd, value,
4599 sgot->contents + gotent->got_offset);
4600 }
4601
4602 value = (sgot->output_section->vma
4603 + sgot->output_offset
4604 + gotent->got_offset);
4605 value -= gp;
4606 goto default_reloc;
4607
252b5132
RH
4608 default:
4609 default_reloc:
4610 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
3765b1be 4611 contents, rel->r_offset, value, 0);
252b5132
RH
4612 break;
4613 }
4614
4615 switch (r)
4616 {
4617 case bfd_reloc_ok:
4618 break;
4619
4620 case bfd_reloc_overflow:
4621 {
4622 const char *name;
4623
ed4de5e2
JJ
4624 /* Don't warn if the overflow is due to pc relative reloc
4625 against discarded section. Section optimization code should
4626 handle it. */
4627
4628 if (r_symndx < symtab_hdr->sh_info
4629 && sec != NULL && howto->pc_relative
4630 && elf_discarded_section (sec))
4631 break;
4632
252b5132 4633 if (h != NULL)
dfeffb9f 4634 name = NULL;
252b5132
RH
4635 else
4636 {
4637 name = (bfd_elf_string_from_elf_section
4638 (input_bfd, symtab_hdr->sh_link, sym->st_name));
4639 if (name == NULL)
b34976b6 4640 return FALSE;
252b5132
RH
4641 if (*name == '\0')
4642 name = bfd_section_name (input_bfd, sec);
4643 }
4644 if (! ((*info->callbacks->reloc_overflow)
dfeffb9f
L
4645 (info, (h ? &h->root.root : NULL), name, howto->name,
4646 (bfd_vma) 0, input_bfd, input_section,
4647 rel->r_offset)))
b34976b6 4648 ret_val = FALSE;
252b5132
RH
4649 }
4650 break;
4651
4652 default:
4653 case bfd_reloc_outofrange:
4654 abort ();
4655 }
4656 }
4657
f16fbd61 4658 return ret_val;
252b5132
RH
4659}
4660
4661/* Finish up dynamic symbol handling. We set the contents of various
4662 dynamic sections here. */
4663
b34976b6 4664static bfd_boolean
a7519a3c
RH
4665elf64_alpha_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
4666 struct elf_link_hash_entry *h,
4667 Elf_Internal_Sym *sym)
252b5132 4668{
6ec7057a 4669 struct alpha_elf_link_hash_entry *ah = (struct alpha_elf_link_hash_entry *)h;
252b5132
RH
4670 bfd *dynobj = elf_hash_table(info)->dynobj;
4671
6ec7057a 4672 if (h->needs_plt)
252b5132
RH
4673 {
4674 /* Fill in the .plt entry for this symbol. */
4675 asection *splt, *sgot, *srel;
4676 Elf_Internal_Rela outrel;
947216bf 4677 bfd_byte *loc;
252b5132
RH
4678 bfd_vma got_addr, plt_addr;
4679 bfd_vma plt_index;
4680 struct alpha_elf_got_entry *gotent;
4681
4682 BFD_ASSERT (h->dynindx != -1);
4683
252b5132
RH
4684 splt = bfd_get_section_by_name (dynobj, ".plt");
4685 BFD_ASSERT (splt != NULL);
4686 srel = bfd_get_section_by_name (dynobj, ".rela.plt");
4687 BFD_ASSERT (srel != NULL);
252b5132 4688
6ec7057a
RH
4689 for (gotent = ah->got_entries; gotent ; gotent = gotent->next)
4690 if (gotent->reloc_type == R_ALPHA_LITERAL
4691 && gotent->use_count > 0)
4692 {
4693 unsigned int insn;
4694 int disp;
252b5132 4695
6ec7057a
RH
4696 sgot = alpha_elf_tdata (gotent->gotobj)->got;
4697 BFD_ASSERT (sgot != NULL);
252b5132 4698
6ec7057a
RH
4699 BFD_ASSERT (gotent->got_offset != -1);
4700 BFD_ASSERT (gotent->plt_offset != -1);
252b5132 4701
6ec7057a
RH
4702 got_addr = (sgot->output_section->vma
4703 + sgot->output_offset
4704 + gotent->got_offset);
4705 plt_addr = (splt->output_section->vma
4706 + splt->output_offset
4707 + gotent->plt_offset);
252b5132 4708
6ec7057a 4709 plt_index = (gotent->plt_offset-PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
252b5132 4710
6ec7057a
RH
4711 /* Fill in the entry in the procedure linkage table. */
4712 if (elf64_alpha_use_secureplt)
4713 {
4714 disp = (PLT_HEADER_SIZE - 4) - (gotent->plt_offset + 4);
4715 insn = INSN_AD (INSN_BR, 31, disp);
4716 bfd_put_32 (output_bfd, insn,
4717 splt->contents + gotent->plt_offset);
252b5132 4718
6ec7057a
RH
4719 plt_index = ((gotent->plt_offset - NEW_PLT_HEADER_SIZE)
4720 / NEW_PLT_ENTRY_SIZE);
4721 }
4722 else
4723 {
4724 disp = -(gotent->plt_offset + 4);
4725 insn = INSN_AD (INSN_BR, 28, disp);
4726 bfd_put_32 (output_bfd, insn,
4727 splt->contents + gotent->plt_offset);
4728 bfd_put_32 (output_bfd, INSN_UNOP,
4729 splt->contents + gotent->plt_offset + 4);
4730 bfd_put_32 (output_bfd, INSN_UNOP,
4731 splt->contents + gotent->plt_offset + 8);
4732
4733 plt_index = ((gotent->plt_offset - OLD_PLT_HEADER_SIZE)
4734 / OLD_PLT_ENTRY_SIZE);
4735 }
252b5132 4736
6ec7057a
RH
4737 /* Fill in the entry in the .rela.plt section. */
4738 outrel.r_offset = got_addr;
4739 outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT);
4740 outrel.r_addend = 0;
252b5132 4741
6ec7057a
RH
4742 loc = srel->contents + plt_index * sizeof (Elf64_External_Rela);
4743 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
252b5132 4744
6ec7057a
RH
4745 /* Fill in the entry in the .got. */
4746 bfd_put_64 (output_bfd, plt_addr,
4747 sgot->contents + gotent->got_offset);
4748 }
252b5132
RH
4749 }
4750 else if (alpha_elf_dynamic_symbol_p (h, info))
4751 {
4752 /* Fill in the dynamic relocations for this symbol's .got entries. */
4753 asection *srel;
252b5132
RH
4754 struct alpha_elf_got_entry *gotent;
4755
4756 srel = bfd_get_section_by_name (dynobj, ".rela.got");
4757 BFD_ASSERT (srel != NULL);
4758
252b5132
RH
4759 for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
4760 gotent != NULL;
4761 gotent = gotent->next)
4762 {
f44f99a5 4763 asection *sgot;
1bbc9cec 4764 long r_type;
3765b1be 4765
f44f99a5
RH
4766 if (gotent->use_count == 0)
4767 continue;
4768
4769 sgot = alpha_elf_tdata (gotent->gotobj)->got;
3765b1be
RH
4770
4771 r_type = gotent->reloc_type;
4772 switch (r_type)
4773 {
4774 case R_ALPHA_LITERAL:
4775 r_type = R_ALPHA_GLOB_DAT;
4776 break;
4777 case R_ALPHA_TLSGD:
4778 r_type = R_ALPHA_DTPMOD64;
4779 break;
4780 case R_ALPHA_GOTDTPREL:
4781 r_type = R_ALPHA_DTPREL64;
4782 break;
4783 case R_ALPHA_GOTTPREL:
4784 r_type = R_ALPHA_TPREL64;
4785 break;
4786 case R_ALPHA_TLSLDM:
4787 default:
4788 abort ();
4789 }
4790
1bbc9cec
RH
4791 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
4792 gotent->got_offset, h->dynindx,
4793 r_type, gotent->addend);
3765b1be
RH
4794
4795 if (gotent->reloc_type == R_ALPHA_TLSGD)
1bbc9cec
RH
4796 elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
4797 gotent->got_offset + 8, h->dynindx,
4798 R_ALPHA_DTPREL64, gotent->addend);
252b5132
RH
4799 }
4800 }
4801
4802 /* Mark some specially defined symbols as absolute. */
4803 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
22edb2f1
RS
4804 || h == elf_hash_table (info)->hgot
4805 || h == elf_hash_table (info)->hplt)
252b5132
RH
4806 sym->st_shndx = SHN_ABS;
4807
b34976b6 4808 return TRUE;
252b5132
RH
4809}
4810
4811/* Finish up the dynamic sections. */
4812
b34976b6 4813static bfd_boolean
a7519a3c
RH
4814elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
4815 struct bfd_link_info *info)
252b5132
RH
4816{
4817 bfd *dynobj;
4818 asection *sdyn;
4819
4820 dynobj = elf_hash_table (info)->dynobj;
4821 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4822
4823 if (elf_hash_table (info)->dynamic_sections_created)
4824 {
6ec7057a 4825 asection *splt, *sgotplt, *srelaplt;
252b5132 4826 Elf64_External_Dyn *dyncon, *dynconend;
6ec7057a 4827 bfd_vma plt_vma, gotplt_vma;
252b5132
RH
4828
4829 splt = bfd_get_section_by_name (dynobj, ".plt");
6ec7057a 4830 srelaplt = bfd_get_section_by_name (output_bfd, ".rela.plt");
252b5132
RH
4831 BFD_ASSERT (splt != NULL && sdyn != NULL);
4832
6ec7057a
RH
4833 plt_vma = splt->output_section->vma + splt->output_offset;
4834
4835 gotplt_vma = 0;
4836 if (elf64_alpha_use_secureplt)
4837 {
4838 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4839 BFD_ASSERT (sgotplt != NULL);
4840 if (sgotplt->size > 0)
4841 gotplt_vma = sgotplt->output_section->vma + sgotplt->output_offset;
4842 }
4843
252b5132 4844 dyncon = (Elf64_External_Dyn *) sdyn->contents;
eea6121a 4845 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
252b5132
RH
4846 for (; dyncon < dynconend; dyncon++)
4847 {
4848 Elf_Internal_Dyn dyn;
252b5132
RH
4849
4850 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
4851
4852 switch (dyn.d_tag)
4853 {
4854 case DT_PLTGOT:
6ec7057a
RH
4855 dyn.d_un.d_ptr
4856 = elf64_alpha_use_secureplt ? gotplt_vma : plt_vma;
4857 break;
252b5132 4858 case DT_PLTRELSZ:
6ec7057a
RH
4859 dyn.d_un.d_val = srelaplt ? srelaplt->size : 0;
4860 break;
252b5132 4861 case DT_JMPREL:
6ec7057a
RH
4862 dyn.d_un.d_ptr = srelaplt ? srelaplt->vma : 0;
4863 break;
252b5132
RH
4864
4865 case DT_RELASZ:
4866 /* My interpretation of the TIS v1.1 ELF document indicates
4867 that RELASZ should not include JMPREL. This is not what
4868 the rest of the BFD does. It is, however, what the
4869 glibc ld.so wants. Do this fixup here until we found
4870 out who is right. */
6ec7057a
RH
4871 if (srelaplt)
4872 dyn.d_un.d_val -= srelaplt->size;
252b5132
RH
4873 break;
4874 }
4875
4876 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
4877 }
4878
6ec7057a 4879 /* Initialize the plt header. */
eea6121a 4880 if (splt->size > 0)
252b5132 4881 {
6ec7057a
RH
4882 unsigned int insn;
4883 int ofs;
4884
4885 if (elf64_alpha_use_secureplt)
4886 {
4887 ofs = gotplt_vma - (plt_vma + PLT_HEADER_SIZE);
4888
4889 insn = INSN_ABC (INSN_SUBQ, 27, 28, 25);
4890 bfd_put_32 (output_bfd, insn, splt->contents);
4891
4892 insn = INSN_ABO (INSN_LDAH, 28, 28, (ofs + 0x8000) >> 16);
4893 bfd_put_32 (output_bfd, insn, splt->contents + 4);
4894
4895 insn = INSN_ABC (INSN_S4SUBQ, 25, 25, 25);
4896 bfd_put_32 (output_bfd, insn, splt->contents + 8);
4897
4898 insn = INSN_ABO (INSN_LDA, 28, 28, ofs);
4899 bfd_put_32 (output_bfd, insn, splt->contents + 12);
4900
4901 insn = INSN_ABO (INSN_LDQ, 27, 28, 0);
4902 bfd_put_32 (output_bfd, insn, splt->contents + 16);
4903
4904 insn = INSN_ABC (INSN_ADDQ, 25, 25, 25);
4905 bfd_put_32 (output_bfd, insn, splt->contents + 20);
4906
4907 insn = INSN_ABO (INSN_LDQ, 28, 28, 8);
4908 bfd_put_32 (output_bfd, insn, splt->contents + 24);
4909
4910 insn = INSN_AB (INSN_JMP, 31, 27);
4911 bfd_put_32 (output_bfd, insn, splt->contents + 28);
4912
4913 insn = INSN_AD (INSN_BR, 28, -PLT_HEADER_SIZE);
4914 bfd_put_32 (output_bfd, insn, splt->contents + 32);
4915 }
4916 else
4917 {
4918 insn = INSN_AD (INSN_BR, 27, 0); /* br $27, .+4 */
4919 bfd_put_32 (output_bfd, insn, splt->contents);
4920
4921 insn = INSN_ABO (INSN_LDQ, 27, 27, 12);
4922 bfd_put_32 (output_bfd, insn, splt->contents + 4);
4923
4924 insn = INSN_UNOP;
4925 bfd_put_32 (output_bfd, insn, splt->contents + 8);
4926
4927 insn = INSN_AB (INSN_JMP, 27, 27);
4928 bfd_put_32 (output_bfd, insn, splt->contents + 12);
4929
4930 /* The next two words will be filled in by ld.so. */
4931 bfd_put_64 (output_bfd, 0, splt->contents + 16);
4932 bfd_put_64 (output_bfd, 0, splt->contents + 24);
4933 }
252b5132 4934
eecdbe52 4935 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 0;
252b5132
RH
4936 }
4937 }
4938
b34976b6 4939 return TRUE;
252b5132
RH
4940}
4941
96e2734b
RH
4942/* We need to use a special link routine to handle the .mdebug section.
4943 We need to merge all instances of these sections together, not write
4944 them all out sequentially. */
252b5132 4945
b34976b6 4946static bfd_boolean
a7519a3c 4947elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info)
252b5132
RH
4948{
4949 asection *o;
4950 struct bfd_link_order *p;
96e2734b 4951 asection *mdebug_sec;
252b5132
RH
4952 struct ecoff_debug_info debug;
4953 const struct ecoff_debug_swap *swap
4954 = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
4955 HDRR *symhdr = &debug.symbolic_header;
4956 PTR mdebug_handle = NULL;
4957
96e2734b 4958 /* Go through the sections and collect the mdebug information. */
252b5132 4959 mdebug_sec = NULL;
252b5132
RH
4960 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
4961 {
252b5132
RH
4962 if (strcmp (o->name, ".mdebug") == 0)
4963 {
4964 struct extsym_info einfo;
4965
4966 /* We have found the .mdebug section in the output file.
4967 Look through all the link_orders comprising it and merge
4968 the information together. */
4969 symhdr->magic = swap->sym_magic;
4970 /* FIXME: What should the version stamp be? */
4971 symhdr->vstamp = 0;
4972 symhdr->ilineMax = 0;
4973 symhdr->cbLine = 0;
4974 symhdr->idnMax = 0;
4975 symhdr->ipdMax = 0;
4976 symhdr->isymMax = 0;
4977 symhdr->ioptMax = 0;
4978 symhdr->iauxMax = 0;
4979 symhdr->issMax = 0;
4980 symhdr->issExtMax = 0;
4981 symhdr->ifdMax = 0;
4982 symhdr->crfd = 0;
4983 symhdr->iextMax = 0;
4984
4985 /* We accumulate the debugging information itself in the
4986 debug_info structure. */
4987 debug.line = NULL;
4988 debug.external_dnr = NULL;
4989 debug.external_pdr = NULL;
4990 debug.external_sym = NULL;
4991 debug.external_opt = NULL;
4992 debug.external_aux = NULL;
4993 debug.ss = NULL;
4994 debug.ssext = debug.ssext_end = NULL;
4995 debug.external_fdr = NULL;
4996 debug.external_rfd = NULL;
4997 debug.external_ext = debug.external_ext_end = NULL;
4998
4999 mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
5000 if (mdebug_handle == (PTR) NULL)
b34976b6 5001 return FALSE;
252b5132
RH
5002
5003 if (1)
5004 {
5005 asection *s;
5006 EXTR esym;
52b9d213 5007 bfd_vma last = 0;
252b5132
RH
5008 unsigned int i;
5009 static const char * const name[] =
5010 {
5011 ".text", ".init", ".fini", ".data",
5012 ".rodata", ".sdata", ".sbss", ".bss"
5013 };
5014 static const int sc[] = { scText, scInit, scFini, scData,
5015 scRData, scSData, scSBss, scBss };
5016
5017 esym.jmptbl = 0;
5018 esym.cobol_main = 0;
5019 esym.weakext = 0;
5020 esym.reserved = 0;
5021 esym.ifd = ifdNil;
5022 esym.asym.iss = issNil;
5023 esym.asym.st = stLocal;
5024 esym.asym.reserved = 0;
5025 esym.asym.index = indexNil;
5026 for (i = 0; i < 8; i++)
5027 {
5028 esym.asym.sc = sc[i];
5029 s = bfd_get_section_by_name (abfd, name[i]);
5030 if (s != NULL)
5031 {
5032 esym.asym.value = s->vma;
eea6121a 5033 last = s->vma + s->size;
252b5132
RH
5034 }
5035 else
5036 esym.asym.value = last;
5037
5038 if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
5039 name[i], &esym))
b34976b6 5040 return FALSE;
252b5132
RH
5041 }
5042 }
5043
8423293d 5044 for (p = o->map_head.link_order;
252b5132
RH
5045 p != (struct bfd_link_order *) NULL;
5046 p = p->next)
5047 {
5048 asection *input_section;
5049 bfd *input_bfd;
5050 const struct ecoff_debug_swap *input_swap;
5051 struct ecoff_debug_info input_debug;
5052 char *eraw_src;
5053 char *eraw_end;
5054
5055 if (p->type != bfd_indirect_link_order)
5056 {
fd96f80f 5057 if (p->type == bfd_data_link_order)
252b5132
RH
5058 continue;
5059 abort ();
5060 }
5061
5062 input_section = p->u.indirect.section;
5063 input_bfd = input_section->owner;
5064
0ffa91dd
NC
5065 if (! is_alpha_elf (input_bfd))
5066 /* I don't know what a non ALPHA ELF bfd would be
5067 doing with a .mdebug section, but I don't really
5068 want to deal with it. */
5069 continue;
252b5132
RH
5070
5071 input_swap = (get_elf_backend_data (input_bfd)
5072 ->elf_backend_ecoff_debug_swap);
5073
eea6121a 5074 BFD_ASSERT (p->size == input_section->size);
252b5132
RH
5075
5076 /* The ECOFF linking code expects that we have already
5077 read in the debugging information and set up an
5078 ecoff_debug_info structure, so we do that now. */
5079 if (!elf64_alpha_read_ecoff_info (input_bfd, input_section,
5080 &input_debug))
b34976b6 5081 return FALSE;
252b5132
RH
5082
5083 if (! (bfd_ecoff_debug_accumulate
5084 (mdebug_handle, abfd, &debug, swap, input_bfd,
5085 &input_debug, input_swap, info)))
b34976b6 5086 return FALSE;
252b5132
RH
5087
5088 /* Loop through the external symbols. For each one with
5089 interesting information, try to find the symbol in
5090 the linker global hash table and save the information
5091 for the output external symbols. */
5092 eraw_src = input_debug.external_ext;
5093 eraw_end = (eraw_src
5094 + (input_debug.symbolic_header.iextMax
5095 * input_swap->external_ext_size));
5096 for (;
5097 eraw_src < eraw_end;
5098 eraw_src += input_swap->external_ext_size)
5099 {
5100 EXTR ext;
5101 const char *name;
5102 struct alpha_elf_link_hash_entry *h;
5103
5104 (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
5105 if (ext.asym.sc == scNil
5106 || ext.asym.sc == scUndefined
5107 || ext.asym.sc == scSUndefined)
5108 continue;
5109
5110 name = input_debug.ssext + ext.asym.iss;
5111 h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info),
b34976b6 5112 name, FALSE, FALSE, TRUE);
252b5132
RH
5113 if (h == NULL || h->esym.ifd != -2)
5114 continue;
5115
5116 if (ext.ifd != -1)
5117 {
5118 BFD_ASSERT (ext.ifd
5119 < input_debug.symbolic_header.ifdMax);
5120 ext.ifd = input_debug.ifdmap[ext.ifd];
5121 }
5122
5123 h->esym = ext;
5124 }
5125
5126 /* Free up the information we just read. */
5127 free (input_debug.line);
5128 free (input_debug.external_dnr);
5129 free (input_debug.external_pdr);
5130 free (input_debug.external_sym);
5131 free (input_debug.external_opt);
5132 free (input_debug.external_aux);
5133 free (input_debug.ss);
5134 free (input_debug.ssext);
5135 free (input_debug.external_fdr);
5136 free (input_debug.external_rfd);
5137 free (input_debug.external_ext);
5138
5139 /* Hack: reset the SEC_HAS_CONTENTS flag so that
5140 elf_link_input_bfd ignores this section. */
5141 input_section->flags &=~ SEC_HAS_CONTENTS;
5142 }
5143
252b5132
RH
5144 /* Build the external symbol information. */
5145 einfo.abfd = abfd;
5146 einfo.info = info;
5147 einfo.debug = &debug;
5148 einfo.swap = swap;
b34976b6 5149 einfo.failed = FALSE;
252b5132
RH
5150 elf_link_hash_traverse (elf_hash_table (info),
5151 elf64_alpha_output_extsym,
5152 (PTR) &einfo);
5153 if (einfo.failed)
b34976b6 5154 return FALSE;
252b5132
RH
5155
5156 /* Set the size of the .mdebug section. */
eea6121a 5157 o->size = bfd_ecoff_debug_size (abfd, &debug, swap);
252b5132
RH
5158
5159 /* Skip this section later on (I don't think this currently
5160 matters, but someday it might). */
8423293d 5161 o->map_head.link_order = (struct bfd_link_order *) NULL;
252b5132
RH
5162
5163 mdebug_sec = o;
5164 }
252b5132
RH
5165 }
5166
5167 /* Invoke the regular ELF backend linker to do all the work. */
c152c796 5168 if (! bfd_elf_final_link (abfd, info))
b34976b6 5169 return FALSE;
252b5132
RH
5170
5171 /* Now write out the computed sections. */
5172
5173 /* The .got subsections... */
5174 {
5175 bfd *i, *dynobj = elf_hash_table(info)->dynobj;
5176 for (i = alpha_elf_hash_table(info)->got_list;
5177 i != NULL;
5178 i = alpha_elf_tdata(i)->got_link_next)
5179 {
5180 asection *sgot;
5181
5182 /* elf_bfd_final_link already did everything in dynobj. */
5183 if (i == dynobj)
5184 continue;
5185
5186 sgot = alpha_elf_tdata(i)->got;
5187 if (! bfd_set_section_contents (abfd, sgot->output_section,
dc810e39
AM
5188 sgot->contents,
5189 (file_ptr) sgot->output_offset,
eea6121a 5190 sgot->size))
b34976b6 5191 return FALSE;
252b5132
RH
5192 }
5193 }
5194
252b5132
RH
5195 if (mdebug_sec != (asection *) NULL)
5196 {
5197 BFD_ASSERT (abfd->output_has_begun);
5198 if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
5199 swap, info,
5200 mdebug_sec->filepos))
b34976b6 5201 return FALSE;
252b5132
RH
5202
5203 bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
5204 }
5205
b34976b6 5206 return TRUE;
252b5132 5207}
fcfbdf31
JJ
5208
5209static enum elf_reloc_type_class
a7519a3c 5210elf64_alpha_reloc_type_class (const Elf_Internal_Rela *rela)
fcfbdf31 5211{
f51e552e 5212 switch ((int) ELF64_R_TYPE (rela->r_info))
fcfbdf31
JJ
5213 {
5214 case R_ALPHA_RELATIVE:
5215 return reloc_class_relative;
5216 case R_ALPHA_JMP_SLOT:
5217 return reloc_class_plt;
5218 case R_ALPHA_COPY:
5219 return reloc_class_copy;
5220 default:
5221 return reloc_class_normal;
5222 }
5223}
252b5132 5224\f
b35d266b 5225static const struct bfd_elf_special_section elf64_alpha_special_sections[] =
2f89ff8d 5226{
0112cd26
NC
5227 { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
5228 { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
5229 { NULL, 0, 0, 0, 0 }
2f89ff8d
L
5230};
5231
252b5132
RH
5232/* ECOFF swapping routines. These are used when dealing with the
5233 .mdebug section, which is in the ECOFF debugging format. Copied
fe8bc63d 5234 from elf32-mips.c. */
252b5132
RH
5235static const struct ecoff_debug_swap
5236elf64_alpha_ecoff_debug_swap =
5237{
5238 /* Symbol table magic number. */
5239 magicSym2,
5240 /* Alignment of debugging information. E.g., 4. */
5241 8,
5242 /* Sizes of external symbolic information. */
5243 sizeof (struct hdr_ext),
5244 sizeof (struct dnr_ext),
5245 sizeof (struct pdr_ext),
5246 sizeof (struct sym_ext),
5247 sizeof (struct opt_ext),
5248 sizeof (struct fdr_ext),
5249 sizeof (struct rfd_ext),
5250 sizeof (struct ext_ext),
5251 /* Functions to swap in external symbolic data. */
5252 ecoff_swap_hdr_in,
5253 ecoff_swap_dnr_in,
5254 ecoff_swap_pdr_in,
5255 ecoff_swap_sym_in,
5256 ecoff_swap_opt_in,
5257 ecoff_swap_fdr_in,
5258 ecoff_swap_rfd_in,
5259 ecoff_swap_ext_in,
5260 _bfd_ecoff_swap_tir_in,
5261 _bfd_ecoff_swap_rndx_in,
5262 /* Functions to swap out external symbolic data. */
5263 ecoff_swap_hdr_out,
5264 ecoff_swap_dnr_out,
5265 ecoff_swap_pdr_out,
5266 ecoff_swap_sym_out,
5267 ecoff_swap_opt_out,
5268 ecoff_swap_fdr_out,
5269 ecoff_swap_rfd_out,
5270 ecoff_swap_ext_out,
5271 _bfd_ecoff_swap_tir_out,
5272 _bfd_ecoff_swap_rndx_out,
5273 /* Function to read in symbolic data. */
5274 elf64_alpha_read_ecoff_info
5275};
5276\f
70bcb145
JW
5277/* Use a non-standard hash bucket size of 8. */
5278
562ace6b 5279static const struct elf_size_info alpha_elf_size_info =
70bcb145
JW
5280{
5281 sizeof (Elf64_External_Ehdr),
5282 sizeof (Elf64_External_Phdr),
5283 sizeof (Elf64_External_Shdr),
5284 sizeof (Elf64_External_Rel),
5285 sizeof (Elf64_External_Rela),
5286 sizeof (Elf64_External_Sym),
5287 sizeof (Elf64_External_Dyn),
5288 sizeof (Elf_External_Note),
5289 8,
5290 1,
45d6a902 5291 64, 3,
70bcb145
JW
5292 ELFCLASS64, EV_CURRENT,
5293 bfd_elf64_write_out_phdrs,
5294 bfd_elf64_write_shdrs_and_ehdr,
1489a3a0 5295 bfd_elf64_checksum_contents,
70bcb145 5296 bfd_elf64_write_relocs,
73ff0d56 5297 bfd_elf64_swap_symbol_in,
70bcb145
JW
5298 bfd_elf64_swap_symbol_out,
5299 bfd_elf64_slurp_reloc_table,
5300 bfd_elf64_slurp_symbol_table,
5301 bfd_elf64_swap_dyn_in,
5302 bfd_elf64_swap_dyn_out,
947216bf
AM
5303 bfd_elf64_swap_reloc_in,
5304 bfd_elf64_swap_reloc_out,
5305 bfd_elf64_swap_reloca_in,
5306 bfd_elf64_swap_reloca_out
70bcb145
JW
5307};
5308
252b5132
RH
5309#define TARGET_LITTLE_SYM bfd_elf64_alpha_vec
5310#define TARGET_LITTLE_NAME "elf64-alpha"
5311#define ELF_ARCH bfd_arch_alpha
56fc028e
AJ
5312#define ELF_MACHINE_CODE EM_ALPHA
5313#define ELF_MAXPAGESIZE 0x10000
24718e3b 5314#define ELF_COMMONPAGESIZE 0x2000
252b5132
RH
5315
5316#define bfd_elf64_bfd_link_hash_table_create \
5317 elf64_alpha_bfd_link_hash_table_create
5318
5319#define bfd_elf64_bfd_reloc_type_lookup \
5320 elf64_alpha_bfd_reloc_type_lookup
157090f7
AM
5321#define bfd_elf64_bfd_reloc_name_lookup \
5322 elf64_alpha_bfd_reloc_name_lookup
252b5132
RH
5323#define elf_info_to_howto \
5324 elf64_alpha_info_to_howto
5325
5326#define bfd_elf64_mkobject \
5327 elf64_alpha_mkobject
5328#define elf_backend_object_p \
5329 elf64_alpha_object_p
5330
5331#define elf_backend_section_from_shdr \
5332 elf64_alpha_section_from_shdr
204692d7
RH
5333#define elf_backend_section_flags \
5334 elf64_alpha_section_flags
252b5132
RH
5335#define elf_backend_fake_sections \
5336 elf64_alpha_fake_sections
5337
5338#define bfd_elf64_bfd_is_local_label_name \
5339 elf64_alpha_is_local_label_name
5340#define bfd_elf64_find_nearest_line \
5341 elf64_alpha_find_nearest_line
5342#define bfd_elf64_bfd_relax_section \
5343 elf64_alpha_relax_section
5344
5345#define elf_backend_add_symbol_hook \
5346 elf64_alpha_add_symbol_hook
13285a1b
AM
5347#define elf_backend_relocs_compatible \
5348 _bfd_elf_relocs_compatible
252b5132
RH
5349#define elf_backend_check_relocs \
5350 elf64_alpha_check_relocs
5351#define elf_backend_create_dynamic_sections \
5352 elf64_alpha_create_dynamic_sections
5353#define elf_backend_adjust_dynamic_symbol \
5354 elf64_alpha_adjust_dynamic_symbol
747ffa7b
AM
5355#define elf_backend_merge_symbol_attribute \
5356 elf64_alpha_merge_symbol_attribute
252b5132
RH
5357#define elf_backend_always_size_sections \
5358 elf64_alpha_always_size_sections
5359#define elf_backend_size_dynamic_sections \
5360 elf64_alpha_size_dynamic_sections
74541ad4
AM
5361#define elf_backend_omit_section_dynsym \
5362 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
252b5132
RH
5363#define elf_backend_relocate_section \
5364 elf64_alpha_relocate_section
5365#define elf_backend_finish_dynamic_symbol \
5366 elf64_alpha_finish_dynamic_symbol
5367#define elf_backend_finish_dynamic_sections \
5368 elf64_alpha_finish_dynamic_sections
5369#define bfd_elf64_bfd_final_link \
5370 elf64_alpha_final_link
fcfbdf31
JJ
5371#define elf_backend_reloc_type_class \
5372 elf64_alpha_reloc_type_class
252b5132
RH
5373
5374#define elf_backend_ecoff_debug_swap \
5375 &elf64_alpha_ecoff_debug_swap
5376
70bcb145
JW
5377#define elf_backend_size_info \
5378 alpha_elf_size_info
5379
29ef7005
L
5380#define elf_backend_special_sections \
5381 elf64_alpha_special_sections
2f89ff8d 5382
38b1a46c 5383/* A few constants that determine how the .plt section is set up. */
252b5132
RH
5384#define elf_backend_want_got_plt 0
5385#define elf_backend_plt_readonly 0
5386#define elf_backend_want_plt_sym 1
5387#define elf_backend_got_header_size 0
252b5132
RH
5388
5389#include "elf64-target.h"
2238051f
RH
5390\f
5391/* FreeBSD support. */
5392
5393#undef TARGET_LITTLE_SYM
5394#define TARGET_LITTLE_SYM bfd_elf64_alpha_freebsd_vec
5395#undef TARGET_LITTLE_NAME
5396#define TARGET_LITTLE_NAME "elf64-alpha-freebsd"
d1036acb
L
5397#undef ELF_OSABI
5398#define ELF_OSABI ELFOSABI_FREEBSD
2238051f
RH
5399
5400/* The kernel recognizes executables as valid only if they carry a
5401 "FreeBSD" label in the ELF header. So we put this label on all
5402 executables and (for simplicity) also all other object files. */
5403
2238051f 5404static void
a7519a3c
RH
5405elf64_alpha_fbsd_post_process_headers (bfd * abfd,
5406 struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
2238051f
RH
5407{
5408 Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */
5409
5410 i_ehdrp = elf_elfheader (abfd);
5411
5412 /* Put an ABI label supported by FreeBSD >= 4.1. */
d1036acb 5413 i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
2238051f
RH
5414#ifdef OLD_FREEBSD_ABI_LABEL
5415 /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */
5416 memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
5417#endif
5418}
5419
5420#undef elf_backend_post_process_headers
5421#define elf_backend_post_process_headers \
5422 elf64_alpha_fbsd_post_process_headers
5423
571fe01f 5424#undef elf64_bed
2238051f
RH
5425#define elf64_bed elf64_alpha_fbsd_bed
5426
5427#include "elf64-target.h"