OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

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
  const char *rel_sec_name;
1752
  Elf_Internal_Shdr *symtab_hdr;
1753
  struct alpha_elf_link_hash_entry **sym_hashes;
1754
  const Elf_Internal_Rela *rel, *relend;
1755
  bfd_size_type amt;
1756
 
1757
  if (info->relocatable)
1758
    return TRUE;
1759
 
1760
  /* Don't do anything special with non-loaded, non-alloced sections.
1761
     In particular, any relocs in such sections should not affect GOT
1762
     and PLT reference counting (ie. we don't allow them to create GOT
1763
     or PLT entries), there's no possibility or desire to optimize TLS
1764
     relocs, and there's not much point in propagating relocs to shared
1765
     libs that the dynamic linker won't relocate.  */
1766
  if ((sec->flags & SEC_ALLOC) == 0)
1767
    return TRUE;
1768
 
1769
  BFD_ASSERT (is_alpha_elf (abfd));
1770
 
1771
  dynobj = elf_hash_table (info)->dynobj;
1772
  if (dynobj == NULL)
1773
    elf_hash_table (info)->dynobj = dynobj = abfd;
1774
 
1775
  sreloc = NULL;
1776
  rel_sec_name = NULL;
1777
  symtab_hdr = &elf_symtab_hdr (abfd);
1778
  sym_hashes = alpha_elf_sym_hashes (abfd);
1779
 
1780
  relend = relocs + sec->reloc_count;
1781
  for (rel = relocs; rel < relend; ++rel)
1782
    {
1783
      enum {
1784
        NEED_GOT = 1,
1785
        NEED_GOT_ENTRY = 2,
1786
        NEED_DYNREL = 4
1787
      };
1788
 
1789
      unsigned long r_symndx, r_type;
1790
      struct alpha_elf_link_hash_entry *h;
1791
      unsigned int gotent_flags;
1792
      bfd_boolean maybe_dynamic;
1793
      unsigned int need;
1794
      bfd_vma addend;
1795
 
1796
      r_symndx = ELF64_R_SYM (rel->r_info);
1797
      if (r_symndx < symtab_hdr->sh_info)
1798
        h = NULL;
1799
      else
1800
        {
1801
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1802
 
1803
          while (h->root.root.type == bfd_link_hash_indirect
1804
                 || h->root.root.type == bfd_link_hash_warning)
1805
            h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
1806
 
1807
          h->root.ref_regular = 1;
1808
        }
1809
 
1810
      /* We can only get preliminary data on whether a symbol is
1811
         locally or externally defined, as not all of the input files
1812
         have yet been processed.  Do something with what we know, as
1813
         this may help reduce memory usage and processing time later.  */
1814
      maybe_dynamic = FALSE;
1815
      if (h && ((info->shared
1816
                 && (!info->symbolic
1817
                     || info->unresolved_syms_in_shared_libs == RM_IGNORE))
1818
                || !h->root.def_regular
1819
                || h->root.root.type == bfd_link_hash_defweak))
1820
        maybe_dynamic = TRUE;
1821
 
1822
      need = 0;
1823
      gotent_flags = 0;
1824
      r_type = ELF64_R_TYPE (rel->r_info);
1825
      addend = rel->r_addend;
1826
 
1827
      switch (r_type)
1828
        {
1829
        case R_ALPHA_LITERAL:
1830
          need = NEED_GOT | NEED_GOT_ENTRY;
1831
 
1832
          /* Remember how this literal is used from its LITUSEs.
1833
             This will be important when it comes to decide if we can
1834
             create a .plt entry for a function symbol.  */
1835
          while (++rel < relend && ELF64_R_TYPE (rel->r_info) == R_ALPHA_LITUSE)
1836
            if (rel->r_addend >= 1 && rel->r_addend <= 6)
1837
              gotent_flags |= 1 << rel->r_addend;
1838
          --rel;
1839
 
1840
          /* No LITUSEs -- presumably the address is used somehow.  */
1841
          if (gotent_flags == 0)
1842
            gotent_flags = ALPHA_ELF_LINK_HASH_LU_ADDR;
1843
          break;
1844
 
1845
        case R_ALPHA_GPDISP:
1846
        case R_ALPHA_GPREL16:
1847
        case R_ALPHA_GPREL32:
1848
        case R_ALPHA_GPRELHIGH:
1849
        case R_ALPHA_GPRELLOW:
1850
        case R_ALPHA_BRSGP:
1851
          need = NEED_GOT;
1852
          break;
1853
 
1854
        case R_ALPHA_REFLONG:
1855
        case R_ALPHA_REFQUAD:
1856
          if (info->shared || maybe_dynamic)
1857
            need = NEED_DYNREL;
1858
          break;
1859
 
1860
        case R_ALPHA_TLSLDM:
1861
          /* The symbol for a TLSLDM reloc is ignored.  Collapse the
1862
             reloc to the 0 symbol so that they all match.  */
1863
          r_symndx = 0;
1864
          h = 0;
1865
          maybe_dynamic = FALSE;
1866
          /* FALLTHRU */
1867
 
1868
        case R_ALPHA_TLSGD:
1869
        case R_ALPHA_GOTDTPREL:
1870
          need = NEED_GOT | NEED_GOT_ENTRY;
1871
          break;
1872
 
1873
        case R_ALPHA_GOTTPREL:
1874
          need = NEED_GOT | NEED_GOT_ENTRY;
1875
          gotent_flags = ALPHA_ELF_LINK_HASH_TLS_IE;
1876
          if (info->shared)
1877
            info->flags |= DF_STATIC_TLS;
1878
          break;
1879
 
1880
        case R_ALPHA_TPREL64:
1881
          if (info->shared || maybe_dynamic)
1882
            need = NEED_DYNREL;
1883
          if (info->shared)
1884
            info->flags |= DF_STATIC_TLS;
1885
          break;
1886
        }
1887
 
1888
      if (need & NEED_GOT)
1889
        {
1890
          if (alpha_elf_tdata(abfd)->gotobj == NULL)
1891
            {
1892
              if (!elf64_alpha_create_got_section (abfd, info))
1893
                return FALSE;
1894
            }
1895
        }
1896
 
1897
      if (need & NEED_GOT_ENTRY)
1898
        {
1899
          struct alpha_elf_got_entry *gotent;
1900
 
1901
          gotent = get_got_entry (abfd, h, r_type, r_symndx, addend);
1902
          if (!gotent)
1903
            return FALSE;
1904
 
1905
          if (gotent_flags)
1906
            {
1907
              gotent->flags |= gotent_flags;
1908
              if (h)
1909
                {
1910
                  gotent_flags |= h->flags;
1911
                  h->flags = gotent_flags;
1912
 
1913
                  /* Make a guess as to whether a .plt entry is needed.  */
1914
                  /* ??? It appears that we won't make it into
1915
                     adjust_dynamic_symbol for symbols that remain
1916
                     totally undefined.  Copying this check here means
1917
                     we can create a plt entry for them too.  */
1918
                  h->root.needs_plt
1919
                    = (maybe_dynamic && elf64_alpha_want_plt (h));
1920
                }
1921
            }
1922
        }
1923
 
1924
      if (need & NEED_DYNREL)
1925
        {
1926
          if (rel_sec_name == NULL)
1927
            {
1928
              rel_sec_name = (bfd_elf_string_from_elf_section
1929
                              (abfd, elf_elfheader(abfd)->e_shstrndx,
1930
                               elf_section_data(sec)->rel_hdr.sh_name));
1931
              if (rel_sec_name == NULL)
1932
                return FALSE;
1933
 
1934
              BFD_ASSERT (CONST_STRNEQ (rel_sec_name, ".rela")
1935
                          && strcmp (bfd_get_section_name (abfd, sec),
1936
                                     rel_sec_name+5) == 0);
1937
            }
1938
 
1939
          /* We need to create the section here now whether we eventually
1940
             use it or not so that it gets mapped to an output section by
1941
             the linker.  If not used, we'll kill it in
1942
             size_dynamic_sections.  */
1943
          if (sreloc == NULL)
1944
            {
1945
              sreloc = bfd_get_section_by_name (dynobj, rel_sec_name);
1946
              if (sreloc == NULL)
1947
                {
1948
                  flagword flags;
1949
 
1950
                  flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
1951
                           | SEC_LINKER_CREATED | SEC_READONLY);
1952
                  if (sec->flags & SEC_ALLOC)
1953
                    flags |= SEC_ALLOC | SEC_LOAD;
1954
                  sreloc = bfd_make_section_with_flags (dynobj,
1955
                                                        rel_sec_name,
1956
                                                        flags);
1957
                  if (sreloc == NULL
1958
                      || !bfd_set_section_alignment (dynobj, sreloc, 3))
1959
                    return FALSE;
1960
                }
1961
            }
1962
 
1963
          if (h)
1964
            {
1965
              /* Since we havn't seen all of the input symbols yet, we
1966
                 don't know whether we'll actually need a dynamic relocation
1967
                 entry for this reloc.  So make a record of it.  Once we
1968
                 find out if this thing needs dynamic relocation we'll
1969
                 expand the relocation sections by the appropriate amount.  */
1970
 
1971
              struct alpha_elf_reloc_entry *rent;
1972
 
1973
              for (rent = h->reloc_entries; rent; rent = rent->next)
1974
                if (rent->rtype == r_type && rent->srel == sreloc)
1975
                  break;
1976
 
1977
              if (!rent)
1978
                {
1979
                  amt = sizeof (struct alpha_elf_reloc_entry);
1980
                  rent = (struct alpha_elf_reloc_entry *) bfd_alloc (abfd, amt);
1981
                  if (!rent)
1982
                    return FALSE;
1983
 
1984
                  rent->srel = sreloc;
1985
                  rent->rtype = r_type;
1986
                  rent->count = 1;
1987
                  rent->reltext = (sec->flags & SEC_READONLY) != 0;
1988
 
1989
                  rent->next = h->reloc_entries;
1990
                  h->reloc_entries = rent;
1991
                }
1992
              else
1993
                rent->count++;
1994
            }
1995
          else if (info->shared)
1996
            {
1997
              /* If this is a shared library, and the section is to be
1998
                 loaded into memory, we need a RELATIVE reloc.  */
1999
              sreloc->size += sizeof (Elf64_External_Rela);
2000
              if (sec->flags & SEC_READONLY)
2001
                info->flags |= DF_TEXTREL;
2002
            }
2003
        }
2004
    }
2005
 
2006
  return TRUE;
2007
}
2008
 
2009
/* Adjust a symbol defined by a dynamic object and referenced by a
2010
   regular object.  The current definition is in some section of the
2011
   dynamic object, but we're not including those sections.  We have to
2012
   change the definition to something the rest of the link can
2013
   understand.  */
2014
 
2015
static bfd_boolean
2016
elf64_alpha_adjust_dynamic_symbol (struct bfd_link_info *info,
2017
                                   struct elf_link_hash_entry *h)
2018
{
2019
  bfd *dynobj;
2020
  asection *s;
2021
  struct alpha_elf_link_hash_entry *ah;
2022
 
2023
  dynobj = elf_hash_table(info)->dynobj;
2024
  ah = (struct alpha_elf_link_hash_entry *)h;
2025
 
2026
  /* Now that we've seen all of the input symbols, finalize our decision
2027
     about whether this symbol should get a .plt entry.  Irritatingly, it
2028
     is common for folk to leave undefined symbols in shared libraries,
2029
     and they still expect lazy binding; accept undefined symbols in lieu
2030
     of STT_FUNC.  */
2031
  if (alpha_elf_dynamic_symbol_p (h, info) && elf64_alpha_want_plt (ah))
2032
    {
2033
      h->needs_plt = TRUE;
2034
 
2035
      s = bfd_get_section_by_name(dynobj, ".plt");
2036
      if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
2037
        return FALSE;
2038
 
2039
      /* We need one plt entry per got subsection.  Delay allocation of
2040
         the actual plt entries until size_plt_section, called from
2041
         size_dynamic_sections or during relaxation.  */
2042
 
2043
      return TRUE;
2044
    }
2045
  else
2046
    h->needs_plt = FALSE;
2047
 
2048
  /* If this is a weak symbol, and there is a real definition, the
2049
     processor independent code will have arranged for us to see the
2050
     real definition first, and we can just use the same value.  */
2051
  if (h->u.weakdef != NULL)
2052
    {
2053
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2054
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
2055
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
2056
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
2057
      return TRUE;
2058
    }
2059
 
2060
  /* This is a reference to a symbol defined by a dynamic object which
2061
     is not a function.  The Alpha, since it uses .got entries for all
2062
     symbols even in regular objects, does not need the hackery of a
2063
     .dynbss section and COPY dynamic relocations.  */
2064
 
2065
  return TRUE;
2066
}
2067
 
2068
/* Record STO_ALPHA_NOPV and STO_ALPHA_STD_GPLOAD.  */
2069
 
2070
static void
2071
elf64_alpha_merge_symbol_attribute (struct elf_link_hash_entry *h,
2072
                                    const Elf_Internal_Sym *isym,
2073
                                    bfd_boolean definition,
2074
                                    bfd_boolean dynamic)
