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 161

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 148 khays
          if ((bfd_signed_vma) (symaddr - reladdr) >= offset
590 14 khays
              && (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->info)
1425
    {
1426
      free (entry->info);
1427
      entry->info = NULL;
1428
      entry->count = 0;
1429
      entry->sorted_count = 0;
1430
      entry->size = 0;
1431
    }
1432
 
1433
  return TRUE;
1434
}
1435
 
1436
/* Free the local elfNN_ia64_dyn_sym_info array.  */
1437
 
1438
static bfd_boolean
1439
elfNN_ia64_local_dyn_info_free (void **slot,
1440
                                PTR unused ATTRIBUTE_UNUSED)
1441
{
1442
  struct elfNN_ia64_local_hash_entry *entry
1443
    = (struct elfNN_ia64_local_hash_entry *) *slot;
1444
 
1445
  if (entry->info)
1446
    {
1447
      free (entry->info);
1448
      entry->info = NULL;
1449
      entry->count = 0;
1450
      entry->sorted_count = 0;
1451
      entry->size = 0;
1452
    }
1453
 
1454
  return TRUE;
1455
}
1456
 
1457
/* Destroy IA-64 linker hash table.  */
1458
 
1459
static void
1460
elfNN_ia64_hash_table_free (struct bfd_link_hash_table *hash)
1461
{
1462
  struct elfNN_ia64_link_hash_table *ia64_info
1463
    = (struct elfNN_ia64_link_hash_table *) hash;
1464
  if (ia64_info->loc_hash_table)
1465
    {
1466
      htab_traverse (ia64_info->loc_hash_table,
1467
                     elfNN_ia64_local_dyn_info_free, NULL);
1468
      htab_delete (ia64_info->loc_hash_table);
1469
    }
1470
  if (ia64_info->loc_hash_memory)
1471
    objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
1472
  elf_link_hash_traverse (&ia64_info->root,
1473
                          elfNN_ia64_global_dyn_info_free, NULL);
1474
  _bfd_generic_link_hash_table_free (hash);
1475
}
1476
 
1477
/* Traverse both local and global hash tables.  */
1478
 
1479
struct elfNN_ia64_dyn_sym_traverse_data
1480
{
1481
  bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR);
1482
  PTR data;
1483
};
1484
 
1485
static bfd_boolean
1486
elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
1487
                                 PTR xdata)
1488
{
1489
  struct elfNN_ia64_link_hash_entry *entry
1490
    = (struct elfNN_ia64_link_hash_entry *) xentry;
1491
  struct elfNN_ia64_dyn_sym_traverse_data *data
1492
    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1493
  struct elfNN_ia64_dyn_sym_info *dyn_i;
1494
  unsigned int count;
1495
 
1496
  for (count = entry->count, dyn_i = entry->info;
1497
       count != 0;
1498
       count--, dyn_i++)
1499
    if (! (*data->func) (dyn_i, data->data))
1500
      return FALSE;
1501
  return TRUE;
1502
}
1503
 
1504
static bfd_boolean
1505
elfNN_ia64_local_dyn_sym_thunk (void **slot, PTR xdata)
1506
{
1507
  struct elfNN_ia64_local_hash_entry *entry
1508
    = (struct elfNN_ia64_local_hash_entry *) *slot;
1509
  struct elfNN_ia64_dyn_sym_traverse_data *data
1510
    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1511
  struct elfNN_ia64_dyn_sym_info *dyn_i;
1512
  unsigned int count;
1513
 
1514
  for (count = entry->count, dyn_i = entry->info;
1515
       count != 0;
1516
       count--, dyn_i++)
1517
    if (! (*data->func) (dyn_i, data->data))
1518
      return FALSE;
1519
  return TRUE;
1520
}
1521
 
1522
static void
1523
elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table *ia64_info,
1524
                             bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
1525
                             PTR data)
1526
{
1527
  struct elfNN_ia64_dyn_sym_traverse_data xdata;
1528
 
1529
  xdata.func = func;
1530
  xdata.data = data;
1531
 
1532
  elf_link_hash_traverse (&ia64_info->root,
1533
                          elfNN_ia64_global_dyn_sym_thunk, &xdata);
1534
  htab_traverse (ia64_info->loc_hash_table,
1535
                 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1536
}
1537
 
1538
static bfd_boolean
1539
elfNN_ia64_create_dynamic_sections (bfd *abfd,
1540
                                    struct bfd_link_info *info)
1541
{
1542
  struct elfNN_ia64_link_hash_table *ia64_info;
1543
  asection *s;
1544
 
1545
  if (! _bfd_elf_create_dynamic_sections (abfd, info))
1546
    return FALSE;
1547
 
1548
  ia64_info = elfNN_ia64_hash_table (info);
1549
  if (ia64_info == NULL)
1550
    return FALSE;
1551
 
1552
  {
1553
    flagword flags = bfd_get_section_flags (abfd, ia64_info->root.sgot);
1554
    bfd_set_section_flags (abfd, ia64_info->root.sgot,
1555
                           SEC_SMALL_DATA | flags);
1556
    /* The .got section is always aligned at 8 bytes.  */
1557
    bfd_set_section_alignment (abfd, ia64_info->root.sgot, 3);
1558
  }
1559
 
1560
  if (!get_pltoff (abfd, info, ia64_info))
1561
    return FALSE;
1562
 
1563
  s = bfd_make_section_with_flags (abfd, ".rela.IA_64.pltoff",
1564
                                   (SEC_ALLOC | SEC_LOAD
1565
                                    | SEC_HAS_CONTENTS
1566
                                    | SEC_IN_MEMORY
1567
                                    | SEC_LINKER_CREATED
1568
                                    | SEC_READONLY));
1569
  if (s == NULL
1570
      || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
1571
    return FALSE;
1572
  ia64_info->rel_pltoff_sec = s;
1573
 
1574
  return TRUE;
1575
}
1576
 
1577
/* Find and/or create a hash entry for local symbol.  */
1578
static struct elfNN_ia64_local_hash_entry *
1579
get_local_sym_hash (struct elfNN_ia64_link_hash_table *ia64_info,
1580
                    bfd *abfd, const Elf_Internal_Rela *rel,
1581
                    bfd_boolean create)
1582
{
1583
  struct elfNN_ia64_local_hash_entry e, *ret;
1584
  asection *sec = abfd->sections;
1585
  hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
1586
                                       ELFNN_R_SYM (rel->r_info));
1587
  void **slot;
1588
 
1589
  e.id = sec->id;
1590
  e.r_sym = ELFNN_R_SYM (rel->r_info);
1591
  slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
1592
                                   create ? INSERT : NO_INSERT);
1593
 
1594
  if (!slot)
1595
    return NULL;
1596
 
1597
  if (*slot)
1598
    return (struct elfNN_ia64_local_hash_entry *) *slot;
1599
 
1600
  ret = (struct elfNN_ia64_local_hash_entry *)
1601
        objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
1602
                        sizeof (struct elfNN_ia64_local_hash_entry));
1603
  if (ret)
1604
    {
1605
      memset (ret, 0, sizeof (*ret));
1606
      ret->id = sec->id;
1607
      ret->r_sym = ELFNN_R_SYM (rel->r_info);
1608
      *slot = ret;
1609
    }
1610
  return ret;
1611
}
1612
 
1613
/* Used to sort elfNN_ia64_dyn_sym_info array.  */
1614
 
1615
static int
1616
addend_compare (const void *xp, const void *yp)
1617
{
1618
  const struct elfNN_ia64_dyn_sym_info *x
1619
    = (const struct elfNN_ia64_dyn_sym_info *) xp;
1620
  const struct elfNN_ia64_dyn_sym_info *y
1621
    = (const struct elfNN_ia64_dyn_sym_info *) yp;
1622
 
1623
  return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
1624
}
1625
 
1626
/* Sort elfNN_ia64_dyn_sym_info array and remove duplicates.  */
1627
 
1628
static unsigned int
1629
sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
1630
                   unsigned int count)
1631
{
1632
  bfd_vma curr, prev, got_offset;
1633
  unsigned int i, kept, dupes, diff, dest, src, len;
1634
 
1635
  qsort (info, count, sizeof (*info), addend_compare);
1636
 
1637
  /* Find the first duplicate.  */
1638
  prev = info [0].addend;
1639
  got_offset = info [0].got_offset;
1640
  for (i = 1; i < count; i++)
1641
    {
1642
      curr = info [i].addend;
1643
      if (curr == prev)
1644
        {
1645
          /* For duplicates, make sure that GOT_OFFSET is valid.  */
1646
          if (got_offset == (bfd_vma) -1)
1647
            got_offset = info [i].got_offset;
1648
          break;
1649
        }
1650
      got_offset = info [i].got_offset;
1651
      prev = curr;
1652
    }
1653
 
1654
  /* We may move a block of elements to here.  */
1655
  dest = i++;
1656
 
1657
  /* Remove duplicates.  */
1658
  if (i < count)
1659
    {
1660
      while (i < count)
1661
        {
1662
          /* For duplicates, make sure that the kept one has a valid
1663
             got_offset.  */
1664
          kept = dest - 1;
1665
          if (got_offset != (bfd_vma) -1)
1666
            info [kept].got_offset = got_offset;
1667
 
1668
          curr = info [i].addend;
1669
          got_offset = info [i].got_offset;
1670
 
1671
          /* Move a block of elements whose first one is different from
1672
             the previous.  */
1673
          if (curr == prev)
1674
            {
1675
              for (src = i + 1; src < count; src++)
1676
                {
1677
                  if (info [src].addend != curr)
1678
                    break;
1679
                  /* For duplicates, make sure that GOT_OFFSET is
1680
                     valid.  */
1681
                  if (got_offset == (bfd_vma) -1)
1682
                    got_offset = info [src].got_offset;
1683
                }
1684
 
1685
              /* Make sure that the kept one has a valid got_offset.  */
1686
              if (got_offset != (bfd_vma) -1)
1687
                info [kept].got_offset = got_offset;
1688
            }
1689
          else
1690
            src = i;
1691
 
1692
          if (src >= count)
1693
            break;
1694
 
1695
          /* Find the next duplicate.  SRC will be kept.  */
1696
          prev = info [src].addend;
1697
          got_offset = info [src].got_offset;
1698
          for (dupes = src + 1; dupes < count; dupes ++)
1699
            {
1700
              curr = info [dupes].addend;
1701
              if (curr == prev)
1702
                {
1703
                  /* Make sure that got_offset is valid.  */
1704
                  if (got_offset == (bfd_vma) -1)
1705
                    got_offset = info [dupes].got_offset;
1706
 
1707
                  /* For duplicates, make sure that the kept one has
1708
                     a valid got_offset.  */
1709
                  if (got_offset != (bfd_vma) -1)
1710
                    info [dupes - 1].got_offset = got_offset;
1711
                  break;
1712
                }
1713
              got_offset = info [dupes].got_offset;
1714
              prev = curr;
1715
            }
1716
 
1717
          /* How much to move.  */
1718
          len = dupes - src;
1719
          i = dupes + 1;
1720
 
1721
          if (len == 1 && dupes < count)
1722
            {
1723
              /* If we only move 1 element, we combine it with the next
1724
                 one.  There must be at least a duplicate.  Find the
1725
                 next different one.  */
1726
              for (diff = dupes + 1, src++; diff < count; diff++, src++)
1727
                {
1728
                  if (info [diff].addend != curr)
1729
                    break;
1730
                  /* Make sure that got_offset is valid.  */
1731
                  if (got_offset == (bfd_vma) -1)
1732
                    got_offset = info [diff].got_offset;
1733
                }
1734
 
1735
              /* Makre sure that the last duplicated one has an valid
1736
                 offset.  */
1737
              BFD_ASSERT (curr == prev);
1738
              if (got_offset != (bfd_vma) -1)
1739
                info [diff - 1].got_offset = got_offset;
1740
 
1741
              if (diff < count)
1742
                {
1743
                  /* Find the next duplicate.  Track the current valid
1744
                     offset.  */
1745
                  prev = info [diff].addend;
1746
                  got_offset = info [diff].got_offset;
1747
                  for (dupes = diff + 1; dupes < count; dupes ++)
1748
                    {
1749
                      curr = info [dupes].addend;
1750
                      if (curr == prev)
1751
                        {
1752
                          /* For duplicates, make sure that GOT_OFFSET
1753
                             is valid.  */
1754
                          if (got_offset == (bfd_vma) -1)
1755
                            got_offset = info [dupes].got_offset;
1756
                          break;
1757
                        }
1758
                      got_offset = info [dupes].got_offset;
1759
                      prev = curr;
1760
                      diff++;
1761
                    }
1762
 
1763
                  len = diff - src + 1;
1764
                  i = diff + 1;
1765
                }
1766
            }
1767
 
1768
          memmove (&info [dest], &info [src], len * sizeof (*info));
1769
 
1770
          dest += len;
1771
        }
1772
 
1773
      count = dest;
1774
    }
1775
  else
1776
    {
1777
      /* When we get here, either there is no duplicate at all or
1778
         the only duplicate is the last element.  */
1779
      if (dest < count)
1780
        {
1781
          /* If the last element is a duplicate, make sure that the
1782
             kept one has a valid got_offset.  We also update count.  */
1783
          if (got_offset != (bfd_vma) -1)
1784
            info [dest - 1].got_offset = got_offset;
1785
          count = dest;
1786
        }
1787
    }
1788
 
1789
  return count;
1790
}
1791
 
1792
/* Find and/or create a descriptor for dynamic symbol info.  This will
1793
   vary based on global or local symbol, and the addend to the reloc.
1794
 
1795
   We don't sort when inserting.  Also, we sort and eliminate
1796
   duplicates if there is an unsorted section.  Typically, this will
1797
   only happen once, because we do all insertions before lookups.  We
1798
   then use bsearch to do a lookup.  This also allows lookups to be
1799
   fast.  So we have fast insertion (O(log N) due to duplicate check),
1800
   fast lookup (O(log N)) and one sort (O(N log N) expected time).
1801
   Previously, all lookups were O(N) because of the use of the linked
1802
   list and also all insertions were O(N) because of the check for
1803
   duplicates.  There are some complications here because the array
1804
   size grows occasionally, which may add an O(N) factor, but this
1805
   should be rare.  Also,  we free the excess array allocation, which
1806
   requires a copy which is O(N), but this only happens once.  */
1807
 
1808
static struct elfNN_ia64_dyn_sym_info *
1809
get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
1810
                  struct elf_link_hash_entry *h, bfd *abfd,
1811
                  const Elf_Internal_Rela *rel, bfd_boolean create)
1812
{
1813
  struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
1814
  unsigned int *count_p, *sorted_count_p, *size_p;
1815
  unsigned int count, sorted_count, size;
1816
  bfd_vma addend = rel ? rel->r_addend : 0;
1817
  bfd_size_type amt;
1818
 
1819
  if (h)
1820
    {
1821
      struct elfNN_ia64_link_hash_entry *global_h;
1822
 
1823
      global_h = (struct elfNN_ia64_link_hash_entry *) h;
1824
      info_p = &global_h->info;
1825
      count_p = &global_h->count;
1826
      sorted_count_p = &global_h->sorted_count;
1827
      size_p = &global_h->size;
1828
    }
1829
  else
1830
    {
1831
      struct elfNN_ia64_local_hash_entry *loc_h;
1832
 
1833
      loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1834
      if (!loc_h)
1835
        {
1836
          BFD_ASSERT (!create);
1837
          return NULL;
1838
        }
1839
 
1840
      info_p = &loc_h->info;
1841
      count_p = &loc_h->count;
1842
      sorted_count_p = &loc_h->sorted_count;
1843
      size_p = &loc_h->size;
1844
    }
1845
 
1846
  count = *count_p;
1847
  sorted_count = *sorted_count_p;
1848
  size = *size_p;
1849
  info = *info_p;
1850
  if (create)
1851
    {
1852
      /* When we create the array, we don't check for duplicates,
1853
         except in the previously sorted section if one exists, and
1854
         against the last inserted entry.  This allows insertions to
1855
         be fast.  */
1856
      if (info)
1857
        {
1858
          if (sorted_count)
1859
            {
1860
              /* Try bsearch first on the sorted section.  */
1861
              key.addend = addend;
1862
              dyn_i = bsearch (&key, info, sorted_count,
1863
                               sizeof (*info), addend_compare);
1864
 
1865
              if (dyn_i)
1866
                {
1867
                  return dyn_i;
1868
                }
1869
            }
1870
 
1871
          /* Do a quick check for the last inserted entry.  */
1872
          dyn_i = info + count - 1;
1873
          if (dyn_i->addend == addend)
1874
            {
1875
              return dyn_i;
1876
            }
1877
        }
1878
 
1879
      if (size == 0)
1880
        {
1881
          /* It is the very first element. We create the array of size
1882
             1.  */
1883
          size = 1;
1884
          amt = size * sizeof (*info);
1885
          info = bfd_malloc (amt);
1886
        }
1887
      else if (size <= count)
1888
        {
1889
          /* We double the array size every time when we reach the
1890
             size limit.  */
1891
          size += size;
1892
          amt = size * sizeof (*info);
1893
          info = bfd_realloc (info, amt);
1894
        }
1895
      else
1896
        goto has_space;
1897
 
1898
      if (info == NULL)
1899
        return NULL;
1900
      *size_p = size;
1901
      *info_p = info;
1902
 
1903
has_space:
1904
      /* Append the new one to the array.  */
1905
      dyn_i = info + count;
1906
      memset (dyn_i, 0, sizeof (*dyn_i));
1907
      dyn_i->got_offset = (bfd_vma) -1;
1908
      dyn_i->addend = addend;
1909
 
1910
      /* We increment count only since the new ones are unsorted and
1911
         may have duplicate.  */
1912
      (*count_p)++;
1913
    }
1914
  else
1915
    {
1916
      /* It is a lookup without insertion.  Sort array if part of the
1917
         array isn't sorted.  */
1918
      if (count != sorted_count)
1919
        {
1920
          count = sort_dyn_sym_info (info, count);
1921
          *count_p = count;
1922
          *sorted_count_p = count;
1923
        }
1924
 
1925
      /* Free unused memory.  */
1926
      if (size != count)
1927
        {
1928
          amt = count * sizeof (*info);
1929
          info = bfd_malloc (amt);
1930
          if (info != NULL)
1931
            {
1932
              memcpy (info, *info_p, amt);
1933
              free (*info_p);
1934
              *size_p = count;
1935
              *info_p = info;
1936
            }
1937
        }
1938
 
1939
      key.addend = addend;
1940
      dyn_i = bsearch (&key, info, count,
1941
                       sizeof (*info), addend_compare);
1942
    }
1943
 
1944
  return dyn_i;
1945
}
1946
 
