OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [bfd/] [elfxx-ia64.c] - Blame information for rev 274

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

Line No. Rev Author Line
1 38 julius
/* 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
  return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
4192
                                     tls_sec->alignment_power);
4193
}
4194
 
4195
/* Return the base VMA address which should be subtracted from real addresses
4196
   when resolving @dtprel() relocation.
4197
   This is PT_TLS segment p_vaddr.  */
4198
 
4199
static bfd_vma
4200
elfNN_ia64_dtprel_base (struct bfd_link_info *info)
4201
{
4202
  return elf_hash_table (info)->tls_sec->vma;
4203
}
4204
 
4205
/* Called through qsort to sort the .IA_64.unwind section during a
4206
   non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
4207
   to the output bfd so we can do proper endianness frobbing.  */
4208
 
4209
static bfd *elfNN_ia64_unwind_entry_compare_bfd;
4210
 
4211
static int
4212
elfNN_ia64_unwind_entry_compare (const PTR a, const PTR b)
4213
{
4214
  bfd_vma av, bv;
4215
 
4216
  av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
4217
  bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
4218
 
4219
  return (av < bv ? -1 : av > bv ? 1 : 0);
4220
}
4221
 
4222
/* Make sure we've got ourselves a nice fat __gp value.  */
4223
static bfd_boolean
4224
elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info)
4225
{
4226
  bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
4227
  bfd_vma min_short_vma = min_vma, max_short_vma = 0;
4228
  struct elf_link_hash_entry *gp;
4229
  bfd_vma gp_val;
4230
  asection *os;
4231
  struct elfNN_ia64_link_hash_table *ia64_info;
4232
 
4233
  ia64_info = elfNN_ia64_hash_table (info);
4234
 
4235
  /* Find the min and max vma of all sections marked short.  Also collect
4236
     min and max vma of any type, for use in selecting a nice gp.  */
4237
  for (os = abfd->sections; os ; os = os->next)
4238
    {
4239
      bfd_vma lo, hi;
4240
 
4241
      if ((os->flags & SEC_ALLOC) == 0)
4242
        continue;
4243
 
4244
      lo = os->vma;
4245
      hi = os->vma + (os->rawsize ? os->rawsize : os->size);
4246
      if (hi < lo)
4247
        hi = (bfd_vma) -1;
4248
 
4249
      if (min_vma > lo)
4250
        min_vma = lo;
4251
      if (max_vma < hi)
4252
        max_vma = hi;
4253
      if (os->flags & SEC_SMALL_DATA)
4254
        {
4255
          if (min_short_vma > lo)
4256
            min_short_vma = lo;
4257
          if (max_short_vma < hi)
4258
            max_short_vma = hi;
4259
        }
4260
    }
4261
 
4262
  /* See if the user wants to force a value.  */
4263
  gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4264
                             FALSE, FALSE);
4265
 
4266
  if (gp
4267
      && (gp->root.type == bfd_link_hash_defined
4268
          || gp->root.type == bfd_link_hash_defweak))
4269
    {
4270
      asection *gp_sec = gp->root.u.def.section;
4271
      gp_val = (gp->root.u.def.value
4272
                + gp_sec->output_section->vma
4273
                + gp_sec->output_offset);
4274
    }
4275
  else
4276
    {
4277
      /* Pick a sensible value.  */
4278
 
4279
      asection *got_sec = ia64_info->got_sec;
4280
 
4281
      /* Start with just the address of the .got.  */
4282
      if (got_sec)
4283
        gp_val = got_sec->output_section->vma;
4284
      else if (max_short_vma != 0)
4285
        gp_val = min_short_vma;
4286
      else if (max_vma - min_vma < 0x200000)
4287
        gp_val = min_vma;
4288
      else
4289
        gp_val = max_vma - 0x200000 + 8;
4290
 
4291
      /* If it is possible to address the entire image, but we
4292
         don't with the choice above, adjust.  */
4293
      if (max_vma - min_vma < 0x400000
4294
          && (max_vma - gp_val >= 0x200000
4295
              || gp_val - min_vma > 0x200000))
4296
        gp_val = min_vma + 0x200000;
4297
      else if (max_short_vma != 0)
4298
        {
4299
          /* If we don't cover all the short data, adjust.  */
4300
          if (max_short_vma - gp_val >= 0x200000)
4301
            gp_val = min_short_vma + 0x200000;
4302
 
4303
          /* If we're addressing stuff past the end, adjust back.  */
4304
          if (gp_val > max_vma)
4305
            gp_val = max_vma - 0x200000 + 8;
4306
        }
4307
    }
4308
 
4309
  /* Validate whether all SHF_IA_64_SHORT sections are within
4310
     range of the chosen GP.  */
4311
 
4312
  if (max_short_vma != 0)
4313
    {
4314
      if (max_short_vma - min_short_vma >= 0x400000)
4315
        {
4316
          (*_bfd_error_handler)
4317
            (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4318
             bfd_get_filename (abfd),
4319
             (unsigned long) (max_short_vma - min_short_vma));
4320
          return FALSE;
4321
        }
4322
      else if ((gp_val > min_short_vma
4323
                && gp_val - min_short_vma > 0x200000)
4324
               || (gp_val < max_short_vma
4325
                   && max_short_vma - gp_val >= 0x200000))
4326
        {
4327
          (*_bfd_error_handler)
4328
            (_("%s: __gp does not cover short data segment"),
4329
             bfd_get_filename (abfd));
4330
          return FALSE;
4331
        }
4332
    }
4333
 
4334
  _bfd_set_gp_value (abfd, gp_val);
4335
 
4336
  return TRUE;
4337
}
4338
 
4339
static bfd_boolean
4340
elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
4341
{
4342
  struct elfNN_ia64_link_hash_table *ia64_info;
4343
  asection *unwind_output_sec;
4344
 
4345
  ia64_info = elfNN_ia64_hash_table (info);
4346
 
4347
  /* Make sure we've got ourselves a nice fat __gp value.  */
4348
  if (!info->relocatable)
4349
    {
4350
      bfd_vma gp_val;
4351
      struct elf_link_hash_entry *gp;
4352
 
4353
      /* We assume after gp is set, section size will only decrease. We
4354
         need to adjust gp for it.  */
4355
      _bfd_set_gp_value (abfd, 0);
4356
      if (! elfNN_ia64_choose_gp (abfd, info))
4357
        return FALSE;
4358
      gp_val = _bfd_get_gp_value (abfd);
4359
 
4360
      gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4361
                                 FALSE, FALSE);
4362
      if (gp)
4363
        {
4364
          gp->root.type = bfd_link_hash_defined;
4365
          gp->root.u.def.value = gp_val;
4366
          gp->root.u.def.section = bfd_abs_section_ptr;
4367
        }
4368
    }
4369
 
4370
  /* If we're producing a final executable, we need to sort the contents
4371
     of the .IA_64.unwind section.  Force this section to be relocated
4372
     into memory rather than written immediately to the output file.  */
4373
  unwind_output_sec = NULL;
4374
  if (!info->relocatable)
4375
    {
4376
      asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
4377
      if (s)
4378
        {
4379
          unwind_output_sec = s->output_section;
4380
          unwind_output_sec->contents
4381
            = bfd_malloc (unwind_output_sec->size);
4382
          if (unwind_output_sec->contents == NULL)
4383
            return FALSE;
4384
        }
4385
    }
