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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [elfxx-ia64.c] - Blame information for rev 178

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

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

powered by: WebSVN 2.1.0

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