1947
static asection *
1948
get_got (bfd *abfd, struct bfd_link_info *info,
1949
         struct elfNN_ia64_link_hash_table *ia64_info)
1950
{
1951
  asection *got;
1952
  bfd *dynobj;
1953
 
1954
  got = ia64_info->root.sgot;
1955
  if (!got)
1956
    {
1957
      flagword flags;
1958
 
1959
      dynobj = ia64_info->root.dynobj;
1960
      if (!dynobj)
1961
        ia64_info->root.dynobj = dynobj = abfd;
1962
      if (!_bfd_elf_create_got_section (dynobj, info))
1963
        return 0;
1964
 
1965
      got = ia64_info->root.sgot;
1966
 
1967
      /* The .got section is always aligned at 8 bytes.  */
1968
      if (!bfd_set_section_alignment (abfd, got, 3))
1969
        return 0;
1970
 
1971
      flags = bfd_get_section_flags (abfd, got);
1972
      bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1973
    }
1974
 
1975
  return got;
1976
}
1977
 
1978
/* Create function descriptor section (.opd).  This section is called .opd
1979
   because it contains "official procedure descriptors".  The "official"
1980
   refers to the fact that these descriptors are used when taking the address
1981
   of a procedure, thus ensuring a unique address for each procedure.  */
1982
 
1983
static asection *
1984
get_fptr (bfd *abfd, struct bfd_link_info *info,
1985
          struct elfNN_ia64_link_hash_table *ia64_info)
1986
{
1987
  asection *fptr;
1988
  bfd *dynobj;
1989
 
1990
  fptr = ia64_info->fptr_sec;
1991
  if (!fptr)
1992
    {
1993
      dynobj = ia64_info->root.dynobj;
1994
      if (!dynobj)
1995
        ia64_info->root.dynobj = dynobj = abfd;
1996
 
1997
      fptr = bfd_make_section_with_flags (dynobj, ".opd",
1998
                                          (SEC_ALLOC
1999
                                           | SEC_LOAD
2000
                                           | SEC_HAS_CONTENTS
2001
                                           | SEC_IN_MEMORY
2002
                                           | (info->pie ? 0 : SEC_READONLY)
2003
                                           | SEC_LINKER_CREATED));
2004
      if (!fptr
2005
          || !bfd_set_section_alignment (abfd, fptr, 4))
2006
        {
2007
          BFD_ASSERT (0);
2008
          return NULL;
2009
        }
2010
 
2011
      ia64_info->fptr_sec = fptr;
2012
 
2013
      if (info->pie)
2014
        {
2015
          asection *fptr_rel;
2016
          fptr_rel = bfd_make_section_with_flags (dynobj, ".rela.opd",
2017
                                                  (SEC_ALLOC | SEC_LOAD
2018
                                                   | SEC_HAS_CONTENTS
2019
                                                   | SEC_IN_MEMORY
2020
                                                   | SEC_LINKER_CREATED
2021
                                                   | SEC_READONLY));
2022
          if (fptr_rel == NULL
2023
              || !bfd_set_section_alignment (abfd, fptr_rel,
2024
                                             LOG_SECTION_ALIGN))
2025
            {
2026
              BFD_ASSERT (0);
2027
              return NULL;
2028
            }
2029
 
2030
          ia64_info->rel_fptr_sec = fptr_rel;
2031
        }
2032
    }
2033
 
2034
  return fptr;
2035
}
2036
 
2037
static asection *
2038
get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
2039
            struct elfNN_ia64_link_hash_table *ia64_info)
2040
{
2041
  asection *pltoff;
2042
  bfd *dynobj;
2043
 
2044
  pltoff = ia64_info->pltoff_sec;
2045
  if (!pltoff)
2046
    {
2047
      dynobj = ia64_info->root.dynobj;
2048
      if (!dynobj)
2049
        ia64_info->root.dynobj = dynobj = abfd;
2050
 
2051
      pltoff = bfd_make_section_with_flags (dynobj,
2052
                                            ELF_STRING_ia64_pltoff,
2053
                                            (SEC_ALLOC
2054
                                             | SEC_LOAD
2055
                                             | SEC_HAS_CONTENTS
2056
                                             | SEC_IN_MEMORY
2057
                                             | SEC_SMALL_DATA
2058
                                             | SEC_LINKER_CREATED));
2059
      if (!pltoff
2060
          || !bfd_set_section_alignment (abfd, pltoff, 4))
2061
        {
2062
          BFD_ASSERT (0);
2063
          return NULL;
2064
        }
2065
 
2066
      ia64_info->pltoff_sec = pltoff;
2067
    }
2068
 
2069
  return pltoff;
2070
}
2071
 
2072
static asection *
2073
get_reloc_section (bfd *abfd,
2074
                   struct elfNN_ia64_link_hash_table *ia64_info,
2075
                   asection *sec, bfd_boolean create)
2076
{
2077
  const char *srel_name;
2078
  asection *srel;
2079
  bfd *dynobj;
2080
 
2081
  srel_name = (bfd_elf_string_from_elf_section
2082
               (abfd, elf_elfheader(abfd)->e_shstrndx,
2083
                _bfd_elf_single_rel_hdr (sec)->sh_name));
2084
  if (srel_name == NULL)
2085
    return NULL;
2086
 
2087
  dynobj = ia64_info->root.dynobj;
2088
  if (!dynobj)
2089
    ia64_info->root.dynobj = dynobj = abfd;
2090
 
2091
  srel = bfd_get_section_by_name (dynobj, srel_name);
2092
  if (srel == NULL && create)
2093
    {
2094
      srel = bfd_make_section_with_flags (dynobj, srel_name,
2095
                                          (SEC_ALLOC | SEC_LOAD
2096
                                           | SEC_HAS_CONTENTS
2097
                                           | SEC_IN_MEMORY
2098
                                           | SEC_LINKER_CREATED
2099
                                           | SEC_READONLY));
2100
      if (srel == NULL
2101
          || !bfd_set_section_alignment (dynobj, srel,
2102
                                         LOG_SECTION_ALIGN))
2103
        return NULL;
2104
    }
2105
 
2106
  return srel;
2107
}
2108
 
2109
static bfd_boolean
2110
count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2111
                 asection *srel, int type, bfd_boolean reltext)
2112
{
2113
  struct elfNN_ia64_dyn_reloc_entry *rent;
2114
 
2115
  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2116
    if (rent->srel == srel && rent->type == type)
2117
      break;
2118
 
2119
  if (!rent)
2120
    {
2121
      rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2122
              bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2123
      if (!rent)
2124
        return FALSE;
2125
 
2126
      rent->next = dyn_i->reloc_entries;
2127
      rent->srel = srel;
2128
      rent->type = type;
2129
      rent->count = 0;
2130
      dyn_i->reloc_entries = rent;
2131
    }
2132 161 khays
  rent->reltext = reltext;
2133 14 khays
  rent->count++;
2134
 
2135
  return TRUE;
2136
}
2137
 
2138
static bfd_boolean
2139
elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
2140
                         asection *sec,
2141
                         const Elf_Internal_Rela *relocs)
2142
{
2143
  struct elfNN_ia64_link_hash_table *ia64_info;
2144
  const Elf_Internal_Rela *relend;
2145
  Elf_Internal_Shdr *symtab_hdr;
2146
  const Elf_Internal_Rela *rel;
2147
  asection *got, *fptr, *srel, *pltoff;
2148
  enum {
2149
    NEED_GOT = 1,
2150
    NEED_GOTX = 2,
2151
    NEED_FPTR = 4,
2152
    NEED_PLTOFF = 8,
2153
    NEED_MIN_PLT = 16,
2154
    NEED_FULL_PLT = 32,
2155
    NEED_DYNREL = 64,
2156
    NEED_LTOFF_FPTR = 128,
2157
    NEED_TPREL = 256,
2158
    NEED_DTPMOD = 512,
2159
    NEED_DTPREL = 1024
2160
  };
2161
  int need_entry;
2162
  struct elf_link_hash_entry *h;
2163
  unsigned long r_symndx;
2164
  bfd_boolean maybe_dynamic;
2165
 
2166
  if (info->relocatable)
2167
    return TRUE;
2168
 
2169
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2170
  ia64_info = elfNN_ia64_hash_table (info);
2171
  if (ia64_info == NULL)
2172
    return FALSE;
2173
 
2174
  got = fptr = srel = pltoff = NULL;
2175
 
2176
  relend = relocs + sec->reloc_count;
2177
 
2178
  /* We scan relocations first to create dynamic relocation arrays.  We
2179
     modified get_dyn_sym_info to allow fast insertion and support fast
2180
     lookup in the next loop.  */
2181
  for (rel = relocs; rel < relend; ++rel)
2182
    {
2183
      r_symndx = ELFNN_R_SYM (rel->r_info);
2184
      if (r_symndx >= symtab_hdr->sh_info)
2185
        {
2186
          long indx = r_symndx - symtab_hdr->sh_info;
2187
          h = elf_sym_hashes (abfd)[indx];
2188
          while (h->root.type == bfd_link_hash_indirect
2189
                 || h->root.type == bfd_link_hash_warning)
2190
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
2191
        }
2192
      else
2193
        h = NULL;
2194
 
2195
      /* We can only get preliminary data on whether a symbol is
2196
         locally or externally defined, as not all of the input files
2197
         have yet been processed.  Do something with what we know, as
2198
         this may help reduce memory usage and processing time later.  */
2199
      maybe_dynamic = (h && ((!info->executable
2200
                              && (!SYMBOLIC_BIND (info, h)
2201
                                  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2202
                             || !h->def_regular
2203
                             || h->root.type == bfd_link_hash_defweak));
2204
 
2205
      need_entry = 0;
2206
      switch (ELFNN_R_TYPE (rel->r_info))
2207
        {
2208
        case R_IA64_TPREL64MSB:
2209
        case R_IA64_TPREL64LSB:
2210
          if (info->shared || maybe_dynamic)
2211
            need_entry = NEED_DYNREL;
2212
          break;
2213
 
2214
        case R_IA64_LTOFF_TPREL22:
2215
          need_entry = NEED_TPREL;
2216
          if (info->shared)
2217
            info->flags |= DF_STATIC_TLS;
2218
          break;
2219
 
2220
        case R_IA64_DTPREL32MSB:
2221
        case R_IA64_DTPREL32LSB:
2222
        case R_IA64_DTPREL64MSB:
2223
        case R_IA64_DTPREL64LSB:
2224
          if (info->shared || maybe_dynamic)
2225
            need_entry = NEED_DYNREL;
2226
          break;
2227
 
2228
        case R_IA64_LTOFF_DTPREL22:
2229
          need_entry = NEED_DTPREL;
2230
          break;
2231
 
2232
        case R_IA64_DTPMOD64MSB:
2233
        case R_IA64_DTPMOD64LSB:
2234
          if (info->shared || maybe_dynamic)
2235
            need_entry = NEED_DYNREL;
2236
          break;
2237
 
2238
        case R_IA64_LTOFF_DTPMOD22:
2239
          need_entry = NEED_DTPMOD;
2240
          break;
2241
 
2242
        case R_IA64_LTOFF_FPTR22:
2243
        case R_IA64_LTOFF_FPTR64I:
2244
        case R_IA64_LTOFF_FPTR32MSB:
2245
        case R_IA64_LTOFF_FPTR32LSB:
2246
        case R_IA64_LTOFF_FPTR64MSB:
2247
        case R_IA64_LTOFF_FPTR64LSB:
2248
          need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2249
          break;
2250
 
2251
        case R_IA64_FPTR64I:
2252
        case R_IA64_FPTR32MSB:
2253
        case R_IA64_FPTR32LSB:
2254
        case R_IA64_FPTR64MSB:
2255
        case R_IA64_FPTR64LSB:
2256
          if (info->shared || h)
2257
            need_entry = NEED_FPTR | NEED_DYNREL;
2258
          else
2259
            need_entry = NEED_FPTR;
2260
          break;
2261
 
2262
        case R_IA64_LTOFF22:
2263
        case R_IA64_LTOFF64I:
2264
          need_entry = NEED_GOT;
2265
          break;
2266
 
2267
        case R_IA64_LTOFF22X:
2268
          need_entry = NEED_GOTX;
2269
          break;
2270
 
2271
        case R_IA64_PLTOFF22:
2272
        case R_IA64_PLTOFF64I:
2273
        case R_IA64_PLTOFF64MSB:
2274
        case R_IA64_PLTOFF64LSB:
2275
          need_entry = NEED_PLTOFF;
2276
          if (h)
2277
            {
2278
              if (maybe_dynamic)
2279
                need_entry |= NEED_MIN_PLT;
2280
            }
2281
          else
2282
            {
2283
              (*info->callbacks->warning)
2284
                (info, _("@pltoff reloc against local symbol"), 0,
2285
                 abfd, 0, (bfd_vma) 0);
2286
            }
2287
          break;
2288
 
2289
        case R_IA64_PCREL21B:
2290
        case R_IA64_PCREL60B:
2291
          /* Depending on where this symbol is defined, we may or may not
2292
             need a full plt entry.  Only skip if we know we'll not need
2293
             the entry -- static or symbolic, and the symbol definition
2294
             has already been seen.  */
2295
          if (maybe_dynamic && rel->r_addend == 0)
2296
            need_entry = NEED_FULL_PLT;
2297
          break;
2298
 
2299
        case R_IA64_IMM14:
2300
        case R_IA64_IMM22:
2301
        case R_IA64_IMM64:
2302
        case R_IA64_DIR32MSB:
2303
        case R_IA64_DIR32LSB:
2304
        case R_IA64_DIR64MSB:
2305
        case R_IA64_DIR64LSB:
2306
          /* Shared objects will always need at least a REL relocation.  */
2307
          if (info->shared || maybe_dynamic)
2308
            need_entry = NEED_DYNREL;
2309
          break;
2310
 
2311
        case R_IA64_IPLTMSB:
2312
        case R_IA64_IPLTLSB:
2313
          /* Shared objects will always need at least a REL relocation.  */
2314
          if (info->shared || maybe_dynamic)
2315
            need_entry = NEED_DYNREL;
2316
          break;
2317
 
2318
        case R_IA64_PCREL22:
2319
        case R_IA64_PCREL64I:
2320
        case R_IA64_PCREL32MSB:
2321
        case R_IA64_PCREL32LSB:
2322
        case R_IA64_PCREL64MSB:
2323
        case R_IA64_PCREL64LSB:
2324
          if (maybe_dynamic)
2325
            need_entry = NEED_DYNREL;
2326
          break;
2327
        }
2328
 
2329
      if (!need_entry)
2330
        continue;
2331
 
2332
      if ((need_entry & NEED_FPTR) != 0
2333
          && rel->r_addend)
2334
        {
2335
          (*info->callbacks->warning)
2336
            (info, _("non-zero addend in @fptr reloc"), 0,
2337
             abfd, 0, (bfd_vma) 0);
2338
        }
2339
 
2340
      if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
2341
        return FALSE;
2342
    }
2343
 
2344
  /* Now, we only do lookup without insertion, which is very fast
2345
     with the modified get_dyn_sym_info.  */
2346
  for (rel = relocs; rel < relend; ++rel)
2347
    {
2348
      struct elfNN_ia64_dyn_sym_info *dyn_i;
2349
      int dynrel_type = R_IA64_NONE;
2350
 
2351
      r_symndx = ELFNN_R_SYM (rel->r_info);
2352
      if (r_symndx >= symtab_hdr->sh_info)
2353
        {
2354
          /* We're dealing with a global symbol -- find its hash entry
2355
             and mark it as being referenced.  */
2356
          long indx = r_symndx - symtab_hdr->sh_info;
2357
          h = elf_sym_hashes (abfd)[indx];
2358
          while (h->root.type == bfd_link_hash_indirect
2359
                 || h->root.type == bfd_link_hash_warning)
2360
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
2361
 
2362
          h->ref_regular = 1;
2363
        }
2364
      else
2365
        h = NULL;
2366
 
2367
      /* We can only get preliminary data on whether a symbol is
2368
         locally or externally defined, as not all of the input files
2369
         have yet been processed.  Do something with what we know, as
2370
         this may help reduce memory usage and processing time later.  */
2371
      maybe_dynamic = (h && ((!info->executable
2372
                              && (!SYMBOLIC_BIND (info, h)
2373
                                  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2374
                             || !h->def_regular
2375
                             || h->root.type == bfd_link_hash_defweak));
2376
 
2377
      need_entry = 0;
2378
      switch (ELFNN_R_TYPE (rel->r_info))
2379
        {
2380
        case R_IA64_TPREL64MSB:
2381
        case R_IA64_TPREL64LSB:
2382
          if (info->shared || maybe_dynamic)
2383
            need_entry = NEED_DYNREL;
2384
          dynrel_type = R_IA64_TPREL64LSB;
2385
          if (info->shared)
2386
            info->flags |= DF_STATIC_TLS;
2387
          break;
2388
 
2389
        case R_IA64_LTOFF_TPREL22:
2390
          need_entry = NEED_TPREL;
2391
          if (info->shared)
2392
            info->flags |= DF_STATIC_TLS;
2393
          break;
2394
 
2395
        case R_IA64_DTPREL32MSB:
2396
        case R_IA64_DTPREL32LSB:
2397
        case R_IA64_DTPREL64MSB:
2398
        case R_IA64_DTPREL64LSB:
2399
          if (info->shared || maybe_dynamic)
2400
            need_entry = NEED_DYNREL;
2401
          dynrel_type = R_IA64_DTPRELNNLSB;
2402
          break;
2403
 
2404
        case R_IA64_LTOFF_DTPREL22:
2405
          need_entry = NEED_DTPREL;
2406
          break;
2407
 
2408
        case R_IA64_DTPMOD64MSB:
2409
        case R_IA64_DTPMOD64LSB:
2410
          if (info->shared || maybe_dynamic)
2411
            need_entry = NEED_DYNREL;
2412
          dynrel_type = R_IA64_DTPMOD64LSB;
2413
          break;
2414
 
2415
        case R_IA64_LTOFF_DTPMOD22:
2416
          need_entry = NEED_DTPMOD;
2417
          break;
2418
 
2419
        case R_IA64_LTOFF_FPTR22:
2420
        case R_IA64_LTOFF_FPTR64I:
2421
        case R_IA64_LTOFF_FPTR32MSB:
2422
        case R_IA64_LTOFF_FPTR32LSB:
2423
        case R_IA64_LTOFF_FPTR64MSB:
2424
        case R_IA64_LTOFF_FPTR64LSB:
2425
          need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2426
          break;
2427
 
2428
        case R_IA64_FPTR64I:
2429
        case R_IA64_FPTR32MSB:
2430
        case R_IA64_FPTR32LSB:
2431
        case R_IA64_FPTR64MSB:
2432
        case R_IA64_FPTR64LSB:
2433
          if (info->shared || h)
2434
            need_entry = NEED_FPTR | NEED_DYNREL;
2435
          else
2436
            need_entry = NEED_FPTR;
2437
          dynrel_type = R_IA64_FPTRNNLSB;
2438
          break;
2439
 
2440
        case R_IA64_LTOFF22:
2441
        case R_IA64_LTOFF64I:
2442
          need_entry = NEED_GOT;
2443
          break;
2444
 
2445
        case R_IA64_LTOFF22X:
2446
          need_entry = NEED_GOTX;
2447
          break;
2448
 
2449
        case R_IA64_PLTOFF22:
2450
        case R_IA64_PLTOFF64I:
2451
        case R_IA64_PLTOFF64MSB:
2452
        case R_IA64_PLTOFF64LSB:
2453
          need_entry = NEED_PLTOFF;
2454
          if (h)
2455
            {
2456
              if (maybe_dynamic)
2457
                need_entry |= NEED_MIN_PLT;
2458
            }
2459
          break;
2460
 
2461
        case R_IA64_PCREL21B:
2462
        case R_IA64_PCREL60B:
2463
          /* Depending on where this symbol is defined, we may or may not
2464
             need a full plt entry.  Only skip if we know we'll not need
2465
             the entry -- static or symbolic, and the symbol definition
2466
             has already been seen.  */
2467
          if (maybe_dynamic && rel->r_addend == 0)
2468
            need_entry = NEED_FULL_PLT;
2469
          break;
2470
 
2471
        case R_IA64_IMM14:
2472
        case R_IA64_IMM22:
2473
        case R_IA64_IMM64:
2474
        case R_IA64_DIR32MSB:
2475
        case R_IA64_DIR32LSB:
2476
        case R_IA64_DIR64MSB:
2477
        case R_IA64_DIR64LSB:
2478
          /* Shared objects will always need at least a REL relocation.  */
2479
          if (info->shared || maybe_dynamic)
2480
            need_entry = NEED_DYNREL;
2481
          dynrel_type = R_IA64_DIRNNLSB;
2482
          break;
2483
 
2484
        case R_IA64_IPLTMSB:
2485
        case R_IA64_IPLTLSB:
2486
          /* Shared objects will always need at least a REL relocation.  */
2487
          if (info->shared || maybe_dynamic)
2488
            need_entry = NEED_DYNREL;
2489
          dynrel_type = R_IA64_IPLTLSB;
2490
          break;
2491
 
2492
        case R_IA64_PCREL22:
2493
        case R_IA64_PCREL64I:
2494
        case R_IA64_PCREL32MSB:
2495
        case R_IA64_PCREL32LSB:
2496
        case R_IA64_PCREL64MSB:
2497
        case R_IA64_PCREL64LSB:
2498
          if (maybe_dynamic)
2499
            need_entry = NEED_DYNREL;
2500
          dynrel_type = R_IA64_PCRELNNLSB;
2501
          break;
2502
        }
2503
 
2504
      if (!need_entry)
2505
        continue;
2506
 
2507
      dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
2508
 
2509
      /* Record whether or not this is a local symbol.  */
2510
      dyn_i->h = h;
2511
 
2512
      /* Create what's needed.  */
2513
      if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2514
                        | NEED_DTPMOD | NEED_DTPREL))
2515
        {
2516
          if (!got)
2517
            {
2518
              got = get_got (abfd, info, ia64_info);
2519
              if (!got)
2520
                return FALSE;
2521
            }
2522
          if (need_entry & NEED_GOT)
2523
            dyn_i->want_got = 1;
2524
          if (need_entry & NEED_GOTX)
2525
            dyn_i->want_gotx = 1;
2526
          if (need_entry & NEED_TPREL)
2527
            dyn_i->want_tprel = 1;
2528
          if (need_entry & NEED_DTPMOD)
2529
            dyn_i->want_dtpmod = 1;
2530
          if (need_entry & NEED_DTPREL)
2531
            dyn_i->want_dtprel = 1;
2532
        }
2533
      if (need_entry & NEED_FPTR)
2534
        {
2535
          if (!fptr)
2536
            {
2537
              fptr = get_fptr (abfd, info, ia64_info);
2538
              if (!fptr)
2539
                return FALSE;
2540
            }
2541
 
2542
          /* FPTRs for shared libraries are allocated by the dynamic
2543
             linker.  Make sure this local symbol will appear in the
2544
             dynamic symbol table.  */
2545
          if (!h && info->shared)
2546
            {
2547
              if (! (bfd_elf_link_record_local_dynamic_symbol
2548
                     (info, abfd, (long) r_symndx)))
2549
                return FALSE;
2550
            }
2551
 
2552
          dyn_i->want_fptr = 1;
2553
        }
2554
      if (need_entry & NEED_LTOFF_FPTR)
2555
        dyn_i->want_ltoff_fptr = 1;
2556
      if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2557
        {
2558
          if (!ia64_info->root.dynobj)
2559
            ia64_info->root.dynobj = abfd;
2560
          h->needs_plt = 1;
2561
          dyn_i->want_plt = 1;
2562
        }
2563
      if (need_entry & NEED_FULL_PLT)
2564
        dyn_i->want_plt2 = 1;
2565
      if (need_entry & NEED_PLTOFF)
2566
        {
2567
          /* This is needed here, in case @pltoff is used in a non-shared
2568
             link.  */
2569
          if (!pltoff)
2570
            {
2571
              pltoff = get_pltoff (abfd, info, ia64_info);
2572
              if (!pltoff)
2573
                return FALSE;
2574
            }
2575
 
2576
          dyn_i->want_pltoff = 1;
2577
        }
2578
      if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2579
        {
2580
          if (!srel)
2581
            {
2582
              srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
2583
              if (!srel)
2584
                return FALSE;
2585
            }
2586
          if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
2587
                                (sec->flags & SEC_READONLY) != 0))
2588
            return FALSE;
2589
        }
2590
    }
2591
 
2592
  return TRUE;
2593
}
2594
 