4386
 
4387
  /* Invoke the regular ELF backend linker to do all the work.  */
4388
  if (!bfd_elf_final_link (abfd, info))
4389
    return FALSE;
4390
 
4391
  if (unwind_output_sec)
4392
    {
4393
      elfNN_ia64_unwind_entry_compare_bfd = abfd;
4394
      qsort (unwind_output_sec->contents,
4395
             (size_t) (unwind_output_sec->size / 24),
4396
             24,
4397
             elfNN_ia64_unwind_entry_compare);
4398
 
4399
      if (! bfd_set_section_contents (abfd, unwind_output_sec,
4400
                                      unwind_output_sec->contents, (bfd_vma) 0,
4401
                                      unwind_output_sec->size))
4402
        return FALSE;
4403
    }
4404
 
4405
  return TRUE;
4406
}
4407
 
4408
static bfd_boolean
4409
elfNN_ia64_relocate_section (bfd *output_bfd,
4410
                             struct bfd_link_info *info,
4411
                             bfd *input_bfd,
4412
                             asection *input_section,
4413
                             bfd_byte *contents,
4414
                             Elf_Internal_Rela *relocs,
4415
                             Elf_Internal_Sym *local_syms,
4416
                             asection **local_sections)
4417
{
4418
  struct elfNN_ia64_link_hash_table *ia64_info;
4419
  Elf_Internal_Shdr *symtab_hdr;
4420
  Elf_Internal_Rela *rel;
4421
  Elf_Internal_Rela *relend;
4422
  asection *srel;
4423
  bfd_boolean ret_val = TRUE;   /* for non-fatal errors */
4424
  bfd_vma gp_val;
4425
 
4426
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4427
  ia64_info = elfNN_ia64_hash_table (info);
4428
 
4429
  /* Infect various flags from the input section to the output section.  */
4430
  if (info->relocatable)
4431
    {
4432
      bfd_vma flags;
4433
 
4434
      flags = elf_section_data(input_section)->this_hdr.sh_flags;
4435
      flags &= SHF_IA_64_NORECOV;
4436
 
4437
      elf_section_data(input_section->output_section)
4438
        ->this_hdr.sh_flags |= flags;
4439
    }
4440
 
4441
  gp_val = _bfd_get_gp_value (output_bfd);
4442
  srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
4443
 
4444
  rel = relocs;
4445
  relend = relocs + input_section->reloc_count;
4446
  for (; rel < relend; ++rel)
4447
    {
4448
      struct elf_link_hash_entry *h;
4449
      struct elfNN_ia64_dyn_sym_info *dyn_i;
4450
      bfd_reloc_status_type r;
4451
      reloc_howto_type *howto;
4452
      unsigned long r_symndx;
4453
      Elf_Internal_Sym *sym;
4454
      unsigned int r_type;
4455
      bfd_vma value;
4456
      asection *sym_sec;
4457
      bfd_byte *hit_addr;
4458
      bfd_boolean dynamic_symbol_p;
4459
      bfd_boolean undef_weak_ref;
4460
 
4461
      r_type = ELFNN_R_TYPE (rel->r_info);
4462
      if (r_type > R_IA64_MAX_RELOC_CODE)
4463
        {
4464
          (*_bfd_error_handler)
4465
            (_("%B: unknown relocation type %d"),
4466
             input_bfd, (int) r_type);
4467
          bfd_set_error (bfd_error_bad_value);
4468
          ret_val = FALSE;
4469
          continue;
4470
        }
4471
 
4472
      howto = lookup_howto (r_type);
4473
      r_symndx = ELFNN_R_SYM (rel->r_info);
4474
      h = NULL;
4475
      sym = NULL;
4476
      sym_sec = NULL;
4477
      undef_weak_ref = FALSE;
4478
 
4479
      if (r_symndx < symtab_hdr->sh_info)
4480
        {
4481
          /* Reloc against local symbol.  */
4482
          asection *msec;
4483
          sym = local_syms + r_symndx;
4484
          sym_sec = local_sections[r_symndx];
4485
          msec = sym_sec;
4486
          value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
4487
          if (!info->relocatable
4488
              && (sym_sec->flags & SEC_MERGE) != 0
4489
              && ELF_ST_TYPE (sym->st_info) == STT_SECTION
4490
              && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
4491
            {
4492
              struct elfNN_ia64_local_hash_entry *loc_h;
4493
 
4494
              loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
4495
              if (loc_h && ! loc_h->sec_merge_done)
4496
                {
4497
                  struct elfNN_ia64_dyn_sym_info *dynent;
4498
                  unsigned int count;
4499
 
4500
                  for (count = loc_h->count, dynent = loc_h->info;
4501
                       count != 0;
4502
                       count--, dynent++)
4503
                    {
4504
                      msec = sym_sec;
4505
                      dynent->addend =
4506
                        _bfd_merged_section_offset (output_bfd, &msec,
4507
                                                    elf_section_data (msec)->
4508
                                                    sec_info,
4509
                                                    sym->st_value
4510
                                                    + dynent->addend);
4511
                      dynent->addend -= sym->st_value;
4512
                      dynent->addend += msec->output_section->vma
4513
                                        + msec->output_offset
4514
                                        - sym_sec->output_section->vma
4515
                                        - sym_sec->output_offset;
4516
                    }
4517
 
4518
                  /* We may have introduced duplicated entries. We need
4519
                     to remove them properly.  */
4520
                  count = sort_dyn_sym_info (loc_h->info, loc_h->count);
4521
                  if (count != loc_h->count)
4522
                    {
4523
                      loc_h->count = count;
4524
                      loc_h->sorted_count = count;
4525
                    }
4526
 
4527
                  loc_h->sec_merge_done = 1;
4528
                }
4529
            }
4530
        }
4531
      else
4532
        {
4533
          bfd_boolean unresolved_reloc;
4534
          bfd_boolean warned;
4535
          struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
4536
 
4537
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4538
                                   r_symndx, symtab_hdr, sym_hashes,
4539
                                   h, sym_sec, value,
4540
                                   unresolved_reloc, warned);
4541
 
4542
          if (h->root.type == bfd_link_hash_undefweak)
4543
            undef_weak_ref = TRUE;
4544
          else if (warned)
4545
            continue;
4546
        }
4547
 
4548
      /* For relocs against symbols from removed linkonce sections,
4549
         or sections discarded by a linker script, we just want the
4550
         section contents zeroed.  Avoid any special processing.  */
4551
      if (sym_sec != NULL && elf_discarded_section (sym_sec))
4552
        {
4553
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
4554
          rel->r_info = 0;
4555
          rel->r_addend = 0;
4556
          continue;
4557
        }
4558
 
4559
      if (info->relocatable)
4560
        continue;
4561
 
4562
      hit_addr = contents + rel->r_offset;
4563
      value += rel->r_addend;
4564
      dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
4565
 
4566
      switch (r_type)
4567
        {
4568
        case R_IA64_NONE:
4569
        case R_IA64_LDXMOV:
4570
          continue;
4571
 
4572
        case R_IA64_IMM14:
4573
        case R_IA64_IMM22:
4574
        case R_IA64_IMM64:
4575
        case R_IA64_DIR32MSB:
4576
        case R_IA64_DIR32LSB:
4577
        case R_IA64_DIR64MSB:
4578
        case R_IA64_DIR64LSB:
4579
          /* Install a dynamic relocation for this reloc.  */
4580
          if ((dynamic_symbol_p || info->shared)
4581
              && r_symndx != 0
4582
              && (input_section->flags & SEC_ALLOC) != 0)
4583
            {
4584
              unsigned int dyn_r_type;
4585
              long dynindx;
4586
              bfd_vma addend;
4587
 
4588
              BFD_ASSERT (srel != NULL);
4589
 
4590
              switch (r_type)
4591
                {
4592
                case R_IA64_IMM14:
4593
                case R_IA64_IMM22:
4594
                case R_IA64_IMM64:
4595
                  /* ??? People shouldn't be doing non-pic code in
4596
                     shared libraries nor dynamic executables.  */
4597
                  (*_bfd_error_handler)
4598
                    (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4599
                     input_bfd,
4600
                     h ? h->root.root.string
4601
                       : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4602
                                           sym_sec));
4603
                  ret_val = FALSE;
4604
                  continue;
4605
 
4606
                default:
4607
                  break;
4608
                }
4609
 
4610
              /* If we don't need dynamic symbol lookup, find a
4611
                 matching RELATIVE relocation.  */
4612
              dyn_r_type = r_type;
4613
              if (dynamic_symbol_p)
4614
                {
4615
                  dynindx = h->dynindx;
4616
                  addend = rel->r_addend;
4617
                  value = 0;
4618
                }
4619
              else
4620
                {
4621
                  switch (r_type)
4622
                    {
4623
                    case R_IA64_DIR32MSB:
4624
                      dyn_r_type = R_IA64_REL32MSB;
4625
                      break;
4626
                    case R_IA64_DIR32LSB:
4627
                      dyn_r_type = R_IA64_REL32LSB;
4628
                      break;
4629
                    case R_IA64_DIR64MSB:
4630
                      dyn_r_type = R_IA64_REL64MSB;
4631
                      break;
4632
                    case R_IA64_DIR64LSB:
4633
                      dyn_r_type = R_IA64_REL64LSB;
4634
                      break;
4635
 
4636
                    default:
4637
                      break;
4638
                    }
4639
                  dynindx = 0;
4640
                  addend = value;
4641
                }
4642
 
4643
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4644
                                            srel, rel->r_offset, dyn_r_type,
4645
                                            dynindx, addend);
4646
            }
4647
          /* Fall through.  */
4648
 
4649
        case R_IA64_LTV32MSB:
4650
        case R_IA64_LTV32LSB:
4651
        case R_IA64_LTV64MSB:
4652
        case R_IA64_LTV64LSB:
4653
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
4654
          break;
4655
 
4656
        case R_IA64_GPREL22:
4657
        case R_IA64_GPREL64I:
4658
        case R_IA64_GPREL32MSB:
4659
        case R_IA64_GPREL32LSB:
4660
        case R_IA64_GPREL64MSB:
4661
        case R_IA64_GPREL64LSB:
4662
          if (dynamic_symbol_p)
4663
            {
4664
              (*_bfd_error_handler)
4665
                (_("%B: @gprel relocation against dynamic symbol %s"),
4666
                 input_bfd,
4667
                 h ? h->root.root.string
4668
                   : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4669
                                       sym_sec));
4670
              ret_val = FALSE;
4671
              continue;
4672
            }
