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