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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elfnn-ia64.c] - Blame information for rev 53

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

Line No. Rev Author Line
1 14 khays
/* IA-64 support for 64-bit ELF
2
   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3
   2008, 2009, 2010, 2011  Free Software Foundation, Inc.
4
   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
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
#include "sysdep.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
#include "elf-bfd.h"
27
#include "opcode/ia64.h"
28
#include "elf/ia64.h"
29
#include "objalloc.h"
30
#include "hashtab.h"
31
#include "bfd_stdint.h"
32
#include "elfxx-ia64.h"
33
 
34
#define ARCH_SIZE       NN
35
 
36
#if ARCH_SIZE == 64
37
#define LOG_SECTION_ALIGN       3
38
#endif
39
 
40
#if ARCH_SIZE == 32
41
#define LOG_SECTION_ALIGN       2
42
#endif
43
 
44
/* Only add code for vms when the vms target is enabled.  This is required
45
   because it depends on vms-lib.c for its archive format and we don't want
46
   to compile that code if it is not used.  */
47
#if ARCH_SIZE == 64 && \
48
  (defined (HAVE_bfd_elf64_ia64_vms_vec) || defined (HAVE_all_vecs))
49
#define INCLUDE_IA64_VMS
50
#endif
51
 
52
typedef struct bfd_hash_entry *(*new_hash_entry_func)
53
  (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
54
 
55
/* In dynamically (linker-) created sections, we generally need to keep track
56
   of the place a symbol or expression got allocated to. This is done via hash
57
   tables that store entries of the following type.  */
58
 
59
struct elfNN_ia64_dyn_sym_info
60
{
61
  /* The addend for which this entry is relevant.  */
62
  bfd_vma addend;
63
 
64
  bfd_vma got_offset;
65
  bfd_vma fptr_offset;
66
  bfd_vma pltoff_offset;
67
  bfd_vma plt_offset;
68
  bfd_vma plt2_offset;
69
  bfd_vma tprel_offset;
70
  bfd_vma dtpmod_offset;
71
  bfd_vma dtprel_offset;
72
 
73
  /* The symbol table entry, if any, that this was derived from.  */
74
  struct elf_link_hash_entry *h;
75
 
76
  /* Used to count non-got, non-plt relocations for delayed sizing
77
     of relocation sections.  */
78
  struct elfNN_ia64_dyn_reloc_entry
79
  {
80
    struct elfNN_ia64_dyn_reloc_entry *next;
81
    asection *srel;
82
    int type;
83
    int count;
84
 
85
    /* Is this reloc against readonly section? */
86
    bfd_boolean reltext;
87
  } *reloc_entries;
88
 
89
  /* TRUE when the section contents have been updated.  */
90
  unsigned got_done : 1;
91
  unsigned fptr_done : 1;
92
  unsigned pltoff_done : 1;
93
  unsigned tprel_done : 1;
94
  unsigned dtpmod_done : 1;
95
  unsigned dtprel_done : 1;
96
 
97
  /* TRUE for the different kinds of linker data we want created.  */
98
  unsigned want_got : 1;
99
  unsigned want_gotx : 1;
100
  unsigned want_fptr : 1;
101
  unsigned want_ltoff_fptr : 1;
102
  unsigned want_plt : 1;
103
  unsigned want_plt2 : 1;
104
  unsigned want_pltoff : 1;
105
  unsigned want_tprel : 1;
106
  unsigned want_dtpmod : 1;
107
  unsigned want_dtprel : 1;
108
};
109
 
110
struct elfNN_ia64_local_hash_entry
111
{
112
  int id;
113
  unsigned int r_sym;
114
  /* The number of elements in elfNN_ia64_dyn_sym_info array.  */
115
  unsigned int count;
116
  /* The number of sorted elements in elfNN_ia64_dyn_sym_info array.  */
117
  unsigned int sorted_count;
118
  /* The size of elfNN_ia64_dyn_sym_info array.  */
119
  unsigned int size;
120
  /* The array of elfNN_ia64_dyn_sym_info.  */
121
  struct elfNN_ia64_dyn_sym_info *info;
122
 
123
  /* TRUE if this hash entry's addends was translated for
124
     SHF_MERGE optimization.  */
125
  unsigned sec_merge_done : 1;
126
};
127
 
128
struct elfNN_ia64_link_hash_entry
129
{
130
  struct elf_link_hash_entry root;
131
  /* The number of elements in elfNN_ia64_dyn_sym_info array.  */
132
  unsigned int count;
133
  /* The number of sorted elements in elfNN_ia64_dyn_sym_info array.  */
134
  unsigned int sorted_count;
135
  /* The size of elfNN_ia64_dyn_sym_info array.  */
136
  unsigned int size;
137
  /* The array of elfNN_ia64_dyn_sym_info.  */
138
  struct elfNN_ia64_dyn_sym_info *info;
139
};
140
 
141
struct elfNN_ia64_link_hash_table
142
{
143
  /* The main hash table.  */
144
  struct elf_link_hash_table root;
145
 
146
  asection *fptr_sec;           /* Function descriptor table (or NULL).  */
147
  asection *rel_fptr_sec;       /* Dynamic relocation section for same.  */
148
  asection *pltoff_sec;         /* Private descriptors for plt (or NULL).  */
149
  asection *rel_pltoff_sec;     /* Dynamic relocation section for same.  */
150
 
151
  bfd_size_type minplt_entries; /* Number of minplt entries.  */
152
  unsigned reltext : 1;         /* Are there relocs against readonly sections?  */
153
  unsigned self_dtpmod_done : 1;/* Has self DTPMOD entry been finished?  */
154
  bfd_vma self_dtpmod_offset;   /* .got offset to self DTPMOD entry.  */
155
  /* There are maybe R_IA64_GPREL22 relocations, including those
156
     optimized from R_IA64_LTOFF22X, against non-SHF_IA_64_SHORT
157
     sections.  We need to record those sections so that we can choose
158
     a proper GP to cover all R_IA64_GPREL22 relocations.  */
159
  asection *max_short_sec;      /* Maximum short output section.  */
160
  bfd_vma max_short_offset;     /* Maximum short offset.  */
161
  asection *min_short_sec;      /* Minimum short output section.  */
162
  bfd_vma min_short_offset;     /* Minimum short offset.  */
163
 
164
  htab_t loc_hash_table;
165
  void *loc_hash_memory;
166
};
167
 
168
struct elfNN_ia64_allocate_data
169
{
170
  struct bfd_link_info *info;
171
  bfd_size_type ofs;
172
  bfd_boolean only_got;
173
};
174
 
175
#define elfNN_ia64_hash_table(p) \
176
  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
177
  == IA64_ELF_DATA ? ((struct elfNN_ia64_link_hash_table *) ((p)->hash)) : NULL)
178
 
179
static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
180
  (struct elfNN_ia64_link_hash_table *ia64_info,
181
   struct elf_link_hash_entry *h,
182
   bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create);
183
static bfd_boolean elfNN_ia64_dynamic_symbol_p
184
  (struct elf_link_hash_entry *h, struct bfd_link_info *info, int);
185
static bfd_boolean elfNN_ia64_choose_gp
186
  (bfd *abfd, struct bfd_link_info *info, bfd_boolean final);
187
static void elfNN_ia64_dyn_sym_traverse
188
  (struct elfNN_ia64_link_hash_table *ia64_info,
189
   bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
190
   PTR info);
191
static bfd_boolean allocate_global_data_got
192
  (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
193
static bfd_boolean allocate_global_fptr_got
194
  (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
195
static bfd_boolean allocate_local_got
196
  (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
197
static bfd_boolean elfNN_ia64_hpux_vec
198
  (const bfd_target *vec);
199
static bfd_boolean allocate_dynrel_entries
200
  (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
201
static asection *get_pltoff
202
  (bfd *abfd, struct bfd_link_info *info,
203
   struct elfNN_ia64_link_hash_table *ia64_info);
204
 
205
/* ia64-specific relocation.  */
206
 
207
/* Given a ELF reloc, return the matching HOWTO structure.  */
208
 
209
static void
210
elfNN_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
211
                          arelent *bfd_reloc,
212
                          Elf_Internal_Rela *elf_reloc)
213
{
214
  bfd_reloc->howto
215
    = ia64_elf_lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
216
}
217
 
218
#define PLT_HEADER_SIZE         (3 * 16)
219
#define PLT_MIN_ENTRY_SIZE      (1 * 16)
220
#define PLT_FULL_ENTRY_SIZE     (2 * 16)
221
#define PLT_RESERVED_WORDS      3
222
 
223
static const bfd_byte plt_header[PLT_HEADER_SIZE] =
224
{
225
  0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21,  /*   [MMI]       mov r2=r14;;       */
226
  0xe0, 0x00, 0x08, 0x00, 0x48, 0x00,  /*               addl r14=0,r2      */
227
  0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
228
  0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14,  /*   [MMI]       ld8 r16=[r14],8;;  */
229
  0x10, 0x41, 0x38, 0x30, 0x28, 0x00,  /*               ld8 r17=[r14],8    */
230
  0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
231
  0x11, 0x08, 0x00, 0x1c, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r14]       */
232
  0x60, 0x88, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r17         */
233
  0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
234
};
235
 
236
static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
237
{
238
  0x11, 0x78, 0x00, 0x00, 0x00, 0x24,  /*   [MIB]       mov r15=0          */
239
  0x00, 0x00, 0x00, 0x02, 0x00, 0x00,  /*               nop.i 0x0          */
240
  0x00, 0x00, 0x00, 0x40               /*               br.few 0 <PLT0>;;  */
241
};
242
 
243
static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
244
{
245
  0x0b, 0x78, 0x00, 0x02, 0x00, 0x24,  /*   [MMI]       addl r15=0,r1;;    */
246
  0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0,  /*               ld8.acq r16=[r15],8*/
247
  0x01, 0x08, 0x00, 0x84,              /*               mov r14=r1;;       */
248
  0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r15]       */
249
  0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
250
  0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
251
};
252
 
253
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
254
 
255
static const bfd_byte oor_brl[16] =
256
{
257
  0x05, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
258
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /*               brl.sptk.few tgt;; */
259
  0x00, 0x00, 0x00, 0xc0
260
};
261
 
262
static const bfd_byte oor_ip[48] =
263
{
264
  0x04, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
265
  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,  /*               movl r15=0         */
266
  0x01, 0x00, 0x00, 0x60,
267
  0x03, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MII]        nop.m 0            */
268
  0x00, 0x01, 0x00, 0x60, 0x00, 0x00,  /*               mov r16=ip;;       */
269
  0xf2, 0x80, 0x00, 0x80,              /*               add r16=r15,r16;;  */
270
  0x11, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MIB]        nop.m 0            */
271
  0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
272
  0x60, 0x00, 0x80, 0x00               /*               br b6;;            */
273
};
274
 
275
static size_t oor_branch_size = sizeof (oor_brl);
276
 
277
void
278
bfd_elfNN_ia64_after_parse (int itanium)
279
{
280
  oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
281
}
282
 
283
 
284
/* Rename some of the generic section flags to better document how they
285
   are used here.  */
286
#define skip_relax_pass_0 sec_flg0
287
#define skip_relax_pass_1 sec_flg1
288
 
289
/* These functions do relaxation for IA-64 ELF.  */
290
 
291
static void
292
elfNN_ia64_update_short_info (asection *sec, bfd_vma offset,
293
                              struct elfNN_ia64_link_hash_table *ia64_info)
294
{
295
  /* Skip ABS and SHF_IA_64_SHORT sections.  */
296
  if (sec == bfd_abs_section_ptr
297
      || (sec->flags & SEC_SMALL_DATA) != 0)
298
    return;
299
 
300
  if (!ia64_info->min_short_sec)
301
    {
302
      ia64_info->max_short_sec = sec;
303
      ia64_info->max_short_offset = offset;
304
      ia64_info->min_short_sec = sec;
305
      ia64_info->min_short_offset = offset;
306
    }
307
  else if (sec == ia64_info->max_short_sec
308
           && offset > ia64_info->max_short_offset)
309
    ia64_info->max_short_offset = offset;
310
  else if (sec == ia64_info->min_short_sec
311
           && offset < ia64_info->min_short_offset)
312
    ia64_info->min_short_offset = offset;
313
  else if (sec->output_section->vma
314
           > ia64_info->max_short_sec->vma)
315
    {
316
      ia64_info->max_short_sec = sec;
317
      ia64_info->max_short_offset = offset;
318
    }
319
  else if (sec->output_section->vma
320
           < ia64_info->min_short_sec->vma)
321
    {
322
      ia64_info->min_short_sec = sec;
323
      ia64_info->min_short_offset = offset;
324
    }
325
}
326
 
327
static bfd_boolean
328
elfNN_ia64_relax_section (bfd *abfd, asection *sec,
329
                          struct bfd_link_info *link_info,
330
                          bfd_boolean *again)
331
{
332
  struct one_fixup
333
    {
334
      struct one_fixup *next;
335
      asection *tsec;
336
      bfd_vma toff;
337
      bfd_vma trampoff;
338
    };
339
 
340
  Elf_Internal_Shdr *symtab_hdr;
341
  Elf_Internal_Rela *internal_relocs;
342
  Elf_Internal_Rela *irel, *irelend;
343
  bfd_byte *contents;
344
  Elf_Internal_Sym *isymbuf = NULL;
345
  struct elfNN_ia64_link_hash_table *ia64_info;
346
  struct one_fixup *fixups = NULL;
347
  bfd_boolean changed_contents = FALSE;
348
  bfd_boolean changed_relocs = FALSE;
349
  bfd_boolean changed_got = FALSE;
350
  bfd_boolean skip_relax_pass_0 = TRUE;
351
  bfd_boolean skip_relax_pass_1 = TRUE;
352
  bfd_vma gp = 0;
353
 
354
  /* Assume we're not going to change any sizes, and we'll only need
355
     one pass.  */
356
  *again = FALSE;
357
 
358
  if (link_info->relocatable)
359
    (*link_info->callbacks->einfo)
360
      (_("%P%F: --relax and -r may not be used together\n"));
361
 
362
  /* Don't even try to relax for non-ELF outputs.  */
363
  if (!is_elf_hash_table (link_info->hash))
364
    return FALSE;
365
 
366
  /* Nothing to do if there are no relocations or there is no need for
367
     the current pass.  */
368
  if ((sec->flags & SEC_RELOC) == 0
369
      || sec->reloc_count == 0
370
      || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
371
      || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
372
    return TRUE;
373
 
374
  ia64_info = elfNN_ia64_hash_table (link_info);
375
  if (ia64_info == NULL)
376
    return FALSE;
377
 
378
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
379
 
380
  /* Load the relocations for this section.  */
381
  internal_relocs = (_bfd_elf_link_read_relocs
382
                     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
383
                      link_info->keep_memory));
384
  if (internal_relocs == NULL)
385
    return FALSE;
386
 
387
  irelend = internal_relocs + sec->reloc_count;
388
 
389
  /* Get the section contents.  */
390
  if (elf_section_data (sec)->this_hdr.contents != NULL)
391
    contents = elf_section_data (sec)->this_hdr.contents;
392
  else
393
    {
394
      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
395
        goto error_return;
396
    }
397
 
398
  for (irel = internal_relocs; irel < irelend; irel++)
399
    {
400
      unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
401
      bfd_vma symaddr, reladdr, trampoff, toff, roff;
402
      asection *tsec;
403
      struct one_fixup *f;
404
      bfd_size_type amt;
405
      bfd_boolean is_branch;
406
      struct elfNN_ia64_dyn_sym_info *dyn_i;
407
      char symtype;
408
 
409
      switch (r_type)
410
        {
411
        case R_IA64_PCREL21B:
412
        case R_IA64_PCREL21BI:
413
        case R_IA64_PCREL21M:
414
        case R_IA64_PCREL21F:
415
          /* In pass 1, all br relaxations are done. We can skip it. */
416
          if (link_info->relax_pass == 1)
417
            continue;
418
          skip_relax_pass_0 = FALSE;
419
          is_branch = TRUE;
420
          break;
421
 
422
        case R_IA64_PCREL60B:
423
          /* We can't optimize brl to br in pass 0 since br relaxations
424
             will increase the code size. Defer it to pass 1.  */
425
          if (link_info->relax_pass == 0)
426
            {
427
              skip_relax_pass_1 = FALSE;
428
              continue;
429
            }
430
          is_branch = TRUE;
431
          break;
432
 
433
        case R_IA64_GPREL22:
434
          /* Update max_short_sec/min_short_sec.  */
435
 
436
        case R_IA64_LTOFF22X:
437
        case R_IA64_LDXMOV:
438
          /* We can't relax ldx/mov in pass 0 since br relaxations will
439
             increase the code size. Defer it to pass 1.  */
440
          if (link_info->relax_pass == 0)
441
            {
442
              skip_relax_pass_1 = FALSE;
443
              continue;
444
            }
445
          is_branch = FALSE;
446
          break;
447
 
448
        default:
449
          continue;
450
        }
451
 
452
      /* Get the value of the symbol referred to by the reloc.  */
453
      if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
454
        {
455
          /* A local symbol.  */
456
          Elf_Internal_Sym *isym;
457
 
458
          /* Read this BFD's local symbols.  */
459
          if (isymbuf == NULL)
460
            {
461
              isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
462
              if (isymbuf == NULL)
463
                isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
464
                                                symtab_hdr->sh_info, 0,
465
                                                NULL, NULL, NULL);
466
              if (isymbuf == 0)
467
                goto error_return;
468
            }
469
 
470
          isym = isymbuf + ELFNN_R_SYM (irel->r_info);
471
          if (isym->st_shndx == SHN_UNDEF)
472
            continue;   /* We can't do anything with undefined symbols.  */
473
          else if (isym->st_shndx == SHN_ABS)
474
            tsec = bfd_abs_section_ptr;
475
          else if (isym->st_shndx == SHN_COMMON)
476
            tsec = bfd_com_section_ptr;
477
          else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
478
            tsec = bfd_com_section_ptr;
479
          else
480
            tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
481
 
482
          toff = isym->st_value;
483
          dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
484
          symtype = ELF_ST_TYPE (isym->st_info);
485
        }
486
      else
487
        {
488
          unsigned long indx;
489
          struct elf_link_hash_entry *h;
490
 
491
          indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
492
          h = elf_sym_hashes (abfd)[indx];
493
          BFD_ASSERT (h != NULL);
494
 
495
          while (h->root.type == bfd_link_hash_indirect
496
                 || h->root.type == bfd_link_hash_warning)
497
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
498
 
499
          dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
500
 
501
          /* For branches to dynamic symbols, we're interested instead
502
             in a branch to the PLT entry.  */
503
          if (is_branch && dyn_i && dyn_i->want_plt2)
504
            {
505
              /* Internal branches shouldn't be sent to the PLT.
506
                 Leave this for now and we'll give an error later.  */
507
              if (r_type != R_IA64_PCREL21B)
508
                continue;
509
 
510
              tsec = ia64_info->root.splt;
511
              toff = dyn_i->plt2_offset;
512
              BFD_ASSERT (irel->r_addend == 0);
513
            }
514
 
515
          /* Can't do anything else with dynamic symbols.  */
516
          else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
517
            continue;
518
 
519
          else
520
            {
521
              /* We can't do anything with undefined symbols.  */
522
              if (h->root.type == bfd_link_hash_undefined
523
                  || h->root.type == bfd_link_hash_undefweak)
524
                continue;
525
 
526
              tsec = h->root.u.def.section;
527
              toff = h->root.u.def.value;
528
            }
529
 
530
          symtype = h->type;
531
        }
532
 
533
      if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
534
        {
535
          /* At this stage in linking, no SEC_MERGE symbol has been
536
             adjusted, so all references to such symbols need to be
537
             passed through _bfd_merged_section_offset.  (Later, in
538
             relocate_section, all SEC_MERGE symbols *except* for
539
             section symbols have been adjusted.)
540
 
541
             gas may reduce relocations against symbols in SEC_MERGE
542
             sections to a relocation against the section symbol when
543
             the original addend was zero.  When the reloc is against
544
             a section symbol we should include the addend in the
545
             offset passed to _bfd_merged_section_offset, since the
546
             location of interest is the original symbol.  On the
547
             other hand, an access to "sym+addend" where "sym" is not
548
             a section symbol should not include the addend;  Such an
549
             access is presumed to be an offset from "sym";  The
550
             location of interest is just "sym".  */
551
           if (symtype == STT_SECTION)
552
             toff += irel->r_addend;
553
 
554
           toff = _bfd_merged_section_offset (abfd, &tsec,
555
                                              elf_section_data (tsec)->sec_info,
556
                                              toff);
557
 
558
           if (symtype != STT_SECTION)
559
             toff += irel->r_addend;
560
        }
561
      else
562
        toff += irel->r_addend;
563
 
564
      symaddr = tsec->output_section->vma + tsec->output_offset + toff;
565
 
566
      roff = irel->r_offset;
567
 
568
      if (is_branch)
569
        {
570
          bfd_signed_vma offset;
571
 
572
          reladdr = (sec->output_section->vma
573
                     + sec->output_offset
574
                     + roff) & (bfd_vma) -4;
575
 
576
          /* The .plt section is aligned at 32byte and the .text section
577
             is aligned at 64byte. The .text section is right after the
578
             .plt section.  After the first relaxation pass, linker may
579
             increase the gap between the .plt and .text sections up
580
             to 32byte.  We assume linker will always insert 32byte
581
             between the .plt and .text sections after the the first
582
             relaxation pass.  */
583
          if (tsec == ia64_info->root.splt)
584
            offset = -0x1000000 + 32;
585
          else
586
            offset = -0x1000000;
587
 
588
          /* If the branch is in range, no need to do anything.  */
589
          if ((bfd_signed_vma) (symaddr - reladdr) >= offset
590
              && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
591
            {
592
              /* If the 60-bit branch is in 21-bit range, optimize it. */
593
              if (r_type == R_IA64_PCREL60B)
594
                {
595
                  ia64_elf_relax_brl (contents, roff);
596
 
597
                  irel->r_info
598
                    = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
599
                                    R_IA64_PCREL21B);
600
 
601
                  /* If the original relocation offset points to slot
602
                     1, change it to slot 2.  */
603
                  if ((irel->r_offset & 3) == 1)
604
                    irel->r_offset += 1;
605
                }
606
 
607
              continue;
608
            }
609
          else if (r_type == R_IA64_PCREL60B)
610
            continue;
611
          else if (ia64_elf_relax_br (contents, roff))
612
            {
613
              irel->r_info
614
                = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
615
                                R_IA64_PCREL60B);
616
 
617
              /* Make the relocation offset point to slot 1.  */
618
              irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
619
              continue;
620
            }
621
 
622
          /* We can't put a trampoline in a .init/.fini section. Issue
623
             an error.  */
624
          if (strcmp (sec->output_section->name, ".init") == 0
625
              || strcmp (sec->output_section->name, ".fini") == 0)
626
            {
627
              (*_bfd_error_handler)
628
                (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
629
                 sec->owner, sec, (unsigned long) roff);
630
              bfd_set_error (bfd_error_bad_value);
631
              goto error_return;
632
            }
633
 
634
          /* If the branch and target are in the same section, you've
635
             got one honking big section and we can't help you unless
636
             you are branching backwards.  You'll get an error message
637
             later.  */
638
          if (tsec == sec && toff > roff)
639
            continue;
640
 
641
          /* Look for an existing fixup to this address.  */
642
          for (f = fixups; f ; f = f->next)
643
            if (f->tsec == tsec && f->toff == toff)
644
              break;
645
 
646
          if (f == NULL)
647
            {
648
              /* Two alternatives: If it's a branch to a PLT entry, we can
649
                 make a copy of the FULL_PLT entry.  Otherwise, we'll have
650
                 to use a `brl' insn to get where we're going.  */
651
 
652
              size_t size;
653
 
654
              if (tsec == ia64_info->root.splt)
655
                size = sizeof (plt_full_entry);
656
              else
657
                size = oor_branch_size;
658
 
659
              /* Resize the current section to make room for the new branch. */
660
              trampoff = (sec->size + 15) & (bfd_vma) -16;
661
 
662
              /* If trampoline is out of range, there is nothing we
663
                 can do.  */
664
              offset = trampoff - (roff & (bfd_vma) -4);
665
              if (offset < -0x1000000 || offset > 0x0FFFFF0)
666
                continue;
667
 
668
              amt = trampoff + size;
669
              contents = (bfd_byte *) bfd_realloc (contents, amt);
670
              if (contents == NULL)
671
                goto error_return;
672
              sec->size = amt;
673
 
674
              if (tsec == ia64_info->root.splt)
675
                {
676
                  memcpy (contents + trampoff, plt_full_entry, size);
677
 
678
                  /* Hijack the old relocation for use as the PLTOFF reloc.  */
679
                  irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
680
                                               R_IA64_PLTOFF22);
681
                  irel->r_offset = trampoff;
682
                }
683
              else
684
                {
685
                  if (size == sizeof (oor_ip))
686
                    {
687
                      memcpy (contents + trampoff, oor_ip, size);
688
                      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
689
                                                   R_IA64_PCREL64I);
690
                      irel->r_addend -= 16;
691
                      irel->r_offset = trampoff + 2;
692
                    }
693
                  else
694
                    {
695
                      memcpy (contents + trampoff, oor_brl, size);
696
                      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
697
                                                   R_IA64_PCREL60B);
698
                      irel->r_offset = trampoff + 2;
699
                    }
