source: trunk/src/binutils/bfd/elf64-alpha.c@ 729

Last change on this file since 729 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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