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