2595
/* For cleanliness, and potentially faster dynamic loading, allocate
2596
   external GOT entries first.  */
2597
 
2598
static bfd_boolean
2599
allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
2600
                          void * data)
2601
{
2602
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2603
 
2604
  if ((dyn_i->want_got || dyn_i->want_gotx)
2605
      && ! dyn_i->want_fptr
2606
      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2607
     {
2608
       dyn_i->got_offset = x->ofs;
2609
       x->ofs += 8;
2610
     }
2611
  if (dyn_i->want_tprel)
2612
    {
2613
      dyn_i->tprel_offset = x->ofs;
2614
      x->ofs += 8;
2615
    }
2616
  if (dyn_i->want_dtpmod)
2617
    {
2618
      if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2619
        {
2620
          dyn_i->dtpmod_offset = x->ofs;
2621
          x->ofs += 8;
2622
        }
2623
      else
2624
        {
2625
          struct elfNN_ia64_link_hash_table *ia64_info;
2626
 
2627
          ia64_info = elfNN_ia64_hash_table (x->info);
2628
          if (ia64_info == NULL)
2629
            return FALSE;
2630
 
2631
          if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2632
            {
2633
              ia64_info->self_dtpmod_offset = x->ofs;
2634
              x->ofs += 8;
2635
            }
2636
          dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2637
        }
2638
    }
2639
  if (dyn_i->want_dtprel)
2640
    {
2641
      dyn_i->dtprel_offset = x->ofs;
2642
      x->ofs += 8;
2643
    }
2644
  return TRUE;
2645
}
2646
 
2647
/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
2648
 
2649
static bfd_boolean
2650
allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
2651
                          void * data)
2652
{
2653
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2654
 
2655
  if (dyn_i->want_got
2656
      && dyn_i->want_fptr
2657
      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
2658
    {
2659
      dyn_i->got_offset = x->ofs;
2660
      x->ofs += 8;
2661
    }
2662
  return TRUE;
2663
}
2664
 
2665
/* Lastly, allocate all the GOT entries for local data.  */
2666
 
2667
static bfd_boolean
2668
allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
2669
                    PTR data)
2670
{
2671
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2672
 
2673
  if ((dyn_i->want_got || dyn_i->want_gotx)
2674
      && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2675
    {
2676
      dyn_i->got_offset = x->ofs;
2677
      x->ofs += 8;
2678
    }
2679
  return TRUE;
2680
}
2681
 
2682
/* Search for the index of a global symbol in it's defining object file.  */
2683
 
2684
static long
2685
global_sym_index (struct elf_link_hash_entry *h)
2686
{
2687
  struct elf_link_hash_entry **p;
2688
  bfd *obj;
2689
 
2690
  BFD_ASSERT (h->root.type == bfd_link_hash_defined
2691
              || h->root.type == bfd_link_hash_defweak);
2692
 
2693
  obj = h->root.u.def.section->owner;
2694
  for (p = elf_sym_hashes (obj); *p != h; ++p)
2695
    continue;
2696
 
2697
  return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2698
}
2699
 
2700
/* Allocate function descriptors.  We can do these for every function
2701
   in a main executable that is not exported.  */
2702
 
2703
static bfd_boolean
2704
allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data)
2705
{
2706
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2707
 
2708
  if (dyn_i->want_fptr)
2709
    {
2710
      struct elf_link_hash_entry *h = dyn_i->h;
2711
 
2712
      if (h)
2713
        while (h->root.type == bfd_link_hash_indirect
2714
               || h->root.type == bfd_link_hash_warning)
2715
          h = (struct elf_link_hash_entry *) h->root.u.i.link;
2716
 
2717
      if (!x->info->executable
2718
          && (!h
2719
              || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2720
              || (h->root.type != bfd_link_hash_undefweak
2721
                  && h->root.type != bfd_link_hash_undefined)))
2722
        {
2723
          if (h && h->dynindx == -1)
2724
            {
2725
              BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2726
                          || (h->root.type == bfd_link_hash_defweak));
2727
 
2728
              if (!bfd_elf_link_record_local_dynamic_symbol
2729
                    (x->info, h->root.u.def.section->owner,
2730
                     global_sym_index (h)))
2731
                return FALSE;
2732
            }
2733
 
2734
          dyn_i->want_fptr = 0;
2735
        }
2736
      else if (h == NULL || h->dynindx == -1)
2737
        {
2738
          dyn_i->fptr_offset = x->ofs;
2739
          x->ofs += 16;
2740
        }
2741
      else
2742
        dyn_i->want_fptr = 0;
2743
    }
2744
  return TRUE;
2745
}
2746
 
2747
/* Allocate all the minimal PLT entries.  */
2748
 
2749
static bfd_boolean
2750
allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2751
                      PTR data)
2752
{
2753
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2754
 
2755
  if (dyn_i->want_plt)
2756
    {
2757
      struct elf_link_hash_entry *h = dyn_i->h;
2758
 
2759
      if (h)
2760
        while (h->root.type == bfd_link_hash_indirect
2761
               || h->root.type == bfd_link_hash_warning)
2762
          h = (struct elf_link_hash_entry *) h->root.u.i.link;
2763
 
2764
      /* ??? Versioned symbols seem to lose NEEDS_PLT.  */
2765
      if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
2766
        {
2767
          bfd_size_type offset = x->ofs;
2768
          if (offset == 0)
2769
            offset = PLT_HEADER_SIZE;
2770
          dyn_i->plt_offset = offset;
2771
          x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2772
 
2773
          dyn_i->want_pltoff = 1;
2774
        }
2775
      else
2776
        {
2777
          dyn_i->want_plt = 0;
2778
          dyn_i->want_plt2 = 0;
2779
        }
2780
    }
2781
  return TRUE;
2782
}
2783
 
2784
/* Allocate all the full PLT entries.  */
2785
 
2786
static bfd_boolean
2787
allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2788
                       PTR data)
2789
{
2790
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2791
 
2792
  if (dyn_i->want_plt2)
2793
    {
2794
      struct elf_link_hash_entry *h = dyn_i->h;
2795
      bfd_size_type ofs = x->ofs;
2796
 
2797
      dyn_i->plt2_offset = ofs;
2798
      x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2799
 
2800
      while (h->root.type == bfd_link_hash_indirect
2801
             || h->root.type == bfd_link_hash_warning)
2802
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
2803
      dyn_i->h->plt.offset = ofs;
2804
    }
2805
  return TRUE;
2806
}
2807
 
2808
/* Allocate all the PLTOFF entries requested by relocations and
2809
   plt entries.  We can't share space with allocated FPTR entries,
2810
   because the latter are not necessarily addressable by the GP.
2811
   ??? Relaxation might be able to determine that they are.  */
2812
 
2813
static bfd_boolean
2814
allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2815
                         PTR data)
2816
{
2817
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2818
 
2819
  if (dyn_i->want_pltoff)
2820
    {
2821
      dyn_i->pltoff_offset = x->ofs;
2822
      x->ofs += 16;
2823
    }
2824
  return TRUE;
2825
}
2826
 
2827
/* Allocate dynamic relocations for those symbols that turned out
2828
   to be dynamic.  */
2829
 
2830
static bfd_boolean
2831
allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
2832
                         PTR data)
2833
{
2834
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2835
  struct elfNN_ia64_link_hash_table *ia64_info;
2836
  struct elfNN_ia64_dyn_reloc_entry *rent;
2837
  bfd_boolean dynamic_symbol, shared, resolved_zero;
2838
 
2839
  ia64_info = elfNN_ia64_hash_table (x->info);
2840
  if (ia64_info == NULL)
2841
    return FALSE;
2842
 
2843
  /* Note that this can't be used in relation to FPTR relocs below.  */
2844
  dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
2845
 
2846
  shared = x->info->shared;
2847
  resolved_zero = (dyn_i->h
2848
                   && ELF_ST_VISIBILITY (dyn_i->h->other)
2849
                   && dyn_i->h->root.type == bfd_link_hash_undefweak);
2850
 
2851
  /* Take care of the GOT and PLT relocations.  */
2852
 
2853
  if ((!resolved_zero
2854
       && (dynamic_symbol || shared)
2855
       && (dyn_i->want_got || dyn_i->want_gotx))
2856
      || (dyn_i->want_ltoff_fptr
2857
          && dyn_i->h
2858
          && dyn_i->h->dynindx != -1))
2859
    {
2860
      if (!dyn_i->want_ltoff_fptr
2861
          || !x->info->pie
2862
          || dyn_i->h == NULL
2863
          || dyn_i->h->root.type != bfd_link_hash_undefweak)
2864
        ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2865
    }
2866
  if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2867
    ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2868
  if (dynamic_symbol && dyn_i->want_dtpmod)
2869
    ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2870
  if (dynamic_symbol && dyn_i->want_dtprel)
2871
    ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
2872
 
2873
  if (x->only_got)
2874
    return TRUE;
2875
 
2876
  if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
2877
    {
2878
      if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
2879
        ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
2880
    }
2881
 
2882
  if (!resolved_zero && dyn_i->want_pltoff)
2883
    {
2884
      bfd_size_type t = 0;
2885
 
2886
      /* Dynamic symbols get one IPLT relocation.  Local symbols in
2887
         shared libraries get two REL relocations.  Local symbols in
2888
         main applications get nothing.  */
2889
      if (dynamic_symbol)
2890
        t = sizeof (ElfNN_External_Rela);
2891
      else if (shared)
2892
        t = 2 * sizeof (ElfNN_External_Rela);
2893
 
2894
      ia64_info->rel_pltoff_sec->size += t;
2895
    }
2896
 
2897
  /* Take care of the normal data relocations.  */
2898
 
2899
  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2900
    {
2901
      int count = rent->count;
2902
 
2903
      switch (rent->type)
2904
        {
2905
        case R_IA64_FPTR32LSB:
2906
        case R_IA64_FPTR64LSB:
2907
          /* Allocate one iff !want_fptr and not PIE, which by this point
2908
             will be true only if we're actually allocating one statically
2909
             in the main executable.  Position independent executables
2910
             need a relative reloc.  */
2911
          if (dyn_i->want_fptr && !x->info->pie)
2912
            continue;
2913
          break;
2914
        case R_IA64_PCREL32LSB:
2915
        case R_IA64_PCREL64LSB:
2916
          if (!dynamic_symbol)
2917
            continue;
2918
          break;
2919
        case R_IA64_DIR32LSB:
2920
        case R_IA64_DIR64LSB:
2921
          if (!dynamic_symbol && !shared)
2922
            continue;
2923
          break;
2924
        case R_IA64_IPLTLSB:
2925
          if (!dynamic_symbol && !shared)
2926
            continue;
2927
          /* Use two REL relocations for IPLT relocations
2928
             against local symbols.  */
2929
          if (!dynamic_symbol)
2930
            count *= 2;
2931
          break;
2932
        case R_IA64_DTPREL32LSB:
2933
        case R_IA64_TPREL64LSB:
2934
        case R_IA64_DTPREL64LSB:
2935
        case R_IA64_DTPMOD64LSB:
2936
          break;
2937
        default:
2938
          abort ();
2939
        }
2940
      if (rent->reltext)
2941
        ia64_info->reltext = 1;
2942
      rent->srel->size += sizeof (ElfNN_External_Rela) * count;
2943
    }
2944
 
2945
  return TRUE;
2946
}
2947
 
2948
static bfd_boolean
2949
elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2950
                                  struct elf_link_hash_entry *h)
2951
{
2952
  /* ??? Undefined symbols with PLT entries should be re-defined
2953
     to be the PLT entry.  */
2954
 
2955
  /* If this is a weak symbol, and there is a real definition, the
2956
     processor independent code will have arranged for us to see the
2957
     real definition first, and we can just use the same value.  */
2958
  if (h->u.weakdef != NULL)
2959
    {
2960
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2961
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
2962
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
2963
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
2964
      return TRUE;
2965
    }
2966
 
2967
  /* If this is a reference to a symbol defined by a dynamic object which
2968
     is not a function, we might allocate the symbol in our .dynbss section
2969
     and allocate a COPY dynamic relocation.
2970
 
2971
     But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2972
     of hackery.  */
2973
 
2974
  return TRUE;
2975
}
2976
 
2977
static bfd_boolean
2978
elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2979
                                  struct bfd_link_info *info)
