Coverage Report

Created: 2023-08-28 06:26

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