2075
{
2076
  if (!dynamic && definition)
2077
    h->other = ((h->other & ELF_ST_VISIBILITY (-1))
2078
                | (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
2079
}
2080
 
2081
/* Symbol versioning can create new symbols, and make our old symbols
2082
   indirect to the new ones.  Consolidate the got and reloc information
2083
   in these situations.  */
2084
 
2085
static bfd_boolean
2086
elf64_alpha_merge_ind_symbols (struct alpha_elf_link_hash_entry *hi,
2087
                               PTR dummy ATTRIBUTE_UNUSED)
2088
{
2089
  struct alpha_elf_link_hash_entry *hs;
2090
 
2091
  if (hi->root.root.type != bfd_link_hash_indirect)
2092
    return TRUE;
2093
  hs = hi;
2094
  do {
2095
    hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link;
2096
  } while (hs->root.root.type == bfd_link_hash_indirect);
2097
 
2098
  /* Merge the flags.  Whee.  */
2099
 
2100
  hs->flags |= hi->flags;
2101
 
2102
  /* Merge the .got entries.  Cannibalize the old symbol's list in
2103
     doing so, since we don't need it anymore.  */
2104
 
2105
  if (hs->got_entries == NULL)
2106
    hs->got_entries = hi->got_entries;
2107
  else
2108
    {
2109
      struct alpha_elf_got_entry *gi, *gs, *gin, *gsh;
2110
 
2111
      gsh = hs->got_entries;
2112
      for (gi = hi->got_entries; gi ; gi = gin)
2113
        {
2114
          gin = gi->next;
2115
          for (gs = gsh; gs ; gs = gs->next)
2116
            if (gi->gotobj == gs->gotobj
2117
                && gi->reloc_type == gs->reloc_type
2118
                && gi->addend == gs->addend)
2119
              {
2120
                gi->use_count += gs->use_count;
2121
                goto got_found;
2122
              }
2123
          gi->next = hs->got_entries;
2124
          hs->got_entries = gi;
2125
        got_found:;
2126
        }
2127
    }
2128
  hi->got_entries = NULL;
2129
 
2130
  /* And similar for the reloc entries.  */
2131
 
2132
  if (hs->reloc_entries == NULL)
2133
    hs->reloc_entries = hi->reloc_entries;
2134
  else
2135
    {
2136
      struct alpha_elf_reloc_entry *ri, *rs, *rin, *rsh;
2137
 
2138
      rsh = hs->reloc_entries;
2139
      for (ri = hi->reloc_entries; ri ; ri = rin)
2140
        {
2141
          rin = ri->next;
2142
          for (rs = rsh; rs ; rs = rs->next)
2143
            if (ri->rtype == rs->rtype && ri->srel == rs->srel)
2144
              {
2145
                rs->count += ri->count;
2146
                goto found_reloc;
2147
              }
2148
          ri->next = hs->reloc_entries;
2149
          hs->reloc_entries = ri;
2150
        found_reloc:;
2151
        }
2152
    }
2153
  hi->reloc_entries = NULL;
2154
 
2155
  return TRUE;
2156
}
2157
 
2158
/* Is it possible to merge two object file's .got tables?  */
2159
 
2160
static bfd_boolean
2161
elf64_alpha_can_merge_gots (bfd *a, bfd *b)
2162
{
2163
  int total = alpha_elf_tdata (a)->total_got_size;
2164
  bfd *bsub;
2165
 
2166
  /* Trivial quick fallout test.  */
2167
  if (total + alpha_elf_tdata (b)->total_got_size <= MAX_GOT_SIZE)
2168
    return TRUE;
2169
 
2170
  /* By their nature, local .got entries cannot be merged.  */
2171
  if ((total += alpha_elf_tdata (b)->local_got_size) > MAX_GOT_SIZE)
2172
    return FALSE;
2173
 
2174
  /* Failing the common trivial comparison, we must effectively
2175
     perform the merge.  Not actually performing the merge means that
2176
     we don't have to store undo information in case we fail.  */
2177
  for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
2178
    {
2179
      struct alpha_elf_link_hash_entry **hashes = alpha_elf_sym_hashes (bsub);
2180
      Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
2181
      int i, n;
2182
 
2183
      n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
2184
      for (i = 0; i < n; ++i)
2185
        {
2186
          struct alpha_elf_got_entry *ae, *be;
2187
          struct alpha_elf_link_hash_entry *h;
2188
 
2189
          h = hashes[i];
2190
          while (h->root.root.type == bfd_link_hash_indirect
2191
                 || h->root.root.type == bfd_link_hash_warning)
2192
            h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
2193
 
2194
          for (be = h->got_entries; be ; be = be->next)
2195
            {
2196
              if (be->use_count == 0)
2197
                continue;
2198
              if (be->gotobj != b)
2199
                continue;
2200
 
2201
              for (ae = h->got_entries; ae ; ae = ae->next)
2202
                if (ae->gotobj == a
2203
                    && ae->reloc_type == be->reloc_type
2204
                    && ae->addend == be->addend)
2205
                  goto global_found;
2206
 
2207
              total += alpha_got_entry_size (be->reloc_type);
2208
              if (total > MAX_GOT_SIZE)
2209
                return FALSE;
2210
            global_found:;
2211
            }
2212
        }
2213
    }
2214
 
2215
  return TRUE;
2216
}
2217
 
2218
/* Actually merge two .got tables.  */
2219
 
2220
static void
2221
elf64_alpha_merge_gots (bfd *a, bfd *b)
2222
{
2223
  int total = alpha_elf_tdata (a)->total_got_size;
2224
  bfd *bsub;
2225
 
2226
  /* Remember local expansion.  */
2227
  {
2228
    int e = alpha_elf_tdata (b)->local_got_size;
2229
    total += e;
2230
    alpha_elf_tdata (a)->local_got_size += e;
2231
  }
2232
 
2233
  for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
2234
    {
2235
      struct alpha_elf_got_entry **local_got_entries;
2236
      struct alpha_elf_link_hash_entry **hashes;
2237
      Elf_Internal_Shdr *symtab_hdr;
2238
      int i, n;
2239
 
2240
      /* Let the local .got entries know they are part of a new subsegment.  */
2241
      local_got_entries = alpha_elf_tdata (bsub)->local_got_entries;
2242
      if (local_got_entries)
2243
        {
2244
          n = elf_tdata (bsub)->symtab_hdr.sh_info;
2245
          for (i = 0; i < n; ++i)
2246
            {
2247
              struct alpha_elf_got_entry *ent;
2248
              for (ent = local_got_entries[i]; ent; ent = ent->next)
2249
                ent->gotobj = a;
2250
            }
2251
        }
2252
 
2253
      /* Merge the global .got entries.  */
2254
      hashes = alpha_elf_sym_hashes (bsub);
2255
      symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
2256
 
2257
      n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
2258
      for (i = 0; i < n; ++i)
2259
        {
2260
          struct alpha_elf_got_entry *ae, *be, **pbe, **start;
2261
          struct alpha_elf_link_hash_entry *h;
2262
 
2263
          h = hashes[i];
2264
          while (h->root.root.type == bfd_link_hash_indirect
2265
                 || h->root.root.type == bfd_link_hash_warning)
2266
            h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
2267
 
2268
          pbe = start = &h->got_entries;
2269
          while ((be = *pbe) != NULL)
2270
            {
2271
              if (be->use_count == 0)
2272
                {
2273
                  *pbe = be->next;
2274
                  memset (be, 0xa5, sizeof (*be));
2275
                  goto kill;
2276
                }
2277
              if (be->gotobj != b)
2278
                goto next;
2279
 
2280
              for (ae = *start; ae ; ae = ae->next)
2281
                if (ae->gotobj == a
2282
                    && ae->reloc_type == be->reloc_type
2283
                    && ae->addend == be->addend)
2284
                  {
2285
                    ae->flags |= be->flags;
2286
                    ae->use_count += be->use_count;
2287
                    *pbe = be->next;
2288
                    memset (be, 0xa5, sizeof (*be));
2289
                    goto kill;
2290
                  }
2291
              be->gotobj = a;
2292
              total += alpha_got_entry_size (be->reloc_type);
2293
 
2294
            next:;
2295
              pbe = &be->next;
2296
            kill:;
2297
            }
2298
        }
2299
 
2300
      alpha_elf_tdata (bsub)->gotobj = a;
2301
    }
2302
  alpha_elf_tdata (a)->total_got_size = total;
2303
 
2304
  /* Merge the two in_got chains.  */
2305
  {
2306
    bfd *next;
2307
 
2308
    bsub = a;
2309
    while ((next = alpha_elf_tdata (bsub)->in_got_link_next) != NULL)
2310
      bsub = next;
2311
 
2312
    alpha_elf_tdata (bsub)->in_got_link_next = b;
2313
  }
2314
}
2315
 
2316
/* Calculate the offsets for the got entries.  */
2317
 
2318
static bfd_boolean
2319
elf64_alpha_calc_got_offsets_for_symbol (struct alpha_elf_link_hash_entry *h,
2320
                                         PTR arg ATTRIBUTE_UNUSED)
2321
{
2322
  struct alpha_elf_got_entry *gotent;
2323
 
2324
  if (h->root.root.type == bfd_link_hash_warning)
2325
    h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
2326
 
2327
  for (gotent = h->got_entries; gotent; gotent = gotent->next)
2328
    if (gotent->use_count > 0)
2329
      {
2330
        struct alpha_elf_obj_tdata *td;
2331
        bfd_size_type *plge;
2332
 
2333
        td = alpha_elf_tdata (gotent->gotobj);
2334
        plge = &td->got->size;
2335
        gotent->got_offset = *plge;
2336
        *plge += alpha_got_entry_size (gotent->reloc_type);
2337
      }
2338
 
2339
  return TRUE;
2340
}
2341
 
2342
static void
2343
elf64_alpha_calc_got_offsets (struct bfd_link_info *info)
2344
{
2345
  bfd *i, *got_list = alpha_elf_hash_table(info)->got_list;
2346
 
2347
  /* First, zero out the .got sizes, as we may be recalculating the
2348
     .got after optimizing it.  */
2349
  for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
2350
    alpha_elf_tdata(i)->got->size = 0;
2351
 
2352
  /* Next, fill in the offsets for all the global entries.  */
2353
  alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2354
                                elf64_alpha_calc_got_offsets_for_symbol,
2355
                                NULL);
2356
 
2357
  /* Finally, fill in the offsets for the local entries.  */
2358
  for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
2359
    {
2360
      bfd_size_type got_offset = alpha_elf_tdata(i)->got->size;
2361
      bfd *j;
2362
 
2363
      for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
2364
        {
2365
          struct alpha_elf_got_entry **local_got_entries, *gotent;
2366
          int k, n;
2367
 
2368
          local_got_entries = alpha_elf_tdata(j)->local_got_entries;
2369
          if (!local_got_entries)
2370
            continue;
2371
 
2372
          for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
2373
            for (gotent = local_got_entries[k]; gotent; gotent = gotent->next)
2374
              if (gotent->use_count > 0)
2375
                {
2376
                  gotent->got_offset = got_offset;
2377
                  got_offset += alpha_got_entry_size (gotent->reloc_type);
2378
                }
2379
        }
2380
 
2381
      alpha_elf_tdata(i)->got->size = got_offset;
2382
    }
2383
}
2384
 
2385
/* Constructs the gots.  */
2386
 
2387
static bfd_boolean
2388
elf64_alpha_size_got_sections (struct bfd_link_info *info)
2389
{
2390
  bfd *i, *got_list, *cur_got_obj = NULL;
2391
 
2392
  got_list = alpha_elf_hash_table (info)->got_list;
2393
 
2394
  /* On the first time through, pretend we have an existing got list
2395
     consisting of all of the input files.  */
2396
  if (got_list == NULL)
2397
    {
2398
      for (i = info->input_bfds; i ; i = i->link_next)
2399
        {
2400
          bfd *this_got;
2401
 
2402
          if (! is_alpha_elf (i))
2403
            continue;
2404
 
2405
          this_got = alpha_elf_tdata (i)->gotobj;
2406
          if (this_got == NULL)
2407
            continue;
2408
 
2409
          /* We are assuming no merging has yet occurred.  */
2410
          BFD_ASSERT (this_got == i);
2411
 
2412
          if (alpha_elf_tdata (this_got)->total_got_size > MAX_GOT_SIZE)
2413
            {
2414
              /* Yikes! A single object file has too many entries.  */
2415
              (*_bfd_error_handler)
2416
                (_("%B: .got subsegment exceeds 64K (size %d)"),
2417
                 i, alpha_elf_tdata (this_got)->total_got_size);
2418
              return FALSE;
2419
            }
2420
 
2421
          if (got_list == NULL)
2422
            got_list = this_got;
2423
          else
2424
            alpha_elf_tdata(cur_got_obj)->got_link_next = this_got;
2425
          cur_got_obj = this_got;
2426
        }
2427
 
2428
      /* Strange degenerate case of no got references.  */
2429
      if (got_list == NULL)
2430
        return TRUE;
2431
 
2432
      alpha_elf_hash_table (info)->got_list = got_list;
2433
    }
2434
 
2435
  cur_got_obj = got_list;
2436
  if (cur_got_obj == NULL)
2437
    return FALSE;
2438
 
2439
  i = alpha_elf_tdata(cur_got_obj)->got_link_next;
2440
  while (i != NULL)
2441
    {
2442
      if (elf64_alpha_can_merge_gots (cur_got_obj, i))
2443
        {
2444
          elf64_alpha_merge_gots (cur_got_obj, i);
2445
 
2446
          alpha_elf_tdata(i)->got->size = 0;
2447
          i = alpha_elf_tdata(i)->got_link_next;
2448
          alpha_elf_tdata(cur_got_obj)->got_link_next = i;
2449
        }
2450
      else
2451
        {
2452
          cur_got_obj = i;
2453
          i = alpha_elf_tdata(i)->got_link_next;
2454
        }
2455
    }
2456
 
2457
  /* Once the gots have been merged, fill in the got offsets for
2458
     everything therein.  */
2459
  elf64_alpha_calc_got_offsets (info);
2460
 
2461
  return TRUE;
2462
}
2463
 
2464
static bfd_boolean
2465
elf64_alpha_size_plt_section_1 (struct alpha_elf_link_hash_entry *h, PTR data)
2466
{
2467
  asection *splt = (asection *) data;
2468
  struct alpha_elf_got_entry *gotent;
2469
  bfd_boolean saw_one = FALSE;
2470
 
2471
  /* If we didn't need an entry before, we still don't.  */
2472
  if (!h->root.needs_plt)
2473
    return TRUE;
2474
 
2475
  /* For each LITERAL got entry still in use, allocate a plt entry.  */
2476
  for (gotent = h->got_entries; gotent ; gotent = gotent->next)
2477
    if (gotent->reloc_type == R_ALPHA_LITERAL
2478
        && gotent->use_count > 0)
2479
      {
2480
        if (splt->size == 0)
2481
          splt->size = PLT_HEADER_SIZE;
2482
        gotent->plt_offset = splt->size;
2483
        splt->size += PLT_ENTRY_SIZE;
2484
        saw_one = TRUE;
2485
      }
2486
 
2487
  /* If there weren't any, there's no longer a need for the PLT entry.  */
2488
  if (!saw_one)
2489
    h->root.needs_plt = FALSE;
2490
 
2491
  return TRUE;
2492
}
2493
 
2494
/* Called from relax_section to rebuild the PLT in light of potential changes
2495
   in the function's status.  */
2496
 
2497
static void
2498
elf64_alpha_size_plt_section (struct bfd_link_info *info)
2499
{
2500
  asection *splt, *spltrel, *sgotplt;
2501
  unsigned long entries;
2502
  bfd *dynobj;
2503
 
2504
  dynobj = elf_hash_table(info)->dynobj;
2505
  splt = bfd_get_section_by_name (dynobj, ".plt");
2506
  if (splt == NULL)
2507
    return;
2508
 
2509
  splt->size = 0;
2510
 
2511
  alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2512
                                elf64_alpha_size_plt_section_1, splt);
2513
 
2514
  /* Every plt entry requires a JMP_SLOT relocation.  */
2515
  spltrel = bfd_get_section_by_name (dynobj, ".rela.plt");
2516
  entries = 0;
2517
  if (splt->size)
2518
    {
2519
      if (elf64_alpha_use_secureplt)
2520
        entries = (splt->size - NEW_PLT_HEADER_SIZE) / NEW_PLT_ENTRY_SIZE;
2521
      else
2522
        entries = (splt->size - OLD_PLT_HEADER_SIZE) / OLD_PLT_ENTRY_SIZE;
2523
    }
2524
  spltrel->size = entries * sizeof (Elf64_External_Rela);
2525
 
2526
  /* When using the secureplt, we need two words somewhere in the data
2527
     segment for the dynamic linker to tell us where to go.  This is the
2528
     entire contents of the .got.plt section.  */
2529
  if (elf64_alpha_use_secureplt)
2530
    {
2531
      sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
2532
      sgotplt->size = entries ? 16 : 0;
2533
    }
2534
}
2535
 
2536
static bfd_boolean
2537
elf64_alpha_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2538
                                  struct bfd_link_info *info)
2539
{
2540
  bfd *i;
2541
 
2542
  if (info->relocatable)
2543
    return TRUE;
2544
 
2545
  /* First, take care of the indirect symbols created by versioning.  */
2546
  alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2547
                                elf64_alpha_merge_ind_symbols,
2548
                                NULL);
2549
 
2550
  if (!elf64_alpha_size_got_sections (info))
2551
    return FALSE;
2552
 
2553
  /* Allocate space for all of the .got subsections.  */
2554
  i = alpha_elf_hash_table (info)->got_list;
2555
  for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
2556
    {
2557
      asection *s = alpha_elf_tdata(i)->got;
2558
      if (s->size > 0)
2559
        {
2560
          s->contents = (bfd_byte *) bfd_zalloc (i, s->size);
2561
          if (s->contents == NULL)
2562
            return FALSE;
2563
        }
2564
    }
2565
 
2566
  return TRUE;
2567
}
2568
 
2569
/* The number of dynamic relocations required by a static relocation.  */
2570
 
2571
static int
2572
alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared)
2573
{
2574
  switch (r_type)
2575
    {
2576
    /* May appear in GOT entries.  */
2577
    case R_ALPHA_TLSGD:
2578
      return (dynamic ? 2 : shared ? 1 : 0);
2579
    case R_ALPHA_TLSLDM:
2580
      return shared;
2581
    case R_ALPHA_LITERAL:
2582
    case R_ALPHA_GOTTPREL:
2583
      return dynamic || shared;
2584
    case R_ALPHA_GOTDTPREL:
2585
      return dynamic;
2586
 
2587
    /* May appear in data sections.  */
2588
    case R_ALPHA_REFLONG:
2589
    case R_ALPHA_REFQUAD:
2590
    case R_ALPHA_TPREL64:
2591
      return dynamic || shared;
2592
 
2593
    /* Everything else is illegal.  We'll issue an error during
2594
       relocate_section.  */
2595
    default:
2596
      return 0;
2597
    }
2598
}
2599
 
2600
/* Work out the sizes of the dynamic relocation entries.  */
2601
 
2602
static bfd_boolean
2603
elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h,
2604
                               struct bfd_link_info *info)
2605
{
2606
  bfd_boolean dynamic;
2607
  struct alpha_elf_reloc_entry *relent;
2608
  unsigned long entries;
2609
 
2610
  if (h->root.root.type == bfd_link_hash_warning)
2611
    h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
2612
 
2613
  /* If the symbol was defined as a common symbol in a regular object
2614
     file, and there was no definition in any dynamic object, then the
2615
     linker will have allocated space for the symbol in a common
2616
     section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been
2617
     set.  This is done for dynamic symbols in
2618
     elf_adjust_dynamic_symbol but this is not done for non-dynamic
2619
     symbols, somehow.  */
2620
  if (!h->root.def_regular
2621
      && h->root.ref_regular
2622
      && !h->root.def_dynamic
2623
      && (h->root.root.type == bfd_link_hash_defined
2624
          || h->root.root.type == bfd_link_hash_defweak)
2625
      && !(h->root.root.u.def.section->owner->flags & DYNAMIC))
2626
    h->root.def_regular = 1;
2627
 
2628
  /* If the symbol is dynamic, we'll need all the relocations in their
2629
     natural form.  If this is a shared object, and it has been forced
2630
     local, we'll need the same number of RELATIVE relocations.  */
2631
  dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
2632
 
2633
  /* If the symbol is a hidden undefined weak, then we never have any
2634
     relocations.  Avoid the loop which may want to add RELATIVE relocs
2635
     based on info->shared.  */
2636
  if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
2637
    return TRUE;
2638
 
2639
  for (relent = h->reloc_entries; relent; relent = relent->next)
2640
    {
2641
      entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
2642
                                                 info->shared);
2643
      if (entries)
2644
        {
2645
          relent->srel->size +=
2646
            entries * sizeof (Elf64_External_Rela) * relent->count;
2647
          if (relent->reltext)
2648
            info->flags |= DT_TEXTREL;
2649
        }
2650
    }
2651
 
2652
  return TRUE;
2653
}
2654
 
2655
/* Subroutine of elf64_alpha_size_rela_got_section for doing the
2656
   global symbols.  */
2657
 
2658
static bfd_boolean
2659
elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h,
2660
                             struct bfd_link_info *info)
2661
{
2662
  bfd_boolean dynamic;
2663
  struct alpha_elf_got_entry *gotent;
2664
  unsigned long entries;
2665
 
2666
  if (h->root.root.type == bfd_link_hash_warning)
2667
    h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
2668
 
2669
  /* If we're using a plt for this symbol, then all of its relocations
2670
     for its got entries go into .rela.plt.  */
2671
  if (h->root.needs_plt)
2672
    return TRUE;
2673
 
2674
  /* If the symbol is dynamic, we'll need all the relocations in their
2675
     natural form.  If this is a shared object, and it has been forced
2676
     local, we'll need the same number of RELATIVE relocations.  */
2677
  dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
2678
 
2679
  /* If the symbol is a hidden undefined weak, then we never have any
2680
     relocations.  Avoid the loop which may want to add RELATIVE relocs
2681
     based on info->shared.  */
2682
  if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
2683
    return TRUE;
2684
 
2685
  entries = 0;
2686
  for (gotent = h->got_entries; gotent ; gotent = gotent->next)
2687
    if (gotent->use_count > 0)
2688
      entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type,
2689
                                                  dynamic, info->shared);