2980
{
2981
  struct elfNN_ia64_allocate_data data;
2982
  struct elfNN_ia64_link_hash_table *ia64_info;
2983
  asection *sec;
2984
  bfd *dynobj;
2985
  bfd_boolean relplt = FALSE;
2986
 
2987
  dynobj = elf_hash_table(info)->dynobj;
2988
  ia64_info = elfNN_ia64_hash_table (info);
2989
  if (ia64_info == NULL)
2990
    return FALSE;
2991
  ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2992
  BFD_ASSERT(dynobj != NULL);
2993
  data.info = info;
2994
 
2995
  /* Set the contents of the .interp section to the interpreter.  */
2996
  if (ia64_info->root.dynamic_sections_created
2997
      && info->executable)
2998
    {
2999
      sec = bfd_get_section_by_name (dynobj, ".interp");
3000
      BFD_ASSERT (sec != NULL);
3001
      sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3002
      sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3003
    }
3004
 
3005
  /* Allocate the GOT entries.  */
3006
 
3007
  if (ia64_info->root.sgot)
3008
    {
3009
      data.ofs = 0;
3010
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
3011
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
3012
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
3013
      ia64_info->root.sgot->size = data.ofs;
3014
    }
3015
 
3016
  /* Allocate the FPTR entries.  */
3017
 
3018
  if (ia64_info->fptr_sec)
3019
    {
3020
      data.ofs = 0;
3021
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
3022
      ia64_info->fptr_sec->size = data.ofs;
3023
    }
3024
 
3025
  /* Now that we've seen all of the input files, we can decide which
3026
     symbols need plt entries.  Allocate the minimal PLT entries first.
3027
     We do this even though dynamic_sections_created may be FALSE, because
3028
     this has the side-effect of clearing want_plt and want_plt2.  */
3029
 
3030
  data.ofs = 0;
3031
  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
3032
 
3033
  ia64_info->minplt_entries = 0;
3034
  if (data.ofs)
3035
    {
3036
      ia64_info->minplt_entries
3037
        = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3038
    }
3039
 
3040
  /* Align the pointer for the plt2 entries.  */
3041
  data.ofs = (data.ofs + 31) & (bfd_vma) -32;
3042
 
3043
  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
3044
  if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
3045
    {
3046
      /* FIXME: we always reserve the memory for dynamic linker even if
3047
         there are no PLT entries since dynamic linker may assume the
3048
         reserved memory always exists.  */
3049
 
3050
      BFD_ASSERT (ia64_info->root.dynamic_sections_created);
3051
 
3052
      ia64_info->root.splt->size = data.ofs;
3053
 
3054
      /* If we've got a .plt, we need some extra memory for the dynamic
3055
         linker.  We stuff these in .got.plt.  */
3056
      sec = bfd_get_section_by_name (dynobj, ".got.plt");
3057
      sec->size = 8 * PLT_RESERVED_WORDS;
3058
    }
3059
 
3060
  /* Allocate the PLTOFF entries.  */
3061
 
3062
  if (ia64_info->pltoff_sec)
3063
    {
3064
      data.ofs = 0;
3065
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
3066
      ia64_info->pltoff_sec->size = data.ofs;
3067
    }
3068
 
3069
  if (ia64_info->root.dynamic_sections_created)
3070
    {
3071
      /* Allocate space for the dynamic relocations that turned out to be
3072
         required.  */
3073
 
3074
      if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
3075
        ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
3076
      data.only_got = FALSE;
3077
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
3078
    }
3079
 
3080
  /* We have now determined the sizes of the various dynamic sections.
3081
     Allocate memory for them.  */
3082
  for (sec = dynobj->sections; sec != NULL; sec = sec->next)
3083
    {
3084
      bfd_boolean strip;
3085
 
3086
      if (!(sec->flags & SEC_LINKER_CREATED))
3087
        continue;
3088
 
3089
      /* If we don't need this section, strip it from the output file.
3090
         There were several sections primarily related to dynamic
3091
         linking that must be create before the linker maps input
3092
         sections to output sections.  The linker does that before
3093
         bfd_elf_size_dynamic_sections is called, and it is that
3094
         function which decides whether anything needs to go into
3095
         these sections.  */
3096
 
3097
      strip = (sec->size == 0);
3098
 
3099
      if (sec == ia64_info->root.sgot)
3100
        strip = FALSE;
3101
      else if (sec == ia64_info->root.srelgot)
3102
        {
3103
          if (strip)
3104
            ia64_info->root.srelgot = NULL;
3105
          else
3106
            /* We use the reloc_count field as a counter if we need to
3107
               copy relocs into the output file.  */
3108
            sec->reloc_count = 0;
3109
        }
3110
      else if (sec == ia64_info->fptr_sec)
3111
        {
3112
          if (strip)
3113
            ia64_info->fptr_sec = NULL;
3114
        }
3115
      else if (sec == ia64_info->rel_fptr_sec)
3116
        {
3117
          if (strip)
3118
            ia64_info->rel_fptr_sec = NULL;
3119
          else
3120
            /* We use the reloc_count field as a counter if we need to
3121
               copy relocs into the output file.  */
3122
            sec->reloc_count = 0;
3123
        }
3124
      else if (sec == ia64_info->root.splt)
3125
        {
3126
          if (strip)
3127
            ia64_info->root.splt = NULL;
3128
        }
3129
      else if (sec == ia64_info->pltoff_sec)
3130
        {
3131
          if (strip)
3132
            ia64_info->pltoff_sec = NULL;
3133
        }
3134
      else if (sec == ia64_info->rel_pltoff_sec)
3135
        {
3136
          if (strip)
3137
            ia64_info->rel_pltoff_sec = NULL;
3138
          else
3139
            {
3140
              relplt = TRUE;
3141
              /* We use the reloc_count field as a counter if we need to
3142
                 copy relocs into the output file.  */
3143
              sec->reloc_count = 0;
3144
            }
3145
        }
3146
      else
3147
        {
3148
          const char *name;
3149
 
3150
          /* It's OK to base decisions on the section name, because none
3151
             of the dynobj section names depend upon the input files.  */
3152
          name = bfd_get_section_name (dynobj, sec);
3153
 
3154
          if (strcmp (name, ".got.plt") == 0)
3155
            strip = FALSE;
3156
          else if (CONST_STRNEQ (name, ".rel"))
3157
            {
3158
              if (!strip)
3159
                {
3160
                  /* We use the reloc_count field as a counter if we need to
3161
                     copy relocs into the output file.  */
3162
                  sec->reloc_count = 0;
3163
                }
3164
            }
3165
          else
3166
            continue;
3167
        }
3168
 
3169
      if (strip)
3170
        sec->flags |= SEC_EXCLUDE;
3171
      else
3172
        {
3173
          /* Allocate memory for the section contents.  */
3174
          sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3175
          if (sec->contents == NULL && sec->size != 0)
3176
            return FALSE;
3177
        }
3178
    }
3179
 
3180
  if (elf_hash_table (info)->dynamic_sections_created)
3181
    {
3182
      /* Add some entries to the .dynamic section.  We fill in the values
3183
         later (in finish_dynamic_sections) but we must add the entries now
3184
         so that we get the correct size for the .dynamic section.  */
3185
 
3186
      if (info->executable)
3187
        {
3188
          /* The DT_DEBUG entry is filled in by the dynamic linker and used
3189
             by the debugger.  */
3190
#define add_dynamic_entry(TAG, VAL) \
3191
  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3192
 
3193
          if (!add_dynamic_entry (DT_DEBUG, 0))
3194
            return FALSE;
3195
        }
3196
 
3197
      if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3198
        return FALSE;
3199
      if (!add_dynamic_entry (DT_PLTGOT, 0))
3200
        return FALSE;
3201
 
3202
      if (relplt)
3203
        {
3204
          if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3205
              || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3206
              || !add_dynamic_entry (DT_JMPREL, 0))
3207
            return FALSE;
3208
        }
3209
 
3210
      if (!add_dynamic_entry (DT_RELA, 0)
3211
          || !add_dynamic_entry (DT_RELASZ, 0)
3212
          || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3213
        return FALSE;
3214
 
3215
      if (ia64_info->reltext)
3216
        {
3217
          if (!add_dynamic_entry (DT_TEXTREL, 0))
3218
            return FALSE;
3219
          info->flags |= DF_TEXTREL;
3220
        }
3221
    }
3222
 
3223
  /* ??? Perhaps force __gp local.  */
3224
 
3225
  return TRUE;
3226
}
3227
 
3228
static void
3229
elfNN_ia64_install_dyn_reloc (bfd *abfd, struct bfd_link_info *info,
3230
                              asection *sec, asection *srel,
3231
                              bfd_vma offset, unsigned int type,
3232
                              long dynindx, bfd_vma addend)
3233
{
3234
  Elf_Internal_Rela outrel;
3235
  bfd_byte *loc;
3236
 
3237
  BFD_ASSERT (dynindx != -1);
3238
  outrel.r_info = ELFNN_R_INFO (dynindx, type);
3239
  outrel.r_addend = addend;
3240
  outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3241
  if (outrel.r_offset >= (bfd_vma) -2)
3242
    {
3243
      /* Run for the hills.  We shouldn't be outputting a relocation
3244
         for this.  So do what everyone else does and output a no-op.  */
3245
      outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3246
      outrel.r_addend = 0;
3247
      outrel.r_offset = 0;
3248
    }
3249
  else
3250
    outrel.r_offset += sec->output_section->vma + sec->output_offset;
3251
 
3252
  loc = srel->contents;
3253
  loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3254
  bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3255
  BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
3256
}
3257
 
3258
/* Store an entry for target address TARGET_ADDR in the linkage table
3259
   and return the gp-relative address of the linkage table entry.  */
3260
 
3261
static bfd_vma
3262
set_got_entry (bfd *abfd, struct bfd_link_info *info,
3263
               struct elfNN_ia64_dyn_sym_info *dyn_i,
3264
               long dynindx, bfd_vma addend, bfd_vma value,
3265
               unsigned int dyn_r_type)
3266
{
3267
  struct elfNN_ia64_link_hash_table *ia64_info;
3268
  asection *got_sec;
3269
  bfd_boolean done;
3270
  bfd_vma got_offset;
3271
 
3272
  ia64_info = elfNN_ia64_hash_table (info);
3273
  if (ia64_info == NULL)
3274
    return 0;
3275
 
3276
  got_sec = ia64_info->root.sgot;
3277
 
3278
  switch (dyn_r_type)
3279
    {
3280
    case R_IA64_TPREL64LSB:
3281
      done = dyn_i->tprel_done;
3282
      dyn_i->tprel_done = TRUE;
3283
      got_offset = dyn_i->tprel_offset;
3284
      break;
3285
    case R_IA64_DTPMOD64LSB:
3286
      if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3287
        {
3288
          done = dyn_i->dtpmod_done;
3289
          dyn_i->dtpmod_done = TRUE;
3290
        }
3291
      else
3292
        {
3293
          done = ia64_info->self_dtpmod_done;
3294
          ia64_info->self_dtpmod_done = TRUE;
3295
          dynindx = 0;
3296
        }
3297
      got_offset = dyn_i->dtpmod_offset;
3298
      break;
3299
    case R_IA64_DTPREL32LSB:
3300
    case R_IA64_DTPREL64LSB:
3301
      done = dyn_i->dtprel_done;
3302
      dyn_i->dtprel_done = TRUE;
3303
      got_offset = dyn_i->dtprel_offset;
3304
      break;
3305
    default:
3306
      done = dyn_i->got_done;
3307
      dyn_i->got_done = TRUE;
3308
      got_offset = dyn_i->got_offset;
3309
      break;
3310
    }
3311
 
3312
  BFD_ASSERT ((got_offset & 7) == 0);
3313
 
3314
  if (! done)
3315
    {
3316
      /* Store the target address in the linkage table entry.  */
3317
      bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3318
 
3319
      /* Install a dynamic relocation if needed.  */
3320
      if (((info->shared
3321
            && (!dyn_i->h
3322
                || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3323
                || dyn_i->h->root.type != bfd_link_hash_undefweak)
3324
            && dyn_r_type != R_IA64_DTPREL32LSB
3325
            && dyn_r_type != R_IA64_DTPREL64LSB)
3326
           || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
3327
           || (dynindx != -1
3328
               && (dyn_r_type == R_IA64_FPTR32LSB
3329
                   || dyn_r_type == R_IA64_FPTR64LSB)))
3330
          && (!dyn_i->want_ltoff_fptr
3331
              || !info->pie
3332
              || !dyn_i->h
3333
              || dyn_i->h->root.type != bfd_link_hash_undefweak))
3334
        {
3335
          if (dynindx == -1
3336
              && dyn_r_type != R_IA64_TPREL64LSB
3337
              && dyn_r_type != R_IA64_DTPMOD64LSB
3338
              && dyn_r_type != R_IA64_DTPREL32LSB
3339
              && dyn_r_type != R_IA64_DTPREL64LSB)
3340
            {
3341
              dyn_r_type = R_IA64_RELNNLSB;
3342
              dynindx = 0;
3343
              addend = value;
3344
            }
3345
 
3346
          if (bfd_big_endian (abfd))
3347
            {
3348
              switch (dyn_r_type)
3349
                {
3350
                case R_IA64_REL32LSB:
3351
                  dyn_r_type = R_IA64_REL32MSB;
3352
                  break;
3353
                case R_IA64_DIR32LSB:
3354
                  dyn_r_type = R_IA64_DIR32MSB;
3355
                  break;
3356
                case R_IA64_FPTR32LSB:
3357
                  dyn_r_type = R_IA64_FPTR32MSB;
3358
                  break;
3359
                case R_IA64_DTPREL32LSB:
3360
                  dyn_r_type = R_IA64_DTPREL32MSB;
3361
                  break;
3362
                case R_IA64_REL64LSB:
3363
                  dyn_r_type = R_IA64_REL64MSB;
3364
                  break;
3365
                case R_IA64_DIR64LSB:
3366
                  dyn_r_type = R_IA64_DIR64MSB;
3367
                  break;
3368
                case R_IA64_FPTR64LSB:
3369
                  dyn_r_type = R_IA64_FPTR64MSB;
3370
                  break;
3371
                case R_IA64_TPREL64LSB:
3372
                  dyn_r_type = R_IA64_TPREL64MSB;
3373
                  break;
3374
                case R_IA64_DTPMOD64LSB:
3375
                  dyn_r_type = R_IA64_DTPMOD64MSB;
3376
                  break;
3377
                case R_IA64_DTPREL64LSB:
3378
                  dyn_r_type = R_IA64_DTPREL64MSB;
3379
                  break;
3380
                default:
3381
                  BFD_ASSERT (FALSE);
3382
                  break;
3383
                }
3384
            }
3385
 
3386
          elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3387
                                        ia64_info->root.srelgot,
3388
                                        got_offset, dyn_r_type,
3389
                                        dynindx, addend);
3390
        }
3391
    }
3392
 
3393
  /* Return the address of the linkage table entry.  */
3394
  value = (got_sec->output_section->vma
3395
           + got_sec->output_offset
3396
           + got_offset);
3397
 
3398
  return value;
3399
}
3400
 
3401
/* Fill in a function descriptor consisting of the function's code
3402
   address and its global pointer.  Return the descriptor's address.  */
3403
 
3404
static bfd_vma
3405
set_fptr_entry (bfd *abfd, struct bfd_link_info *info,
3406
                struct elfNN_ia64_dyn_sym_info *dyn_i,
3407
                bfd_vma value)
3408
{
3409
  struct elfNN_ia64_link_hash_table *ia64_info;
3410
  asection *fptr_sec;
3411
 
3412
  ia64_info = elfNN_ia64_hash_table (info);
3413
  if (ia64_info == NULL)
3414
    return 0;
3415
 
3416
  fptr_sec = ia64_info->fptr_sec;
3417
 
3418
  if (!dyn_i->fptr_done)
3419
    {
3420
      dyn_i->fptr_done = 1;
3421
 
3422
      /* Fill in the function descriptor.  */
3423
      bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3424
      bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3425
                  fptr_sec->contents + dyn_i->fptr_offset + 8);
3426
      if (ia64_info->rel_fptr_sec)
3427
        {
3428
          Elf_Internal_Rela outrel;
3429
          bfd_byte *loc;
3430
 
3431
          if (bfd_little_endian (abfd))
3432
            outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
3433
          else
3434
            outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
3435
          outrel.r_addend = value;
3436
          outrel.r_offset = (fptr_sec->output_section->vma
3437
                             + fptr_sec->output_offset
3438
                             + dyn_i->fptr_offset);
3439
          loc = ia64_info->rel_fptr_sec->contents;
3440
          loc += ia64_info->rel_fptr_sec->reloc_count++
3441
                 * sizeof (ElfNN_External_Rela);
3442
          bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3443
        }
3444
    }
3445
 
3446
  /* Return the descriptor's address.  */
3447
  value = (fptr_sec->output_section->vma
3448
           + fptr_sec->output_offset
3449
           + dyn_i->fptr_offset);
3450
 
3451
  return value;
3452
}
3453
 
3454
/* Fill in a PLTOFF entry consisting of the function's code address
3455
   and its global pointer.  Return the descriptor's address.  */
3456
 
3457
static bfd_vma
3458
set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
3459
                  struct elfNN_ia64_dyn_sym_info *dyn_i,
3460
                  bfd_vma value, bfd_boolean is_plt)
3461
{
3462
  struct elfNN_ia64_link_hash_table *ia64_info;
3463
  asection *pltoff_sec;
3464
 
3465
  ia64_info = elfNN_ia64_hash_table (info);
3466
  if (ia64_info == NULL)
3467
    return 0;
3468
 
3469
  pltoff_sec = ia64_info->pltoff_sec;
3470
 
3471
  /* Don't do anything if this symbol uses a real PLT entry.  In
3472
     that case, we'll fill this in during finish_dynamic_symbol.  */
3473
  if ((! dyn_i->want_plt || is_plt)
3474
      && !dyn_i->pltoff_done)
3475
    {
3476
      bfd_vma gp = _bfd_get_gp_value (abfd);
3477
 
3478
      /* Fill in the function descriptor.  */
3479
      bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3480
      bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3481
 
3482
      /* Install dynamic relocations if needed.  */
3483
      if (!is_plt
3484
          && info->shared
3485
          && (!dyn_i->h
3486
              || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3487
              || dyn_i->h->root.type != bfd_link_hash_undefweak))
3488
        {
3489
          unsigned int dyn_r_type;
3490
 
3491
          if (bfd_big_endian (abfd))
3492
            dyn_r_type = R_IA64_RELNNMSB;
3493
          else
3494
            dyn_r_type = R_IA64_RELNNLSB;
3495
 
3496
          elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3497
                                        ia64_info->rel_pltoff_sec,
3498
                                        dyn_i->pltoff_offset,
3499
                                        dyn_r_type, 0, value);
3500
          elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3501
                                        ia64_info->rel_pltoff_sec,
3502
                                        dyn_i->pltoff_offset + ARCH_SIZE / 8,
3503
                                        dyn_r_type, 0, gp);
3504
        }