700
 
701
                }
702
 
703
              /* Record the fixup so we don't do it again this section.  */
704
              f = (struct one_fixup *)
705
                bfd_malloc ((bfd_size_type) sizeof (*f));
706
              f->next = fixups;
707
              f->tsec = tsec;
708
              f->toff = toff;
709
              f->trampoff = trampoff;
710
              fixups = f;
711
            }
712
          else
713
            {
714
              /* If trampoline is out of range, there is nothing we
715
                 can do.  */
716
              offset = f->trampoff - (roff & (bfd_vma) -4);
717
              if (offset < -0x1000000 || offset > 0x0FFFFF0)
718
                continue;
719
 
720
              /* Nop out the reloc, since we're finalizing things here.  */
721
              irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
722
            }
723
 
724
          /* Fix up the existing branch to hit the trampoline.  */
725
          if (ia64_elf_install_value (contents + roff, offset, r_type)
726
              != bfd_reloc_ok)
727
            goto error_return;
728
 
729
          changed_contents = TRUE;
730
          changed_relocs = TRUE;
731
        }
732
      else
733
        {
734
          /* Fetch the gp.  */
735
          if (gp == 0)
736
            {
737
              bfd *obfd = sec->output_section->owner;
738
              gp = _bfd_get_gp_value (obfd);
739
              if (gp == 0)
740
                {
741
                  if (!elfNN_ia64_choose_gp (obfd, link_info, FALSE))
742
                    goto error_return;
743
                  gp = _bfd_get_gp_value (obfd);
744
                }
745
            }
746
 
747
          /* If the data is out of range, do nothing.  */
748
          if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
749
              ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
750
            continue;
751
 
752
          if (r_type == R_IA64_GPREL22)
753
            elfNN_ia64_update_short_info (tsec->output_section,
754
                                          tsec->output_offset + toff,
755
                                          ia64_info);
756
          else if (r_type == R_IA64_LTOFF22X)
757
            {
758
              irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
759
                                           R_IA64_GPREL22);
760
              changed_relocs = TRUE;
761
              if (dyn_i->want_gotx)
762
                {
763
                  dyn_i->want_gotx = 0;
764
                  changed_got |= !dyn_i->want_got;
765
                }
766
 
767
              elfNN_ia64_update_short_info (tsec->output_section,
768
                                            tsec->output_offset + toff,
769
                                            ia64_info);
770
            }
771
          else
772
            {
773
              ia64_elf_relax_ldxmov (contents, roff);
774
              irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
775
              changed_contents = TRUE;
776
              changed_relocs = TRUE;
777
            }
778
        }
779
    }
780
 
781
  /* ??? If we created fixups, this may push the code segment large
782
     enough that the data segment moves, which will change the GP.
783
     Reset the GP so that we re-calculate next round.  We need to
784
     do this at the _beginning_ of the next round; now will not do.  */
785
 
786
  /* Clean up and go home.  */
787
  while (fixups)
788
    {
789
      struct one_fixup *f = fixups;
790
      fixups = fixups->next;
791
      free (f);
792
    }
793
 
794
  if (isymbuf != NULL
795
      && symtab_hdr->contents != (unsigned char *) isymbuf)
796
    {
797
      if (! link_info->keep_memory)
798
        free (isymbuf);
799
      else
800
        {
801
          /* Cache the symbols for elf_link_input_bfd.  */
802
          symtab_hdr->contents = (unsigned char *) isymbuf;
803
        }
804
    }
805
 
806
  if (contents != NULL
807
      && elf_section_data (sec)->this_hdr.contents != contents)
808
    {
809
      if (!changed_contents && !link_info->keep_memory)
810
        free (contents);
811
      else
812
        {
813
          /* Cache the section contents for elf_link_input_bfd.  */
814
          elf_section_data (sec)->this_hdr.contents = contents;
815
        }
816
    }
817
 
818
  if (elf_section_data (sec)->relocs != internal_relocs)
819
    {
820
      if (!changed_relocs)
821
        free (internal_relocs);
822
      else
823
        elf_section_data (sec)->relocs = internal_relocs;
824
    }
825
 
826
  if (changed_got)
827
    {
828
      struct elfNN_ia64_allocate_data data;
829
      data.info = link_info;
830
      data.ofs = 0;
831
      ia64_info->self_dtpmod_offset = (bfd_vma) -1;
832
 
833
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
834
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
835
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
836
      ia64_info->root.sgot->size = data.ofs;
837
 
838
      if (ia64_info->root.dynamic_sections_created
839
          && ia64_info->root.srelgot != NULL)
840
        {
841
          /* Resize .rela.got.  */
842
          ia64_info->root.srelgot->size = 0;
843
          if (link_info->shared
844
              && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
845
            ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
846
          data.only_got = TRUE;
847
          elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
848
                                       &data);
849
        }
850
    }
851
 
852
  if (link_info->relax_pass == 0)
853
    {
854
      /* Pass 0 is only needed to relax br.  */
855
      sec->skip_relax_pass_0 = skip_relax_pass_0;
856
      sec->skip_relax_pass_1 = skip_relax_pass_1;
857
    }
858
 
859
  *again = changed_contents || changed_relocs;
860
  return TRUE;
861
 
862
 error_return:
863
  if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
864
    free (isymbuf);
865
  if (contents != NULL
866
      && elf_section_data (sec)->this_hdr.contents != contents)
867
    free (contents);
868
  if (internal_relocs != NULL
869
      && elf_section_data (sec)->relocs != internal_relocs)
870
    free (internal_relocs);
871
  return FALSE;
872
}
873
#undef skip_relax_pass_0
874
#undef skip_relax_pass_1
875
 
876
/* Return TRUE if NAME is an unwind table section name.  */
877
 
878
static inline bfd_boolean
879
is_unwind_section_name (bfd *abfd, const char *name)
880
{
881
  if (elfNN_ia64_hpux_vec (abfd->xvec)
882
      && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
883
    return FALSE;
884
 
885
  return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
886
           && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
887
          || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
888
}
889
 
890
/* Handle an IA-64 specific section when reading an object file.  This
891
   is called when bfd_section_from_shdr finds a section with an unknown
892
   type.  */
893
 
894
static bfd_boolean
895
elfNN_ia64_section_from_shdr (bfd *abfd,
896
                              Elf_Internal_Shdr *hdr,
897
                              const char *name,
898
                              int shindex)
899
{
900
  /* There ought to be a place to keep ELF backend specific flags, but
901
     at the moment there isn't one.  We just keep track of the
902
     sections by their name, instead.  Fortunately, the ABI gives
903
     suggested names for all the MIPS specific sections, so we will
904
     probably get away with this.  */
905
  switch (hdr->sh_type)
906
    {
907
    case SHT_IA_64_UNWIND:
908
    case SHT_IA_64_HP_OPT_ANOT:
909
      break;
910
 
911
    case SHT_IA_64_EXT:
912
      if (strcmp (name, ELF_STRING_ia64_archext) != 0)
913
        return FALSE;
914
      break;
915
 
916
    default:
917
      return FALSE;
918
    }
919
 
920
  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
921
    return FALSE;
922
 
923
  return TRUE;
924
}
925
 
926
/* Convert IA-64 specific section flags to bfd internal section flags.  */
927
 
928
/* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
929
   flag.  */
930
 
931
static bfd_boolean
932
elfNN_ia64_section_flags (flagword *flags,
933
                          const Elf_Internal_Shdr *hdr)
934
{
935
  if (hdr->sh_flags & SHF_IA_64_SHORT)
936
    *flags |= SEC_SMALL_DATA;
937
 
938
  return TRUE;
939
}
940
 
941
/* Set the correct type for an IA-64 ELF section.  We do this by the
942
   section name, which is a hack, but ought to work.  */
943
 
944
static bfd_boolean
945
elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
946
                          asection *sec)
947
{
948
  const char *name;
949
 
950
  name = bfd_get_section_name (abfd, sec);
951
 
952
  if (is_unwind_section_name (abfd, name))
953
    {
954
      /* We don't have the sections numbered at this point, so sh_info
955
         is set later, in elfNN_ia64_final_write_processing.  */
956
      hdr->sh_type = SHT_IA_64_UNWIND;
957
      hdr->sh_flags |= SHF_LINK_ORDER;
958
    }
959
  else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
960
    hdr->sh_type = SHT_IA_64_EXT;
961
  else if (strcmp (name, ".HP.opt_annot") == 0)
962
    hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
963
  else if (strcmp (name, ".reloc") == 0)
964
    /* This is an ugly, but unfortunately necessary hack that is
965
       needed when producing EFI binaries on IA-64. It tells
966
       elf.c:elf_fake_sections() not to consider ".reloc" as a section
967
       containing ELF relocation info.  We need this hack in order to
968
       be able to generate ELF binaries that can be translated into
969
       EFI applications (which are essentially COFF objects).  Those
970
       files contain a COFF ".reloc" section inside an ELFNN object,
971
       which would normally cause BFD to segfault because it would
972
       attempt to interpret this section as containing relocation
973
       entries for section "oc".  With this hack enabled, ".reloc"
974
       will be treated as a normal data section, which will avoid the
975
       segfault.  However, you won't be able to create an ELFNN binary
976
       with a section named "oc" that needs relocations, but that's
977
       the kind of ugly side-effects you get when detecting section
978
       types based on their names...  In practice, this limitation is
979
       unlikely to bite.  */
980
    hdr->sh_type = SHT_PROGBITS;
981
 
982
  if (sec->flags & SEC_SMALL_DATA)
983
    hdr->sh_flags |= SHF_IA_64_SHORT;
984
 
985
  /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
986
 
987
  if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
988
    hdr->sh_flags |= SHF_IA_64_HP_TLS;
989
 
990
  return TRUE;
991
}
992
 
993
/* The final processing done just before writing out an IA-64 ELF
994
   object file.  */
995
 
996
static void
997
elfNN_ia64_final_write_processing (bfd *abfd,
998
                                   bfd_boolean linker ATTRIBUTE_UNUSED)
999
{
1000
  Elf_Internal_Shdr *hdr;
1001
  asection *s;
1002
 
1003
  for (s = abfd->sections; s; s = s->next)
1004
    {
1005
      hdr = &elf_section_data (s)->this_hdr;
1006
      switch (hdr->sh_type)
1007
        {
1008
        case SHT_IA_64_UNWIND:
1009
          /* The IA-64 processor-specific ABI requires setting sh_link
1010
             to the unwind section, whereas HP-UX requires sh_info to
1011
             do so.  For maximum compatibility, we'll set both for
1012
             now... */
1013
          hdr->sh_info = hdr->sh_link;
1014
          break;
1015
        }
1016
    }
1017
 
1018
  if (! elf_flags_init (abfd))
1019
    {
1020
      unsigned long flags = 0;
1021
 
1022
      if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1023
        flags |= EF_IA_64_BE;
1024
      if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1025
        flags |= EF_IA_64_ABI64;
1026
 
1027
      elf_elfheader(abfd)->e_flags = flags;
1028
      elf_flags_init (abfd) = TRUE;
1029
    }
1030
}
1031
 
1032
/* Hook called by the linker routine which adds symbols from an object
1033
   file.  We use it to put .comm items in .sbss, and not .bss.  */
1034
 
1035
static bfd_boolean
1036
elfNN_ia64_add_symbol_hook (bfd *abfd,
1037
                            struct bfd_link_info *info,
1038
                            Elf_Internal_Sym *sym,
1039
                            const char **namep ATTRIBUTE_UNUSED,
1040
                            flagword *flagsp ATTRIBUTE_UNUSED,
1041
                            asection **secp,
1042
                            bfd_vma *valp)
1043
{
1044
  if (sym->st_shndx == SHN_COMMON
1045
      && !info->relocatable
1046
      && sym->st_size <= elf_gp_size (abfd))
1047
    {
1048
      /* Common symbols less than or equal to -G nn bytes are
1049
         automatically put into .sbss.  */
1050
 
1051
      asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1052
 
1053
      if (scomm == NULL)
1054
        {
1055
          scomm = bfd_make_section_with_flags (abfd, ".scommon",
1056
                                               (SEC_ALLOC
1057
                                                | SEC_IS_COMMON
1058
                                                | SEC_LINKER_CREATED));
1059
          if (scomm == NULL)
1060
            return FALSE;
1061
        }
1062
 
1063
      *secp = scomm;
1064
      *valp = sym->st_size;
1065
    }
1066
 
1067
  return TRUE;
1068
}
1069
 
1070
/* Return the number of additional phdrs we will need.  */
1071
 
1072
static int
1073
elfNN_ia64_additional_program_headers (bfd *abfd,
1074
                                       struct bfd_link_info *info ATTRIBUTE_UNUSED)
1075
{
1076
  asection *s;
1077
  int ret = 0;
1078
 
1079
  /* See if we need a PT_IA_64_ARCHEXT segment.  */
1080
  s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1081
  if (s && (s->flags & SEC_LOAD))
1082
    ++ret;
1083
 
1084
  /* Count how many PT_IA_64_UNWIND segments we need.  */
1085
  for (s = abfd->sections; s; s = s->next)
1086
    if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1087
      ++ret;
1088
 
1089
  return ret;
1090
}
1091
 
1092
static bfd_boolean
1093
elfNN_ia64_modify_segment_map (bfd *abfd,
1094
                               struct bfd_link_info *info ATTRIBUTE_UNUSED)
1095
{
1096
  struct elf_segment_map *m, **pm;
1097
  Elf_Internal_Shdr *hdr;
1098
  asection *s;
1099
 
1100
  /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1101
     all PT_LOAD segments.  */
1102
  s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1103
  if (s && (s->flags & SEC_LOAD))
1104
    {
1105
      for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1106
        if (m->p_type == PT_IA_64_ARCHEXT)
1107
          break;
1108
      if (m == NULL)
1109
        {
1110
          m = ((struct elf_segment_map *)
1111
               bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1112
          if (m == NULL)
1113
            return FALSE;
1114
 
1115
          m->p_type = PT_IA_64_ARCHEXT;
1116
          m->count = 1;
1117
          m->sections[0] = s;
1118
 
1119
          /* We want to put it after the PHDR and INTERP segments.  */
1120
          pm = &elf_tdata (abfd)->segment_map;
1121
          while (*pm != NULL
1122
                 && ((*pm)->p_type == PT_PHDR
1123
                     || (*pm)->p_type == PT_INTERP))
1124
            pm = &(*pm)->next;
1125
 
1126
          m->next = *pm;
1127
          *pm = m;
1128
        }
1129
    }
1130
 
1131
  /* Install PT_IA_64_UNWIND segments, if needed.  */
1132
  for (s = abfd->sections; s; s = s->next)
1133
    {
1134
      hdr = &elf_section_data (s)->this_hdr;
1135
      if (hdr->sh_type != SHT_IA_64_UNWIND)
1136
        continue;
1137
 
1138
      if (s && (s->flags & SEC_LOAD))
1139
        {
1140
          for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1141
            if (m->p_type == PT_IA_64_UNWIND)
1142
              {
1143
                int i;
1144
 
1145
                /* Look through all sections in the unwind segment
1146
                   for a match since there may be multiple sections
1147
                   to a segment.  */
1148
                for (i = m->count - 1; i >= 0; --i)
1149
                  if (m->sections[i] == s)
1150
                    break;
1151
 
1152
                if (i >= 0)
1153
                  break;
1154
              }
1155
 
1156
          if (m == NULL)
1157
            {
1158
              m = ((struct elf_segment_map *)
1159
                   bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1160
              if (m == NULL)
1161
                return FALSE;
1162
 
1163
              m->p_type = PT_IA_64_UNWIND;
1164
              m->count = 1;
1165
              m->sections[0] = s;
1166
              m->next = NULL;
1167
 
1168
              /* We want to put it last.  */
1169
              pm = &elf_tdata (abfd)->segment_map;
1170
              while (*pm != NULL)
1171
                pm = &(*pm)->next;
1172
              *pm = m;
1173
            }
1174
        }
1175
    }
1176
 
1177
  return TRUE;
1178
}
1179
 
1180
/* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
1181
   the input sections for each output section in the segment and testing
1182
   for SHF_IA_64_NORECOV on each.  */
1183
 
1184
static bfd_boolean
1185
elfNN_ia64_modify_program_headers (bfd *abfd,
1186
                                   struct bfd_link_info *info ATTRIBUTE_UNUSED)
1187
{
1188
  struct elf_obj_tdata *tdata = elf_tdata (abfd);
1189
  struct elf_segment_map *m;
1190
  Elf_Internal_Phdr *p;
1191
 
1192
  for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
1193
    if (m->p_type == PT_LOAD)
1194
      {
1195
        int i;
1196
        for (i = m->count - 1; i >= 0; --i)
1197
          {
1198
            struct bfd_link_order *order = m->sections[i]->map_head.link_order;
1199
 
1200
            while (order != NULL)
1201
              {
1202
                if (order->type == bfd_indirect_link_order)
1203
                  {
1204
                    asection *is = order->u.indirect.section;
1205
                    bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1206
                    if (flags & SHF_IA_64_NORECOV)
1207
                      {
1208
                        p->p_flags |= PF_IA_64_NORECOV;
1209
                        goto found;
1210
                      }
1211
                  }
1212
                order = order->next;
1213
              }
1214
          }
1215
      found:;
1216
      }
1217
 
1218
  return TRUE;
1219
}
1220
 
1221
/* According to the Tahoe assembler spec, all labels starting with a
1222
   '.' are local.  */
1223
 
1224
static bfd_boolean
1225
elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
1226
                                const char *name)
1227
{
1228
  return name[0] == '.';
1229
}
1230
 
1231
/* Should we do dynamic things to this symbol?  */
1232
 
1233
static bfd_boolean
1234
elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry *h,
1235
                             struct bfd_link_info *info, int r_type)
1236
{
1237
  bfd_boolean ignore_protected
1238
    = ((r_type & 0xf8) == 0x40          /* FPTR relocs */
1239
       || (r_type & 0xf8) == 0x50);     /* LTOFF_FPTR relocs */
1240
 
1241
  return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
1242
}
1243
 
1244
static struct bfd_hash_entry*
1245
elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry *entry,
1246
                               struct bfd_hash_table *table,
1247
                               const char *string)
1248
{
1249
  struct elfNN_ia64_link_hash_entry *ret;
1250
  ret = (struct elfNN_ia64_link_hash_entry *) entry;
1251
 
1252
  /* Allocate the structure if it has not already been allocated by a
1253
     subclass.  */
1254
  if (!ret)
1255
    ret = bfd_hash_allocate (table, sizeof (*ret));
1256
 
1257
  if (!ret)
1258
    return 0;
1259
 
1260
  /* Call the allocation method of the superclass.  */
1261
  ret = ((struct elfNN_ia64_link_hash_entry *)
1262
         _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1263
                                     table, string));
1264
 
1265
  ret->info = NULL;
1266
  ret->count = 0;
1267
  ret->sorted_count = 0;
1268
  ret->size = 0;
1269
  return (struct bfd_hash_entry *) ret;
1270
}
1271
 
1272
static void
1273
elfNN_ia64_hash_copy_indirect (struct bfd_link_info *info,
1274
                               struct elf_link_hash_entry *xdir,
1275
                               struct elf_link_hash_entry *xind)
1276
{
1277
  struct elfNN_ia64_link_hash_entry *dir, *ind;
1278
 
1279
  dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1280
  ind = (struct elfNN_ia64_link_hash_entry *) xind;
1281
 
1282
  /* Copy down any references that we may have already seen to the
1283
     symbol which just became indirect.  */
1284
 
1285
  dir->root.ref_dynamic |= ind->root.ref_dynamic;
1286
  dir->root.ref_regular |= ind->root.ref_regular;
1287
  dir->root.ref_regular_nonweak |= ind->root.ref_regular_nonweak;
1288
  dir->root.needs_plt |= ind->root.needs_plt;
1289
 
1290
  if (ind->root.root.type != bfd_link_hash_indirect)
1291
    return;
1292
 
1293
  /* Copy over the got and plt data.  This would have been done
1294
     by check_relocs.  */
1295
 
1296
  if (ind->info != NULL)
1297
    {
1298
      struct elfNN_ia64_dyn_sym_info *dyn_i;
1299
      unsigned int count;
1300
 
1301
      if (dir->info)
1302
        free (dir->info);
1303
 
1304
      dir->info = ind->info;
1305
      dir->count = ind->count;
1306
      dir->sorted_count = ind->sorted_count;
1307
      dir->size = ind->size;
1308
 
1309
      ind->info = NULL;
1310
      ind->count = 0;
1311
      ind->sorted_count = 0;
1312
      ind->size = 0;
1313
 
1314
      /* Fix up the dyn_sym_info pointers to the global symbol.  */
1315
      for (count = dir->count, dyn_i = dir->info;
1316
           count != 0;
1317
           count--, dyn_i++)
1318
        dyn_i->h = &dir->root;
1319
    }
1320
 
1321
  /* Copy over the dynindx.  */
1322
 
1323
  if (ind->root.dynindx != -1)
1324
    {
1325
      if (dir->root.dynindx != -1)
1326
        _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
1327
                                dir->root.dynstr_index);
1328
      dir->root.dynindx = ind->root.dynindx;
1329
      dir->root.dynstr_index = ind->root.dynstr_index;
1330
      ind->root.dynindx = -1;
1331
      ind->root.dynstr_index = 0;
1332
    }
1333
}
1334
 
1335
static void
1336
elfNN_ia64_hash_hide_symbol (struct bfd_link_info *info,
1337
                             struct elf_link_hash_entry *xh,
1338
                             bfd_boolean force_local)
1339
{
1340
  struct elfNN_ia64_link_hash_entry *h;
1341
  struct elfNN_ia64_dyn_sym_info *dyn_i;
1342
  unsigned int count;
1343
 
1344
  h = (struct elfNN_ia64_link_hash_entry *)xh;
1345
 
1346
  _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1347
 
1348
  for (count = h->count, dyn_i = h->info;
1349
       count != 0;
1350
       count--, dyn_i++)
1351
    {
1352
      dyn_i->want_plt2 = 0;
1353
      dyn_i->want_plt = 0;
1354
    }
1355
}
1356
 
1357
/* Compute a hash of a local hash entry.  */
1358
 
1359
static hashval_t
1360
elfNN_ia64_local_htab_hash (const void *ptr)
1361
{
1362
  struct elfNN_ia64_local_hash_entry *entry
1363
    = (struct elfNN_ia64_local_hash_entry *) ptr;
1364
 
1365
  return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
1366
}
1367
 
1368
/* Compare local hash entries.  */
1369
 
1370
static int
1371
elfNN_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
1372
{
1373
  struct elfNN_ia64_local_hash_entry *entry1
1374
    = (struct elfNN_ia64_local_hash_entry *) ptr1;
1375
  struct elfNN_ia64_local_hash_entry *entry2
1376
    = (struct elfNN_ia64_local_hash_entry *) ptr2;
1377
 
1378
  return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
1379
}
1380
 
1381
/* Create the derived linker hash table.  The IA-64 ELF port uses this
1382
   derived hash table to keep information specific to the IA-64 ElF
1383
   linker (without using static variables).  */
1384
 
1385
static struct bfd_link_hash_table *
1386
elfNN_ia64_hash_table_create (bfd *abfd)
1387
{
1388
  struct elfNN_ia64_link_hash_table *ret;
1389
 
1390
  ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1391
  if (!ret)
1392
    return NULL;
1393
 
1394
  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1395
                                      elfNN_ia64_new_elf_hash_entry,
1396
                                      sizeof (struct elfNN_ia64_link_hash_entry),
1397
                                      IA64_ELF_DATA))
1398
    {
1399
      free (ret);
1400
      return NULL;
1401
    }
1402
 
1403
  ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
1404
                                         elfNN_ia64_local_htab_eq, NULL);
1405
  ret->loc_hash_memory = objalloc_create ();
1406
  if (!ret->loc_hash_table || !ret->loc_hash_memory)
1407
    {
1408
      free (ret);
1409
      return NULL;
1410
    }