2690
 
2691
  if (entries > 0)
2692
    {
2693
      bfd *dynobj = elf_hash_table(info)->dynobj;
2694
      asection *srel = bfd_get_section_by_name (dynobj, ".rela.got");
2695
      BFD_ASSERT (srel != NULL);
2696
      srel->size += sizeof (Elf64_External_Rela) * entries;
2697
    }
2698
 
2699
  return TRUE;
2700
}
2701
 
2702
/* Set the sizes of the dynamic relocation sections.  */
2703
 
2704
static void
2705
elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
2706
{
2707
  unsigned long entries;
2708
  bfd *i, *dynobj;
2709
  asection *srel;
2710
 
2711
  /* Shared libraries often require RELATIVE relocs, and some relocs
2712
     require attention for the main application as well.  */
2713
 
2714
  entries = 0;
2715
  for (i = alpha_elf_hash_table(info)->got_list;
2716
       i ; i = alpha_elf_tdata(i)->got_link_next)
2717
    {
2718
      bfd *j;
2719
 
2720
      for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
2721
        {
2722
          struct alpha_elf_got_entry **local_got_entries, *gotent;
2723
          int k, n;
2724
 
2725
          local_got_entries = alpha_elf_tdata(j)->local_got_entries;
2726
          if (!local_got_entries)
2727
            continue;
2728
 
2729
          for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
2730
            for (gotent = local_got_entries[k];
2731
                 gotent ; gotent = gotent->next)
2732
              if (gotent->use_count > 0)
2733
                entries += (alpha_dynamic_entries_for_reloc
2734
                            (gotent->reloc_type, 0, info->shared));
2735
        }
2736
    }
2737
 
2738
  dynobj = elf_hash_table(info)->dynobj;
2739
  srel = bfd_get_section_by_name (dynobj, ".rela.got");
2740
  if (!srel)
2741
    {
2742
      BFD_ASSERT (entries == 0);
2743
      return;
2744
    }
2745
  srel->size = sizeof (Elf64_External_Rela) * entries;
2746
 
2747
  /* Now do the non-local symbols.  */
2748
  alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2749
                                elf64_alpha_size_rela_got_1, info);
2750
}
2751
 
2752
/* Set the sizes of the dynamic sections.  */
2753
 
2754
static bfd_boolean
2755
elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2756
                                   struct bfd_link_info *info)
2757
{
2758
  bfd *dynobj;
2759
  asection *s;
2760
  bfd_boolean relplt;
2761
 
2762
  dynobj = elf_hash_table(info)->dynobj;
2763
  BFD_ASSERT(dynobj != NULL);
2764
 
2765
  if (elf_hash_table (info)->dynamic_sections_created)
2766
    {
2767
      /* Set the contents of the .interp section to the interpreter.  */
2768
      if (info->executable)
2769
        {
2770
          s = bfd_get_section_by_name (dynobj, ".interp");
2771
          BFD_ASSERT (s != NULL);
2772
          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2773
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2774
        }
2775
 
2776
      /* Now that we've seen all of the input files, we can decide which
2777
         symbols need dynamic relocation entries and which don't.  We've
2778
         collected information in check_relocs that we can now apply to
2779
         size the dynamic relocation sections.  */
2780
      alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
2781
                                    elf64_alpha_calc_dynrel_sizes, info);
2782
 
2783
      elf64_alpha_size_rela_got_section (info);
2784
      elf64_alpha_size_plt_section (info);
2785
    }
2786
  /* else we're not dynamic and by definition we don't need such things.  */
2787
 
2788
  /* The check_relocs and adjust_dynamic_symbol entry points have
2789
     determined the sizes of the various dynamic sections.  Allocate
2790
     memory for them.  */
2791
  relplt = FALSE;
2792
  for (s = dynobj->sections; s != NULL; s = s->next)
2793
    {
2794
      const char *name;
2795
 
2796
      if (!(s->flags & SEC_LINKER_CREATED))
2797
        continue;
2798
 
2799
      /* It's OK to base decisions on the section name, because none
2800
         of the dynobj section names depend upon the input files.  */
2801
      name = bfd_get_section_name (dynobj, s);
2802
 
2803
      if (CONST_STRNEQ (name, ".rela"))
2804
        {
2805
          if (s->size != 0)
2806
            {
2807
              if (strcmp (name, ".rela.plt") == 0)
2808
                relplt = TRUE;
2809
 
2810
              /* We use the reloc_count field as a counter if we need
2811
                 to copy relocs into the output file.  */
2812
              s->reloc_count = 0;
2813
            }
2814
        }
2815
      else if (! CONST_STRNEQ (name, ".got")
2816
               && strcmp (name, ".plt") != 0
2817
               && strcmp (name, ".dynbss") != 0)
2818
        {
2819
          /* It's not one of our dynamic sections, so don't allocate space.  */
2820
          continue;
2821
        }
2822
 
2823
      if (s->size == 0)
2824
        {
2825
          /* If we don't need this section, strip it from the output file.
2826
             This is to handle .rela.bss and .rela.plt.  We must create it
2827
             in create_dynamic_sections, because it must be created before
2828
             the linker maps input sections to output sections.  The
2829
             linker does that before adjust_dynamic_symbol is called, and
2830
             it is that function which decides whether anything needs to
2831
             go into these sections.  */
2832
          s->flags |= SEC_EXCLUDE;
2833
        }
2834
      else if ((s->flags & SEC_HAS_CONTENTS) != 0)
2835
        {
2836
          /* Allocate memory for the section contents.  */
2837
          s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2838
          if (s->contents == NULL)
2839
            return FALSE;
2840
        }
2841
    }
2842
 
2843
  if (elf_hash_table (info)->dynamic_sections_created)
2844
    {
2845
      /* Add some entries to the .dynamic section.  We fill in the
2846
         values later, in elf64_alpha_finish_dynamic_sections, but we
2847
         must add the entries now so that we get the correct size for
2848
         the .dynamic section.  The DT_DEBUG entry is filled in by the
2849
         dynamic linker and used by the debugger.  */
2850
#define add_dynamic_entry(TAG, VAL) \
2851
  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2852
 
2853
      if (info->executable)
2854
        {
2855
          if (!add_dynamic_entry (DT_DEBUG, 0))
2856
            return FALSE;
2857
        }
2858
 
2859
      if (relplt)
2860
        {
2861
          if (!add_dynamic_entry (DT_PLTGOT, 0)
2862
              || !add_dynamic_entry (DT_PLTRELSZ, 0)
2863
              || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2864
              || !add_dynamic_entry (DT_JMPREL, 0))
2865
            return FALSE;
2866
 
2867
          if (elf64_alpha_use_secureplt
2868
              && !add_dynamic_entry (DT_ALPHA_PLTRO, 1))
2869
            return FALSE;
2870
        }
2871
 
2872
      if (!add_dynamic_entry (DT_RELA, 0)
2873
          || !add_dynamic_entry (DT_RELASZ, 0)
2874
          || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
2875
        return FALSE;
2876
 
2877
      if (info->flags & DF_TEXTREL)
2878
        {
2879
          if (!add_dynamic_entry (DT_TEXTREL, 0))
2880
            return FALSE;
2881
        }
2882
    }
2883
#undef add_dynamic_entry
2884
 
2885
  return TRUE;
2886
}
2887
 
2888
/* These functions do relaxation for Alpha ELF.
2889
 
2890
   Currently I'm only handling what I can do with existing compiler
2891
   and assembler support, which means no instructions are removed,
2892
   though some may be nopped.  At this time GCC does not emit enough
2893
   information to do all of the relaxing that is possible.  It will
2894
   take some not small amount of work for that to happen.
2895
 
2896
   There are a couple of interesting papers that I once read on this
2897
   subject, that I cannot find references to at the moment, that
2898
   related to Alpha in particular.  They are by David Wall, then of
2899
   DEC WRL.  */
2900
 
2901
struct alpha_relax_info
2902
{
2903
  bfd *abfd;
2904
  asection *sec;
2905
  bfd_byte *contents;
2906
  Elf_Internal_Shdr *symtab_hdr;
2907
  Elf_Internal_Rela *relocs, *relend;
2908
  struct bfd_link_info *link_info;
2909
  bfd_vma gp;
2910
  bfd *gotobj;
2911
  asection *tsec;
2912
  struct alpha_elf_link_hash_entry *h;
2913
  struct alpha_elf_got_entry **first_gotent;
2914
  struct alpha_elf_got_entry *gotent;
2915
  bfd_boolean changed_contents;
2916
  bfd_boolean changed_relocs;
2917
  unsigned char other;
2918
};
2919
 
2920
static Elf_Internal_Rela *
2921
elf64_alpha_find_reloc_at_ofs (Elf_Internal_Rela *rel,
2922
                               Elf_Internal_Rela *relend,
2923
                               bfd_vma offset, int type)
2924
{
2925
  while (rel < relend)
2926
    {
2927
      if (rel->r_offset == offset
2928
          && ELF64_R_TYPE (rel->r_info) == (unsigned int) type)
2929
        return rel;
2930
      ++rel;
2931
    }
2932
  return NULL;
2933
}
2934
 
2935
static bfd_boolean
2936
elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
2937
                            Elf_Internal_Rela *irel, unsigned long r_type)
2938
{
2939
  unsigned int insn;
2940
  bfd_signed_vma disp;
2941
 
2942
  /* Get the instruction.  */
2943
  insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
2944
 
2945
  if (insn >> 26 != OP_LDQ)
2946
    {
2947
      reloc_howto_type *howto = elf64_alpha_howto_table + r_type;
2948
      ((*_bfd_error_handler)
2949
       ("%B: %A+0x%lx: warning: %s relocation against unexpected insn",
2950
        info->abfd, info->sec,
2951
        (unsigned long) irel->r_offset, howto->name));
2952
      return TRUE;
2953
    }
2954
 
2955
  /* Can't relax dynamic symbols.  */
2956
  if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
2957
    return TRUE;
2958
 
2959
  /* Can't use local-exec relocations in shared libraries.  */
2960
  if (r_type == R_ALPHA_GOTTPREL && info->link_info->shared)
2961
    return TRUE;
2962
 
2963
  if (r_type == R_ALPHA_LITERAL)
2964
    {
2965
      /* Look for nice constant addresses.  This includes the not-uncommon
2966
         special case of 0 for undefweak symbols.  */
2967
      if ((info->h && info->h->root.root.type == bfd_link_hash_undefweak)
2968
          || (!info->link_info->shared
2969
              && (symval >= (bfd_vma)-0x8000 || symval < 0x8000)))
2970
        {
2971
          disp = 0;
2972
          insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
2973
          insn |= (symval & 0xffff);
2974
          r_type = R_ALPHA_NONE;
2975
        }
2976
      else
2977
        {
2978
          disp = symval - info->gp;
2979
          insn = (OP_LDA << 26) | (insn & 0x03ff0000);
2980
          r_type = R_ALPHA_GPREL16;
2981
        }
2982
    }
2983
  else
2984
    {
2985
      bfd_vma dtp_base, tp_base;
2986
 
2987
      BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
2988
      dtp_base = alpha_get_dtprel_base (info->link_info);
2989
      tp_base = alpha_get_tprel_base (info->link_info);
2990
      disp = symval - (r_type == R_ALPHA_GOTDTPREL ? dtp_base : tp_base);
2991
 
2992
      insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
2993
 
2994
      switch (r_type)
2995
        {
2996
        case R_ALPHA_GOTDTPREL:
2997
          r_type = R_ALPHA_DTPREL16;
2998
          break;
2999
        case R_ALPHA_GOTTPREL:
3000
          r_type = R_ALPHA_TPREL16;
3001
          break;
3002
        default:
3003
          BFD_ASSERT (0);
3004
          return FALSE;
3005
        }
3006
    }
3007
 
3008
  if (disp < -0x8000 || disp >= 0x8000)
3009
    return TRUE;
3010
 
3011
  bfd_put_32 (info->abfd, (bfd_vma) insn, info->contents + irel->r_offset);
3012
  info->changed_contents = TRUE;
3013
 
3014
  /* Reduce the use count on this got entry by one, possibly
3015
     eliminating it.  */
3016
  if (--info->gotent->use_count == 0)
3017
    {
3018
      int sz = alpha_got_entry_size (r_type);
3019
      alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3020
      if (!info->h)
3021
        alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
3022
    }
3023
 
3024
  /* Smash the existing GOT relocation for its 16-bit immediate pair.  */
3025
  irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), r_type);
3026
  info->changed_relocs = TRUE;
3027
 
3028
  /* ??? Search forward through this basic block looking for insns
3029
     that use the target register.  Stop after an insn modifying the
3030
     register is seen, or after a branch or call.
3031
 
3032
     Any such memory load insn may be substituted by a load directly
3033
     off the GP.  This allows the memory load insn to be issued before
3034
     the calculated GP register would otherwise be ready.
3035
 
3036
     Any such jsr insn can be replaced by a bsr if it is in range.
3037
 
3038
     This would mean that we'd have to _add_ relocations, the pain of
3039
     which gives one pause.  */
3040
 
3041
  return TRUE;
3042
}
3043
 
3044
static bfd_vma
3045
elf64_alpha_relax_opt_call (struct alpha_relax_info *info, bfd_vma symval)
3046
{
3047
  /* If the function has the same gp, and we can identify that the
3048
     function does not use its function pointer, we can eliminate the
3049
     address load.  */
3050
 
3051
  /* If the symbol is marked NOPV, we are being told the function never
3052
     needs its procedure value.  */
3053
  if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV)
3054
    return symval;
3055
 
3056
  /* If the symbol is marked STD_GP, we are being told the function does
3057
     a normal ldgp in the first two words.  */
3058
  else if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD)
3059
    ;
3060
 
3061
  /* Otherwise, we may be able to identify a GP load in the first two
3062
     words, which we can then skip.  */
3063
  else
3064
    {
3065
      Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp;
3066
      bfd_vma ofs;
3067
 
3068
      /* Load the relocations from the section that the target symbol is in.  */
3069
      if (info->sec == info->tsec)
3070
        {
3071
          tsec_relocs = info->relocs;
3072
          tsec_relend = info->relend;
3073
          tsec_free = NULL;
3074
        }
3075
      else
3076
        {
3077
          tsec_relocs = (_bfd_elf_link_read_relocs
3078
                         (info->abfd, info->tsec, (PTR) NULL,
3079
                         (Elf_Internal_Rela *) NULL,
3080
                         info->link_info->keep_memory));
3081
          if (tsec_relocs == NULL)
3082
            return 0;
3083
          tsec_relend = tsec_relocs + info->tsec->reloc_count;
3084
          tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs);
3085
        }
3086
 
3087
      /* Recover the symbol's offset within the section.  */
3088
      ofs = (symval - info->tsec->output_section->vma
3089
             - info->tsec->output_offset);
3090
 
3091
      /* Look for a GPDISP reloc.  */
3092
      gpdisp = (elf64_alpha_find_reloc_at_ofs
3093
                (tsec_relocs, tsec_relend, ofs, R_ALPHA_GPDISP));
3094
 
3095
      if (!gpdisp || gpdisp->r_addend != 4)
3096
        {
3097
          if (tsec_free)
3098
            free (tsec_free);
3099
          return 0;
3100
        }
3101
      if (tsec_free)
3102
        free (tsec_free);
3103
    }
3104
 
3105
  /* We've now determined that we can skip an initial gp load.  Verify
3106
     that the call and the target use the same gp.   */
3107
  if (info->link_info->output_bfd->xvec != info->tsec->owner->xvec
3108
      || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
3109
    return 0;
3110
 
3111
  return symval + 8;
3112
}
3113
 
3114
static bfd_boolean
3115
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
3116
                               bfd_vma symval, Elf_Internal_Rela *irel)
3117
{
3118
  Elf_Internal_Rela *urel, *irelend = info->relend;
3119
  int flags, count, i;
3120
  bfd_signed_vma disp;
3121
  bfd_boolean fits16;
3122
  bfd_boolean fits32;
3123
  bfd_boolean lit_reused = FALSE;
3124
  bfd_boolean all_optimized = TRUE;
3125
  unsigned int lit_insn;
3126
 
3127
  lit_insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
3128
  if (lit_insn >> 26 != OP_LDQ)
3129
    {
3130
      ((*_bfd_error_handler)
3131
       ("%B: %A+0x%lx: warning: LITERAL relocation against unexpected insn",
3132
        info->abfd, info->sec,
3133
        (unsigned long) irel->r_offset));
3134
      return TRUE;
3135
    }
3136
 
3137
  /* Can't relax dynamic symbols.  */
3138
  if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
3139
    return TRUE;
3140
 
3141
  /* Summarize how this particular LITERAL is used.  */
3142
  for (urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count)
3143
    {
3144
      if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE)
3145
        break;
3146
      if (urel->r_addend <= 6)
3147
        flags |= 1 << urel->r_addend;
3148
    }
3149
 
3150
  /* A little preparation for the loop...  */
3151
  disp = symval - info->gp;
3152
 
3153
  for (urel = irel+1, i = 0; i < count; ++i, ++urel)