3505
 
3506
      dyn_i->pltoff_done = 1;
3507
    }
3508
 
3509
  /* Return the descriptor's address.  */
3510
  value = (pltoff_sec->output_section->vma
3511
           + pltoff_sec->output_offset
3512
           + dyn_i->pltoff_offset);
3513
 
3514
  return value;
3515
}
3516
 
3517
/* Return the base VMA address which should be subtracted from real addresses
3518
   when resolving @tprel() relocation.
3519
   Main program TLS (whose template starts at PT_TLS p_vaddr)
3520
   is assigned offset round(2 * size of pointer, PT_TLS p_align).  */
3521
 
3522
static bfd_vma
3523
elfNN_ia64_tprel_base (struct bfd_link_info *info)
3524
{
3525
  asection *tls_sec = elf_hash_table (info)->tls_sec;
3526
  return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
3527
                                     tls_sec->alignment_power);
3528
}
3529
 
3530
/* Return the base VMA address which should be subtracted from real addresses
3531
   when resolving @dtprel() relocation.
3532
   This is PT_TLS segment p_vaddr.  */
3533
 
3534
static bfd_vma
3535
elfNN_ia64_dtprel_base (struct bfd_link_info *info)
3536
{
3537
  return elf_hash_table (info)->tls_sec->vma;
3538
}
3539
 
3540
/* Called through qsort to sort the .IA_64.unwind section during a
3541
   non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
3542
   to the output bfd so we can do proper endianness frobbing.  */
3543
 
3544
static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3545
 
3546
static int
3547
elfNN_ia64_unwind_entry_compare (const PTR a, const PTR b)
3548
{
3549
  bfd_vma av, bv;
3550
 
3551
  av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3552
  bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3553
 
3554
  return (av < bv ? -1 : av > bv ? 1 : 0);
3555
}
3556
 
3557
/* Make sure we've got ourselves a nice fat __gp value.  */
3558
static bfd_boolean
3559
elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
3560
{
3561
  bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3562
  bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3563
  struct elf_link_hash_entry *gp;
3564
  bfd_vma gp_val;
3565
  asection *os;
3566
  struct elfNN_ia64_link_hash_table *ia64_info;
3567
 
3568
  ia64_info = elfNN_ia64_hash_table (info);
3569
  if (ia64_info == NULL)
3570
    return FALSE;
3571
 
3572
  /* Find the min and max vma of all sections marked short.  Also collect
3573
     min and max vma of any type, for use in selecting a nice gp.  */
3574
  for (os = abfd->sections; os ; os = os->next)
3575
    {
3576
      bfd_vma lo, hi;
3577
 
3578
      if ((os->flags & SEC_ALLOC) == 0)
3579
        continue;
3580
 
3581
      lo = os->vma;
3582
      /* When this function is called from elfNN_ia64_final_link
3583
         the correct value to use is os->size.  When called from
3584
         elfNN_ia64_relax_section we are in the middle of section
3585
         sizing; some sections will already have os->size set, others
3586
         will have os->size zero and os->rawsize the previous size.  */
3587
      hi = os->vma + (!final && os->rawsize ? os->rawsize : os->size);
3588
      if (hi < lo)
3589
        hi = (bfd_vma) -1;
3590
 
3591
      if (min_vma > lo)
3592
        min_vma = lo;
3593
      if (max_vma < hi)
3594
        max_vma = hi;
3595
      if (os->flags & SEC_SMALL_DATA)
3596
        {
3597
          if (min_short_vma > lo)
3598
            min_short_vma = lo;
3599
          if (max_short_vma < hi)
3600
            max_short_vma = hi;
3601
        }
3602
    }
3603
 
3604
  if (ia64_info->min_short_sec)
3605
    {
3606 148 khays
      if (min_short_vma
3607 14 khays
          > (ia64_info->min_short_sec->vma
3608
             + ia64_info->min_short_offset))
3609
        min_short_vma = (ia64_info->min_short_sec->vma
3610
                         + ia64_info->min_short_offset);
3611
      if (max_short_vma
3612
          < (ia64_info->max_short_sec->vma
3613
             + ia64_info->max_short_offset))
3614
        max_short_vma = (ia64_info->max_short_sec->vma
3615
                         + ia64_info->max_short_offset);
3616
    }
3617
 
3618
  /* See if the user wants to force a value.  */
3619
  gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3620
                             FALSE, FALSE);
3621
 
3622
  if (gp
3623
      && (gp->root.type == bfd_link_hash_defined
3624
          || gp->root.type == bfd_link_hash_defweak))
3625
    {
3626
      asection *gp_sec = gp->root.u.def.section;
3627
      gp_val = (gp->root.u.def.value
3628
                + gp_sec->output_section->vma
3629
                + gp_sec->output_offset);
3630
    }
3631
  else
3632
    {
3633
      /* Pick a sensible value.  */
3634
 
3635
      if (ia64_info->min_short_sec)
3636
        {
3637
          bfd_vma short_range = max_short_vma - min_short_vma;
3638
 
3639
          /* If min_short_sec is set, pick one in the middle bewteen
3640
             min_short_vma and max_short_vma.  */
3641
          if (short_range >= 0x400000)
3642
            goto overflow;
3643
          gp_val = min_short_vma + short_range / 2;
3644
        }
3645
      else
3646
        {
3647
          asection *got_sec = ia64_info->root.sgot;
3648
 
3649
          /* Start with just the address of the .got.  */
3650
          if (got_sec)
3651
            gp_val = got_sec->output_section->vma;
3652
          else if (max_short_vma != 0)
3653
            gp_val = min_short_vma;
3654
          else if (max_vma - min_vma < 0x200000)
3655
            gp_val = min_vma;
3656
          else
3657
            gp_val = max_vma - 0x200000 + 8;
3658
        }
3659
 
3660
      /* If it is possible to address the entire image, but we
3661
         don't with the choice above, adjust.  */
3662
      if (max_vma - min_vma < 0x400000
3663
          && (max_vma - gp_val >= 0x200000
3664
              || gp_val - min_vma > 0x200000))
3665
        gp_val = min_vma + 0x200000;
3666
      else if (max_short_vma != 0)
3667
        {
3668
          /* If we don't cover all the short data, adjust.  */
3669
          if (max_short_vma - gp_val >= 0x200000)
3670
            gp_val = min_short_vma + 0x200000;
3671
 
3672
          /* If we're addressing stuff past the end, adjust back.  */
3673
          if (gp_val > max_vma)
3674
            gp_val = max_vma - 0x200000 + 8;
3675
        }
3676
    }
3677
 
3678
  /* Validate whether all SHF_IA_64_SHORT sections are within
3679
     range of the chosen GP.  */
3680
 
3681
  if (max_short_vma != 0)
3682
    {
3683
      if (max_short_vma - min_short_vma >= 0x400000)
3684
        {
3685
overflow:
3686
          (*_bfd_error_handler)
3687
            (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3688
             bfd_get_filename (abfd),
3689
             (unsigned long) (max_short_vma - min_short_vma));
3690
          return FALSE;
3691
        }
3692
      else if ((gp_val > min_short_vma
3693
                && gp_val - min_short_vma > 0x200000)
3694
               || (gp_val < max_short_vma
3695
                   && max_short_vma - gp_val >= 0x200000))
3696
        {
3697
          (*_bfd_error_handler)
3698
            (_("%s: __gp does not cover short data segment"),
3699
             bfd_get_filename (abfd));
3700
          return FALSE;
3701
        }
3702
    }
3703
 
3704
  _bfd_set_gp_value (abfd, gp_val);
3705
 
3706
  return TRUE;
3707
}
3708
 
3709
static bfd_boolean
3710
elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
3711
{
3712
  struct elfNN_ia64_link_hash_table *ia64_info;
3713
  asection *unwind_output_sec;
3714
 
3715
  ia64_info = elfNN_ia64_hash_table (info);
3716
  if (ia64_info == NULL)
3717
    return FALSE;
3718
 
3719
  /* Make sure we've got ourselves a nice fat __gp value.  */
3720
  if (!info->relocatable)
3721
    {
3722
      bfd_vma gp_val;
3723
      struct elf_link_hash_entry *gp;
3724
 
3725
      /* We assume after gp is set, section size will only decrease. We
3726
         need to adjust gp for it.  */
3727
      _bfd_set_gp_value (abfd, 0);
3728
      if (! elfNN_ia64_choose_gp (abfd, info, TRUE))
3729
        return FALSE;
3730
      gp_val = _bfd_get_gp_value (abfd);
3731
 
3732
      gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3733
                                 FALSE, FALSE);
3734
      if (gp)
3735
        {
3736
          gp->root.type = bfd_link_hash_defined;
3737
          gp->root.u.def.value = gp_val;
3738
          gp->root.u.def.section = bfd_abs_section_ptr;
3739
        }
3740
    }
3741
 
3742
  /* If we're producing a final executable, we need to sort the contents
3743
     of the .IA_64.unwind section.  Force this section to be relocated
3744
     into memory rather than written immediately to the output file.  */
3745
  unwind_output_sec = NULL;
3746
  if (!info->relocatable)
3747
    {
3748
      asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3749
      if (s)
3750
        {
3751
          unwind_output_sec = s->output_section;
3752
          unwind_output_sec->contents
3753
            = bfd_malloc (unwind_output_sec->size);
3754
          if (unwind_output_sec->contents == NULL)
3755
            return FALSE;
3756
        }
3757
    }
3758
 
3759
  /* Invoke the regular ELF backend linker to do all the work.  */
3760
  if (!bfd_elf_final_link (abfd, info))
3761
    return FALSE;
3762
 
3763
  if (unwind_output_sec)
3764
    {
3765
      elfNN_ia64_unwind_entry_compare_bfd = abfd;
3766
      qsort (unwind_output_sec->contents,
3767
             (size_t) (unwind_output_sec->size / 24),
3768
             24,
3769
             elfNN_ia64_unwind_entry_compare);
3770
 
3771
      if (! bfd_set_section_contents (abfd, unwind_output_sec,
3772
                                      unwind_output_sec->contents, (bfd_vma) 0,
3773
                                      unwind_output_sec->size))
3774
        return FALSE;
3775
    }
3776
 
3777
  return TRUE;
3778
}
3779
 
3780
static bfd_boolean
3781
elfNN_ia64_relocate_section (bfd *output_bfd,
3782
                             struct bfd_link_info *info,
3783
                             bfd *input_bfd,
3784
                             asection *input_section,
3785
                             bfd_byte *contents,
3786
                             Elf_Internal_Rela *relocs,
3787
                             Elf_Internal_Sym *local_syms,
3788
                             asection **local_sections)
3789
{
3790
  struct elfNN_ia64_link_hash_table *ia64_info;
3791
  Elf_Internal_Shdr *symtab_hdr;
3792
  Elf_Internal_Rela *rel;
3793
  Elf_Internal_Rela *relend;
3794
  asection *srel;
3795
  bfd_boolean ret_val = TRUE;   /* for non-fatal errors */
3796
  bfd_vma gp_val;
3797
 
3798
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3799
  ia64_info = elfNN_ia64_hash_table (info);
3800
  if (ia64_info == NULL)
3801
    return FALSE;
3802
 
3803
  /* Infect various flags from the input section to the output section.  */
3804
  if (info->relocatable)
3805
    {
3806
      bfd_vma flags;
3807
 
3808
      flags = elf_section_data(input_section)->this_hdr.sh_flags;
3809
      flags &= SHF_IA_64_NORECOV;
3810
 
3811
      elf_section_data(input_section->output_section)
3812
        ->this_hdr.sh_flags |= flags;
3813
    }
3814
 
3815
  gp_val = _bfd_get_gp_value (output_bfd);
3816
  srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3817
 
3818
  rel = relocs;
3819
  relend = relocs + input_section->reloc_count;
3820
  for (; rel < relend; ++rel)
3821
    {
3822
      struct elf_link_hash_entry *h;
3823
      struct elfNN_ia64_dyn_sym_info *dyn_i;
3824
      bfd_reloc_status_type r;
3825
      reloc_howto_type *howto;
3826
      unsigned long r_symndx;
3827
      Elf_Internal_Sym *sym;
3828
      unsigned int r_type;
3829
      bfd_vma value;
3830
      asection *sym_sec;
3831
      bfd_byte *hit_addr;
3832
      bfd_boolean dynamic_symbol_p;
3833
      bfd_boolean undef_weak_ref;
3834
 
3835
      r_type = ELFNN_R_TYPE (rel->r_info);
3836
      if (r_type > R_IA64_MAX_RELOC_CODE)
3837
        {
3838
          (*_bfd_error_handler)
3839
            (_("%B: unknown relocation type %d"),
3840
             input_bfd, (int) r_type);
3841
          bfd_set_error (bfd_error_bad_value);
3842
          ret_val = FALSE;
3843
          continue;
3844
        }
3845
 
3846
      howto = ia64_elf_lookup_howto (r_type);
3847
      r_symndx = ELFNN_R_SYM (rel->r_info);
3848
      h = NULL;
3849
      sym = NULL;
3850
      sym_sec = NULL;
3851
      undef_weak_ref = FALSE;
3852
 
3853
      if (r_symndx < symtab_hdr->sh_info)
3854
        {
3855
          /* Reloc against local symbol.  */
3856
          asection *msec;
3857
          sym = local_syms + r_symndx;
3858
          sym_sec = local_sections[r_symndx];
3859
          msec = sym_sec;
3860
          value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
3861
          if (!info->relocatable
3862
              && (sym_sec->flags & SEC_MERGE) != 0
3863
              && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3864
              && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
3865 148 khays
            {
3866 14 khays
              struct elfNN_ia64_local_hash_entry *loc_h;
3867
 
3868
              loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3869
              if (loc_h && ! loc_h->sec_merge_done)
3870
                {
3871
                  struct elfNN_ia64_dyn_sym_info *dynent;
3872
                  unsigned int count;
3873
 
3874
                  for (count = loc_h->count, dynent = loc_h->info;
3875
                       count != 0;
3876
                       count--, dynent++)
3877
                    {
3878
                      msec = sym_sec;
3879
                      dynent->addend =
3880
                        _bfd_merged_section_offset (output_bfd, &msec,
3881
                                                    elf_section_data (msec)->
3882
                                                    sec_info,
3883
                                                    sym->st_value
3884
                                                    + dynent->addend);
3885
                      dynent->addend -= sym->st_value;
3886
                      dynent->addend += msec->output_section->vma
3887
                                        + msec->output_offset
3888
                                        - sym_sec->output_section->vma
3889
                                        - sym_sec->output_offset;
3890
                    }
3891
 
3892
                  /* We may have introduced duplicated entries. We need
3893
                     to remove them properly.  */
3894
                  count = sort_dyn_sym_info (loc_h->info, loc_h->count);
3895
                  if (count != loc_h->count)
3896
                    {
3897
                      loc_h->count = count;
3898
                      loc_h->sorted_count = count;
3899
                    }
3900
 
3901
                  loc_h->sec_merge_done = 1;
3902
                }
3903
            }
3904
        }
3905
      else
3906
        {
3907
          bfd_boolean unresolved_reloc;
3908
          bfd_boolean warned;
3909
          struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
3910
 
3911
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3912
                                   r_symndx, symtab_hdr, sym_hashes,
3913
                                   h, sym_sec, value,
3914
                                   unresolved_reloc, warned);
3915
 
3916
          if (h->root.type == bfd_link_hash_undefweak)
3917
            undef_weak_ref = TRUE;
3918
          else if (warned)
3919
            continue;
3920
        }
3921
 
3922
      if (sym_sec != NULL && elf_discarded_section (sym_sec))
3923
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
3924
                                         rel, relend, howto, contents);
3925
 
3926
      if (info->relocatable)
3927
        continue;
3928
 
3929
      hit_addr = contents + rel->r_offset;
3930
      value += rel->r_addend;
3931
      dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
3932
 
3933
      switch (r_type)
3934
        {
3935
        case R_IA64_NONE:
3936
        case R_IA64_LDXMOV:
3937
          continue;
3938
 
3939
        case R_IA64_IMM14:
3940
        case R_IA64_IMM22:
3941
        case R_IA64_IMM64:
3942
        case R_IA64_DIR32MSB:
3943
        case R_IA64_DIR32LSB:
3944
        case R_IA64_DIR64MSB:
3945
        case R_IA64_DIR64LSB:
3946
          /* Install a dynamic relocation for this reloc.  */
3947
          if ((dynamic_symbol_p || info->shared)
3948
              && r_symndx != STN_UNDEF
3949
              && (input_section->flags & SEC_ALLOC) != 0)
3950
            {
3951
              unsigned int dyn_r_type;
3952
              long dynindx;
3953
              bfd_vma addend;
3954
 
3955
              BFD_ASSERT (srel != NULL);
3956
 
3957
              switch (r_type)
3958
                {
3959
                case R_IA64_IMM14:
3960
                case R_IA64_IMM22:
3961
                case R_IA64_IMM64:
3962
                  /* ??? People shouldn't be doing non-pic code in
3963
                     shared libraries nor dynamic executables.  */
3964
                  (*_bfd_error_handler)
3965
                    (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
3966
                     input_bfd,
3967
                     h ? h->root.root.string
3968
                       : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
3969
                                           sym_sec));
3970
                  ret_val = FALSE;
3971
                  continue;
3972
 
3973
                default:
3974
                  break;
3975
                }
3976
 
3977
              /* If we don't need dynamic symbol lookup, find a
3978
                 matching RELATIVE relocation.  */
3979
              dyn_r_type = r_type;
3980
              if (dynamic_symbol_p)
3981
                {
3982
                  dynindx = h->dynindx;
3983
                  addend = rel->r_addend;
3984
                  value = 0;
3985
                }
3986
              else
3987
                {
3988
                  switch (r_type)
3989
                    {
3990
                    case R_IA64_DIR32MSB:
3991
                      dyn_r_type = R_IA64_REL32MSB;
3992
                      break;
3993
                    case R_IA64_DIR32LSB:
3994
                      dyn_r_type = R_IA64_REL32LSB;
3995
                      break;
3996
                    case R_IA64_DIR64MSB:
3997
                      dyn_r_type = R_IA64_REL64MSB;
3998
                      break;
3999
                    case R_IA64_DIR64LSB:
4000
                      dyn_r_type = R_IA64_REL64LSB;
4001
                      break;
4002
 
4003
                    default:
4004
                      break;
4005
                    }
4006
                  dynindx = 0;
4007
                  addend = value;
4008
                }
4009
 
4010
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4011
                                            srel, rel->r_offset, dyn_r_type,
4012
                                            dynindx, addend);
4013
            }