4673
          value -= gp_val;
4674
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
4675
          break;
4676
 
4677
        case R_IA64_LTOFF22:
4678
        case R_IA64_LTOFF22X:
4679
        case R_IA64_LTOFF64I:
4680
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4681
          value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4682
                                 rel->r_addend, value, R_IA64_DIRNNLSB);
4683
          value -= gp_val;
4684
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
4685
          break;
4686
 
4687
        case R_IA64_PLTOFF22:
4688
        case R_IA64_PLTOFF64I:
4689
        case R_IA64_PLTOFF64MSB:
4690
        case R_IA64_PLTOFF64LSB:
4691
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4692
          value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4693
          value -= gp_val;
4694
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
4695
          break;
4696
 
4697
        case R_IA64_FPTR64I:
4698
        case R_IA64_FPTR32MSB:
4699
        case R_IA64_FPTR32LSB:
4700
        case R_IA64_FPTR64MSB:
4701
        case R_IA64_FPTR64LSB:
4702
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4703
          if (dyn_i->want_fptr)
4704
            {
4705
              if (!undef_weak_ref)
4706
                value = set_fptr_entry (output_bfd, info, dyn_i, value);
4707
            }
4708
          if (!dyn_i->want_fptr || info->pie)
4709
            {
4710
              long dynindx;
4711
              unsigned int dyn_r_type = r_type;
4712
              bfd_vma addend = rel->r_addend;
4713
 
4714
              /* Otherwise, we expect the dynamic linker to create
4715
                 the entry.  */
4716
 
4717
              if (dyn_i->want_fptr)
4718
                {
4719
                  if (r_type == R_IA64_FPTR64I)
4720
                    {
4721
                      /* We can't represent this without a dynamic symbol.
4722
                         Adjust the relocation to be against an output
4723
                         section symbol, which are always present in the
4724
                         dynamic symbol table.  */
4725
                      /* ??? People shouldn't be doing non-pic code in
4726
                         shared libraries.  Hork.  */
4727
                      (*_bfd_error_handler)
4728
                        (_("%B: linking non-pic code in a position independent executable"),
4729
                         input_bfd);
4730
                      ret_val = FALSE;
4731
                      continue;
4732
                    }
4733
                  dynindx = 0;
4734
                  addend = value;
4735
                  dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4736
                }
4737
              else if (h)
4738
                {
4739
                  if (h->dynindx != -1)
4740
                    dynindx = h->dynindx;
4741
                  else
4742
                    dynindx = (_bfd_elf_link_lookup_local_dynindx
4743
                               (info, h->root.u.def.section->owner,
4744
                                global_sym_index (h)));
4745
                  value = 0;
4746
                }
4747
              else
4748
                {
4749
                  dynindx = (_bfd_elf_link_lookup_local_dynindx
4750
                             (info, input_bfd, (long) r_symndx));
4751
                  value = 0;
4752
                }
4753
 
4754
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4755
                                            srel, rel->r_offset, dyn_r_type,
4756
                                            dynindx, addend);
4757
            }
4758
 
4759
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
4760
          break;
4761
 
4762
        case R_IA64_LTOFF_FPTR22:
4763
        case R_IA64_LTOFF_FPTR64I:
4764
        case R_IA64_LTOFF_FPTR32MSB:
4765
        case R_IA64_LTOFF_FPTR32LSB:
4766
        case R_IA64_LTOFF_FPTR64MSB:
4767
        case R_IA64_LTOFF_FPTR64LSB:
