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