4014
          /* Fall through.  */
4015
 
4016
        case R_IA64_LTV32MSB:
4017
        case R_IA64_LTV32LSB:
4018
        case R_IA64_LTV64MSB:
4019
        case R_IA64_LTV64LSB:
4020
          r = ia64_elf_install_value (hit_addr, value, r_type);
4021
          break;
4022
 
4023
        case R_IA64_GPREL22:
4024
        case R_IA64_GPREL64I:
4025
        case R_IA64_GPREL32MSB:
4026
        case R_IA64_GPREL32LSB:
4027
        case R_IA64_GPREL64MSB:
4028
        case R_IA64_GPREL64LSB:
4029
          if (dynamic_symbol_p)
4030
            {
4031
              (*_bfd_error_handler)
4032
                (_("%B: @gprel relocation against dynamic symbol %s"),
4033
                 input_bfd,
4034
                 h ? h->root.root.string
4035
                   : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4036
                                       sym_sec));
4037
              ret_val = FALSE;
4038
              continue;
4039
            }
4040
          value -= gp_val;
4041
          r = ia64_elf_install_value (hit_addr, value, r_type);
4042
          break;
4043
 
4044
        case R_IA64_LTOFF22:
4045
        case R_IA64_LTOFF22X:
4046
        case R_IA64_LTOFF64I:
4047
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4048
          value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4049
                                 rel->r_addend, value, R_IA64_DIRNNLSB);
4050
          value -= gp_val;
4051
          r = ia64_elf_install_value (hit_addr, value, r_type);
4052
          break;
4053
 
4054
        case R_IA64_PLTOFF22:
4055
        case R_IA64_PLTOFF64I:
4056
        case R_IA64_PLTOFF64MSB:
4057
        case R_IA64_PLTOFF64LSB:
4058
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4059
          value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4060
          value -= gp_val;
4061
          r = ia64_elf_install_value (hit_addr, value, r_type);
4062
          break;
4063
 
4064
        case R_IA64_FPTR64I:
4065
        case R_IA64_FPTR32MSB:
4066
        case R_IA64_FPTR32LSB:
4067
        case R_IA64_FPTR64MSB:
4068
        case R_IA64_FPTR64LSB:
4069
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4070
          if (dyn_i->want_fptr)
4071
            {
4072
              if (!undef_weak_ref)
4073
                value = set_fptr_entry (output_bfd, info, dyn_i, value);
4074
            }
4075
          if (!dyn_i->want_fptr || info->pie)
4076
            {
4077
              long dynindx;
4078
              unsigned int dyn_r_type = r_type;
4079
              bfd_vma addend = rel->r_addend;
4080
 
4081
              /* Otherwise, we expect the dynamic linker to create
4082
                 the entry.  */
4083
 
4084
              if (dyn_i->want_fptr)
4085
                {
4086
                  if (r_type == R_IA64_FPTR64I)
4087
                    {
4088
                      /* We can't represent this without a dynamic symbol.
4089
                         Adjust the relocation to be against an output
4090
                         section symbol, which are always present in the
4091
                         dynamic symbol table.  */
4092
                      /* ??? People shouldn't be doing non-pic code in
4093
                         shared libraries.  Hork.  */
4094
                      (*_bfd_error_handler)
4095
                        (_("%B: linking non-pic code in a position independent executable"),
4096
                         input_bfd);
4097
                      ret_val = FALSE;
4098
                      continue;
4099
                    }
4100
                  dynindx = 0;
4101
                  addend = value;
4102
                  dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4103
                }
4104
              else if (h)
4105
                {
4106
                  if (h->dynindx != -1)
4107
                    dynindx = h->dynindx;
4108
                  else
4109
                    dynindx = (_bfd_elf_link_lookup_local_dynindx
4110
                               (info, h->root.u.def.section->owner,
4111
                                global_sym_index (h)));
4112
                  value = 0;
4113
                }
4114
              else
4115
                {
4116
                  dynindx = (_bfd_elf_link_lookup_local_dynindx
4117
                             (info, input_bfd, (long) r_symndx));
4118
                  value = 0;
4119
                }
4120
 
4121
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4122
                                            srel, rel->r_offset, dyn_r_type,
4123
                                            dynindx, addend);
4124
            }
4125
 
4126
          r = ia64_elf_install_value (hit_addr, value, r_type);
4127
          break;
4128
 
4129
        case R_IA64_LTOFF_FPTR22:
4130
        case R_IA64_LTOFF_FPTR64I:
4131
        case R_IA64_LTOFF_FPTR32MSB:
4132
        case R_IA64_LTOFF_FPTR32LSB:
4133
        case R_IA64_LTOFF_FPTR64MSB:
4134
        case R_IA64_LTOFF_FPTR64LSB:
4135
          {
4136
            long dynindx;
4137
 
4138
            dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4139
            if (dyn_i->want_fptr)
4140
              {
4141
                BFD_ASSERT (h == NULL || h->dynindx == -1);
4142
                if (!undef_weak_ref)
4143
                  value = set_fptr_entry (output_bfd, info, dyn_i, value);
4144
                dynindx = -1;
4145
              }
4146
            else
4147
              {
4148
                /* Otherwise, we expect the dynamic linker to create
4149
                   the entry.  */
4150
                if (h)
4151
                  {
4152
                    if (h->dynindx != -1)
4153
                      dynindx = h->dynindx;
4154
                    else
4155
                      dynindx = (_bfd_elf_link_lookup_local_dynindx
4156
                                 (info, h->root.u.def.section->owner,
4157
                                  global_sym_index (h)));
4158
                  }
4159
                else
4160
                  dynindx = (_bfd_elf_link_lookup_local_dynindx
4161
                             (info, input_bfd, (long) r_symndx));
4162
                value = 0;
4163
              }
4164
 
4165
            value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4166
                                   rel->r_addend, value, R_IA64_FPTRNNLSB);
4167
            value -= gp_val;
4168
            r = ia64_elf_install_value (hit_addr, value, r_type);
4169
          }
4170
          break;
4171
 
4172
        case R_IA64_PCREL32MSB:
4173
        case R_IA64_PCREL32LSB:
4174
        case R_IA64_PCREL64MSB:
4175
        case R_IA64_PCREL64LSB:
4176
          /* Install a dynamic relocation for this reloc.  */
4177
          if (dynamic_symbol_p && r_symndx != STN_UNDEF)
4178
            {
4179
              BFD_ASSERT (srel != NULL);
4180
 
4181
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4182
                                            srel, rel->r_offset, r_type,
4183
                                            h->dynindx, rel->r_addend);
4184
            }
4185
          goto finish_pcrel;
4186
 
4187
        case R_IA64_PCREL21B:
4188
        case R_IA64_PCREL60B:
4189
          /* We should have created a PLT entry for any dynamic symbol.  */
4190
          dyn_i = NULL;
4191
          if (h)
4192
            dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4193
 
4194
          if (dyn_i && dyn_i->want_plt2)
4195
            {
4196
              /* Should have caught this earlier.  */
4197
              BFD_ASSERT (rel->r_addend == 0);
4198
 
4199
              value = (ia64_info->root.splt->output_section->vma
4200
                       + ia64_info->root.splt->output_offset
4201
                       + dyn_i->plt2_offset);
4202
            }
4203
          else
4204
            {
4205
              /* Since there's no PLT entry, Validate that this is
4206
                 locally defined.  */
4207
              BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4208
 
4209
              /* If the symbol is undef_weak, we shouldn't be trying
4210
                 to call it.  There's every chance that we'd wind up
4211
                 with an out-of-range fixup here.  Don't bother setting
4212
                 any value at all.  */
4213
              if (undef_weak_ref)
4214
                continue;
4215
            }
4216
          goto finish_pcrel;
4217
 
4218
        case R_IA64_PCREL21BI:
4219
        case R_IA64_PCREL21F:
4220
        case R_IA64_PCREL21M:
4221
        case R_IA64_PCREL22:
4222
        case R_IA64_PCREL64I:
4223
          /* The PCREL21BI reloc is specifically not intended for use with
4224
             dynamic relocs.  PCREL21F and PCREL21M are used for speculation
4225
             fixup code, and thus probably ought not be dynamic.  The
4226
             PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs.  */
4227
          if (dynamic_symbol_p)
4228
            {
4229
              const char *msg;
4230
 
4231
              if (r_type == R_IA64_PCREL21BI)
4232
                msg = _("%B: @internal branch to dynamic symbol %s");
4233
              else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4234
                msg = _("%B: speculation fixup to dynamic symbol %s");
4235
              else
4236
                msg = _("%B: @pcrel relocation against dynamic symbol %s");
4237
              (*_bfd_error_handler) (msg, input_bfd,
4238
                                     h ? h->root.root.string
4239
                                       : bfd_elf_sym_name (input_bfd,
4240
                                                           symtab_hdr,
4241
                                                           sym,
4242
                                                           sym_sec));
4243
              ret_val = FALSE;
4244
              continue;
4245
            }
4246
          goto finish_pcrel;
4247
 
4248
        finish_pcrel:
4249
          /* Make pc-relative.  */
4250
          value -= (input_section->output_section->vma
4251
                    + input_section->output_offset
4252
                    + rel->r_offset) & ~ (bfd_vma) 0x3;
4253
          r = ia64_elf_install_value (hit_addr, value, r_type);
4254
          break;
4255
 
4256
        case R_IA64_SEGREL32MSB:
4257
        case R_IA64_SEGREL32LSB:
4258
        case R_IA64_SEGREL64MSB:
4259
        case R_IA64_SEGREL64LSB:
4260
            {
4261
              /* Find the segment that contains the output_section.  */
4262
              Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
4263
                (output_bfd, input_section->output_section);
4264
 
4265
              if (p == NULL)
4266
                {
4267
                  r = bfd_reloc_notsupported;
4268
                }
4269
              else
4270
                {
4271
                  /* The VMA of the segment is the vaddr of the associated
4272
                     program header.  */
4273
                  if (value > p->p_vaddr)
4274
                    value -= p->p_vaddr;
4275
                  else
4276
                    value = 0;
4277
                  r = ia64_elf_install_value (hit_addr, value, r_type);
4278
                }
4279
              break;
4280
            }
4281
 
4282
        case R_IA64_SECREL32MSB:
4283
        case R_IA64_SECREL32LSB:
4284
        case R_IA64_SECREL64MSB:
4285
        case R_IA64_SECREL64LSB:
4286
          /* Make output-section relative to section where the symbol
4287
             is defined. PR 475  */
4288
          if (sym_sec)
4289
            value -= sym_sec->output_section->vma;
4290
          r = ia64_elf_install_value (hit_addr, value, r_type);
4291
          break;
4292
 
4293
        case R_IA64_IPLTMSB:
4294
        case R_IA64_IPLTLSB:
4295
          /* Install a dynamic relocation for this reloc.  */
4296
          if ((dynamic_symbol_p || info->shared)
4297
              && (input_section->flags & SEC_ALLOC) != 0)
4298
            {
4299
              BFD_ASSERT (srel != NULL);
4300
 
4301
              /* If we don't need dynamic symbol lookup, install two
4302
                 RELATIVE relocations.  */
4303
              if (!dynamic_symbol_p)
4304
                {
4305
                  unsigned int dyn_r_type;
4306
 
4307
                  if (r_type == R_IA64_IPLTMSB)
4308
                    dyn_r_type = R_IA64_REL64MSB;
4309
                  else
4310
                    dyn_r_type = R_IA64_REL64LSB;
4311
 
4312
                  elfNN_ia64_install_dyn_reloc (output_bfd, info,
4313
                                                input_section,
4314
                                                srel, rel->r_offset,
4315
                                                dyn_r_type, 0, value);
4316
                  elfNN_ia64_install_dyn_reloc (output_bfd, info,
4317
                                                input_section,
4318
                                                srel, rel->r_offset + 8,
4319
                                                dyn_r_type, 0, gp_val);
4320
                }
4321
              else
4322
                elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4323
                                              srel, rel->r_offset, r_type,
4324
                                              h->dynindx, rel->r_addend);
4325
            }
4326
 
4327
          if (r_type == R_IA64_IPLTMSB)
4328
            r_type = R_IA64_DIR64MSB;
4329
          else
4330
            r_type = R_IA64_DIR64LSB;
4331
          ia64_elf_install_value (hit_addr, value, r_type);
4332
          r = ia64_elf_install_value (hit_addr + 8, gp_val, r_type);
4333
          break;
4334
 
4335
        case R_IA64_TPREL14:
4336
        case R_IA64_TPREL22:
4337
        case R_IA64_TPREL64I:
4338
          if (elf_hash_table (info)->tls_sec == NULL)
4339
            goto missing_tls_sec;
4340
          value -= elfNN_ia64_tprel_base (info);
4341
          r = ia64_elf_install_value (hit_addr, value, r_type);
4342
          break;
4343
 
4344
        case R_IA64_DTPREL14:
4345
        case R_IA64_DTPREL22:
4346
        case R_IA64_DTPREL64I:
4347
        case R_IA64_DTPREL32LSB:
4348
        case R_IA64_DTPREL32MSB:
4349
        case R_IA64_DTPREL64LSB:
4350
        case R_IA64_DTPREL64MSB:
4351
          if (elf_hash_table (info)->tls_sec == NULL)
4352
            goto missing_tls_sec;
4353
          value -= elfNN_ia64_dtprel_base (info);
4354
          r = ia64_elf_install_value (hit_addr, value, r_type);
4355
          break;
4356
 
4357
        case R_IA64_LTOFF_TPREL22:
4358
        case R_IA64_LTOFF_DTPMOD22:
4359
        case R_IA64_LTOFF_DTPREL22:
4360
          {
4361
            int got_r_type;
4362
            long dynindx = h ? h->dynindx : -1;
4363
            bfd_vma r_addend = rel->r_addend;
4364
 
4365
            switch (r_type)
4366
              {
4367
              default:
4368
              case R_IA64_LTOFF_TPREL22:
4369
                if (!dynamic_symbol_p)
4370
                  {
4371
                    if (elf_hash_table (info)->tls_sec == NULL)
4372
                      goto missing_tls_sec;
4373
                    if (!info->shared)
4374
                      value -= elfNN_ia64_tprel_base (info);
4375
                    else
4376
                      {
4377
                        r_addend += value - elfNN_ia64_dtprel_base (info);
4378
                        dynindx = 0;
4379
                      }
4380
                  }
4381
                got_r_type = R_IA64_TPREL64LSB;
4382
                break;
4383
              case R_IA64_LTOFF_DTPMOD22:
4384
                if (!dynamic_symbol_p && !info->shared)
4385
                  value = 1;
4386
                got_r_type = R_IA64_DTPMOD64LSB;
4387
                break;
4388
              case R_IA64_LTOFF_DTPREL22:
4389
                if (!dynamic_symbol_p)
4390
                  {
4391
                    if (elf_hash_table (info)->tls_sec == NULL)
4392
                      goto missing_tls_sec;
4393
                    value -= elfNN_ia64_dtprel_base (info);
4394
                  }
4395
                got_r_type = R_IA64_DTPRELNNLSB;
4396
                break;
4397
              }
4398
            dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4399
            value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4400
                                   value, got_r_type);
4401
            value -= gp_val;
4402
            r = ia64_elf_install_value (hit_addr, value, r_type);
4403
          }
4404
          break;
4405
 
4406
        default:
4407
          r = bfd_reloc_notsupported;
4408
          break;
4409
        }
4410
 
4411
      switch (r)
4412
        {
4413
        case bfd_reloc_ok:
4414
          break;
4415
 
4416
        case bfd_reloc_undefined:
4417
          /* This can happen for global table relative relocs if
4418
             __gp is undefined.  This is a panic situation so we
4419
             don't try to continue.  */
4420
          (*info->callbacks->undefined_symbol)
4421
            (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4422
          return FALSE;
4423
 
4424
        case bfd_reloc_notsupported:
4425
          {
4426
            const char *name;
4427
 
4428
            if (h)
4429
              name = h->root.root.string;
4430
            else
4431
              name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4432
                                       sym_sec);
4433
            if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4434
                                              name, input_bfd,
4435
                                              input_section, rel->r_offset))
4436
              return FALSE;
4437
            ret_val = FALSE;
4438
          }
4439
          break;
4440
 
4441
        case bfd_reloc_dangerous:
4442
        case bfd_reloc_outofrange:
4443
        case bfd_reloc_overflow:
4444
        default:
4445
missing_tls_sec:
4446
          {
4447
            const char *name;
4448
 
4449
            if (h)
4450
              name = h->root.root.string;
4451
            else
4452
              name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4453
                                       sym_sec);
4454
 
4455
            switch (r_type)
4456
              {
4457
              case R_IA64_TPREL14:
4458
              case R_IA64_TPREL22:
4459
              case R_IA64_TPREL64I:
4460
              case R_IA64_DTPREL14:
4461
              case R_IA64_DTPREL22:
4462
              case R_IA64_DTPREL64I:
4463
              case R_IA64_DTPREL32LSB:
4464
              case R_IA64_DTPREL32MSB:
4465
              case R_IA64_DTPREL64LSB:
4466
              case R_IA64_DTPREL64MSB:
4467
              case R_IA64_LTOFF_TPREL22:
4468
              case R_IA64_LTOFF_DTPMOD22:
4469
              case R_IA64_LTOFF_DTPREL22:
4470
                (*_bfd_error_handler)
4471
                  (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
4472
                   input_bfd, input_section, howto->name, name,
4473
                   rel->r_offset);
4474
                break;
4475
 
4476
              case R_IA64_PCREL21B:
4477
              case R_IA64_PCREL21BI:
4478
              case R_IA64_PCREL21M:
4479
              case R_IA64_PCREL21F:
4480
                if (is_elf_hash_table (info->hash))
4481
                  {
4482
                    /* Relaxtion is always performed for ELF output.
4483
                       Overflow failures for those relocations mean
4484
                       that the section is too big to relax.  */
4485
                    (*_bfd_error_handler)
4486
                      (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
4487
                       input_bfd, input_section, howto->name, name,
4488
                       rel->r_offset, input_section->size);
4489
                    break;
4490
                  }
4491
              default:
4492
                if (!(*info->callbacks->reloc_overflow) (info,
4493
                                                         &h->root,
4494
                                                         name,
4495
                                                         howto->name,
4496
                                                         (bfd_vma) 0,
4497
                                                         input_bfd,
4498
                                                         input_section,
4499
                                                         rel->r_offset))
4500
                  return FALSE;
4501
                break;
4502
              }