1411
 
1412
  return &ret->root.root;
1413
}
1414
 
1415
/* Free the global elfNN_ia64_dyn_sym_info array.  */
1416
 
1417
static bfd_boolean
1418
elfNN_ia64_global_dyn_info_free (void **xentry,
1419
                                PTR unused ATTRIBUTE_UNUSED)
1420
{
1421
  struct elfNN_ia64_link_hash_entry *entry
1422
    = (struct elfNN_ia64_link_hash_entry *) xentry;
1423
 
1424
  if (entry->root.root.type == bfd_link_hash_warning)
1425
    entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1426
 
1427
  if (entry->info)
1428
    {
1429
      free (entry->info);
1430
      entry->info = NULL;
1431
      entry->count = 0;
1432
      entry->sorted_count = 0;
1433
      entry->size = 0;
1434
    }
1435
 
1436
  return TRUE;
1437
}
1438
 
1439
/* Free the local elfNN_ia64_dyn_sym_info array.  */
1440
 
1441
static bfd_boolean
1442
elfNN_ia64_local_dyn_info_free (void **slot,
1443
                                PTR unused ATTRIBUTE_UNUSED)
1444
{
1445
  struct elfNN_ia64_local_hash_entry *entry
1446
    = (struct elfNN_ia64_local_hash_entry *) *slot;
1447
 
1448
  if (entry->info)
1449
    {
1450
      free (entry->info);
1451
      entry->info = NULL;
1452
      entry->count = 0;
1453
      entry->sorted_count = 0;
1454
      entry->size = 0;
1455
    }
1456
 
1457
  return TRUE;
1458
}
1459
 
1460
/* Destroy IA-64 linker hash table.  */
1461
 
1462
static void
1463
elfNN_ia64_hash_table_free (struct bfd_link_hash_table *hash)
1464
{
1465
  struct elfNN_ia64_link_hash_table *ia64_info
1466
    = (struct elfNN_ia64_link_hash_table *) hash;
1467
  if (ia64_info->loc_hash_table)
1468
    {
1469
      htab_traverse (ia64_info->loc_hash_table,
1470
                     elfNN_ia64_local_dyn_info_free, NULL);
1471
      htab_delete (ia64_info->loc_hash_table);
1472
    }
1473
  if (ia64_info->loc_hash_memory)
1474
    objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
1475
  elf_link_hash_traverse (&ia64_info->root,
1476
                          elfNN_ia64_global_dyn_info_free, NULL);
1477
  _bfd_generic_link_hash_table_free (hash);
1478
}
1479
 
1480
/* Traverse both local and global hash tables.  */
1481
 
1482
struct elfNN_ia64_dyn_sym_traverse_data
1483
{
1484
  bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR);
1485
  PTR data;
1486
};
1487
 
1488
static bfd_boolean
1489
elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
1490
                                 PTR xdata)
1491
{
1492
  struct elfNN_ia64_link_hash_entry *entry
1493
    = (struct elfNN_ia64_link_hash_entry *) xentry;
1494
  struct elfNN_ia64_dyn_sym_traverse_data *data
1495
    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1496
  struct elfNN_ia64_dyn_sym_info *dyn_i;
1497
  unsigned int count;
1498
 
1499
  if (entry->root.root.type == bfd_link_hash_warning)
1500
    entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1501
 
1502
  for (count = entry->count, dyn_i = entry->info;
1503
       count != 0;
1504
       count--, dyn_i++)
1505
    if (! (*data->func) (dyn_i, data->data))
1506
      return FALSE;
1507
  return TRUE;
1508
}
1509
 
1510
static bfd_boolean
1511
elfNN_ia64_local_dyn_sym_thunk (void **slot, PTR xdata)
1512
{
1513
  struct elfNN_ia64_local_hash_entry *entry
1514
    = (struct elfNN_ia64_local_hash_entry *) *slot;
1515
  struct elfNN_ia64_dyn_sym_traverse_data *data
1516
    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1517
  struct elfNN_ia64_dyn_sym_info *dyn_i;
1518
  unsigned int count;
1519
 
1520
  for (count = entry->count, dyn_i = entry->info;
1521
       count != 0;
1522
       count--, dyn_i++)
1523
    if (! (*data->func) (dyn_i, data->data))
1524
      return FALSE;
1525
  return TRUE;
1526
}
1527
 
1528
static void
1529
elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table *ia64_info,
1530
                             bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
1531
                             PTR data)
1532
{
1533
  struct elfNN_ia64_dyn_sym_traverse_data xdata;
1534
 
1535
  xdata.func = func;
1536
  xdata.data = data;
1537
 
1538
  elf_link_hash_traverse (&ia64_info->root,
1539
                          elfNN_ia64_global_dyn_sym_thunk, &xdata);
1540
  htab_traverse (ia64_info->loc_hash_table,
1541
                 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1542
}
1543
 
1544
static bfd_boolean
1545
elfNN_ia64_create_dynamic_sections (bfd *abfd,
1546
                                    struct bfd_link_info *info)
1547
{
1548
  struct elfNN_ia64_link_hash_table *ia64_info;
1549
  asection *s;
1550
 
1551
  if (! _bfd_elf_create_dynamic_sections (abfd, info))
1552
    return FALSE;
1553
 
1554
  ia64_info = elfNN_ia64_hash_table (info);
1555
  if (ia64_info == NULL)
1556
    return FALSE;
1557
 
1558
  {
1559
    flagword flags = bfd_get_section_flags (abfd, ia64_info->root.sgot);
1560
    bfd_set_section_flags (abfd, ia64_info->root.sgot,
1561
                           SEC_SMALL_DATA | flags);
1562
    /* The .got section is always aligned at 8 bytes.  */
1563
    bfd_set_section_alignment (abfd, ia64_info->root.sgot, 3);
1564
  }
1565
 
1566
  if (!get_pltoff (abfd, info, ia64_info))
1567
    return FALSE;
1568
 
1569
  s = bfd_make_section_with_flags (abfd, ".rela.IA_64.pltoff",
1570
                                   (SEC_ALLOC | SEC_LOAD
1571
                                    | SEC_HAS_CONTENTS
1572
                                    | SEC_IN_MEMORY
1573
                                    | SEC_LINKER_CREATED
1574
                                    | SEC_READONLY));
1575
  if (s == NULL
1576
      || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
1577
    return FALSE;
1578
  ia64_info->rel_pltoff_sec = s;
1579
 
1580
  return TRUE;
1581
}
1582
 
1583
/* Find and/or create a hash entry for local symbol.  */
1584
static struct elfNN_ia64_local_hash_entry *
1585
get_local_sym_hash (struct elfNN_ia64_link_hash_table *ia64_info,
1586
                    bfd *abfd, const Elf_Internal_Rela *rel,
1587
                    bfd_boolean create)
1588
{
1589
  struct elfNN_ia64_local_hash_entry e, *ret;
1590
  asection *sec = abfd->sections;
1591
  hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
1592
                                       ELFNN_R_SYM (rel->r_info));
1593
  void **slot;
1594
 
1595
  e.id = sec->id;
1596
  e.r_sym = ELFNN_R_SYM (rel->r_info);
1597
  slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
1598
                                   create ? INSERT : NO_INSERT);
1599
 
1600
  if (!slot)
1601
    return NULL;
1602
 
1603
  if (*slot)
1604
    return (struct elfNN_ia64_local_hash_entry *) *slot;
1605
 
1606
  ret = (struct elfNN_ia64_local_hash_entry *)
1607
        objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
1608
                        sizeof (struct elfNN_ia64_local_hash_entry));
1609
  if (ret)
1610
    {
1611
      memset (ret, 0, sizeof (*ret));
1612
      ret->id = sec->id;
1613
      ret->r_sym = ELFNN_R_SYM (rel->r_info);
1614
      *slot = ret;
1615
    }
1616
  return ret;
1617
}
1618
 
1619
/* Used to sort elfNN_ia64_dyn_sym_info array.  */
1620
 
1621
static int
1622
addend_compare (const void *xp, const void *yp)
1623
{
1624
  const struct elfNN_ia64_dyn_sym_info *x
1625
    = (const struct elfNN_ia64_dyn_sym_info *) xp;
1626
  const struct elfNN_ia64_dyn_sym_info *y
1627
    = (const struct elfNN_ia64_dyn_sym_info *) yp;
1628
 
1629
  return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
1630
}
1631
 
1632
/* Sort elfNN_ia64_dyn_sym_info array and remove duplicates.  */
1633
 
1634
static unsigned int
1635
sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
1636
                   unsigned int count)
1637
{
1638
  bfd_vma curr, prev, got_offset;
1639
  unsigned int i, kept, dupes, diff, dest, src, len;
1640
 
1641
  qsort (info, count, sizeof (*info), addend_compare);
1642
 
1643
  /* Find the first duplicate.  */
1644
  prev = info [0].addend;
1645
  got_offset = info [0].got_offset;
1646
  for (i = 1; i < count; i++)
1647
    {
1648
      curr = info [i].addend;
1649
      if (curr == prev)
1650
        {
1651
          /* For duplicates, make sure that GOT_OFFSET is valid.  */
1652
          if (got_offset == (bfd_vma) -1)
1653
            got_offset = info [i].got_offset;
1654
          break;
1655
        }
1656
      got_offset = info [i].got_offset;
1657
      prev = curr;
1658
    }
1659
 
1660
  /* We may move a block of elements to here.  */
1661
  dest = i++;
1662
 
1663
  /* Remove duplicates.  */
1664
  if (i < count)
1665
    {
1666
      while (i < count)
1667
        {
1668
          /* For duplicates, make sure that the kept one has a valid
1669
             got_offset.  */
1670
          kept = dest - 1;
1671
          if (got_offset != (bfd_vma) -1)
1672
            info [kept].got_offset = got_offset;
1673
 
1674
          curr = info [i].addend;
1675
          got_offset = info [i].got_offset;
1676
 
1677
          /* Move a block of elements whose first one is different from
1678
             the previous.  */
1679
          if (curr == prev)
1680
            {
1681
              for (src = i + 1; src < count; src++)
1682
                {
1683
                  if (info [src].addend != curr)
1684
                    break;
1685
                  /* For duplicates, make sure that GOT_OFFSET is
1686
                     valid.  */
1687
                  if (got_offset == (bfd_vma) -1)
1688
                    got_offset = info [src].got_offset;
1689
                }
1690
 
1691
              /* Make sure that the kept one has a valid got_offset.  */
1692
              if (got_offset != (bfd_vma) -1)
1693
                info [kept].got_offset = got_offset;
1694
            }
1695
          else
1696
            src = i;
1697
 
1698
          if (src >= count)
1699
            break;
1700
 
1701
          /* Find the next duplicate.  SRC will be kept.  */
1702
          prev = info [src].addend;
1703
          got_offset = info [src].got_offset;
1704
          for (dupes = src + 1; dupes < count; dupes ++)
1705
            {
1706
              curr = info [dupes].addend;
1707
              if (curr == prev)
1708
                {
1709
                  /* Make sure that got_offset is valid.  */
1710
                  if (got_offset == (bfd_vma) -1)
1711
                    got_offset = info [dupes].got_offset;
1712
 
1713
                  /* For duplicates, make sure that the kept one has
1714
                     a valid got_offset.  */
1715
                  if (got_offset != (bfd_vma) -1)
1716
                    info [dupes - 1].got_offset = got_offset;
1717
                  break;
1718
                }
1719
              got_offset = info [dupes].got_offset;
1720
              prev = curr;
1721
            }
1722
 
1723
          /* How much to move.  */
1724
          len = dupes - src;
1725
          i = dupes + 1;
1726
 
1727
          if (len == 1 && dupes < count)
1728
            {
1729
              /* If we only move 1 element, we combine it with the next
1730
                 one.  There must be at least a duplicate.  Find the
1731
                 next different one.  */
1732
              for (diff = dupes + 1, src++; diff < count; diff++, src++)
1733
                {
1734
                  if (info [diff].addend != curr)
1735
                    break;
1736
                  /* Make sure that got_offset is valid.  */
1737
                  if (got_offset == (bfd_vma) -1)
1738
                    got_offset = info [diff].got_offset;
1739
                }
1740
 
1741
              /* Makre sure that the last duplicated one has an valid
1742
                 offset.  */
1743
              BFD_ASSERT (curr == prev);
1744
              if (got_offset != (bfd_vma) -1)
1745
                info [diff - 1].got_offset = got_offset;
1746
 
1747
              if (diff < count)
1748
                {
1749
                  /* Find the next duplicate.  Track the current valid
1750
                     offset.  */
1751
                  prev = info [diff].addend;
1752
                  got_offset = info [diff].got_offset;
1753
                  for (dupes = diff + 1; dupes < count; dupes ++)
1754
                    {
1755
                      curr = info [dupes].addend;
1756
                      if (curr == prev)
1757
                        {
1758
                          /* For duplicates, make sure that GOT_OFFSET
1759
                             is valid.  */
1760
                          if (got_offset == (bfd_vma) -1)
1761
                            got_offset = info [dupes].got_offset;
1762
                          break;
1763
                        }
1764
                      got_offset = info [dupes].got_offset;
1765
                      prev = curr;
1766
                      diff++;
1767
                    }
1768
 
1769
                  len = diff - src + 1;
1770
                  i = diff + 1;
1771
                }
1772
            }
1773
 
1774
          memmove (&info [dest], &info [src], len * sizeof (*info));
1775
 
1776
          dest += len;
1777
        }
1778
 
1779
      count = dest;
1780
    }
1781
  else
1782
    {
1783
      /* When we get here, either there is no duplicate at all or
1784
         the only duplicate is the last element.  */
1785
      if (dest < count)
1786
        {
1787
          /* If the last element is a duplicate, make sure that the
1788
             kept one has a valid got_offset.  We also update count.  */
1789
          if (got_offset != (bfd_vma) -1)
1790
            info [dest - 1].got_offset = got_offset;
1791
          count = dest;
1792
        }
1793
    }
1794
 
1795
  return count;
1796
}
1797
 
1798
/* Find and/or create a descriptor for dynamic symbol info.  This will
1799
   vary based on global or local symbol, and the addend to the reloc.
1800
 
1801
   We don't sort when inserting.  Also, we sort and eliminate
1802
   duplicates if there is an unsorted section.  Typically, this will
1803
   only happen once, because we do all insertions before lookups.  We
1804
   then use bsearch to do a lookup.  This also allows lookups to be
1805
   fast.  So we have fast insertion (O(log N) due to duplicate check),
1806
   fast lookup (O(log N)) and one sort (O(N log N) expected time).
1807
   Previously, all lookups were O(N) because of the use of the linked
1808
   list and also all insertions were O(N) because of the check for
1809
   duplicates.  There are some complications here because the array
1810
   size grows occasionally, which may add an O(N) factor, but this
1811
   should be rare.  Also,  we free the excess array allocation, which
1812
   requires a copy which is O(N), but this only happens once.  */
1813
 
1814
static struct elfNN_ia64_dyn_sym_info *
1815
get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
1816
                  struct elf_link_hash_entry *h, bfd *abfd,
1817
                  const Elf_Internal_Rela *rel, bfd_boolean create)
1818
{
1819
  struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
1820
  unsigned int *count_p, *sorted_count_p, *size_p;
1821
  unsigned int count, sorted_count, size;
1822
  bfd_vma addend = rel ? rel->r_addend : 0;
1823
  bfd_size_type amt;
1824
 
1825
  if (h)
1826
    {
1827
      struct elfNN_ia64_link_hash_entry *global_h;
1828
 
1829
      global_h = (struct elfNN_ia64_link_hash_entry *) h;
1830
      info_p = &global_h->info;
1831
      count_p = &global_h->count;
1832
      sorted_count_p = &global_h->sorted_count;
1833
      size_p = &global_h->size;
1834
    }
1835
  else
1836
    {
1837
      struct elfNN_ia64_local_hash_entry *loc_h;
1838
 
1839
      loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1840
      if (!loc_h)
1841
        {
1842
          BFD_ASSERT (!create);
1843
          return NULL;
1844
        }
1845
 
1846
      info_p = &loc_h->info;
1847
      count_p = &loc_h->count;
1848
      sorted_count_p = &loc_h->sorted_count;
1849
      size_p = &loc_h->size;
1850
    }
1851
 
1852
  count = *count_p;
1853
  sorted_count = *sorted_count_p;
1854
  size = *size_p;
1855
  info = *info_p;
1856
  if (create)
1857
    {
1858
      /* When we create the array, we don't check for duplicates,
1859
         except in the previously sorted section if one exists, and
1860
         against the last inserted entry.  This allows insertions to
1861
         be fast.  */
1862
      if (info)
1863
        {
1864
          if (sorted_count)
1865
            {
1866
              /* Try bsearch first on the sorted section.  */
1867
              key.addend = addend;
1868
              dyn_i = bsearch (&key, info, sorted_count,
1869
                               sizeof (*info), addend_compare);
1870
 
1871
              if (dyn_i)
1872
                {
1873
                  return dyn_i;
1874
                }
1875
            }
1876
 
1877
          /* Do a quick check for the last inserted entry.  */
1878
          dyn_i = info + count - 1;
1879
          if (dyn_i->addend == addend)
1880
            {
1881
              return dyn_i;
1882
            }
1883
        }
1884
 
1885
      if (size == 0)
1886
        {
1887
          /* It is the very first element. We create the array of size
1888
             1.  */
1889
          size = 1;
1890
          amt = size * sizeof (*info);
1891
          info = bfd_malloc (amt);
1892
        }
1893
      else if (size <= count)
1894
        {
1895
          /* We double the array size every time when we reach the
1896
             size limit.  */
1897
          size += size;
1898
          amt = size * sizeof (*info);
1899
          info = bfd_realloc (info, amt);
1900
        }
1901
      else
1902
        goto has_space;
1903
 
1904
      if (info == NULL)
1905
        return NULL;
1906
      *size_p = size;
1907
      *info_p = info;
1908
 
1909
has_space:
1910
      /* Append the new one to the array.  */
1911
      dyn_i = info + count;
1912
      memset (dyn_i, 0, sizeof (*dyn_i));
1913
      dyn_i->got_offset = (bfd_vma) -1;
1914
      dyn_i->addend = addend;
1915
 
1916
      /* We increment count only since the new ones are unsorted and
1917
         may have duplicate.  */
1918
      (*count_p)++;
1919
    }
1920
  else
1921
    {
1922
      /* It is a lookup without insertion.  Sort array if part of the
1923
         array isn't sorted.  */
1924
      if (count != sorted_count)
1925
        {
1926
          count = sort_dyn_sym_info (info, count);
1927
          *count_p = count;
1928
          *sorted_count_p = count;
1929
        }
1930
 
1931
      /* Free unused memory.  */
1932
      if (size != count)
1933
        {
1934
          amt = count * sizeof (*info);
1935
          info = bfd_malloc (amt);
1936
          if (info != NULL)
1937
            {
1938
              memcpy (info, *info_p, amt);
1939
              free (*info_p);
1940
              *size_p = count;
1941
              *info_p = info;
1942
            }
1943
        }
1944
 
1945
      key.addend = addend;
1946
      dyn_i = bsearch (&key, info, count,
1947
                       sizeof (*info), addend_compare);
1948
    }
1949
 
1950
  return dyn_i;
1951
}
1952
 
1953
static asection *
1954
get_got (bfd *abfd, struct bfd_link_info *info,
1955
         struct elfNN_ia64_link_hash_table *ia64_info)
1956
{
1957
  asection *got;
1958
  bfd *dynobj;
1959
 
1960
  got = ia64_info->root.sgot;
1961
  if (!got)
1962
    {
1963
      flagword flags;
1964
 
1965
      dynobj = ia64_info->root.dynobj;
1966
      if (!dynobj)
1967
        ia64_info->root.dynobj = dynobj = abfd;
1968
      if (!_bfd_elf_create_got_section (dynobj, info))
1969
        return 0;
1970
 
1971
      got = ia64_info->root.sgot;
1972
 
1973
      /* The .got section is always aligned at 8 bytes.  */
1974
      if (!bfd_set_section_alignment (abfd, got, 3))
1975
        return 0;
1976
 
1977
      flags = bfd_get_section_flags (abfd, got);
1978
      bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1979
    }
1980
 
1981
  return got;
1982
}
1983
 
1984
/* Create function descriptor section (.opd).  This section is called .opd
1985
   because it contains "official procedure descriptors".  The "official"
1986
   refers to the fact that these descriptors are used when taking the address
1987
   of a procedure, thus ensuring a unique address for each procedure.  */
1988
 
1989
static asection *
1990
get_fptr (bfd *abfd, struct bfd_link_info *info,
1991
          struct elfNN_ia64_link_hash_table *ia64_info)
1992
{
1993
  asection *fptr;
1994
  bfd *dynobj;
1995
 
1996
  fptr = ia64_info->fptr_sec;
1997
  if (!fptr)
1998
    {
1999
      dynobj = ia64_info->root.dynobj;
2000
      if (!dynobj)
2001
        ia64_info->root.dynobj = dynobj = abfd;
2002
 
2003
      fptr = bfd_make_section_with_flags (dynobj, ".opd",
2004
                                          (SEC_ALLOC
2005
                                           | SEC_LOAD
2006
                                           | SEC_HAS_CONTENTS
2007
                                           | SEC_IN_MEMORY
2008
                                           | (info->pie ? 0 : SEC_READONLY)
2009
                                           | SEC_LINKER_CREATED));
2010
      if (!fptr
2011
          || !bfd_set_section_alignment (abfd, fptr, 4))
2012
        {
2013
          BFD_ASSERT (0);
2014
          return NULL;
2015
        }
2016
 
2017
      ia64_info->fptr_sec = fptr;
2018
 
2019
      if (info->pie)
2020
        {
2021
          asection *fptr_rel;
2022
          fptr_rel = bfd_make_section_with_flags (dynobj, ".rela.opd",
2023
                                                  (SEC_ALLOC | SEC_LOAD
2024
                                                   | SEC_HAS_CONTENTS
2025
                                                   | SEC_IN_MEMORY
2026
                                                   | SEC_LINKER_CREATED
2027
                                                   | SEC_READONLY));
2028
          if (fptr_rel == NULL
2029
              || !bfd_set_section_alignment (abfd, fptr_rel,
2030
                                             LOG_SECTION_ALIGN))
2031
            {
2032
              BFD_ASSERT (0);
2033
              return NULL;
2034
            }
2035
 
2036
          ia64_info->rel_fptr_sec = fptr_rel;
2037
        }
2038
    }
2039
 
2040
  return fptr;
2041
}
2042
 
2043
static asection *
2044
get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
2045
            struct elfNN_ia64_link_hash_table *ia64_info)
2046
{
2047
  asection *pltoff;
2048
  bfd *dynobj;
2049
 
2050
  pltoff = ia64_info->pltoff_sec;
2051
  if (!pltoff)
2052
    {
2053
      dynobj = ia64_info->root.dynobj;
2054
      if (!dynobj)
2055
        ia64_info->root.dynobj = dynobj = abfd;
2056
 
2057
      pltoff = bfd_make_section_with_flags (dynobj,
2058
                                            ELF_STRING_ia64_pltoff,
2059
                                            (SEC_ALLOC
2060
                                             | SEC_LOAD
2061
                                             | SEC_HAS_CONTENTS
2062
                                             | SEC_IN_MEMORY
2063
                                             | SEC_SMALL_DATA
2064
                                             | SEC_LINKER_CREATED));
2065
      if (!pltoff
2066
          || !bfd_set_section_alignment (abfd, pltoff, 4))
2067
        {
2068
          BFD_ASSERT (0);
2069
          return NULL;
2070
        }
2071
 
2072
      ia64_info->pltoff_sec = pltoff;
2073
    }
2074
 
2075
  return pltoff;
2076
}
2077
 
2078
static asection *
2079
get_reloc_section (bfd *abfd,
2080
                   struct elfNN_ia64_link_hash_table *ia64_info,
2081
                   asection *sec, bfd_boolean create)
2082
{
2083
  const char *srel_name;
2084
  asection *srel;
2085
  bfd *dynobj;
2086
 
2087
  srel_name = (bfd_elf_string_from_elf_section
2088
               (abfd, elf_elfheader(abfd)->e_shstrndx,
2089
                _bfd_elf_single_rel_hdr (sec)->sh_name));
2090
  if (srel_name == NULL)
2091
    return NULL;
2092
 
2093
  dynobj = ia64_info->root.dynobj;
2094
  if (!dynobj)
2095
    ia64_info->root.dynobj = dynobj = abfd;
2096
 
2097
  srel = bfd_get_section_by_name (dynobj, srel_name);
2098
  if (srel == NULL && create)
2099
    {
2100
      srel = bfd_make_section_with_flags (dynobj, srel_name,
2101
                                          (SEC_ALLOC | SEC_LOAD
2102
                                           | SEC_HAS_CONTENTS
2103
                                           | SEC_IN_MEMORY
2104
                                           | SEC_LINKER_CREATED
2105
                                           | SEC_READONLY));
2106
      if (srel == NULL
2107
          || !bfd_set_section_alignment (dynobj, srel,
2108
                                         LOG_SECTION_ALIGN))
2109
        return NULL;
2110
    }
2111
 
2112
  return srel;
2113
}
2114
 