4768
          {
4769
            long dynindx;
4770
 
4771
            dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4772
            if (dyn_i->want_fptr)
4773
              {
4774
                BFD_ASSERT (h == NULL || h->dynindx == -1);
4775
                if (!undef_weak_ref)
4776
                  value = set_fptr_entry (output_bfd, info, dyn_i, value);
4777
                dynindx = -1;
4778
              }
4779
            else
4780
              {
4781
                /* Otherwise, we expect the dynamic linker to create
4782
                   the entry.  */
4783
                if (h)
4784
                  {
4785
                    if (h->dynindx != -1)
4786
                      dynindx = h->dynindx;
4787
                    else
4788
                      dynindx = (_bfd_elf_link_lookup_local_dynindx
4789
                                 (info, h->root.u.def.section->owner,
4790
                                  global_sym_index (h)));
4791
                  }
4792
                else
4793
                  dynindx = (_bfd_elf_link_lookup_local_dynindx
4794
                             (info, input_bfd, (long) r_symndx));
4795
                value = 0;
4796
              }
4797
 
4798
            value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4799
                                   rel->r_addend, value, R_IA64_FPTRNNLSB);
4800
            value -= gp_val;
4801
            r = elfNN_ia64_install_value (hit_addr, value, r_type);
4802
          }
4803
          break;
4804
 
4805
        case R_IA64_PCREL32MSB:
4806
        case R_IA64_PCREL32LSB:
4807
        case R_IA64_PCREL64MSB:
4808
        case R_IA64_PCREL64LSB:
4809
          /* Install a dynamic relocation for this reloc.  */
4810
          if (dynamic_symbol_p && r_symndx != 0)
4811
            {
4812
              BFD_ASSERT (srel != NULL);
4813
 
4814
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4815
                                            srel, rel->r_offset, r_type,
4816
                                            h->dynindx, rel->r_addend);
4817
            }
4818
          goto finish_pcrel;
4819
 
4820
        case R_IA64_PCREL21B:
4821
        case R_IA64_PCREL60B:
4822
          /* We should have created a PLT entry for any dynamic symbol.  */
4823
          dyn_i = NULL;
4824
          if (h)
4825
            dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4826
 
4827
          if (dyn_i && dyn_i->want_plt2)
4828
            {
4829
              /* Should have caught this earlier.  */
4830
              BFD_ASSERT (rel->r_addend == 0);
4831
 
4832
              value = (ia64_info->plt_sec->output_section->vma
4833
                       + ia64_info->plt_sec->output_offset
4834
                       + dyn_i->plt2_offset);
4835
            }
4836
          else
4837
            {
4838
              /* Since there's no PLT entry, Validate that this is
4839
                 locally defined.  */
4840
              BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4841
 
4842
              /* If the symbol is undef_weak, we shouldn't be trying
4843
                 to call it.  There's every chance that we'd wind up
4844
                 with an out-of-range fixup here.  Don't bother setting
4845
                 any value at all.  */
4846
              if (undef_weak_ref)
4847
                continue;
4848
            }
4849
          goto finish_pcrel;
4850
 
4851
        case R_IA64_PCREL21BI:
4852
        case R_IA64_PCREL21F:
4853
        case R_IA64_PCREL21M:
4854
        case R_IA64_PCREL22:
4855
        case R_IA64_PCREL64I:
4856
          /* The PCREL21BI reloc is specifically not intended for use with
4857
             dynamic relocs.  PCREL21F and PCREL21M are used for speculation
4858
             fixup code, and thus probably ought not be dynamic.  The
4859
             PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs.  */
4860
          if (dynamic_symbol_p)
4861
            {
4862
              const char *msg;
4863
 
4864
              if (r_type == R_IA64_PCREL21BI)
4865
                msg = _("%B: @internal branch to dynamic symbol %s");
4866
              else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4867
                msg = _("%B: speculation fixup to dynamic symbol %s");
4868
              else
4869
                msg = _("%B: @pcrel relocation against dynamic symbol %s");
4870
              (*_bfd_error_handler) (msg, input_bfd,
4871
                                     h ? h->root.root.string
4872
                                       : bfd_elf_sym_name (input_bfd,
4873
                                                           symtab_hdr,
4874
                                                           sym,
4875
                                                           sym_sec));
4876
              ret_val = FALSE;
4877
              continue;
4878
            }
4879
          goto finish_pcrel;
4880
 
4881
        finish_pcrel:
4882
          /* Make pc-relative.  */
4883
          value -= (input_section->output_section->vma
4884
                    + input_section->output_offset
4885
                    + rel->r_offset) & ~ (bfd_vma) 0x3;
4886
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
4887
          break;
4888
 
4889
        case R_IA64_SEGREL32MSB:
4890
        case R_IA64_SEGREL32LSB:
4891
        case R_IA64_SEGREL64MSB:
4892
        case R_IA64_SEGREL64LSB:
4893
            {
4894
              /* Find the segment that contains the output_section.  */
4895
              Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
4896
                (output_bfd, input_section->output_section);
4897
 
4898
              if (p == NULL)
4899
                {
4900
                  r = bfd_reloc_notsupported;
4901
                }
4902
              else
4903
                {
4904
                  /* The VMA of the segment is the vaddr of the associated
4905
                     program header.  */
4906
                  if (value > p->p_vaddr)
4907
                    value -= p->p_vaddr;
4908
                  else
4909
                    value = 0;
4910
                  r = elfNN_ia64_install_value (hit_addr, value, r_type);
4911
                }
4912
              break;
4913
            }
4914
 
4915
        case R_IA64_SECREL32MSB:
4916
        case R_IA64_SECREL32LSB:
4917
        case R_IA64_SECREL64MSB:
4918
        case R_IA64_SECREL64LSB:
4919
          /* Make output-section relative to section where the symbol
4920
             is defined. PR 475  */
4921
          if (sym_sec)
4922
            value -= sym_sec->output_section->vma;
4923
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
4924
          break;
4925
 
4926
        case R_IA64_IPLTMSB:
4927
        case R_IA64_IPLTLSB:
4928
          /* Install a dynamic relocation for this reloc.  */
4929
          if ((dynamic_symbol_p || info->shared)
4930
              && (input_section->flags & SEC_ALLOC) != 0)
4931
            {
4932
              BFD_ASSERT (srel != NULL);
4933
 
4934
              /* If we don't need dynamic symbol lookup, install two
4935
                 RELATIVE relocations.  */
4936
              if (!dynamic_symbol_p)
4937
                {
4938
                  unsigned int dyn_r_type;
4939
 
4940
                  if (r_type == R_IA64_IPLTMSB)
4941
                    dyn_r_type = R_IA64_REL64MSB;
4942
                  else
4943
                    dyn_r_type = R_IA64_REL64LSB;
4944
 
4945
                  elfNN_ia64_install_dyn_reloc (output_bfd, info,
4946
                                                input_section,
4947
                                                srel, rel->r_offset,
4948
                                                dyn_r_type, 0, value);
4949
                  elfNN_ia64_install_dyn_reloc (output_bfd, info,
4950
                                                input_section,
4951
                                                srel, rel->r_offset + 8,
4952
                                                dyn_r_type, 0, gp_val);
4953
                }
4954
              else
4955
                elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4956
                                              srel, rel->r_offset, r_type,
4957
                                              h->dynindx, rel->r_addend);
4958
            }
4959
 
4960
          if (r_type == R_IA64_IPLTMSB)
4961
            r_type = R_IA64_DIR64MSB;
4962
          else
4963
            r_type = R_IA64_DIR64LSB;
