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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [bfd/] [elfxx-ia64.c] - Blame information for rev 859

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

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

powered by: WebSVN 2.1.0

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