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 161

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

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

powered by: WebSVN 2.1.0

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