2115
static bfd_boolean
2116
count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2117
                 asection *srel, int type, bfd_boolean reltext)
2118
{
2119
  struct elfNN_ia64_dyn_reloc_entry *rent;
2120
 
2121
  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2122
    if (rent->srel == srel && rent->type == type)
2123
      break;
2124
 
2125
  if (!rent)
2126
    {
2127
      rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2128
              bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2129
      if (!rent)
2130
        return FALSE;
2131
 
2132
      rent->next = dyn_i->reloc_entries;
2133
      rent->srel = srel;
2134
      rent->type = type;
2135
      rent->count = 0;
2136
      dyn_i->reloc_entries = rent;
2137
    }
2138
  rent->reltext |= reltext;
2139
  rent->count++;
2140
 
2141
  return TRUE;
2142
}
2143
 
2144
static bfd_boolean
2145
elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
2146
                         asection *sec,
2147
                         const Elf_Internal_Rela *relocs)
2148
{
2149
  struct elfNN_ia64_link_hash_table *ia64_info;
2150
  const Elf_Internal_Rela *relend;
2151
  Elf_Internal_Shdr *symtab_hdr;
2152
  const Elf_Internal_Rela *rel;
2153
  asection *got, *fptr, *srel, *pltoff;
2154
  enum {
2155
    NEED_GOT = 1,
2156
    NEED_GOTX = 2,
2157
    NEED_FPTR = 4,
2158
    NEED_PLTOFF = 8,
2159
    NEED_MIN_PLT = 16,
2160
    NEED_FULL_PLT = 32,
2161
    NEED_DYNREL = 64,
2162
    NEED_LTOFF_FPTR = 128,
2163
    NEED_TPREL = 256,
2164
    NEED_DTPMOD = 512,
2165
    NEED_DTPREL = 1024
2166
  };
2167
  int need_entry;
2168
  struct elf_link_hash_entry *h;
2169
  unsigned long r_symndx;
2170
  bfd_boolean maybe_dynamic;
2171
 
2172
  if (info->relocatable)
2173
    return TRUE;
2174
 
2175
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2176
  ia64_info = elfNN_ia64_hash_table (info);
2177
  if (ia64_info == NULL)
2178
    return FALSE;
2179
 
2180
  got = fptr = srel = pltoff = NULL;
2181
 
2182
  relend = relocs + sec->reloc_count;
2183
 
2184
  /* We scan relocations first to create dynamic relocation arrays.  We
2185
     modified get_dyn_sym_info to allow fast insertion and support fast
2186
     lookup in the next loop.  */
2187
  for (rel = relocs; rel < relend; ++rel)
2188
    {
2189
      r_symndx = ELFNN_R_SYM (rel->r_info);
2190
      if (r_symndx >= symtab_hdr->sh_info)
2191
        {
2192
          long indx = r_symndx - symtab_hdr->sh_info;
2193
          h = elf_sym_hashes (abfd)[indx];
2194
          while (h->root.type == bfd_link_hash_indirect
2195
                 || h->root.type == bfd_link_hash_warning)
2196
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
2197
        }
2198
      else
2199
        h = NULL;
2200
 
2201
      /* We can only get preliminary data on whether a symbol is
2202
         locally or externally defined, as not all of the input files
2203
         have yet been processed.  Do something with what we know, as
2204
         this may help reduce memory usage and processing time later.  */
2205
      maybe_dynamic = (h && ((!info->executable
2206
                              && (!SYMBOLIC_BIND (info, h)
2207
                                  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2208
                             || !h->def_regular
2209
                             || h->root.type == bfd_link_hash_defweak));
2210
 
2211
      need_entry = 0;
2212
      switch (ELFNN_R_TYPE (rel->r_info))
2213
        {
2214
        case R_IA64_TPREL64MSB:
2215
        case R_IA64_TPREL64LSB:
2216
          if (info->shared || maybe_dynamic)
2217
            need_entry = NEED_DYNREL;
2218
          break;
2219
 
2220
        case R_IA64_LTOFF_TPREL22:
2221
          need_entry = NEED_TPREL;
2222
          if (info->shared)
2223
            info->flags |= DF_STATIC_TLS;
2224
          break;
2225
 
2226
        case R_IA64_DTPREL32MSB:
2227
        case R_IA64_DTPREL32LSB:
2228
        case R_IA64_DTPREL64MSB:
2229
        case R_IA64_DTPREL64LSB:
2230
          if (info->shared || maybe_dynamic)
2231
            need_entry = NEED_DYNREL;
2232
          break;
2233
 
2234
        case R_IA64_LTOFF_DTPREL22:
2235
          need_entry = NEED_DTPREL;
2236
          break;
2237
 
2238
        case R_IA64_DTPMOD64MSB:
2239
        case R_IA64_DTPMOD64LSB:
2240
          if (info->shared || maybe_dynamic)
2241
            need_entry = NEED_DYNREL;
2242
          break;
2243
 
2244
        case R_IA64_LTOFF_DTPMOD22:
2245
          need_entry = NEED_DTPMOD;
2246
          break;
2247
 
2248
        case R_IA64_LTOFF_FPTR22:
2249
        case R_IA64_LTOFF_FPTR64I:
2250
        case R_IA64_LTOFF_FPTR32MSB:
2251
        case R_IA64_LTOFF_FPTR32LSB:
2252
        case R_IA64_LTOFF_FPTR64MSB:
2253
        case R_IA64_LTOFF_FPTR64LSB:
2254
          need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2255
          break;
2256
 
2257
        case R_IA64_FPTR64I:
2258
        case R_IA64_FPTR32MSB:
2259
        case R_IA64_FPTR32LSB:
2260
        case R_IA64_FPTR64MSB:
2261
        case R_IA64_FPTR64LSB:
2262
          if (info->shared || h)
2263
            need_entry = NEED_FPTR | NEED_DYNREL;
2264
          else
2265
            need_entry = NEED_FPTR;
2266
          break;
2267
 
2268
        case R_IA64_LTOFF22:
2269
        case R_IA64_LTOFF64I:
2270
          need_entry = NEED_GOT;
2271
          break;
2272
 
2273
        case R_IA64_LTOFF22X:
2274
          need_entry = NEED_GOTX;
2275
          break;
2276
 
2277
        case R_IA64_PLTOFF22:
2278
        case R_IA64_PLTOFF64I:
2279
        case R_IA64_PLTOFF64MSB:
2280
        case R_IA64_PLTOFF64LSB:
2281
          need_entry = NEED_PLTOFF;
2282
          if (h)
2283
            {
2284
              if (maybe_dynamic)
2285
                need_entry |= NEED_MIN_PLT;
2286
            }
2287
          else
2288
            {
2289
              (*info->callbacks->warning)
2290
                (info, _("@pltoff reloc against local symbol"), 0,
2291
                 abfd, 0, (bfd_vma) 0);
2292
            }
2293
          break;
2294
 
2295
        case R_IA64_PCREL21B:
2296
        case R_IA64_PCREL60B:
2297
          /* Depending on where this symbol is defined, we may or may not
2298
             need a full plt entry.  Only skip if we know we'll not need
2299
             the entry -- static or symbolic, and the symbol definition
2300
             has already been seen.  */
2301
          if (maybe_dynamic && rel->r_addend == 0)
2302
            need_entry = NEED_FULL_PLT;
2303
          break;
2304
 
2305
        case R_IA64_IMM14:
2306
        case R_IA64_IMM22:
2307
        case R_IA64_IMM64:
2308
        case R_IA64_DIR32MSB:
2309
        case R_IA64_DIR32LSB:
2310
        case R_IA64_DIR64MSB:
2311
        case R_IA64_DIR64LSB:
2312
          /* Shared objects will always need at least a REL relocation.  */
2313
          if (info->shared || maybe_dynamic)
2314
            need_entry = NEED_DYNREL;
2315
          break;
2316
 
2317
        case R_IA64_IPLTMSB:
2318
        case R_IA64_IPLTLSB:
2319
          /* Shared objects will always need at least a REL relocation.  */
2320
          if (info->shared || maybe_dynamic)
2321
            need_entry = NEED_DYNREL;
2322
          break;
2323
 
2324
        case R_IA64_PCREL22:
2325
        case R_IA64_PCREL64I:
2326
        case R_IA64_PCREL32MSB:
2327
        case R_IA64_PCREL32LSB:
2328
        case R_IA64_PCREL64MSB:
2329
        case R_IA64_PCREL64LSB:
2330
          if (maybe_dynamic)
2331
            need_entry = NEED_DYNREL;
2332
          break;
2333
        }
2334
 
2335
      if (!need_entry)
2336
        continue;
2337
 
2338
      if ((need_entry & NEED_FPTR) != 0
2339
          && rel->r_addend)
2340
        {
2341
          (*info->callbacks->warning)
2342
            (info, _("non-zero addend in @fptr reloc"), 0,
2343
             abfd, 0, (bfd_vma) 0);
2344
        }
2345
 
2346
      if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
2347
        return FALSE;
2348
    }
2349
 
2350
  /* Now, we only do lookup without insertion, which is very fast
2351
     with the modified get_dyn_sym_info.  */
2352
  for (rel = relocs; rel < relend; ++rel)
2353
    {
2354
      struct elfNN_ia64_dyn_sym_info *dyn_i;
2355
      int dynrel_type = R_IA64_NONE;
2356
 
2357
      r_symndx = ELFNN_R_SYM (rel->r_info);
2358
      if (r_symndx >= symtab_hdr->sh_info)
2359
        {
2360
          /* We're dealing with a global symbol -- find its hash entry
2361
             and mark it as being referenced.  */
2362
          long indx = r_symndx - symtab_hdr->sh_info;
2363
          h = elf_sym_hashes (abfd)[indx];
2364
          while (h->root.type == bfd_link_hash_indirect
2365
                 || h->root.type == bfd_link_hash_warning)
2366
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
2367
 
2368
          h->ref_regular = 1;
2369
        }
2370
      else
2371
        h = NULL;
2372
 
2373
      /* We can only get preliminary data on whether a symbol is
2374
         locally or externally defined, as not all of the input files
2375
         have yet been processed.  Do something with what we know, as
2376
         this may help reduce memory usage and processing time later.  */
2377
      maybe_dynamic = (h && ((!info->executable
2378
                              && (!SYMBOLIC_BIND (info, h)
2379
                                  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2380
                             || !h->def_regular
2381
                             || h->root.type == bfd_link_hash_defweak));
2382
 
2383
      need_entry = 0;
2384
      switch (ELFNN_R_TYPE (rel->r_info))
2385
        {
2386
        case R_IA64_TPREL64MSB:
2387
        case R_IA64_TPREL64LSB:
2388
          if (info->shared || maybe_dynamic)
2389
            need_entry = NEED_DYNREL;
2390
          dynrel_type = R_IA64_TPREL64LSB;
2391
          if (info->shared)
2392
            info->flags |= DF_STATIC_TLS;
2393
          break;
2394
 
2395
        case R_IA64_LTOFF_TPREL22:
2396
          need_entry = NEED_TPREL;
2397
          if (info->shared)
2398
            info->flags |= DF_STATIC_TLS;
2399
          break;
2400
 
2401
        case R_IA64_DTPREL32MSB:
2402
        case R_IA64_DTPREL32LSB:
2403
        case R_IA64_DTPREL64MSB:
2404
        case R_IA64_DTPREL64LSB:
2405
          if (info->shared || maybe_dynamic)
2406
            need_entry = NEED_DYNREL;
2407
          dynrel_type = R_IA64_DTPRELNNLSB;
2408
          break;
2409
 
2410
        case R_IA64_LTOFF_DTPREL22:
2411
          need_entry = NEED_DTPREL;
2412
          break;
2413
 
2414
        case R_IA64_DTPMOD64MSB:
2415
        case R_IA64_DTPMOD64LSB:
2416
          if (info->shared || maybe_dynamic)
2417
            need_entry = NEED_DYNREL;
2418
          dynrel_type = R_IA64_DTPMOD64LSB;
2419
          break;
2420
 
2421
        case R_IA64_LTOFF_DTPMOD22:
2422
          need_entry = NEED_DTPMOD;
2423
          break;
2424
 
2425
        case R_IA64_LTOFF_FPTR22:
2426
        case R_IA64_LTOFF_FPTR64I:
2427
        case R_IA64_LTOFF_FPTR32MSB:
2428
        case R_IA64_LTOFF_FPTR32LSB:
2429
        case R_IA64_LTOFF_FPTR64MSB:
2430
        case R_IA64_LTOFF_FPTR64LSB:
2431
          need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2432
          break;
2433
 
2434
        case R_IA64_FPTR64I:
2435
        case R_IA64_FPTR32MSB:
2436
        case R_IA64_FPTR32LSB:
2437
        case R_IA64_FPTR64MSB:
2438
        case R_IA64_FPTR64LSB:
2439
          if (info->shared || h)
2440
            need_entry = NEED_FPTR | NEED_DYNREL;
2441
          else
2442
            need_entry = NEED_FPTR;
2443
          dynrel_type = R_IA64_FPTRNNLSB;
2444
          break;
2445
 
2446
        case R_IA64_LTOFF22:
2447
        case R_IA64_LTOFF64I:
2448
          need_entry = NEED_GOT;
2449
          break;
2450
 
2451
        case R_IA64_LTOFF22X:
2452
          need_entry = NEED_GOTX;
2453
          break;
2454
 
2455
        case R_IA64_PLTOFF22:
2456
        case R_IA64_PLTOFF64I:
2457
        case R_IA64_PLTOFF64MSB:
2458
        case R_IA64_PLTOFF64LSB:
2459
          need_entry = NEED_PLTOFF;
2460
          if (h)
2461
            {
2462
              if (maybe_dynamic)
2463
                need_entry |= NEED_MIN_PLT;
2464
            }
2465
          break;
2466
 
2467
        case R_IA64_PCREL21B:
2468
        case R_IA64_PCREL60B:
2469
          /* Depending on where this symbol is defined, we may or may not
2470
             need a full plt entry.  Only skip if we know we'll not need
2471
             the entry -- static or symbolic, and the symbol definition
2472
             has already been seen.  */
2473
          if (maybe_dynamic && rel->r_addend == 0)
2474
            need_entry = NEED_FULL_PLT;
2475
          break;
2476
 
2477
        case R_IA64_IMM14:
2478
        case R_IA64_IMM22:
2479
        case R_IA64_IMM64:
2480
        case R_IA64_DIR32MSB:
2481
        case R_IA64_DIR32LSB:
2482
        case R_IA64_DIR64MSB:
2483
        case R_IA64_DIR64LSB:
2484
          /* Shared objects will always need at least a REL relocation.  */
2485
          if (info->shared || maybe_dynamic)
2486
            need_entry = NEED_DYNREL;
2487
          dynrel_type = R_IA64_DIRNNLSB;
2488
          break;
2489
 
2490
        case R_IA64_IPLTMSB:
2491
        case R_IA64_IPLTLSB:
2492
          /* Shared objects will always need at least a REL relocation.  */
2493
          if (info->shared || maybe_dynamic)
2494
            need_entry = NEED_DYNREL;
2495
          dynrel_type = R_IA64_IPLTLSB;
2496
          break;
2497
 
2498
        case R_IA64_PCREL22:
2499
        case R_IA64_PCREL64I:
2500
        case R_IA64_PCREL32MSB:
2501
        case R_IA64_PCREL32LSB:
2502
        case R_IA64_PCREL64MSB:
2503
        case R_IA64_PCREL64LSB:
2504
          if (maybe_dynamic)
2505
            need_entry = NEED_DYNREL;
2506
          dynrel_type = R_IA64_PCRELNNLSB;
2507
          break;
2508
        }
2509
 
2510
      if (!need_entry)
2511
        continue;
2512
 
2513
      dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
2514
 
2515
      /* Record whether or not this is a local symbol.  */
2516
      dyn_i->h = h;
2517
 
2518
      /* Create what's needed.  */
2519
      if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2520
                        | NEED_DTPMOD | NEED_DTPREL))
2521
        {
2522
          if (!got)
2523
            {
2524
              got = get_got (abfd, info, ia64_info);
2525
              if (!got)
2526
                return FALSE;
2527
            }
2528
          if (need_entry & NEED_GOT)
2529
            dyn_i->want_got = 1;
2530
          if (need_entry & NEED_GOTX)
2531
            dyn_i->want_gotx = 1;
2532
          if (need_entry & NEED_TPREL)
2533
            dyn_i->want_tprel = 1;
2534
          if (need_entry & NEED_DTPMOD)
2535
            dyn_i->want_dtpmod = 1;
2536
          if (need_entry & NEED_DTPREL)
2537
            dyn_i->want_dtprel = 1;
2538
        }
2539
      if (need_entry & NEED_FPTR)
2540
        {
2541
          if (!fptr)
2542
            {
2543
              fptr = get_fptr (abfd, info, ia64_info);
2544
              if (!fptr)
2545
                return FALSE;
2546
            }
2547
 
2548
          /* FPTRs for shared libraries are allocated by the dynamic
2549
             linker.  Make sure this local symbol will appear in the
2550
             dynamic symbol table.  */
2551
          if (!h && info->shared)
2552
            {
2553
              if (! (bfd_elf_link_record_local_dynamic_symbol
2554
                     (info, abfd, (long) r_symndx)))
2555
                return FALSE;
2556
            }
2557
 
2558
          dyn_i->want_fptr = 1;
2559
        }
2560
      if (need_entry & NEED_LTOFF_FPTR)
2561
        dyn_i->want_ltoff_fptr = 1;
2562
      if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2563
        {
2564
          if (!ia64_info->root.dynobj)
2565
            ia64_info->root.dynobj = abfd;
2566
          h->needs_plt = 1;
2567
          dyn_i->want_plt = 1;
2568
        }
2569
      if (need_entry & NEED_FULL_PLT)
2570
        dyn_i->want_plt2 = 1;
2571
      if (need_entry & NEED_PLTOFF)
2572
        {
2573
          /* This is needed here, in case @pltoff is used in a non-shared
2574
             link.  */
2575
          if (!pltoff)
2576
            {
2577
              pltoff = get_pltoff (abfd, info, ia64_info);
2578
              if (!pltoff)
2579
                return FALSE;
2580
            }
2581
 
2582
          dyn_i->want_pltoff = 1;
2583
        }
2584
      if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2585
        {
2586
          if (!srel)
2587
            {
2588
              srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
2589
              if (!srel)
2590
                return FALSE;
2591
            }
2592
          if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
2593
                                (sec->flags & SEC_READONLY) != 0))
2594
            return FALSE;
2595
        }
2596
    }
2597
 
2598
  return TRUE;
2599
}
2600
 
2601
/* For cleanliness, and potentially faster dynamic loading, allocate
2602
   external GOT entries first.  */
2603
 
2604
static bfd_boolean
2605
allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
2606
                          void * data)
2607
{
2608
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2609
 
2610
  if ((dyn_i->want_got || dyn_i->want_gotx)
2611
      && ! dyn_i->want_fptr
2612
      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2613
     {
2614
       dyn_i->got_offset = x->ofs;
2615
       x->ofs += 8;
2616
     }
2617
  if (dyn_i->want_tprel)
2618
    {
2619
      dyn_i->tprel_offset = x->ofs;
2620
      x->ofs += 8;
2621
    }
2622
  if (dyn_i->want_dtpmod)
2623
    {
2624
      if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2625
        {
2626
          dyn_i->dtpmod_offset = x->ofs;
2627
          x->ofs += 8;
2628
        }
2629
      else
2630
        {
2631
          struct elfNN_ia64_link_hash_table *ia64_info;
2632
 
2633
          ia64_info = elfNN_ia64_hash_table (x->info);
2634
          if (ia64_info == NULL)
2635
            return FALSE;
2636
 
2637
          if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2638
            {
2639
              ia64_info->self_dtpmod_offset = x->ofs;
2640
              x->ofs += 8;
2641
            }
2642
          dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2643
        }
2644
    }
2645
  if (dyn_i->want_dtprel)
2646
    {
2647
      dyn_i->dtprel_offset = x->ofs;
2648
      x->ofs += 8;
2649
    }
2650
  return TRUE;
2651
}
2652
 
2653
/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
2654
 
2655
static bfd_boolean
2656
allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
2657
                          void * data)
2658
{
2659
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2660
 
2661
  if (dyn_i->want_got
2662
      && dyn_i->want_fptr
2663
      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
2664
    {
2665
      dyn_i->got_offset = x->ofs;
2666
      x->ofs += 8;
2667
    }
2668
  return TRUE;
2669
}
2670
 
2671
/* Lastly, allocate all the GOT entries for local data.  */
2672
 
2673
static bfd_boolean
2674
allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
2675
                    PTR data)
2676
{
2677
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2678
 
2679
  if ((dyn_i->want_got || dyn_i->want_gotx)
2680
      && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2681
    {
2682
      dyn_i->got_offset = x->ofs;
2683
      x->ofs += 8;
2684
    }
2685
  return TRUE;
2686
}
2687
 
2688
/* Search for the index of a global symbol in it's defining object file.  */
2689
 
2690
static long
2691
global_sym_index (struct elf_link_hash_entry *h)
2692
{
2693
  struct elf_link_hash_entry **p;
2694
  bfd *obj;
2695
 
2696
  BFD_ASSERT (h->root.type == bfd_link_hash_defined
2697
              || h->root.type == bfd_link_hash_defweak);
2698
 
2699
  obj = h->root.u.def.section->owner;
2700
  for (p = elf_sym_hashes (obj); *p != h; ++p)
2701
    continue;
2702
 
2703
  return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2704
}
2705
 
2706
/* Allocate function descriptors.  We can do these for every function
2707
   in a main executable that is not exported.  */
2708
 
2709
static bfd_boolean
2710
allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data)
2711
{
2712
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2713
 
2714
  if (dyn_i->want_fptr)
2715
    {
2716
      struct elf_link_hash_entry *h = dyn_i->h;
2717
 
2718
      if (h)
2719
        while (h->root.type == bfd_link_hash_indirect
2720
               || h->root.type == bfd_link_hash_warning)
2721
          h = (struct elf_link_hash_entry *) h->root.u.i.link;
2722
 
2723
      if (!x->info->executable
2724
          && (!h
2725
              || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2726
              || (h->root.type != bfd_link_hash_undefweak
2727
                  && h->root.type != bfd_link_hash_undefined)))
2728
        {
2729
          if (h && h->dynindx == -1)
2730
            {
2731
              BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2732
                          || (h->root.type == bfd_link_hash_defweak));
2733
 
2734
              if (!bfd_elf_link_record_local_dynamic_symbol
2735
                    (x->info, h->root.u.def.section->owner,
2736
                     global_sym_index (h)))
2737
                return FALSE;
2738
            }
2739
 
2740
          dyn_i->want_fptr = 0;
2741
        }
2742
      else if (h == NULL || h->dynindx == -1)
2743
        {
2744
          dyn_i->fptr_offset = x->ofs;
2745
          x->ofs += 16;
2746
        }
2747
      else
2748
        dyn_i->want_fptr = 0;
2749
    }
2750
  return TRUE;
2751
}
2752
 
2753
/* Allocate all the minimal PLT entries.  */
2754
 
2755
static bfd_boolean
2756
allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2757
                      PTR data)
2758
{
2759
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2760
 
2761
  if (dyn_i->want_plt)
2762
    {
2763
      struct elf_link_hash_entry *h = dyn_i->h;
2764
 
2765
      if (h)
2766
        while (h->root.type == bfd_link_hash_indirect
2767
               || h->root.type == bfd_link_hash_warning)
2768
          h = (struct elf_link_hash_entry *) h->root.u.i.link;
2769
 
2770
      /* ??? Versioned symbols seem to lose NEEDS_PLT.  */
2771
      if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
2772
        {
2773
          bfd_size_type offset = x->ofs;
2774
          if (offset == 0)
2775
            offset = PLT_HEADER_SIZE;
2776
          dyn_i->plt_offset = offset;
2777
          x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2778
 
2779
          dyn_i->want_pltoff = 1;
2780
        }
2781
      else
2782
        {
2783
          dyn_i->want_plt = 0;
2784
          dyn_i->want_plt2 = 0;
2785
        }
2786
    }
2787
  return TRUE;
2788
}
2789
 
