* stabsread.c (read_type): Add code to parse Sun's syntax for
[deliverable/binutils-gdb.git] / bfd / elf64-alpha.c
CommitLineData
252b5132 1/* Alpha specific support for 64-bit ELF
73896efb 2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
7898deda 3 Free Software Foundation, Inc.
252b5132
RH
4 Contributed by Richard Henderson <rth@tamu.edu>.
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, 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
fe8bc63d 38/* Get the ECOFF swapping routines. Needed for the debug information. */
252b5132
RH
39#include "coff/internal.h"
40#include "coff/sym.h"
41#include "coff/symconst.h"
42#include "coff/ecoff.h"
43#include "coff/alpha.h"
44#include "aout/ar.h"
45#include "libcoff.h"
46#include "libecoff.h"
47#define ECOFF_64
48#include "ecoffswap.h"
49
8fb35fed
RH
50static int alpha_elf_dynamic_symbol_p
51 PARAMS((struct elf_link_hash_entry *, struct bfd_link_info *));
252b5132
RH
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 *, Elf64_Internal_Rela *));
70
8fb35fed
RH
71static boolean elf64_alpha_mkobject
72 PARAMS((bfd *));
252b5132
RH
73static boolean elf64_alpha_object_p
74 PARAMS((bfd *));
75static boolean elf64_alpha_section_from_shdr
76 PARAMS((bfd *, Elf64_Internal_Shdr *, char *));
204692d7
RH
77static boolean elf64_alpha_section_flags
78 PARAMS((flagword *, Elf64_Internal_Shdr *));
252b5132
RH
79static boolean elf64_alpha_fake_sections
80 PARAMS((bfd *, Elf64_Internal_Shdr *, asection *));
81static boolean elf64_alpha_create_got_section
82 PARAMS((bfd *, struct bfd_link_info *));
83static boolean elf64_alpha_create_dynamic_sections
84 PARAMS((bfd *, struct bfd_link_info *));
85
86static boolean elf64_alpha_read_ecoff_info
87 PARAMS((bfd *, asection *, struct ecoff_debug_info *));
88static boolean elf64_alpha_is_local_label_name
89 PARAMS((bfd *, const char *));
90static 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 boolean elf64_alpha_output_extsym
99 PARAMS((struct alpha_elf_link_hash_entry *, PTR));
100
101static boolean elf64_alpha_can_merge_gots
102 PARAMS((bfd *, bfd *));
103static void elf64_alpha_merge_gots
104 PARAMS((bfd *, bfd *));
105static boolean elf64_alpha_calc_got_offsets_for_symbol
106 PARAMS ((struct alpha_elf_link_hash_entry *, PTR));
107static void elf64_alpha_calc_got_offsets PARAMS ((struct bfd_link_info *));
108static boolean elf64_alpha_size_got_sections
109 PARAMS ((bfd *, struct bfd_link_info *));
110static boolean elf64_alpha_always_size_sections
111 PARAMS ((bfd *, struct bfd_link_info *));
112static boolean elf64_alpha_calc_dynrel_sizes
113 PARAMS ((struct alpha_elf_link_hash_entry *, struct bfd_link_info *));
114static boolean elf64_alpha_add_symbol_hook
115 PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
116 const char **, flagword *, asection **, bfd_vma *));
117static boolean elf64_alpha_check_relocs
118 PARAMS((bfd *, struct bfd_link_info *, asection *sec,
119 const Elf_Internal_Rela *));
120static boolean elf64_alpha_adjust_dynamic_symbol
121 PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
122static boolean elf64_alpha_size_dynamic_sections
123 PARAMS((bfd *, struct bfd_link_info *));
252b5132
RH
124static boolean elf64_alpha_relocate_section
125 PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
126 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
127static boolean elf64_alpha_finish_dynamic_symbol
128 PARAMS((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
129 Elf_Internal_Sym *));
130static boolean elf64_alpha_finish_dynamic_sections
131 PARAMS((bfd *, struct bfd_link_info *));
132static boolean elf64_alpha_final_link
133 PARAMS((bfd *, struct bfd_link_info *));
cd6f9321
L
134static boolean elf64_alpha_merge_ind_symbols
135 PARAMS((struct alpha_elf_link_hash_entry *, PTR));
136static Elf_Internal_Rela * elf64_alpha_find_reloc_at_ofs
137 PARAMS ((Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_vma, int));
fcfbdf31 138static enum elf_reloc_type_class elf64_alpha_reloc_type_class
f51e552e 139 PARAMS ((const Elf_Internal_Rela *));
252b5132
RH
140\f
141struct alpha_elf_link_hash_entry
142{
143 struct elf_link_hash_entry root;
144
145 /* External symbol information. */
146 EXTR esym;
147
148 /* Cumulative flags for all the .got entries. */
149 int flags;
150
151 /* Contexts (LITUSE) in which a literal was referenced. */
152#define ALPHA_ELF_LINK_HASH_LU_ADDR 0x01
153#define ALPHA_ELF_LINK_HASH_LU_MEM 0x02
154#define ALPHA_ELF_LINK_HASH_LU_BYTE 0x04
155#define ALPHA_ELF_LINK_HASH_LU_FUNC 0x08
156
157 /* Used to implement multiple .got subsections. */
158 struct alpha_elf_got_entry
159 {
160 struct alpha_elf_got_entry *next;
161
162 /* which .got subsection? */
163 bfd *gotobj;
164
165 /* the addend in effect for this entry. */
dc810e39 166 bfd_vma addend;
252b5132
RH
167
168 /* the .got offset for this entry. */
169 int got_offset;
170
171 int flags;
172
f7460f5f 173 /* Additional flags. */
252b5132 174#define ALPHA_ELF_GOT_ENTRY_RELOCS_DONE 0x10
f7460f5f 175#define ALPHA_ELF_GOT_ENTRY_RELOCS_XLATED 0x20
252b5132
RH
176
177 int use_count;
178 } *got_entries;
179
180 /* used to count non-got, non-plt relocations for delayed sizing
181 of relocation sections. */
182 struct alpha_elf_reloc_entry
183 {
184 struct alpha_elf_reloc_entry *next;
185
186 /* which .reloc section? */
187 asection *srel;
188
189 /* what kind of relocation? */
fcfbdf31
JJ
190 unsigned int rtype;
191
192 /* is this against read-only section? */
193 unsigned int reltext : 1;
252b5132
RH
194
195 /* how many did we find? */
196 unsigned long count;
197 } *reloc_entries;
198};
199
200/* Alpha ELF linker hash table. */
201
202struct alpha_elf_link_hash_table
203{
204 struct elf_link_hash_table root;
205
206 /* The head of a list of .got subsections linked through
207 alpha_elf_tdata(abfd)->got_link_next. */
208 bfd *got_list;
209};
210
211/* Look up an entry in a Alpha ELF linker hash table. */
212
213#define alpha_elf_link_hash_lookup(table, string, create, copy, follow) \
214 ((struct alpha_elf_link_hash_entry *) \
215 elf_link_hash_lookup (&(table)->root, (string), (create), \
216 (copy), (follow)))
217
218/* Traverse a Alpha ELF linker hash table. */
219
220#define alpha_elf_link_hash_traverse(table, func, info) \
221 (elf_link_hash_traverse \
222 (&(table)->root, \
223 (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
224 (info)))
225
226/* Get the Alpha ELF linker hash table from a link_info structure. */
227
228#define alpha_elf_hash_table(p) \
229 ((struct alpha_elf_link_hash_table *) ((p)->hash))
230
231/* Get the object's symbols as our own entry type. */
232
233#define alpha_elf_sym_hashes(abfd) \
234 ((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
235
236/* Should we do dynamic things to this symbol? */
237
8fb35fed
RH
238static int
239alpha_elf_dynamic_symbol_p (h, info)
240 struct elf_link_hash_entry *h;
241 struct bfd_link_info *info;
242{
243 if (h == NULL)
244 return false;
245
246 while (h->root.type == bfd_link_hash_indirect
247 || h->root.type == bfd_link_hash_warning)
248 h = (struct elf_link_hash_entry *) h->root.u.i.link;
249
250 if (h->dynindx == -1)
251 return false;
ca88208a
RH
252
253 if (h->root.type == bfd_link_hash_undefweak
254 || h->root.type == bfd_link_hash_defweak)
255 return true;
256
2719f880
L
257 switch (ELF_ST_VISIBILITY (h->other))
258 {
ca88208a
RH
259 case STV_DEFAULT:
260 break;
2719f880 261 case STV_HIDDEN:
ca88208a 262 case STV_INTERNAL:
2719f880 263 return false;
ca88208a
RH
264 case STV_PROTECTED:
265 if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
266 return false;
267 break;
2719f880 268 }
8fb35fed 269
8fb35fed
RH
270 if ((info->shared && !info->symbolic)
271 || ((h->elf_link_hash_flags
272 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
273 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
274 return true;
275
276 return false;
277}
252b5132
RH
278
279/* Create an entry in a Alpha ELF linker hash table. */
280
281static struct bfd_hash_entry *
282elf64_alpha_link_hash_newfunc (entry, table, string)
283 struct bfd_hash_entry *entry;
284 struct bfd_hash_table *table;
285 const char *string;
286{
287 struct alpha_elf_link_hash_entry *ret =
288 (struct alpha_elf_link_hash_entry *) entry;
289
290 /* Allocate the structure if it has not already been allocated by a
291 subclass. */
292 if (ret == (struct alpha_elf_link_hash_entry *) NULL)
293 ret = ((struct alpha_elf_link_hash_entry *)
294 bfd_hash_allocate (table,
295 sizeof (struct alpha_elf_link_hash_entry)));
296 if (ret == (struct alpha_elf_link_hash_entry *) NULL)
297 return (struct bfd_hash_entry *) ret;
298
299 /* Call the allocation method of the superclass. */
300 ret = ((struct alpha_elf_link_hash_entry *)
301 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
302 table, string));
303 if (ret != (struct alpha_elf_link_hash_entry *) NULL)
304 {
305 /* Set local fields. */
306 memset (&ret->esym, 0, sizeof (EXTR));
307 /* We use -2 as a marker to indicate that the information has
308 not been set. -1 means there is no associated ifd. */
309 ret->esym.ifd = -2;
310 ret->flags = 0;
311 ret->got_entries = NULL;
312 ret->reloc_entries = NULL;
313 }
314
315 return (struct bfd_hash_entry *) ret;
316}
317
318/* Create a Alpha ELF linker hash table. */
319
320static struct bfd_link_hash_table *
321elf64_alpha_bfd_link_hash_table_create (abfd)
322 bfd *abfd;
323{
324 struct alpha_elf_link_hash_table *ret;
dc810e39 325 bfd_size_type amt = sizeof (struct alpha_elf_link_hash_table);
252b5132 326
dc810e39 327 ret = (struct alpha_elf_link_hash_table *) bfd_zalloc (abfd, amt);
252b5132
RH
328 if (ret == (struct alpha_elf_link_hash_table *) NULL)
329 return NULL;
330
331 if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
332 elf64_alpha_link_hash_newfunc))
333 {
334 bfd_release (abfd, ret);
335 return NULL;
336 }
337
338 return &ret->root.root;
339}
340\f
341/* We have some private fields hanging off of the elf_tdata structure. */
342
343struct alpha_elf_obj_tdata
344{
345 struct elf_obj_tdata root;
346
347 /* For every input file, these are the got entries for that object's
348 local symbols. */
349 struct alpha_elf_got_entry ** local_got_entries;
350
351 /* For every input file, this is the object that owns the got that
352 this input file uses. */
353 bfd *gotobj;
354
355 /* For every got, this is a linked list through the objects using this got */
356 bfd *in_got_link_next;
357
358 /* For every got, this is a link to the next got subsegment. */
359 bfd *got_link_next;
360
361 /* For every got, this is the section. */
362 asection *got;
363
364 /* For every got, this is it's total number of *entries*. */
365 int total_got_entries;
366
367 /* For every got, this is the sum of the number of *entries* required
368 to hold all of the member object's local got. */
369 int n_local_got_entries;
370};
371
372#define alpha_elf_tdata(abfd) \
373 ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any)
374
375static boolean
376elf64_alpha_mkobject (abfd)
377 bfd *abfd;
378{
dc810e39
AM
379 bfd_size_type amt = sizeof (struct alpha_elf_obj_tdata);
380 abfd->tdata.any = bfd_zalloc (abfd, amt);
252b5132
RH
381 if (abfd->tdata.any == NULL)
382 return false;
383 return true;
384}
385
386static boolean
387elf64_alpha_object_p (abfd)
388 bfd *abfd;
389{
390 /* Allocate our special target data. */
391 struct alpha_elf_obj_tdata *new_tdata;
dc810e39
AM
392 bfd_size_type amt = sizeof (struct alpha_elf_obj_tdata);
393 new_tdata = bfd_zalloc (abfd, amt);
252b5132
RH
394 if (new_tdata == NULL)
395 return false;
396 new_tdata->root = *abfd->tdata.elf_obj_data;
397 abfd->tdata.any = new_tdata;
398
399 /* Set the right machine number for an Alpha ELF file. */
400 return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
401}
402\f
403/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
404 from smaller values. Start with zero, widen, *then* decrement. */
405#define MINUS_ONE (((bfd_vma)0) - 1)
406
dfe57ca0
RH
407#define SKIP_HOWTO(N) \
408 HOWTO(N, 0, 0, 0, 0, 0, 0, elf64_alpha_reloc_bad, 0, 0, 0, 0, 0)
409
252b5132
RH
410static reloc_howto_type elf64_alpha_howto_table[] =
411{
412 HOWTO (R_ALPHA_NONE, /* type */
413 0, /* rightshift */
414 0, /* size (0 = byte, 1 = short, 2 = long) */
415 8, /* bitsize */
416 true, /* pc_relative */
417 0, /* bitpos */
418 complain_overflow_dont, /* complain_on_overflow */
419 elf64_alpha_reloc_nil, /* special_function */
420 "NONE", /* name */
421 false, /* partial_inplace */
422 0, /* src_mask */
423 0, /* dst_mask */
424 true), /* pcrel_offset */
425
426 /* A 32 bit reference to a symbol. */
427 HOWTO (R_ALPHA_REFLONG, /* type */
428 0, /* rightshift */
429 2, /* size (0 = byte, 1 = short, 2 = long) */
430 32, /* bitsize */
431 false, /* pc_relative */
432 0, /* bitpos */
433 complain_overflow_bitfield, /* complain_on_overflow */
434 0, /* special_function */
435 "REFLONG", /* name */
436 false, /* partial_inplace */
437 0xffffffff, /* src_mask */
438 0xffffffff, /* dst_mask */
439 false), /* pcrel_offset */
440
441 /* A 64 bit reference to a symbol. */
442 HOWTO (R_ALPHA_REFQUAD, /* type */
443 0, /* rightshift */
444 4, /* size (0 = byte, 1 = short, 2 = long) */
445 64, /* bitsize */
446 false, /* pc_relative */
447 0, /* bitpos */
448 complain_overflow_bitfield, /* complain_on_overflow */
449 0, /* special_function */
450 "REFQUAD", /* name */
451 false, /* partial_inplace */
452 MINUS_ONE, /* src_mask */
453 MINUS_ONE, /* dst_mask */
454 false), /* pcrel_offset */
455
456 /* A 32 bit GP relative offset. This is just like REFLONG except
457 that when the value is used the value of the gp register will be
458 added in. */
459 HOWTO (R_ALPHA_GPREL32, /* type */
460 0, /* rightshift */
461 2, /* size (0 = byte, 1 = short, 2 = long) */
462 32, /* bitsize */
463 false, /* pc_relative */
464 0, /* bitpos */
465 complain_overflow_bitfield, /* complain_on_overflow */
466 0, /* special_function */
467 "GPREL32", /* name */
468 false, /* partial_inplace */
469 0xffffffff, /* src_mask */
470 0xffffffff, /* dst_mask */
471 false), /* pcrel_offset */
472
473 /* Used for an instruction that refers to memory off the GP register. */
474 HOWTO (R_ALPHA_LITERAL, /* type */
475 0, /* rightshift */
dfe57ca0 476 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132
RH
477 16, /* bitsize */
478 false, /* pc_relative */
479 0, /* bitpos */
480 complain_overflow_signed, /* complain_on_overflow */
481 0, /* special_function */
482 "ELF_LITERAL", /* name */
483 false, /* partial_inplace */
484 0xffff, /* src_mask */
485 0xffff, /* dst_mask */
486 false), /* pcrel_offset */
487
488 /* This reloc only appears immediately following an ELF_LITERAL reloc.
489 It identifies a use of the literal. The symbol index is special:
490 1 means the literal address is in the base register of a memory
491 format instruction; 2 means the literal address is in the byte
492 offset register of a byte-manipulation instruction; 3 means the
493 literal address is in the target register of a jsr instruction.
494 This does not actually do any relocation. */
495 HOWTO (R_ALPHA_LITUSE, /* type */
496 0, /* rightshift */
dfe57ca0 497 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132
RH
498 32, /* bitsize */
499 false, /* pc_relative */
500 0, /* bitpos */
501 complain_overflow_dont, /* complain_on_overflow */
502 elf64_alpha_reloc_nil, /* special_function */
503 "LITUSE", /* name */
504 false, /* partial_inplace */
505 0, /* src_mask */
506 0, /* dst_mask */
507 false), /* pcrel_offset */
508
509 /* Load the gp register. This is always used for a ldah instruction
510 which loads the upper 16 bits of the gp register. The symbol
511 index of the GPDISP instruction is an offset in bytes to the lda
512 instruction that loads the lower 16 bits. The value to use for
513 the relocation is the difference between the GP value and the
514 current location; the load will always be done against a register
515 holding the current address.
516
517 NOTE: Unlike ECOFF, partial in-place relocation is not done. If
518 any offset is present in the instructions, it is an offset from
519 the register to the ldah instruction. This lets us avoid any
520 stupid hackery like inventing a gp value to do partial relocation
521 against. Also unlike ECOFF, we do the whole relocation off of
522 the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair. An odd,
523 space consuming bit, that, since all the information was present
524 in the GPDISP_HI16 reloc. */
525 HOWTO (R_ALPHA_GPDISP, /* type */
526 16, /* rightshift */
527 2, /* size (0 = byte, 1 = short, 2 = long) */
528 16, /* bitsize */
529 false, /* pc_relative */
530 0, /* bitpos */
531 complain_overflow_dont, /* complain_on_overflow */
532 elf64_alpha_reloc_gpdisp, /* special_function */
533 "GPDISP", /* name */
534 false, /* partial_inplace */
535 0xffff, /* src_mask */
536 0xffff, /* dst_mask */
537 true), /* pcrel_offset */
538
539 /* A 21 bit branch. */
540 HOWTO (R_ALPHA_BRADDR, /* type */
541 2, /* rightshift */
542 2, /* size (0 = byte, 1 = short, 2 = long) */
543 21, /* bitsize */
544 true, /* pc_relative */
545 0, /* bitpos */
546 complain_overflow_signed, /* complain_on_overflow */
547 0, /* special_function */
548 "BRADDR", /* name */
549 false, /* partial_inplace */
550 0x1fffff, /* src_mask */
551 0x1fffff, /* dst_mask */
552 true), /* pcrel_offset */
553
554 /* A hint for a jump to a register. */
555 HOWTO (R_ALPHA_HINT, /* type */
556 2, /* rightshift */
dfe57ca0 557 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132
RH
558 14, /* bitsize */
559 true, /* pc_relative */
560 0, /* bitpos */
561 complain_overflow_dont, /* complain_on_overflow */
562 0, /* special_function */
563 "HINT", /* name */
564 false, /* partial_inplace */
565 0x3fff, /* src_mask */
566 0x3fff, /* dst_mask */
567 true), /* pcrel_offset */
568
569 /* 16 bit PC relative offset. */
570 HOWTO (R_ALPHA_SREL16, /* type */
571 0, /* rightshift */
572 1, /* size (0 = byte, 1 = short, 2 = long) */
573 16, /* bitsize */
574 true, /* pc_relative */
575 0, /* bitpos */
576 complain_overflow_signed, /* complain_on_overflow */
577 0, /* special_function */
578 "SREL16", /* name */
579 false, /* partial_inplace */
580 0xffff, /* src_mask */
581 0xffff, /* dst_mask */
16b65e4e 582 true), /* pcrel_offset */
252b5132
RH
583
584 /* 32 bit PC relative offset. */
585 HOWTO (R_ALPHA_SREL32, /* type */
586 0, /* rightshift */
587 2, /* size (0 = byte, 1 = short, 2 = long) */
588 32, /* bitsize */
589 true, /* pc_relative */
590 0, /* bitpos */
591 complain_overflow_signed, /* complain_on_overflow */
592 0, /* special_function */
593 "SREL32", /* name */
594 false, /* partial_inplace */
595 0xffffffff, /* src_mask */
596 0xffffffff, /* dst_mask */
16b65e4e 597 true), /* pcrel_offset */
252b5132
RH
598
599 /* A 64 bit PC relative offset. */
600 HOWTO (R_ALPHA_SREL64, /* type */
601 0, /* rightshift */
602 4, /* size (0 = byte, 1 = short, 2 = long) */
603 64, /* bitsize */
604 true, /* pc_relative */
605 0, /* bitpos */
606 complain_overflow_signed, /* complain_on_overflow */
607 0, /* special_function */
608 "SREL64", /* name */
609 false, /* partial_inplace */
610 MINUS_ONE, /* src_mask */
611 MINUS_ONE, /* dst_mask */
16b65e4e 612 true), /* pcrel_offset */
252b5132 613
dfe57ca0
RH
614 /* Skip 12 - 16; deprecated ECOFF relocs. */
615 SKIP_HOWTO (12),
616 SKIP_HOWTO (13),
617 SKIP_HOWTO (14),
618 SKIP_HOWTO (15),
619 SKIP_HOWTO (16),
252b5132
RH
620
621 /* The high 16 bits of the displacement from GP to the target. */
622 HOWTO (R_ALPHA_GPRELHIGH,
623 0, /* rightshift */
dfe57ca0 624 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132
RH
625 16, /* bitsize */
626 false, /* pc_relative */
627 0, /* bitpos */
628 complain_overflow_signed, /* complain_on_overflow */
dfe57ca0 629 0, /* special_function */
252b5132
RH
630 "GPRELHIGH", /* name */
631 false, /* partial_inplace */
632 0xffff, /* src_mask */
633 0xffff, /* dst_mask */
634 false), /* pcrel_offset */
635
636 /* The low 16 bits of the displacement from GP to the target. */
637 HOWTO (R_ALPHA_GPRELLOW,
638 0, /* rightshift */
dfe57ca0 639 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132
RH
640 16, /* bitsize */
641 false, /* pc_relative */
642 0, /* bitpos */
643 complain_overflow_dont, /* complain_on_overflow */
dfe57ca0 644 0, /* special_function */
252b5132
RH
645 "GPRELLOW", /* name */
646 false, /* partial_inplace */
647 0xffff, /* src_mask */
648 0xffff, /* dst_mask */
649 false), /* pcrel_offset */
650
651 /* A 16-bit displacement from the GP to the target. */
dfe57ca0 652 HOWTO (R_ALPHA_GPREL16,
252b5132 653 0, /* rightshift */
dfe57ca0 654 1, /* size (0 = byte, 1 = short, 2 = long) */
252b5132
RH
655 16, /* bitsize */
656 false, /* pc_relative */
657 0, /* bitpos */
658 complain_overflow_signed, /* complain_on_overflow */
659 0, /* special_function */
dfe57ca0 660 "GPREL16", /* name */
252b5132
RH
661 false, /* partial_inplace */
662 0xffff, /* src_mask */
663 0xffff, /* dst_mask */
664 false), /* pcrel_offset */
665
dfe57ca0
RH
666 /* Skip 20 - 23; deprecated ECOFF relocs. */
667 SKIP_HOWTO (20),
668 SKIP_HOWTO (21),
669 SKIP_HOWTO (22),
670 SKIP_HOWTO (23),
252b5132 671
fe8bc63d 672 /* Misc ELF relocations. */
252b5132
RH
673
674 /* A dynamic relocation to copy the target into our .dynbss section. */
675 /* Not generated, as all Alpha objects use PIC, so it is not needed. It
676 is present because every other ELF has one, but should not be used
677 because .dynbss is an ugly thing. */
678 HOWTO (R_ALPHA_COPY,
679 0,
680 0,
681 0,
682 false,
683 0,
684 complain_overflow_dont,
685 bfd_elf_generic_reloc,
686 "COPY",
687 false,
688 0,
689 0,
690 true),
691
692 /* A dynamic relocation for a .got entry. */
693 HOWTO (R_ALPHA_GLOB_DAT,
694 0,
695 0,
696 0,
697 false,
698 0,
699 complain_overflow_dont,
700 bfd_elf_generic_reloc,
701 "GLOB_DAT",
702 false,
703 0,
704 0,
705 true),
706
707 /* A dynamic relocation for a .plt entry. */
708 HOWTO (R_ALPHA_JMP_SLOT,
709 0,
710 0,
711 0,
712 false,
713 0,
714 complain_overflow_dont,
715 bfd_elf_generic_reloc,
716 "JMP_SLOT",
717 false,
718 0,
719 0,
720 true),
721
722 /* A dynamic relocation to add the base of the DSO to a 64-bit field. */
723 HOWTO (R_ALPHA_RELATIVE,
724 0,
725 0,
726 0,
727 false,
728 0,
729 complain_overflow_dont,
730 bfd_elf_generic_reloc,
731 "RELATIVE",
732 false,
733 0,
734 0,
735 true)
736};
737
738/* A relocation function which doesn't do anything. */
739
740static bfd_reloc_status_type
741elf64_alpha_reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
56fc028e 742 bfd *abfd ATTRIBUTE_UNUSED;
252b5132 743 arelent *reloc;
56fc028e
AJ
744 asymbol *sym ATTRIBUTE_UNUSED;
745 PTR data ATTRIBUTE_UNUSED;
252b5132
RH
746 asection *sec;
747 bfd *output_bfd;
56fc028e 748 char **error_message ATTRIBUTE_UNUSED;
252b5132
RH
749{
750 if (output_bfd)
751 reloc->address += sec->output_offset;
752 return bfd_reloc_ok;
753}
754
755/* A relocation function used for an unsupported reloc. */
756
757static bfd_reloc_status_type
758elf64_alpha_reloc_bad (abfd, reloc, sym, data, sec, output_bfd, error_message)
56fc028e 759 bfd *abfd ATTRIBUTE_UNUSED;
252b5132 760 arelent *reloc;
56fc028e
AJ
761 asymbol *sym ATTRIBUTE_UNUSED;
762 PTR data ATTRIBUTE_UNUSED;
252b5132
RH
763 asection *sec;
764 bfd *output_bfd;
56fc028e 765 char **error_message ATTRIBUTE_UNUSED;
252b5132
RH
766{
767 if (output_bfd)
768 reloc->address += sec->output_offset;
769 return bfd_reloc_notsupported;
770}
771
772/* Do the work of the GPDISP relocation. */
773
774static bfd_reloc_status_type
775elf64_alpha_do_reloc_gpdisp (abfd, gpdisp, p_ldah, p_lda)
776 bfd *abfd;
777 bfd_vma gpdisp;
778 bfd_byte *p_ldah;
779 bfd_byte *p_lda;
780{
781 bfd_reloc_status_type ret = bfd_reloc_ok;
782 bfd_vma addend;
783 unsigned long i_ldah, i_lda;
784
785 i_ldah = bfd_get_32 (abfd, p_ldah);
786 i_lda = bfd_get_32 (abfd, p_lda);
787
788 /* Complain if the instructions are not correct. */
789 if (((i_ldah >> 26) & 0x3f) != 0x09
790 || ((i_lda >> 26) & 0x3f) != 0x08)
791 ret = bfd_reloc_dangerous;
792
793 /* Extract the user-supplied offset, mirroring the sign extensions
794 that the instructions perform. */
795 addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff);
796 addend = (addend ^ 0x80008000) - 0x80008000;
797
798 gpdisp += addend;
799
800 if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000
801 || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000)
802 ret = bfd_reloc_overflow;
803
804 /* compensate for the sign extension again. */
805 i_ldah = ((i_ldah & 0xffff0000)
806 | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff));
807 i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff);
808
dc810e39
AM
809 bfd_put_32 (abfd, (bfd_vma) i_ldah, p_ldah);
810 bfd_put_32 (abfd, (bfd_vma) i_lda, p_lda);
252b5132
RH
811
812 return ret;
813}
814
815/* The special function for the GPDISP reloc. */
816
817static bfd_reloc_status_type
818elf64_alpha_reloc_gpdisp (abfd, reloc_entry, sym, data, input_section,
819 output_bfd, err_msg)
820 bfd *abfd;
821 arelent *reloc_entry;
56fc028e 822 asymbol *sym ATTRIBUTE_UNUSED;
252b5132
RH
823 PTR data;
824 asection *input_section;
825 bfd *output_bfd;
826 char **err_msg;
827{
828 bfd_reloc_status_type ret;
829 bfd_vma gp, relocation;
830 bfd_byte *p_ldah, *p_lda;
831
832 /* Don't do anything if we're not doing a final link. */
833 if (output_bfd)
834 {
835 reloc_entry->address += input_section->output_offset;
836 return bfd_reloc_ok;
837 }
838
839 if (reloc_entry->address > input_section->_cooked_size ||
840 reloc_entry->address + reloc_entry->addend > input_section->_cooked_size)
841 return bfd_reloc_outofrange;
842
843 /* The gp used in the portion of the output object to which this
844 input object belongs is cached on the input bfd. */
845 gp = _bfd_get_gp_value (abfd);
846
847 relocation = (input_section->output_section->vma
848 + input_section->output_offset
849 + reloc_entry->address);
850
851 p_ldah = (bfd_byte *) data + reloc_entry->address;
852 p_lda = p_ldah + reloc_entry->addend;
853
854 ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda);
855
856 /* Complain if the instructions are not correct. */
857 if (ret == bfd_reloc_dangerous)
858 *err_msg = _("GPDISP relocation did not find ldah and lda instructions");
859
860 return ret;
861}
862
863/* A mapping from BFD reloc types to Alpha ELF reloc types. */
864
865struct elf_reloc_map
866{
867 bfd_reloc_code_real_type bfd_reloc_val;
868 int elf_reloc_val;
869};
870
871static const struct elf_reloc_map elf64_alpha_reloc_map[] =
872{
dfe57ca0
RH
873 {BFD_RELOC_NONE, R_ALPHA_NONE},
874 {BFD_RELOC_32, R_ALPHA_REFLONG},
875 {BFD_RELOC_64, R_ALPHA_REFQUAD},
876 {BFD_RELOC_CTOR, R_ALPHA_REFQUAD},
877 {BFD_RELOC_GPREL32, R_ALPHA_GPREL32},
878 {BFD_RELOC_ALPHA_ELF_LITERAL, R_ALPHA_LITERAL},
879 {BFD_RELOC_ALPHA_LITUSE, R_ALPHA_LITUSE},
880 {BFD_RELOC_ALPHA_GPDISP, R_ALPHA_GPDISP},
881 {BFD_RELOC_23_PCREL_S2, R_ALPHA_BRADDR},
882 {BFD_RELOC_ALPHA_HINT, R_ALPHA_HINT},
883 {BFD_RELOC_16_PCREL, R_ALPHA_SREL16},
884 {BFD_RELOC_32_PCREL, R_ALPHA_SREL32},
885 {BFD_RELOC_64_PCREL, R_ALPHA_SREL64},
886 {BFD_RELOC_ALPHA_GPREL_HI16, R_ALPHA_GPRELHIGH},
887 {BFD_RELOC_ALPHA_GPREL_LO16, R_ALPHA_GPRELLOW},
888 {BFD_RELOC_GPREL16, R_ALPHA_GPREL16},
252b5132
RH
889};
890
891/* Given a BFD reloc type, return a HOWTO structure. */
892
893static reloc_howto_type *
894elf64_alpha_bfd_reloc_type_lookup (abfd, code)
56fc028e 895 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
896 bfd_reloc_code_real_type code;
897{
898 const struct elf_reloc_map *i, *e;
899 i = e = elf64_alpha_reloc_map;
900 e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map);
901 for (; i != e; ++i)
902 {
903 if (i->bfd_reloc_val == code)
904 return &elf64_alpha_howto_table[i->elf_reloc_val];
905 }
906 return 0;
907}
908
909/* Given an Alpha ELF reloc type, fill in an arelent structure. */
910
911static void
912elf64_alpha_info_to_howto (abfd, cache_ptr, dst)
56fc028e 913 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
914 arelent *cache_ptr;
915 Elf64_Internal_Rela *dst;
916{
917 unsigned r_type;
918
919 r_type = ELF64_R_TYPE(dst->r_info);
920 BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max);
921 cache_ptr->howto = &elf64_alpha_howto_table[r_type];
922}
923\f
fe8bc63d 924/* These functions do relaxation for Alpha ELF.
252b5132
RH
925
926 Currently I'm only handling what I can do with existing compiler
927 and assembler support, which means no instructions are removed,
928 though some may be nopped. At this time GCC does not emit enough
929 information to do all of the relaxing that is possible. It will
930 take some not small amount of work for that to happen.
931
932 There are a couple of interesting papers that I once read on this
933 subject, that I cannot find references to at the moment, that
934 related to Alpha in particular. They are by David Wall, then of
935 DEC WRL. */
936
937#define OP_LDA 0x08
938#define OP_LDAH 0x09
939#define INSN_JSR 0x68004000
940#define INSN_JSR_MASK 0xfc00c000
941#define OP_LDQ 0x29
942#define OP_BR 0x30
943#define OP_BSR 0x34
f304919d 944#define INSN_UNOP 0x2ffe0000
252b5132
RH
945
946struct alpha_relax_info
947{
948 bfd *abfd;
949 asection *sec;
950 bfd_byte *contents;
951 Elf_Internal_Rela *relocs, *relend;
952 struct bfd_link_info *link_info;
953 boolean changed_contents;
954 boolean changed_relocs;
955 bfd_vma gp;
956 bfd *gotobj;
957 asection *tsec;
958 struct alpha_elf_link_hash_entry *h;
959 struct alpha_elf_got_entry *gotent;
960 unsigned char other;
961};
962
963static Elf_Internal_Rela * elf64_alpha_relax_with_lituse
fe8bc63d 964 PARAMS((struct alpha_relax_info *info, bfd_vma symval,
252b5132
RH
965 Elf_Internal_Rela *irel, Elf_Internal_Rela *irelend));
966
967static boolean elf64_alpha_relax_without_lituse
fe8bc63d 968 PARAMS((struct alpha_relax_info *info, bfd_vma symval,
252b5132
RH
969 Elf_Internal_Rela *irel));
970
971static bfd_vma elf64_alpha_relax_opt_call
972 PARAMS((struct alpha_relax_info *info, bfd_vma symval));
973
974static boolean elf64_alpha_relax_section
975 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
976 boolean *again));
977
978static Elf_Internal_Rela *
979elf64_alpha_find_reloc_at_ofs (rel, relend, offset, type)
980 Elf_Internal_Rela *rel, *relend;
981 bfd_vma offset;
982 int type;
983{
984 while (rel < relend)
985 {
52b9d213
AM
986 if (rel->r_offset == offset
987 && ELF64_R_TYPE (rel->r_info) == (unsigned int) type)
252b5132
RH
988 return rel;
989 ++rel;
990 }
991 return NULL;
992}
993
994static Elf_Internal_Rela *
995elf64_alpha_relax_with_lituse (info, symval, irel, irelend)
996 struct alpha_relax_info *info;
997 bfd_vma symval;
998 Elf_Internal_Rela *irel, *irelend;
999{
1000 Elf_Internal_Rela *urel;
1001 int flags, count, i;
1002 bfd_signed_vma disp;
1003 boolean fits16;
1004 boolean fits32;
1005 boolean lit_reused = false;
1006 boolean all_optimized = true;
1007 unsigned int lit_insn;
1008
1009 lit_insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
1010 if (lit_insn >> 26 != OP_LDQ)
1011 {
1012 ((*_bfd_error_handler)
1013 ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn",
8f615d07
AM
1014 bfd_archive_filename (info->abfd), info->sec->name,
1015 (unsigned long) irel->r_offset));
252b5132
RH
1016 return irel;
1017 }
1018
1019 /* Summarize how this particular LITERAL is used. */
1020 for (urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count)
1021 {
1022 if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE)
1023 break;
1e738b87 1024 if (urel->r_addend <= 3)
252b5132
RH
1025 flags |= 1 << urel->r_addend;
1026 }
1027
fe8bc63d 1028 /* A little preparation for the loop... */
252b5132 1029 disp = symval - info->gp;
252b5132
RH
1030
1031 for (urel = irel+1, i = 0; i < count; ++i, ++urel)
1032 {
1033 unsigned int insn;
ffcb7aff
NC
1034 int insn_disp;
1035 bfd_signed_vma xdisp;
1036
252b5132
RH
1037 insn = bfd_get_32 (info->abfd, info->contents + urel->r_offset);
1038
1039 switch (urel->r_addend)
1040 {
1041 default: /* 0 = ADDRESS FORMAT */
1042 /* This type is really just a placeholder to note that all
1043 uses cannot be optimized, but to still allow some. */
1044 all_optimized = false;
1045 break;
1046
1047 case 1: /* MEM FORMAT */
1048 /* We can always optimize 16-bit displacements. */
ffcb7aff
NC
1049
1050 /* Extract the displacement from the instruction, sign-extending
1051 it if necessary, then test whether it is within 16 or 32 bits
1052 displacement from GP. */
1053 insn_disp = insn & 0x0000ffff;
1054 if (insn_disp & 0x00008000)
1055 insn_disp |= 0xffff0000; /* Negative: sign-extend. */
1056
1057 xdisp = disp + insn_disp;
1058 fits16 = (xdisp >= - (bfd_signed_vma) 0x00008000 && xdisp < 0x00008000);
1059 fits32 = (xdisp >= - (bfd_signed_vma) 0x80000000 && xdisp < 0x7fff8000);
1060
252b5132
RH
1061 if (fits16)
1062 {
ffcb7aff 1063 /* Take the op code and dest from this insn, take the base
fe8bc63d 1064 register from the literal insn. Leave the offset alone. */
ffcb7aff 1065 insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
252b5132 1066 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
dfe57ca0 1067 R_ALPHA_GPREL16);
252b5132
RH
1068 urel->r_addend = irel->r_addend;
1069 info->changed_relocs = true;
1070
dc810e39
AM
1071 bfd_put_32 (info->abfd, (bfd_vma) insn,
1072 info->contents + urel->r_offset);
252b5132
RH
1073 info->changed_contents = true;
1074 }
1075
1076 /* If all mem+byte, we can optimize 32-bit mem displacements. */
1077 else if (fits32 && !(flags & ~6))
1078 {
ffcb7aff 1079 /* FIXME: sanity check that lit insn Ra is mem insn Rb. */
252b5132
RH
1080
1081 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1082 R_ALPHA_GPRELHIGH);
1083 lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
dc810e39 1084 bfd_put_32 (info->abfd, (bfd_vma) lit_insn,
252b5132
RH
1085 info->contents + irel->r_offset);
1086 lit_reused = true;
1087 info->changed_contents = true;
1088
1089 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1090 R_ALPHA_GPRELLOW);
1091 urel->r_addend = irel->r_addend;
1092 info->changed_relocs = true;
1093 }
1094 else
1095 all_optimized = false;
1096 break;
1097
1098 case 2: /* BYTE OFFSET FORMAT */
1099 /* We can always optimize byte instructions. */
1100
1101 /* FIXME: sanity check the insn for byte op. Check that the
1102 literal dest reg is indeed Rb in the byte insn. */
1103
dc810e39
AM
1104 insn &= ~ (unsigned) 0x001ff000;
1105 insn |= ((symval & 7) << 13) | 0x1000;
252b5132
RH
1106
1107 urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1108 urel->r_addend = 0;
1109 info->changed_relocs = true;
1110
dc810e39
AM
1111 bfd_put_32 (info->abfd, (bfd_vma) insn,
1112 info->contents + urel->r_offset);
252b5132
RH
1113 info->changed_contents = true;
1114 break;
1115
1116 case 3: /* CALL FORMAT */
1117 {
1118 /* If not zero, place to jump without needing pv. */
1119 bfd_vma optdest = elf64_alpha_relax_opt_call (info, symval);
1120 bfd_vma org = (info->sec->output_section->vma
1121 + info->sec->output_offset
1122 + urel->r_offset + 4);
1123 bfd_signed_vma odisp;
1124
1125 odisp = (optdest ? optdest : symval) - org;
1126 if (odisp >= -0x400000 && odisp < 0x400000)
1127 {
1128 Elf_Internal_Rela *xrel;
1129
fe8bc63d 1130 /* Preserve branch prediction call stack when possible. */
252b5132
RH
1131 if ((insn & INSN_JSR_MASK) == INSN_JSR)
1132 insn = (OP_BSR << 26) | (insn & 0x03e00000);
1133 else
1134 insn = (OP_BR << 26) | (insn & 0x03e00000);
fe8bc63d 1135
252b5132
RH
1136 urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
1137 R_ALPHA_BRADDR);
1138 urel->r_addend = irel->r_addend;
1139
1140 if (optdest)
1141 urel->r_addend += optdest - symval;
1142 else
1143 all_optimized = false;
1144
dc810e39
AM
1145 bfd_put_32 (info->abfd, (bfd_vma) insn,
1146 info->contents + urel->r_offset);
252b5132
RH
1147
1148 /* Kill any HINT reloc that might exist for this insn. */
1149 xrel = (elf64_alpha_find_reloc_at_ofs
fe8bc63d 1150 (info->relocs, info->relend, urel->r_offset,
252b5132
RH
1151 R_ALPHA_HINT));
1152 if (xrel)
1153 xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1154
1155 info->changed_contents = true;
1156 info->changed_relocs = true;
1157 }
1158 else
1159 all_optimized = false;
1160
1cd6895c
RH
1161 /* Even if the target is not in range for a direct branch,
1162 if we share a GP, we can eliminate the gp reload. */
1163 if (optdest)
1164 {
1165 Elf_Internal_Rela *gpdisp
1166 = (elf64_alpha_find_reloc_at_ofs
1167 (irel, irelend, urel->r_offset + 4, R_ALPHA_GPDISP));
1168 if (gpdisp)
1169 {
1170 bfd_byte *p_ldah = info->contents + gpdisp->r_offset;
1171 bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
1172 unsigned int ldah = bfd_get_32 (info->abfd, p_ldah);
1173 unsigned int lda = bfd_get_32 (info->abfd, p_lda);
1174
1175 /* Verify that the instruction is "ldah $29,0($26)".
1176 Consider a function that ends in a noreturn call,
1177 and that the next function begins with an ldgp,
1178 and that by accident there is no padding between.
1179 In that case the insn would use $27 as the base. */
1180 if (ldah == 0x27ba0000 && lda == 0x23bd0000)
1181 {
dc810e39
AM
1182 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_ldah);
1183 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_lda);
1cd6895c
RH
1184
1185 gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1186 info->changed_contents = true;
1187 info->changed_relocs = true;
1188 }
1189 }
1190 }
252b5132
RH
1191 }
1192 break;
1193 }
1194 }
1195
1196 /* If all cases were optimized, we can reduce the use count on this
1197 got entry by one, possibly eliminating it. */
1198 if (all_optimized)
1199 {
1200 info->gotent->use_count -= 1;
1201 alpha_elf_tdata (info->gotent->gotobj)->total_got_entries -= 1;
1202 if (!info->h)
1203 alpha_elf_tdata (info->gotent->gotobj)->n_local_got_entries -= 1;
1204
1205 /* If the literal instruction is no longer needed (it may have been
1206 reused. We can eliminate it.
1207 ??? For now, I don't want to deal with compacting the section,
1208 so just nop it out. */
1209 if (!lit_reused)
1210 {
1211 irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
1212 info->changed_relocs = true;
1213
dc810e39
AM
1214 bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP,
1215 info->contents + irel->r_offset);
252b5132
RH
1216 info->changed_contents = true;
1217 }
1218 }
1219
1220 return irel + count;
1221}
1222
1223static bfd_vma
1224elf64_alpha_relax_opt_call (info, symval)
1225 struct alpha_relax_info *info;
1226 bfd_vma symval;
1227{
1228 /* If the function has the same gp, and we can identify that the
1229 function does not use its function pointer, we can eliminate the
1230 address load. */
1231
1232 /* If the symbol is marked NOPV, we are being told the function never
1233 needs its procedure value. */
c810873d 1234 if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV)
252b5132
RH
1235 return symval;
1236
1237 /* If the symbol is marked STD_GP, we are being told the function does
fe8bc63d 1238 a normal ldgp in the first two words. */
c810873d 1239 else if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD)
252b5132
RH
1240 ;
1241
1242 /* Otherwise, we may be able to identify a GP load in the first two
1243 words, which we can then skip. */
fe8bc63d 1244 else
252b5132
RH
1245 {
1246 Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp;
1247 bfd_vma ofs;
1248
fe8bc63d 1249 /* Load the relocations from the section that the target symbol is in. */
252b5132
RH
1250 if (info->sec == info->tsec)
1251 {
1252 tsec_relocs = info->relocs;
1253 tsec_relend = info->relend;
1254 tsec_free = NULL;
1255 }
1256 else
1257 {
1258 tsec_relocs = (_bfd_elf64_link_read_relocs
1259 (info->abfd, info->tsec, (PTR) NULL,
1260 (Elf_Internal_Rela *) NULL,
1261 info->link_info->keep_memory));
1262 if (tsec_relocs == NULL)
1263 return 0;
1264 tsec_relend = tsec_relocs + info->tsec->reloc_count;
1265 tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs);
1266 }
1267
1268 /* Recover the symbol's offset within the section. */
1269 ofs = (symval - info->tsec->output_section->vma
1270 - info->tsec->output_offset);
fe8bc63d 1271
252b5132
RH
1272 /* Look for a GPDISP reloc. */
1273 gpdisp = (elf64_alpha_find_reloc_at_ofs
1274 (tsec_relocs, tsec_relend, ofs, R_ALPHA_GPDISP));
1275
1276 if (!gpdisp || gpdisp->r_addend != 4)
1277 {
1278 if (tsec_free)
1279 free (tsec_free);
1280 return 0;
1281 }
1282 if (tsec_free)
1283 free (tsec_free);
1284 }
1285
fe8bc63d 1286 /* We've now determined that we can skip an initial gp load. Verify
252b5132
RH
1287 that the call and the target use the same gp. */
1288 if (info->link_info->hash->creator != info->tsec->owner->xvec
1289 || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
1290 return 0;
1291
1292 return symval + 8;
1293}
1294
1295static boolean
1296elf64_alpha_relax_without_lituse (info, symval, irel)
1297 struct alpha_relax_info *info;
1298 bfd_vma symval;
1299 Elf_Internal_Rela *irel;
1300{
1301 unsigned int insn;
1302 bfd_signed_vma disp;
1303
1304 /* Get the instruction. */
1305 insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
1306
1307 if (insn >> 26 != OP_LDQ)
1308 {
1309 ((*_bfd_error_handler)
1310 ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn",
8f615d07 1311 bfd_archive_filename (info->abfd), info->sec->name,
252b5132
RH
1312 (unsigned long) irel->r_offset));
1313 return true;
1314 }
1315
1316 /* So we aren't told much. Do what we can with the address load and
1317 fake the rest. All of the optimizations here require that the
1318 offset from the GP fit in 16 bits. */
1319
1320 disp = symval - info->gp;
1321 if (disp < -0x8000 || disp >= 0x8000)
1322 return true;
1323
1324 /* On the LITERAL instruction itself, consider exchanging
1325 `ldq R,X(gp)' for `lda R,Y(gp)'. */
1326
1327 insn = (OP_LDA << 26) | (insn & 0x03ff0000);
dc810e39 1328 bfd_put_32 (info->abfd, (bfd_vma) insn, info->contents + irel->r_offset);
252b5132
RH
1329 info->changed_contents = true;
1330
dfe57ca0 1331 irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), R_ALPHA_GPREL16);
252b5132
RH
1332 info->changed_relocs = true;
1333
1334 /* Reduce the use count on this got entry by one, possibly
1335 eliminating it. */
1336 info->gotent->use_count -= 1;
1337 alpha_elf_tdata (info->gotent->gotobj)->total_got_entries -= 1;
1338 if (!info->h)
1339 alpha_elf_tdata (info->gotent->gotobj)->n_local_got_entries -= 1;
1340
1341 /* ??? Search forward through this basic block looking for insns
1342 that use the target register. Stop after an insn modifying the
1343 register is seen, or after a branch or call.
1344
1345 Any such memory load insn may be substituted by a load directly
1346 off the GP. This allows the memory load insn to be issued before
fe8bc63d 1347 the calculated GP register would otherwise be ready.
252b5132
RH
1348
1349 Any such jsr insn can be replaced by a bsr if it is in range.
1350
1351 This would mean that we'd have to _add_ relocations, the pain of
1352 which gives one pause. */
1353
1354 return true;
1355}
1356
1357static boolean
1358elf64_alpha_relax_section (abfd, sec, link_info, again)
1359 bfd *abfd;
1360 asection *sec;
1361 struct bfd_link_info *link_info;
1362 boolean *again;
1363{
1364 Elf_Internal_Shdr *symtab_hdr;
9ad5cbcf 1365 Elf_Internal_Shdr *shndx_hdr;
252b5132
RH
1366 Elf_Internal_Rela *internal_relocs;
1367 Elf_Internal_Rela *free_relocs = NULL;
1368 Elf_Internal_Rela *irel, *irelend;
1369 bfd_byte *free_contents = NULL;
1370 Elf64_External_Sym *extsyms = NULL;
1371 Elf64_External_Sym *free_extsyms = NULL;
9ad5cbcf 1372 Elf_External_Sym_Shndx *shndx_buf = NULL;
252b5132
RH
1373 struct alpha_elf_got_entry **local_got_entries;
1374 struct alpha_relax_info info;
1375
1376 /* We are not currently changing any sizes, so only one pass. */
1377 *again = false;
1378
1379 if (link_info->relocateable
1380 || (sec->flags & SEC_RELOC) == 0
1381 || sec->reloc_count == 0)
1382 return true;
1383
1384 /* If this is the first time we have been called for this section,
1385 initialize the cooked size. */
1386 if (sec->_cooked_size == 0)
1387 sec->_cooked_size = sec->_raw_size;
1388
1389 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1390 local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
1391
1392 /* Load the relocations for this section. */
1393 internal_relocs = (_bfd_elf64_link_read_relocs
1394 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
1395 link_info->keep_memory));
1396 if (internal_relocs == NULL)
1397 goto error_return;
1398 if (! link_info->keep_memory)
1399 free_relocs = internal_relocs;
1400
fe8bc63d 1401 memset(&info, 0, sizeof (info));
252b5132
RH
1402 info.abfd = abfd;
1403 info.sec = sec;
1404 info.link_info = link_info;
1405 info.relocs = internal_relocs;
1406 info.relend = irelend = internal_relocs + sec->reloc_count;
1407
1408 /* Find the GP for this object. */
1409 info.gotobj = alpha_elf_tdata (abfd)->gotobj;
1410 if (info.gotobj)
1411 {
1412 asection *sgot = alpha_elf_tdata (info.gotobj)->got;
1413 info.gp = _bfd_get_gp_value (info.gotobj);
1414 if (info.gp == 0)
1415 {
1416 info.gp = (sgot->output_section->vma
1417 + sgot->output_offset
1418 + 0x8000);
1419 _bfd_set_gp_value (info.gotobj, info.gp);
1420 }
1421 }
1422
1423 for (irel = internal_relocs; irel < irelend; irel++)
1424 {
1425 bfd_vma symval;
1426 Elf_Internal_Sym isym;
1427 struct alpha_elf_got_entry *gotent;
1428
1429 if (ELF64_R_TYPE (irel->r_info) != (int) R_ALPHA_LITERAL)
1430 continue;
1431
1432 /* Get the section contents. */
1433 if (info.contents == NULL)
1434 {
1435 if (elf_section_data (sec)->this_hdr.contents != NULL)
1436 info.contents = elf_section_data (sec)->this_hdr.contents;
1437 else
1438 {
1439 info.contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
1440 if (info.contents == NULL)
1441 goto error_return;
1442 free_contents = info.contents;
1443
1444 if (! bfd_get_section_contents (abfd, sec, info.contents,
1445 (file_ptr) 0, sec->_raw_size))
1446 goto error_return;
1447 }
1448 }
1449
1450 /* Read this BFD's symbols if we haven't done so already. */
1451 if (extsyms == NULL)
1452 {
9ad5cbcf
AM
1453 bfd_size_type amt;
1454
252b5132
RH
1455 if (symtab_hdr->contents != NULL)
1456 extsyms = (Elf64_External_Sym *) symtab_hdr->contents;
1457 else
1458 {
9ad5cbcf
AM
1459 amt = symtab_hdr->sh_info;
1460 amt *= sizeof (Elf64_External_Sym);
1461 extsyms = (Elf64_External_Sym *) bfd_malloc (amt);
252b5132
RH
1462 if (extsyms == NULL)
1463 goto error_return;
1464 free_extsyms = extsyms;
1465 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
9ad5cbcf
AM
1466 || bfd_bread ((PTR) extsyms, amt, abfd) != amt)
1467 goto error_return;
1468 }
1469
1470 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
1471 if (shndx_hdr->sh_size != 0)
1472 {
1473 amt = symtab_hdr->sh_info;
1474 amt *= sizeof (Elf_External_Sym_Shndx);
1475 shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
1476 if (shndx_buf == NULL)
1477 goto error_return;
1478 if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
1479 || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
252b5132
RH
1480 goto error_return;
1481 }
1482 }
1483
1484 /* Get the value of the symbol referred to by the reloc. */
1485 if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1486 {
1487 /* A local symbol. */
9ad5cbcf
AM
1488 Elf64_External_Sym *esym;
1489 Elf_External_Sym_Shndx *shndx;
1490
1491 esym = extsyms + ELF64_R_SYM (irel->r_info);
1492 shndx = shndx_buf + (shndx_buf ? ELF64_R_SYM (irel->r_info) : 0);
1493 bfd_elf64_swap_symbol_in (abfd, esym, shndx, &isym);
252b5132
RH
1494 if (isym.st_shndx == SHN_UNDEF)
1495 info.tsec = bfd_und_section_ptr;
252b5132
RH
1496 else if (isym.st_shndx == SHN_ABS)
1497 info.tsec = bfd_abs_section_ptr;
1498 else if (isym.st_shndx == SHN_COMMON)
1499 info.tsec = bfd_com_section_ptr;
fe8bc63d 1500 else
9ad5cbcf 1501 info.tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
252b5132
RH
1502
1503 info.h = NULL;
1504 info.other = isym.st_other;
1505 gotent = local_got_entries[ELF64_R_SYM(irel->r_info)];
1506 symval = isym.st_value;
1507 }
1508 else
1509 {
1510 unsigned long indx;
1511 struct alpha_elf_link_hash_entry *h;
1512
1513 indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1514 h = alpha_elf_sym_hashes (abfd)[indx];
1515 BFD_ASSERT (h != NULL);
1516
1517 while (h->root.root.type == bfd_link_hash_indirect
1518 || h->root.root.type == bfd_link_hash_warning)
1519 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
1520
1521 /* We can't do anthing with undefined or dynamic symbols. */
1522 if (h->root.root.type == bfd_link_hash_undefined
1523 || h->root.root.type == bfd_link_hash_undefweak
1524 || alpha_elf_dynamic_symbol_p (&h->root, link_info))
1525 continue;
1526
1527 info.h = h;
252b5132
RH
1528 info.tsec = h->root.root.u.def.section;
1529 info.other = h->root.other;
1530 gotent = h->got_entries;
1531 symval = h->root.root.u.def.value;
1532 }
1533
1534 /* Search for the got entry to be used by this relocation. */
1535 while (gotent->gotobj != info.gotobj || gotent->addend != irel->r_addend)
1536 gotent = gotent->next;
1537 info.gotent = gotent;
1538
1539 symval += info.tsec->output_section->vma + info.tsec->output_offset;
1540 symval += irel->r_addend;
1541
1542 BFD_ASSERT(info.gotent != NULL);
1543
1544 /* If there exist LITUSE relocations immediately following, this
1545 opens up all sorts of interesting optimizations, because we
1546 now know every location that this address load is used. */
1547
1548 if (irel+1 < irelend && ELF64_R_TYPE (irel[1].r_info) == R_ALPHA_LITUSE)
1549 {
1550 irel = elf64_alpha_relax_with_lituse (&info, symval, irel, irelend);
1551 if (irel == NULL)
1552 goto error_return;
1553 }
1554 else
1555 {
1556 if (!elf64_alpha_relax_without_lituse (&info, symval, irel))
1557 goto error_return;
1558 }
1559 }
1560
1561 if (!elf64_alpha_size_got_sections (abfd, link_info))
1562 return false;
1563
1564 if (info.changed_relocs)
1565 {
1566 elf_section_data (sec)->relocs = internal_relocs;
1567 }
1568 else if (free_relocs != NULL)
1569 {
1570 free (free_relocs);
1571 }
1572
1573 if (info.changed_contents)
1574 {
1575 elf_section_data (sec)->this_hdr.contents = info.contents;
1576 }
1577 else if (free_contents != NULL)
1578 {
1579 if (! link_info->keep_memory)
1580 free (free_contents);
1581 else
1582 {
1583 /* Cache the section contents for elf_link_input_bfd. */
1584 elf_section_data (sec)->this_hdr.contents = info.contents;
1585 }
1586 }
1587
9ad5cbcf
AM
1588 if (shndx_buf != NULL)
1589 free (shndx_buf);
1590
252b5132
RH
1591 if (free_extsyms != NULL)
1592 {
1593 if (! link_info->keep_memory)
1594 free (free_extsyms);
1595 else
1596 {
1597 /* Cache the symbols for elf_link_input_bfd. */
973ffd63 1598 symtab_hdr->contents = (unsigned char *) extsyms;
252b5132
RH
1599 }
1600 }
1601
1602 *again = info.changed_contents || info.changed_relocs;
1603
1604 return true;
1605
1606 error_return:
1607 if (free_relocs != NULL)
1608 free (free_relocs);
1609 if (free_contents != NULL)
1610 free (free_contents);
9ad5cbcf
AM
1611 if (shndx_buf != NULL)
1612 free (shndx_buf);
252b5132
RH
1613 if (free_extsyms != NULL)
1614 free (free_extsyms);
1615 return false;
1616}
1617\f
1618/* PLT/GOT Stuff */
1619#define PLT_HEADER_SIZE 32
dc810e39
AM
1620#define PLT_HEADER_WORD1 (bfd_vma) 0xc3600000 /* br $27,.+4 */
1621#define PLT_HEADER_WORD2 (bfd_vma) 0xa77b000c /* ldq $27,12($27) */
1622#define PLT_HEADER_WORD3 (bfd_vma) 0x47ff041f /* nop */
1623#define PLT_HEADER_WORD4 (bfd_vma) 0x6b7b0000 /* jmp $27,($27) */
252b5132
RH
1624
1625#define PLT_ENTRY_SIZE 12
1626#define PLT_ENTRY_WORD1 0xc3800000 /* br $28, plt0 */
1627#define PLT_ENTRY_WORD2 0
1628#define PLT_ENTRY_WORD3 0
1629
1630#define MAX_GOT_ENTRIES (64*1024 / 8)
1631
1632#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so"
1633\f
1634/* Handle an Alpha specific section when reading an object file. This
1635 is called when elfcode.h finds a section with an unknown type.
1636 FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure
1637 how to. */
1638
1639static boolean
1640elf64_alpha_section_from_shdr (abfd, hdr, name)
1641 bfd *abfd;
1642 Elf64_Internal_Shdr *hdr;
1643 char *name;
1644{
1645 asection *newsect;
1646
1647 /* There ought to be a place to keep ELF backend specific flags, but
1648 at the moment there isn't one. We just keep track of the
1649 sections by their name, instead. Fortunately, the ABI gives
1650 suggested names for all the MIPS specific sections, so we will
1651 probably get away with this. */
1652 switch (hdr->sh_type)
1653 {
1654 case SHT_ALPHA_DEBUG:
1655 if (strcmp (name, ".mdebug") != 0)
1656 return false;
1657 break;
252b5132
RH
1658 default:
1659 return false;
1660 }
1661
1662 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1663 return false;
1664 newsect = hdr->bfd_section;
1665
1666 if (hdr->sh_type == SHT_ALPHA_DEBUG)
1667 {
1668 if (! bfd_set_section_flags (abfd, newsect,
1669 (bfd_get_section_flags (abfd, newsect)
1670 | SEC_DEBUGGING)))
1671 return false;
1672 }
1673
252b5132
RH
1674 return true;
1675}
1676
204692d7
RH
1677/* Convert Alpha specific section flags to bfd internal section flags. */
1678
1679static boolean
1680elf64_alpha_section_flags (flags, hdr)
1681 flagword *flags;
1682 Elf64_Internal_Shdr *hdr;
1683{
1684 if (hdr->sh_flags & SHF_ALPHA_GPREL)
1685 *flags |= SEC_SMALL_DATA;
1686
1687 return true;
1688}
1689
252b5132
RH
1690/* Set the correct type for an Alpha ELF section. We do this by the
1691 section name, which is a hack, but ought to work. */
1692
1693static boolean
1694elf64_alpha_fake_sections (abfd, hdr, sec)
1695 bfd *abfd;
1696 Elf64_Internal_Shdr *hdr;
1697 asection *sec;
1698{
1699 register const char *name;
1700
1701 name = bfd_get_section_name (abfd, sec);
1702
1703 if (strcmp (name, ".mdebug") == 0)
1704 {
1705 hdr->sh_type = SHT_ALPHA_DEBUG;
1706 /* In a shared object on Irix 5.3, the .mdebug section has an
1707 entsize of 0. FIXME: Does this matter? */
1708 if ((abfd->flags & DYNAMIC) != 0 )
1709 hdr->sh_entsize = 0;
1710 else
1711 hdr->sh_entsize = 1;
1712 }
204692d7
RH
1713 else if ((sec->flags & SEC_SMALL_DATA)
1714 || strcmp (name, ".sdata") == 0
252b5132
RH
1715 || strcmp (name, ".sbss") == 0
1716 || strcmp (name, ".lit4") == 0
1717 || strcmp (name, ".lit8") == 0)
1718 hdr->sh_flags |= SHF_ALPHA_GPREL;
1719
1720 return true;
1721}
1722
1723/* Hook called by the linker routine which adds symbols from an object
1724 file. We use it to put .comm items in .sbss, and not .bss. */
1725
1726static boolean
1727elf64_alpha_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1728 bfd *abfd;
1729 struct bfd_link_info *info;
1730 const Elf_Internal_Sym *sym;
56fc028e
AJ
1731 const char **namep ATTRIBUTE_UNUSED;
1732 flagword *flagsp ATTRIBUTE_UNUSED;
252b5132
RH
1733 asection **secp;
1734 bfd_vma *valp;
1735{
1736 if (sym->st_shndx == SHN_COMMON
1737 && !info->relocateable
c0846b23 1738 && sym->st_size <= elf_gp_size (abfd))
252b5132
RH
1739 {
1740 /* Common symbols less than or equal to -G nn bytes are
1741 automatically put into .sbss. */
1742
1743 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1744
1745 if (scomm == NULL)
1746 {
1747 scomm = bfd_make_section (abfd, ".scommon");
1748 if (scomm == NULL
1749 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1750 | SEC_IS_COMMON
1751 | SEC_LINKER_CREATED)))
1752 return false;
1753 }
1754
1755 *secp = scomm;
1756 *valp = sym->st_size;
1757 }
1758
1759 return true;
1760}
1761
1762/* Create the .got section. */
1763
1764static boolean
1765elf64_alpha_create_got_section(abfd, info)
1766 bfd *abfd;
56fc028e 1767 struct bfd_link_info *info ATTRIBUTE_UNUSED;
252b5132
RH
1768{
1769 asection *s;
1770
1771 if (bfd_get_section_by_name (abfd, ".got"))
1772 return true;
1773
1774 s = bfd_make_section (abfd, ".got");
1775 if (s == NULL
1776 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1777 | SEC_HAS_CONTENTS
1778 | SEC_IN_MEMORY
1779 | SEC_LINKER_CREATED))
1780 || !bfd_set_section_alignment (abfd, s, 3))
1781 return false;
1782
1783 alpha_elf_tdata (abfd)->got = s;
1784
1785 return true;
1786}
1787
1788/* Create all the dynamic sections. */
1789
1790static boolean
1791elf64_alpha_create_dynamic_sections (abfd, info)
1792 bfd *abfd;
1793 struct bfd_link_info *info;
1794{
1795 asection *s;
1796 struct elf_link_hash_entry *h;
1797
1798 /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */
1799
1800 s = bfd_make_section (abfd, ".plt");
1801 if (s == NULL
1802 || ! bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1803 | SEC_HAS_CONTENTS
1804 | SEC_IN_MEMORY
1805 | SEC_LINKER_CREATED
1806 | SEC_CODE))
1807 || ! bfd_set_section_alignment (abfd, s, 3))
1808 return false;
1809
1810 /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
1811 .plt section. */
1812 h = NULL;
1813 if (! (_bfd_generic_link_add_one_symbol
1814 (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
1815 (bfd_vma) 0, (const char *) NULL, false,
1816 get_elf_backend_data (abfd)->collect,
1817 (struct bfd_link_hash_entry **) &h)))
1818 return false;
1819 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1820 h->type = STT_OBJECT;
1821
1822 if (info->shared
1823 && ! _bfd_elf_link_record_dynamic_symbol (info, h))
1824 return false;
1825
1826 s = bfd_make_section (abfd, ".rela.plt");
1827 if (s == NULL
1828 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1829 | SEC_HAS_CONTENTS
1830 | SEC_IN_MEMORY
1831 | SEC_LINKER_CREATED
1832 | SEC_READONLY))
1833 || ! bfd_set_section_alignment (abfd, s, 3))
1834 return false;
1835
1836 /* We may or may not have created a .got section for this object, but
1837 we definitely havn't done the rest of the work. */
1838
1839 if (!elf64_alpha_create_got_section (abfd, info))
1840 return false;
1841
1842 s = bfd_make_section(abfd, ".rela.got");
1843 if (s == NULL
1844 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1845 | SEC_HAS_CONTENTS
1846 | SEC_IN_MEMORY
1847 | SEC_LINKER_CREATED
1848 | SEC_READONLY))
1849 || !bfd_set_section_alignment (abfd, s, 3))
1850 return false;
1851
1852 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
1853 dynobj's .got section. We don't do this in the linker script
1854 because we don't want to define the symbol if we are not creating
1855 a global offset table. */
1856 h = NULL;
1857 if (!(_bfd_generic_link_add_one_symbol
1858 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL,
1859 alpha_elf_tdata(abfd)->got, (bfd_vma) 0, (const char *) NULL,
1860 false, get_elf_backend_data (abfd)->collect,
1861 (struct bfd_link_hash_entry **) &h)))
1862 return false;
1863 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1864 h->type = STT_OBJECT;
1865
1866 if (info->shared
1867 && ! _bfd_elf_link_record_dynamic_symbol (info, h))
1868 return false;
1869
1870 elf_hash_table (info)->hgot = h;
1871
1872 return true;
1873}
1874\f
1875/* Read ECOFF debugging information from a .mdebug section into a
1876 ecoff_debug_info structure. */
1877
1878static boolean
1879elf64_alpha_read_ecoff_info (abfd, section, debug)
1880 bfd *abfd;
1881 asection *section;
1882 struct ecoff_debug_info *debug;
1883{
1884 HDRR *symhdr;
1885 const struct ecoff_debug_swap *swap;
1886 char *ext_hdr = NULL;
1887
1888 swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
fe8bc63d 1889 memset (debug, 0, sizeof (*debug));
252b5132 1890
dc810e39 1891 ext_hdr = (char *) bfd_malloc (swap->external_hdr_size);
252b5132
RH
1892 if (ext_hdr == NULL && swap->external_hdr_size != 0)
1893 goto error_return;
1894
1895 if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
1896 swap->external_hdr_size)
1897 == false)
1898 goto error_return;
1899
1900 symhdr = &debug->symbolic_header;
1901 (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);
1902
1903 /* The symbolic header contains absolute file offsets and sizes to
1904 read. */
1905#define READ(ptr, offset, count, size, type) \
1906 if (symhdr->count == 0) \
1907 debug->ptr = NULL; \
1908 else \
1909 { \
dc810e39
AM
1910 bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
1911 debug->ptr = (type) bfd_malloc (amt); \
252b5132
RH
1912 if (debug->ptr == NULL) \
1913 goto error_return; \
1914 if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
dc810e39 1915 || bfd_bread (debug->ptr, amt, abfd) != amt) \
252b5132
RH
1916 goto error_return; \
1917 }
1918
1919 READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
1920 READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
1921 READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
1922 READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
1923 READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
1924 READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
1925 union aux_ext *);
1926 READ (ss, cbSsOffset, issMax, sizeof (char), char *);
1927 READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
1928 READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
1929 READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
1930 READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
1931#undef READ
1932
1933 debug->fdr = NULL;
1934 debug->adjust = NULL;
1935
1936 return true;
1937
1938 error_return:
1939 if (ext_hdr != NULL)
1940 free (ext_hdr);
1941 if (debug->line != NULL)
1942 free (debug->line);
1943 if (debug->external_dnr != NULL)
1944 free (debug->external_dnr);
1945 if (debug->external_pdr != NULL)
1946 free (debug->external_pdr);
1947 if (debug->external_sym != NULL)
1948 free (debug->external_sym);
1949 if (debug->external_opt != NULL)
1950 free (debug->external_opt);
1951 if (debug->external_aux != NULL)
1952 free (debug->external_aux);
1953 if (debug->ss != NULL)
1954 free (debug->ss);
1955 if (debug->ssext != NULL)
1956 free (debug->ssext);
1957 if (debug->external_fdr != NULL)
1958 free (debug->external_fdr);
1959 if (debug->external_rfd != NULL)
1960 free (debug->external_rfd);
1961 if (debug->external_ext != NULL)
1962 free (debug->external_ext);
1963 return false;
1964}
1965
1966/* Alpha ELF local labels start with '$'. */
1967
1968static boolean
1969elf64_alpha_is_local_label_name (abfd, name)
56fc028e 1970 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
1971 const char *name;
1972{
1973 return name[0] == '$';
1974}
1975
1976/* Alpha ELF follows MIPS ELF in using a special find_nearest_line
1977 routine in order to handle the ECOFF debugging information. We
1978 still call this mips_elf_find_line because of the slot
1979 find_line_info in elf_obj_tdata is declared that way. */
1980
1981struct mips_elf_find_line
1982{
1983 struct ecoff_debug_info d;
1984 struct ecoff_find_line i;
1985};
1986
1987static boolean
1988elf64_alpha_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
1989 functionname_ptr, line_ptr)
1990 bfd *abfd;
1991 asection *section;
1992 asymbol **symbols;
1993 bfd_vma offset;
1994 const char **filename_ptr;
1995 const char **functionname_ptr;
1996 unsigned int *line_ptr;
1997{
1998 asection *msec;
1999
95404643
RH
2000 if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
2001 filename_ptr, functionname_ptr,
2002 line_ptr, 0,
2003 &elf_tdata (abfd)->dwarf2_find_line_info))
2004 return true;
2005
252b5132
RH
2006 msec = bfd_get_section_by_name (abfd, ".mdebug");
2007 if (msec != NULL)
2008 {
2009 flagword origflags;
2010 struct mips_elf_find_line *fi;
2011 const struct ecoff_debug_swap * const swap =
2012 get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
2013
2014 /* If we are called during a link, alpha_elf_final_link may have
2015 cleared the SEC_HAS_CONTENTS field. We force it back on here
2016 if appropriate (which it normally will be). */
2017 origflags = msec->flags;
2018 if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
2019 msec->flags |= SEC_HAS_CONTENTS;
2020
2021 fi = elf_tdata (abfd)->find_line_info;
2022 if (fi == NULL)
2023 {
2024 bfd_size_type external_fdr_size;
2025 char *fraw_src;
2026 char *fraw_end;
2027 struct fdr *fdr_ptr;
dc810e39 2028 bfd_size_type amt = sizeof (struct mips_elf_find_line);
252b5132 2029
dc810e39 2030 fi = (struct mips_elf_find_line *) bfd_zalloc (abfd, amt);
252b5132
RH
2031 if (fi == NULL)
2032 {
2033 msec->flags = origflags;
2034 return false;
2035 }
2036
2037 if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d))
2038 {
2039 msec->flags = origflags;
2040 return false;
2041 }
2042
2043 /* Swap in the FDR information. */
dc810e39
AM
2044 amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
2045 fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt);
252b5132
RH
2046 if (fi->d.fdr == NULL)
2047 {
2048 msec->flags = origflags;
2049 return false;
2050 }
2051 external_fdr_size = swap->external_fdr_size;
2052 fdr_ptr = fi->d.fdr;
2053 fraw_src = (char *) fi->d.external_fdr;
2054 fraw_end = (fraw_src
2055 + fi->d.symbolic_header.ifdMax * external_fdr_size);
2056 for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
2057 (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
2058
2059 elf_tdata (abfd)->find_line_info = fi;
2060
2061 /* Note that we don't bother to ever free this information.
2062 find_nearest_line is either called all the time, as in
2063 objdump -l, so the information should be saved, or it is
2064 rarely called, as in ld error messages, so the memory
2065 wasted is unimportant. Still, it would probably be a
2066 good idea for free_cached_info to throw it away. */
2067 }
2068
2069 if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap,
2070 &fi->i, filename_ptr, functionname_ptr,
2071 line_ptr))
2072 {
2073 msec->flags = origflags;
2074 return true;
2075 }
2076
2077 msec->flags = origflags;
2078 }
2079
2080 /* Fall back on the generic ELF find_nearest_line routine. */
2081
2082 return _bfd_elf_find_nearest_line (abfd, section, symbols, offset,
2083 filename_ptr, functionname_ptr,
2084 line_ptr);
2085}
2086\f
2087/* Structure used to pass information to alpha_elf_output_extsym. */
2088
2089struct extsym_info
2090{
2091 bfd *abfd;
2092 struct bfd_link_info *info;
2093 struct ecoff_debug_info *debug;
2094 const struct ecoff_debug_swap *swap;
2095 boolean failed;
2096};
2097
2098static boolean
2099elf64_alpha_output_extsym (h, data)
2100 struct alpha_elf_link_hash_entry *h;
2101 PTR data;
2102{
2103 struct extsym_info *einfo = (struct extsym_info *) data;
2104 boolean strip;
2105 asection *sec, *output_section;
2106
2107 if (h->root.indx == -2)
2108 strip = false;
2109 else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
2110 || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0)
2111 && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
2112 && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
2113 strip = true;
2114 else if (einfo->info->strip == strip_all
2115 || (einfo->info->strip == strip_some
2116 && bfd_hash_lookup (einfo->info->keep_hash,
2117 h->root.root.root.string,
2118 false, false) == NULL))
2119 strip = true;
2120 else
2121 strip = false;
2122
2123 if (strip)
2124 return true;
2125
2126 if (h->esym.ifd == -2)
2127 {
2128 h->esym.jmptbl = 0;
2129 h->esym.cobol_main = 0;
2130 h->esym.weakext = 0;
2131 h->esym.reserved = 0;
2132 h->esym.ifd = ifdNil;
2133 h->esym.asym.value = 0;
2134 h->esym.asym.st = stGlobal;
2135
2136 if (h->root.root.type != bfd_link_hash_defined
2137 && h->root.root.type != bfd_link_hash_defweak)
2138 h->esym.asym.sc = scAbs;
2139 else
2140 {
2141 const char *name;
2142
2143 sec = h->root.root.u.def.section;
2144 output_section = sec->output_section;
2145
2146 /* When making a shared library and symbol h is the one from
2147 the another shared library, OUTPUT_SECTION may be null. */
2148 if (output_section == NULL)
2149 h->esym.asym.sc = scUndefined;
2150 else
2151 {
2152 name = bfd_section_name (output_section->owner, output_section);
2153
2154 if (strcmp (name, ".text") == 0)
2155 h->esym.asym.sc = scText;
2156 else if (strcmp (name, ".data") == 0)
2157 h->esym.asym.sc = scData;
2158 else if (strcmp (name, ".sdata") == 0)
2159 h->esym.asym.sc = scSData;
2160 else if (strcmp (name, ".rodata") == 0
2161 || strcmp (name, ".rdata") == 0)
2162 h->esym.asym.sc = scRData;
2163 else if (strcmp (name, ".bss") == 0)
2164 h->esym.asym.sc = scBss;
2165 else if (strcmp (name, ".sbss") == 0)
2166 h->esym.asym.sc = scSBss;
2167 else if (strcmp (name, ".init") == 0)
2168 h->esym.asym.sc = scInit;
2169 else if (strcmp (name, ".fini") == 0)
2170 h->esym.asym.sc = scFini;
2171 else
2172 h->esym.asym.sc = scAbs;
2173 }
2174 }
2175
2176 h->esym.asym.reserved = 0;
2177 h->esym.asym.index = indexNil;
2178 }
2179
2180 if (h->root.root.type == bfd_link_hash_common)
2181 h->esym.asym.value = h->root.root.u.c.size;
2182 else if (h->root.root.type == bfd_link_hash_defined
2183 || h->root.root.type == bfd_link_hash_defweak)
2184 {
2185 if (h->esym.asym.sc == scCommon)
2186 h->esym.asym.sc = scBss;
2187 else if (h->esym.asym.sc == scSCommon)
2188 h->esym.asym.sc = scSBss;
2189
2190 sec = h->root.root.u.def.section;
2191 output_section = sec->output_section;
2192 if (output_section != NULL)
2193 h->esym.asym.value = (h->root.root.u.def.value
2194 + sec->output_offset
2195 + output_section->vma);
2196 else
2197 h->esym.asym.value = 0;
2198 }
2199 else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
2200 {
2201 /* Set type and value for a symbol with a function stub. */
2202 h->esym.asym.st = stProc;
2203 sec = bfd_get_section_by_name (einfo->abfd, ".plt");
2204 if (sec == NULL)
2205 h->esym.asym.value = 0;
2206 else
2207 {
2208 output_section = sec->output_section;
2209 if (output_section != NULL)
2210 h->esym.asym.value = (h->root.plt.offset
2211 + sec->output_offset
2212 + output_section->vma);
2213 else
2214 h->esym.asym.value = 0;
2215 }
252b5132
RH
2216 }
2217
2218 if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
2219 h->root.root.root.string,
2220 &h->esym))
2221 {
2222 einfo->failed = true;
2223 return false;
2224 }
2225
2226 return true;
2227}
2228
2229/* FIXME: Create a runtime procedure table from the .mdebug section.
2230
2231static boolean
2232mips_elf_create_procedure_table (handle, abfd, info, s, debug)
2233 PTR handle;
2234 bfd *abfd;
2235 struct bfd_link_info *info;
2236 asection *s;
2237 struct ecoff_debug_info *debug;
2238*/
2239\f
2240/* Handle dynamic relocations when doing an Alpha ELF link. */
2241
2242static boolean
2243elf64_alpha_check_relocs (abfd, info, sec, relocs)
2244 bfd *abfd;
2245 struct bfd_link_info *info;
2246 asection *sec;
2247 const Elf_Internal_Rela *relocs;
2248{
2249 bfd *dynobj;
2250 asection *sreloc;
2251 const char *rel_sec_name;
2252 Elf_Internal_Shdr *symtab_hdr;
2253 struct alpha_elf_link_hash_entry **sym_hashes;
2254 struct alpha_elf_got_entry **local_got_entries;
2255 const Elf_Internal_Rela *rel, *relend;
2256 int got_created;
dc810e39 2257 bfd_size_type amt;
252b5132
RH
2258
2259 if (info->relocateable)
2260 return true;
2261
2262 dynobj = elf_hash_table(info)->dynobj;
2263 if (dynobj == NULL)
2264 elf_hash_table(info)->dynobj = dynobj = abfd;
2265
2266 sreloc = NULL;
2267 rel_sec_name = NULL;
2268 symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
2269 sym_hashes = alpha_elf_sym_hashes(abfd);
2270 local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
2271 got_created = 0;
2272
2273 relend = relocs + sec->reloc_count;
2274 for (rel = relocs; rel < relend; ++rel)
2275 {
2276 unsigned long r_symndx, r_type;
2277 struct alpha_elf_link_hash_entry *h;
2278
2279 r_symndx = ELF64_R_SYM (rel->r_info);
2280 if (r_symndx < symtab_hdr->sh_info)
2281 h = NULL;
2282 else
2283 {
2284 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2285
2286 while (h->root.root.type == bfd_link_hash_indirect
2287 || h->root.root.type == bfd_link_hash_warning)
2288 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
2289
2290 h->root.elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2291 }
2292 r_type = ELF64_R_TYPE (rel->r_info);
2293
2294 switch (r_type)
2295 {
2296 case R_ALPHA_LITERAL:
2297 {
2298 struct alpha_elf_got_entry *gotent;
2299 int flags = 0;
2300
2301 if (h)
2302 {
2303 /* Search for and possibly create a got entry. */
2304 for (gotent = h->got_entries; gotent ; gotent = gotent->next)
2305 if (gotent->gotobj == abfd &&
2306 gotent->addend == rel->r_addend)
2307 break;
2308
2309 if (!gotent)
2310 {
dc810e39 2311 amt = sizeof (struct alpha_elf_got_entry);
252b5132 2312 gotent = ((struct alpha_elf_got_entry *)
dc810e39 2313 bfd_alloc (abfd, amt));
252b5132
RH
2314 if (!gotent)
2315 return false;
2316
2317 gotent->gotobj = abfd;
2318 gotent->addend = rel->r_addend;
2319 gotent->got_offset = -1;
2320 gotent->flags = 0;
2321 gotent->use_count = 1;
2322
2323 gotent->next = h->got_entries;
2324 h->got_entries = gotent;
2325
2326 alpha_elf_tdata (abfd)->total_got_entries++;
2327 }
2328 else
2329 gotent->use_count += 1;
2330 }
2331 else
2332 {
2333 /* This is a local .got entry -- record for merge. */
2334 if (!local_got_entries)
2335 {
dc810e39
AM
2336 bfd_size_type size;
2337 size = symtab_hdr->sh_info;
2338 size *= sizeof (struct alpha_elf_got_entry *);
252b5132
RH
2339
2340 local_got_entries = ((struct alpha_elf_got_entry **)
2341 bfd_alloc (abfd, size));
2342 if (!local_got_entries)
2343 return false;
2344
dc810e39 2345 memset (local_got_entries, 0, (size_t) size);
252b5132
RH
2346 alpha_elf_tdata (abfd)->local_got_entries =
2347 local_got_entries;
2348 }
2349
2350 for (gotent = local_got_entries[ELF64_R_SYM(rel->r_info)];
2351 gotent != NULL && gotent->addend != rel->r_addend;
2352 gotent = gotent->next)
2353 continue;
2354 if (!gotent)
2355 {
dc810e39 2356 amt = sizeof (struct alpha_elf_got_entry);
252b5132 2357 gotent = ((struct alpha_elf_got_entry *)
dc810e39 2358 bfd_alloc (abfd, amt));
252b5132
RH
2359 if (!gotent)
2360 return false;
2361
2362 gotent->gotobj = abfd;
2363 gotent->addend = rel->r_addend;
2364 gotent->got_offset = -1;
2365 gotent->flags = 0;
2366 gotent->use_count = 1;
2367
2368 gotent->next = local_got_entries[ELF64_R_SYM(rel->r_info)];
2369 local_got_entries[ELF64_R_SYM(rel->r_info)] = gotent;
2370
2371 alpha_elf_tdata(abfd)->total_got_entries++;
2372 alpha_elf_tdata(abfd)->n_local_got_entries++;
2373 }
2374 else
2375 gotent->use_count += 1;
2376 }
2377
2378 /* Remember how this literal is used from its LITUSEs.
2379 This will be important when it comes to decide if we can
2380 create a .plt entry for a function symbol. */
2381 if (rel+1 < relend
2382 && ELF64_R_TYPE (rel[1].r_info) == R_ALPHA_LITUSE)
2383 {
2384 do
2385 {
2386 ++rel;
2387 if (rel->r_addend >= 1 && rel->r_addend <= 3)
2388 flags |= 1 << rel->r_addend;
2389 }
2390 while (rel+1 < relend &&
2391 ELF64_R_TYPE (rel[1].r_info) == R_ALPHA_LITUSE);
2392 }
2393 else
2394 {
2395 /* No LITUSEs -- presumably the address is not being
2396 loaded for nothing. */
2397 flags = ALPHA_ELF_LINK_HASH_LU_ADDR;
2398 }
2399
2400 gotent->flags |= flags;
2401 if (h)
2402 {
2403 /* Make a guess as to whether a .plt entry will be needed. */
2404 if ((h->flags |= flags) == ALPHA_ELF_LINK_HASH_LU_FUNC)
2405 h->root.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2406 else
2407 h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
2408 }
2409 }
2410 /* FALLTHRU */
2411
2412 case R_ALPHA_GPDISP:
dfe57ca0 2413 case R_ALPHA_GPREL16:
252b5132
RH
2414 case R_ALPHA_GPREL32:
2415 case R_ALPHA_GPRELHIGH:
2416 case R_ALPHA_GPRELLOW:
2417 /* We don't actually use the .got here, but the sections must
2418 be created before the linker maps input sections to output
2419 sections. */
2420 if (!got_created)
2421 {
2422 if (!elf64_alpha_create_got_section (abfd, info))
2423 return false;
2424
2425 /* Make sure the object's gotobj is set to itself so
2426 that we default to every object with its own .got.
2427 We'll merge .gots later once we've collected each
2428 object's info. */
2429 alpha_elf_tdata(abfd)->gotobj = abfd;
2430
2431 got_created = 1;
2432 }
2433 break;
2434
2435 case R_ALPHA_SREL16:
2436 case R_ALPHA_SREL32:
2437 case R_ALPHA_SREL64:
2438 if (h == NULL)
2439 break;
2440 /* FALLTHRU */
2441
2442 case R_ALPHA_REFLONG:
2443 case R_ALPHA_REFQUAD:
2444 if (rel_sec_name == NULL)
2445 {
2446 rel_sec_name = (bfd_elf_string_from_elf_section
2447 (abfd, elf_elfheader(abfd)->e_shstrndx,
2448 elf_section_data(sec)->rel_hdr.sh_name));
2449 if (rel_sec_name == NULL)
2450 return false;
2451
2452 BFD_ASSERT (strncmp (rel_sec_name, ".rela", 5) == 0
2453 && strcmp (bfd_get_section_name (abfd, sec),
2454 rel_sec_name+5) == 0);
2455 }
2456
2457 /* We need to create the section here now whether we eventually
2458 use it or not so that it gets mapped to an output section by
2459 the linker. If not used, we'll kill it in
2460 size_dynamic_sections. */
2461 if (sreloc == NULL)
2462 {
2463 sreloc = bfd_get_section_by_name (dynobj, rel_sec_name);
2464 if (sreloc == NULL)
2465 {
dc810e39
AM
2466 flagword flags;
2467
252b5132 2468 sreloc = bfd_make_section (dynobj, rel_sec_name);
dc810e39
AM
2469 flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
2470 | SEC_LINKER_CREATED | SEC_READONLY);
2471 if (sec->flags & SEC_ALLOC)
2472 flags |= SEC_ALLOC | SEC_LOAD;
252b5132 2473 if (sreloc == NULL
dc810e39 2474 || !bfd_set_section_flags (dynobj, sreloc, flags)
252b5132
RH
2475 || !bfd_set_section_alignment (dynobj, sreloc, 3))
2476 return false;
2477 }
2478 }
2479
2480 if (h)
2481 {
2482 /* Since we havn't seen all of the input symbols yet, we
2483 don't know whether we'll actually need a dynamic relocation
2484 entry for this reloc. So make a record of it. Once we
2485 find out if this thing needs dynamic relocation we'll
fe8bc63d 2486 expand the relocation sections by the appropriate amount. */
252b5132
RH
2487
2488 struct alpha_elf_reloc_entry *rent;
2489
2490 for (rent = h->reloc_entries; rent; rent = rent->next)
2491 if (rent->rtype == r_type && rent->srel == sreloc)
2492 break;
2493
2494 if (!rent)
2495 {
dc810e39
AM
2496 amt = sizeof (struct alpha_elf_reloc_entry);
2497 rent = (struct alpha_elf_reloc_entry *) bfd_alloc (abfd, amt);
252b5132
RH
2498 if (!rent)
2499 return false;
2500
2501 rent->srel = sreloc;
2502 rent->rtype = r_type;
2503 rent->count = 1;
73896efb
RH
2504 rent->reltext = ((sec->flags & (SEC_READONLY | SEC_ALLOC))
2505 == (SEC_READONLY | SEC_ALLOC));
252b5132
RH
2506
2507 rent->next = h->reloc_entries;
2508 h->reloc_entries = rent;
2509 }
2510 else
2511 rent->count++;
2512 }
c555c5c5 2513 else if (info->shared && (sec->flags & SEC_ALLOC))
252b5132 2514 {
c555c5c5
AM
2515 /* If this is a shared library, and the section is to be
2516 loaded into memory, we need a RELATIVE reloc. */
252b5132 2517 sreloc->_raw_size += sizeof (Elf64_External_Rela);
fcfbdf31
JJ
2518 if (sec->flags & SEC_READONLY)
2519 info->flags |= DF_TEXTREL;
252b5132
RH
2520 }
2521 break;
2522 }
2523 }
2524
2525 return true;
2526}
2527
2528/* Adjust a symbol defined by a dynamic object and referenced by a
2529 regular object. The current definition is in some section of the
2530 dynamic object, but we're not including those sections. We have to
2531 change the definition to something the rest of the link can
2532 understand. */
2533
2534static boolean
2535elf64_alpha_adjust_dynamic_symbol (info, h)
2536 struct bfd_link_info *info;
2537 struct elf_link_hash_entry *h;
2538{
2539 bfd *dynobj;
2540 asection *s;
2541 struct alpha_elf_link_hash_entry *ah;
2542
2543 dynobj = elf_hash_table(info)->dynobj;
2544 ah = (struct alpha_elf_link_hash_entry *)h;
2545
2546 /* Now that we've seen all of the input symbols, finalize our decision
2547 about whether this symbol should get a .plt entry. */
2548
8ba89f17 2549 if (alpha_elf_dynamic_symbol_p (h, info)
252b5132
RH
2550 && ((h->type == STT_FUNC
2551 && !(ah->flags & ALPHA_ELF_LINK_HASH_LU_ADDR))
2552 || (h->type == STT_NOTYPE
2553 && ah->flags == ALPHA_ELF_LINK_HASH_LU_FUNC))
2554 /* Don't prevent otherwise valid programs from linking by attempting
2555 to create a new .got entry somewhere. A Correct Solution would be
2556 to add a new .got section to a new object file and let it be merged
2557 somewhere later. But for now don't bother. */
2558 && ah->got_entries)
2559 {
2560 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2561
2562 s = bfd_get_section_by_name(dynobj, ".plt");
2563 if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
2564 return false;
2565
2566 /* The first bit of the .plt is reserved. */
2567 if (s->_raw_size == 0)
2568 s->_raw_size = PLT_HEADER_SIZE;
2569
2570 h->plt.offset = s->_raw_size;
2571 s->_raw_size += PLT_ENTRY_SIZE;
2572
2573 /* If this symbol is not defined in a regular file, and we are not
2574 generating a shared library, then set the symbol to the location
2575 in the .plt. This is required to make function pointers compare
2576 equal between the normal executable and the shared library. */
2577 if (! info->shared
2578 && h->root.type != bfd_link_hash_defweak)
2579 {
2580 h->root.u.def.section = s;
2581 h->root.u.def.value = h->plt.offset;
2582 }
2583
2584 /* We also need a JMP_SLOT entry in the .rela.plt section. */
2585 s = bfd_get_section_by_name (dynobj, ".rela.plt");
2586 BFD_ASSERT (s != NULL);
2587 s->_raw_size += sizeof (Elf64_External_Rela);
2588
2589 return true;
2590 }
2591 else
2592 h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
2593
2594 /* If this is a weak symbol, and there is a real definition, the
2595 processor independent code will have arranged for us to see the
2596 real definition first, and we can just use the same value. */
2597 if (h->weakdef != NULL)
2598 {
2599 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2600 || h->weakdef->root.type == bfd_link_hash_defweak);
2601 h->root.u.def.section = h->weakdef->root.u.def.section;
2602 h->root.u.def.value = h->weakdef->root.u.def.value;
2603 return true;
2604 }
2605
2606 /* This is a reference to a symbol defined by a dynamic object which
2607 is not a function. The Alpha, since it uses .got entries for all
2608 symbols even in regular objects, does not need the hackery of a
2609 .dynbss section and COPY dynamic relocations. */
2610
2611 return true;
2612}
2613
2614/* Symbol versioning can create new symbols, and make our old symbols
2615 indirect to the new ones. Consolidate the got and reloc information
2616 in these situations. */
2617
2618static boolean
2619elf64_alpha_merge_ind_symbols (hi, dummy)
2620 struct alpha_elf_link_hash_entry *hi;
56fc028e 2621 PTR dummy ATTRIBUTE_UNUSED;
252b5132
RH
2622{
2623 struct alpha_elf_link_hash_entry *hs;
2624
2625 if (hi->root.root.type != bfd_link_hash_indirect)
2626 return true;
2627 hs = hi;
2628 do {
2629 hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link;
2630 } while (hs->root.root.type == bfd_link_hash_indirect);
2631
2632 /* Merge the flags. Whee. */
2633
2634 hs->flags |= hi->flags;
2635
2636 /* Merge the .got entries. Cannibalize the old symbol's list in
2637 doing so, since we don't need it anymore. */
2638
2639 if (hs->got_entries == NULL)
2640 hs->got_entries = hi->got_entries;
2641 else
2642 {
2643 struct alpha_elf_got_entry *gi, *gs, *gin, *gsh;
2644
2645 gsh = hs->got_entries;
2646 for (gi = hi->got_entries; gi ; gi = gin)
2647 {
2648 gin = gi->next;
2649 for (gs = gsh; gs ; gs = gs->next)
2650 if (gi->gotobj == gs->gotobj && gi->addend == gs->addend)
2651 goto got_found;
2652 gi->next = hs->got_entries;
2653 hs->got_entries = gi;
2654 got_found:;
2655 }
2656 }
2657 hi->got_entries = NULL;
2658
2659 /* And similar for the reloc entries. */
2660
2661 if (hs->reloc_entries == NULL)
2662 hs->reloc_entries = hi->reloc_entries;
2663 else
2664 {
2665 struct alpha_elf_reloc_entry *ri, *rs, *rin, *rsh;
2666
2667 rsh = hs->reloc_entries;
2668 for (ri = hi->reloc_entries; ri ; ri = rin)
2669 {
2670 rin = ri->next;
2671 for (rs = rsh; rs ; rs = rs->next)
2672 if (ri->rtype == rs->rtype)
2673 {
2674 rs->count += ri->count;
2675 goto found_reloc;
2676 }
2677 ri->next = hs->reloc_entries;
2678 hs->reloc_entries = ri;
2679 found_reloc:;
2680 }
2681 }
2682 hi->reloc_entries = NULL;
2683
2684 return true;
2685}
2686
2687/* Is it possible to merge two object file's .got tables? */
2688
2689static boolean
2690elf64_alpha_can_merge_gots (a, b)
2691 bfd *a, *b;
2692{
2693 int total = alpha_elf_tdata (a)->total_got_entries;
2694 bfd *bsub;
2695
2696 /* Trivial quick fallout test. */
2697 if (total + alpha_elf_tdata (b)->total_got_entries <= MAX_GOT_ENTRIES)
2698 return true;
2699
2700 /* By their nature, local .got entries cannot be merged. */
2701 if ((total += alpha_elf_tdata (b)->n_local_got_entries) > MAX_GOT_ENTRIES)
2702 return false;
2703
2704 /* Failing the common trivial comparison, we must effectively
2705 perform the merge. Not actually performing the merge means that
2706 we don't have to store undo information in case we fail. */
2707 for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
2708 {
2709 struct alpha_elf_link_hash_entry **hashes = alpha_elf_sym_hashes (bsub);
2710 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
2711 int i, n;
2712
d9bc7a44 2713 n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
252b5132
RH
2714 for (i = 0; i < n; ++i)
2715 {
2716 struct alpha_elf_got_entry *ae, *be;
2717 struct alpha_elf_link_hash_entry *h;
2718
2719 h = hashes[i];
2720 while (h->root.root.type == bfd_link_hash_indirect
2721 || h->root.root.type == bfd_link_hash_warning)
2722 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
2723
2724 for (be = h->got_entries; be ; be = be->next)
2725 {
2726 if (be->use_count == 0)
2727 continue;
2728 if (be->gotobj != b)
2729 continue;
2730
2731 for (ae = h->got_entries; ae ; ae = ae->next)
2732 if (ae->gotobj == a && ae->addend == be->addend)
2733 goto global_found;
2734
2735 if (++total > MAX_GOT_ENTRIES)
2736 return false;
2737 global_found:;
2738 }
2739 }
2740 }
2741
2742 return true;
2743}
2744
2745/* Actually merge two .got tables. */
2746
2747static void
2748elf64_alpha_merge_gots (a, b)
2749 bfd *a, *b;
2750{
2751 int total = alpha_elf_tdata (a)->total_got_entries;
2752 bfd *bsub;
2753
2754 /* Remember local expansion. */
2755 {
2756 int e = alpha_elf_tdata (b)->n_local_got_entries;
2757 total += e;
2758 alpha_elf_tdata (a)->n_local_got_entries += e;
2759 }
2760
2761 for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
2762 {
2763 struct alpha_elf_got_entry **local_got_entries;
2764 struct alpha_elf_link_hash_entry **hashes;
2765 Elf_Internal_Shdr *symtab_hdr;
2766 int i, n;
2767
2768 /* Let the local .got entries know they are part of a new subsegment. */
2769 local_got_entries = alpha_elf_tdata (bsub)->local_got_entries;
2770 if (local_got_entries)
2771 {
2772 n = elf_tdata (bsub)->symtab_hdr.sh_info;
2773 for (i = 0; i < n; ++i)
2774 {
2775 struct alpha_elf_got_entry *ent;
2776 for (ent = local_got_entries[i]; ent; ent = ent->next)
2777 ent->gotobj = a;
2778 }
2779 }
2780
2781 /* Merge the global .got entries. */
2782 hashes = alpha_elf_sym_hashes (bsub);
2783 symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
2784
d9bc7a44 2785 n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
252b5132
RH
2786 for (i = 0; i < n; ++i)
2787 {
2788 struct alpha_elf_got_entry *ae, *be, **pbe, **start;
2789 struct alpha_elf_link_hash_entry *h;
2790
2791 h = hashes[i];
2792 while (h->root.root.type == bfd_link_hash_indirect
2793 || h->root.root.type == bfd_link_hash_warning)
2794 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
2795
2796 start = &h->got_entries;
2797 for (pbe = start, be = *start; be ; pbe = &be->next, be = be->next)
2798 {
2799 if (be->use_count == 0)
2800 {
2801 *pbe = be->next;
2802 continue;
2803 }
2804 if (be->gotobj != b)
2805 continue;
2806
2807 for (ae = *start; ae ; ae = ae->next)
2808 if (ae->gotobj == a && ae->addend == be->addend)
2809 {
2810 ae->flags |= be->flags;
2811 ae->use_count += be->use_count;
2812 *pbe = be->next;
2813 goto global_found;
2814 }
2815 be->gotobj = a;
2816 total += 1;
2817
2818 global_found:;
2819 }
2820 }
2821
2822 alpha_elf_tdata (bsub)->gotobj = a;
2823 }
2824 alpha_elf_tdata (a)->total_got_entries = total;
2825
2826 /* Merge the two in_got chains. */
2827 {
2828 bfd *next;
2829
2830 bsub = a;
2831 while ((next = alpha_elf_tdata (bsub)->in_got_link_next) != NULL)
2832 bsub = next;
2833
2834 alpha_elf_tdata (bsub)->in_got_link_next = b;
2835 }
2836}
2837
2838/* Calculate the offsets for the got entries. */
2839
2840static boolean
2841elf64_alpha_calc_got_offsets_for_symbol (h, arg)
2842 struct alpha_elf_link_hash_entry *h;
52b9d213 2843 PTR arg ATTRIBUTE_UNUSED;
252b5132
RH
2844{
2845 struct alpha_elf_got_entry *gotent;
2846
2847 for (gotent = h->got_entries; gotent; gotent = gotent->next)
2848 if (gotent->use_count > 0)
2849 {
2850 bfd_size_type *plge
2851 = &alpha_elf_tdata (gotent->gotobj)->got->_raw_size;
2852
2853 gotent->got_offset = *plge;
2854 *plge += 8;
2855 }
2856
2857 return true;
2858}
2859
2860static void
2861elf64_alpha_calc_got_offsets (info)
2862 struct bfd_link_info *info;
2863{
2864 bfd *i, *got_list = alpha_elf_hash_table(info)->got_list;
2865
2866 /* First, zero out the .got sizes, as we may be recalculating the
2867 .got after optimizing it. */
2868 for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
2869 alpha_elf_tdata(i)->got->_raw_size = 0;
2870
2871 /* Next, fill in the offsets for all the global entries. */
2872 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2873 elf64_alpha_calc_got_offsets_for_symbol,
2874 NULL);
2875
2876 /* Finally, fill in the offsets for the local entries. */
2877 for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
2878 {
2879 bfd_size_type got_offset = alpha_elf_tdata(i)->got->_raw_size;
2880 bfd *j;
2881
2882 for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
2883 {
2884 struct alpha_elf_got_entry **local_got_entries, *gotent;
2885 int k, n;
2886
2887 local_got_entries = alpha_elf_tdata(j)->local_got_entries;
2888 if (!local_got_entries)
2889 continue;
2890
2891 for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
2892 for (gotent = local_got_entries[k]; gotent; gotent = gotent->next)
2893 if (gotent->use_count > 0)
2894 {
2895 gotent->got_offset = got_offset;
2896 got_offset += 8;
2897 }
2898 }
2899
2900 alpha_elf_tdata(i)->got->_raw_size = got_offset;
2901 alpha_elf_tdata(i)->got->_cooked_size = got_offset;
2902 }
2903}
2904
2905/* Constructs the gots. */
2906
2907static boolean
2908elf64_alpha_size_got_sections (output_bfd, info)
52b9d213 2909 bfd *output_bfd ATTRIBUTE_UNUSED;
252b5132
RH
2910 struct bfd_link_info *info;
2911{
52b9d213 2912 bfd *i, *got_list, *cur_got_obj = NULL;
252b5132
RH
2913 int something_changed = 0;
2914
2915 got_list = alpha_elf_hash_table (info)->got_list;
2916
2917 /* On the first time through, pretend we have an existing got list
2918 consisting of all of the input files. */
2919 if (got_list == NULL)
2920 {
2921 for (i = info->input_bfds; i ; i = i->link_next)
2922 {
2923 bfd *this_got = alpha_elf_tdata (i)->gotobj;
2924 if (this_got == NULL)
2925 continue;
2926
2927 /* We are assuming no merging has yet ocurred. */
2928 BFD_ASSERT (this_got == i);
2929
2930 if (alpha_elf_tdata (this_got)->total_got_entries > MAX_GOT_ENTRIES)
2931 {
2932 /* Yikes! A single object file has too many entries. */
2933 (*_bfd_error_handler)
2934 (_("%s: .got subsegment exceeds 64K (size %d)"),
8f615d07 2935 bfd_archive_filename (i),
252b5132
RH
2936 alpha_elf_tdata (this_got)->total_got_entries * 8);
2937 return false;
2938 }
2939
2940 if (got_list == NULL)
2941 got_list = this_got;
2942 else
2943 alpha_elf_tdata(cur_got_obj)->got_link_next = this_got;
2944 cur_got_obj = this_got;
2945 }
2946
2947 /* Strange degenerate case of no got references. */
2948 if (got_list == NULL)
2949 return true;
2950
2951 alpha_elf_hash_table (info)->got_list = got_list;
2952
2953 /* Force got offsets to be recalculated. */
2954 something_changed = 1;
2955 }
2956
2957 cur_got_obj = got_list;
2958 i = alpha_elf_tdata(cur_got_obj)->got_link_next;
2959 while (i != NULL)
2960 {
2961 if (elf64_alpha_can_merge_gots (cur_got_obj, i))
2962 {
2963 elf64_alpha_merge_gots (cur_got_obj, i);
2964 i = alpha_elf_tdata(i)->got_link_next;
2965 alpha_elf_tdata(cur_got_obj)->got_link_next = i;
2966 something_changed = 1;
2967 }
2968 else
2969 {
2970 cur_got_obj = i;
2971 i = alpha_elf_tdata(i)->got_link_next;
2972 }
2973 }
2974
2975 /* Once the gots have been merged, fill in the got offsets for
2976 everything therein. */
2977 if (1 || something_changed)
2978 elf64_alpha_calc_got_offsets (info);
2979
2980 return true;
2981}
2982
2983static boolean
2984elf64_alpha_always_size_sections (output_bfd, info)
2985 bfd *output_bfd;
2986 struct bfd_link_info *info;
2987{
2988 bfd *i;
2989
2990 if (info->relocateable)
2991 return true;
2992
2993 /* First, take care of the indirect symbols created by versioning. */
2994 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2995 elf64_alpha_merge_ind_symbols,
2996 NULL);
2997
2998 if (!elf64_alpha_size_got_sections (output_bfd, info))
2999 return false;
3000
3001 /* Allocate space for all of the .got subsections. */
3002 i = alpha_elf_hash_table (info)->got_list;
3003 for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
3004 {
3005 asection *s = alpha_elf_tdata(i)->got;
3006 if (s->_raw_size > 0)
3007 {
3008 s->contents = (bfd_byte *) bfd_zalloc (i, s->_raw_size);
3009 if (s->contents == NULL)
3010 return false;
3011 }
3012 }
3013
3014 return true;
3015}
3016
3017/* Work out the sizes of the dynamic relocation entries. */
3018
3019static boolean
3020elf64_alpha_calc_dynrel_sizes (h, info)
3021 struct alpha_elf_link_hash_entry *h;
3022 struct bfd_link_info *info;
3023{
3024 /* If the symbol was defined as a common symbol in a regular object
3025 file, and there was no definition in any dynamic object, then the
3026 linker will have allocated space for the symbol in a common
3027 section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been
3028 set. This is done for dynamic symbols in
3029 elf_adjust_dynamic_symbol but this is not done for non-dynamic
3030 symbols, somehow. */
3031 if (((h->root.elf_link_hash_flags
3032 & (ELF_LINK_HASH_DEF_REGULAR
3033 | ELF_LINK_HASH_REF_REGULAR
3034 | ELF_LINK_HASH_DEF_DYNAMIC))
3035 == ELF_LINK_HASH_REF_REGULAR)
3036 && (h->root.root.type == bfd_link_hash_defined
3037 || h->root.root.type == bfd_link_hash_defweak)
3038 && !(h->root.root.u.def.section->owner->flags & DYNAMIC))
3039 {
3040 h->root.elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
3041 }
3042
3043 /* If the symbol is dynamic, we'll need all the relocations in their
3044 natural form. If this is a shared object, and it has been forced
3045 local, we'll need the same number of RELATIVE relocations. */
3046
3047 if (alpha_elf_dynamic_symbol_p (&h->root, info) || info->shared)
3048 {
3049 struct alpha_elf_reloc_entry *relent;
3050 bfd *dynobj;
3051 struct alpha_elf_got_entry *gotent;
3052 bfd_size_type count;
3053 asection *srel;
3054
3055 for (relent = h->reloc_entries; relent; relent = relent->next)
3056 if (relent->rtype == R_ALPHA_REFLONG
3057 || relent->rtype == R_ALPHA_REFQUAD)
3058 {
3059 relent->srel->_raw_size +=
fe8bc63d 3060 sizeof (Elf64_External_Rela) * relent->count;
fcfbdf31
JJ
3061 if (relent->reltext)
3062 info->flags |= DT_TEXTREL;
252b5132
RH
3063 }
3064
3065 dynobj = elf_hash_table(info)->dynobj;
3066 count = 0;
3067
3068 for (gotent = h->got_entries; gotent ; gotent = gotent->next)
3069 count++;
3070
3071 /* If we are using a .plt entry, subtract one, as the first
3072 reference uses a .rela.plt entry instead. */
3073 if (h->root.plt.offset != MINUS_ONE)
3074 count--;
3075
3076 if (count > 0)
3077 {
3078 srel = bfd_get_section_by_name (dynobj, ".rela.got");
3079 BFD_ASSERT (srel != NULL);
3080 srel->_raw_size += sizeof (Elf64_External_Rela) * count;
3081 }
3082 }
3083
3084 return true;
3085}
3086
3087/* Set the sizes of the dynamic sections. */
3088
3089static boolean
3090elf64_alpha_size_dynamic_sections (output_bfd, info)
24a35864 3091 bfd *output_bfd ATTRIBUTE_UNUSED;
252b5132
RH
3092 struct bfd_link_info *info;
3093{
3094 bfd *dynobj;
3095 asection *s;
252b5132
RH
3096 boolean relplt;
3097
3098 dynobj = elf_hash_table(info)->dynobj;
3099 BFD_ASSERT(dynobj != NULL);
3100
3101 if (elf_hash_table (info)->dynamic_sections_created)
3102 {
3103 /* Set the contents of the .interp section to the interpreter. */
3104 if (!info->shared)
3105 {
3106 s = bfd_get_section_by_name (dynobj, ".interp");
3107 BFD_ASSERT (s != NULL);
3108 s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
3109 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
3110 }
3111
3112 /* Now that we've seen all of the input files, we can decide which
3113 symbols need dynamic relocation entries and which don't. We've
3114 collected information in check_relocs that we can now apply to
3115 size the dynamic relocation sections. */
3116 alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
3117 elf64_alpha_calc_dynrel_sizes,
3118 info);
3119
3120 /* When building shared libraries, each local .got entry needs a
3121 RELATIVE reloc. */
3122 if (info->shared)
3123 {
3124 bfd *i;
3125 asection *srel;
3126 bfd_size_type count;
3127
3128 srel = bfd_get_section_by_name (dynobj, ".rela.got");
3129 BFD_ASSERT (srel != NULL);
3130
3131 for (i = alpha_elf_hash_table(info)->got_list, count = 0;
3132 i != NULL;
3133 i = alpha_elf_tdata(i)->got_link_next)
3134 count += alpha_elf_tdata(i)->n_local_got_entries;
3135
fe8bc63d 3136 srel->_raw_size += count * sizeof (Elf64_External_Rela);
252b5132
RH
3137 }
3138 }
3139 /* else we're not dynamic and by definition we don't need such things. */
3140
3141 /* The check_relocs and adjust_dynamic_symbol entry points have
3142 determined the sizes of the various dynamic sections. Allocate
3143 memory for them. */
252b5132
RH
3144 relplt = false;
3145 for (s = dynobj->sections; s != NULL; s = s->next)
3146 {
3147 const char *name;
3148 boolean strip;
3149
3150 if (!(s->flags & SEC_LINKER_CREATED))
3151 continue;
3152
3153 /* It's OK to base decisions on the section name, because none
3154 of the dynobj section names depend upon the input files. */
3155 name = bfd_get_section_name (dynobj, s);
3156
3157 /* If we don't need this section, strip it from the output file.
3158 This is to handle .rela.bss and .rela.plt. We must create it
3159 in create_dynamic_sections, because it must be created before
3160 the linker maps input sections to output sections. The
3161 linker does that before adjust_dynamic_symbol is called, and
3162 it is that function which decides whether anything needs to
3163 go into these sections. */
3164
3165 strip = false;
3166
3167 if (strncmp (name, ".rela", 5) == 0)
3168 {
3169 strip = (s->_raw_size == 0);
3170
3171 if (!strip)
3172 {
252b5132
RH
3173 if (strcmp(name, ".rela.plt") == 0)
3174 relplt = true;
3175
3176 /* We use the reloc_count field as a counter if we need
3177 to copy relocs into the output file. */
3178 s->reloc_count = 0;
3179 }
3180 }
3181 else if (strcmp (name, ".plt") != 0)
3182 {
3183 /* It's not one of our dynamic sections, so don't allocate space. */
3184 continue;
3185 }
3186
3187 if (strip)
7f8d5fc9 3188 _bfd_strip_section_from_output (info, s);
252b5132
RH
3189 else
3190 {
3191 /* Allocate memory for the section contents. */
dc810e39 3192 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
252b5132
RH
3193 if (s->contents == NULL && s->_raw_size != 0)
3194 return false;
3195 }
3196 }
3197
252b5132
RH
3198 if (elf_hash_table (info)->dynamic_sections_created)
3199 {
3200 /* Add some entries to the .dynamic section. We fill in the
3201 values later, in elf64_alpha_finish_dynamic_sections, but we
3202 must add the entries now so that we get the correct size for
3203 the .dynamic section. The DT_DEBUG entry is filled in by the
3204 dynamic linker and used by the debugger. */
dc810e39
AM
3205#define add_dynamic_entry(TAG, VAL) \
3206 bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3207
252b5132
RH
3208 if (!info->shared)
3209 {
dc810e39 3210 if (!add_dynamic_entry (DT_DEBUG, 0))
252b5132
RH
3211 return false;
3212 }
3213
dc810e39 3214 if (!add_dynamic_entry (DT_PLTGOT, 0))
252b5132
RH
3215 return false;
3216
3217 if (relplt)
3218 {
dc810e39
AM
3219 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3220 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3221 || !add_dynamic_entry (DT_JMPREL, 0))
252b5132
RH
3222 return false;
3223 }
3224
dc810e39
AM
3225 if (!add_dynamic_entry (DT_RELA, 0)
3226 || !add_dynamic_entry (DT_RELASZ, 0)
3227 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
252b5132
RH
3228 return false;
3229
fcfbdf31 3230 if (info->flags & DF_TEXTREL)
252b5132 3231 {
dc810e39 3232 if (!add_dynamic_entry (DT_TEXTREL, 0))
252b5132
RH
3233 return false;
3234 }
3235 }
dc810e39 3236#undef add_dynamic_entry
252b5132
RH
3237
3238 return true;
3239}
3240
252b5132
RH
3241/* Relocate an Alpha ELF section. */
3242
3243static boolean
3244elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
3245 contents, relocs, local_syms, local_sections)
3246 bfd *output_bfd;
3247 struct bfd_link_info *info;
3248 bfd *input_bfd;
3249 asection *input_section;
3250 bfd_byte *contents;
3251 Elf_Internal_Rela *relocs;
3252 Elf_Internal_Sym *local_syms;
3253 asection **local_sections;
3254{
3255 Elf_Internal_Shdr *symtab_hdr;
3256 Elf_Internal_Rela *rel;
3257 Elf_Internal_Rela *relend;
3258 asection *sec, *sgot, *srel, *srelgot;
3259 bfd *dynobj, *gotobj;
3260 bfd_vma gp;
f16fbd61 3261 boolean ret_val = true;
252b5132
RH
3262
3263 srelgot = srel = NULL;
3264 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3265 dynobj = elf_hash_table (info)->dynobj;
3266 if (dynobj)
3267 {
3268 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
3269 }
3270
3271 /* Find the gp value for this input bfd. */
3272 sgot = NULL;
3273 gp = 0;
3274 gotobj = alpha_elf_tdata (input_bfd)->gotobj;
3275 if (gotobj)
3276 {
3277 sgot = alpha_elf_tdata (gotobj)->got;
3278 gp = _bfd_get_gp_value (gotobj);
3279 if (gp == 0)
3280 {
3281 gp = (sgot->output_section->vma
3282 + sgot->output_offset
3283 + 0x8000);
3284 _bfd_set_gp_value (gotobj, gp);
3285 }
3286 }
3287
3288 rel = relocs;
3289 relend = relocs + input_section->reloc_count;
3290 for (; rel < relend; rel++)
3291 {
3292 int r_type;
3293 reloc_howto_type *howto;
3294 unsigned long r_symndx;
3295 struct alpha_elf_link_hash_entry *h;
3296 Elf_Internal_Sym *sym;
3297 bfd_vma relocation;
dc810e39 3298 bfd_vma addend;
252b5132
RH
3299 bfd_reloc_status_type r;
3300
3301 r_type = ELF64_R_TYPE(rel->r_info);
3302 if (r_type < 0 || r_type >= (int) R_ALPHA_max)
3303 {
3304 bfd_set_error (bfd_error_bad_value);
3305 return false;
3306 }
3307 howto = elf64_alpha_howto_table + r_type;
3308
3309 r_symndx = ELF64_R_SYM(rel->r_info);
3310
3311 if (info->relocateable)
3312 {
3313 /* This is a relocateable link. We don't have to change
3314 anything, unless the reloc is against a section symbol,
3315 in which case we have to adjust according to where the
3316 section symbol winds up in the output section. */
72b60c23 3317
fe8bc63d 3318 /* The symbol associated with GPDISP and LITUSE is
72b60c23
RH
3319 immaterial. Only the addend is significant. */
3320 if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE)
3321 continue;
3322
252b5132
RH
3323 if (r_symndx < symtab_hdr->sh_info)
3324 {
3325 sym = local_syms + r_symndx;
3326 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
3327 {
3328 sec = local_sections[r_symndx];
3329 rel->r_addend += sec->output_offset + sym->st_value;
3330 }
3331 }
3332
3333 continue;
3334 }
3335
3336 /* This is a final link. */
3337
3338 h = NULL;
3339 sym = NULL;
3340 sec = NULL;
3341
3342 if (r_symndx < symtab_hdr->sh_info)
3343 {
3344 sym = local_syms + r_symndx;
3345 sec = local_sections[r_symndx];
f8df10f4 3346 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
252b5132
RH
3347 }
3348 else
3349 {
3350 h = alpha_elf_sym_hashes (input_bfd)[r_symndx - symtab_hdr->sh_info];
3351
3352 while (h->root.root.type == bfd_link_hash_indirect
3353 || h->root.root.type == bfd_link_hash_warning)
3354 h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
3355
3356 if (h->root.root.type == bfd_link_hash_defined
3357 || h->root.root.type == bfd_link_hash_defweak)
3358 {
3359 sec = h->root.root.u.def.section;
3360
252b5132
RH
3361 if (sec->output_section == NULL)
3362 relocation = 0;
252b5132
RH
3363 else
3364 {
3365 relocation = (h->root.root.u.def.value
3366 + sec->output_section->vma
3367 + sec->output_offset);
3368 }
3369 }
3370 else if (h->root.root.type == bfd_link_hash_undefweak)
3371 relocation = 0;
671bae9c
NC
3372 else if (info->shared
3373 && (!info->symbolic || info->allow_shlib_undefined)
3a27a730 3374 && !info->no_undefined
edb72b3b 3375 && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
252b5132
RH
3376 relocation = 0;
3377 else
3378 {
3379 if (!((*info->callbacks->undefined_symbol)
3380 (info, h->root.root.root.string, input_bfd,
5cc7c785 3381 input_section, rel->r_offset,
3a27a730 3382 (!info->shared || info->no_undefined
edb72b3b 3383 || ELF_ST_VISIBILITY (h->root.other)))))
f16fbd61 3384 ret_val = false;
252b5132
RH
3385 relocation = 0;
3386 }
3387 }
3388 addend = rel->r_addend;
3389
3390 switch (r_type)
3391 {
3392 case R_ALPHA_GPDISP:
3393 {
3394 bfd_byte *p_ldah, *p_lda;
3395
3396 BFD_ASSERT(gp != 0);
3397
3398 relocation = (input_section->output_section->vma
3399 + input_section->output_offset
3400 + rel->r_offset);
3401
3402 p_ldah = contents + rel->r_offset - input_section->vma;
3403 p_lda = p_ldah + rel->r_addend;
3404
3405 r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - relocation,
3406 p_ldah, p_lda);
3407 }
3408 break;
3409
252b5132
RH
3410 case R_ALPHA_LITERAL:
3411 {
3412 struct alpha_elf_got_entry *gotent;
3413 boolean dynamic_symbol;
3414
3415 BFD_ASSERT(sgot != NULL);
3416 BFD_ASSERT(gp != 0);
3417
3418 if (h != NULL)
3419 {
3420 gotent = h->got_entries;
3421 dynamic_symbol = alpha_elf_dynamic_symbol_p (&h->root, info);
3422 }
3423 else
3424 {
3425 gotent = (alpha_elf_tdata(input_bfd)->
3426 local_got_entries[r_symndx]);
3427 dynamic_symbol = false;
f7460f5f
JJ
3428
3429 /* Need to adjust local GOT entries' addends for SEC_MERGE
3430 unless it has been done already. */
3431 if ((sec->flags & SEC_MERGE)
3432 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
65765700
JJ
3433 && (elf_section_data (sec)->sec_info_type
3434 == ELF_INFO_TYPE_MERGE)
f7460f5f
JJ
3435 && (gotent->flags & ALPHA_ELF_GOT_ENTRY_RELOCS_XLATED) == 0)
3436 {
3437 struct alpha_elf_got_entry *ent;
3438 asection *msec;
3439
3440 for (ent = gotent; ent; ent = ent->next)
3441 {
3442 ent->flags |= ALPHA_ELF_GOT_ENTRY_RELOCS_XLATED;
3443 if (ent->use_count == 0)
3444 continue;
3445 msec = sec;
3446 ent->addend =
3447 _bfd_merged_section_offset (output_bfd, &msec,
3448 elf_section_data (sec)->
65765700 3449 sec_info,
f7460f5f
JJ
3450 sym->st_value
3451 + ent->addend,
3452 (bfd_vma) 0);
3453 ent->addend -= sym->st_value;
3454 ent->addend += msec->output_section->vma
3455 + msec->output_offset
3456 - sec->output_section->vma
3457 - sec->output_offset;
3458 }
3459 }
252b5132
RH
3460 }
3461
3462 BFD_ASSERT(gotent != NULL);
3463
3464 while (gotent->gotobj != gotobj || gotent->addend != addend)
3465 gotent = gotent->next;
3466
3467 BFD_ASSERT(gotent->use_count >= 1);
3468
3469 /* Initialize the .got entry's value. */
3470 if (!(gotent->flags & ALPHA_ELF_GOT_ENTRY_RELOCS_DONE))
3471 {
dc810e39 3472 bfd_put_64 (output_bfd, relocation + addend,
252b5132
RH
3473 sgot->contents + gotent->got_offset);
3474
3475 /* If the symbol has been forced local, output a
3476 RELATIVE reloc, otherwise it will be handled in
3477 finish_dynamic_symbol. */
3478 if (info->shared && !dynamic_symbol)
3479 {
3480 Elf_Internal_Rela outrel;
3481
3482 BFD_ASSERT(srelgot != NULL);
3483
3484 outrel.r_offset = (sgot->output_section->vma
3485 + sgot->output_offset
3486 + gotent->got_offset);
3487 outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
dc810e39 3488 outrel.r_addend = relocation + addend;
252b5132
RH
3489
3490 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
3491 ((Elf64_External_Rela *)
3492 srelgot->contents)
3493 + srelgot->reloc_count++);
fe8bc63d 3494 BFD_ASSERT (sizeof (Elf64_External_Rela)
252b5132
RH
3495 * srelgot->reloc_count
3496 <= srelgot->_cooked_size);
3497 }
3498
3499 gotent->flags |= ALPHA_ELF_GOT_ENTRY_RELOCS_DONE;
3500 }
3501
3502 /* Figure the gprel relocation. */
3503 addend = 0;
3504 relocation = (sgot->output_section->vma
3505 + sgot->output_offset
3506 + gotent->got_offset);
3507 relocation -= gp;
3508 }
3509 /* overflow handled by _bfd_final_link_relocate */
3510 goto default_reloc;
3511
dfe57ca0 3512 case R_ALPHA_GPREL16:
252b5132
RH
3513 case R_ALPHA_GPREL32:
3514 case R_ALPHA_GPRELLOW:
f16fbd61
RH
3515 if (h && alpha_elf_dynamic_symbol_p (&h->root, info))
3516 {
3517 (*_bfd_error_handler)
3518 (_("%s: gp-relative relocation against dynamic symbol %s"),
8f615d07 3519 bfd_archive_filename (input_bfd), h->root.root.root.string);
f16fbd61
RH
3520 ret_val = false;
3521 }
252b5132
RH
3522 BFD_ASSERT(gp != 0);
3523 relocation -= gp;
3524 goto default_reloc;
3525
3526 case R_ALPHA_GPRELHIGH:
f16fbd61
RH
3527 if (h && alpha_elf_dynamic_symbol_p (&h->root, info))
3528 {
3529 (*_bfd_error_handler)
3530 (_("%s: gp-relative relocation against dynamic symbol %s"),
8f615d07 3531 bfd_archive_filename (input_bfd), h->root.root.root.string);
f16fbd61
RH
3532 ret_val = false;
3533 }
252b5132
RH
3534 BFD_ASSERT(gp != 0);
3535 relocation -= gp;
3536 relocation += addend;
3537 addend = 0;
3538 relocation = (((bfd_signed_vma) relocation >> 16)
3539 + ((relocation >> 15) & 1));
3540 goto default_reloc;
3541
252b5132 3542 case R_ALPHA_HINT:
f94952df
RH
3543 /* A call to a dynamic symbol is definitely out of range of
3544 the 16-bit displacement. Don't bother writing anything. */
3545 if (h && alpha_elf_dynamic_symbol_p (&h->root, info))
3546 {
3547 r = bfd_reloc_ok;
3548 break;
3549 }
3550 /* FALLTHRU */
3551
3552 case R_ALPHA_BRADDR:
252b5132
RH
3553 /* The regular PC-relative stuff measures from the start of
3554 the instruction rather than the end. */
3555 addend -= 4;
3556 goto default_reloc;
3557
3558 case R_ALPHA_REFLONG:
3559 case R_ALPHA_REFQUAD:
3560 {
3561 Elf_Internal_Rela outrel;
252b5132
RH
3562
3563 /* Careful here to remember RELATIVE relocations for global
3564 variables for symbolic shared objects. */
3565
3566 if (h && alpha_elf_dynamic_symbol_p (&h->root, info))
3567 {
3568 BFD_ASSERT(h->root.dynindx != -1);
3569 outrel.r_info = ELF64_R_INFO(h->root.dynindx, r_type);
3570 outrel.r_addend = addend;
3571 addend = 0, relocation = 0;
3572 }
ec338859
AM
3573 else if (info->shared
3574 && r_symndx != 0
3575 && (input_section->flags & SEC_ALLOC))
252b5132
RH
3576 {
3577 outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
28cfee26 3578 outrel.r_addend = relocation + addend;
252b5132
RH
3579 }
3580 else
3581 goto default_reloc;
3582
3583 if (!srel)
3584 {
3585 const char *name;
3586
3587 name = (bfd_elf_string_from_elf_section
3588 (input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
3589 elf_section_data(input_section)->rel_hdr.sh_name));
3590 BFD_ASSERT(name != NULL);
3591
3592 srel = bfd_get_section_by_name (dynobj, name);
3593 BFD_ASSERT(srel != NULL);
3594 }
3595
c629eae0
JJ
3596 outrel.r_offset =
3597 _bfd_elf_section_offset (output_bfd, info, input_section,
3598 rel->r_offset);
3599 if (outrel.r_offset != (bfd_vma) -1)
252b5132
RH
3600 outrel.r_offset += (input_section->output_section->vma
3601 + input_section->output_offset);
3602 else
3603 memset (&outrel, 0, sizeof outrel);
3604
3605 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
3606 ((Elf64_External_Rela *)
3607 srel->contents)
3608 + srel->reloc_count++);
fe8bc63d 3609 BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
252b5132
RH
3610 <= srel->_cooked_size);
3611 }
3612 goto default_reloc;
3613
3614 default:
3615 default_reloc:
3616 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
3617 contents, rel->r_offset, relocation,
3618 addend);
3619 break;
3620 }
3621
3622 switch (r)
3623 {
3624 case bfd_reloc_ok:
3625 break;
3626
3627 case bfd_reloc_overflow:
3628 {
3629 const char *name;
3630
ed4de5e2
JJ
3631 /* Don't warn if the overflow is due to pc relative reloc
3632 against discarded section. Section optimization code should
3633 handle it. */
3634
3635 if (r_symndx < symtab_hdr->sh_info
3636 && sec != NULL && howto->pc_relative
3637 && elf_discarded_section (sec))
3638 break;
3639
252b5132
RH
3640 if (h != NULL)
3641 name = h->root.root.root.string;
3642 else
3643 {
3644 name = (bfd_elf_string_from_elf_section
3645 (input_bfd, symtab_hdr->sh_link, sym->st_name));
3646 if (name == NULL)
3647 return false;
3648 if (*name == '\0')
3649 name = bfd_section_name (input_bfd, sec);
3650 }
3651 if (! ((*info->callbacks->reloc_overflow)
3652 (info, name, howto->name, (bfd_vma) 0,
3653 input_bfd, input_section, rel->r_offset)))
f16fbd61 3654 ret_val = false;
252b5132
RH
3655 }
3656 break;
3657
3658 default:
3659 case bfd_reloc_outofrange:
3660 abort ();
3661 }
3662 }
3663
f16fbd61 3664 return ret_val;
252b5132
RH
3665}
3666
3667/* Finish up dynamic symbol handling. We set the contents of various
3668 dynamic sections here. */
3669
3670static boolean
3671elf64_alpha_finish_dynamic_symbol (output_bfd, info, h, sym)
3672 bfd *output_bfd;
3673 struct bfd_link_info *info;
3674 struct elf_link_hash_entry *h;
3675 Elf_Internal_Sym *sym;
3676{
3677 bfd *dynobj = elf_hash_table(info)->dynobj;
3678
3679 if (h->plt.offset != MINUS_ONE)
3680 {
3681 /* Fill in the .plt entry for this symbol. */
3682 asection *splt, *sgot, *srel;
3683 Elf_Internal_Rela outrel;
3684 bfd_vma got_addr, plt_addr;
3685 bfd_vma plt_index;
3686 struct alpha_elf_got_entry *gotent;
3687
3688 BFD_ASSERT (h->dynindx != -1);
3689
3690 /* The first .got entry will be updated by the .plt with the
3691 address of the target function. */
3692 gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
3693 BFD_ASSERT (gotent && gotent->addend == 0);
3694
3695 splt = bfd_get_section_by_name (dynobj, ".plt");
3696 BFD_ASSERT (splt != NULL);
3697 srel = bfd_get_section_by_name (dynobj, ".rela.plt");
3698 BFD_ASSERT (srel != NULL);
3699 sgot = alpha_elf_tdata (gotent->gotobj)->got;
3700 BFD_ASSERT (sgot != NULL);
3701
3702 got_addr = (sgot->output_section->vma
3703 + sgot->output_offset
3704 + gotent->got_offset);
3705 plt_addr = (splt->output_section->vma
3706 + splt->output_offset
3707 + h->plt.offset);
3708
3709 plt_index = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3710
3711 /* Fill in the entry in the procedure linkage table. */
3712 {
dc810e39 3713 bfd_vma insn1, insn2, insn3;
252b5132
RH
3714
3715 insn1 = PLT_ENTRY_WORD1 | ((-(h->plt.offset + 4) >> 2) & 0x1fffff);
3716 insn2 = PLT_ENTRY_WORD2;
3717 insn3 = PLT_ENTRY_WORD3;
3718
3719 bfd_put_32 (output_bfd, insn1, splt->contents + h->plt.offset);
3720 bfd_put_32 (output_bfd, insn2, splt->contents + h->plt.offset + 4);
3721 bfd_put_32 (output_bfd, insn3, splt->contents + h->plt.offset + 8);
3722 }
3723
3724 /* Fill in the entry in the .rela.plt section. */
3725 outrel.r_offset = got_addr;
3726 outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT);
3727 outrel.r_addend = 0;
3728
3729 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
3730 ((Elf64_External_Rela *)srel->contents
3731 + plt_index));
3732
3733 if (!(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
3734 {
3735 /* Mark the symbol as undefined, rather than as defined in the
3736 .plt section. Leave the value alone. */
3737 sym->st_shndx = SHN_UNDEF;
3738 }
3739
3740 /* Fill in the entries in the .got. */
3741 bfd_put_64 (output_bfd, plt_addr, sgot->contents + gotent->got_offset);
3742
3743 /* Subsequent .got entries will continue to bounce through the .plt. */
3744 if (gotent->next)
3745 {
3746 srel = bfd_get_section_by_name (dynobj, ".rela.got");
3747 BFD_ASSERT (! info->shared || srel != NULL);
3748
3749 gotent = gotent->next;
3750 do
3751 {
3752 sgot = alpha_elf_tdata(gotent->gotobj)->got;
3753 BFD_ASSERT(sgot != NULL);
3754 BFD_ASSERT(gotent->addend == 0);
3755
3756 bfd_put_64 (output_bfd, plt_addr,
3757 sgot->contents + gotent->got_offset);
3758
3759 if (info->shared)
3760 {
3761 outrel.r_offset = (sgot->output_section->vma
3762 + sgot->output_offset
3763 + gotent->got_offset);
3764 outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
28cfee26 3765 outrel.r_addend = plt_addr;
252b5132
RH
3766
3767 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
3768 ((Elf64_External_Rela *)
3769 srel->contents)
3770 + srel->reloc_count++);
fe8bc63d 3771 BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
252b5132
RH
3772 <= srel->_cooked_size);
3773 }
3774
3775 gotent = gotent->next;
3776 }
3777 while (gotent != NULL);
3778 }
3779 }
3780 else if (alpha_elf_dynamic_symbol_p (h, info))
3781 {
3782 /* Fill in the dynamic relocations for this symbol's .got entries. */
3783 asection *srel;
3784 Elf_Internal_Rela outrel;
3785 struct alpha_elf_got_entry *gotent;
3786
3787 srel = bfd_get_section_by_name (dynobj, ".rela.got");
3788 BFD_ASSERT (srel != NULL);
3789
3790 outrel.r_info = ELF64_R_INFO (h->dynindx, R_ALPHA_GLOB_DAT);
3791 for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
3792 gotent != NULL;
3793 gotent = gotent->next)
3794 {
3795 asection *sgot = alpha_elf_tdata (gotent->gotobj)->got;
3796 outrel.r_offset = (sgot->output_section->vma
3797 + sgot->output_offset
3798 + gotent->got_offset);
3799 outrel.r_addend = gotent->addend;
3800
3801 bfd_elf64_swap_reloca_out (output_bfd, &outrel,
3802 ((Elf64_External_Rela *)srel->contents
3803 + srel->reloc_count++));
fe8bc63d 3804 BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
252b5132
RH
3805 <= srel->_cooked_size);
3806 }
3807 }
3808
3809 /* Mark some specially defined symbols as absolute. */
3810 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
3811 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
3812 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
3813 sym->st_shndx = SHN_ABS;
3814
3815 return true;
3816}
3817
3818/* Finish up the dynamic sections. */
3819
3820static boolean
3821elf64_alpha_finish_dynamic_sections (output_bfd, info)
3822 bfd *output_bfd;
3823 struct bfd_link_info *info;
3824{
3825 bfd *dynobj;
3826 asection *sdyn;
3827
3828 dynobj = elf_hash_table (info)->dynobj;
3829 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3830
3831 if (elf_hash_table (info)->dynamic_sections_created)
3832 {
3833 asection *splt;
3834 Elf64_External_Dyn *dyncon, *dynconend;
3835
3836 splt = bfd_get_section_by_name (dynobj, ".plt");
3837 BFD_ASSERT (splt != NULL && sdyn != NULL);
3838
3839 dyncon = (Elf64_External_Dyn *) sdyn->contents;
3840 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
3841 for (; dyncon < dynconend; dyncon++)
3842 {
3843 Elf_Internal_Dyn dyn;
3844 const char *name;
3845 asection *s;
3846
3847 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
3848
3849 switch (dyn.d_tag)
3850 {
3851 case DT_PLTGOT:
3852 name = ".plt";
3853 goto get_vma;
3854 case DT_PLTRELSZ:
3855 name = ".rela.plt";
3856 goto get_size;
3857 case DT_JMPREL:
3858 name = ".rela.plt";
3859 goto get_vma;
3860
3861 case DT_RELASZ:
3862 /* My interpretation of the TIS v1.1 ELF document indicates
3863 that RELASZ should not include JMPREL. This is not what
3864 the rest of the BFD does. It is, however, what the
3865 glibc ld.so wants. Do this fixup here until we found
3866 out who is right. */
3867 s = bfd_get_section_by_name (output_bfd, ".rela.plt");
3868 if (s)
3869 {
3870 dyn.d_un.d_val -=
3871 (s->_cooked_size ? s->_cooked_size : s->_raw_size);
3872 }
3873 break;
3874
3875 get_vma:
3876 s = bfd_get_section_by_name (output_bfd, name);
3877 dyn.d_un.d_ptr = (s ? s->vma : 0);
3878 break;
3879
3880 get_size:
3881 s = bfd_get_section_by_name (output_bfd, name);
3882 dyn.d_un.d_val =
3883 (s->_cooked_size ? s->_cooked_size : s->_raw_size);
3884 break;
3885 }
3886
3887 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
3888 }
3889
3890 /* Initialize the PLT0 entry */
3891 if (splt->_raw_size > 0)
3892 {
3893 bfd_put_32 (output_bfd, PLT_HEADER_WORD1, splt->contents);
3894 bfd_put_32 (output_bfd, PLT_HEADER_WORD2, splt->contents + 4);
3895 bfd_put_32 (output_bfd, PLT_HEADER_WORD3, splt->contents + 8);
3896 bfd_put_32 (output_bfd, PLT_HEADER_WORD4, splt->contents + 12);
3897
3898 /* The next two words will be filled in by ld.so */
dc810e39
AM
3899 bfd_put_64 (output_bfd, (bfd_vma) 0, splt->contents + 16);
3900 bfd_put_64 (output_bfd, (bfd_vma) 0, splt->contents + 24);
252b5132
RH
3901
3902 elf_section_data (splt->output_section)->this_hdr.sh_entsize =
3903 PLT_HEADER_SIZE;
3904 }
3905 }
3906
252b5132
RH
3907 return true;
3908}
3909
96e2734b
RH
3910/* We need to use a special link routine to handle the .mdebug section.
3911 We need to merge all instances of these sections together, not write
3912 them all out sequentially. */
252b5132
RH
3913
3914static boolean
3915elf64_alpha_final_link (abfd, info)
3916 bfd *abfd;
3917 struct bfd_link_info *info;
3918{
3919 asection *o;
3920 struct bfd_link_order *p;
96e2734b 3921 asection *mdebug_sec;
252b5132
RH
3922 struct ecoff_debug_info debug;
3923 const struct ecoff_debug_swap *swap
3924 = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
3925 HDRR *symhdr = &debug.symbolic_header;
3926 PTR mdebug_handle = NULL;
3927
96e2734b 3928 /* Go through the sections and collect the mdebug information. */
252b5132 3929 mdebug_sec = NULL;
252b5132
RH
3930 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3931 {
252b5132
RH
3932 if (strcmp (o->name, ".mdebug") == 0)
3933 {
3934 struct extsym_info einfo;
3935
3936 /* We have found the .mdebug section in the output file.
3937 Look through all the link_orders comprising it and merge
3938 the information together. */
3939 symhdr->magic = swap->sym_magic;
3940 /* FIXME: What should the version stamp be? */
3941 symhdr->vstamp = 0;
3942 symhdr->ilineMax = 0;
3943 symhdr->cbLine = 0;
3944 symhdr->idnMax = 0;
3945 symhdr->ipdMax = 0;
3946 symhdr->isymMax = 0;
3947 symhdr->ioptMax = 0;
3948 symhdr->iauxMax = 0;
3949 symhdr->issMax = 0;
3950 symhdr->issExtMax = 0;
3951 symhdr->ifdMax = 0;
3952 symhdr->crfd = 0;
3953 symhdr->iextMax = 0;
3954
3955 /* We accumulate the debugging information itself in the
3956 debug_info structure. */
3957 debug.line = NULL;
3958 debug.external_dnr = NULL;
3959 debug.external_pdr = NULL;
3960 debug.external_sym = NULL;
3961 debug.external_opt = NULL;
3962 debug.external_aux = NULL;
3963 debug.ss = NULL;
3964 debug.ssext = debug.ssext_end = NULL;
3965 debug.external_fdr = NULL;
3966 debug.external_rfd = NULL;
3967 debug.external_ext = debug.external_ext_end = NULL;
3968
3969 mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
3970 if (mdebug_handle == (PTR) NULL)
3971 return false;
3972
3973 if (1)
3974 {
3975 asection *s;
3976 EXTR esym;
52b9d213 3977 bfd_vma last = 0;
252b5132
RH
3978 unsigned int i;
3979 static const char * const name[] =
3980 {
3981 ".text", ".init", ".fini", ".data",
3982 ".rodata", ".sdata", ".sbss", ".bss"
3983 };
3984 static const int sc[] = { scText, scInit, scFini, scData,
3985 scRData, scSData, scSBss, scBss };
3986
3987 esym.jmptbl = 0;
3988 esym.cobol_main = 0;
3989 esym.weakext = 0;
3990 esym.reserved = 0;
3991 esym.ifd = ifdNil;
3992 esym.asym.iss = issNil;
3993 esym.asym.st = stLocal;
3994 esym.asym.reserved = 0;
3995 esym.asym.index = indexNil;
3996 for (i = 0; i < 8; i++)
3997 {
3998 esym.asym.sc = sc[i];
3999 s = bfd_get_section_by_name (abfd, name[i]);
4000 if (s != NULL)
4001 {
4002 esym.asym.value = s->vma;
4003 last = s->vma + s->_raw_size;
4004 }
4005 else
4006 esym.asym.value = last;
4007
4008 if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
4009 name[i], &esym))
4010 return false;
4011 }
4012 }
4013
4014 for (p = o->link_order_head;
4015 p != (struct bfd_link_order *) NULL;
4016 p = p->next)
4017 {
4018 asection *input_section;
4019 bfd *input_bfd;
4020 const struct ecoff_debug_swap *input_swap;
4021 struct ecoff_debug_info input_debug;
4022 char *eraw_src;
4023 char *eraw_end;
4024
4025 if (p->type != bfd_indirect_link_order)
4026 {
4027 if (p->type == bfd_fill_link_order)
4028 continue;
4029 abort ();
4030 }
4031
4032 input_section = p->u.indirect.section;
4033 input_bfd = input_section->owner;
4034
4035 if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour
4036 || (get_elf_backend_data (input_bfd)
4037 ->elf_backend_ecoff_debug_swap) == NULL)
4038 {
4039 /* I don't know what a non ALPHA ELF bfd would be
4040 doing with a .mdebug section, but I don't really
4041 want to deal with it. */
4042 continue;
4043 }
4044
4045 input_swap = (get_elf_backend_data (input_bfd)
4046 ->elf_backend_ecoff_debug_swap);
4047
4048 BFD_ASSERT (p->size == input_section->_raw_size);
4049
4050 /* The ECOFF linking code expects that we have already
4051 read in the debugging information and set up an
4052 ecoff_debug_info structure, so we do that now. */
4053 if (!elf64_alpha_read_ecoff_info (input_bfd, input_section,
4054 &input_debug))
4055 return false;
4056
4057 if (! (bfd_ecoff_debug_accumulate
4058 (mdebug_handle, abfd, &debug, swap, input_bfd,
4059 &input_debug, input_swap, info)))
4060 return false;
4061
4062 /* Loop through the external symbols. For each one with
4063 interesting information, try to find the symbol in
4064 the linker global hash table and save the information
4065 for the output external symbols. */
4066 eraw_src = input_debug.external_ext;
4067 eraw_end = (eraw_src
4068 + (input_debug.symbolic_header.iextMax
4069 * input_swap->external_ext_size));
4070 for (;
4071 eraw_src < eraw_end;
4072 eraw_src += input_swap->external_ext_size)
4073 {
4074 EXTR ext;
4075 const char *name;
4076 struct alpha_elf_link_hash_entry *h;
4077
4078 (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
4079 if (ext.asym.sc == scNil
4080 || ext.asym.sc == scUndefined
4081 || ext.asym.sc == scSUndefined)
4082 continue;
4083
4084 name = input_debug.ssext + ext.asym.iss;
4085 h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info),
4086 name, false, false, true);
4087 if (h == NULL || h->esym.ifd != -2)
4088 continue;
4089
4090 if (ext.ifd != -1)
4091 {
4092 BFD_ASSERT (ext.ifd
4093 < input_debug.symbolic_header.ifdMax);
4094 ext.ifd = input_debug.ifdmap[ext.ifd];
4095 }
4096
4097 h->esym = ext;
4098 }
4099
4100 /* Free up the information we just read. */
4101 free (input_debug.line);
4102 free (input_debug.external_dnr);
4103 free (input_debug.external_pdr);
4104 free (input_debug.external_sym);
4105 free (input_debug.external_opt);
4106 free (input_debug.external_aux);
4107 free (input_debug.ss);
4108 free (input_debug.ssext);
4109 free (input_debug.external_fdr);
4110 free (input_debug.external_rfd);
4111 free (input_debug.external_ext);
4112
4113 /* Hack: reset the SEC_HAS_CONTENTS flag so that
4114 elf_link_input_bfd ignores this section. */
4115 input_section->flags &=~ SEC_HAS_CONTENTS;
4116 }
4117
252b5132
RH
4118 /* Build the external symbol information. */
4119 einfo.abfd = abfd;
4120 einfo.info = info;
4121 einfo.debug = &debug;
4122 einfo.swap = swap;
4123 einfo.failed = false;
4124 elf_link_hash_traverse (elf_hash_table (info),
4125 elf64_alpha_output_extsym,
4126 (PTR) &einfo);
4127 if (einfo.failed)
4128 return false;
4129
4130 /* Set the size of the .mdebug section. */
4131 o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap);
4132
4133 /* Skip this section later on (I don't think this currently
4134 matters, but someday it might). */
4135 o->link_order_head = (struct bfd_link_order *) NULL;
4136
4137 mdebug_sec = o;
4138 }
252b5132
RH
4139 }
4140
4141 /* Invoke the regular ELF backend linker to do all the work. */
4142 if (! bfd_elf64_bfd_final_link (abfd, info))
4143 return false;
4144
4145 /* Now write out the computed sections. */
4146
4147 /* The .got subsections... */
4148 {
4149 bfd *i, *dynobj = elf_hash_table(info)->dynobj;
4150 for (i = alpha_elf_hash_table(info)->got_list;
4151 i != NULL;
4152 i = alpha_elf_tdata(i)->got_link_next)
4153 {
4154 asection *sgot;
4155
4156 /* elf_bfd_final_link already did everything in dynobj. */
4157 if (i == dynobj)
4158 continue;
4159
4160 sgot = alpha_elf_tdata(i)->got;
4161 if (! bfd_set_section_contents (abfd, sgot->output_section,
dc810e39
AM
4162 sgot->contents,
4163 (file_ptr) sgot->output_offset,
252b5132
RH
4164 sgot->_raw_size))
4165 return false;
4166 }
4167 }
4168
252b5132
RH
4169 if (mdebug_sec != (asection *) NULL)
4170 {
4171 BFD_ASSERT (abfd->output_has_begun);
4172 if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
4173 swap, info,
4174 mdebug_sec->filepos))
4175 return false;
4176
4177 bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
4178 }
4179
252b5132
RH
4180 return true;
4181}
fcfbdf31
JJ
4182
4183static enum elf_reloc_type_class
f51e552e
AM
4184elf64_alpha_reloc_type_class (rela)
4185 const Elf_Internal_Rela *rela;
fcfbdf31 4186{
f51e552e 4187 switch ((int) ELF64_R_TYPE (rela->r_info))
fcfbdf31
JJ
4188 {
4189 case R_ALPHA_RELATIVE:
4190 return reloc_class_relative;
4191 case R_ALPHA_JMP_SLOT:
4192 return reloc_class_plt;
4193 case R_ALPHA_COPY:
4194 return reloc_class_copy;
4195 default:
4196 return reloc_class_normal;
4197 }
4198}
252b5132
RH
4199\f
4200/* ECOFF swapping routines. These are used when dealing with the
4201 .mdebug section, which is in the ECOFF debugging format. Copied
fe8bc63d 4202 from elf32-mips.c. */
252b5132
RH
4203static const struct ecoff_debug_swap
4204elf64_alpha_ecoff_debug_swap =
4205{
4206 /* Symbol table magic number. */
4207 magicSym2,
4208 /* Alignment of debugging information. E.g., 4. */
4209 8,
4210 /* Sizes of external symbolic information. */
4211 sizeof (struct hdr_ext),
4212 sizeof (struct dnr_ext),
4213 sizeof (struct pdr_ext),
4214 sizeof (struct sym_ext),
4215 sizeof (struct opt_ext),
4216 sizeof (struct fdr_ext),
4217 sizeof (struct rfd_ext),
4218 sizeof (struct ext_ext),
4219 /* Functions to swap in external symbolic data. */
4220 ecoff_swap_hdr_in,
4221 ecoff_swap_dnr_in,
4222 ecoff_swap_pdr_in,
4223 ecoff_swap_sym_in,
4224 ecoff_swap_opt_in,
4225 ecoff_swap_fdr_in,
4226 ecoff_swap_rfd_in,
4227 ecoff_swap_ext_in,
4228 _bfd_ecoff_swap_tir_in,
4229 _bfd_ecoff_swap_rndx_in,
4230 /* Functions to swap out external symbolic data. */
4231 ecoff_swap_hdr_out,
4232 ecoff_swap_dnr_out,
4233 ecoff_swap_pdr_out,
4234 ecoff_swap_sym_out,
4235 ecoff_swap_opt_out,
4236 ecoff_swap_fdr_out,
4237 ecoff_swap_rfd_out,
4238 ecoff_swap_ext_out,
4239 _bfd_ecoff_swap_tir_out,
4240 _bfd_ecoff_swap_rndx_out,
4241 /* Function to read in symbolic data. */
4242 elf64_alpha_read_ecoff_info
4243};
4244\f
70bcb145
JW
4245/* Use a non-standard hash bucket size of 8. */
4246
4247const struct elf_size_info alpha_elf_size_info =
4248{
4249 sizeof (Elf64_External_Ehdr),
4250 sizeof (Elf64_External_Phdr),
4251 sizeof (Elf64_External_Shdr),
4252 sizeof (Elf64_External_Rel),
4253 sizeof (Elf64_External_Rela),
4254 sizeof (Elf64_External_Sym),
4255 sizeof (Elf64_External_Dyn),
4256 sizeof (Elf_External_Note),
4257 8,
4258 1,
4259 64, 8,
4260 ELFCLASS64, EV_CURRENT,
4261 bfd_elf64_write_out_phdrs,
4262 bfd_elf64_write_shdrs_and_ehdr,
4263 bfd_elf64_write_relocs,
4264 bfd_elf64_swap_symbol_out,
4265 bfd_elf64_slurp_reloc_table,
4266 bfd_elf64_slurp_symbol_table,
4267 bfd_elf64_swap_dyn_in,
4268 bfd_elf64_swap_dyn_out,
4269 NULL,
4270 NULL,
4271 NULL,
4272 NULL
4273};
4274
252b5132
RH
4275#define TARGET_LITTLE_SYM bfd_elf64_alpha_vec
4276#define TARGET_LITTLE_NAME "elf64-alpha"
4277#define ELF_ARCH bfd_arch_alpha
56fc028e
AJ
4278#define ELF_MACHINE_CODE EM_ALPHA
4279#define ELF_MAXPAGESIZE 0x10000
252b5132
RH
4280
4281#define bfd_elf64_bfd_link_hash_table_create \
4282 elf64_alpha_bfd_link_hash_table_create
4283
4284#define bfd_elf64_bfd_reloc_type_lookup \
4285 elf64_alpha_bfd_reloc_type_lookup
4286#define elf_info_to_howto \
4287 elf64_alpha_info_to_howto
4288
4289#define bfd_elf64_mkobject \
4290 elf64_alpha_mkobject
4291#define elf_backend_object_p \
4292 elf64_alpha_object_p
4293
4294#define elf_backend_section_from_shdr \
4295 elf64_alpha_section_from_shdr
204692d7
RH
4296#define elf_backend_section_flags \
4297 elf64_alpha_section_flags
252b5132
RH
4298#define elf_backend_fake_sections \
4299 elf64_alpha_fake_sections
4300
4301#define bfd_elf64_bfd_is_local_label_name \
4302 elf64_alpha_is_local_label_name
4303#define bfd_elf64_find_nearest_line \
4304 elf64_alpha_find_nearest_line
4305#define bfd_elf64_bfd_relax_section \
4306 elf64_alpha_relax_section
4307
4308#define elf_backend_add_symbol_hook \
4309 elf64_alpha_add_symbol_hook
4310#define elf_backend_check_relocs \
4311 elf64_alpha_check_relocs
4312#define elf_backend_create_dynamic_sections \
4313 elf64_alpha_create_dynamic_sections
4314#define elf_backend_adjust_dynamic_symbol \
4315 elf64_alpha_adjust_dynamic_symbol
4316#define elf_backend_always_size_sections \
4317 elf64_alpha_always_size_sections
4318#define elf_backend_size_dynamic_sections \
4319 elf64_alpha_size_dynamic_sections
4320#define elf_backend_relocate_section \
4321 elf64_alpha_relocate_section
4322#define elf_backend_finish_dynamic_symbol \
4323 elf64_alpha_finish_dynamic_symbol
4324#define elf_backend_finish_dynamic_sections \
4325 elf64_alpha_finish_dynamic_sections
4326#define bfd_elf64_bfd_final_link \
4327 elf64_alpha_final_link
fcfbdf31
JJ
4328#define elf_backend_reloc_type_class \
4329 elf64_alpha_reloc_type_class
252b5132
RH
4330
4331#define elf_backend_ecoff_debug_swap \
4332 &elf64_alpha_ecoff_debug_swap
4333
70bcb145
JW
4334#define elf_backend_size_info \
4335 alpha_elf_size_info
4336
38b1a46c 4337/* A few constants that determine how the .plt section is set up. */
252b5132
RH
4338#define elf_backend_want_got_plt 0
4339#define elf_backend_plt_readonly 0
4340#define elf_backend_want_plt_sym 1
4341#define elf_backend_got_header_size 0
4342#define elf_backend_plt_header_size PLT_HEADER_SIZE
4343
4344#include "elf64-target.h"
This page took 0.350899 seconds and 4 git commands to generate.