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