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

Subversion Repositories open8_urisc

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

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

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

powered by: WebSVN 2.1.0

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