4964
          elfNN_ia64_install_value (hit_addr, value, r_type);
4965
          r = elfNN_ia64_install_value (hit_addr + 8, gp_val, r_type);
4966
          break;
4967
 
4968
        case R_IA64_TPREL14:
4969
        case R_IA64_TPREL22:
4970
        case R_IA64_TPREL64I:
4971
          if (elf_hash_table (info)->tls_sec == NULL)
4972
            goto missing_tls_sec;
4973
          value -= elfNN_ia64_tprel_base (info);
4974
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
4975
          break;
4976
 
4977
        case R_IA64_DTPREL14:
4978
        case R_IA64_DTPREL22:
4979
        case R_IA64_DTPREL64I:
4980
        case R_IA64_DTPREL32LSB:
4981
        case R_IA64_DTPREL32MSB:
4982
        case R_IA64_DTPREL64LSB:
4983
        case R_IA64_DTPREL64MSB:
4984
          if (elf_hash_table (info)->tls_sec == NULL)
4985
            goto missing_tls_sec;
4986
          value -= elfNN_ia64_dtprel_base (info);
4987
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
4988
          break;
4989
 
4990
        case R_IA64_LTOFF_TPREL22:
4991
        case R_IA64_LTOFF_DTPMOD22:
4992
        case R_IA64_LTOFF_DTPREL22:
4993
          {
4994
            int got_r_type;
4995
            long dynindx = h ? h->dynindx : -1;
4996
            bfd_vma r_addend = rel->r_addend;
4997
 
4998
            switch (r_type)
4999
              {
5000
              default:
5001
              case R_IA64_LTOFF_TPREL22:
5002
                if (!dynamic_symbol_p)
5003
                  {
5004
                    if (elf_hash_table (info)->tls_sec == NULL)
5005
                      goto missing_tls_sec;
5006
                    if (!info->shared)
5007
                      value -= elfNN_ia64_tprel_base (info);
5008
                    else
5009
                      {
5010
                        r_addend += value - elfNN_ia64_dtprel_base (info);
5011
                        dynindx = 0;
5012
                      }
5013
                  }
5014
                got_r_type = R_IA64_TPREL64LSB;
5015
                break;
5016
              case R_IA64_LTOFF_DTPMOD22:
5017
                if (!dynamic_symbol_p && !info->shared)
5018
                  value = 1;
5019
                got_r_type = R_IA64_DTPMOD64LSB;
5020
                break;
5021
              case R_IA64_LTOFF_DTPREL22:
5022
                if (!dynamic_symbol_p)
5023
                  {
5024
                    if (elf_hash_table (info)->tls_sec == NULL)
5025
                      goto missing_tls_sec;
5026
                    value -= elfNN_ia64_dtprel_base (info);
5027
                  }
5028
                got_r_type = R_IA64_DTPRELNNLSB;
5029
                break;
5030
              }
5031
            dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
5032
            value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
5033
                                   value, got_r_type);
5034
            value -= gp_val;
5035
            r = elfNN_ia64_install_value (hit_addr, value, r_type);
5036
          }
5037
          break;
5038
 
5039
        default:
5040
          r = bfd_reloc_notsupported;
5041
          break;
5042
        }
5043
 
5044
      switch (r)
5045
        {
5046
        case bfd_reloc_ok:
5047
          break;
5048
 
5049
        case bfd_reloc_undefined:
5050
          /* This can happen for global table relative relocs if
5051
             __gp is undefined.  This is a panic situation so we
5052
             don't try to continue.  */
5053
          (*info->callbacks->undefined_symbol)
5054
            (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
5055
          return FALSE;
5056
 
5057
        case bfd_reloc_notsupported:
5058
          {
5059
            const char *name;
5060
 
5061
            if (h)
5062
              name = h->root.root.string;
5063
            else
5064
              name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5065
                                       sym_sec);
5066
            if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
5067
                                              name, input_bfd,
5068
                                              input_section, rel->r_offset))
5069
              return FALSE;
5070
            ret_val = FALSE;
5071
          }
5072
          break;
5073
 
5074
        case bfd_reloc_dangerous:
5075
        case bfd_reloc_outofrange:
5076
        case bfd_reloc_overflow:
5077
        default:
5078
missing_tls_sec:
5079
          {
5080
            const char *name;
5081
 
5082
            if (h)
5083
              name = h->root.root.string;
5084
            else
5085
              name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5086
                                       sym_sec);
5087
 
5088
            switch (r_type)
5089
              {
5090
              case R_IA64_TPREL14:
5091
              case R_IA64_TPREL22:
5092
              case R_IA64_TPREL64I:
5093
              case R_IA64_DTPREL14:
5094
              case R_IA64_DTPREL22:
5095
              case R_IA64_DTPREL64I:
5096
              case R_IA64_DTPREL32LSB:
5097
              case R_IA64_DTPREL32MSB:
5098
              case R_IA64_DTPREL64LSB:
5099
              case R_IA64_DTPREL64MSB:
5100
              case R_IA64_LTOFF_TPREL22:
5101
              case R_IA64_LTOFF_DTPMOD22:
5102
              case R_IA64_LTOFF_DTPREL22:
5103
                (*_bfd_error_handler)
5104
                  (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
5105
                   input_bfd, input_section, howto->name, name,
5106
                   rel->r_offset);
5107
                break;
5108
 
5109
              case R_IA64_PCREL21B:
5110
              case R_IA64_PCREL21BI:
5111
              case R_IA64_PCREL21M:
5112
              case R_IA64_PCREL21F:
5113
                if (is_elf_hash_table (info->hash))
5114
                  {
5115
                    /* Relaxtion is always performed for ELF output.
5116
                       Overflow failures for those relocations mean
5117
                       that the section is too big to relax.  */
5118
                    (*_bfd_error_handler)
5119
                      (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5120
                       input_bfd, input_section, howto->name, name,
5121
                       rel->r_offset, input_section->size);
5122
                    break;
5123
                  }
5124
              default:
5125
                if (!(*info->callbacks->reloc_overflow) (info,
5126
                                                         &h->root,
5127
                                                         name,
5128
                                                         howto->name,
5129
                                                         (bfd_vma) 0,
5130
                                                         input_bfd,
5131
                                                         input_section,
5132
                                                         rel->r_offset))
5133
                  return FALSE;
5134
                break;
5135
              }
5136
 
5137
            ret_val = FALSE;
5138
          }
5139
          break;
5140
        }
5141
    }
5142
 
5143
  return ret_val;
5144
}
5145
 
5146
static bfd_boolean
5147
elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
5148
                                  struct bfd_link_info *info,
5149
                                  struct elf_link_hash_entry *h,
5150
                                  Elf_Internal_Sym *sym)