2790
/* Allocate all the full PLT entries.  */
2791
 
2792
static bfd_boolean
2793
allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2794
                       PTR data)
2795
{
2796
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2797
 
2798
  if (dyn_i->want_plt2)
2799
    {
2800
      struct elf_link_hash_entry *h = dyn_i->h;
2801
      bfd_size_type ofs = x->ofs;
2802
 
2803
      dyn_i->plt2_offset = ofs;
2804
      x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2805
 
2806
      while (h->root.type == bfd_link_hash_indirect
2807
             || h->root.type == bfd_link_hash_warning)
2808
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
2809
      dyn_i->h->plt.offset = ofs;
2810
    }
2811
  return TRUE;
2812
}
2813
 
2814
/* Allocate all the PLTOFF entries requested by relocations and
2815
   plt entries.  We can't share space with allocated FPTR entries,
2816
   because the latter are not necessarily addressable by the GP.
2817
   ??? Relaxation might be able to determine that they are.  */
2818
 
2819
static bfd_boolean
2820
allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2821
                         PTR data)
2822
{
2823
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2824
 
2825
  if (dyn_i->want_pltoff)
2826
    {
2827
      dyn_i->pltoff_offset = x->ofs;
2828
      x->ofs += 16;
2829
    }
2830
  return TRUE;
2831
}
2832
 
2833
/* Allocate dynamic relocations for those symbols that turned out
2834
   to be dynamic.  */
2835
 
2836
static bfd_boolean
2837
allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2838
                         PTR data)
2839
{
2840
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2841
  struct elfNN_ia64_link_hash_table *ia64_info;
2842
  struct elfNN_ia64_dyn_reloc_entry *rent;
2843
  bfd_boolean dynamic_symbol, shared, resolved_zero;
2844
 
2845
  ia64_info = elfNN_ia64_hash_table (x->info);
2846
  if (ia64_info == NULL)
2847
    return FALSE;
2848
 
2849
  /* Note that this can't be used in relation to FPTR relocs below.  */
2850
  dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
2851
 
2852
  shared = x->info->shared;
2853
  resolved_zero = (dyn_i->h
2854
                   && ELF_ST_VISIBILITY (dyn_i->h->other)
2855
                   && dyn_i->h->root.type == bfd_link_hash_undefweak);
2856
 
2857
  /* Take care of the GOT and PLT relocations.  */
2858
 
2859
  if ((!resolved_zero
2860
       && (dynamic_symbol || shared)
2861
       && (dyn_i->want_got || dyn_i->want_gotx))
2862
      || (dyn_i->want_ltoff_fptr
2863
          && dyn_i->h
2864
          && dyn_i->h->dynindx != -1))
2865
    {
2866
      if (!dyn_i->want_ltoff_fptr
2867
          || !x->info->pie
2868
          || dyn_i->h == NULL
2869
          || dyn_i->h->root.type != bfd_link_hash_undefweak)
2870
        ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2871
    }
2872
  if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2873
    ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2874
  if (dynamic_symbol && dyn_i->want_dtpmod)
2875
    ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2876
  if (dynamic_symbol && dyn_i->want_dtprel)
2877
    ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2878
 
2879
  if (x->only_got)
2880
    return TRUE;
2881
 
2882
  if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
2883
    {
2884
      if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
2885
        ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
2886
    }
2887
 
2888
  if (!resolved_zero && dyn_i->want_pltoff)
2889
    {
2890
      bfd_size_type t = 0;
2891
 
2892
      /* Dynamic symbols get one IPLT relocation.  Local symbols in
2893
         shared libraries get two REL relocations.  Local symbols in
2894
         main applications get nothing.  */
2895
      if (dynamic_symbol)
2896
        t = sizeof (ElfNN_External_Rela);
2897
      else if (shared)
2898
        t = 2 * sizeof (ElfNN_External_Rela);
2899
 
2900
      ia64_info->rel_pltoff_sec->size += t;
2901
    }
2902
 
2903
  /* Take care of the normal data relocations.  */
2904
 
2905
  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2906
    {
2907
      int count = rent->count;
2908
 
2909
      switch (rent->type)
2910
        {
2911
        case R_IA64_FPTR32LSB:
2912
        case R_IA64_FPTR64LSB:
2913
          /* Allocate one iff !want_fptr and not PIE, which by this point
2914
             will be true only if we're actually allocating one statically
2915
             in the main executable.  Position independent executables
2916
             need a relative reloc.  */
2917
          if (dyn_i->want_fptr && !x->info->pie)
2918
            continue;
2919
          break;
2920
        case R_IA64_PCREL32LSB:
2921
        case R_IA64_PCREL64LSB:
2922
          if (!dynamic_symbol)
2923
            continue;
2924
          break;
2925
        case R_IA64_DIR32LSB:
2926
        case R_IA64_DIR64LSB:
2927
          if (!dynamic_symbol && !shared)
2928
            continue;
2929
          break;
2930
        case R_IA64_IPLTLSB:
2931
          if (!dynamic_symbol && !shared)
2932
            continue;
2933
          /* Use two REL relocations for IPLT relocations
2934
             against local symbols.  */
2935
          if (!dynamic_symbol)
2936
            count *= 2;
2937
          break;
2938
        case R_IA64_DTPREL32LSB:
2939
        case R_IA64_TPREL64LSB:
2940
        case R_IA64_DTPREL64LSB:
2941
        case R_IA64_DTPMOD64LSB:
2942
          break;
2943
        default:
2944
          abort ();
2945
        }
2946
      if (rent->reltext)
2947
        ia64_info->reltext = 1;
2948
      rent->srel->size += sizeof (ElfNN_External_Rela) * count;
2949
    }
2950
 
2951
  return TRUE;
2952
}
2953
 
2954
static bfd_boolean
2955
elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2956
                                  struct elf_link_hash_entry *h)
2957
{
2958
  /* ??? Undefined symbols with PLT entries should be re-defined
2959
     to be the PLT entry.  */
2960
 
2961
  /* If this is a weak symbol, and there is a real definition, the
2962
     processor independent code will have arranged for us to see the
2963
     real definition first, and we can just use the same value.  */
2964
  if (h->u.weakdef != NULL)
2965
    {
2966
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2967
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
2968
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
2969
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
2970
      return TRUE;
2971
    }
2972
 
2973
  /* If this is a reference to a symbol defined by a dynamic object which
2974
     is not a function, we might allocate the symbol in our .dynbss section
2975
     and allocate a COPY dynamic relocation.
2976
 
2977
     But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2978
     of hackery.  */
2979
 
2980
  return TRUE;
2981
}
2982
 
2983
static bfd_boolean
2984
elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2985
                                  struct bfd_link_info *info)
2986
{
2987
  struct elfNN_ia64_allocate_data data;
2988
  struct elfNN_ia64_link_hash_table *ia64_info;
2989
  asection *sec;
2990
  bfd *dynobj;
2991
  bfd_boolean relplt = FALSE;
2992
 
2993
  dynobj = elf_hash_table(info)->dynobj;
2994
  ia64_info = elfNN_ia64_hash_table (info);
2995
  if (ia64_info == NULL)
2996
    return FALSE;
2997
  ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2998
  BFD_ASSERT(dynobj != NULL);
2999
  data.info = info;
3000
 
3001
  /* Set the contents of the .interp section to the interpreter.  */
3002
  if (ia64_info->root.dynamic_sections_created
3003
      && info->executable)
3004
    {
3005
      sec = bfd_get_section_by_name (dynobj, ".interp");
3006
      BFD_ASSERT (sec != NULL);
3007
      sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3008
      sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3009
    }
3010
 
3011
  /* Allocate the GOT entries.  */
3012
 
3013
  if (ia64_info->root.sgot)
3014
    {
3015
      data.ofs = 0;
3016
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
3017
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
3018
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
3019
      ia64_info->root.sgot->size = data.ofs;
3020
    }
3021
 
3022
  /* Allocate the FPTR entries.  */
3023
 
3024
  if (ia64_info->fptr_sec)
3025
    {
3026
      data.ofs = 0;
3027
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
3028
      ia64_info->fptr_sec->size = data.ofs;
3029
    }
3030
 
3031
  /* Now that we've seen all of the input files, we can decide which
3032
     symbols need plt entries.  Allocate the minimal PLT entries first.
3033
     We do this even though dynamic_sections_created may be FALSE, because
3034
     this has the side-effect of clearing want_plt and want_plt2.  */
3035
 
3036
  data.ofs = 0;
3037
  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
3038
 
3039
  ia64_info->minplt_entries = 0;
3040
  if (data.ofs)
3041
    {
3042
      ia64_info->minplt_entries
3043
        = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3044
    }
3045
 
3046
  /* Align the pointer for the plt2 entries.  */
3047
  data.ofs = (data.ofs + 31) & (bfd_vma) -32;
3048
 
3049
  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
3050
  if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
3051
    {
3052
      /* FIXME: we always reserve the memory for dynamic linker even if
3053
         there are no PLT entries since dynamic linker may assume the
3054
         reserved memory always exists.  */
3055
 
3056
      BFD_ASSERT (ia64_info->root.dynamic_sections_created);
3057
 
3058
      ia64_info->root.splt->size = data.ofs;
3059
 
3060
      /* If we've got a .plt, we need some extra memory for the dynamic
3061
         linker.  We stuff these in .got.plt.  */
3062
      sec = bfd_get_section_by_name (dynobj, ".got.plt");
3063
      sec->size = 8 * PLT_RESERVED_WORDS;
3064
    }
3065
 
3066
  /* Allocate the PLTOFF entries.  */
3067
 
3068
  if (ia64_info->pltoff_sec)
3069
    {
3070
      data.ofs = 0;
3071
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
3072
      ia64_info->pltoff_sec->size = data.ofs;
3073
    }
3074
 
3075
  if (ia64_info->root.dynamic_sections_created)
3076
    {
3077
      /* Allocate space for the dynamic relocations that turned out to be
3078
         required.  */
3079
 
3080
      if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
3081
        ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
3082
      data.only_got = FALSE;
3083
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
3084
    }
3085
 
3086
  /* We have now determined the sizes of the various dynamic sections.
3087
     Allocate memory for them.  */
3088
  for (sec = dynobj->sections; sec != NULL; sec = sec->next)
3089
    {
3090
      bfd_boolean strip;
3091
 
3092
      if (!(sec->flags & SEC_LINKER_CREATED))
3093
        continue;
3094
 
3095
      /* If we don't need this section, strip it from the output file.
3096
         There were several sections primarily related to dynamic
3097
         linking that must be create before the linker maps input
3098
         sections to output sections.  The linker does that before
3099
         bfd_elf_size_dynamic_sections is called, and it is that
3100
         function which decides whether anything needs to go into
3101
         these sections.  */
3102
 
3103
      strip = (sec->size == 0);
3104
 
3105
      if (sec == ia64_info->root.sgot)
3106
        strip = FALSE;
3107
      else if (sec == ia64_info->root.srelgot)
3108
        {
3109
          if (strip)
3110
            ia64_info->root.srelgot = NULL;
3111
          else
3112
            /* We use the reloc_count field as a counter if we need to
3113
               copy relocs into the output file.  */
3114
            sec->reloc_count = 0;
3115
        }
3116
      else if (sec == ia64_info->fptr_sec)
3117
        {
3118
          if (strip)
3119
            ia64_info->fptr_sec = NULL;
3120
        }
3121
      else if (sec == ia64_info->rel_fptr_sec)
3122
        {
3123
          if (strip)
3124
            ia64_info->rel_fptr_sec = NULL;
3125
          else
3126
            /* We use the reloc_count field as a counter if we need to
3127
               copy relocs into the output file.  */
3128
            sec->reloc_count = 0;
3129
        }
3130
      else if (sec == ia64_info->root.splt)
3131
        {
3132
          if (strip)
3133
            ia64_info->root.splt = NULL;
3134
        }
3135
      else if (sec == ia64_info->pltoff_sec)
3136
        {
3137
          if (strip)
3138
            ia64_info->pltoff_sec = NULL;
3139
        }
3140
      else if (sec == ia64_info->rel_pltoff_sec)
3141
        {
3142
          if (strip)
3143
            ia64_info->rel_pltoff_sec = NULL;
3144
          else
3145
            {
3146
              relplt = TRUE;
3147
              /* We use the reloc_count field as a counter if we need to
3148
                 copy relocs into the output file.  */
3149
              sec->reloc_count = 0;
3150
            }
3151
        }
3152
      else
3153
        {
3154
          const char *name;
3155
 
3156
          /* It's OK to base decisions on the section name, because none
3157
             of the dynobj section names depend upon the input files.  */
3158
          name = bfd_get_section_name (dynobj, sec);
3159
 
3160
          if (strcmp (name, ".got.plt") == 0)
3161
            strip = FALSE;
3162
          else if (CONST_STRNEQ (name, ".rel"))
3163
            {
3164
              if (!strip)
3165
                {
3166
                  /* We use the reloc_count field as a counter if we need to
3167
                     copy relocs into the output file.  */
3168
                  sec->reloc_count = 0;
3169
                }
3170
            }
3171
          else
3172
            continue;
3173
        }
3174
 
3175
      if (strip)
3176
        sec->flags |= SEC_EXCLUDE;
3177
      else
3178
        {
3179
          /* Allocate memory for the section contents.  */
3180
          sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3181
          if (sec->contents == NULL && sec->size != 0)
3182
            return FALSE;
3183
        }
3184
    }
3185
 
3186
  if (elf_hash_table (info)->dynamic_sections_created)
3187
    {
3188
      /* Add some entries to the .dynamic section.  We fill in the values
3189
         later (in finish_dynamic_sections) but we must add the entries now
3190
         so that we get the correct size for the .dynamic section.  */
3191
 
3192
      if (info->executable)
3193
        {
3194
          /* The DT_DEBUG entry is filled in by the dynamic linker and used
3195
             by the debugger.  */
3196
#define add_dynamic_entry(TAG, VAL) \
3197
  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3198
 
3199
          if (!add_dynamic_entry (DT_DEBUG, 0))
3200
            return FALSE;
3201
        }
3202
 
3203
      if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3204
        return FALSE;
3205
      if (!add_dynamic_entry (DT_PLTGOT, 0))
3206
        return FALSE;
3207
 
3208
      if (relplt)
3209
        {
3210
          if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3211
              || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3212
              || !add_dynamic_entry (DT_JMPREL, 0))
3213
            return FALSE;
3214
        }
3215
 
3216
      if (!add_dynamic_entry (DT_RELA, 0)
3217
          || !add_dynamic_entry (DT_RELASZ, 0)
3218
          || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3219
        return FALSE;
3220
 
3221
      if (ia64_info->reltext)
3222
        {
3223
          if (!add_dynamic_entry (DT_TEXTREL, 0))
3224
            return FALSE;
3225
          info->flags |= DF_TEXTREL;
3226
        }
3227
    }
3228
 
3229
  /* ??? Perhaps force __gp local.  */
3230
 
3231
  return TRUE;
3232
}
3233
 
3234
static void
3235
elfNN_ia64_install_dyn_reloc (bfd *abfd, struct bfd_link_info *info,
3236
                              asection *sec, asection *srel,
3237
                              bfd_vma offset, unsigned int type,
3238
                              long dynindx, bfd_vma addend)
3239
{
3240
  Elf_Internal_Rela outrel;
3241
  bfd_byte *loc;
3242
 
3243
  BFD_ASSERT (dynindx != -1);
3244
  outrel.r_info = ELFNN_R_INFO (dynindx, type);
3245
  outrel.r_addend = addend;
3246
  outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3247
  if (outrel.r_offset >= (bfd_vma) -2)
3248
    {
3249
      /* Run for the hills.  We shouldn't be outputting a relocation
3250
         for this.  So do what everyone else does and output a no-op.  */
3251
      outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3252
      outrel.r_addend = 0;
3253
      outrel.r_offset = 0;
3254
    }
3255
  else
3256
    outrel.r_offset += sec->output_section->vma + sec->output_offset;
3257
 
3258
  loc = srel->contents;
3259
  loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3260
  bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3261
  BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
3262
}
3263
 
3264
/* Store an entry for target address TARGET_ADDR in the linkage table
3265
   and return the gp-relative address of the linkage table entry.  */
3266
 
3267
static bfd_vma
3268
set_got_entry (bfd *abfd, struct bfd_link_info *info,
3269
               struct elfNN_ia64_dyn_sym_info *dyn_i,
3270
               long dynindx, bfd_vma addend, bfd_vma value,
3271
               unsigned int dyn_r_type)
3272
{
3273
  struct elfNN_ia64_link_hash_table *ia64_info;
3274
  asection *got_sec;
3275
  bfd_boolean done;
3276
  bfd_vma got_offset;
3277
 
3278
  ia64_info = elfNN_ia64_hash_table (info);
3279
  if (ia64_info == NULL)
3280
    return 0;
3281
 
3282
  got_sec = ia64_info->root.sgot;
3283
 
3284
  switch (dyn_r_type)
3285
    {
3286
    case R_IA64_TPREL64LSB:
3287
      done = dyn_i->tprel_done;
3288
      dyn_i->tprel_done = TRUE;
3289
      got_offset = dyn_i->tprel_offset;
3290
      break;
3291
    case R_IA64_DTPMOD64LSB:
3292
      if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3293
        {
3294
          done = dyn_i->dtpmod_done;
3295
          dyn_i->dtpmod_done = TRUE;
3296
        }
3297
      else
3298
        {
3299
          done = ia64_info->self_dtpmod_done;
3300
          ia64_info->self_dtpmod_done = TRUE;
3301
          dynindx = 0;
3302
        }
3303
      got_offset = dyn_i->dtpmod_offset;
3304
      break;
3305
    case R_IA64_DTPREL32LSB:
3306
    case R_IA64_DTPREL64LSB:
3307
      done = dyn_i->dtprel_done;
3308
      dyn_i->dtprel_done = TRUE;
3309
      got_offset = dyn_i->dtprel_offset;
3310
      break;
3311
    default:
3312
      done = dyn_i->got_done;
3313
      dyn_i->got_done = TRUE;
3314
      got_offset = dyn_i->got_offset;
3315
      break;
3316
    }
3317
 
3318
  BFD_ASSERT ((got_offset & 7) == 0);
3319
 
3320
  if (! done)
3321
    {
3322
      /* Store the target address in the linkage table entry.  */
3323
      bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3324
 
3325
      /* Install a dynamic relocation if needed.  */
3326
      if (((info->shared
3327
            && (!dyn_i->h
3328
                || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3329
                || dyn_i->h->root.type != bfd_link_hash_undefweak)
3330
            && dyn_r_type != R_IA64_DTPREL32LSB
3331
            && dyn_r_type != R_IA64_DTPREL64LSB)
3332
           || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
3333
           || (dynindx != -1
3334
               && (dyn_r_type == R_IA64_FPTR32LSB
3335
                   || dyn_r_type == R_IA64_FPTR64LSB)))
3336
          && (!dyn_i->want_ltoff_fptr
3337
              || !info->pie
3338
              || !dyn_i->h
3339
              || dyn_i->h->root.type != bfd_link_hash_undefweak))
3340
        {
3341
          if (dynindx == -1
3342
              && dyn_r_type != R_IA64_TPREL64LSB
3343
              && dyn_r_type != R_IA64_DTPMOD64LSB
3344
              && dyn_r_type != R_IA64_DTPREL32LSB
3345
              && dyn_r_type != R_IA64_DTPREL64LSB)
3346
            {
3347
              dyn_r_type = R_IA64_RELNNLSB;
3348
              dynindx = 0;
3349
              addend = value;
3350
            }
3351
 
3352
          if (bfd_big_endian (abfd))
3353
            {
3354
              switch (dyn_r_type)
3355
                {
3356
                case R_IA64_REL32LSB:
3357
                  dyn_r_type = R_IA64_REL32MSB;
3358
                  break;
3359
                case R_IA64_DIR32LSB:
3360
                  dyn_r_type = R_IA64_DIR32MSB;
3361
                  break;
3362
                case R_IA64_FPTR32LSB:
3363
                  dyn_r_type = R_IA64_FPTR32MSB;
3364
                  break;
3365
                case R_IA64_DTPREL32LSB:
3366
                  dyn_r_type = R_IA64_DTPREL32MSB;
3367
                  break;
3368
                case R_IA64_REL64LSB:
3369
                  dyn_r_type = R_IA64_REL64MSB;
3370
                  break;
3371
                case R_IA64_DIR64LSB:
3372
                  dyn_r_type = R_IA64_DIR64MSB;
3373
                  break;
3374
                case R_IA64_FPTR64LSB:
3375
                  dyn_r_type = R_IA64_FPTR64MSB;
3376
                  break;
3377
                case R_IA64_TPREL64LSB:
3378
                  dyn_r_type = R_IA64_TPREL64MSB;
3379
                  break;
3380
                case R_IA64_DTPMOD64LSB:
3381
                  dyn_r_type = R_IA64_DTPMOD64MSB;
3382
                  break;
3383
                case R_IA64_DTPREL64LSB:
3384
                  dyn_r_type = R_IA64_DTPREL64MSB;
3385
                  break;
3386
                default:
3387
                  BFD_ASSERT (FALSE);
3388
                  break;
3389
                }
3390
            }
3391
 
3392
          elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3393
                                        ia64_info->root.srelgot,
3394
                                        got_offset, dyn_r_type,
3395
                                        dynindx, addend);
3396
        }
3397
    }
3398
 
3399
  /* Return the address of the linkage table entry.  */
3400
  value = (got_sec->output_section->vma
3401
           + got_sec->output_offset
3402
           + got_offset);
3403
 
3404
  return value;
3405
}
3406
 
3407
/* Fill in a function descriptor consisting of the function's code
3408
   address and its global pointer.  Return the descriptor's address.  */
3409
 
3410
static bfd_vma
3411
set_fptr_entry (bfd *abfd, struct bfd_link_info *info,
3412
                struct elfNN_ia64_dyn_sym_info *dyn_i,
3413
                bfd_vma value)
3414
{
3415
  struct elfNN_ia64_link_hash_table *ia64_info;
3416
  asection *fptr_sec;
3417
 
3418
  ia64_info = elfNN_ia64_hash_table (info);
3419
  if (ia64_info == NULL)
3420
    return 0;
3421
 
3422
  fptr_sec = ia64_info->fptr_sec;
3423
 
3424
  if (!dyn_i->fptr_done)
3425
    {
3426
      dyn_i->fptr_done = 1;
3427
 
3428
      /* Fill in the function descriptor.  */
3429
      bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3430
      bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3431
                  fptr_sec->contents + dyn_i->fptr_offset + 8);
3432
      if (ia64_info->rel_fptr_sec)
3433
        {
3434
          Elf_Internal_Rela outrel;
3435
          bfd_byte *loc;
3436
 
3437
          if (bfd_little_endian (abfd))
3438
            outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
3439
          else
3440
            outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
3441
          outrel.r_addend = value;
3442
          outrel.r_offset = (fptr_sec->output_section->vma
3443
                             + fptr_sec->output_offset
3444
                             + dyn_i->fptr_offset);
3445
          loc = ia64_info->rel_fptr_sec->contents;
3446
          loc += ia64_info->rel_fptr_sec->reloc_count++
3447
                 * sizeof (ElfNN_External_Rela);
3448
          bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3449
        }
3450
    }
3451
 
3452
  /* Return the descriptor's address.  */
3453
  value = (fptr_sec->output_section->vma
3454
           + fptr_sec->output_offset
3455
           + dyn_i->fptr_offset);
3456
 
3457
  return value;
3458
}
3459
 
3460
/* Fill in a PLTOFF entry consisting of the function's code address
3461
   and its global pointer.  Return the descriptor's address.  */
3462
 
3463
static bfd_vma
3464
set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
3465
                  struct elfNN_ia64_dyn_sym_info *dyn_i,
3466
                  bfd_vma value, bfd_boolean is_plt)
3467
{
3468
  struct elfNN_ia64_link_hash_table *ia64_info;
3469
  asection *pltoff_sec;
3470
 
3471
  ia64_info = elfNN_ia64_hash_table (info);
3472
  if (ia64_info == NULL)
3473
    return 0;
3474
 
3475
  pltoff_sec = ia64_info->pltoff_sec;
3476
 
3477
  /* Don't do anything if this symbol uses a real PLT entry.  In
3478
     that case, we'll fill this in during finish_dynamic_symbol.  */
3479
  if ((! dyn_i->want_plt || is_plt)
3480
      && !dyn_i->pltoff_done)
3481
    {
3482
      bfd_vma gp = _bfd_get_gp_value (abfd);
3483
 
3484
      /* Fill in the function descriptor.  */
3485
      bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3486
      bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3487
 
3488
      /* Install dynamic relocations if needed.  */
3489
      if (!is_plt
3490
          && info->shared
3491
          && (!dyn_i->h
3492
              || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3493
              || dyn_i->h->root.type != bfd_link_hash_undefweak))
3494
        {
3495
          unsigned int dyn_r_type;
3496
 
3497
          if (bfd_big_endian (abfd))
3498
            dyn_r_type = R_IA64_RELNNMSB;
3499
          else
3500
            dyn_r_type = R_IA64_RELNNLSB;
3501
 
3502
          elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3503
                                        ia64_info->rel_pltoff_sec,
3504
                                        dyn_i->pltoff_offset,
3505
                                        dyn_r_type, 0, value);
3506
          elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3507
                                        ia64_info->rel_pltoff_sec,
3508
                                        dyn_i->pltoff_offset + ARCH_SIZE / 8,
3509
                                        dyn_r_type, 0, gp);
3510
        }