3154
    {
3155
      unsigned int insn;
3156
      int insn_disp;
3157
      bfd_signed_vma xdisp;
3158
 
3159
      insn = bfd_get_32 (info->abfd, info->contents + urel->r_offset);
3160
 
3161
      switch (urel->r_addend)
3162
        {
3163
        case LITUSE_ALPHA_ADDR:
3164
        default:
3165
          /* This type is really just a placeholder to note that all
3166
             uses cannot be optimized, but to still allow some.  */
3167
          all_optimized = FALSE;
3168
          break;
3169
 
3170
        case LITUSE_ALPHA_BASE:
3171
          /* We can always optimize 16-bit displacements.  */
3172
 
3173
          /* Extract the displacement from the instruction, sign-extending
3174
             it if necessary, then test whether it is within 16 or 32 bits
3175
             displacement from GP.  */
3176
          insn_disp = ((insn & 0xffff) ^ 0x8000) - 0x8000;
3177
 
3178
          xdisp = disp + insn_disp;
3179
          fits16 = (xdisp >= - (bfd_signed_vma) 0x8000 && xdisp < 0x8000);
3180
          fits32 = (xdisp >= - (bfd_signed_vma) 0x80000000
3181
                    && xdisp < 0x7fff8000);
3182
 
3183
          if (fits16)
3184
            {
3185
              /* Take the op code and dest from this insn, take the base
3186
                 register from the literal insn.  Leave the offset alone.  */
3187
              insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
3188
              urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3189
                                           R_ALPHA_GPREL16);
3190
              urel->r_addend = irel->r_addend;
3191
              info->changed_relocs = TRUE;
3192
 
3193
              bfd_put_32 (info->abfd, (bfd_vma) insn,
3194
                          info->contents + urel->r_offset);
3195
              info->changed_contents = TRUE;
3196
            }
3197
 
3198
          /* If all mem+byte, we can optimize 32-bit mem displacements.  */
3199
          else if (fits32 && !(flags & ~6))
3200
            {
3201
              /* FIXME: sanity check that lit insn Ra is mem insn Rb.  */
3202
 
3203
              irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3204
                                           R_ALPHA_GPRELHIGH);
3205
              lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
3206
              bfd_put_32 (info->abfd, (bfd_vma) lit_insn,
3207
                          info->contents + irel->r_offset);
3208
              lit_reused = TRUE;
3209
              info->changed_contents = TRUE;
3210
 
3211
              urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3212
                                           R_ALPHA_GPRELLOW);
3213
              urel->r_addend = irel->r_addend;
3214
              info->changed_relocs = TRUE;
3215
            }
3216
          else
3217
            all_optimized = FALSE;
3218
          break;
3219
 
3220
        case LITUSE_ALPHA_BYTOFF:
3221
          /* We can always optimize byte instructions.  */
3222
 
3223
          /* FIXME: sanity check the insn for byte op.  Check that the
3224
             literal dest reg is indeed Rb in the byte insn.  */
3225
 
3226
          insn &= ~ (unsigned) 0x001ff000;
3227
          insn |= ((symval & 7) << 13) | 0x1000;
3228
 
3229
          urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3230
          urel->r_addend = 0;
3231
          info->changed_relocs = TRUE;
3232
 
3233
          bfd_put_32 (info->abfd, (bfd_vma) insn,
3234
                      info->contents + urel->r_offset);
3235
          info->changed_contents = TRUE;
3236
          break;
3237
 
3238
        case LITUSE_ALPHA_JSR:
3239
        case LITUSE_ALPHA_TLSGD:
3240
        case LITUSE_ALPHA_TLSLDM:
3241
        case LITUSE_ALPHA_JSRDIRECT:
3242
          {
3243
            bfd_vma optdest, org;
3244
            bfd_signed_vma odisp;
3245
 
3246
            /* For undefined weak symbols, we're mostly interested in getting
3247
               rid of the got entry whenever possible, so optimize this to a
3248
               use of the zero register.  */
3249
            if (info->h && info->h->root.root.type == bfd_link_hash_undefweak)
3250
              {
3251
                insn |= 31 << 16;
3252
                bfd_put_32 (info->abfd, (bfd_vma) insn,
3253
                            info->contents + urel->r_offset);
3254
 
3255
                info->changed_contents = TRUE;
3256
                break;
3257
              }
3258
 
3259
            /* If not zero, place to jump without needing pv.  */
3260
            optdest = elf64_alpha_relax_opt_call (info, symval);
3261
            org = (info->sec->output_section->vma
3262
                   + info->sec->output_offset
3263
                   + urel->r_offset + 4);
3264
            odisp = (optdest ? optdest : symval) - org;
3265
 
3266
            if (odisp >= -0x400000 && odisp < 0x400000)
3267
              {
3268
                Elf_Internal_Rela *xrel;
3269
 
3270
                /* Preserve branch prediction call stack when possible.  */
3271
                if ((insn & INSN_JSR_MASK) == INSN_JSR)
3272
                  insn = (OP_BSR << 26) | (insn & 0x03e00000);
3273
                else
3274
                  insn = (OP_BR << 26) | (insn & 0x03e00000);
3275
 
3276
                urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
3277
                                             R_ALPHA_BRADDR);
3278
                urel->r_addend = irel->r_addend;
3279
 
3280
                if (optdest)
3281
                  urel->r_addend += optdest - symval;
3282
                else
3283
                  all_optimized = FALSE;
3284
 
3285
                bfd_put_32 (info->abfd, (bfd_vma) insn,
3286
                            info->contents + urel->r_offset);
3287
 
3288
                /* Kill any HINT reloc that might exist for this insn.  */
3289
                xrel = (elf64_alpha_find_reloc_at_ofs
3290
                        (info->relocs, info->relend, urel->r_offset,
3291
                         R_ALPHA_HINT));
3292
                if (xrel)
3293
                  xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3294
 
3295
                info->changed_contents = TRUE;
3296
                info->changed_relocs = TRUE;
3297
              }
3298
            else
3299
              all_optimized = FALSE;
3300
 
3301
            /* Even if the target is not in range for a direct branch,
3302
               if we share a GP, we can eliminate the gp reload.  */
3303
            if (optdest)
3304
              {
3305
                Elf_Internal_Rela *gpdisp
3306
                  = (elf64_alpha_find_reloc_at_ofs
3307
                     (info->relocs, irelend, urel->r_offset + 4,
3308
                      R_ALPHA_GPDISP));
3309
                if (gpdisp)
3310
                  {
3311
                    bfd_byte *p_ldah = info->contents + gpdisp->r_offset;
3312
                    bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
3313
                    unsigned int ldah = bfd_get_32 (info->abfd, p_ldah);
3314
                    unsigned int lda = bfd_get_32 (info->abfd, p_lda);
3315
 
3316
                    /* Verify that the instruction is "ldah $29,0($26)".
3317
                       Consider a function that ends in a noreturn call,
3318
                       and that the next function begins with an ldgp,
3319
                       and that by accident there is no padding between.
3320
                       In that case the insn would use $27 as the base.  */
3321
                    if (ldah == 0x27ba0000 && lda == 0x23bd0000)
3322
                      {
3323
                        bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_ldah);
3324
                        bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_lda);
3325
 
3326
                        gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3327
                        info->changed_contents = TRUE;
3328
                        info->changed_relocs = TRUE;
3329
                      }
3330
                  }
3331
              }
3332
          }
3333
          break;
3334
        }
3335
    }
3336
 
3337
  /* If all cases were optimized, we can reduce the use count on this
3338
     got entry by one, possibly eliminating it.  */
3339
  if (all_optimized)
3340
    {
3341
      if (--info->gotent->use_count == 0)
3342
        {
3343
          int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
3344
          alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3345
          if (!info->h)
3346
            alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
3347
        }
3348
 
3349
      /* If the literal instruction is no longer needed (it may have been
3350
         reused.  We can eliminate it.  */
3351
      /* ??? For now, I don't want to deal with compacting the section,
3352
         so just nop it out.  */
3353
      if (!lit_reused)
3354
        {
3355
          irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3356
          info->changed_relocs = TRUE;
3357
 
3358
          bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP,
3359
                      info->contents + irel->r_offset);
3360
          info->changed_contents = TRUE;
3361
        }
3362
 
3363
      return TRUE;
3364
    }
3365
  else
3366
    return elf64_alpha_relax_got_load (info, symval, irel, R_ALPHA_LITERAL);
3367
}
3368
 
3369
static bfd_boolean
3370
elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval,
3371
                                Elf_Internal_Rela *irel, bfd_boolean is_gd)
3372
{
3373
  bfd_byte *pos[5];
3374
  unsigned int insn;
3375
  Elf_Internal_Rela *gpdisp, *hint;
3376
  bfd_boolean dynamic, use_gottprel, pos1_unusable;
3377
  unsigned long new_symndx;
3378
 
3379
  dynamic = alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info);
3380
 
3381
  /* If a TLS symbol is accessed using IE at least once, there is no point
3382
     to use dynamic model for it.  */
3383
  if (is_gd && info->h && (info->h->flags & ALPHA_ELF_LINK_HASH_TLS_IE))
3384
    ;
3385
 
3386
  /* If the symbol is local, and we've already committed to DF_STATIC_TLS,
3387
     then we might as well relax to IE.  */
3388
  else if (info->link_info->shared && !dynamic
3389
           && (info->link_info->flags & DF_STATIC_TLS))
3390
    ;
3391
 
3392
  /* Otherwise we must be building an executable to do anything.  */
3393
  else if (info->link_info->shared)
3394
    return TRUE;
3395
 
3396
  /* The TLSGD/TLSLDM relocation must be followed by a LITERAL and
3397
     the matching LITUSE_TLS relocations.  */
3398
  if (irel + 2 >= info->relend)
3399
    return TRUE;
3400
  if (ELF64_R_TYPE (irel[1].r_info) != R_ALPHA_LITERAL
3401
      || ELF64_R_TYPE (irel[2].r_info) != R_ALPHA_LITUSE
3402
      || irel[2].r_addend != (is_gd ? LITUSE_ALPHA_TLSGD : LITUSE_ALPHA_TLSLDM))
3403
    return TRUE;
3404
 
3405
  /* There must be a GPDISP relocation positioned immediately after the
3406
     LITUSE relocation.  */
3407
  gpdisp = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
3408
                                          irel[2].r_offset + 4, R_ALPHA_GPDISP);
3409
  if (!gpdisp)
3410
    return TRUE;
3411
 
3412
  pos[0] = info->contents + irel[0].r_offset;
3413
  pos[1] = info->contents + irel[1].r_offset;
3414
  pos[2] = info->contents + irel[2].r_offset;
3415
  pos[3] = info->contents + gpdisp->r_offset;
3416
  pos[4] = pos[3] + gpdisp->r_addend;
3417
  pos1_unusable = FALSE;
3418
 
3419
  /* Generally, the positions are not allowed to be out of order, lest the
3420
     modified insn sequence have different register lifetimes.  We can make
3421
     an exception when pos 1 is adjacent to pos 0.  */
3422
  if (pos[1] + 4 == pos[0])
3423
    {
3424
      bfd_byte *tmp = pos[0];
3425
      pos[0] = pos[1];
3426
      pos[1] = tmp;
3427
    }
3428
  else if (pos[1] < pos[0])
3429
    pos1_unusable = TRUE;
3430
  if (pos[1] >= pos[2] || pos[2] >= pos[3])
3431
    return TRUE;
3432
 
3433
  /* Reduce the use count on the LITERAL relocation.  Do this before we
3434
     smash the symndx when we adjust the relocations below.  */
3435
  {
3436
    struct alpha_elf_got_entry *lit_gotent;
3437
    struct alpha_elf_link_hash_entry *lit_h;
3438
    unsigned long indx;
3439
 
3440
    BFD_ASSERT (ELF64_R_SYM (irel[1].r_info) >= info->symtab_hdr->sh_info);
3441
    indx = ELF64_R_SYM (irel[1].r_info) - info->symtab_hdr->sh_info;
3442
    lit_h = alpha_elf_sym_hashes (info->abfd)[indx];
3443
 
3444
    while (lit_h->root.root.type == bfd_link_hash_indirect
3445
           || lit_h->root.root.type == bfd_link_hash_warning)
3446
      lit_h = (struct alpha_elf_link_hash_entry *) lit_h->root.root.u.i.link;
3447
 
3448
    for (lit_gotent = lit_h->got_entries; lit_gotent ;
3449
         lit_gotent = lit_gotent->next)
3450
      if (lit_gotent->gotobj == info->gotobj
3451
          && lit_gotent->reloc_type == R_ALPHA_LITERAL
3452
          && lit_gotent->addend == irel[1].r_addend)
3453
        break;
3454
    BFD_ASSERT (lit_gotent);
3455
 
3456
    if (--lit_gotent->use_count == 0)
3457
      {
3458
        int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
3459
        alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3460
      }
3461
  }
3462
 
3463
  /* Change
3464
 
3465
        lda     $16,x($gp)                      !tlsgd!1
3466
        ldq     $27,__tls_get_addr($gp)         !literal!1
3467
        jsr     $26,($27),__tls_get_addr        !lituse_tlsgd!1
3468
        ldah    $29,0($26)                      !gpdisp!2
3469
        lda     $29,0($29)                      !gpdisp!2
3470
     to
3471
        ldq     $16,x($gp)                      !gottprel
3472
        unop
3473
        call_pal rduniq
3474
        addq    $16,$0,$0
3475
        unop
3476
     or the first pair to
3477
        lda     $16,x($gp)                      !tprel
3478
        unop
3479
     or
3480
        ldah    $16,x($gp)                      !tprelhi
3481
        lda     $16,x($16)                      !tprello
3482
 
3483
     as appropriate.  */
3484
 
3485
  use_gottprel = FALSE;
3486
  new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : 0;
3487
  switch (!dynamic && !info->link_info->shared)
3488
    {
3489
    case 1:
3490
      {
3491
        bfd_vma tp_base;
3492
        bfd_signed_vma disp;
3493
 
3494
        BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
3495
        tp_base = alpha_get_tprel_base (info->link_info);
3496
        disp = symval - tp_base;
3497
 
3498
        if (disp >= -0x8000 && disp < 0x8000)
3499
          {
3500
            insn = (OP_LDA << 26) | (16 << 21) | (31 << 16);
3501
            bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
3502
            bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
3503
 
3504
            irel[0].r_offset = pos[0] - info->contents;
3505
            irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPREL16);
3506
            irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3507
            break;
3508
          }
3509
        else if (disp >= -(bfd_signed_vma) 0x80000000
3510
                 && disp < (bfd_signed_vma) 0x7fff8000
3511
                 && !pos1_unusable)
3512
          {
3513
            insn = (OP_LDAH << 26) | (16 << 21) | (31 << 16);
3514
            bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
3515
            insn = (OP_LDA << 26) | (16 << 21) | (16 << 16);
3516
            bfd_put_32 (info->abfd, (bfd_vma) insn, pos[1]);
3517
 
3518
            irel[0].r_offset = pos[0] - info->contents;
3519
            irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELHI);
3520
            irel[1].r_offset = pos[1] - info->contents;
3521
            irel[1].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELLO);
3522
            break;
3523
          }
3524
      }
3525
      /* FALLTHRU */
3526
 
3527
    default:
3528
      use_gottprel = TRUE;
3529
 
3530
      insn = (OP_LDQ << 26) | (16 << 21) | (29 << 16);
3531
      bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
3532
      bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
3533
 
3534
      irel[0].r_offset = pos[0] - info->contents;
3535
      irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_GOTTPREL);
3536
      irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3537
      break;
3538
    }
3539
 
3540
  bfd_put_32 (info->abfd, (bfd_vma) INSN_RDUNIQ, pos[2]);
3541
 
3542
  insn = INSN_ADDQ | (16 << 21) | (0 << 16) | (0 << 0);
3543
  bfd_put_32 (info->abfd, (bfd_vma) insn, pos[3]);
3544
 
3545
  bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[4]);
3546
 
3547
  irel[2].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3548
  gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3549
 
3550
  hint = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
3551
                                        irel[2].r_offset, R_ALPHA_HINT);
3552
  if (hint)
3553
    hint->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
3554
 
3555
  info->changed_contents = TRUE;
3556
  info->changed_relocs = TRUE;
3557
 
3558
  /* Reduce the use count on the TLSGD/TLSLDM relocation.  */
3559
  if (--info->gotent->use_count == 0)
3560
    {
3561
      int sz = alpha_got_entry_size (info->gotent->reloc_type);
3562
      alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
3563
      if (!info->h)
3564
        alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
3565
    }
3566
 
3567
  /* If we've switched to a GOTTPREL relocation, increment the reference
3568
     count on that got entry.  */
3569
  if (use_gottprel)
3570
    {
3571
      struct alpha_elf_got_entry *tprel_gotent;
3572
 
3573
      for (tprel_gotent = *info->first_gotent; tprel_gotent ;
3574
           tprel_gotent = tprel_gotent->next)
3575
        if (tprel_gotent->gotobj == info->gotobj
3576
            && tprel_gotent->reloc_type == R_ALPHA_GOTTPREL
3577
            && tprel_gotent->addend == irel->r_addend)
3578
          break;
3579
      if (tprel_gotent)
3580
        tprel_gotent->use_count++;
3581
      else
3582
        {
3583
          if (info->gotent->use_count == 0)
3584
            tprel_gotent = info->gotent;
3585
          else
3586
            {
3587
              tprel_gotent = (struct alpha_elf_got_entry *)
3588
                bfd_alloc (info->abfd, sizeof (struct alpha_elf_got_entry));
3589
              if (!tprel_gotent)
3590
                return FALSE;
3591
 
3592
              tprel_gotent->next = *info->first_gotent;
3593
              *info->first_gotent = tprel_gotent;
3594
 
3595
              tprel_gotent->gotobj = info->gotobj;
3596
              tprel_gotent->addend = irel->r_addend;
3597
              tprel_gotent->got_offset = -1;
3598
              tprel_gotent->reloc_done = 0;
3599
              tprel_gotent->reloc_xlated = 0;
3600
            }
3601
 
3602
          tprel_gotent->use_count = 1;
3603
          tprel_gotent->reloc_type = R_ALPHA_GOTTPREL;
3604
        }
3605
    }
3606
 
3607
  return TRUE;
3608
}
3609
 
3610
static bfd_boolean
3611
elf64_alpha_relax_section (bfd *abfd, asection *sec,
3612
                           struct bfd_link_info *link_info, bfd_boolean *again)
