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

Subversion Repositories openrisc_me

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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