5151
{
5152
  struct elfNN_ia64_link_hash_table *ia64_info;
5153
  struct elfNN_ia64_dyn_sym_info *dyn_i;
5154
 
5155
  ia64_info = elfNN_ia64_hash_table (info);
5156
  dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
5157
 
5158
  /* Fill in the PLT data, if required.  */
5159
  if (dyn_i && dyn_i->want_plt)
5160
    {
5161
      Elf_Internal_Rela outrel;
5162
      bfd_byte *loc;
5163
      asection *plt_sec;
5164
      bfd_vma plt_addr, pltoff_addr, gp_val, index;
5165
 
5166
      gp_val = _bfd_get_gp_value (output_bfd);
5167
 
5168
      /* Initialize the minimal PLT entry.  */
5169
 
5170
      index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
5171
      plt_sec = ia64_info->plt_sec;
5172
      loc = plt_sec->contents + dyn_i->plt_offset;
5173
 
5174
      memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
5175
      elfNN_ia64_install_value (loc, index, R_IA64_IMM22);
5176
      elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
5177
 
5178
      plt_addr = (plt_sec->output_section->vma
5179
                  + plt_sec->output_offset
5180
                  + dyn_i->plt_offset);
5181
      pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
5182
 
5183
      /* Initialize the FULL PLT entry, if needed.  */
5184
      if (dyn_i->want_plt2)
5185
        {
5186
          loc = plt_sec->contents + dyn_i->plt2_offset;
5187
 
5188
          memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
5189
          elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
5190
 
5191
          /* Mark the symbol as undefined, rather than as defined in the
5192
             plt section.  Leave the value alone.  */
5193
          /* ??? We didn't redefine it in adjust_dynamic_symbol in the
5194
             first place.  But perhaps elflink.c did some for us.  */
5195
          if (!h->def_regular)
5196
            sym->st_shndx = SHN_UNDEF;
5197
        }
5198
 
5199
      /* Create the dynamic relocation.  */
5200
      outrel.r_offset = pltoff_addr;
5201
      if (bfd_little_endian (output_bfd))
5202
        outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
5203
      else
5204
        outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
5205
      outrel.r_addend = 0;
5206
 
5207
      /* This is fun.  In the .IA_64.pltoff section, we've got entries
5208
         that correspond both to real PLT entries, and those that
5209
         happened to resolve to local symbols but need to be created
5210
         to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
5211
         relocations for the real PLT should come at the end of the
5212
         section, so that they can be indexed by plt entry at runtime.
5213
 
5214
         We emitted all of the relocations for the non-PLT @pltoff
5215
         entries during relocate_section.  So we can consider the
5216
         existing sec->reloc_count to be the base of the array of
5217
         PLT relocations.  */
5218
 
5219
      loc = ia64_info->rel_pltoff_sec->contents;
5220
      loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
5221
              * sizeof (ElfNN_External_Rela));
5222
      bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
5223
    }
5224
 
5225
  /* Mark some specially defined symbols as absolute.  */
5226
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
5227
      || h == ia64_info->root.hgot
5228
      || h == ia64_info->root.hplt)
5229
    sym->st_shndx = SHN_ABS;
5230
 
5231
  return TRUE;
5232
}
5233
 
5234
static bfd_boolean
5235
elfNN_ia64_finish_dynamic_sections (bfd *abfd,
5236
                                    struct bfd_link_info *info)
5237
{
5238
  struct elfNN_ia64_link_hash_table *ia64_info;
5239
  bfd *dynobj;
5240
 
5241
  ia64_info = elfNN_ia64_hash_table (info);
5242
  dynobj = ia64_info->root.dynobj;
5243
 
5244
  if (elf_hash_table (info)->dynamic_sections_created)
5245
    {
5246
      ElfNN_External_Dyn *dyncon, *dynconend;
5247
      asection *sdyn, *sgotplt;
5248
      bfd_vma gp_val;
5249
 
5250
      sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
5251
      sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
5252
      BFD_ASSERT (sdyn != NULL);
5253
      dyncon = (ElfNN_External_Dyn *) sdyn->contents;
5254
      dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
5255
 
5256
      gp_val = _bfd_get_gp_value (abfd);
5257
 
5258
      for (; dyncon < dynconend; dyncon++)
5259
        {
5260
          Elf_Internal_Dyn dyn;
5261
 
5262
          bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
5263
 
5264
          switch (dyn.d_tag)
5265
            {
5266
            case DT_PLTGOT:
5267
              dyn.d_un.d_ptr = gp_val;
5268
              break;
5269
 
5270
            case DT_PLTRELSZ:
5271
              dyn.d_un.d_val = (ia64_info->minplt_entries
5272
                                * sizeof (ElfNN_External_Rela));
5273
              break;
5274
 
5275
            case DT_JMPREL:
5276
              /* See the comment above in finish_dynamic_symbol.  */
5277
              dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
5278
                                + ia64_info->rel_pltoff_sec->output_offset
5279
                                + (ia64_info->rel_pltoff_sec->reloc_count
5280
                                   * sizeof (ElfNN_External_Rela)));
5281
              break;
5282
 
5283
            case DT_IA_64_PLT_RESERVE:
5284
              dyn.d_un.d_ptr = (sgotplt->output_section->vma
5285
                                + sgotplt->output_offset);
5286
              break;
5287
 
5288
            case DT_RELASZ:
5289
              /* Do not have RELASZ include JMPREL.  This makes things
5290
                 easier on ld.so.  This is not what the rest of BFD set up.  */
5291
              dyn.d_un.d_val -= (ia64_info->minplt_entries
5292
                                 * sizeof (ElfNN_External_Rela));
5293
              break;
5294
            }
5295
 
5296
          bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
5297
        }
5298
 
5299
      /* Initialize the PLT0 entry.  */
5300
      if (ia64_info->plt_sec)
5301
        {
5302
          bfd_byte *loc = ia64_info->plt_sec->contents;
5303
          bfd_vma pltres;
5304
 
5305
          memcpy (loc, plt_header, PLT_HEADER_SIZE);
5306
 
5307
          pltres = (sgotplt->output_section->vma
5308
                    + sgotplt->output_offset
5309
                    - gp_val);
5310
 
5311
          elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
5312
        }
5313
    }
5314
 
5315
  return TRUE;
5316
}
5317
 
5318
/* ELF file flag handling:  */
5319
 
5320
/* Function to keep IA-64 specific file flags.  */
5321
static bfd_boolean
5322
elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
5323
{
5324
  BFD_ASSERT (!elf_flags_init (abfd)
5325
              || elf_elfheader (abfd)->e_flags == flags);
5326
 
5327
  elf_elfheader (abfd)->e_flags = flags;
5328
  elf_flags_init (abfd) = TRUE;
5329
  return TRUE;
5330
}
5331
 
5332
/* Merge backend specific data from an object file to the output
5333
   object file when linking.  */
5334
static bfd_boolean
5335
elfNN_ia64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
5336
{
5337
  flagword out_flags;
5338
  flagword in_flags;
5339
  bfd_boolean ok = TRUE;
5340
 
5341
  /* Don't even pretend to support mixed-format linking.  */
5342
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
5343
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
5344
    return FALSE;
5345
 
5346
  in_flags  = elf_elfheader (ibfd)->e_flags;
5347
  out_flags = elf_elfheader (obfd)->e_flags;
5348
 
5349
  if (! elf_flags_init (obfd))
5350
    {
5351
      elf_flags_init (obfd) = TRUE;
5352
      elf_elfheader (obfd)->e_flags = in_flags;
5353
 
5354
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
5355
          && bfd_get_arch_info (obfd)->the_default)
5356
        {
5357
          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
5358
                                    bfd_get_mach (ibfd));
5359
        }
5360
 