3613
{
3614
  Elf_Internal_Shdr *symtab_hdr;
3615
  Elf_Internal_Rela *internal_relocs;
3616
  Elf_Internal_Rela *irel, *irelend;
3617
  Elf_Internal_Sym *isymbuf = NULL;
3618
  struct alpha_elf_got_entry **local_got_entries;
3619
  struct alpha_relax_info info;
3620
 
3621
  /* There's nothing to change, yet.  */
3622
  *again = FALSE;
3623
 
3624
  if (link_info->relocatable
3625
      || ((sec->flags & (SEC_CODE | SEC_RELOC | SEC_ALLOC))
3626
          != (SEC_CODE | SEC_RELOC | SEC_ALLOC))
3627
      || sec->reloc_count == 0)
3628
    return TRUE;
3629
 
3630
  BFD_ASSERT (is_alpha_elf (abfd));
3631
 
3632
  /* Make sure our GOT and PLT tables are up-to-date.  */
3633
  if (alpha_elf_hash_table(link_info)->relax_trip != link_info->relax_trip)
3634
    {
3635
      alpha_elf_hash_table(link_info)->relax_trip = link_info->relax_trip;
3636
 
3637
      /* This should never fail after the initial round, since the only
3638
         error is GOT overflow, and relaxation only shrinks the table.  */
3639
      if (!elf64_alpha_size_got_sections (link_info))
3640
        abort ();
3641
      if (elf_hash_table (link_info)->dynamic_sections_created)
3642
        {
3643
          elf64_alpha_size_plt_section (link_info);
3644
          elf64_alpha_size_rela_got_section (link_info);
3645
        }
3646
    }
3647
 
3648
  symtab_hdr = &elf_symtab_hdr (abfd);
3649
  local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
3650
 
3651
  /* Load the relocations for this section.  */
3652
  internal_relocs = (_bfd_elf_link_read_relocs
3653
                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
3654
                      link_info->keep_memory));
3655
  if (internal_relocs == NULL)
3656
    return FALSE;
3657
 
3658
  memset(&info, 0, sizeof (info));
3659
  info.abfd = abfd;
3660
  info.sec = sec;
3661
  info.link_info = link_info;
3662
  info.symtab_hdr = symtab_hdr;
3663
  info.relocs = internal_relocs;
3664
  info.relend = irelend = internal_relocs + sec->reloc_count;
3665
 
3666
  /* Find the GP for this object.  Do not store the result back via
3667
     _bfd_set_gp_value, since this could change again before final.  */
3668
  info.gotobj = alpha_elf_tdata (abfd)->gotobj;
3669
  if (info.gotobj)
3670
    {
3671
      asection *sgot = alpha_elf_tdata (info.gotobj)->got;
3672
      info.gp = (sgot->output_section->vma
3673
                 + sgot->output_offset
3674
                 + 0x8000);
3675
    }
3676
 
3677
  /* Get the section contents.  */
3678
  if (elf_section_data (sec)->this_hdr.contents != NULL)
3679
    info.contents = elf_section_data (sec)->this_hdr.contents;
3680
  else
3681
    {
3682
      if (!bfd_malloc_and_get_section (abfd, sec, &info.contents))
3683
        goto error_return;
3684
    }
3685
 
3686
  for (irel = internal_relocs; irel < irelend; irel++)
3687
    {
3688
      bfd_vma symval;
3689
      struct alpha_elf_got_entry *gotent;
3690
      unsigned long r_type = ELF64_R_TYPE (irel->r_info);
3691
      unsigned long r_symndx = ELF64_R_SYM (irel->r_info);
3692
 
3693
      /* Early exit for unhandled or unrelaxable relocations.  */
3694
      switch (r_type)
3695
        {
3696
        case R_ALPHA_LITERAL:
3697
        case R_ALPHA_GPRELHIGH:
3698
        case R_ALPHA_GPRELLOW:
3699
        case R_ALPHA_GOTDTPREL:
3700
        case R_ALPHA_GOTTPREL:
3701
        case R_ALPHA_TLSGD:
3702
          break;
3703
 
3704
        case R_ALPHA_TLSLDM:
3705
          /* The symbol for a TLSLDM reloc is ignored.  Collapse the
3706
             reloc to the 0 symbol so that they all match.  */
3707
          r_symndx = 0;
3708
          break;
3709
 
3710
        default:
3711
          continue;
3712
        }
3713
 
3714
      /* Get the value of the symbol referred to by the reloc.  */
3715
      if (r_symndx < symtab_hdr->sh_info)
3716
        {
3717
          /* A local symbol.  */
3718
          Elf_Internal_Sym *isym;
3719
 
3720
          /* Read this BFD's local symbols.  */
3721
          if (isymbuf == NULL)
3722
            {
3723
              isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
3724
              if (isymbuf == NULL)
3725
                isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
3726
                                                symtab_hdr->sh_info, 0,
3727
                                                NULL, NULL, NULL);
3728
              if (isymbuf == NULL)
3729
                goto error_return;
3730
            }
3731
 
3732
          isym = isymbuf + r_symndx;
3733
 
3734
          /* Given the symbol for a TLSLDM reloc is ignored, this also
3735
             means forcing the symbol value to the tp base.  */
3736
          if (r_type == R_ALPHA_TLSLDM)
3737
            {
3738
              info.tsec = bfd_abs_section_ptr;
3739
              symval = alpha_get_tprel_base (info.link_info);
3740
            }
3741
          else
3742
            {
3743
              symval = isym->st_value;
3744
              if (isym->st_shndx == SHN_UNDEF)
3745
                continue;
3746
              else if (isym->st_shndx == SHN_ABS)
3747
                info.tsec = bfd_abs_section_ptr;
3748
              else if (isym->st_shndx == SHN_COMMON)
3749
                info.tsec = bfd_com_section_ptr;
3750
              else
3751
                info.tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3752
            }
3753
 
3754
          info.h = NULL;
3755
          info.other = isym->st_other;
3756
          if (local_got_entries)
3757
            info.first_gotent = &local_got_entries[r_symndx];
3758
          else
3759
            {
3760
              info.first_gotent = &info.gotent;
3761
              info.gotent = NULL;
3762
            }
3763
        }
3764
      else
3765
        {
3766
          unsigned long indx;
3767
          struct alpha_elf_link_hash_entry *h;
3768
 
3769
          indx = r_symndx - symtab_hdr->sh_info;
3770
          h = alpha_elf_sym_hashes (abfd)[indx];
3771
          BFD_ASSERT (h != NULL);
3772
 
3773
          while (h->root.root.type == bfd_link_hash_indirect
3774
                 || h->root.root.type == bfd_link_hash_warning)
3775
            h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
3776
 
3777
          /* If the symbol is undefined, we can't do anything with it.  */
3778
          if (h->root.root.type == bfd_link_hash_undefined)
3779
            continue;
3780
 
3781
          /* If the symbol isn't defined in the current module,
3782
             again we can't do anything.  */
3783
          if (h->root.root.type == bfd_link_hash_undefweak)
3784
            {
3785
              info.tsec = bfd_abs_section_ptr;
3786
              symval = 0;
3787
            }
3788
          else if (!h->root.def_regular)
3789
            {
3790
              /* Except for TLSGD relocs, which can sometimes be
3791
                 relaxed to GOTTPREL relocs.  */
3792
              if (r_type != R_ALPHA_TLSGD)
3793
                continue;
3794
              info.tsec = bfd_abs_section_ptr;
3795
              symval = 0;
3796
            }
3797
          else
3798
            {
3799
              info.tsec = h->root.root.u.def.section;
3800
              symval = h->root.root.u.def.value;
3801
            }
3802
 
3803
          info.h = h;
3804
          info.other = h->root.other;
3805
          info.first_gotent = &h->got_entries;
3806
        }
3807
 
3808
      /* Search for the got entry to be used by this relocation.  */
3809
      for (gotent = *info.first_gotent; gotent ; gotent = gotent->next)
3810
        if (gotent->gotobj == info.gotobj
3811
            && gotent->reloc_type == r_type
3812
            && gotent->addend == irel->r_addend)
3813
          break;
3814
      info.gotent = gotent;
3815
 
3816
      symval += info.tsec->output_section->vma + info.tsec->output_offset;
3817
      symval += irel->r_addend;
3818
 
3819
      switch (r_type)
3820
        {
3821
        case R_ALPHA_LITERAL:
3822
          BFD_ASSERT(info.gotent != NULL);
3823
 
3824
          /* If there exist LITUSE relocations immediately following, this
3825
             opens up all sorts of interesting optimizations, because we
3826
             now know every location that this address load is used.  */
3827
          if (irel+1 < irelend
3828
              && ELF64_R_TYPE (irel[1].r_info) == R_ALPHA_LITUSE)
3829
            {
3830
              if (!elf64_alpha_relax_with_lituse (&info, symval, irel))
3831
                goto error_return;
3832
            }
3833
          else
3834
            {
3835
              if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
3836
                goto error_return;
3837
            }
3838
          break;
3839
 
3840
        case R_ALPHA_GOTDTPREL:
3841
        case R_ALPHA_GOTTPREL:
3842
          BFD_ASSERT(info.gotent != NULL);
3843
          if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
3844
            goto error_return;
3845
          break;
3846
 
3847
        case R_ALPHA_TLSGD:
3848
        case R_ALPHA_TLSLDM:
3849
          BFD_ASSERT(info.gotent != NULL);
3850
          if (!elf64_alpha_relax_tls_get_addr (&info, symval, irel,
3851
                                               r_type == R_ALPHA_TLSGD))
3852
            goto error_return;
3853
          break;
3854
        }
3855
    }
3856
 
3857
  if (isymbuf != NULL
3858
      && symtab_hdr->contents != (unsigned char *) isymbuf)
3859
    {
3860
      if (!link_info->keep_memory)
3861
        free (isymbuf);
3862
      else
3863
        {
3864
          /* Cache the symbols for elf_link_input_bfd.  */
3865
          symtab_hdr->contents = (unsigned char *) isymbuf;
3866
        }
3867
    }
3868
 
3869
  if (info.contents != NULL
3870
      && elf_section_data (sec)->this_hdr.contents != info.contents)
3871
    {
3872
      if (!info.changed_contents && !link_info->keep_memory)
3873
        free (info.contents);
3874
      else
3875
        {
3876
          /* Cache the section contents for elf_link_input_bfd.  */
3877
          elf_section_data (sec)->this_hdr.contents = info.contents;
3878
        }
3879
    }
3880
 
3881
  if (elf_section_data (sec)->relocs != internal_relocs)
3882
    {
3883
      if (!info.changed_relocs)
3884
        free (internal_relocs);
3885
      else
3886
        elf_section_data (sec)->relocs = internal_relocs;
3887
    }
3888
 
3889
  *again = info.changed_contents || info.changed_relocs;
3890
 
3891
  return TRUE;
3892
 
3893
 error_return:
3894
  if (isymbuf != NULL
3895
      && symtab_hdr->contents != (unsigned char *) isymbuf)
3896
    free (isymbuf);
3897
  if (info.contents != NULL
3898
      && elf_section_data (sec)->this_hdr.contents != info.contents)
3899
    free (info.contents);
3900
  if (internal_relocs != NULL
3901
      && elf_section_data (sec)->relocs != internal_relocs)
3902
    free (internal_relocs);
3903
  return FALSE;
3904
}
3905
 
3906
/* Emit a dynamic relocation for (DYNINDX, RTYPE, ADDEND) at (SEC, OFFSET)
3907
   into the next available slot in SREL.  */
3908
 
3909
static void
3910
elf64_alpha_emit_dynrel (bfd *abfd, struct bfd_link_info *info,
3911
                         asection *sec, asection *srel, bfd_vma offset,
3912
                         long dynindx, long rtype, bfd_vma addend)
3913
{
3914
  Elf_Internal_Rela outrel;
3915
  bfd_byte *loc;
3916
 
3917
  BFD_ASSERT (srel != NULL);
3918
 
3919
  outrel.r_info = ELF64_R_INFO (dynindx, rtype);
3920
  outrel.r_addend = addend;
3921
 
3922
  offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3923
  if ((offset | 1) != (bfd_vma) -1)
3924
    outrel.r_offset = sec->output_section->vma + sec->output_offset + offset;
3925
  else
3926
    memset (&outrel, 0, sizeof (outrel));
3927
 
3928
  loc = srel->contents;
3929
  loc += srel->reloc_count++ * sizeof (Elf64_External_Rela);
3930
  bfd_elf64_swap_reloca_out (abfd, &outrel, loc);
3931
  BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count <= srel->size);
3932
}
3933
 
3934
/* Relocate an Alpha ELF section for a relocatable link.
3935
 
3936
   We don't have to change anything unless the reloc is against a section
3937
   symbol, in which case we have to adjust according to where the section
3938
   symbol winds up in the output section.  */
3939
 
3940
static bfd_boolean
3941
elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED,
3942
                                struct bfd_link_info *info ATTRIBUTE_UNUSED,
3943
                                bfd *input_bfd, asection *input_section,
3944
                                bfd_byte *contents ATTRIBUTE_UNUSED,
3945
                                Elf_Internal_Rela *relocs,
3946
                                Elf_Internal_Sym *local_syms,
3947
                                asection **local_sections)
3948
{
3949
  unsigned long symtab_hdr_sh_info;
3950
  Elf_Internal_Rela *rel;
3951
  Elf_Internal_Rela *relend;
3952
  struct elf_link_hash_entry **sym_hashes;
3953
  bfd_boolean ret_val = TRUE;
3954
 
3955
  symtab_hdr_sh_info = elf_symtab_hdr (input_bfd).sh_info;
3956
  sym_hashes = elf_sym_hashes (input_bfd);
3957
 
3958
  relend = relocs + input_section->reloc_count;
3959
  for (rel = relocs; rel < relend; rel++)
3960
    {
3961
      unsigned long r_symndx;
3962
      Elf_Internal_Sym *sym;
3963
      asection *sec;
3964
      unsigned long r_type;
3965
 
3966
      r_type = ELF64_R_TYPE (rel->r_info);
3967
      if (r_type >= R_ALPHA_max)
3968
        {
3969
          (*_bfd_error_handler)
3970
            (_("%B: unknown relocation type %d"),
3971
             input_bfd, (int) r_type);
3972
          bfd_set_error (bfd_error_bad_value);
3973
          ret_val = FALSE;
3974
          continue;
3975
        }
3976
 
3977
      /* The symbol associated with GPDISP and LITUSE is
3978
         immaterial.  Only the addend is significant.  */
3979
      if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE)
3980
        continue;
3981
 
3982
      r_symndx = ELF64_R_SYM (rel->r_info);
3983
      if (r_symndx < symtab_hdr_sh_info)
3984
        {
3985
          sym = local_syms + r_symndx;
3986
          sec = local_sections[r_symndx];
3987
        }
3988
      else
3989
        {
3990
          struct elf_link_hash_entry *h;
3991
 
3992
          h = sym_hashes[r_symndx - symtab_hdr_sh_info];
3993
 
3994
          while (h->root.type == bfd_link_hash_indirect
3995
                 || h->root.type == bfd_link_hash_warning)
3996
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
3997
 
3998
          if (h->root.type != bfd_link_hash_defined
3999
              && h->root.type != bfd_link_hash_defweak)
4000
            continue;
4001
 
4002
          sym = NULL;
4003
          sec = h->root.u.def.section;
4004
        }
4005
 
4006
      if (sec != NULL && elf_discarded_section (sec))
4007
        {
4008
          /* For relocs against symbols from removed linkonce sections,
4009
             or sections discarded by a linker script, we just want the
4010
             section contents zeroed.  */
4011
          _bfd_clear_contents (elf64_alpha_howto_table + r_type,
4012
                               input_bfd, contents + rel->r_offset);
4013
          rel->r_info = 0;
4014
          rel->r_addend = 0;
4015
          continue;
4016
        }
4017
 
4018
      if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4019
        rel->r_addend += sec->output_offset;
4020
    }
4021
 
4022
  return ret_val;
4023
}
4024
 
4025
/* Relocate an Alpha ELF section.  */
4026
 
4027
static bfd_boolean
4028
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
4029
                              bfd *input_bfd, asection *input_section,
4030
                              bfd_byte *contents, Elf_Internal_Rela *relocs,
4031
                              Elf_Internal_Sym *local_syms,
4032
                              asection **local_sections)
