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/] [gdb-7.1/] [bfd/] [elfxx-ia64.c] - Blame information for rev 517

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

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

powered by: WebSVN 2.1.0

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