3511
 
3512
      dyn_i->pltoff_done = 1;
3513
    }
3514
 
3515
  /* Return the descriptor's address.  */
3516
  value = (pltoff_sec->output_section->vma
3517
           + pltoff_sec->output_offset
3518
           + dyn_i->pltoff_offset);
3519
 
3520
  return value;
3521
}
3522
 
3523
/* Return the base VMA address which should be subtracted from real addresses
3524
   when resolving @tprel() relocation.
3525
   Main program TLS (whose template starts at PT_TLS p_vaddr)
3526
   is assigned offset round(2 * size of pointer, PT_TLS p_align).  */
3527
 
3528
static bfd_vma
3529
elfNN_ia64_tprel_base (struct bfd_link_info *info)
3530
{
3531
  asection *tls_sec = elf_hash_table (info)->tls_sec;
3532
  return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
3533
                                     tls_sec->alignment_power);
3534
}
3535
 
3536
/* Return the base VMA address which should be subtracted from real addresses
3537
   when resolving @dtprel() relocation.
3538
   This is PT_TLS segment p_vaddr.  */
3539
 
3540
static bfd_vma
3541
elfNN_ia64_dtprel_base (struct bfd_link_info *info)
3542
{
3543
  return elf_hash_table (info)->tls_sec->vma;
3544
}
3545
 
3546
/* Called through qsort to sort the .IA_64.unwind section during a
3547
   non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
3548
   to the output bfd so we can do proper endianness frobbing.  */
3549
 
3550
static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3551
 
3552
static int
3553
elfNN_ia64_unwind_entry_compare (const PTR a, const PTR b)
3554
{
3555
  bfd_vma av, bv;
3556
 
3557
  av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3558
  bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3559
 
3560
  return (av < bv ? -1 : av > bv ? 1 : 0);
3561
}
3562
 
3563
/* Make sure we've got ourselves a nice fat __gp value.  */
3564
static bfd_boolean
3565
elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
3566
{
3567
  bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3568
  bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3569
  struct elf_link_hash_entry *gp;
3570
  bfd_vma gp_val;
3571
  asection *os;
3572
  struct elfNN_ia64_link_hash_table *ia64_info;
3573
 
3574
  ia64_info = elfNN_ia64_hash_table (info);
3575
  if (ia64_info == NULL)
3576
    return FALSE;
3577
 
3578
  /* Find the min and max vma of all sections marked short.  Also collect
3579
     min and max vma of any type, for use in selecting a nice gp.  */
3580
  for (os = abfd->sections; os ; os = os->next)
3581
    {
3582
      bfd_vma lo, hi;
3583
 
3584
      if ((os->flags & SEC_ALLOC) == 0)
3585
        continue;
3586
 
3587
      lo = os->vma;
3588
      /* When this function is called from elfNN_ia64_final_link
3589
         the correct value to use is os->size.  When called from
3590
         elfNN_ia64_relax_section we are in the middle of section
3591
         sizing; some sections will already have os->size set, others
3592
         will have os->size zero and os->rawsize the previous size.  */
3593
      hi = os->vma + (!final && os->rawsize ? os->rawsize : os->size);
3594
      if (hi < lo)
3595
        hi = (bfd_vma) -1;
3596
 
3597
      if (min_vma > lo)
3598
        min_vma = lo;
3599
      if (max_vma < hi)
3600
        max_vma = hi;
3601
      if (os->flags & SEC_SMALL_DATA)
3602
        {
3603
          if (min_short_vma > lo)
3604
            min_short_vma = lo;
3605
          if (max_short_vma < hi)
3606
            max_short_vma = hi;
3607
        }
3608
    }
3609
 
3610
  if (ia64_info->min_short_sec)
3611
    {
3612
      if (min_short_vma
3613
          > (ia64_info->min_short_sec->vma
3614
             + ia64_info->min_short_offset))
3615
        min_short_vma = (ia64_info->min_short_sec->vma
3616
                         + ia64_info->min_short_offset);
3617
      if (max_short_vma
3618
          < (ia64_info->max_short_sec->vma
3619
             + ia64_info->max_short_offset))
3620
        max_short_vma = (ia64_info->max_short_sec->vma
3621
                         + ia64_info->max_short_offset);
3622
    }
3623
 
3624
  /* See if the user wants to force a value.  */
3625
  gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3626
                             FALSE, FALSE);
3627
 
3628
  if (gp
3629
      && (gp->root.type == bfd_link_hash_defined
3630
          || gp->root.type == bfd_link_hash_defweak))
3631
    {
3632
      asection *gp_sec = gp->root.u.def.section;
3633
      gp_val = (gp->root.u.def.value
3634
                + gp_sec->output_section->vma
3635
                + gp_sec->output_offset);
3636
    }
3637
  else
3638
    {
3639
      /* Pick a sensible value.  */
3640
 
3641
      if (ia64_info->min_short_sec)
3642
        {
3643
          bfd_vma short_range = max_short_vma - min_short_vma;
3644
 
3645
          /* If min_short_sec is set, pick one in the middle bewteen
3646
             min_short_vma and max_short_vma.  */
3647
          if (short_range >= 0x400000)
3648
            goto overflow;
3649
          gp_val = min_short_vma + short_range / 2;
3650
        }
3651
      else
3652
        {
3653
          asection *got_sec = ia64_info->root.sgot;
3654
 
3655
          /* Start with just the address of the .got.  */
3656
          if (got_sec)
3657
            gp_val = got_sec->output_section->vma;
3658
          else if (max_short_vma != 0)
3659
            gp_val = min_short_vma;
3660
          else if (max_vma - min_vma < 0x200000)
3661
            gp_val = min_vma;
3662
          else
3663
            gp_val = max_vma - 0x200000 + 8;
3664
        }
3665
 
3666
      /* If it is possible to address the entire image, but we
3667
         don't with the choice above, adjust.  */
3668
      if (max_vma - min_vma < 0x400000
3669
          && (max_vma - gp_val >= 0x200000
3670
              || gp_val - min_vma > 0x200000))
3671
        gp_val = min_vma + 0x200000;
3672
      else if (max_short_vma != 0)
3673
        {
3674
          /* If we don't cover all the short data, adjust.  */
3675
          if (max_short_vma - gp_val >= 0x200000)
3676
            gp_val = min_short_vma + 0x200000;
3677
 
3678
          /* If we're addressing stuff past the end, adjust back.  */
3679
          if (gp_val > max_vma)
3680
            gp_val = max_vma - 0x200000 + 8;
3681
        }
3682
    }
3683
 
3684
  /* Validate whether all SHF_IA_64_SHORT sections are within
3685
     range of the chosen GP.  */
3686
 
3687
  if (max_short_vma != 0)
3688
    {
3689
      if (max_short_vma - min_short_vma >= 0x400000)
3690
        {
3691
overflow:
3692
          (*_bfd_error_handler)
3693
            (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3694
             bfd_get_filename (abfd),
3695
             (unsigned long) (max_short_vma - min_short_vma));
3696
          return FALSE;
3697
        }
3698
      else if ((gp_val > min_short_vma
3699
                && gp_val - min_short_vma > 0x200000)
3700
               || (gp_val < max_short_vma
3701
                   && max_short_vma - gp_val >= 0x200000))
3702
        {
3703
          (*_bfd_error_handler)
3704
            (_("%s: __gp does not cover short data segment"),
3705
             bfd_get_filename (abfd));
3706
          return FALSE;
3707
        }
3708
    }
3709
 
3710
  _bfd_set_gp_value (abfd, gp_val);
3711
 
3712
  return TRUE;
3713
}
3714
 
3715
static bfd_boolean
3716
elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
3717
{
3718
  struct elfNN_ia64_link_hash_table *ia64_info;
3719
  asection *unwind_output_sec;
3720
 
3721
  ia64_info = elfNN_ia64_hash_table (info);
3722
  if (ia64_info == NULL)
3723
    return FALSE;
3724
 
3725
  /* Make sure we've got ourselves a nice fat __gp value.  */
3726
  if (!info->relocatable)
3727
    {
3728
      bfd_vma gp_val;
3729
      struct elf_link_hash_entry *gp;
3730
 
3731
      /* We assume after gp is set, section size will only decrease. We
3732
         need to adjust gp for it.  */
3733
      _bfd_set_gp_value (abfd, 0);
3734
      if (! elfNN_ia64_choose_gp (abfd, info, TRUE))
3735
        return FALSE;
3736
      gp_val = _bfd_get_gp_value (abfd);
3737
 
3738
      gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3739
                                 FALSE, FALSE);
3740
      if (gp)
3741
        {
3742
          gp->root.type = bfd_link_hash_defined;
3743
          gp->root.u.def.value = gp_val;
3744
          gp->root.u.def.section = bfd_abs_section_ptr;
3745
        }
3746
    }
3747
 
3748
  /* If we're producing a final executable, we need to sort the contents
3749
     of the .IA_64.unwind section.  Force this section to be relocated
3750
     into memory rather than written immediately to the output file.  */
3751
  unwind_output_sec = NULL;
3752
  if (!info->relocatable)
3753
    {
3754
      asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3755
      if (s)
3756
        {
3757
          unwind_output_sec = s->output_section;
3758
          unwind_output_sec->contents
3759
            = bfd_malloc (unwind_output_sec->size);
3760
          if (unwind_output_sec->contents == NULL)
3761
            return FALSE;
3762
        }
3763
    }
3764
 
3765
  /* Invoke the regular ELF backend linker to do all the work.  */
3766
  if (!bfd_elf_final_link (abfd, info))
3767
    return FALSE;
3768
 
3769
  if (unwind_output_sec)
3770
    {
3771
      elfNN_ia64_unwind_entry_compare_bfd = abfd;
3772
      qsort (unwind_output_sec->contents,
3773
             (size_t) (unwind_output_sec->size / 24),
3774
             24,
3775
             elfNN_ia64_unwind_entry_compare);
3776
 
3777
      if (! bfd_set_section_contents (abfd, unwind_output_sec,
3778
                                      unwind_output_sec->contents, (bfd_vma) 0,
3779
                                      unwind_output_sec->size))
3780
        return FALSE;
3781
    }
3782
 
3783
  return TRUE;
3784
}
3785
 
3786
static bfd_boolean
3787
elfNN_ia64_relocate_section (bfd *output_bfd,
3788
                             struct bfd_link_info *info,
3789
                             bfd *input_bfd,
3790
                             asection *input_section,
3791
                             bfd_byte *contents,
3792
                             Elf_Internal_Rela *relocs,
3793
                             Elf_Internal_Sym *local_syms,
3794
                             asection **local_sections)
3795
{
3796
  struct elfNN_ia64_link_hash_table *ia64_info;
3797
  Elf_Internal_Shdr *symtab_hdr;
3798
  Elf_Internal_Rela *rel;
3799
  Elf_Internal_Rela *relend;
3800
  asection *srel;
3801
  bfd_boolean ret_val = TRUE;   /* for non-fatal errors */
3802
  bfd_vma gp_val;
3803
 
3804
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3805
  ia64_info = elfNN_ia64_hash_table (info);
3806
  if (ia64_info == NULL)
3807
    return FALSE;
3808
 
3809
  /* Infect various flags from the input section to the output section.  */
3810
  if (info->relocatable)
3811
    {
3812
      bfd_vma flags;
3813
 
3814
      flags = elf_section_data(input_section)->this_hdr.sh_flags;
3815
      flags &= SHF_IA_64_NORECOV;
3816
 
3817
      elf_section_data(input_section->output_section)
3818
        ->this_hdr.sh_flags |= flags;
3819
    }
3820
 
3821
  gp_val = _bfd_get_gp_value (output_bfd);
3822
  srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3823
 
3824
  rel = relocs;
3825
  relend = relocs + input_section->reloc_count;
3826
  for (; rel < relend; ++rel)
3827
    {
3828
      struct elf_link_hash_entry *h;
3829
      struct elfNN_ia64_dyn_sym_info *dyn_i;
3830
      bfd_reloc_status_type r;
3831
      reloc_howto_type *howto;
3832
      unsigned long r_symndx;
3833
      Elf_Internal_Sym *sym;
3834
      unsigned int r_type;
3835
      bfd_vma value;
3836
      asection *sym_sec;
3837
      bfd_byte *hit_addr;
3838
      bfd_boolean dynamic_symbol_p;
3839
      bfd_boolean undef_weak_ref;
3840
 
3841
      r_type = ELFNN_R_TYPE (rel->r_info);
3842
      if (r_type > R_IA64_MAX_RELOC_CODE)
3843
        {
3844
          (*_bfd_error_handler)
3845
            (_("%B: unknown relocation type %d"),
3846
             input_bfd, (int) r_type);
3847
          bfd_set_error (bfd_error_bad_value);
3848
          ret_val = FALSE;
3849
          continue;
3850
        }
3851
 
3852
      howto = ia64_elf_lookup_howto (r_type);
3853
      r_symndx = ELFNN_R_SYM (rel->r_info);
3854
      h = NULL;
3855
      sym = NULL;
3856
      sym_sec = NULL;
3857
      undef_weak_ref = FALSE;
3858
 
3859
      if (r_symndx < symtab_hdr->sh_info)
3860
        {
3861
          /* Reloc against local symbol.  */
3862
          asection *msec;
3863
          sym = local_syms + r_symndx;
3864
          sym_sec = local_sections[r_symndx];
3865
          msec = sym_sec;
3866
          value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
3867
          if (!info->relocatable
3868
              && (sym_sec->flags & SEC_MERGE) != 0
3869
              && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3870
              && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
3871
            {
3872
              struct elfNN_ia64_local_hash_entry *loc_h;
3873
 
3874
              loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3875
              if (loc_h && ! loc_h->sec_merge_done)
3876
                {
3877
                  struct elfNN_ia64_dyn_sym_info *dynent;
3878
                  unsigned int count;
3879
 
3880
                  for (count = loc_h->count, dynent = loc_h->info;
3881
                       count != 0;
3882
                       count--, dynent++)
3883
                    {
3884
                      msec = sym_sec;
3885
                      dynent->addend =
3886
                        _bfd_merged_section_offset (output_bfd, &msec,
3887
                                                    elf_section_data (msec)->
3888
                                                    sec_info,
3889
                                                    sym->st_value
3890
                                                    + dynent->addend);
3891
                      dynent->addend -= sym->st_value;
3892
                      dynent->addend += msec->output_section->vma
3893
                                        + msec->output_offset
3894
                                        - sym_sec->output_section->vma
3895
                                        - sym_sec->output_offset;
3896
                    }
3897
 
3898
                  /* We may have introduced duplicated entries. We need
3899
                     to remove them properly.  */
3900
                  count = sort_dyn_sym_info (loc_h->info, loc_h->count);
3901
                  if (count != loc_h->count)
3902
                    {
3903
                      loc_h->count = count;
3904
                      loc_h->sorted_count = count;
3905
                    }
3906
 
3907
                  loc_h->sec_merge_done = 1;
3908
                }
3909
            }
3910
        }
3911
      else
3912
        {
3913
          bfd_boolean unresolved_reloc;
3914
          bfd_boolean warned;
3915
          struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
3916
 
3917
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3918
                                   r_symndx, symtab_hdr, sym_hashes,
3919
                                   h, sym_sec, value,
3920
                                   unresolved_reloc, warned);
3921
 
3922
          if (h->root.type == bfd_link_hash_undefweak)
3923
            undef_weak_ref = TRUE;
3924
          else if (warned)
3925
            continue;
3926
        }
3927
 
3928
      if (sym_sec != NULL && elf_discarded_section (sym_sec))
3929
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
3930
                                         rel, relend, howto, contents);
3931
 
3932
      if (info->relocatable)
3933
        continue;
3934
 
3935
      hit_addr = contents + rel->r_offset;
3936
      value += rel->r_addend;
3937
      dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
3938
 
3939
      switch (r_type)
3940
        {
3941
        case R_IA64_NONE:
3942
        case R_IA64_LDXMOV:
3943
          continue;
3944
 
3945
        case R_IA64_IMM14:
3946
        case R_IA64_IMM22:
3947
        case R_IA64_IMM64:
3948
        case R_IA64_DIR32MSB:
3949
        case R_IA64_DIR32LSB:
3950
        case R_IA64_DIR64MSB:
3951
        case R_IA64_DIR64LSB:
3952
          /* Install a dynamic relocation for this reloc.  */
3953
          if ((dynamic_symbol_p || info->shared)
3954
              && r_symndx != STN_UNDEF
3955
              && (input_section->flags & SEC_ALLOC) != 0)
3956
            {
3957
              unsigned int dyn_r_type;
3958
              long dynindx;
3959
              bfd_vma addend;
3960
 
3961
              BFD_ASSERT (srel != NULL);
3962
 
3963
              switch (r_type)
3964
                {
3965
                case R_IA64_IMM14:
3966
                case R_IA64_IMM22:
3967
                case R_IA64_IMM64:
3968
                  /* ??? People shouldn't be doing non-pic code in
3969
                     shared libraries nor dynamic executables.  */
3970
                  (*_bfd_error_handler)
3971
                    (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
3972
                     input_bfd,
3973
                     h ? h->root.root.string
3974
                       : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
3975
                                           sym_sec));
3976
                  ret_val = FALSE;
3977
                  continue;
3978
 
3979
                default:
3980
                  break;
3981
                }
3982
 
3983
              /* If we don't need dynamic symbol lookup, find a
3984
                 matching RELATIVE relocation.  */
3985
              dyn_r_type = r_type;
3986
              if (dynamic_symbol_p)
3987
                {
3988
                  dynindx = h->dynindx;
3989
                  addend = rel->r_addend;
3990
                  value = 0;
3991
                }
3992
              else
3993
                {
3994
                  switch (r_type)
3995
                    {
3996
                    case R_IA64_DIR32MSB:
3997
                      dyn_r_type = R_IA64_REL32MSB;
3998
                      break;
3999
                    case R_IA64_DIR32LSB:
4000
                      dyn_r_type = R_IA64_REL32LSB;
4001
                      break;
4002
                    case R_IA64_DIR64MSB:
4003
                      dyn_r_type = R_IA64_REL64MSB;
4004
                      break;
4005
                    case R_IA64_DIR64LSB:
4006
                      dyn_r_type = R_IA64_REL64LSB;
4007
                      break;
4008
 
4009
                    default:
4010
                      break;
4011
                    }
4012
                  dynindx = 0;
4013
                  addend = value;
4014
                }
4015
 
4016
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4017
                                            srel, rel->r_offset, dyn_r_type,
4018
                                            dynindx, addend);
4019
            }
4020
          /* Fall through.  */
4021
 
4022
        case R_IA64_LTV32MSB:
4023
        case R_IA64_LTV32LSB:
4024
        case R_IA64_LTV64MSB:
4025
        case R_IA64_LTV64LSB:
4026
          r = ia64_elf_install_value (hit_addr, value, r_type);
4027
          break;
4028
 
4029
        case R_IA64_GPREL22:
4030
        case R_IA64_GPREL64I:
4031
        case R_IA64_GPREL32MSB:
4032
        case R_IA64_GPREL32LSB:
4033
        case R_IA64_GPREL64MSB:
4034
        case R_IA64_GPREL64LSB:
4035
          if (dynamic_symbol_p)
4036
            {
4037
              (*_bfd_error_handler)
4038
                (_("%B: @gprel relocation against dynamic symbol %s"),
4039
                 input_bfd,
4040
                 h ? h->root.root.string
4041
                   : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4042
                                       sym_sec));
4043
              ret_val = FALSE;
4044
              continue;
4045
            }
4046
          value -= gp_val;
4047
          r = ia64_elf_install_value (hit_addr, value, r_type);
4048
          break;
4049
 
4050
        case R_IA64_LTOFF22:
4051
        case R_IA64_LTOFF22X:
4052
        case R_IA64_LTOFF64I:
4053
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4054
          value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4055
                                 rel->r_addend, value, R_IA64_DIRNNLSB);
4056
          value -= gp_val;
4057
          r = ia64_elf_install_value (hit_addr, value, r_type);
4058
          break;
4059
 
4060
        case R_IA64_PLTOFF22:
4061
        case R_IA64_PLTOFF64I:
4062
        case R_IA64_PLTOFF64MSB:
4063
        case R_IA64_PLTOFF64LSB:
4064
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4065
          value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4066
          value -= gp_val;
4067
          r = ia64_elf_install_value (hit_addr, value, r_type);
4068
          break;
4069
 
4070
        case R_IA64_FPTR64I:
4071
        case R_IA64_FPTR32MSB:
4072
        case R_IA64_FPTR32LSB:
4073
        case R_IA64_FPTR64MSB:
4074
        case R_IA64_FPTR64LSB:
4075
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4076
          if (dyn_i->want_fptr)
4077
            {
4078
              if (!undef_weak_ref)
4079
                value = set_fptr_entry (output_bfd, info, dyn_i, value);
4080
            }
4081
          if (!dyn_i->want_fptr || info->pie)
4082
            {
4083
              long dynindx;
4084
              unsigned int dyn_r_type = r_type;
4085
              bfd_vma addend = rel->r_addend;
4086
 
4087
              /* Otherwise, we expect the dynamic linker to create
4088
                 the entry.  */
4089
 
4090
              if (dyn_i->want_fptr)
4091
                {
4092
                  if (r_type == R_IA64_FPTR64I)
4093
                    {
4094
                      /* We can't represent this without a dynamic symbol.
4095
                         Adjust the relocation to be against an output
4096
                         section symbol, which are always present in the
4097
                         dynamic symbol table.  */
4098
                      /* ??? People shouldn't be doing non-pic code in
4099
                         shared libraries.  Hork.  */
4100
                      (*_bfd_error_handler)
4101
                        (_("%B: linking non-pic code in a position independent executable"),
4102
                         input_bfd);
4103
                      ret_val = FALSE;
4104
                      continue;
4105
                    }
4106
                  dynindx = 0;
4107
                  addend = value;
4108
                  dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4109
                }
4110
              else if (h)
4111
                {
4112
                  if (h->dynindx != -1)
4113
                    dynindx = h->dynindx;
4114
                  else
4115
                    dynindx = (_bfd_elf_link_lookup_local_dynindx
4116
                               (info, h->root.u.def.section->owner,
4117
                                global_sym_index (h)));
4118
                  value = 0;
4119
                }
4120
              else
4121
                {
4122
                  dynindx = (_bfd_elf_link_lookup_local_dynindx
4123
                             (info, input_bfd, (long) r_symndx));
4124
                  value = 0;
4125
                }
4126
 
4127
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4128
                                            srel, rel->r_offset, dyn_r_type,
4129
                                            dynindx, addend);
4130
            }
4131
 
4132
          r = ia64_elf_install_value (hit_addr, value, r_type);
4133
          break;
4134
 
4135
        case R_IA64_LTOFF_FPTR22:
4136
        case R_IA64_LTOFF_FPTR64I:
4137
        case R_IA64_LTOFF_FPTR32MSB:
4138
        case R_IA64_LTOFF_FPTR32LSB:
4139
        case R_IA64_LTOFF_FPTR64MSB:
4140
        case R_IA64_LTOFF_FPTR64LSB:
4141
          {
4142
            long dynindx;
4143
 
4144
            dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4145
            if (dyn_i->want_fptr)
4146
              {
4147
                BFD_ASSERT (h == NULL || h->dynindx == -1);
4148
                if (!undef_weak_ref)
4149
                  value = set_fptr_entry (output_bfd, info, dyn_i, value);
4150
                dynindx = -1;
4151
              }
4152
            else
4153
              {
4154
                /* Otherwise, we expect the dynamic linker to create
4155
                   the entry.  */
4156
                if (h)
4157
                  {
4158
                    if (h->dynindx != -1)
4159
                      dynindx = h->dynindx;
4160
                    else
4161
                      dynindx = (_bfd_elf_link_lookup_local_dynindx
4162
                                 (info, h->root.u.def.section->owner,
4163
                                  global_sym_index (h)));
4164
                  }
4165
                else
4166
                  dynindx = (_bfd_elf_link_lookup_local_dynindx
4167
                             (info, input_bfd, (long) r_symndx));
4168
                value = 0;
4169
              }
4170
 
4171
            value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4172
                                   rel->r_addend, value, R_IA64_FPTRNNLSB);