4033
{
4034
  Elf_Internal_Shdr *symtab_hdr;
4035
  Elf_Internal_Rela *rel;
4036
  Elf_Internal_Rela *relend;
4037
  asection *sgot, *srel, *srelgot;
4038
  bfd *dynobj, *gotobj;
4039
  bfd_vma gp, tp_base, dtp_base;
4040
  struct alpha_elf_got_entry **local_got_entries;
4041
  bfd_boolean ret_val;
4042
 
4043
  BFD_ASSERT (is_alpha_elf (input_bfd));
4044
 
4045
  /* Handle relocatable links with a smaller loop.  */
4046
  if (info->relocatable)
4047
    return elf64_alpha_relocate_section_r (output_bfd, info, input_bfd,
4048
                                           input_section, contents, relocs,
4049
                                           local_syms, local_sections);
4050
 
4051
  /* This is a final link.  */
4052
 
4053
  ret_val = TRUE;
4054
 
4055
  symtab_hdr = &elf_symtab_hdr (input_bfd);
4056
 
4057
  dynobj = elf_hash_table (info)->dynobj;
4058
  if (dynobj)
4059
    srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
4060
  else
4061
    srelgot = NULL;
4062
 
4063
  if (input_section->flags & SEC_ALLOC)
4064
    {
4065
      const char *section_name;
4066
      section_name = (bfd_elf_string_from_elf_section
4067
                      (input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
4068
                       elf_section_data(input_section)->rel_hdr.sh_name));
4069
      BFD_ASSERT(section_name != NULL);
4070
      srel = bfd_get_section_by_name (dynobj, section_name);
4071
    }
4072
  else
4073
    srel = NULL;
4074
 
4075
  /* Find the gp value for this input bfd.  */
4076
  gotobj = alpha_elf_tdata (input_bfd)->gotobj;
4077
  if (gotobj)
4078
    {
4079
      sgot = alpha_elf_tdata (gotobj)->got;
4080
      gp = _bfd_get_gp_value (gotobj);
4081
      if (gp == 0)
4082
        {
4083
          gp = (sgot->output_section->vma
4084
                + sgot->output_offset
4085
                + 0x8000);
4086
          _bfd_set_gp_value (gotobj, gp);
4087
        }
4088
    }
4089
  else
4090
    {
4091
      sgot = NULL;
4092
      gp = 0;
4093
    }
4094
 
4095
  local_got_entries = alpha_elf_tdata(input_bfd)->local_got_entries;
4096
 
4097
  if (elf_hash_table (info)->tls_sec != NULL)
4098
    {
4099
      dtp_base = alpha_get_dtprel_base (info);
4100
      tp_base = alpha_get_tprel_base (info);
4101
    }
4102
  else
4103
    dtp_base = tp_base = 0;
4104
 
4105
  relend = relocs + input_section->reloc_count;
4106
  for (rel = relocs; rel < relend; rel++)
4107
    {
4108
      struct alpha_elf_link_hash_entry *h = NULL;
4109
      struct alpha_elf_got_entry *gotent;
4110
      bfd_reloc_status_type r;
4111
      reloc_howto_type *howto;
4112
      unsigned long r_symndx;
4113
      Elf_Internal_Sym *sym = NULL;
4114
      asection *sec = NULL;
4115
      bfd_vma value;
4116
      bfd_vma addend;
4117
      bfd_boolean dynamic_symbol_p;
4118
      bfd_boolean undef_weak_ref = FALSE;
4119
      unsigned long r_type;
4120
 
4121
      r_type = ELF64_R_TYPE(rel->r_info);
4122
      if (r_type >= R_ALPHA_max)
4123
        {
4124
          (*_bfd_error_handler)
4125
            (_("%B: unknown relocation type %d"),
4126
             input_bfd, (int) r_type);
4127
          bfd_set_error (bfd_error_bad_value);
4128
          ret_val = FALSE;
4129
          continue;
4130
        }
4131
 
4132
      howto = elf64_alpha_howto_table + r_type;
4133
      r_symndx = ELF64_R_SYM(rel->r_info);
4134
 
4135
      /* The symbol for a TLSLDM reloc is ignored.  Collapse the
4136
         reloc to the 0 symbol so that they all match.  */
4137
      if (r_type == R_ALPHA_TLSLDM)
4138
        r_symndx = 0;
4139
 
4140
      if (r_symndx < symtab_hdr->sh_info)
4141
        {
4142
          asection *msec;
4143
          sym = local_syms + r_symndx;
4144
          sec = local_sections[r_symndx];
4145
          msec = sec;
4146
          value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
4147
 
4148
          /* If this is a tp-relative relocation against sym 0,
4149
             this is hackery from relax_section.  Force the value to
4150
             be the tls module base.  */
4151
          if (r_symndx == 0
4152
              && (r_type == R_ALPHA_TLSLDM
4153
                  || r_type == R_ALPHA_GOTTPREL
4154
                  || r_type == R_ALPHA_TPREL64
4155
                  || r_type == R_ALPHA_TPRELHI
4156
                  || r_type == R_ALPHA_TPRELLO
4157
                  || r_type == R_ALPHA_TPREL16))
4158
            value = dtp_base;
4159
 
4160
          if (local_got_entries)
4161
            gotent = local_got_entries[r_symndx];
4162
          else
4163
            gotent = NULL;
4164
 
4165
          /* Need to adjust local GOT entries' addends for SEC_MERGE
4166
             unless it has been done already.  */
4167
          if ((sec->flags & SEC_MERGE)
4168
              && ELF_ST_TYPE (sym->st_info) == STT_SECTION
4169
              && sec->sec_info_type == ELF_INFO_TYPE_MERGE
4170
              && gotent
4171
              && !gotent->reloc_xlated)
4172
            {
4173
              struct alpha_elf_got_entry *ent;
4174
 
4175
              for (ent = gotent; ent; ent = ent->next)
4176
                {
4177
                  ent->reloc_xlated = 1;
4178
                  if (ent->use_count == 0)
4179
                    continue;
4180
                  msec = sec;
4181
                  ent->addend =
4182
                    _bfd_merged_section_offset (output_bfd, &msec,
4183
                                                elf_section_data (sec)->
4184
                                                  sec_info,
4185
                                                sym->st_value + ent->addend);
4186
                  ent->addend -= sym->st_value;
4187
                  ent->addend += msec->output_section->vma
4188
                                 + msec->output_offset
4189
                                 - sec->output_section->vma
4190
                                 - sec->output_offset;
4191
                }
4192
            }
4193
 
4194
          dynamic_symbol_p = FALSE;
4195
        }
4196
      else
4197
        {
4198
          bfd_boolean warned;
4199
          bfd_boolean unresolved_reloc;
4200
          struct elf_link_hash_entry *hh;
4201
          struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
4202
 
4203
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4204
                                   r_symndx, symtab_hdr, sym_hashes,
4205
                                   hh, sec, value,
4206
                                   unresolved_reloc, warned);
4207
 
4208
          if (warned)
4209
            continue;
4210
 
4211
          if (value == 0
4212
              && ! unresolved_reloc
4213
              && hh->root.type == bfd_link_hash_undefweak)
4214
            undef_weak_ref = TRUE;
4215
 
4216
          h = (struct alpha_elf_link_hash_entry *) hh;
4217
          dynamic_symbol_p = alpha_elf_dynamic_symbol_p (&h->root, info);
4218
          gotent = h->got_entries;
4219
        }
4220
 
4221
      if (sec != NULL && elf_discarded_section (sec))
4222
        {
4223
          /* For relocs against symbols from removed linkonce sections,
4224
             or sections discarded by a linker script, we just want the
4225
             section contents zeroed.  Avoid any special processing.  */
4226
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
4227
          rel->r_info = 0;
4228
          rel->r_addend = 0;
4229
          continue;
4230
        }
4231
 
4232
      addend = rel->r_addend;
4233
      value += addend;
4234
 
4235
      /* Search for the proper got entry.  */
4236
      for (; gotent ; gotent = gotent->next)
4237
        if (gotent->gotobj == gotobj
4238
            && gotent->reloc_type == r_type
4239
            && gotent->addend == addend)
4240
          break;
4241
 
4242
      switch (r_type)
4243
        {
4244
        case R_ALPHA_GPDISP:
4245
          {
4246
            bfd_byte *p_ldah, *p_lda;
4247
 
4248
            BFD_ASSERT(gp != 0);
4249
 
4250
            value = (input_section->output_section->vma
4251
                     + input_section->output_offset
4252
                     + rel->r_offset);
4253
 
4254
            p_ldah = contents + rel->r_offset;
4255
            p_lda = p_ldah + rel->r_addend;
4256
 
4257
            r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - value,
4258
                                             p_ldah, p_lda);
4259
          }
4260
          break;
4261
 
4262
        case R_ALPHA_LITERAL:
4263
          BFD_ASSERT(sgot != NULL);
4264
          BFD_ASSERT(gp != 0);
4265
          BFD_ASSERT(gotent != NULL);
4266
          BFD_ASSERT(gotent->use_count >= 1);
4267
 
4268
          if (!gotent->reloc_done)
4269
            {
4270
              gotent->reloc_done = 1;
4271
 
4272
              bfd_put_64 (output_bfd, value,
4273
                          sgot->contents + gotent->got_offset);
4274
 
4275
              /* If the symbol has been forced local, output a
4276
                 RELATIVE reloc, otherwise it will be handled in
4277
                 finish_dynamic_symbol.  */
4278
              if (info->shared && !dynamic_symbol_p && !undef_weak_ref)
4279
                elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
4280
                                         gotent->got_offset, 0,
4281
                                         R_ALPHA_RELATIVE, value);
4282
            }
4283
 
4284
          value = (sgot->output_section->vma
4285
                   + sgot->output_offset
4286
                   + gotent->got_offset);
4287
          value -= gp;
4288
          goto default_reloc;
4289
 
4290
        case R_ALPHA_GPREL32:
4291
        case R_ALPHA_GPREL16:
4292
        case R_ALPHA_GPRELLOW:
4293
          if (dynamic_symbol_p)
4294
            {
4295
              (*_bfd_error_handler)
4296
                (_("%B: gp-relative relocation against dynamic symbol %s"),
4297
                 input_bfd, h->root.root.root.string);
4298
              ret_val = FALSE;
4299
            }
4300
          BFD_ASSERT(gp != 0);
4301
          value -= gp;
4302
          goto default_reloc;
4303
 
4304
        case R_ALPHA_GPRELHIGH:
4305
          if (dynamic_symbol_p)
4306
            {
4307
              (*_bfd_error_handler)
4308
                (_("%B: gp-relative relocation against dynamic symbol %s"),
4309
                 input_bfd, h->root.root.root.string);
4310
              ret_val = FALSE;
4311
            }
4312
          BFD_ASSERT(gp != 0);
4313
          value -= gp;
4314
          value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
4315
          goto default_reloc;
4316
 
4317
        case R_ALPHA_HINT:
4318
          /* A call to a dynamic symbol is definitely out of range of
4319
             the 16-bit displacement.  Don't bother writing anything.  */
4320
          if (dynamic_symbol_p)
4321
            {
4322
              r = bfd_reloc_ok;
4323
              break;
4324
            }
4325
          /* The regular PC-relative stuff measures from the start of
4326
             the instruction rather than the end.  */
4327
          value -= 4;
4328
          goto default_reloc;
4329
 
4330
        case R_ALPHA_BRADDR:
4331
          if (dynamic_symbol_p)
4332
            {
4333
              (*_bfd_error_handler)
4334
                (_("%B: pc-relative relocation against dynamic symbol %s"),
4335
                 input_bfd, h->root.root.root.string);
4336
              ret_val = FALSE;
4337
            }
4338
          /* The regular PC-relative stuff measures from the start of
4339
             the instruction rather than the end.  */
4340
          value -= 4;
4341
          goto default_reloc;
4342
 
4343
        case R_ALPHA_BRSGP:
4344
          {
4345
            int other;
4346
            const char *name;
4347
 
4348
            /* The regular PC-relative stuff measures from the start of
4349
               the instruction rather than the end.  */
4350
            value -= 4;
4351
 
4352
            /* The source and destination gp must be the same.  Note that
4353
               the source will always have an assigned gp, since we forced
4354
               one in check_relocs, but that the destination may not, as
4355
               it might not have had any relocations at all.  Also take
4356
               care not to crash if H is an undefined symbol.  */
4357
            if (h != NULL && sec != NULL
4358
                && alpha_elf_tdata (sec->owner)->gotobj
4359
                && gotobj != alpha_elf_tdata (sec->owner)->gotobj)
4360
              {
4361
                (*_bfd_error_handler)
4362
                  (_("%B: change in gp: BRSGP %s"),
4363
                   input_bfd, h->root.root.root.string);
4364
                ret_val = FALSE;
4365
              }
4366
 
4367
            /* The symbol should be marked either NOPV or STD_GPLOAD.  */
4368
            if (h != NULL)
4369
              other = h->root.other;
4370
            else
4371
              other = sym->st_other;
4372
            switch (other & STO_ALPHA_STD_GPLOAD)
4373
              {
4374
              case STO_ALPHA_NOPV:
4375
                break;
4376
              case STO_ALPHA_STD_GPLOAD:
4377
                value += 8;
4378
                break;
4379
              default:
4380
                if (h != NULL)
4381
                  name = h->root.root.root.string;
4382
                else
4383
                  {
4384
                    name = (bfd_elf_string_from_elf_section
4385
                            (input_bfd, symtab_hdr->sh_link, sym->st_name));
4386
                    if (name == NULL)
4387
                      name = _("<unknown>");
4388
                    else if (name[0] == 0)
4389
                      name = bfd_section_name (input_bfd, sec);
4390
                  }
4391
                (*_bfd_error_handler)
4392
                  (_("%B: !samegp reloc against symbol without .prologue: %s"),
4393
                   input_bfd, name);
4394
                ret_val = FALSE;
4395
                break;
4396
              }
4397
 
4398
            goto default_reloc;
4399
          }
4400
 
4401
        case R_ALPHA_REFLONG:
4402
        case R_ALPHA_REFQUAD:
4403
        case R_ALPHA_DTPREL64:
4404
        case R_ALPHA_TPREL64:
4405
          {
4406
            long dynindx, dyntype = r_type;
4407
            bfd_vma dynaddend;
4408
 
4409
            /* Careful here to remember RELATIVE relocations for global
4410
               variables for symbolic shared objects.  */
4411
 
4412
            if (dynamic_symbol_p)
4413
              {
4414
                BFD_ASSERT(h->root.dynindx != -1);
4415
                dynindx = h->root.dynindx;
4416
                dynaddend = addend;
4417
                addend = 0, value = 0;
4418
              }
4419
            else if (r_type == R_ALPHA_DTPREL64)
4420
              {
4421
                BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4422
                value -= dtp_base;
4423
                goto default_reloc;
4424
              }
4425
            else if (r_type == R_ALPHA_TPREL64)
4426
              {
4427
                BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4428
                if (!info->shared)
4429
                  {
4430
                    value -= tp_base;
4431
                    goto default_reloc;
4432
                  }
4433
                dynindx = 0;
4434
                dynaddend = value - dtp_base;
4435
              }
4436
            else if (info->shared
4437
                     && r_symndx != 0
4438
                     && (input_section->flags & SEC_ALLOC)
4439
                     && !undef_weak_ref)
4440
              {
4441
                if (r_type == R_ALPHA_REFLONG)
4442
                  {
4443
                    (*_bfd_error_handler)
4444
                      (_("%B: unhandled dynamic relocation against %s"),
4445
                       input_bfd,
4446
                       h->root.root.root.string);
4447
                    ret_val = FALSE;
4448
                  }
4449
                dynindx = 0;
4450
                dyntype = R_ALPHA_RELATIVE;
4451
                dynaddend = value;
4452
              }
4453
            else
4454
              goto default_reloc;
4455
 
4456
            if (input_section->flags & SEC_ALLOC)
4457
              elf64_alpha_emit_dynrel (output_bfd, info, input_section,
4458
                                       srel, rel->r_offset, dynindx,
4459
                                       dyntype, dynaddend);
4460
          }
4461
          goto default_reloc;
4462
 
4463
        case R_ALPHA_SREL16:
4464
        case R_ALPHA_SREL32:
4465
        case R_ALPHA_SREL64:
4466
          if (dynamic_symbol_p)
4467
            {
4468
              (*_bfd_error_handler)
4469
                (_("%B: pc-relative relocation against dynamic symbol %s"),
4470
                 input_bfd, h->root.root.root.string);
4471
              ret_val = FALSE;
4472
            }
4473
          else if ((info->shared || info->pie) && undef_weak_ref)
4474
            {
4475
              (*_bfd_error_handler)
4476
                (_("%B: pc-relative relocation against undefined weak symbol %s"),
4477
                 input_bfd, h->root.root.root.string);
4478
              ret_val = FALSE;
4479
            }
4480
 
4481
 
4482
          /* ??? .eh_frame references to discarded sections will be smashed
4483
             to relocations against SHN_UNDEF.  The .eh_frame format allows
4484
             NULL to be encoded as 0 in any format, so this works here.  */
4485
          if (r_symndx == 0)
4486
            howto = (elf64_alpha_howto_table
4487
                     + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG));
4488
          goto default_reloc;
4489
 
4490
        case R_ALPHA_TLSLDM:
4491
          /* Ignore the symbol for the relocation.  The result is always
4492
             the current module.  */
4493
          dynamic_symbol_p = 0;
4494
          /* FALLTHRU */
4495
 
4496
        case R_ALPHA_TLSGD:
4497
          if (!gotent->reloc_done)
4498
            {
4499
              gotent->reloc_done = 1;
4500
 
4501
              /* Note that the module index for the main program is 1.  */
4502
              bfd_put_64 (output_bfd, !info->shared && !dynamic_symbol_p,
4503
                          sgot->contents + gotent->got_offset);
4504
 
4505
              /* If the symbol has been forced local, output a
4506
                 DTPMOD64 reloc, otherwise it will be handled in
4507
                 finish_dynamic_symbol.  */
4508
              if (info->shared && !dynamic_symbol_p)
4509
                elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
4510
                                         gotent->got_offset, 0,
4511
                                         R_ALPHA_DTPMOD64, 0);
4512
 
4513
              if (dynamic_symbol_p || r_type == R_ALPHA_TLSLDM)
4514
                value = 0;
4515
              else
4516
                {
4517
                  BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4518
                  value -= dtp_base;
4519
                }
4520
              bfd_put_64 (output_bfd, value,
4521
                          sgot->contents + gotent->got_offset + 8);
4522
            }
4523
 
4524
          value = (sgot->output_section->vma
4525
                   + sgot->output_offset
4526
                   + gotent->got_offset);
4527
          value -= gp;
4528
          goto default_reloc;
4529
 
4530
        case R_ALPHA_DTPRELHI:
4531
        case R_ALPHA_DTPRELLO:
4532
        case R_ALPHA_DTPREL16:
4533
          if (dynamic_symbol_p)
4534
            {
4535
              (*_bfd_error_handler)
4536
                (_("%B: dtp-relative relocation against dynamic symbol %s"),
4537
                 input_bfd, h->root.root.root.string);
4538
              ret_val = FALSE;
4539
            }
