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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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