4173
            value -= gp_val;
4174
            r = ia64_elf_install_value (hit_addr, value, r_type);
4175
          }
4176
          break;
4177
 
4178
        case R_IA64_PCREL32MSB:
4179
        case R_IA64_PCREL32LSB:
4180
        case R_IA64_PCREL64MSB:
4181
        case R_IA64_PCREL64LSB:
4182
          /* Install a dynamic relocation for this reloc.  */
4183
          if (dynamic_symbol_p && r_symndx != STN_UNDEF)
4184
            {
4185
              BFD_ASSERT (srel != NULL);
4186
 
4187
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4188
                                            srel, rel->r_offset, r_type,
4189
                                            h->dynindx, rel->r_addend);
4190
            }
4191
          goto finish_pcrel;
4192
 
4193
        case R_IA64_PCREL21B:
4194
        case R_IA64_PCREL60B:
4195
          /* We should have created a PLT entry for any dynamic symbol.  */
4196
          dyn_i = NULL;
4197
          if (h)
4198
            dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4199
 
4200
          if (dyn_i && dyn_i->want_plt2)
4201
            {
4202
              /* Should have caught this earlier.  */
4203
              BFD_ASSERT (rel->r_addend == 0);
4204
 
4205
              value = (ia64_info->root.splt->output_section->vma
4206
                       + ia64_info->root.splt->output_offset
4207
                       + dyn_i->plt2_offset);
4208
            }
4209
          else
4210
            {
4211
              /* Since there's no PLT entry, Validate that this is
4212
                 locally defined.  */
4213
              BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4214
 
4215
              /* If the symbol is undef_weak, we shouldn't be trying
4216
                 to call it.  There's every chance that we'd wind up
4217
                 with an out-of-range fixup here.  Don't bother setting
4218
                 any value at all.  */
4219
              if (undef_weak_ref)
4220
                continue;
4221
            }
4222
          goto finish_pcrel;
4223
 
4224
        case R_IA64_PCREL21BI:
4225
        case R_IA64_PCREL21F:
4226
        case R_IA64_PCREL21M:
4227
        case R_IA64_PCREL22:
4228
        case R_IA64_PCREL64I:
4229
          /* The PCREL21BI reloc is specifically not intended for use with
4230
             dynamic relocs.  PCREL21F and PCREL21M are used for speculation
4231
             fixup code, and thus probably ought not be dynamic.  The
4232
             PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs.  */
4233
          if (dynamic_symbol_p)
4234
            {
4235
              const char *msg;
4236
 
4237
              if (r_type == R_IA64_PCREL21BI)
4238
                msg = _("%B: @internal branch to dynamic symbol %s");
4239
              else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4240
                msg = _("%B: speculation fixup to dynamic symbol %s");
4241
              else
4242
                msg = _("%B: @pcrel relocation against dynamic symbol %s");
4243
              (*_bfd_error_handler) (msg, input_bfd,
4244
                                     h ? h->root.root.string
4245
                                       : bfd_elf_sym_name (input_bfd,
4246
                                                           symtab_hdr,
4247
                                                           sym,
4248
                                                           sym_sec));
4249
              ret_val = FALSE;
4250
              continue;
4251
            }
4252
          goto finish_pcrel;
4253
 
4254
        finish_pcrel:
4255
          /* Make pc-relative.  */
4256
          value -= (input_section->output_section->vma
4257
                    + input_section->output_offset
4258
                    + rel->r_offset) & ~ (bfd_vma) 0x3;
4259
          r = ia64_elf_install_value (hit_addr, value, r_type);
4260
          break;
4261
 
4262
        case R_IA64_SEGREL32MSB:
4263
        case R_IA64_SEGREL32LSB:
4264
        case R_IA64_SEGREL64MSB:
4265
        case R_IA64_SEGREL64LSB:
4266
            {
4267
              /* Find the segment that contains the output_section.  */
4268
              Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
4269
                (output_bfd, input_section->output_section);
4270
 
4271
              if (p == NULL)
4272
                {
4273
                  r = bfd_reloc_notsupported;
4274
                }
4275
              else
4276
                {
4277
                  /* The VMA of the segment is the vaddr of the associated
4278
                     program header.  */
4279
                  if (value > p->p_vaddr)
4280
                    value -= p->p_vaddr;
4281
                  else
4282
                    value = 0;
4283
                  r = ia64_elf_install_value (hit_addr, value, r_type);
4284
                }
4285
              break;
4286
            }
4287
 
4288
        case R_IA64_SECREL32MSB:
4289
        case R_IA64_SECREL32LSB:
4290
        case R_IA64_SECREL64MSB:
4291
        case R_IA64_SECREL64LSB:
4292
          /* Make output-section relative to section where the symbol
4293
             is defined. PR 475  */
4294
          if (sym_sec)
4295
            value -= sym_sec->output_section->vma;
4296
          r = ia64_elf_install_value (hit_addr, value, r_type);
4297
          break;
4298
 
4299
        case R_IA64_IPLTMSB:
4300
        case R_IA64_IPLTLSB:
4301
          /* Install a dynamic relocation for this reloc.  */
4302
          if ((dynamic_symbol_p || info->shared)
4303
              && (input_section->flags & SEC_ALLOC) != 0)
4304
            {
4305
              BFD_ASSERT (srel != NULL);
4306
 
4307
              /* If we don't need dynamic symbol lookup, install two
4308
                 RELATIVE relocations.  */
4309
              if (!dynamic_symbol_p)
4310
                {
4311
                  unsigned int dyn_r_type;
4312
 
4313
                  if (r_type == R_IA64_IPLTMSB)
4314
                    dyn_r_type = R_IA64_REL64MSB;
4315
                  else
4316
                    dyn_r_type = R_IA64_REL64LSB;
4317
 
4318
                  elfNN_ia64_install_dyn_reloc (output_bfd, info,
4319
                                                input_section,
4320
                                                srel, rel->r_offset,
4321
                                                dyn_r_type, 0, value);
4322
                  elfNN_ia64_install_dyn_reloc (output_bfd, info,
4323
                                                input_section,
4324
                                                srel, rel->r_offset + 8,
4325
                                                dyn_r_type, 0, gp_val);
4326
                }
4327
              else
4328
                elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4329
                                              srel, rel->r_offset, r_type,
4330
                                              h->dynindx, rel->r_addend);
4331
            }
4332
 
4333
          if (r_type == R_IA64_IPLTMSB)
4334
            r_type = R_IA64_DIR64MSB;
4335
          else
4336
            r_type = R_IA64_DIR64LSB;
4337
          ia64_elf_install_value (hit_addr, value, r_type);
4338
          r = ia64_elf_install_value (hit_addr + 8, gp_val, r_type);
4339
          break;
4340
 
4341
        case R_IA64_TPREL14:
4342
        case R_IA64_TPREL22:
4343
        case R_IA64_TPREL64I:
4344
          if (elf_hash_table (info)->tls_sec == NULL)
4345
            goto missing_tls_sec;
4346
          value -= elfNN_ia64_tprel_base (info);
4347
          r = ia64_elf_install_value (hit_addr, value, r_type);
4348
          break;
4349
 
4350
        case R_IA64_DTPREL14:
4351
        case R_IA64_DTPREL22:
4352
        case R_IA64_DTPREL64I:
4353
        case R_IA64_DTPREL32LSB:
4354
        case R_IA64_DTPREL32MSB:
4355
        case R_IA64_DTPREL64LSB:
4356
        case R_IA64_DTPREL64MSB:
4357
          if (elf_hash_table (info)->tls_sec == NULL)
4358
            goto missing_tls_sec;
4359
          value -= elfNN_ia64_dtprel_base (info);
4360
          r = ia64_elf_install_value (hit_addr, value, r_type);
4361
          break;
4362
 
4363
        case R_IA64_LTOFF_TPREL22:
4364
        case R_IA64_LTOFF_DTPMOD22:
4365
        case R_IA64_LTOFF_DTPREL22:
4366
          {
4367
            int got_r_type;
4368
            long dynindx = h ? h->dynindx : -1;
4369
            bfd_vma r_addend = rel->r_addend;
4370
 
4371
            switch (r_type)
4372
              {
4373
              default:
4374
              case R_IA64_LTOFF_TPREL22:
4375
                if (!dynamic_symbol_p)
4376
                  {
4377
                    if (elf_hash_table (info)->tls_sec == NULL)
4378
                      goto missing_tls_sec;
4379
                    if (!info->shared)
4380
                      value -= elfNN_ia64_tprel_base (info);
4381
                    else
4382
                      {
4383
                        r_addend += value - elfNN_ia64_dtprel_base (info);
4384
                        dynindx = 0;
4385
                      }
4386
                  }
4387
                got_r_type = R_IA64_TPREL64LSB;
4388
                break;
4389
              case R_IA64_LTOFF_DTPMOD22:
4390
                if (!dynamic_symbol_p && !info->shared)
4391
                  value = 1;
4392
                got_r_type = R_IA64_DTPMOD64LSB;
4393
                break;
4394
              case R_IA64_LTOFF_DTPREL22:
4395
                if (!dynamic_symbol_p)
4396
                  {
4397
                    if (elf_hash_table (info)->tls_sec == NULL)
4398
                      goto missing_tls_sec;
4399
                    value -= elfNN_ia64_dtprel_base (info);
4400
                  }
4401
                got_r_type = R_IA64_DTPRELNNLSB;
4402
                break;
4403
              }
4404
            dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4405
            value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4406
                                   value, got_r_type);
4407
            value -= gp_val;
4408
            r = ia64_elf_install_value (hit_addr, value, r_type);
4409
          }
4410
          break;
4411
 
4412
        default:
4413
          r = bfd_reloc_notsupported;
4414
          break;
4415
        }
4416
 
4417
      switch (r)
4418
        {
4419
        case bfd_reloc_ok:
4420
          break;
4421
 
4422
        case bfd_reloc_undefined:
4423
          /* This can happen for global table relative relocs if
4424
             __gp is undefined.  This is a panic situation so we
4425
             don't try to continue.  */
4426
          (*info->callbacks->undefined_symbol)
4427
            (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4428
          return FALSE;
4429
 
4430
        case bfd_reloc_notsupported:
4431
          {
4432
            const char *name;
4433
 
4434
            if (h)
4435
              name = h->root.root.string;
4436
            else
4437
              name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4438
                                       sym_sec);
4439
            if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4440
                                              name, input_bfd,
4441
                                              input_section, rel->r_offset))
4442
              return FALSE;
4443
            ret_val = FALSE;
4444
          }
4445
          break;
4446
 
4447
        case bfd_reloc_dangerous:
4448
        case bfd_reloc_outofrange:
4449
        case bfd_reloc_overflow:
4450
        default:
4451
missing_tls_sec:
4452
          {
4453
            const char *name;
4454
 
4455
            if (h)
4456
              name = h->root.root.string;
4457
            else
4458
              name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4459
                                       sym_sec);
4460
 
4461
            switch (r_type)
4462
              {
4463
              case R_IA64_TPREL14:
4464
              case R_IA64_TPREL22:
4465
              case R_IA64_TPREL64I:
4466
              case R_IA64_DTPREL14:
4467
              case R_IA64_DTPREL22:
4468
              case R_IA64_DTPREL64I:
4469
              case R_IA64_DTPREL32LSB:
4470
              case R_IA64_DTPREL32MSB:
4471
              case R_IA64_DTPREL64LSB:
4472
              case R_IA64_DTPREL64MSB:
4473
              case R_IA64_LTOFF_TPREL22:
4474
              case R_IA64_LTOFF_DTPMOD22:
4475
              case R_IA64_LTOFF_DTPREL22:
4476
                (*_bfd_error_handler)
4477
                  (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
4478
                   input_bfd, input_section, howto->name, name,
4479
                   rel->r_offset);
4480
                break;
4481
 
4482
              case R_IA64_PCREL21B:
4483
              case R_IA64_PCREL21BI:
4484
              case R_IA64_PCREL21M:
4485
              case R_IA64_PCREL21F:
4486
                if (is_elf_hash_table (info->hash))
4487
                  {
4488
                    /* Relaxtion is always performed for ELF output.
4489
                       Overflow failures for those relocations mean
4490
                       that the section is too big to relax.  */
4491
                    (*_bfd_error_handler)
4492
                      (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
4493
                       input_bfd, input_section, howto->name, name,
4494
                       rel->r_offset, input_section->size);
4495
                    break;
4496
                  }
4497
              default:
4498
                if (!(*info->callbacks->reloc_overflow) (info,
4499
                                                         &h->root,
4500
                                                         name,
4501
                                                         howto->name,
4502
                                                         (bfd_vma) 0,
4503
                                                         input_bfd,
4504
                                                         input_section,
4505
                                                         rel->r_offset))
4506
                  return FALSE;
4507
                break;
4508
              }
4509
 
4510
            ret_val = FALSE;
4511
          }
4512
          break;
4513
        }
4514
    }
4515
 
4516
  return ret_val;
4517
}
4518
 
4519
static bfd_boolean
4520
elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
4521
                                  struct bfd_link_info *info,
4522
                                  struct elf_link_hash_entry *h,
4523
                                  Elf_Internal_Sym *sym)
4524
{
4525
  struct elfNN_ia64_link_hash_table *ia64_info;
4526
  struct elfNN_ia64_dyn_sym_info *dyn_i;
4527
 
4528
  ia64_info = elfNN_ia64_hash_table (info);
4529
  if (ia64_info == NULL)
4530
    return FALSE;
4531
 
4532
  dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4533
 
4534
  /* Fill in the PLT data, if required.  */
4535
  if (dyn_i && dyn_i->want_plt)
4536
    {
4537
      Elf_Internal_Rela outrel;
4538
      bfd_byte *loc;
4539
      asection *plt_sec;
4540
      bfd_vma plt_addr, pltoff_addr, gp_val, plt_index;
4541
 
4542
      gp_val = _bfd_get_gp_value (output_bfd);
4543
 
4544
      /* Initialize the minimal PLT entry.  */
4545
 
4546
      plt_index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4547
      plt_sec = ia64_info->root.splt;
4548
      loc = plt_sec->contents + dyn_i->plt_offset;
4549
 
4550
      memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4551
      ia64_elf_install_value (loc, plt_index, R_IA64_IMM22);
4552
      ia64_elf_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
4553
 
4554
      plt_addr = (plt_sec->output_section->vma
4555
                  + plt_sec->output_offset
4556
                  + dyn_i->plt_offset);
4557
      pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4558
 
4559
      /* Initialize the FULL PLT entry, if needed.  */
4560
      if (dyn_i->want_plt2)
4561
        {
4562
          loc = plt_sec->contents + dyn_i->plt2_offset;
4563
 
4564
          memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4565
          ia64_elf_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
4566
 
4567
          /* Mark the symbol as undefined, rather than as defined in the
4568
             plt section.  Leave the value alone.  */
4569
          /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4570
             first place.  But perhaps elflink.c did some for us.  */
4571
          if (!h->def_regular)
4572
            sym->st_shndx = SHN_UNDEF;
4573
        }
4574
 
4575
      /* Create the dynamic relocation.  */
4576
      outrel.r_offset = pltoff_addr;
4577
      if (bfd_little_endian (output_bfd))
4578
        outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4579
      else
4580
        outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4581
      outrel.r_addend = 0;
4582
 
4583
      /* This is fun.  In the .IA_64.pltoff section, we've got entries
4584
         that correspond both to real PLT entries, and those that
4585
         happened to resolve to local symbols but need to be created
4586
         to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
4587
         relocations for the real PLT should come at the end of the
4588
         section, so that they can be indexed by plt entry at runtime.
4589
 
4590
         We emitted all of the relocations for the non-PLT @pltoff
4591
         entries during relocate_section.  So we can consider the
4592
         existing sec->reloc_count to be the base of the array of
4593
         PLT relocations.  */
4594
 
4595
      loc = ia64_info->rel_pltoff_sec->contents;
4596
      loc += ((ia64_info->rel_pltoff_sec->reloc_count + plt_index)
4597
              * sizeof (ElfNN_External_Rela));
4598
      bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4599
    }
4600
 
4601
  /* Mark some specially defined symbols as absolute.  */
4602
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4603
      || h == ia64_info->root.hgot
4604
      || h == ia64_info->root.hplt)
4605
    sym->st_shndx = SHN_ABS;
4606
 
4607
  return TRUE;
4608
}
4609
 
4610
static bfd_boolean
4611
elfNN_ia64_finish_dynamic_sections (bfd *abfd,
4612
                                    struct bfd_link_info *info)
4613
{
4614
  struct elfNN_ia64_link_hash_table *ia64_info;
4615
  bfd *dynobj;
4616
 
4617
  ia64_info = elfNN_ia64_hash_table (info);
4618
  if (ia64_info == NULL)
4619
    return FALSE;
4620
 
4621
  dynobj = ia64_info->root.dynobj;
4622
 
4623
  if (elf_hash_table (info)->dynamic_sections_created)
4624
    {
4625
      ElfNN_External_Dyn *dyncon, *dynconend;
4626
      asection *sdyn, *sgotplt;
4627
      bfd_vma gp_val;
4628
 
4629
      sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4630
      sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4631
      BFD_ASSERT (sdyn != NULL);
4632
      dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4633
      dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
4634
 
4635
      gp_val = _bfd_get_gp_value (abfd);
4636
 
4637
      for (; dyncon < dynconend; dyncon++)
4638
        {
4639
          Elf_Internal_Dyn dyn;
4640
 
4641
          bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4642
 
4643
          switch (dyn.d_tag)
4644
            {
4645
            case DT_PLTGOT:
4646
              dyn.d_un.d_ptr = gp_val;
4647
              break;
4648
 
4649
            case DT_PLTRELSZ:
4650
              dyn.d_un.d_val = (ia64_info->minplt_entries
4651
                                * sizeof (ElfNN_External_Rela));
4652
              break;
4653
 
4654
            case DT_JMPREL:
4655
              /* See the comment above in finish_dynamic_symbol.  */
4656
              dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4657
                                + ia64_info->rel_pltoff_sec->output_offset
4658
                                + (ia64_info->rel_pltoff_sec->reloc_count
4659
                                   * sizeof (ElfNN_External_Rela)));
4660
              break;
4661
 
4662
            case DT_IA_64_PLT_RESERVE:
4663
              dyn.d_un.d_ptr = (sgotplt->output_section->vma
4664
                                + sgotplt->output_offset);
4665
              break;
4666
 
4667
            case DT_RELASZ:
4668
              /* Do not have RELASZ include JMPREL.  This makes things
4669
                 easier on ld.so.  This is not what the rest of BFD set up.  */
4670
              dyn.d_un.d_val -= (ia64_info->minplt_entries
4671
                                 * sizeof (ElfNN_External_Rela));
4672
              break;
4673
            }
4674
 
4675
          bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4676
        }
4677
 
4678
      /* Initialize the PLT0 entry.  */
4679
      if (ia64_info->root.splt)
4680
        {
4681
          bfd_byte *loc = ia64_info->root.splt->contents;
4682
          bfd_vma pltres;
4683
 
4684
          memcpy (loc, plt_header, PLT_HEADER_SIZE);
4685
 
4686
          pltres = (sgotplt->output_section->vma
4687
                    + sgotplt->output_offset
4688
                    - gp_val);
4689
 
4690
          ia64_elf_install_value (loc+1, pltres, R_IA64_GPREL22);
4691
        }
4692
    }
4693
 
4694
  return TRUE;
4695
}
4696
 
4697
/* ELF file flag handling:  */
4698
 
4699
/* Function to keep IA-64 specific file flags.  */
4700
static bfd_boolean
4701
elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
4702
{
4703
  BFD_ASSERT (!elf_flags_init (abfd)
4704
              || elf_elfheader (abfd)->e_flags == flags);
4705
 
4706
  elf_elfheader (abfd)->e_flags = flags;
4707
  elf_flags_init (abfd) = TRUE;
4708
  return TRUE;
4709
}
4710
 
4711
/* Merge backend specific data from an object file to the output
4712
   object file when linking.  */
4713
static bfd_boolean
4714
elfNN_ia64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
4715
{
4716
  flagword out_flags;
4717
  flagword in_flags;
4718
  bfd_boolean ok = TRUE;
4719
 
4720
  /* Don't even pretend to support mixed-format linking.  */
4721
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4722
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4723
    return FALSE;
4724
 
4725
  in_flags  = elf_elfheader (ibfd)->e_flags;
4726
  out_flags = elf_elfheader (obfd)->e_flags;
4727
 
4728
  if (! elf_flags_init (obfd))
4729
    {
4730
      elf_flags_init (obfd) = TRUE;
4731
      elf_elfheader (obfd)->e_flags = in_flags;
4732
 
4733
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4734
          && bfd_get_arch_info (obfd)->the_default)
4735
        {
4736
          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4737
                                    bfd_get_mach (ibfd));
4738
        }
4739
 
4740
      return TRUE;
4741
    }
4742
 
4743
  /* Check flag compatibility.  */
4744
  if (in_flags == out_flags)
4745
    return TRUE;
4746
 
4747
  /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
4748
  if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4749
    elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4750
 
4751
  if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4752
    {
4753
      (*_bfd_error_handler)
4754
        (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
4755
         ibfd);
4756
 
4757
      bfd_set_error (bfd_error_bad_value);
4758
      ok = FALSE;
4759
    }
4760
  if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4761
    {
4762
      (*_bfd_error_handler)
4763
        (_("%B: linking big-endian files with little-endian files"),
4764
         ibfd);
4765
 
4766
      bfd_set_error (bfd_error_bad_value);
4767
      ok = FALSE;
4768
    }
4769
  if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4770
    {
4771
      (*_bfd_error_handler)
4772
        (_("%B: linking 64-bit files with 32-bit files"),
4773
         ibfd);
4774
 
4775
      bfd_set_error (bfd_error_bad_value);
4776
      ok = FALSE;
4777
    }
4778
  if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4779
    {
4780
      (*_bfd_error_handler)
4781
        (_("%B: linking constant-gp files with non-constant-gp files"),
4782
         ibfd);
4783
 
4784
      bfd_set_error (bfd_error_bad_value);
4785
      ok = FALSE;
4786
    }
4787
  if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4788
      != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4789
    {
4790
      (*_bfd_error_handler)
4791
        (_("%B: linking auto-pic files with non-auto-pic files"),
4792
         ibfd);
4793
 
4794
      bfd_set_error (bfd_error_bad_value);
4795
      ok = FALSE;
4796
    }
4797
 
4798
  return ok;
4799
}
4800
 