4540
          BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4541
          value -= dtp_base;
4542
          if (r_type == R_ALPHA_DTPRELHI)
4543
            value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
4544
          goto default_reloc;
4545
 
4546
        case R_ALPHA_TPRELHI:
4547
        case R_ALPHA_TPRELLO:
4548
        case R_ALPHA_TPREL16:
4549
          if (info->shared)
4550
            {
4551
              (*_bfd_error_handler)
4552
                (_("%B: TLS local exec code cannot be linked into shared objects"),
4553
                input_bfd);
4554
              ret_val = FALSE;
4555
            }
4556
          else if (dynamic_symbol_p)
4557
            {
4558
              (*_bfd_error_handler)
4559
                (_("%B: tp-relative relocation against dynamic symbol %s"),
4560
                 input_bfd, h->root.root.root.string);
4561
              ret_val = FALSE;
4562
            }
4563
          BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4564
          value -= tp_base;
4565
          if (r_type == R_ALPHA_TPRELHI)
4566
            value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
4567
          goto default_reloc;
4568
 
4569
        case R_ALPHA_GOTDTPREL:
4570
        case R_ALPHA_GOTTPREL:
4571
          BFD_ASSERT(sgot != NULL);
4572
          BFD_ASSERT(gp != 0);
4573
          BFD_ASSERT(gotent != NULL);
4574
          BFD_ASSERT(gotent->use_count >= 1);
4575
 
4576
          if (!gotent->reloc_done)
4577
            {
4578
              gotent->reloc_done = 1;
4579
 
4580
              if (dynamic_symbol_p)
4581
                value = 0;
4582
              else
4583
                {
4584
                  BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4585
                  if (r_type == R_ALPHA_GOTDTPREL)
4586
                    value -= dtp_base;
4587
                  else if (!info->shared)
4588
                    value -= tp_base;
4589
                  else
4590
                    {
4591
                      elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
4592
                                               gotent->got_offset, 0,
4593
                                               R_ALPHA_TPREL64,
4594
                                               value - dtp_base);
4595
                      value = 0;
4596
                    }
4597
                }
4598
              bfd_put_64 (output_bfd, value,
4599
                          sgot->contents + gotent->got_offset);
4600
            }
4601
 
4602
          value = (sgot->output_section->vma
4603
                   + sgot->output_offset
4604
                   + gotent->got_offset);
4605
          value -= gp;
4606
          goto default_reloc;
4607
 
4608
        default:
4609
        default_reloc:
4610
          r = _bfd_final_link_relocate (howto, input_bfd, input_section,
4611
                                        contents, rel->r_offset, value, 0);
4612
          break;
4613
        }
4614
 
4615
      switch (r)
4616
        {
4617
        case bfd_reloc_ok:
4618
          break;
4619
 
4620
        case bfd_reloc_overflow:
4621
          {
4622
            const char *name;
4623
 
4624
            /* Don't warn if the overflow is due to pc relative reloc
4625
               against discarded section.  Section optimization code should
4626
               handle it.  */
4627
 
4628
            if (r_symndx < symtab_hdr->sh_info
4629
                && sec != NULL && howto->pc_relative
4630
                && elf_discarded_section (sec))
4631
              break;
4632
 
4633
            if (h != NULL)
4634
              name = NULL;
4635
            else
4636
              {
4637
                name = (bfd_elf_string_from_elf_section
4638
                        (input_bfd, symtab_hdr->sh_link, sym->st_name));
4639
                if (name == NULL)
4640
                  return FALSE;
4641
                if (*name == '\0')
4642
                  name = bfd_section_name (input_bfd, sec);
4643
              }
4644
            if (! ((*info->callbacks->reloc_overflow)
4645
                   (info, (h ? &h->root.root : NULL), name, howto->name,
4646
                    (bfd_vma) 0, input_bfd, input_section,
4647
                    rel->r_offset)))
4648
              ret_val = FALSE;
4649
          }
4650
          break;
4651
 
4652
        default:
4653
        case bfd_reloc_outofrange:
4654
          abort ();
4655
        }
4656
    }
4657
 
4658
  return ret_val;
4659
}
4660
 
4661
/* Finish up dynamic symbol handling.  We set the contents of various
4662
   dynamic sections here.  */
4663
 
4664
static bfd_boolean
4665
elf64_alpha_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
4666
                                   struct elf_link_hash_entry *h,
4667
                                   Elf_Internal_Sym *sym)
4668
{
4669
  struct alpha_elf_link_hash_entry *ah = (struct alpha_elf_link_hash_entry *)h;
4670
  bfd *dynobj = elf_hash_table(info)->dynobj;
4671
 
4672
  if (h->needs_plt)
4673
    {
4674
      /* Fill in the .plt entry for this symbol.  */
4675
      asection *splt, *sgot, *srel;
4676
      Elf_Internal_Rela outrel;
4677
      bfd_byte *loc;
4678
      bfd_vma got_addr, plt_addr;
4679
      bfd_vma plt_index;
4680
      struct alpha_elf_got_entry *gotent;
4681
 
4682
      BFD_ASSERT (h->dynindx != -1);
4683
 
4684
      splt = bfd_get_section_by_name (dynobj, ".plt");
4685
      BFD_ASSERT (splt != NULL);
4686
      srel = bfd_get_section_by_name (dynobj, ".rela.plt");
4687
      BFD_ASSERT (srel != NULL);
4688
 
4689
      for (gotent = ah->got_entries; gotent ; gotent = gotent->next)
4690
        if (gotent->reloc_type == R_ALPHA_LITERAL
4691
            && gotent->use_count > 0)
4692
          {
4693
            unsigned int insn;
4694
            int disp;
4695
 
4696
            sgot = alpha_elf_tdata (gotent->gotobj)->got;
4697
            BFD_ASSERT (sgot != NULL);
4698
 
4699
            BFD_ASSERT (gotent->got_offset != -1);
4700
            BFD_ASSERT (gotent->plt_offset != -1);
4701
 
4702
            got_addr = (sgot->output_section->vma
4703
                        + sgot->output_offset
4704
                        + gotent->got_offset);
4705
            plt_addr = (splt->output_section->vma
4706
                        + splt->output_offset
4707
                        + gotent->plt_offset);
4708
 
4709
            plt_index = (gotent->plt_offset-PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
4710
 
4711
            /* Fill in the entry in the procedure linkage table.  */
4712
            if (elf64_alpha_use_secureplt)
4713
              {
4714
                disp = (PLT_HEADER_SIZE - 4) - (gotent->plt_offset + 4);
4715
                insn = INSN_AD (INSN_BR, 31, disp);
4716
                bfd_put_32 (output_bfd, insn,
4717
                            splt->contents + gotent->plt_offset);
4718
 
4719
                plt_index = ((gotent->plt_offset - NEW_PLT_HEADER_SIZE)
4720
                             / NEW_PLT_ENTRY_SIZE);
4721
              }
4722
            else
4723
              {
4724
                disp = -(gotent->plt_offset + 4);
4725
                insn = INSN_AD (INSN_BR, 28, disp);
4726
                bfd_put_32 (output_bfd, insn,
4727
                            splt->contents + gotent->plt_offset);
4728
                bfd_put_32 (output_bfd, INSN_UNOP,
4729
                            splt->contents + gotent->plt_offset + 4);
4730
                bfd_put_32 (output_bfd, INSN_UNOP,
4731
                            splt->contents + gotent->plt_offset + 8);
4732
 
4733
                plt_index = ((gotent->plt_offset - OLD_PLT_HEADER_SIZE)
4734
                             / OLD_PLT_ENTRY_SIZE);
4735
              }
4736
 
4737
            /* Fill in the entry in the .rela.plt section.  */
4738
            outrel.r_offset = got_addr;
4739
            outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT);
4740
            outrel.r_addend = 0;
4741
 
4742
            loc = srel->contents + plt_index * sizeof (Elf64_External_Rela);
4743
            bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
4744
 
4745
            /* Fill in the entry in the .got.  */
4746
            bfd_put_64 (output_bfd, plt_addr,
4747
                        sgot->contents + gotent->got_offset);
4748
          }
4749
    }
4750
  else if (alpha_elf_dynamic_symbol_p (h, info))
4751
    {
4752
      /* Fill in the dynamic relocations for this symbol's .got entries.  */
4753
      asection *srel;
4754
      struct alpha_elf_got_entry *gotent;
4755
 
4756
      srel = bfd_get_section_by_name (dynobj, ".rela.got");
4757
      BFD_ASSERT (srel != NULL);
4758
 
4759
      for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
4760
           gotent != NULL;
4761
           gotent = gotent->next)
4762
        {
4763
          asection *sgot;
4764
          long r_type;
4765
 
4766
          if (gotent->use_count == 0)
4767
            continue;
4768
 
4769
          sgot = alpha_elf_tdata (gotent->gotobj)->got;
4770
 
4771
          r_type = gotent->reloc_type;
4772
          switch (r_type)
4773
            {
4774
            case R_ALPHA_LITERAL:
4775
              r_type = R_ALPHA_GLOB_DAT;
4776
              break;
4777
            case R_ALPHA_TLSGD:
4778
              r_type = R_ALPHA_DTPMOD64;
4779
              break;
4780
            case R_ALPHA_GOTDTPREL:
4781
              r_type = R_ALPHA_DTPREL64;
4782
              break;
4783
            case R_ALPHA_GOTTPREL:
4784
              r_type = R_ALPHA_TPREL64;
4785
              break;
4786
            case R_ALPHA_TLSLDM:
4787
            default:
4788
              abort ();
4789
            }
4790
 
4791
          elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
4792
                                   gotent->got_offset, h->dynindx,
4793
                                   r_type, gotent->addend);
4794
 
4795
          if (gotent->reloc_type == R_ALPHA_TLSGD)
4796
            elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
4797
                                     gotent->got_offset + 8, h->dynindx,
4798
                                     R_ALPHA_DTPREL64, gotent->addend);
4799
        }
4800
    }
4801
 
4802
  /* Mark some specially defined symbols as absolute.  */
4803
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4804
      || h == elf_hash_table (info)->hgot
4805
      || h == elf_hash_table (info)->hplt)
4806
    sym->st_shndx = SHN_ABS;
4807
 
4808
  return TRUE;
4809
}
4810
 
4811
/* Finish up the dynamic sections.  */
4812
 
4813
static bfd_boolean
4814
elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
4815
                                     struct bfd_link_info *info)
4816
{
4817
  bfd *dynobj;
4818
  asection *sdyn;
4819
 
4820
  dynobj = elf_hash_table (info)->dynobj;
4821
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4822
 
4823
  if (elf_hash_table (info)->dynamic_sections_created)
4824
    {
4825
      asection *splt, *sgotplt, *srelaplt;
4826
      Elf64_External_Dyn *dyncon, *dynconend;
4827
      bfd_vma plt_vma, gotplt_vma;
4828
 
4829
      splt = bfd_get_section_by_name (dynobj, ".plt");
4830
      srelaplt = bfd_get_section_by_name (output_bfd, ".rela.plt");
4831
      BFD_ASSERT (splt != NULL && sdyn != NULL);
4832
 
4833
      plt_vma = splt->output_section->vma + splt->output_offset;
4834
 
4835
      gotplt_vma = 0;
4836
      if (elf64_alpha_use_secureplt)
4837
        {
4838
          sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4839
          BFD_ASSERT (sgotplt != NULL);
4840
          if (sgotplt->size > 0)
4841
            gotplt_vma = sgotplt->output_section->vma + sgotplt->output_offset;
4842
        }
4843
 
4844
      dyncon = (Elf64_External_Dyn *) sdyn->contents;
4845
      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
4846
      for (; dyncon < dynconend; dyncon++)
4847
        {
4848
          Elf_Internal_Dyn dyn;
4849
 
4850
          bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
4851
 
4852
          switch (dyn.d_tag)
4853
            {
4854
            case DT_PLTGOT:
4855
              dyn.d_un.d_ptr
4856
                = elf64_alpha_use_secureplt ? gotplt_vma : plt_vma;
4857
              break;
4858
            case DT_PLTRELSZ:
4859
              dyn.d_un.d_val = srelaplt ? srelaplt->size : 0;
4860
              break;
4861
            case DT_JMPREL:
4862
              dyn.d_un.d_ptr = srelaplt ? srelaplt->vma : 0;
4863
              break;
4864
 
4865
            case DT_RELASZ:
4866
              /* My interpretation of the TIS v1.1 ELF document indicates
4867
                 that RELASZ should not include JMPREL.  This is not what
4868
                 the rest of the BFD does.  It is, however, what the
4869
                 glibc ld.so wants.  Do this fixup here until we found
4870
                 out who is right.  */
4871
              if (srelaplt)
4872
                dyn.d_un.d_val -= srelaplt->size;
4873
              break;
4874
            }
4875
 
4876
          bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
4877
        }
4878
 
4879
      /* Initialize the plt header.  */
4880
      if (splt->size > 0)
4881
        {
4882
          unsigned int insn;
4883
          int ofs;
4884
 
4885
          if (elf64_alpha_use_secureplt)
4886
            {
4887
              ofs = gotplt_vma - (plt_vma + PLT_HEADER_SIZE);
4888
 
4889
              insn = INSN_ABC (INSN_SUBQ, 27, 28, 25);
4890
              bfd_put_32 (output_bfd, insn, splt->contents);
4891
 
4892
              insn = INSN_ABO (INSN_LDAH, 28, 28, (ofs + 0x8000) >> 16);
4893
              bfd_put_32 (output_bfd, insn, splt->contents + 4);
4894
 
4895
              insn = INSN_ABC (INSN_S4SUBQ, 25, 25, 25);
4896
              bfd_put_32 (output_bfd, insn, splt->contents + 8);
4897
 
4898
              insn = INSN_ABO (INSN_LDA, 28, 28, ofs);
4899
              bfd_put_32 (output_bfd, insn, splt->contents + 12);
4900
 
4901
              insn = INSN_ABO (INSN_LDQ, 27, 28, 0);
4902
              bfd_put_32 (output_bfd, insn, splt->contents + 16);
4903
 
4904
              insn = INSN_ABC (INSN_ADDQ, 25, 25, 25);
4905
              bfd_put_32 (output_bfd, insn, splt->contents + 20);
4906
 
4907
              insn = INSN_ABO (INSN_LDQ, 28, 28, 8);
4908
              bfd_put_32 (output_bfd, insn, splt->contents + 24);
4909
 
4910
              insn = INSN_AB (INSN_JMP, 31, 27);
4911
              bfd_put_32 (output_bfd, insn, splt->contents + 28);
4912
 
4913
              insn = INSN_AD (INSN_BR, 28, -PLT_HEADER_SIZE);
4914
              bfd_put_32 (output_bfd, insn, splt->contents + 32);
4915
            }
4916
          else
4917
            {
4918
              insn = INSN_AD (INSN_BR, 27, 0);   /* br $27, .+4 */
4919
              bfd_put_32 (output_bfd, insn, splt->contents);
4920
 
4921
              insn = INSN_ABO (INSN_LDQ, 27, 27, 12);
4922
              bfd_put_32 (output_bfd, insn, splt->contents + 4);
4923
 
4924
              insn = INSN_UNOP;
4925
              bfd_put_32 (output_bfd, insn, splt->contents + 8);
4926
 
4927
              insn = INSN_AB (INSN_JMP, 27, 27);
4928
              bfd_put_32 (output_bfd, insn, splt->contents + 12);
4929
 
4930
              /* The next two words will be filled in by ld.so.  */
4931
              bfd_put_64 (output_bfd, 0, splt->contents + 16);
4932
              bfd_put_64 (output_bfd, 0, splt->contents + 24);
4933
            }
4934
 
4935
          elf_section_data (splt->output_section)->this_hdr.sh_entsize = 0;
4936
        }
4937
    }
4938
 
4939
  return TRUE;
4940
}
4941
 
4942
/* We need to use a special link routine to handle the .mdebug section.
4943
   We need to merge all instances of these sections together, not write
4944
   them all out sequentially.  */
4945
 
