Coverage Report

Created: 2025-06-24 06:45

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