4503
 
4504
            ret_val = FALSE;
4505
          }
4506
          break;
4507
        }
4508
    }
4509
 
4510
  return ret_val;
4511
}
4512
 
4513
static bfd_boolean
4514
elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
4515
                                  struct bfd_link_info *info,
4516
                                  struct elf_link_hash_entry *h,
4517
                                  Elf_Internal_Sym *sym)
4518
{
4519
  struct elfNN_ia64_link_hash_table *ia64_info;
4520
  struct elfNN_ia64_dyn_sym_info *dyn_i;
4521
 
4522
  ia64_info = elfNN_ia64_hash_table (info);
4523
  if (ia64_info == NULL)
4524
    return FALSE;
4525
 
4526
  dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4527
 
4528
  /* Fill in the PLT data, if required.  */
4529
  if (dyn_i && dyn_i->want_plt)
4530
    {
4531
      Elf_Internal_Rela outrel;
4532
      bfd_byte *loc;
4533
      asection *plt_sec;
4534
      bfd_vma plt_addr, pltoff_addr, gp_val, plt_index;
4535
 
4536
      gp_val = _bfd_get_gp_value (output_bfd);
4537
 
4538
      /* Initialize the minimal PLT entry.  */
4539
 
4540
      plt_index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4541
      plt_sec = ia64_info->root.splt;
4542
      loc = plt_sec->contents + dyn_i->plt_offset;
4543
 
4544
      memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4545
      ia64_elf_install_value (loc, plt_index, R_IA64_IMM22);
4546
      ia64_elf_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
4547
 
4548
      plt_addr = (plt_sec->output_section->vma
4549
                  + plt_sec->output_offset
4550
                  + dyn_i->plt_offset);
4551
      pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4552
 
4553
      /* Initialize the FULL PLT entry, if needed.  */
4554
      if (dyn_i->want_plt2)
4555
        {
4556
          loc = plt_sec->contents + dyn_i->plt2_offset;
4557
 
4558
          memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4559
          ia64_elf_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
4560
 
4561
          /* Mark the symbol as undefined, rather than as defined in the
4562
             plt section.  Leave the value alone.  */
4563
          /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4564
             first place.  But perhaps elflink.c did some for us.  */
4565
          if (!h->def_regular)
4566
            sym->st_shndx = SHN_UNDEF;
4567
        }
4568
 
4569
      /* Create the dynamic relocation.  */
4570
      outrel.r_offset = pltoff_addr;
4571
      if (bfd_little_endian (output_bfd))
4572
        outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4573
      else
4574
        outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4575
      outrel.r_addend = 0;
4576
 
4577
      /* This is fun.  In the .IA_64.pltoff section, we've got entries
4578
         that correspond both to real PLT entries, and those that
4579
         happened to resolve to local symbols but need to be created
4580
         to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
4581
         relocations for the real PLT should come at the end of the
4582
         section, so that they can be indexed by plt entry at runtime.
4583
 
4584
         We emitted all of the relocations for the non-PLT @pltoff
4585
         entries during relocate_section.  So we can consider the
4586
         existing sec->reloc_count to be the base of the array of
4587
         PLT relocations.  */
4588
 
4589
      loc = ia64_info->rel_pltoff_sec->contents;
4590
      loc += ((ia64_info->rel_pltoff_sec->reloc_count + plt_index)
4591
              * sizeof (ElfNN_External_Rela));
4592
      bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4593
    }
4594
 
4595
  /* Mark some specially defined symbols as absolute.  */
4596
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4597
      || h == ia64_info->root.hgot
4598
      || h == ia64_info->root.hplt)
4599
    sym->st_shndx = SHN_ABS;
4600
 
4601
  return TRUE;
4602
}
4603
 
4604
static bfd_boolean
4605
elfNN_ia64_finish_dynamic_sections (bfd *abfd,
4606
                                    struct bfd_link_info *info)
4607
{
4608
  struct elfNN_ia64_link_hash_table *ia64_info;
4609
  bfd *dynobj;
4610
 
4611
  ia64_info = elfNN_ia64_hash_table (info);
4612
  if (ia64_info == NULL)
4613
    return FALSE;
4614
 
4615
  dynobj = ia64_info->root.dynobj;
4616
 
4617
  if (elf_hash_table (info)->dynamic_sections_created)
4618
    {
4619
      ElfNN_External_Dyn *dyncon, *dynconend;
4620
      asection *sdyn, *sgotplt;
4621
      bfd_vma gp_val;
4622
 
4623
      sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4624
      sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4625
      BFD_ASSERT (sdyn != NULL);
4626
      dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4627
      dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
4628
 
4629
      gp_val = _bfd_get_gp_value (abfd);
4630
 
4631
      for (; dyncon < dynconend; dyncon++)
4632
        {
4633
          Elf_Internal_Dyn dyn;
4634
 
4635
          bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4636
 
4637
          switch (dyn.d_tag)
4638
            {
4639
            case DT_PLTGOT:
4640
              dyn.d_un.d_ptr = gp_val;
4641
              break;
4642
 
4643
            case DT_PLTRELSZ:
4644
              dyn.d_un.d_val = (ia64_info->minplt_entries
4645
                                * sizeof (ElfNN_External_Rela));
4646
              break;
4647
 
4648
            case DT_JMPREL:
4649
              /* See the comment above in finish_dynamic_symbol.  */
4650
              dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4651
                                + ia64_info->rel_pltoff_sec->output_offset
4652
                                + (ia64_info->rel_pltoff_sec->reloc_count
4653
                                   * sizeof (ElfNN_External_Rela)));
4654
              break;
4655
 
4656
            case DT_IA_64_PLT_RESERVE:
4657
              dyn.d_un.d_ptr = (sgotplt->output_section->vma
4658
                                + sgotplt->output_offset);
4659
              break;
4660
 
4661
            case DT_RELASZ:
4662
              /* Do not have RELASZ include JMPREL.  This makes things
4663
                 easier on ld.so.  This is not what the rest of BFD set up.  */
4664
              dyn.d_un.d_val -= (ia64_info->minplt_entries
4665
                                 * sizeof (ElfNN_External_Rela));
4666
              break;
4667
            }
4668
 
4669
          bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4670
        }
4671
 
4672
      /* Initialize the PLT0 entry.  */
4673
      if (ia64_info->root.splt)
4674
        {
4675
          bfd_byte *loc = ia64_info->root.splt->contents;
4676
          bfd_vma pltres;
4677
 
4678
          memcpy (loc, plt_header, PLT_HEADER_SIZE);
4679
 
4680
          pltres = (sgotplt->output_section->vma
4681
                    + sgotplt->output_offset
4682
                    - gp_val);
4683
 
4684
          ia64_elf_install_value (loc+1, pltres, R_IA64_GPREL22);
4685
        }
4686
    }
4687
 
4688
  return TRUE;
4689
}
4690
 
4691
/* ELF file flag handling:  */
4692
 
4693
/* Function to keep IA-64 specific file flags.  */
4694
static bfd_boolean
4695
elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
4696
{
4697
  BFD_ASSERT (!elf_flags_init (abfd)
4698
              || elf_elfheader (abfd)->e_flags == flags);
4699
 
4700
  elf_elfheader (abfd)->e_flags = flags;
4701
  elf_flags_init (abfd) = TRUE;
4702
  return TRUE;
4703
}
4704
 
4705
/* Merge backend specific data from an object file to the output
4706
   object file when linking.  */
4707
static bfd_boolean
4708
elfNN_ia64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
4709
{
4710
  flagword out_flags;
4711
  flagword in_flags;
4712
  bfd_boolean ok = TRUE;
4713
 
4714
  /* Don't even pretend to support mixed-format linking.  */
4715
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4716
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4717
    return FALSE;
4718
 
4719
  in_flags  = elf_elfheader (ibfd)->e_flags;
4720
  out_flags = elf_elfheader (obfd)->e_flags;
4721
 
4722
  if (! elf_flags_init (obfd))
4723
    {
4724
      elf_flags_init (obfd) = TRUE;
4725
      elf_elfheader (obfd)->e_flags = in_flags;
4726
 
4727
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4728
          && bfd_get_arch_info (obfd)->the_default)
4729
        {
4730
          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4731
                                    bfd_get_mach (ibfd));
4732
        }
4733
 
4734
      return TRUE;
4735
    }
4736
 
4737
  /* Check flag compatibility.  */
4738
  if (in_flags == out_flags)
4739
    return TRUE;
4740
 
4741
  /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
4742
  if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4743
    elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4744
 
4745
  if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4746
    {
4747
      (*_bfd_error_handler)
4748
        (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
4749
         ibfd);
4750
 
4751
      bfd_set_error (bfd_error_bad_value);
4752
      ok = FALSE;
4753
    }
4754
  if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4755
    {
4756
      (*_bfd_error_handler)
4757
        (_("%B: linking big-endian files with little-endian files"),
4758
         ibfd);
4759
 
4760
      bfd_set_error (bfd_error_bad_value);
4761
      ok = FALSE;
4762
    }
4763
  if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4764
    {
4765
      (*_bfd_error_handler)
4766
        (_("%B: linking 64-bit files with 32-bit files"),
4767
         ibfd);
4768
 
4769
      bfd_set_error (bfd_error_bad_value);
4770
      ok = FALSE;
4771
    }
4772
  if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4773
    {
4774
      (*_bfd_error_handler)
4775
        (_("%B: linking constant-gp files with non-constant-gp files"),
4776
         ibfd);
4777
 
4778
      bfd_set_error (bfd_error_bad_value);
4779
      ok = FALSE;
4780
    }
4781
  if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4782
      != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4783
    {
4784
      (*_bfd_error_handler)
4785
        (_("%B: linking auto-pic files with non-auto-pic files"),
4786
         ibfd);
4787
 
4788
      bfd_set_error (bfd_error_bad_value);
4789
      ok = FALSE;
4790
    }
4791
 
4792
  return ok;
4793
}
4794
 