4946
static bfd_boolean
4947
elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info)
4948
{
4949
  asection *o;
4950
  struct bfd_link_order *p;
4951
  asection *mdebug_sec;
4952
  struct ecoff_debug_info debug;
4953
  const struct ecoff_debug_swap *swap
4954
    = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
4955
  HDRR *symhdr = &debug.symbolic_header;
4956
  PTR mdebug_handle = NULL;
4957
 
4958
  /* Go through the sections and collect the mdebug information.  */
4959
  mdebug_sec = NULL;
4960
  for (o = abfd->sections; o != (asection *) NULL; o = o->next)
4961
    {
4962
      if (strcmp (o->name, ".mdebug") == 0)
4963
        {
4964
          struct extsym_info einfo;
4965
 
4966
          /* We have found the .mdebug section in the output file.
4967
             Look through all the link_orders comprising it and merge
4968
             the information together.  */
4969
          symhdr->magic = swap->sym_magic;
4970
          /* FIXME: What should the version stamp be?  */
4971
          symhdr->vstamp = 0;
4972
          symhdr->ilineMax = 0;
4973
          symhdr->cbLine = 0;
4974
          symhdr->idnMax = 0;
4975
          symhdr->ipdMax = 0;
4976
          symhdr->isymMax = 0;
4977
          symhdr->ioptMax = 0;
4978
          symhdr->iauxMax = 0;
4979
          symhdr->issMax = 0;
4980
          symhdr->issExtMax = 0;
4981
          symhdr->ifdMax = 0;
4982
          symhdr->crfd = 0;
4983
          symhdr->iextMax = 0;
4984
 
4985
          /* We accumulate the debugging information itself in the
4986
             debug_info structure.  */
4987
          debug.line = NULL;
4988
          debug.external_dnr = NULL;
4989
          debug.external_pdr = NULL;
4990
          debug.external_sym = NULL;
4991
          debug.external_opt = NULL;
4992
          debug.external_aux = NULL;
4993
          debug.ss = NULL;
4994
          debug.ssext = debug.ssext_end = NULL;
4995
          debug.external_fdr = NULL;
4996
          debug.external_rfd = NULL;
4997
          debug.external_ext = debug.external_ext_end = NULL;
4998
 
4999
          mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
5000
          if (mdebug_handle == (PTR) NULL)
5001
            return FALSE;
5002
 
5003
          if (1)
5004
            {
5005
              asection *s;
5006
              EXTR esym;
5007
              bfd_vma last = 0;
5008
              unsigned int i;
5009
              static const char * const name[] =
5010
                {
5011
                  ".text", ".init", ".fini", ".data",
5012
                  ".rodata", ".sdata", ".sbss", ".bss"
5013
                };
5014
              static const int sc[] = { scText, scInit, scFini, scData,
5015
                                          scRData, scSData, scSBss, scBss };
5016
 
5017
              esym.jmptbl = 0;
5018
              esym.cobol_main = 0;
5019
              esym.weakext = 0;
5020
              esym.reserved = 0;
5021
              esym.ifd = ifdNil;
5022
              esym.asym.iss = issNil;
5023
              esym.asym.st = stLocal;
5024
              esym.asym.reserved = 0;
5025
              esym.asym.index = indexNil;
5026
              for (i = 0; i < 8; i++)
5027
                {
5028
                  esym.asym.sc = sc[i];
5029
                  s = bfd_get_section_by_name (abfd, name[i]);
5030
                  if (s != NULL)
5031
                    {
5032
                      esym.asym.value = s->vma;
5033
                      last = s->vma + s->size;
5034
                    }
5035
                  else
5036
                    esym.asym.value = last;
5037
 
5038
                  if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
5039
                                                      name[i], &esym))
5040
                    return FALSE;
5041
                }
5042
            }
5043
 
5044
          for (p = o->map_head.link_order;
5045
               p != (struct bfd_link_order *) NULL;
5046
               p = p->next)
5047
            {
5048
              asection *input_section;
5049
              bfd *input_bfd;
5050
              const struct ecoff_debug_swap *input_swap;
5051
              struct ecoff_debug_info input_debug;
5052
              char *eraw_src;
5053
              char *eraw_end;
5054
 
5055
              if (p->type != bfd_indirect_link_order)
5056
                {
5057
                  if (p->type == bfd_data_link_order)
5058
                    continue;
5059
                  abort ();
5060
                }
5061
 
5062
              input_section = p->u.indirect.section;
5063
              input_bfd = input_section->owner;
5064
 
5065
              if (! is_alpha_elf (input_bfd))
5066
                /* I don't know what a non ALPHA ELF bfd would be
5067
                   doing with a .mdebug section, but I don't really
5068
                   want to deal with it.  */
5069
                continue;
5070
 
5071
              input_swap = (get_elf_backend_data (input_bfd)
5072
                            ->elf_backend_ecoff_debug_swap);
5073
 
5074
              BFD_ASSERT (p->size == input_section->size);
5075
 
5076
              /* The ECOFF linking code expects that we have already
5077
                 read in the debugging information and set up an
5078
                 ecoff_debug_info structure, so we do that now.  */
5079
              if (!elf64_alpha_read_ecoff_info (input_bfd, input_section,
5080
                                                &input_debug))
5081
                return FALSE;
5082
 
5083
              if (! (bfd_ecoff_debug_accumulate
5084
                     (mdebug_handle, abfd, &debug, swap, input_bfd,
5085
                      &input_debug, input_swap, info)))
5086
                return FALSE;
5087
 
5088
              /* Loop through the external symbols.  For each one with
5089
                 interesting information, try to find the symbol in
5090
                 the linker global hash table and save the information
5091
                 for the output external symbols.  */
5092
              eraw_src = input_debug.external_ext;
5093
              eraw_end = (eraw_src
5094
                          + (input_debug.symbolic_header.iextMax
5095
                             * input_swap->external_ext_size));
5096
              for (;
5097
                   eraw_src < eraw_end;
5098
                   eraw_src += input_swap->external_ext_size)
5099
                {
5100
                  EXTR ext;
5101
                  const char *name;
5102
                  struct alpha_elf_link_hash_entry *h;
5103
 
5104
                  (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
5105
                  if (ext.asym.sc == scNil
5106
                      || ext.asym.sc == scUndefined
5107
                      || ext.asym.sc == scSUndefined)
5108
                    continue;
5109
 
5110
                  name = input_debug.ssext + ext.asym.iss;
5111
                  h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info),
5112
                                                  name, FALSE, FALSE, TRUE);
5113
                  if (h == NULL || h->esym.ifd != -2)
5114
                    continue;
5115
 
5116
                  if (ext.ifd != -1)
5117
                    {
5118
                      BFD_ASSERT (ext.ifd
5119
                                  < input_debug.symbolic_header.ifdMax);
5120
                      ext.ifd = input_debug.ifdmap[ext.ifd];
5121
                    }
5122
 
5123
                  h->esym = ext;
5124
                }
5125
 
5126
              /* Free up the information we just read.  */
5127
              free (input_debug.line);
5128
              free (input_debug.external_dnr);
5129
              free (input_debug.external_pdr);
5130
              free (input_debug.external_sym);
5131
              free (input_debug.external_opt);
5132
              free (input_debug.external_aux);
5133
              free (input_debug.ss);
5134
              free (input_debug.ssext);
5135
              free (input_debug.external_fdr);
5136
              free (input_debug.external_rfd);
5137
              free (input_debug.external_ext);
5138
 
5139
              /* Hack: reset the SEC_HAS_CONTENTS flag so that
5140
                 elf_link_input_bfd ignores this section.  */
5141
              input_section->flags &=~ SEC_HAS_CONTENTS;
5142
            }
5143
 
5144
          /* Build the external symbol information.  */
5145
          einfo.abfd = abfd;
5146
          einfo.info = info;
5147
          einfo.debug = &debug;
5148
          einfo.swap = swap;
5149
          einfo.failed = FALSE;
5150
          elf_link_hash_traverse (elf_hash_table (info),
5151
                                  elf64_alpha_output_extsym,
5152
                                  (PTR) &einfo);
5153
          if (einfo.failed)
5154
            return FALSE;
5155
 
5156
          /* Set the size of the .mdebug section.  */
5157
          o->size = bfd_ecoff_debug_size (abfd, &debug, swap);
5158
 
5159
          /* Skip this section later on (I don't think this currently
5160
             matters, but someday it might).  */
5161
          o->map_head.link_order = (struct bfd_link_order *) NULL;
5162
 
5163
          mdebug_sec = o;
5164
        }
5165
    }
5166
 
5167
  /* Invoke the regular ELF backend linker to do all the work.  */
5168
  if (! bfd_elf_final_link (abfd, info))
5169
    return FALSE;
5170
 
5171
  /* Now write out the computed sections.  */
5172
 
5173
  /* The .got subsections...  */
5174
  {
5175
    bfd *i, *dynobj = elf_hash_table(info)->dynobj;
5176
    for (i = alpha_elf_hash_table(info)->got_list;
5177
         i != NULL;
5178
         i = alpha_elf_tdata(i)->got_link_next)
5179
      {
5180
        asection *sgot;
5181
 
5182
        /* elf_bfd_final_link already did everything in dynobj.  */
5183
        if (i == dynobj)
5184
          continue;
5185
 
5186
        sgot = alpha_elf_tdata(i)->got;
5187
        if (! bfd_set_section_contents (abfd, sgot->output_section,
5188
                                        sgot->contents,
5189
                                        (file_ptr) sgot->output_offset,
5190
                                        sgot->size))
5191
          return FALSE;
5192
      }
5193
  }
5194
 
5195
  if (mdebug_sec != (asection *) NULL)
5196
    {
5197
      BFD_ASSERT (abfd->output_has_begun);
5198
      if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
5199
                                               swap, info,
5200
                                               mdebug_sec->filepos))
5201
        return FALSE;
5202
 
5203
      bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
5204
    }
5205
 
5206
  return TRUE;
5207
}
5208
 
5209
static enum elf_reloc_type_class
5210
elf64_alpha_reloc_type_class (const Elf_Internal_Rela *rela)
5211
{
5212
  switch ((int) ELF64_R_TYPE (rela->r_info))
5213
    {
5214
    case R_ALPHA_RELATIVE:
5215
      return reloc_class_relative;
5216
    case R_ALPHA_JMP_SLOT:
5217
      return reloc_class_plt;
5218
    case R_ALPHA_COPY:
5219
      return reloc_class_copy;
5220
    default:
5221
      return reloc_class_normal;
5222
    }
5223
}
5224
 
5225
static const struct bfd_elf_special_section elf64_alpha_special_sections[] =
5226
{
5227
  { STRING_COMMA_LEN (".sbss"),  -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
5228
  { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
5229
  { NULL,                     0,  0, 0,            0 }
5230
};
5231
 
5232
/* ECOFF swapping routines.  These are used when dealing with the
5233
   .mdebug section, which is in the ECOFF debugging format.  Copied
5234
   from elf32-mips.c.  */
5235
static const struct ecoff_debug_swap
5236
elf64_alpha_ecoff_debug_swap =
5237
{
5238
  /* Symbol table magic number.  */
5239
  magicSym2,
5240
  /* Alignment of debugging information.  E.g., 4.  */
5241
  8,
5242
  /* Sizes of external symbolic information.  */
5243
  sizeof (struct hdr_ext),
5244
  sizeof (struct dnr_ext),
5245
  sizeof (struct pdr_ext),
5246
  sizeof (struct sym_ext),
5247
  sizeof (struct opt_ext),
5248
  sizeof (struct fdr_ext),
5249
  sizeof (struct rfd_ext),
5250
  sizeof (struct ext_ext),
5251
  /* Functions to swap in external symbolic data.  */
5252
  ecoff_swap_hdr_in,
5253
  ecoff_swap_dnr_in,
5254
  ecoff_swap_pdr_in,
5255
  ecoff_swap_sym_in,
5256
  ecoff_swap_opt_in,
5257
  ecoff_swap_fdr_in,
5258
  ecoff_swap_rfd_in,
5259
  ecoff_swap_ext_in,
5260
  _bfd_ecoff_swap_tir_in,
5261
  _bfd_ecoff_swap_rndx_in,
5262
  /* Functions to swap out external symbolic data.  */
5263
  ecoff_swap_hdr_out,
5264
  ecoff_swap_dnr_out,
5265
  ecoff_swap_pdr_out,
5266
  ecoff_swap_sym_out,
5267
  ecoff_swap_opt_out,
5268
  ecoff_swap_fdr_out,
5269
  ecoff_swap_rfd_out,
5270
  ecoff_swap_ext_out,
5271
  _bfd_ecoff_swap_tir_out,
5272
  _bfd_ecoff_swap_rndx_out,
5273
  /* Function to read in symbolic data.  */
5274
  elf64_alpha_read_ecoff_info
5275
};
5276
 
5277
/* Use a non-standard hash bucket size of 8.  */
5278
 
5279
static const struct elf_size_info alpha_elf_size_info =
5280
{
5281
  sizeof (Elf64_External_Ehdr),
5282
  sizeof (Elf64_External_Phdr),
5283
  sizeof (Elf64_External_Shdr),
5284
  sizeof (Elf64_External_Rel),
5285
  sizeof (Elf64_External_Rela),
5286
  sizeof (Elf64_External_Sym),
5287
  sizeof (Elf64_External_Dyn),
5288
  sizeof (Elf_External_Note),
5289
  8,
5290
  1,
5291
  64, 3,
5292
  ELFCLASS64, EV_CURRENT,
5293
  bfd_elf64_write_out_phdrs,
5294
  bfd_elf64_write_shdrs_and_ehdr,
5295
  bfd_elf64_checksum_contents,
5296
  bfd_elf64_write_relocs,
5297
  bfd_elf64_swap_symbol_in,
5298
  bfd_elf64_swap_symbol_out,
5299
  bfd_elf64_slurp_reloc_table,
5300
  bfd_elf64_slurp_symbol_table,
5301
  bfd_elf64_swap_dyn_in,
5302
  bfd_elf64_swap_dyn_out,
5303
  bfd_elf64_swap_reloc_in,
5304
  bfd_elf64_swap_reloc_out,
5305
  bfd_elf64_swap_reloca_in,
5306
  bfd_elf64_swap_reloca_out
5307
};
5308
 
5309
#define TARGET_LITTLE_SYM       bfd_elf64_alpha_vec
5310
#define TARGET_LITTLE_NAME      "elf64-alpha"
5311
#define ELF_ARCH                bfd_arch_alpha
5312
#define ELF_MACHINE_CODE        EM_ALPHA
5313
#define ELF_MAXPAGESIZE 0x10000
5314
#define ELF_COMMONPAGESIZE      0x2000
5315
 
5316
#define bfd_elf64_bfd_link_hash_table_create \
5317
  elf64_alpha_bfd_link_hash_table_create
5318
 
5319
#define bfd_elf64_bfd_reloc_type_lookup \
5320
  elf64_alpha_bfd_reloc_type_lookup
5321
#define bfd_elf64_bfd_reloc_name_lookup \
5322
  elf64_alpha_bfd_reloc_name_lookup
5323
#define elf_info_to_howto \
5324
  elf64_alpha_info_to_howto
5325
 
5326
#define bfd_elf64_mkobject \
5327
  elf64_alpha_mkobject
5328
#define elf_backend_object_p \
5329
  elf64_alpha_object_p
5330
 
5331
#define elf_backend_section_from_shdr \
5332
  elf64_alpha_section_from_shdr
5333
#define elf_backend_section_flags \
5334
  elf64_alpha_section_flags
5335
#define elf_backend_fake_sections \
5336
  elf64_alpha_fake_sections
5337
 
5338
#define bfd_elf64_bfd_is_local_label_name \
5339
  elf64_alpha_is_local_label_name
5340
#define bfd_elf64_find_nearest_line \
5341
  elf64_alpha_find_nearest_line
5342
#define bfd_elf64_bfd_relax_section \
5343
  elf64_alpha_relax_section
5344
 
5345
#define elf_backend_add_symbol_hook \
5346
  elf64_alpha_add_symbol_hook
5347
#define elf_backend_relocs_compatible \
5348
  _bfd_elf_relocs_compatible
5349
#define elf_backend_check_relocs \
5350
  elf64_alpha_check_relocs
5351
#define elf_backend_create_dynamic_sections \
5352
  elf64_alpha_create_dynamic_sections
5353
#define elf_backend_adjust_dynamic_symbol \
5354
  elf64_alpha_adjust_dynamic_symbol
5355
#define elf_backend_merge_symbol_attribute \
5356
  elf64_alpha_merge_symbol_attribute
5357
#define elf_backend_always_size_sections \
5358
  elf64_alpha_always_size_sections
5359
#define elf_backend_size_dynamic_sections \
5360
  elf64_alpha_size_dynamic_sections
5361
#define elf_backend_omit_section_dynsym \
5362
  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5363
#define elf_backend_relocate_section \
5364
  elf64_alpha_relocate_section
5365
#define elf_backend_finish_dynamic_symbol \
5366
  elf64_alpha_finish_dynamic_symbol
5367
#define elf_backend_finish_dynamic_sections \
5368
  elf64_alpha_finish_dynamic_sections
5369
#define bfd_elf64_bfd_final_link \
5370
  elf64_alpha_final_link
5371
#define elf_backend_reloc_type_class \
5372
  elf64_alpha_reloc_type_class
5373
 
5374
#define elf_backend_ecoff_debug_swap \
5375
  &elf64_alpha_ecoff_debug_swap
5376
 
5377
#define elf_backend_size_info \
5378
  alpha_elf_size_info
5379
 
5380
#define elf_backend_special_sections \
5381
  elf64_alpha_special_sections
5382
 
5383
/* A few constants that determine how the .plt section is set up.  */
5384
#define elf_backend_want_got_plt 0
5385
#define elf_backend_plt_readonly 0
5386
#define elf_backend_want_plt_sym 1
5387
#define elf_backend_got_header_size 0
5388
 
5389
#include "elf64-target.h"
5390
 
5391
/* FreeBSD support.  */
5392
 
5393
#undef TARGET_LITTLE_SYM
5394
#define TARGET_LITTLE_SYM       bfd_elf64_alpha_freebsd_vec
5395
#undef TARGET_LITTLE_NAME
5396
#define TARGET_LITTLE_NAME      "elf64-alpha-freebsd"
5397
#undef  ELF_OSABI
5398
#define ELF_OSABI               ELFOSABI_FREEBSD
5399
 
5400
/* The kernel recognizes executables as valid only if they carry a
5401
   "FreeBSD" label in the ELF header.  So we put this label on all
5402
   executables and (for simplicity) also all other object files.  */
5403
 
5404
static void
5405
elf64_alpha_fbsd_post_process_headers (bfd * abfd,
5406
        struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
5407
{
5408
  Elf_Internal_Ehdr * i_ehdrp;  /* ELF file header, internal form.  */
5409
 
5410
  i_ehdrp = elf_elfheader (abfd);
5411
 
5412
  /* Put an ABI label supported by FreeBSD >= 4.1.  */
5413
  i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
5414
#ifdef OLD_FREEBSD_ABI_LABEL
5415
  /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard.  */
5416
  memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
5417
#endif
5418
}
5419
 
5420
#undef elf_backend_post_process_headers
5421
#define elf_backend_post_process_headers \
5422
  elf64_alpha_fbsd_post_process_headers
5423
 
5424
#undef  elf64_bed
5425
#define elf64_bed elf64_alpha_fbsd_bed
5426
 
5427
#include "elf64-target.h"

powered by: WebSVN 2.1.0

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