OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf64-alpha.c] - Blame information for rev 139

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.