5361
      return TRUE;
5362
    }
5363
 
5364
  /* Check flag compatibility.  */
5365
  if (in_flags == out_flags)
5366
    return TRUE;
5367
 
5368
  /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
5369
  if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
5370
    elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
5371
 
5372
  if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
5373
    {
5374
      (*_bfd_error_handler)
5375
        (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5376
         ibfd);
5377
 
5378
      bfd_set_error (bfd_error_bad_value);
5379
      ok = FALSE;
5380
    }
5381
  if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
5382
    {
5383
      (*_bfd_error_handler)
5384
        (_("%B: linking big-endian files with little-endian files"),
5385
         ibfd);
5386
 
5387
      bfd_set_error (bfd_error_bad_value);
5388
      ok = FALSE;
5389
    }
5390
  if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
5391
    {
5392
      (*_bfd_error_handler)
5393
        (_("%B: linking 64-bit files with 32-bit files"),
5394
         ibfd);
5395
 
5396
      bfd_set_error (bfd_error_bad_value);
5397
      ok = FALSE;
5398
    }
5399
  if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
5400
    {
5401
      (*_bfd_error_handler)
5402
        (_("%B: linking constant-gp files with non-constant-gp files"),
5403
         ibfd);
5404
 
5405
      bfd_set_error (bfd_error_bad_value);
5406
      ok = FALSE;
5407
    }
5408
  if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
5409
      != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
5410
    {
5411
      (*_bfd_error_handler)
5412
        (_("%B: linking auto-pic files with non-auto-pic files"),
5413
         ibfd);
5414
 
5415
      bfd_set_error (bfd_error_bad_value);
5416
      ok = FALSE;
5417
    }
5418
 
5419
  return ok;
5420
}
5421
 
