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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [elf64-alpha.c] - Blame information for rev 294

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

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

powered by: WebSVN 2.1.0

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