4801
static bfd_boolean
4802
elfNN_ia64_print_private_bfd_data (bfd *abfd, PTR ptr)
4803
{
4804
  FILE *file = (FILE *) ptr;
4805
  flagword flags = elf_elfheader (abfd)->e_flags;
4806
 
4807
  BFD_ASSERT (abfd != NULL && ptr != NULL);
4808
 
4809
  fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4810
           (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4811
           (flags & EF_IA_64_EXT) ? "EXT, " : "",
4812
           (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4813
           (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4814
           (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4815
           (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4816
           (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4817
           (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4818
 
4819
  _bfd_elf_print_private_bfd_data (abfd, ptr);
4820
  return TRUE;
4821
}
4822
 
4823
static enum elf_reloc_type_class
4824
elfNN_ia64_reloc_type_class (const Elf_Internal_Rela *rela)
4825
{
4826
  switch ((int) ELFNN_R_TYPE (rela->r_info))
4827
    {
4828
    case R_IA64_REL32MSB:
4829
    case R_IA64_REL32LSB:
4830
    case R_IA64_REL64MSB:
4831
    case R_IA64_REL64LSB:
4832
      return reloc_class_relative;
4833
    case R_IA64_IPLTMSB:
4834
    case R_IA64_IPLTLSB:
4835
      return reloc_class_plt;
4836
    case R_IA64_COPY:
4837
      return reloc_class_copy;
4838
    default:
4839
      return reloc_class_normal;
4840
    }
4841
}
4842
 
4843
static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
4844
{
4845
  { STRING_COMMA_LEN (".sbss"),  -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4846
  { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4847
  { NULL,                    0,   0, 0,            0 }
4848
};
4849
 
4850
static bfd_boolean
4851
elfNN_ia64_object_p (bfd *abfd)
4852
{
4853
  asection *sec;
4854
  asection *group, *unwi, *unw;
4855
  flagword flags;
4856
  const char *name;
4857
  char *unwi_name, *unw_name;
4858
  bfd_size_type amt;
4859
 
4860
  if (abfd->flags & DYNAMIC)
4861
    return TRUE;
4862
 
4863
  /* Flags for fake group section.  */
4864
  flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
4865
           | SEC_EXCLUDE);
4866
 
4867
  /* We add a fake section group for each .gnu.linkonce.t.* section,
4868
     which isn't in a section group, and its unwind sections.  */
4869
  for (sec = abfd->sections; sec != NULL; sec = sec->next)
4870
    {
4871
      if (elf_sec_group (sec) == NULL
4872
          && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
4873
              == (SEC_LINK_ONCE | SEC_CODE))
4874
          && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
4875
        {
4876
          name = sec->name + 16;
4877
 
4878
          amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
4879
          unwi_name = bfd_alloc (abfd, amt);
4880
          if (!unwi_name)
4881
            return FALSE;
4882
 
4883
          strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
4884
          unwi = bfd_get_section_by_name (abfd, unwi_name);
4885
 
4886
          amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
4887
          unw_name = bfd_alloc (abfd, amt);
4888
          if (!unw_name)
4889
            return FALSE;
4890
 
4891
          strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
4892
          unw = bfd_get_section_by_name (abfd, unw_name);
4893
 
4894
          /* We need to create a fake group section for it and its
4895
             unwind sections.  */
4896
          group = bfd_make_section_anyway_with_flags (abfd, name,
4897
                                                      flags);
4898
          if (group == NULL)
4899
            return FALSE;
4900
 
4901
          /* Move the fake group section to the beginning.  */
4902
          bfd_section_list_remove (abfd, group);
4903
          bfd_section_list_prepend (abfd, group);
4904
 
4905
          elf_next_in_group (group) = sec;
4906
 
4907
          elf_group_name (sec) = name;
4908
          elf_next_in_group (sec) = sec;
4909
          elf_sec_group (sec) = group;
4910
 
4911
          if (unwi)
4912
            {
4913
              elf_group_name (unwi) = name;
4914
              elf_next_in_group (unwi) = sec;
4915
              elf_next_in_group (sec) = unwi;
4916
              elf_sec_group (unwi) = group;
4917
            }
4918
 
4919
           if (unw)
4920
             {
4921
               elf_group_name (unw) = name;
4922
               if (unwi)
4923
                 {
4924
                   elf_next_in_group (unw) = elf_next_in_group (unwi);
4925
                   elf_next_in_group (unwi) = unw;
4926
                 }
4927
               else
4928
                 {
4929
                   elf_next_in_group (unw) = sec;
4930
                   elf_next_in_group (sec) = unw;
4931
                 }
4932
               elf_sec_group (unw) = group;
4933
             }
4934
 
4935
           /* Fake SHT_GROUP section header.  */
4936
          elf_section_data (group)->this_hdr.bfd_section = group;
4937
          elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
4938
        }
4939
    }
4940
  return TRUE;
4941
}
4942
 
4943
static bfd_boolean
4944
elfNN_ia64_hpux_vec (const bfd_target *vec)
4945
{
4946
  extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4947
  return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4948
}
4949
 
4950
static void
4951
elfNN_hpux_post_process_headers (bfd *abfd,
4952
                                 struct bfd_link_info *info ATTRIBUTE_UNUSED)
4953
{
4954
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4955
 
4956
  i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
4957
  i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4958
}
4959
 
4960
static bfd_boolean
4961
elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
4962
                                             asection *sec, int *retval)
4963
{
4964
  if (bfd_is_com_section (sec))
4965
    {
4966
      *retval = SHN_IA_64_ANSI_COMMON;
4967
      return TRUE;
4968
    }
4969
  return FALSE;
4970
}
4971
 
4972
static void
4973
elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
4974
                                      asymbol *asym)
4975
{
4976
  elf_symbol_type *elfsym = (elf_symbol_type *) asym;
4977
 
4978
  switch (elfsym->internal_elf_sym.st_shndx)
4979
    {
4980
    case SHN_IA_64_ANSI_COMMON:
4981
      asym->section = bfd_com_section_ptr;
4982
      asym->value = elfsym->internal_elf_sym.st_size;
4983
      asym->flags &= ~BSF_GLOBAL;
4984
      break;
4985
    }
4986
}
4987
 
4988
#ifdef INCLUDE_IA64_VMS
4989
 
4990
static bfd_boolean
4991
elfNN_vms_section_from_shdr (bfd *abfd,
4992
                             Elf_Internal_Shdr *hdr,
4993
                             const char *name,
4994
                             int shindex)
4995
{
4996
  switch (hdr->sh_type)
4997
    {
4998
    case SHT_IA_64_VMS_TRACE:
4999
    case SHT_IA_64_VMS_DEBUG:
5000
    case SHT_IA_64_VMS_DEBUG_STR:
5001
      break;
5002
 
5003
    default:
5004
      return elfNN_ia64_section_from_shdr (abfd, hdr, name, shindex);
5005
    }
5006
 
5007
  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
5008
    return FALSE;
5009
 
5010
  return TRUE;
5011
}
5012
 
5013
static bfd_boolean
5014
elfNN_vms_object_p (bfd *abfd)
5015
{
5016
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5017
  Elf_Internal_Phdr *i_phdr = elf_tdata (abfd)->phdr;
5018
  unsigned int i;
5019
  unsigned int num_text = 0;
5020
  unsigned int num_data = 0;
5021
  unsigned int num_rodata = 0;
5022
  char name[16];
5023
 
5024
  if (!elfNN_ia64_object_p (abfd))
5025
    return FALSE;
5026
 
5027
  for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)
5028
    {
5029
      /* Is there a section for this segment?  */
5030
      bfd_vma base_vma = i_phdr->p_vaddr;
5031
      bfd_vma limit_vma = base_vma + i_phdr->p_filesz;
5032
 
5033
      if (i_phdr->p_type != PT_LOAD)
5034
        continue;
5035
 
5036
    again:
5037
      while (base_vma < limit_vma)
5038
        {
5039
          bfd_vma next_vma = limit_vma;
5040
          asection *nsec;
5041
          asection *sec;
5042
          flagword flags;
5043
          char *nname = NULL;
5044
 
5045
          /* Find a section covering base_vma.  */
5046
          for (sec = abfd->sections; sec != NULL; sec = sec->next)
5047
            {
5048
              if ((sec->flags & (SEC_ALLOC | SEC_LOAD)) == 0)
5049
                continue;
5050
              if (sec->vma <= base_vma && sec->vma + sec->size > base_vma)
5051
                {
5052
                  base_vma = sec->vma + sec->size;
5053
                  goto again;
5054
                }
5055
              if (sec->vma < next_vma && sec->vma + sec->size >= base_vma)
5056
                next_vma = sec->vma;
5057
            }
5058
 
5059
          /* No section covering [base_vma; next_vma).  Create a fake one.  */
5060
          flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
5061
          if (i_phdr->p_flags & PF_X)
5062
            {
5063
              flags |= SEC_CODE;
5064
              if (num_text++ == 0)
5065
                nname = ".text";
5066
              else
5067
                sprintf (name, ".text$%u", num_text);
5068
            }
5069
          else if ((i_phdr->p_flags & (PF_R | PF_W)) == PF_R)
5070
            {
5071
              flags |= SEC_READONLY;
5072
              sprintf (name, ".rodata$%u", num_rodata++);
5073
            }
5074
          else
5075
            {
5076
              flags |= SEC_DATA;
5077
              sprintf (name, ".data$%u", num_data++);
5078
            }
5079
 
5080
          /* Allocate name.  */
5081
          if (nname == NULL)
5082
            {
5083
              size_t name_len = strlen (name) + 1;
5084
              nname = bfd_alloc (abfd, name_len);
5085
              if (nname == NULL)
5086
                return FALSE;
5087
              memcpy (nname, name, name_len);
5088
            }
5089
 
5090
          /* Create and fill new section.  */
5091
          nsec = bfd_make_section_anyway_with_flags (abfd, nname, flags);
5092
          if (nsec == NULL)
5093
            return FALSE;
5094
          nsec->vma = base_vma;
5095
          nsec->size = next_vma - base_vma;
5096
          nsec->filepos = i_phdr->p_offset + (base_vma - i_phdr->p_vaddr);
5097
 
5098
          base_vma = next_vma;
5099
        }
5100
    }
5101
  return TRUE;
5102
}
5103
 
5104
static void
5105
elfNN_vms_post_process_headers (bfd *abfd,
5106
                                struct bfd_link_info *info ATTRIBUTE_UNUSED)
5107
{
5108
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5109
 
5110
  i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_OPENVMS;
5111
  i_ehdrp->e_ident[EI_ABIVERSION] = 2;
5112
}
5113
 
5114
static bfd_boolean
5115
elfNN_vms_section_processing (bfd *abfd ATTRIBUTE_UNUSED,
5116
                              Elf_Internal_Shdr *hdr)
5117
{
5118
  if (hdr->bfd_section != NULL)
5119
    {
5120
      const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
5121
 
5122
      if (strcmp (name, ".text") == 0)
5123
        hdr->sh_flags |= SHF_IA_64_VMS_SHARED;
5124
      else if ((strcmp (name, ".debug") == 0)
5125
            || (strcmp (name, ".debug_abbrev") == 0)
5126
            || (strcmp (name, ".debug_aranges") == 0)
5127
            || (strcmp (name, ".debug_frame") == 0)
5128
            || (strcmp (name, ".debug_info") == 0)
5129
            || (strcmp (name, ".debug_loc") == 0)
5130
            || (strcmp (name, ".debug_macinfo") == 0)
5131
            || (strcmp (name, ".debug_pubnames") == 0)
5132
            || (strcmp (name, ".debug_pubtypes") == 0))
5133
        hdr->sh_type = SHT_IA_64_VMS_DEBUG;
5134
      else if ((strcmp (name, ".debug_line") == 0)
5135
            || (strcmp (name, ".debug_ranges") == 0))
5136
        hdr->sh_type = SHT_IA_64_VMS_TRACE;
5137
      else if (strcmp (name, ".debug_str") == 0)
5138
        hdr->sh_type = SHT_IA_64_VMS_DEBUG_STR;
5139
      else if (strcmp (name, ".vms_display_name_info") == 0)
5140
        {
5141
          int idx, symcount;
5142
          asymbol **syms;
5143
          struct elf_obj_tdata *t = elf_tdata (abfd);
5144
          int buf[2];
5145
          int demangler_sym_idx = -1;
5146
 
5147
          symcount = bfd_get_symcount (abfd);
5148
          syms = bfd_get_outsymbols (abfd);
5149
          for (idx = 0; idx < symcount; idx++)
5150
            {
5151
              asymbol *sym;
5152
              sym = syms[idx];
5153
              if ((sym->flags & (BSF_DEBUGGING | BSF_DYNAMIC))
5154
                  && strchr (sym->name, '@')
5155
                  && (strcmp (sym->section->name, BFD_ABS_SECTION_NAME) == 0))
5156
                {
5157
                  demangler_sym_idx = sym->udata.i;
5158
                  break;
5159
                }
5160
            }
5161
 
5162
          hdr->sh_type = SHT_IA_64_VMS_DISPLAY_NAME_INFO;
5163
          hdr->sh_entsize = 4;
5164
          hdr->sh_addralign = 0;
5165
          hdr->sh_link = t->symtab_section;
5166
 
5167
          /* Find symtab index of demangler routine and stuff it in
5168
             the second long word of section data.  */
5169
 
5170
          if (demangler_sym_idx > -1)
5171
            {
5172
              bfd_seek (abfd, hdr->sh_offset, SEEK_SET);
5173
              bfd_bread (buf, hdr->sh_size, abfd);
5174
              buf [1] = demangler_sym_idx;
5175
              bfd_seek (abfd, hdr->sh_offset, SEEK_SET);
5176
              bfd_bwrite (buf, hdr->sh_size, abfd);
5177
            }
5178
        }
5179
    }
5180
 
5181
  return TRUE;
5182
}
5183
 
5184
/* The final processing done just before writing out a VMS IA-64 ELF
5185
   object file.  */
5186
 
5187
static void
5188
elfNN_vms_final_write_processing (bfd *abfd,
5189
                                  bfd_boolean linker ATTRIBUTE_UNUSED)
5190
{
5191
  Elf_Internal_Shdr *hdr;
5192
  asection *s;
5193
  int unwind_info_sect_idx = 0;
5194
 
5195
  for (s = abfd->sections; s; s = s->next)
5196
    {
5197
      hdr = &elf_section_data (s)->this_hdr;
5198
 
5199
      if (strcmp (bfd_get_section_name (abfd, hdr->bfd_section),
5200
                  ".IA_64.unwind_info") == 0)
5201
        unwind_info_sect_idx = elf_section_data (s)->this_idx;
5202
 
5203
      switch (hdr->sh_type)
5204
        {
5205
        case SHT_IA_64_UNWIND:
5206
          /* VMS requires sh_info to point to the unwind info section.  */
5207
          hdr->sh_info = unwind_info_sect_idx;
5208
          break;
5209
        }
5210
    }
5211
 
5212
  if (! elf_flags_init (abfd))
5213
    {
5214
      unsigned long flags = 0;
5215
 
5216
      if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
5217
        flags |= EF_IA_64_BE;
5218
      if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
5219
        flags |= EF_IA_64_ABI64;
5220
 
5221
      elf_elfheader(abfd)->e_flags = flags;
5222
      elf_flags_init (abfd) = TRUE;
5223
    }
5224
}
5225
 
5226
static bfd_boolean
5227
elfNN_vms_close_and_cleanup (bfd *abfd)
5228
{
5229
  if (bfd_get_format (abfd) == bfd_object)
5230
    {
5231
      long isize, irsize;
5232
 
5233
      if (elf_shstrtab (abfd) != NULL)
5234
        _bfd_elf_strtab_free (elf_shstrtab (abfd));
5235
 
5236
      /* Pad to 8 byte boundary for IPF/VMS.  */
5237
      isize = bfd_get_size (abfd);
5238
      if ((irsize = isize/8*8) < isize)
5239
        {
5240
          int ishort = (irsize + 8) - isize;
5241
          bfd_seek (abfd, isize, SEEK_SET);
5242
          bfd_bwrite (bfd_zmalloc (ishort), ishort, abfd);
5243
        }
5244
    }
5245
 
5246
  return _bfd_generic_close_and_cleanup (abfd);
5247
}
5248
#endif /* INCLUDE_IA64_VMS */
5249
 
5250
#define TARGET_LITTLE_SYM               bfd_elfNN_ia64_little_vec
5251
#define TARGET_LITTLE_NAME              "elfNN-ia64-little"
5252
#define TARGET_BIG_SYM                  bfd_elfNN_ia64_big_vec
5253
#define TARGET_BIG_NAME                 "elfNN-ia64-big"
5254
#define ELF_ARCH                        bfd_arch_ia64
5255
#define ELF_TARGET_ID                   IA64_ELF_DATA
5256
#define ELF_MACHINE_CODE                EM_IA_64
5257
#define ELF_MACHINE_ALT1                1999    /* EAS2.3 */
5258
#define ELF_MACHINE_ALT2                1998    /* EAS2.2 */
5259
#define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
5260
#define ELF_COMMONPAGESIZE              0x4000  /* 16KB */
5261
 
5262
#define elf_backend_section_from_shdr \
5263
        elfNN_ia64_section_from_shdr
5264
#define elf_backend_section_flags \
5265
        elfNN_ia64_section_flags
5266
#define elf_backend_fake_sections \
5267
        elfNN_ia64_fake_sections
5268
#define elf_backend_final_write_processing \
5269
        elfNN_ia64_final_write_processing
5270
#define elf_backend_add_symbol_hook \
5271
        elfNN_ia64_add_symbol_hook
5272
#define elf_backend_additional_program_headers \
5273
        elfNN_ia64_additional_program_headers
5274
#define elf_backend_modify_segment_map \
5275
        elfNN_ia64_modify_segment_map
5276
#define elf_backend_modify_program_headers \
5277
        elfNN_ia64_modify_program_headers
5278
#define elf_info_to_howto \
5279
        elfNN_ia64_info_to_howto
5280
 
5281
#define bfd_elfNN_bfd_reloc_type_lookup \
5282
        ia64_elf_reloc_type_lookup
5283
#define bfd_elfNN_bfd_reloc_name_lookup \
5284
        ia64_elf_reloc_name_lookup
5285
#define bfd_elfNN_bfd_is_local_label_name \
5286
        elfNN_ia64_is_local_label_name
5287
#define bfd_elfNN_bfd_relax_section \
5288
        elfNN_ia64_relax_section
5289
 
5290
#define elf_backend_object_p \
5291
        elfNN_ia64_object_p
5292
 
5293
/* Stuff for the BFD linker: */
5294
#define bfd_elfNN_bfd_link_hash_table_create \
5295
        elfNN_ia64_hash_table_create
5296
#define bfd_elfNN_bfd_link_hash_table_free \
5297
        elfNN_ia64_hash_table_free
5298
#define elf_backend_create_dynamic_sections \
5299
        elfNN_ia64_create_dynamic_sections
5300
#define elf_backend_check_relocs \
5301
        elfNN_ia64_check_relocs
5302
#define elf_backend_adjust_dynamic_symbol \
5303
        elfNN_ia64_adjust_dynamic_symbol
5304
#define elf_backend_size_dynamic_sections \
5305
        elfNN_ia64_size_dynamic_sections
5306
#define elf_backend_omit_section_dynsym \
5307
  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5308
#define elf_backend_relocate_section \
5309
        elfNN_ia64_relocate_section
5310
#define elf_backend_finish_dynamic_symbol \
5311
        elfNN_ia64_finish_dynamic_symbol
5312
#define elf_backend_finish_dynamic_sections \
5313
        elfNN_ia64_finish_dynamic_sections
5314
#define bfd_elfNN_bfd_final_link \
5315
        elfNN_ia64_final_link
5316
 
5317
#define bfd_elfNN_bfd_merge_private_bfd_data \
5318
        elfNN_ia64_merge_private_bfd_data
5319
#define bfd_elfNN_bfd_set_private_flags \
5320
        elfNN_ia64_set_private_flags
5321
#define bfd_elfNN_bfd_print_private_bfd_data \
5322
        elfNN_ia64_print_private_bfd_data
5323
 
5324
#define elf_backend_plt_readonly        1
5325
#define elf_backend_want_plt_sym        0
5326
#define elf_backend_plt_alignment       5
5327
#define elf_backend_got_header_size     0
5328
#define elf_backend_want_got_plt        1
5329
#define elf_backend_may_use_rel_p       1
5330
#define elf_backend_may_use_rela_p      1
5331
#define elf_backend_default_use_rela_p  1
5332
#define elf_backend_want_dynbss         0
5333
#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5334
#define elf_backend_hide_symbol         elfNN_ia64_hash_hide_symbol
5335
#define elf_backend_fixup_symbol        _bfd_elf_link_hash_fixup_symbol
5336
#define elf_backend_reloc_type_class    elfNN_ia64_reloc_type_class
5337
#define elf_backend_rela_normal         1
5338
#define elf_backend_special_sections    elfNN_ia64_special_sections
5339
#define elf_backend_default_execstack   0
5340
 
5341
/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5342
   SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5343
   We don't want to flood users with so many error messages. We turn
5344
   off the warning for now. It will be turned on later when the Intel
5345
   compiler is fixed.   */
5346
#define elf_backend_link_order_error_handler NULL
5347
 
5348
#include "elfNN-target.h"
5349
 
5350
/* HPUX-specific vectors.  */
5351
 
5352
#undef  TARGET_LITTLE_SYM
5353
#undef  TARGET_LITTLE_NAME
5354
#undef  TARGET_BIG_SYM
5355
#define TARGET_BIG_SYM                  bfd_elfNN_ia64_hpux_big_vec
5356
#undef  TARGET_BIG_NAME
5357
#define TARGET_BIG_NAME                 "elfNN-ia64-hpux-big"
5358
 
5359
/* These are HP-UX specific functions.  */
5360
 
5361
#undef  elf_backend_post_process_headers
5362
#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5363
 
5364
#undef  elf_backend_section_from_bfd_section
5365
#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5366
 
5367
#undef elf_backend_symbol_processing
5368
#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5369
 
5370
#undef  elf_backend_want_p_paddr_set_to_zero
5371
#define elf_backend_want_p_paddr_set_to_zero 1
5372
 
5373
#undef ELF_COMMONPAGESIZE
5374
#undef ELF_OSABI
5375
#define ELF_OSABI                       ELFOSABI_HPUX
5376
 
5377
#undef  elfNN_bed
5378
#define elfNN_bed elfNN_ia64_hpux_bed
5379
 
5380
#include "elfNN-target.h"
5381
 
5382
/* VMS-specific vectors.  */
5383
#ifdef INCLUDE_IA64_VMS
5384
 
5385
#undef  TARGET_LITTLE_SYM
5386
#define TARGET_LITTLE_SYM               bfd_elfNN_ia64_vms_vec
5387
#undef  TARGET_LITTLE_NAME
5388
#define TARGET_LITTLE_NAME              "elfNN-ia64-vms"
5389
#undef  TARGET_BIG_SYM
5390
#undef  TARGET_BIG_NAME
5391
 
5392
/* These are VMS specific functions.  */
5393
 
5394
#undef  elf_backend_object_p
5395
#define elf_backend_object_p elfNN_vms_object_p
5396
 
5397
#undef  elf_backend_section_from_shdr
5398
#define elf_backend_section_from_shdr elfNN_vms_section_from_shdr
5399
 
5400
#undef  elf_backend_post_process_headers
5401
#define elf_backend_post_process_headers elfNN_vms_post_process_headers
5402
 
5403
#undef  elf_backend_section_processing
5404
#define elf_backend_section_processing elfNN_vms_section_processing
5405
 
5406
#undef  elf_backend_final_write_processing
5407
#define elf_backend_final_write_processing elfNN_vms_final_write_processing
5408
 
5409
#undef  bfd_elfNN_close_and_cleanup
5410
#define bfd_elfNN_close_and_cleanup elfNN_vms_close_and_cleanup
5411
 
5412
#undef  elf_backend_section_from_bfd_section
5413
 
5414
#undef  elf_backend_symbol_processing
5415
 
5416
#undef  elf_backend_want_p_paddr_set_to_zero
5417
 
5418
#undef ELF_OSABI
5419
#define ELF_OSABI                       ELFOSABI_OPENVMS
5420
 
5421
#undef  ELF_MAXPAGESIZE
5422
#define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
5423
 
5424
#undef  elfNN_bed
5425
#define elfNN_bed elfNN_ia64_vms_bed
5426
 
5427
/* Use VMS-style archives (in particular, don't use the standard coff
5428
   archive format).  */
5429
#define bfd_elfNN_archive_functions
5430
 
5431
#undef bfd_elfNN_archive_p
5432
#define bfd_elfNN_archive_p _bfd_vms_lib_ia64_archive_p
5433
#undef bfd_elfNN_write_archive_contents
5434
#define bfd_elfNN_write_archive_contents _bfd_vms_lib_write_archive_contents
5435
#undef bfd_elfNN_mkarchive
5436
#define bfd_elfNN_mkarchive _bfd_vms_lib_ia64_mkarchive
5437
 
5438
#define bfd_elfNN_archive_slurp_armap \
5439
  _bfd_vms_lib_slurp_armap
5440
#define bfd_elfNN_archive_slurp_extended_name_table \
5441
  _bfd_vms_lib_slurp_extended_name_table
5442
#define bfd_elfNN_archive_construct_extended_name_table \
5443
  _bfd_vms_lib_construct_extended_name_table
5444
#define bfd_elfNN_archive_truncate_arname \
5445
  _bfd_vms_lib_truncate_arname
5446
#define bfd_elfNN_archive_write_armap \
5447
  _bfd_vms_lib_write_armap
5448
#define bfd_elfNN_archive_read_ar_hdr \
5449
  _bfd_vms_lib_read_ar_hdr
5450
#define bfd_elfNN_archive_write_ar_hdr \
5451
  _bfd_vms_lib_write_ar_hdr
5452
#define bfd_elfNN_archive_openr_next_archived_file \
5453
  _bfd_vms_lib_openr_next_archived_file
5454
#define bfd_elfNN_archive_get_elt_at_index \
5455
  _bfd_vms_lib_get_elt_at_index
5456
#define bfd_elfNN_archive_generic_stat_arch_elt \
5457
  _bfd_vms_lib_generic_stat_arch_elt
5458
#define bfd_elfNN_archive_update_armap_timestamp \
5459
  _bfd_vms_lib_update_armap_timestamp
5460
 
5461
#include "elfNN-target.h"
5462
 
5463
#endif /* INCLUDE_IA64_VMS */

powered by: WebSVN 2.1.0

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