5422
static bfd_boolean
5423
elfNN_ia64_print_private_bfd_data (bfd *abfd, PTR ptr)
5424
{
5425
  FILE *file = (FILE *) ptr;
5426
  flagword flags = elf_elfheader (abfd)->e_flags;
5427
 
5428
  BFD_ASSERT (abfd != NULL && ptr != NULL);
5429
 
5430
  fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
5431
           (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
5432
           (flags & EF_IA_64_EXT) ? "EXT, " : "",
5433
           (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
5434
           (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
5435
           (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
5436
           (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
5437
           (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
5438
           (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
5439
 
5440
  _bfd_elf_print_private_bfd_data (abfd, ptr);
5441
  return TRUE;
5442
}
5443
 
5444
static enum elf_reloc_type_class
5445
elfNN_ia64_reloc_type_class (const Elf_Internal_Rela *rela)
5446
{
5447
  switch ((int) ELFNN_R_TYPE (rela->r_info))
5448
    {
5449
    case R_IA64_REL32MSB:
5450
    case R_IA64_REL32LSB:
5451
    case R_IA64_REL64MSB:
5452
    case R_IA64_REL64LSB:
5453
      return reloc_class_relative;
5454
    case R_IA64_IPLTMSB:
5455
    case R_IA64_IPLTLSB:
5456
      return reloc_class_plt;
5457
    case R_IA64_COPY:
5458
      return reloc_class_copy;
5459
    default:
5460
      return reloc_class_normal;
5461
    }
5462
}
5463
 
5464
static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
5465
{
5466
  { STRING_COMMA_LEN (".sbss"),  -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5467
  { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5468
  { NULL,                    0,   0, 0,            0 }
5469
};
5470
 
5471
static bfd_boolean
5472
elfNN_ia64_object_p (bfd *abfd)
5473
{
5474
  asection *sec;
5475
  asection *group, *unwi, *unw;
5476
  flagword flags;
5477
  const char *name;
5478
  char *unwi_name, *unw_name;
5479
  bfd_size_type amt;
5480
 
5481
  if (abfd->flags & DYNAMIC)
5482
    return TRUE;
5483
 
5484
  /* Flags for fake group section.  */
5485
  flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
5486
           | SEC_EXCLUDE);
5487
 
5488
  /* We add a fake section group for each .gnu.linkonce.t.* section,
5489
     which isn't in a section group, and its unwind sections.  */
5490
  for (sec = abfd->sections; sec != NULL; sec = sec->next)
5491
    {
5492
      if (elf_sec_group (sec) == NULL
5493
          && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
5494
              == (SEC_LINK_ONCE | SEC_CODE))
5495
          && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
5496
        {
5497
          name = sec->name + 16;
5498
 
5499
          amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
5500
          unwi_name = bfd_alloc (abfd, amt);
5501
          if (!unwi_name)
5502
            return FALSE;
5503
 
5504
          strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
5505
          unwi = bfd_get_section_by_name (abfd, unwi_name);
5506
 
5507
          amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
5508
          unw_name = bfd_alloc (abfd, amt);
5509
          if (!unw_name)
5510
            return FALSE;
5511
 
5512
          strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
5513
          unw = bfd_get_section_by_name (abfd, unw_name);
5514
 
5515
          /* We need to create a fake group section for it and its
5516
             unwind sections.  */
5517
          group = bfd_make_section_anyway_with_flags (abfd, name,
5518
                                                      flags);
5519
          if (group == NULL)
5520
            return FALSE;
5521
 
5522
          /* Move the fake group section to the beginning.  */
5523
          bfd_section_list_remove (abfd, group);
5524
          bfd_section_list_prepend (abfd, group);
5525
 
5526
          elf_next_in_group (group) = sec;
5527
 
5528
          elf_group_name (sec) = name;
5529
          elf_next_in_group (sec) = sec;
5530
          elf_sec_group (sec) = group;
5531
 
5532
          if (unwi)
5533
            {
5534
              elf_group_name (unwi) = name;
5535
              elf_next_in_group (unwi) = sec;
5536
              elf_next_in_group (sec) = unwi;
5537
              elf_sec_group (unwi) = group;
5538
            }
5539
 
5540
           if (unw)
5541
             {
5542
               elf_group_name (unw) = name;
5543
               if (unwi)
5544
                 {
5545
                   elf_next_in_group (unw) = elf_next_in_group (unwi);
5546
                   elf_next_in_group (unwi) = unw;
5547
                 }
5548
               else
5549
                 {
5550
                   elf_next_in_group (unw) = sec;
5551
                   elf_next_in_group (sec) = unw;
5552
                 }
5553
               elf_sec_group (unw) = group;
5554
             }
5555
 
5556
           /* Fake SHT_GROUP section header.  */
5557
          elf_section_data (group)->this_hdr.bfd_section = group;
5558
          elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
5559
        }
5560
    }
5561
  return TRUE;
5562
}
5563
 
5564
static bfd_boolean
5565
elfNN_ia64_hpux_vec (const bfd_target *vec)
5566
{
5567
  extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
5568
  return (vec == & bfd_elfNN_ia64_hpux_big_vec);
5569
}
5570
 
5571
static void
5572
elfNN_hpux_post_process_headers (bfd *abfd,
5573
                                 struct bfd_link_info *info ATTRIBUTE_UNUSED)
5574
{
5575
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5576
 
5577
  i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
5578
  i_ehdrp->e_ident[EI_ABIVERSION] = 1;
5579
}
5580
 
5581
static bfd_boolean
5582
elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
5583
                                             asection *sec, int *retval)
5584
{
5585
  if (bfd_is_com_section (sec))
5586
    {
5587
      *retval = SHN_IA_64_ANSI_COMMON;
5588
      return TRUE;
5589
    }
5590
  return FALSE;
5591
}
5592
 
5593
static void
5594
elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5595
                                      asymbol *asym)
5596
{
5597
  elf_symbol_type *elfsym = (elf_symbol_type *) asym;
5598
 
5599
  switch (elfsym->internal_elf_sym.st_shndx)
5600
    {
5601
    case SHN_IA_64_ANSI_COMMON:
5602
      asym->section = bfd_com_section_ptr;
5603
      asym->value = elfsym->internal_elf_sym.st_size;
5604
      asym->flags &= ~BSF_GLOBAL;
5605
      break;
5606
    }
5607
}
5608
 
5609
 
5610
#define TARGET_LITTLE_SYM               bfd_elfNN_ia64_little_vec
5611
#define TARGET_LITTLE_NAME              "elfNN-ia64-little"
5612
#define TARGET_BIG_SYM                  bfd_elfNN_ia64_big_vec
5613
#define TARGET_BIG_NAME                 "elfNN-ia64-big"
5614
#define ELF_ARCH                        bfd_arch_ia64
5615
#define ELF_MACHINE_CODE                EM_IA_64
5616
#define ELF_MACHINE_ALT1                1999    /* EAS2.3 */
5617
#define ELF_MACHINE_ALT2                1998    /* EAS2.2 */
5618
#define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
5619
#define ELF_COMMONPAGESIZE              0x4000  /* 16KB */
5620
 
5621
#define elf_backend_section_from_shdr \
5622
        elfNN_ia64_section_from_shdr
5623
#define elf_backend_section_flags \
5624
        elfNN_ia64_section_flags
5625
#define elf_backend_fake_sections \
5626
        elfNN_ia64_fake_sections
5627
#define elf_backend_final_write_processing \
5628
        elfNN_ia64_final_write_processing
5629
#define elf_backend_add_symbol_hook \
5630
        elfNN_ia64_add_symbol_hook
5631
#define elf_backend_additional_program_headers \
5632
        elfNN_ia64_additional_program_headers
5633
#define elf_backend_modify_segment_map \
5634
        elfNN_ia64_modify_segment_map
5635
#define elf_backend_modify_program_headers \
5636
        elfNN_ia64_modify_program_headers
5637
#define elf_info_to_howto \
5638
        elfNN_ia64_info_to_howto
5639
 
5640
#define bfd_elfNN_bfd_reloc_type_lookup \
5641
        elfNN_ia64_reloc_type_lookup
5642
#define bfd_elfNN_bfd_reloc_name_lookup \
5643
        elfNN_ia64_reloc_name_lookup
5644
#define bfd_elfNN_bfd_is_local_label_name \
5645
        elfNN_ia64_is_local_label_name
5646
#define bfd_elfNN_bfd_relax_section \
5647
        elfNN_ia64_relax_section
5648
 
5649
#define elf_backend_object_p \
5650
        elfNN_ia64_object_p
5651
 
5652
/* Stuff for the BFD linker: */
5653
#define bfd_elfNN_bfd_link_hash_table_create \
5654
        elfNN_ia64_hash_table_create
5655
#define bfd_elfNN_bfd_link_hash_table_free \
5656
        elfNN_ia64_hash_table_free
5657
#define elf_backend_create_dynamic_sections \
5658
        elfNN_ia64_create_dynamic_sections
5659
#define elf_backend_check_relocs \
5660
        elfNN_ia64_check_relocs
5661
#define elf_backend_adjust_dynamic_symbol \
5662
        elfNN_ia64_adjust_dynamic_symbol
5663
#define elf_backend_size_dynamic_sections \
5664
        elfNN_ia64_size_dynamic_sections
5665
#define elf_backend_omit_section_dynsym \
5666
  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
5667
#define elf_backend_relocate_section \
5668
        elfNN_ia64_relocate_section
5669
#define elf_backend_finish_dynamic_symbol \
5670
        elfNN_ia64_finish_dynamic_symbol
5671
#define elf_backend_finish_dynamic_sections \
5672
        elfNN_ia64_finish_dynamic_sections
5673
#define bfd_elfNN_bfd_final_link \
5674
        elfNN_ia64_final_link
5675
 
5676
#define bfd_elfNN_bfd_merge_private_bfd_data \
5677
        elfNN_ia64_merge_private_bfd_data
5678
#define bfd_elfNN_bfd_set_private_flags \
5679
        elfNN_ia64_set_private_flags
5680
#define bfd_elfNN_bfd_print_private_bfd_data \
5681
        elfNN_ia64_print_private_bfd_data
5682
 
5683
#define elf_backend_plt_readonly        1
5684
#define elf_backend_want_plt_sym        0
5685
#define elf_backend_plt_alignment       5
5686
#define elf_backend_got_header_size     0
5687
#define elf_backend_want_got_plt        1
5688
#define elf_backend_may_use_rel_p       1
5689
#define elf_backend_may_use_rela_p      1
5690
#define elf_backend_default_use_rela_p  1
5691
#define elf_backend_want_dynbss         0
5692
#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5693
#define elf_backend_hide_symbol         elfNN_ia64_hash_hide_symbol
5694
#define elf_backend_fixup_symbol        _bfd_elf_link_hash_fixup_symbol
5695
#define elf_backend_reloc_type_class    elfNN_ia64_reloc_type_class
5696
#define elf_backend_rela_normal         1
5697
#define elf_backend_special_sections    elfNN_ia64_special_sections
5698
#define elf_backend_default_execstack   0
5699
 
5700
/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5701
   SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5702
   We don't want to flood users with so many error messages. We turn
5703
   off the warning for now. It will be turned on later when the Intel
5704
   compiler is fixed.   */
5705
#define elf_backend_link_order_error_handler NULL
5706
 
5707
#include "elfNN-target.h"
5708
 
5709
/* HPUX-specific vectors.  */
5710
 
5711
#undef  TARGET_LITTLE_SYM
5712
#undef  TARGET_LITTLE_NAME
5713
#undef  TARGET_BIG_SYM
5714
#define TARGET_BIG_SYM                  bfd_elfNN_ia64_hpux_big_vec
5715
#undef  TARGET_BIG_NAME
5716
#define TARGET_BIG_NAME                 "elfNN-ia64-hpux-big"
5717
 
5718
/* These are HP-UX specific functions.  */
5719
 
5720
#undef  elf_backend_post_process_headers
5721
#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5722
 
5723
#undef  elf_backend_section_from_bfd_section
5724
#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5725
 
5726
#undef elf_backend_symbol_processing
5727
#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5728
 
5729
#undef  elf_backend_want_p_paddr_set_to_zero
5730
#define elf_backend_want_p_paddr_set_to_zero 1
5731
 
5732
#undef ELF_COMMONPAGESIZE
5733
#undef ELF_OSABI
5734
#define ELF_OSABI                       ELFOSABI_HPUX
5735
 
5736
#undef  elfNN_bed
5737
#define elfNN_bed elfNN_ia64_hpux_bed
5738
 
5739
#include "elfNN-target.h"
5740
 
5741
#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.