4795
static bfd_boolean
4796
elfNN_ia64_print_private_bfd_data (bfd *abfd, PTR ptr)
4797
{
4798
  FILE *file = (FILE *) ptr;
4799
  flagword flags = elf_elfheader (abfd)->e_flags;
4800
 
4801
  BFD_ASSERT (abfd != NULL && ptr != NULL);
4802
 
4803
  fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4804
           (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4805
           (flags & EF_IA_64_EXT) ? "EXT, " : "",
4806
           (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4807
           (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4808
           (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4809
           (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4810
           (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4811
           (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4812
 
4813
  _bfd_elf_print_private_bfd_data (abfd, ptr);
4814
  return TRUE;
4815
}
4816
 
4817
static enum elf_reloc_type_class
4818
elfNN_ia64_reloc_type_class (const Elf_Internal_Rela *rela)
4819
{
4820
  switch ((int) ELFNN_R_TYPE (rela->r_info))
4821
    {
4822
    case R_IA64_REL32MSB:
4823
    case R_IA64_REL32LSB:
4824
    case R_IA64_REL64MSB:
4825
    case R_IA64_REL64LSB:
4826
      return reloc_class_relative;
4827
    case R_IA64_IPLTMSB:
4828
    case R_IA64_IPLTLSB:
4829
      return reloc_class_plt;
4830
    case R_IA64_COPY:
4831
      return reloc_class_copy;
4832
    default:
4833
      return reloc_class_normal;
4834
    }
4835
}
4836
 
4837
static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
4838
{
4839
  { STRING_COMMA_LEN (".sbss"),  -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4840
  { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4841
  { NULL,                    0,   0, 0,            0 }
4842
};
4843
 
4844
static bfd_boolean
4845
elfNN_ia64_object_p (bfd *abfd)
4846
{
4847
  asection *sec;
4848
  asection *group, *unwi, *unw;
4849
  flagword flags;
4850
  const char *name;
4851
  char *unwi_name, *unw_name;
4852
  bfd_size_type amt;
4853
 
4854
  if (abfd->flags & DYNAMIC)
4855
    return TRUE;
4856
 
4857
  /* Flags for fake group section.  */
4858
  flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
4859
           | SEC_EXCLUDE);
4860
 
4861
  /* We add a fake section group for each .gnu.linkonce.t.* section,
4862
     which isn't in a section group, and its unwind sections.  */
4863
  for (sec = abfd->sections; sec != NULL; sec = sec->next)
4864
    {
4865
      if (elf_sec_group (sec) == NULL
4866
          && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
4867
              == (SEC_LINK_ONCE | SEC_CODE))
4868
          && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
4869
        {
4870
          name = sec->name + 16;
4871
 
4872
          amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
4873
          unwi_name = bfd_alloc (abfd, amt);
4874
          if (!unwi_name)
4875
            return FALSE;
4876
 
4877
          strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
4878
          unwi = bfd_get_section_by_name (abfd, unwi_name);
4879
 
4880
          amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
4881
          unw_name = bfd_alloc (abfd, amt);
4882
          if (!unw_name)
4883
            return FALSE;
4884
 
4885
          strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
4886
          unw = bfd_get_section_by_name (abfd, unw_name);
4887
 
4888
          /* We need to create a fake group section for it and its
4889
             unwind sections.  */
4890
          group = bfd_make_section_anyway_with_flags (abfd, name,
4891
                                                      flags);
4892
          if (group == NULL)
4893
            return FALSE;
4894
 
4895
          /* Move the fake group section to the beginning.  */
4896
          bfd_section_list_remove (abfd, group);
4897
          bfd_section_list_prepend (abfd, group);
4898
 
4899
          elf_next_in_group (group) = sec;
4900
 
4901
          elf_group_name (sec) = name;
4902
          elf_next_in_group (sec) = sec;
4903
          elf_sec_group (sec) = group;
4904
 
4905
          if (unwi)
4906
            {
4907
              elf_group_name (unwi) = name;
4908
              elf_next_in_group (unwi) = sec;
4909
              elf_next_in_group (sec) = unwi;
4910
              elf_sec_group (unwi) = group;
4911
            }
4912
 
4913
           if (unw)
4914
             {
4915
               elf_group_name (unw) = name;
4916
               if (unwi)
4917
                 {
4918
                   elf_next_in_group (unw) = elf_next_in_group (unwi);
4919
                   elf_next_in_group (unwi) = unw;
4920
                 }
4921
               else
4922
                 {
4923
                   elf_next_in_group (unw) = sec;
4924
                   elf_next_in_group (sec) = unw;
4925
                 }
4926
               elf_sec_group (unw) = group;
4927
             }
4928
 
4929
           /* Fake SHT_GROUP section header.  */
4930
          elf_section_data (group)->this_hdr.bfd_section = group;
4931
          elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
4932
        }
4933
    }
4934
  return TRUE;
4935
}
4936
 
4937
static bfd_boolean
4938
elfNN_ia64_hpux_vec (const bfd_target *vec)
4939
{
4940
  extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4941
  return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4942
}
4943
 
4944
static void
4945
elfNN_hpux_post_process_headers (bfd *abfd,
4946
                                 struct bfd_link_info *info ATTRIBUTE_UNUSED)
4947
{
4948
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4949
 
4950
  i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
4951
  i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4952
}
4953
 
4954
static bfd_boolean
4955
elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
4956
                                             asection *sec, int *retval)
4957
{
4958
  if (bfd_is_com_section (sec))
4959
    {
4960
      *retval = SHN_IA_64_ANSI_COMMON;
4961
      return TRUE;
4962
    }
4963
  return FALSE;
4964
}
4965
 
4966
static void
4967
elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
4968
                                      asymbol *asym)
4969
{
4970
  elf_symbol_type *elfsym = (elf_symbol_type *) asym;
4971
 
4972
  switch (elfsym->internal_elf_sym.st_shndx)
4973
    {
4974
    case SHN_IA_64_ANSI_COMMON:
4975
      asym->section = bfd_com_section_ptr;
4976
      asym->value = elfsym->internal_elf_sym.st_size;
4977
      asym->flags &= ~BSF_GLOBAL;
4978
      break;
4979
    }
4980
}
4981
 
4982
#ifdef INCLUDE_IA64_VMS
4983
 
4984
static bfd_boolean
4985
elfNN_vms_section_from_shdr (bfd *abfd,
4986
                             Elf_Internal_Shdr *hdr,
4987
                             const char *name,
4988
                             int shindex)
4989
{
4990
  switch (hdr->sh_type)
4991
    {
4992
    case SHT_IA_64_VMS_TRACE:
4993
    case SHT_IA_64_VMS_DEBUG:
4994
    case SHT_IA_64_VMS_DEBUG_STR:
4995
      break;
4996
 
4997
    default:
4998
      return elfNN_ia64_section_from_shdr (abfd, hdr, name, shindex);
4999
    }
5000
 
5001
  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
5002
    return FALSE;
5003
 
5004
  return TRUE;
5005
}
5006
 
5007
static bfd_boolean
5008
elfNN_vms_object_p (bfd *abfd)
5009
{
5010
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5011
  Elf_Internal_Phdr *i_phdr = elf_tdata (abfd)->phdr;
5012
  unsigned int i;
5013
  unsigned int num_text = 0;
5014
  unsigned int num_data = 0;
5015
  unsigned int num_rodata = 0;
5016
  char name[16];
5017
 
5018
  if (!elfNN_ia64_object_p (abfd))
5019
    return FALSE;
5020
 
5021
  for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)
5022
    {
5023
      /* Is there a section for this segment?  */
5024
      bfd_vma base_vma = i_phdr->p_vaddr;
5025
      bfd_vma limit_vma = base_vma + i_phdr->p_filesz;
5026
 
5027
      if (i_phdr->p_type != PT_LOAD)
5028
        continue;
5029
 
5030
    again:
5031
      while (base_vma < limit_vma)
5032
        {
5033
          bfd_vma next_vma = limit_vma;
5034
          asection *nsec;
5035
          asection *sec;
5036
          flagword flags;
5037
          char *nname = NULL;
5038
 
5039
          /* Find a section covering base_vma.  */
5040
          for (sec = abfd->sections; sec != NULL; sec = sec->next)
5041
            {
5042
              if ((sec->flags & (SEC_ALLOC | SEC_LOAD)) == 0)
5043
                continue;
5044
              if (sec->vma <= base_vma && sec->vma + sec->size > base_vma)
5045
                {
5046
                  base_vma = sec->vma + sec->size;
5047
                  goto again;
5048
                }
5049
              if (sec->vma < next_vma && sec->vma + sec->size >= base_vma)
5050
                next_vma = sec->vma;
5051
            }
5052
 
5053
          /* No section covering [base_vma; next_vma).  Create a fake one.  */
5054
          flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
5055
          if (i_phdr->p_flags & PF_X)
5056
            {
5057
              flags |= SEC_CODE;
5058
              if (num_text++ == 0)
5059
                nname = ".text";
5060
              else
5061
                sprintf (name, ".text$%u", num_text);
5062
            }
5063
          else if ((i_phdr->p_flags & (PF_R | PF_W)) == PF_R)
5064
            {
5065
              flags |= SEC_READONLY;
5066
              sprintf (name, ".rodata$%u", num_rodata++);
5067
            }
5068
          else
5069
            {
5070
              flags |= SEC_DATA;
5071
              sprintf (name, ".data$%u", num_data++);
5072
            }
5073
 
5074
          /* Allocate name.  */
5075
          if (nname == NULL)
5076
            {
5077
              size_t name_len = strlen (name) + 1;
5078
              nname = bfd_alloc (abfd, name_len);
5079
              if (nname == NULL)
5080
                return FALSE;
5081
              memcpy (nname, name, name_len);
5082
            }
5083
 
5084
          /* Create and fill new section.  */
5085
          nsec = bfd_make_section_anyway_with_flags (abfd, nname, flags);
5086
          if (nsec == NULL)
5087
            return FALSE;
5088
          nsec->vma = base_vma;
5089
          nsec->size = next_vma - base_vma;
5090
          nsec->filepos = i_phdr->p_offset + (base_vma - i_phdr->p_vaddr);
5091 148 khays
 
5092 14 khays
          base_vma = next_vma;
5093
        }
5094
    }
5095
  return TRUE;
5096
}
5097
 
5098
static void
5099
elfNN_vms_post_process_headers (bfd *abfd,
5100
                                struct bfd_link_info *info ATTRIBUTE_UNUSED)
5101
{
5102
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5103
 
5104
  i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_OPENVMS;
5105
  i_ehdrp->e_ident[EI_ABIVERSION] = 2;
5106
}
5107
 
5108
static bfd_boolean
5109
elfNN_vms_section_processing (bfd *abfd ATTRIBUTE_UNUSED,
5110
                              Elf_Internal_Shdr *hdr)
5111
{
5112
  if (hdr->bfd_section != NULL)
5113
    {
5114
      const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
5115
 
5116
      if (strcmp (name, ".text") == 0)
5117
        hdr->sh_flags |= SHF_IA_64_VMS_SHARED;
5118
      else if ((strcmp (name, ".debug") == 0)
5119
            || (strcmp (name, ".debug_abbrev") == 0)
5120
            || (strcmp (name, ".debug_aranges") == 0)
5121
            || (strcmp (name, ".debug_frame") == 0)
5122
            || (strcmp (name, ".debug_info") == 0)
5123
            || (strcmp (name, ".debug_loc") == 0)
5124
            || (strcmp (name, ".debug_macinfo") == 0)
5125
            || (strcmp (name, ".debug_pubnames") == 0)
5126
            || (strcmp (name, ".debug_pubtypes") == 0))
5127
        hdr->sh_type = SHT_IA_64_VMS_DEBUG;
5128
      else if ((strcmp (name, ".debug_line") == 0)
5129
            || (strcmp (name, ".debug_ranges") == 0))
5130
        hdr->sh_type = SHT_IA_64_VMS_TRACE;
5131
      else if (strcmp (name, ".debug_str") == 0)
5132
        hdr->sh_type = SHT_IA_64_VMS_DEBUG_STR;
5133
      else if (strcmp (name, ".vms_display_name_info") == 0)
5134
        {
5135
          int idx, symcount;
5136
          asymbol **syms;
5137
          struct elf_obj_tdata *t = elf_tdata (abfd);
5138
          int buf[2];
5139
          int demangler_sym_idx = -1;
5140
 
5141
          symcount = bfd_get_symcount (abfd);
5142
          syms = bfd_get_outsymbols (abfd);
5143
          for (idx = 0; idx < symcount; idx++)
5144
            {
5145
              asymbol *sym;
5146
              sym = syms[idx];
5147
              if ((sym->flags & (BSF_DEBUGGING | BSF_DYNAMIC))
5148
                  && strchr (sym->name, '@')
5149
                  && (strcmp (sym->section->name, BFD_ABS_SECTION_NAME) == 0))
5150
                {
5151
                  demangler_sym_idx = sym->udata.i;
5152
                  break;
5153
                }
5154
            }
5155
 
5156
          hdr->sh_type = SHT_IA_64_VMS_DISPLAY_NAME_INFO;
5157
          hdr->sh_entsize = 4;
5158
          hdr->sh_addralign = 0;
5159
          hdr->sh_link = t->symtab_section;
5160
 
5161
          /* Find symtab index of demangler routine and stuff it in
5162
             the second long word of section data.  */
5163
 
5164
          if (demangler_sym_idx > -1)
5165
            {
5166
              bfd_seek (abfd, hdr->sh_offset, SEEK_SET);
5167
              bfd_bread (buf, hdr->sh_size, abfd);
5168
              buf [1] = demangler_sym_idx;
5169
              bfd_seek (abfd, hdr->sh_offset, SEEK_SET);
5170
              bfd_bwrite (buf, hdr->sh_size, abfd);
5171
            }
5172
        }
5173
    }
5174
 
5175
  return TRUE;
5176
}
5177
 
5178
/* The final processing done just before writing out a VMS IA-64 ELF
5179
   object file.  */
5180
 
5181
static void
5182
elfNN_vms_final_write_processing (bfd *abfd,
5183
                                  bfd_boolean linker ATTRIBUTE_UNUSED)
5184
{
5185
  Elf_Internal_Shdr *hdr;
5186
  asection *s;
5187
  int unwind_info_sect_idx = 0;
5188
 
5189
  for (s = abfd->sections; s; s = s->next)
5190
    {
5191
      hdr = &elf_section_data (s)->this_hdr;
5192
 
5193
      if (strcmp (bfd_get_section_name (abfd, hdr->bfd_section),
5194
                  ".IA_64.unwind_info") == 0)
5195
        unwind_info_sect_idx = elf_section_data (s)->this_idx;
5196
 
5197
      switch (hdr->sh_type)
5198
        {
5199
        case SHT_IA_64_UNWIND:
5200
          /* VMS requires sh_info to point to the unwind info section.  */
5201
          hdr->sh_info = unwind_info_sect_idx;
5202
          break;
5203
        }
5204
    }
5205
 
5206
  if (! elf_flags_init (abfd))
5207
    {
5208
      unsigned long flags = 0;
5209
 
5210
      if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
5211
        flags |= EF_IA_64_BE;
5212
      if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
5213
        flags |= EF_IA_64_ABI64;
5214
 
5215
      elf_elfheader(abfd)->e_flags = flags;
5216
      elf_flags_init (abfd) = TRUE;
5217
    }
5218
}
5219
 
5220
static bfd_boolean
5221
elfNN_vms_close_and_cleanup (bfd *abfd)
5222
{
5223
  if (bfd_get_format (abfd) == bfd_object)
5224
    {
5225
      long isize, irsize;
5226
 
5227
      if (elf_shstrtab (abfd) != NULL)
5228
        _bfd_elf_strtab_free (elf_shstrtab (abfd));
5229
 
5230
      /* Pad to 8 byte boundary for IPF/VMS.  */
5231
      isize = bfd_get_size (abfd);
5232
      if ((irsize = isize/8*8) < isize)
5233
        {
5234
          int ishort = (irsize + 8) - isize;
5235
          bfd_seek (abfd, isize, SEEK_SET);
5236
          bfd_bwrite (bfd_zmalloc (ishort), ishort, abfd);
5237
        }
5238
    }
5239
 
5240
  return _bfd_generic_close_and_cleanup (abfd);
5241
}
5242
#endif /* INCLUDE_IA64_VMS */
5243
 
5244
#define TARGET_LITTLE_SYM               bfd_elfNN_ia64_little_vec
5245
#define TARGET_LITTLE_NAME              "elfNN-ia64-little"
5246
#define TARGET_BIG_SYM                  bfd_elfNN_ia64_big_vec
5247
#define TARGET_BIG_NAME                 "elfNN-ia64-big"
5248
#define ELF_ARCH                        bfd_arch_ia64
5249
#define ELF_TARGET_ID                   IA64_ELF_DATA
5250
#define ELF_MACHINE_CODE                EM_IA_64
5251
#define ELF_MACHINE_ALT1                1999    /* EAS2.3 */
5252
#define ELF_MACHINE_ALT2                1998    /* EAS2.2 */
5253
#define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
5254
#define ELF_COMMONPAGESIZE              0x4000  /* 16KB */
5255
 
5256
#define elf_backend_section_from_shdr \
5257
        elfNN_ia64_section_from_shdr
5258
#define elf_backend_section_flags \
5259
        elfNN_ia64_section_flags
5260
#define elf_backend_fake_sections \
5261
        elfNN_ia64_fake_sections
5262
#define elf_backend_final_write_processing \
5263
        elfNN_ia64_final_write_processing
5264
#define elf_backend_add_symbol_hook \
5265
        elfNN_ia64_add_symbol_hook
5266
#define elf_backend_additional_program_headers \
5267
        elfNN_ia64_additional_program_headers
5268
#define elf_backend_modify_segment_map \
5269
        elfNN_ia64_modify_segment_map
5270
#define elf_backend_modify_program_headers \
5271
        elfNN_ia64_modify_program_headers
5272
#define elf_info_to_howto \
5273
        elfNN_ia64_info_to_howto
5274
 
5275
#define bfd_elfNN_bfd_reloc_type_lookup \
5276
        ia64_elf_reloc_type_lookup
5277
#define bfd_elfNN_bfd_reloc_name_lookup \
5278
        ia64_elf_reloc_name_lookup
5279
#define bfd_elfNN_bfd_is_local_label_name \
5280
        elfNN_ia64_is_local_label_name
5281
#define bfd_elfNN_bfd_relax_section \
5282
        elfNN_ia64_relax_section
5283
 
5284
#define elf_backend_object_p \
5285
        elfNN_ia64_object_p
5286
 
5287
/* Stuff for the BFD linker: */
5288
#define bfd_elfNN_bfd_link_hash_table_create \
5289
        elfNN_ia64_hash_table_create
5290
#define bfd_elfNN_bfd_link_hash_table_free \
5291
        elfNN_ia64_hash_table_free
5292
#define elf_backend_create_dynamic_sections \
5293
        elfNN_ia64_create_dynamic_sections
5294
#define elf_backend_check_relocs \
5295
        elfNN_ia64_check_relocs
5296
#define elf_backend_adjust_dynamic_symbol \
5297
        elfNN_ia64_adjust_dynamic_symbol
5298
#define elf_backend_size_dynamic_sections \
5299
        elfNN_ia64_size_dynamic_sections
5300
#define elf_backend_omit_section_dynsym \
5301
  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5302
#define elf_backend_relocate_section \
5303
        elfNN_ia64_relocate_section
5304
#define elf_backend_finish_dynamic_symbol \
5305
        elfNN_ia64_finish_dynamic_symbol
5306
#define elf_backend_finish_dynamic_sections \
5307
        elfNN_ia64_finish_dynamic_sections
5308
#define bfd_elfNN_bfd_final_link \
5309
        elfNN_ia64_final_link
5310
 
5311
#define bfd_elfNN_bfd_merge_private_bfd_data \
5312
        elfNN_ia64_merge_private_bfd_data
5313
#define bfd_elfNN_bfd_set_private_flags \
5314
        elfNN_ia64_set_private_flags
5315
#define bfd_elfNN_bfd_print_private_bfd_data \
5316
        elfNN_ia64_print_private_bfd_data
5317
 
5318
#define elf_backend_plt_readonly        1
5319
#define elf_backend_want_plt_sym        0
5320
#define elf_backend_plt_alignment       5
5321
#define elf_backend_got_header_size     0
5322
#define elf_backend_want_got_plt        1
5323
#define elf_backend_may_use_rel_p       1
5324
#define elf_backend_may_use_rela_p      1
5325
#define elf_backend_default_use_rela_p  1
5326
#define elf_backend_want_dynbss         0
5327
#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5328
#define elf_backend_hide_symbol         elfNN_ia64_hash_hide_symbol
5329
#define elf_backend_fixup_symbol        _bfd_elf_link_hash_fixup_symbol
5330
#define elf_backend_reloc_type_class    elfNN_ia64_reloc_type_class
5331
#define elf_backend_rela_normal         1
5332
#define elf_backend_special_sections    elfNN_ia64_special_sections
5333
#define elf_backend_default_execstack   0
5334
 
5335
/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5336
   SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5337
   We don't want to flood users with so many error messages. We turn
5338
   off the warning for now. It will be turned on later when the Intel
5339
   compiler is fixed.   */
5340
#define elf_backend_link_order_error_handler NULL
5341
 
5342
#include "elfNN-target.h"
5343
 
5344
/* HPUX-specific vectors.  */
5345
 
5346
#undef  TARGET_LITTLE_SYM
5347
#undef  TARGET_LITTLE_NAME
5348
#undef  TARGET_BIG_SYM
5349
#define TARGET_BIG_SYM                  bfd_elfNN_ia64_hpux_big_vec
5350
#undef  TARGET_BIG_NAME
5351
#define TARGET_BIG_NAME                 "elfNN-ia64-hpux-big"
5352
 
5353
/* These are HP-UX specific functions.  */
5354
 
5355
#undef  elf_backend_post_process_headers
5356
#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5357
 
5358
#undef  elf_backend_section_from_bfd_section
5359
#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5360
 
5361
#undef elf_backend_symbol_processing
5362
#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5363
 
5364
#undef  elf_backend_want_p_paddr_set_to_zero
5365
#define elf_backend_want_p_paddr_set_to_zero 1
5366
 
5367
#undef ELF_COMMONPAGESIZE
5368
#undef ELF_OSABI
5369
#define ELF_OSABI                       ELFOSABI_HPUX
5370
 
5371
#undef  elfNN_bed
5372
#define elfNN_bed elfNN_ia64_hpux_bed
5373
 
5374
#include "elfNN-target.h"
5375
 
5376
/* VMS-specific vectors.  */
5377
#ifdef INCLUDE_IA64_VMS
5378
 
5379
#undef  TARGET_LITTLE_SYM
5380
#define TARGET_LITTLE_SYM               bfd_elfNN_ia64_vms_vec
5381
#undef  TARGET_LITTLE_NAME
5382
#define TARGET_LITTLE_NAME              "elfNN-ia64-vms"
5383
#undef  TARGET_BIG_SYM
5384
#undef  TARGET_BIG_NAME
5385
 
5386
/* These are VMS specific functions.  */
5387
 
5388
#undef  elf_backend_object_p
5389
#define elf_backend_object_p elfNN_vms_object_p
5390
 
5391
#undef  elf_backend_section_from_shdr
5392
#define elf_backend_section_from_shdr elfNN_vms_section_from_shdr
5393
 
5394
#undef  elf_backend_post_process_headers
5395
#define elf_backend_post_process_headers elfNN_vms_post_process_headers
5396
 
5397
#undef  elf_backend_section_processing
5398
#define elf_backend_section_processing elfNN_vms_section_processing
5399
 
5400
#undef  elf_backend_final_write_processing
5401
#define elf_backend_final_write_processing elfNN_vms_final_write_processing
5402
 
5403
#undef  bfd_elfNN_close_and_cleanup
5404
#define bfd_elfNN_close_and_cleanup elfNN_vms_close_and_cleanup
5405
 
5406
#undef  elf_backend_section_from_bfd_section
5407
 
5408
#undef  elf_backend_symbol_processing
5409
 
5410
#undef  elf_backend_want_p_paddr_set_to_zero
5411
 
5412
#undef ELF_OSABI
5413
#define ELF_OSABI                       ELFOSABI_OPENVMS
5414
 
5415
#undef  ELF_MAXPAGESIZE
5416
#define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
5417
 
5418
#undef  elfNN_bed
5419
#define elfNN_bed elfNN_ia64_vms_bed
5420
 
5421
/* Use VMS-style archives (in particular, don't use the standard coff
5422
   archive format).  */
5423
#define bfd_elfNN_archive_functions
5424
 
5425
#undef bfd_elfNN_archive_p
5426
#define bfd_elfNN_archive_p _bfd_vms_lib_ia64_archive_p
5427
#undef bfd_elfNN_write_archive_contents
5428
#define bfd_elfNN_write_archive_contents _bfd_vms_lib_write_archive_contents
5429
#undef bfd_elfNN_mkarchive
5430
#define bfd_elfNN_mkarchive _bfd_vms_lib_ia64_mkarchive
5431
 
5432
#define bfd_elfNN_archive_slurp_armap \
5433
  _bfd_vms_lib_slurp_armap
5434
#define bfd_elfNN_archive_slurp_extended_name_table \
5435
  _bfd_vms_lib_slurp_extended_name_table
5436
#define bfd_elfNN_archive_construct_extended_name_table \
5437
  _bfd_vms_lib_construct_extended_name_table
5438
#define bfd_elfNN_archive_truncate_arname \
5439
  _bfd_vms_lib_truncate_arname
5440
#define bfd_elfNN_archive_write_armap \
5441
  _bfd_vms_lib_write_armap
5442
#define bfd_elfNN_archive_read_ar_hdr \
5443
  _bfd_vms_lib_read_ar_hdr
5444
#define bfd_elfNN_archive_write_ar_hdr \
5445
  _bfd_vms_lib_write_ar_hdr
5446
#define bfd_elfNN_archive_openr_next_archived_file \
5447
  _bfd_vms_lib_openr_next_archived_file
5448
#define bfd_elfNN_archive_get_elt_at_index \
5449
  _bfd_vms_lib_get_elt_at_index
5450
#define bfd_elfNN_archive_generic_stat_arch_elt \
5451
  _bfd_vms_lib_generic_stat_arch_elt
5452
#define bfd_elfNN_archive_update_armap_timestamp \
5453
  _bfd_vms_lib_update_armap_timestamp
5454
 
5455
#include "elfNN-target.h"
5456
 
5457
#endif /* INCLUDE_IA64_VMS */

powered by: WebSVN 2.1.0

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