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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [elfxx-ia64.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* IA-64 support for 64-bit ELF
2
   Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
 
5
This file is part of BFD, the Binary File Descriptor library.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "bfd.h"
22
#include "sysdep.h"
23
#include "libbfd.h"
24
#include "elf-bfd.h"
25
#include "opcode/ia64.h"
26
#include "elf/ia64.h"
27
 
28
/*
29
 * THE RULES for all the stuff the linker creates --
30
 *
31
 * GOT          Entries created in response to LTOFF or LTOFF_FPTR
32
 *              relocations.  Dynamic relocs created for dynamic
33
 *              symbols in an application; REL relocs for locals
34
 *              in a shared library.
35
 *
36
 * FPTR         The canonical function descriptor.  Created for local
37
 *              symbols in applications.  Descriptors for dynamic symbols
38
 *              and local symbols in shared libraries are created by
39
 *              ld.so.  Thus there are no dynamic relocs against these
40
 *              objects.  The FPTR relocs for such _are_ passed through
41
 *              to the dynamic relocation tables.
42
 *
43
 * FULL_PLT     Created for a PCREL21B relocation against a dynamic symbol.
44
 *              Requires the creation of a PLTOFF entry.  This does not
45
 *              require any dynamic relocations.
46
 *
47
 * PLTOFF       Created by PLTOFF relocations.  For local symbols, this
48
 *              is an alternate function descriptor, and in shared libraries
49
 *              requires two REL relocations.  Note that this cannot be
50
 *              transformed into an FPTR relocation, since it must be in
51
 *              range of the GP.  For dynamic symbols, this is a function
52
 *              descriptor for a MIN_PLT entry, and requires one IPLT reloc.
53
 *
54
 * MIN_PLT      Created by PLTOFF entries against dynamic symbols.  This
55
 *              does not reqire dynamic relocations.
56
 */
57
 
58
#define USE_RELA                /* we want RELA relocs, not REL */
59
 
60
#define NELEMS(a)       ((int) (sizeof (a) / sizeof ((a)[0])))
61
 
62
typedef struct bfd_hash_entry *(*new_hash_entry_func)
63
  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
64
 
65
/* In dynamically (linker-) created sections, we generally need to keep track
66
   of the place a symbol or expression got allocated to. This is done via hash
67
   tables that store entries of the following type.  */
68
 
69
struct elfNN_ia64_dyn_sym_info
70
{
71
  /* The addend for which this entry is relevant.  */
72
  bfd_vma addend;
73
 
74
  /* Next addend in the list.  */
75
  struct elfNN_ia64_dyn_sym_info *next;
76
 
77
  bfd_vma got_offset;
78
  bfd_vma fptr_offset;
79
  bfd_vma pltoff_offset;
80
  bfd_vma plt_offset;
81
  bfd_vma plt2_offset;
82
 
83
  /* The symbol table entry, if any, that this was derrived from.  */
84
  struct elf_link_hash_entry *h;
85
 
86
  /* Used to count non-got, non-plt relocations for delayed sizing
87
     of relocation sections.  */
88
  struct elfNN_ia64_dyn_reloc_entry
89
  {
90
    struct elfNN_ia64_dyn_reloc_entry *next;
91
    asection *srel;
92
    int type;
93
    int count;
94
  } *reloc_entries;
95
 
96
  /* True when the section contents have been updated.  */
97
  unsigned got_done : 1;
98
  unsigned fptr_done : 1;
99
  unsigned pltoff_done : 1;
100
 
101
  /* True for the different kinds of linker data we want created.  */
102
  unsigned want_got : 1;
103
  unsigned want_fptr : 1;
104
  unsigned want_ltoff_fptr : 1;
105
  unsigned want_plt : 1;
106
  unsigned want_plt2 : 1;
107
  unsigned want_pltoff : 1;
108
};
109
 
110
struct elfNN_ia64_local_hash_entry
111
{
112
  struct bfd_hash_entry root;
113
  struct elfNN_ia64_dyn_sym_info *info;
114
};
115
 
116
struct elfNN_ia64_local_hash_table
117
{
118
  struct bfd_hash_table root;
119
  /* No additional fields for now.  */
120
};
121
 
122
struct elfNN_ia64_link_hash_entry
123
{
124
  struct elf_link_hash_entry root;
125
  struct elfNN_ia64_dyn_sym_info *info;
126
};
127
 
128
struct elfNN_ia64_link_hash_table
129
{
130
  /* The main hash table */
131
  struct elf_link_hash_table root;
132
 
133
  asection *got_sec;            /* the linkage table section (or NULL) */
134
  asection *rel_got_sec;        /* dynamic relocation section for same */
135
  asection *fptr_sec;           /* function descriptor table (or NULL) */
136
  asection *plt_sec;            /* the primary plt section (or NULL) */
137
  asection *pltoff_sec;         /* private descriptors for plt (or NULL) */
138
  asection *rel_pltoff_sec;     /* dynamic relocation section for same */
139
 
140
  bfd_size_type minplt_entries; /* number of minplt entries */
141
 
142
  struct elfNN_ia64_local_hash_table loc_hash_table;
143
};
144
 
145
#define elfNN_ia64_hash_table(p) \
146
  ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
147
 
148
static bfd_reloc_status_type elfNN_ia64_reloc
149
  PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
150
           asection *input_section, bfd *output_bfd, char **error_message));
151
static reloc_howto_type * lookup_howto
152
  PARAMS ((unsigned int rtype));
153
static reloc_howto_type *elfNN_ia64_reloc_type_lookup
154
  PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
155
static void elfNN_ia64_info_to_howto
156
  PARAMS ((bfd *abfd, arelent *bfd_reloc, ElfNN_Internal_Rela *elf_reloc));
157
static boolean elfNN_ia64_relax_section
158
  PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
159
          boolean *again));
160
static boolean is_unwind_section_name
161
  PARAMS ((const char *));
162
static boolean elfNN_ia64_section_from_shdr
163
  PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *));
164
static boolean elfNN_ia64_fake_sections
165
  PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec));
166
static void elfNN_ia64_final_write_processing
167
  PARAMS ((bfd *abfd, boolean linker));
168
static boolean elfNN_ia64_add_symbol_hook
169
  PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
170
           const char **namep, flagword *flagsp, asection **secp,
171
           bfd_vma *valp));
172
static boolean elfNN_ia64_aix_vec
173
  PARAMS ((const bfd_target *vec));
174
static boolean elfNN_ia64_aix_add_symbol_hook
175
  PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
176
           const char **namep, flagword *flagsp, asection **secp,
177
           bfd_vma *valp));
178
static boolean elfNN_ia64_aix_link_add_symbols
179
  PARAMS ((bfd *abfd, struct bfd_link_info *info));
180
static int elfNN_ia64_additional_program_headers
181
  PARAMS ((bfd *abfd));
182
static boolean elfNN_ia64_is_local_label_name
183
  PARAMS ((bfd *abfd, const char *name));
184
static boolean elfNN_ia64_dynamic_symbol_p
185
  PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
186
static boolean elfNN_ia64_local_hash_table_init
187
  PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
188
           new_hash_entry_func new));
189
static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
190
  PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
191
           const char *string));
192
static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
193
  PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
194
           const char *string));
195
static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
196
  PARAMS ((bfd *abfd));
197
static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
198
  PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
199
           boolean create, boolean copy));
200
static void elfNN_ia64_dyn_sym_traverse
201
  PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
202
           boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
203
           PTR info));
204
static boolean elfNN_ia64_create_dynamic_sections
205
  PARAMS ((bfd *abfd, struct bfd_link_info *info));
206
static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
207
  PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
208
           struct elf_link_hash_entry *h,
209
           bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
210
static asection *get_got
211
  PARAMS ((bfd *abfd, struct bfd_link_info *info,
212
           struct elfNN_ia64_link_hash_table *ia64_info));
213
static asection *get_fptr
214
  PARAMS ((bfd *abfd, struct bfd_link_info *info,
215
           struct elfNN_ia64_link_hash_table *ia64_info));
216
static asection *get_pltoff
217
  PARAMS ((bfd *abfd, struct bfd_link_info *info,
218
           struct elfNN_ia64_link_hash_table *ia64_info));
219
static asection *get_reloc_section
220
  PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
221
           asection *sec, boolean create));
222
static boolean count_dyn_reloc
223
  PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
224
           asection *srel, int type));
225
static boolean elfNN_ia64_check_relocs
226
  PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
227
           const Elf_Internal_Rela *relocs));
228
static boolean elfNN_ia64_adjust_dynamic_symbol
229
  PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
230
static unsigned long global_sym_index
231
  PARAMS ((struct elf_link_hash_entry *h));
232
static boolean allocate_fptr
233
  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
234
static boolean allocate_global_data_got
235
  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
236
static boolean allocate_global_fptr_got
237
  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
238
static boolean allocate_local_got
239
  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
240
static boolean allocate_pltoff_entries
241
  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
242
static boolean allocate_plt_entries
243
  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
244
static boolean allocate_plt2_entries
245
  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
246
static boolean allocate_dynrel_entries
247
  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
248
static boolean elfNN_ia64_size_dynamic_sections
249
  PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
250
static bfd_reloc_status_type elfNN_ia64_install_value
251
  PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
252
static void elfNN_ia64_install_dyn_reloc
253
  PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
254
           asection *srel, bfd_vma offset, unsigned int type,
255
           long dynindx, bfd_vma addend));
256
static bfd_vma set_got_entry
257
  PARAMS ((bfd *abfd, struct bfd_link_info *info,
258
           struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
259
           bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
260
static bfd_vma set_fptr_entry
261
  PARAMS ((bfd *abfd, struct bfd_link_info *info,
262
           struct elfNN_ia64_dyn_sym_info *dyn_i,
263
           bfd_vma value));
264
static bfd_vma set_pltoff_entry
265
  PARAMS ((bfd *abfd, struct bfd_link_info *info,
266
           struct elfNN_ia64_dyn_sym_info *dyn_i,
267
           bfd_vma value, boolean));
268
static boolean elfNN_ia64_final_link
269
  PARAMS ((bfd *abfd, struct bfd_link_info *info));
270
static boolean elfNN_ia64_relocate_section
271
  PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
272
           asection *input_section, bfd_byte *contents,
273
           Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
274
           asection **local_sections));
275
static boolean elfNN_ia64_finish_dynamic_symbol
276
  PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
277
           struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
278
static boolean elfNN_ia64_finish_dynamic_sections
279
  PARAMS ((bfd *abfd, struct bfd_link_info *info));
280
static boolean elfNN_ia64_set_private_flags
281
  PARAMS ((bfd *abfd, flagword flags));
282
static boolean elfNN_ia64_copy_private_bfd_data
283
  PARAMS ((bfd *ibfd, bfd *obfd));
284
static boolean elfNN_ia64_merge_private_bfd_data
285
  PARAMS ((bfd *ibfd, bfd *obfd));
286
static boolean elfNN_ia64_print_private_bfd_data
287
  PARAMS ((bfd *abfd, PTR ptr));
288
 
289
/* ia64-specific relocation */
290
 
291
/* Perform a relocation.  Not much to do here as all the hard work is
292
   done in elfNN_ia64_final_link_relocate.  */
293
static bfd_reloc_status_type
294
elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
295
                  output_bfd, error_message)
296
     bfd *abfd ATTRIBUTE_UNUSED;
297
     arelent *reloc;
298
     asymbol *sym ATTRIBUTE_UNUSED;
299
     PTR data ATTRIBUTE_UNUSED;
300
     asection *input_section;
301
     bfd *output_bfd;
302
     char **error_message;
303
{
304
  if (output_bfd)
305
    {
306
      reloc->address += input_section->output_offset;
307
      return bfd_reloc_ok;
308
    }
309
  *error_message = "Unsupported call to elfNN_ia64_reloc";
310
  return bfd_reloc_notsupported;
311
}
312
 
313
#define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN)                 \
314
  HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed,     \
315
         elfNN_ia64_reloc, NAME, false, 0, 0, IN)
316
 
317
/* This table has to be sorted according to increasing number of the
318
   TYPE field.  */
319
static reloc_howto_type ia64_howto_table[] =
320
  {
321
    IA64_HOWTO (R_IA64_NONE,        "NONE",        0, false, true),
322
 
323
    IA64_HOWTO (R_IA64_IMM14,       "IMM14",       0, false, true),
324
    IA64_HOWTO (R_IA64_IMM22,       "IMM22",       0, false, true),
325
    IA64_HOWTO (R_IA64_IMM64,       "IMM64",       0, false, true),
326
    IA64_HOWTO (R_IA64_DIR32MSB,    "DIR32MSB",    2, false, true),
327
    IA64_HOWTO (R_IA64_DIR32LSB,    "DIR32LSB",    2, false, true),
328
    IA64_HOWTO (R_IA64_DIR64MSB,    "DIR64MSB",    4, false, true),
329
    IA64_HOWTO (R_IA64_DIR64LSB,    "DIR64LSB",    4, false, true),
330
 
331
    IA64_HOWTO (R_IA64_GPREL22,     "GPREL22",     0, false, true),
332
    IA64_HOWTO (R_IA64_GPREL64I,    "GPREL64I",    0, false, true),
333
    IA64_HOWTO (R_IA64_GPREL32MSB,  "GPREL32MSB",  2, false, true),
334
    IA64_HOWTO (R_IA64_GPREL32LSB,  "GPREL32LSB",  2, false, true),
335
    IA64_HOWTO (R_IA64_GPREL64MSB,  "GPREL64MSB",  4, false, true),
336
    IA64_HOWTO (R_IA64_GPREL64LSB,  "GPREL64LSB",  4, false, true),
337
 
338
    IA64_HOWTO (R_IA64_LTOFF22,     "LTOFF22",     0, false, true),
339
    IA64_HOWTO (R_IA64_LTOFF64I,    "LTOFF64I",    0, false, true),
340
 
341
    IA64_HOWTO (R_IA64_PLTOFF22,    "PLTOFF22",    0, false, true),
342
    IA64_HOWTO (R_IA64_PLTOFF64I,   "PLTOFF64I",   0, false, true),
343
    IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
344
    IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
345
 
346
    IA64_HOWTO (R_IA64_FPTR64I,     "FPTR64I",     0, false, true),
347
    IA64_HOWTO (R_IA64_FPTR32MSB,   "FPTR32MSB",   2, false, true),
348
    IA64_HOWTO (R_IA64_FPTR32LSB,   "FPTR32LSB",   2, false, true),
349
    IA64_HOWTO (R_IA64_FPTR64MSB,   "FPTR64MSB",   4, false, true),
350
    IA64_HOWTO (R_IA64_FPTR64LSB,   "FPTR64LSB",   4, false, true),
351
 
352
    IA64_HOWTO (R_IA64_PCREL60B,    "PCREL60B",    0, true, true),
353
    IA64_HOWTO (R_IA64_PCREL21B,    "PCREL21B",    0, true, true),
354
    IA64_HOWTO (R_IA64_PCREL21M,    "PCREL21M",    0, true, true),
355
    IA64_HOWTO (R_IA64_PCREL21F,    "PCREL21F",    0, true, true),
356
    IA64_HOWTO (R_IA64_PCREL32MSB,  "PCREL32MSB",  2, true, true),
357
    IA64_HOWTO (R_IA64_PCREL32LSB,  "PCREL32LSB",  2, true, true),
358
    IA64_HOWTO (R_IA64_PCREL64MSB,  "PCREL64MSB",  4, true, true),
359
    IA64_HOWTO (R_IA64_PCREL64LSB,  "PCREL64LSB",  4, true, true),
360
 
361
    IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
362
    IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
363
    IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
364
    IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
365
 
366
    IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
367
    IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
368
    IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
369
    IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
370
 
371
    IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
372
    IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
373
    IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
374
    IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
375
 
376
    IA64_HOWTO (R_IA64_REL32MSB,    "REL32MSB",    2, false, true),
377
    IA64_HOWTO (R_IA64_REL32LSB,    "REL32LSB",    2, false, true),
378
    IA64_HOWTO (R_IA64_REL64MSB,    "REL64MSB",    4, false, true),
379
    IA64_HOWTO (R_IA64_REL64LSB,    "REL64LSB",    4, false, true),
380
 
381
    IA64_HOWTO (R_IA64_LTV32MSB,    "LTV32MSB",    2, false, true),
382
    IA64_HOWTO (R_IA64_LTV32LSB,    "LTV32LSB",    2, false, true),
383
    IA64_HOWTO (R_IA64_LTV64MSB,    "LTV64MSB",    4, false, true),
384
    IA64_HOWTO (R_IA64_LTV64LSB,    "LTV64LSB",    4, false, true),
385
 
386
    IA64_HOWTO (R_IA64_PCREL21BI,   "PCREL21BI",   0, true, true),
387
    IA64_HOWTO (R_IA64_PCREL22,     "PCREL22",     0, true, true),
388
    IA64_HOWTO (R_IA64_PCREL64I,    "PCREL64I",    0, true, true),
389
 
390
    IA64_HOWTO (R_IA64_IPLTMSB,     "IPLTMSB",     4, false, true),
391
    IA64_HOWTO (R_IA64_IPLTLSB,     "IPLTLSB",     4, false, true),
392
    IA64_HOWTO (R_IA64_COPY,        "COPY",        4, false, true),
393
    IA64_HOWTO (R_IA64_LTOFF22X,    "LTOFF22X",    0, false, true),
394
    IA64_HOWTO (R_IA64_LDXMOV,      "LDXMOV",      0, false, true),
395
 
396
    IA64_HOWTO (R_IA64_TPREL22,     "TPREL22",     0, false, false),
397
    IA64_HOWTO (R_IA64_TPREL64MSB,  "TPREL64MSB",  8, false, false),
398
    IA64_HOWTO (R_IA64_TPREL64LSB,  "TPREL64LSB",  8, false, false),
399
    IA64_HOWTO (R_IA64_LTOFF_TP22,  "LTOFF_TP22",  0, false, false),
400
  };
401
 
402
static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
403
 
404
/* Given a BFD reloc type, return the matching HOWTO structure.  */
405
 
406
static reloc_howto_type*
407
lookup_howto (rtype)
408
     unsigned int rtype;
409
{
410
  static int inited = 0;
411
  int i;
412
 
413
  if (!inited)
414
    {
415
      inited = 1;
416
 
417
      memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
418
      for (i = 0; i < NELEMS (ia64_howto_table); ++i)
419
        elf_code_to_howto_index[ia64_howto_table[i].type] = i;
420
    }
421
 
422
  BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
423
  i = elf_code_to_howto_index[rtype];
424
  if (i >= NELEMS (ia64_howto_table))
425
    return 0;
426
  return ia64_howto_table + i;
427
}
428
 
429
static reloc_howto_type*
430
elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
431
     bfd *abfd ATTRIBUTE_UNUSED;
432
     bfd_reloc_code_real_type bfd_code;
433
{
434
  unsigned int rtype;
435
 
436
  switch (bfd_code)
437
    {
438
    case BFD_RELOC_NONE:                rtype = R_IA64_NONE; break;
439
 
440
    case BFD_RELOC_IA64_IMM14:          rtype = R_IA64_IMM14; break;
441
    case BFD_RELOC_IA64_IMM22:          rtype = R_IA64_IMM22; break;
442
    case BFD_RELOC_IA64_IMM64:          rtype = R_IA64_IMM64; break;
443
 
444
    case BFD_RELOC_IA64_DIR32MSB:       rtype = R_IA64_DIR32MSB; break;
445
    case BFD_RELOC_IA64_DIR32LSB:       rtype = R_IA64_DIR32LSB; break;
446
    case BFD_RELOC_IA64_DIR64MSB:       rtype = R_IA64_DIR64MSB; break;
447
    case BFD_RELOC_IA64_DIR64LSB:       rtype = R_IA64_DIR64LSB; break;
448
 
449
    case BFD_RELOC_IA64_GPREL22:        rtype = R_IA64_GPREL22; break;
450
    case BFD_RELOC_IA64_GPREL64I:       rtype = R_IA64_GPREL64I; break;
451
    case BFD_RELOC_IA64_GPREL32MSB:     rtype = R_IA64_GPREL32MSB; break;
452
    case BFD_RELOC_IA64_GPREL32LSB:     rtype = R_IA64_GPREL32LSB; break;
453
    case BFD_RELOC_IA64_GPREL64MSB:     rtype = R_IA64_GPREL64MSB; break;
454
    case BFD_RELOC_IA64_GPREL64LSB:     rtype = R_IA64_GPREL64LSB; break;
455
 
456
    case BFD_RELOC_IA64_LTOFF22:        rtype = R_IA64_LTOFF22; break;
457
    case BFD_RELOC_IA64_LTOFF64I:       rtype = R_IA64_LTOFF64I; break;
458
 
459
    case BFD_RELOC_IA64_PLTOFF22:       rtype = R_IA64_PLTOFF22; break;
460
    case BFD_RELOC_IA64_PLTOFF64I:      rtype = R_IA64_PLTOFF64I; break;
461
    case BFD_RELOC_IA64_PLTOFF64MSB:    rtype = R_IA64_PLTOFF64MSB; break;
462
    case BFD_RELOC_IA64_PLTOFF64LSB:    rtype = R_IA64_PLTOFF64LSB; break;
463
    case BFD_RELOC_IA64_FPTR64I:        rtype = R_IA64_FPTR64I; break;
464
    case BFD_RELOC_IA64_FPTR32MSB:      rtype = R_IA64_FPTR32MSB; break;
465
    case BFD_RELOC_IA64_FPTR32LSB:      rtype = R_IA64_FPTR32LSB; break;
466
    case BFD_RELOC_IA64_FPTR64MSB:      rtype = R_IA64_FPTR64MSB; break;
467
    case BFD_RELOC_IA64_FPTR64LSB:      rtype = R_IA64_FPTR64LSB; break;
468
 
469
    case BFD_RELOC_IA64_PCREL21B:       rtype = R_IA64_PCREL21B; break;
470
    case BFD_RELOC_IA64_PCREL21BI:      rtype = R_IA64_PCREL21BI; break;
471
    case BFD_RELOC_IA64_PCREL21M:       rtype = R_IA64_PCREL21M; break;
472
    case BFD_RELOC_IA64_PCREL21F:       rtype = R_IA64_PCREL21F; break;
473
    case BFD_RELOC_IA64_PCREL22:        rtype = R_IA64_PCREL22; break;
474
    case BFD_RELOC_IA64_PCREL60B:       rtype = R_IA64_PCREL60B; break;
475
    case BFD_RELOC_IA64_PCREL64I:       rtype = R_IA64_PCREL64I; break;
476
    case BFD_RELOC_IA64_PCREL32MSB:     rtype = R_IA64_PCREL32MSB; break;
477
    case BFD_RELOC_IA64_PCREL32LSB:     rtype = R_IA64_PCREL32LSB; break;
478
    case BFD_RELOC_IA64_PCREL64MSB:     rtype = R_IA64_PCREL64MSB; break;
479
    case BFD_RELOC_IA64_PCREL64LSB:     rtype = R_IA64_PCREL64LSB; break;
480
 
481
    case BFD_RELOC_IA64_LTOFF_FPTR22:   rtype = R_IA64_LTOFF_FPTR22; break;
482
    case BFD_RELOC_IA64_LTOFF_FPTR64I:  rtype = R_IA64_LTOFF_FPTR64I; break;
483
    case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
484
    case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
485
 
486
    case BFD_RELOC_IA64_SEGREL32MSB:    rtype = R_IA64_SEGREL32MSB; break;
487
    case BFD_RELOC_IA64_SEGREL32LSB:    rtype = R_IA64_SEGREL32LSB; break;
488
    case BFD_RELOC_IA64_SEGREL64MSB:    rtype = R_IA64_SEGREL64MSB; break;
489
    case BFD_RELOC_IA64_SEGREL64LSB:    rtype = R_IA64_SEGREL64LSB; break;
490
 
491
    case BFD_RELOC_IA64_SECREL32MSB:    rtype = R_IA64_SECREL32MSB; break;
492
    case BFD_RELOC_IA64_SECREL32LSB:    rtype = R_IA64_SECREL32LSB; break;
493
    case BFD_RELOC_IA64_SECREL64MSB:    rtype = R_IA64_SECREL64MSB; break;
494
    case BFD_RELOC_IA64_SECREL64LSB:    rtype = R_IA64_SECREL64LSB; break;
495
 
496
    case BFD_RELOC_IA64_REL32MSB:       rtype = R_IA64_REL32MSB; break;
497
    case BFD_RELOC_IA64_REL32LSB:       rtype = R_IA64_REL32LSB; break;
498
    case BFD_RELOC_IA64_REL64MSB:       rtype = R_IA64_REL64MSB; break;
499
    case BFD_RELOC_IA64_REL64LSB:       rtype = R_IA64_REL64LSB; break;
500
 
501
    case BFD_RELOC_IA64_LTV32MSB:       rtype = R_IA64_LTV32MSB; break;
502
    case BFD_RELOC_IA64_LTV32LSB:       rtype = R_IA64_LTV32LSB; break;
503
    case BFD_RELOC_IA64_LTV64MSB:       rtype = R_IA64_LTV64MSB; break;
504
    case BFD_RELOC_IA64_LTV64LSB:       rtype = R_IA64_LTV64LSB; break;
505
 
506
    case BFD_RELOC_IA64_IPLTMSB:        rtype = R_IA64_IPLTMSB; break;
507
    case BFD_RELOC_IA64_IPLTLSB:        rtype = R_IA64_IPLTLSB; break;
508
    case BFD_RELOC_IA64_COPY:           rtype = R_IA64_COPY; break;
509
    case BFD_RELOC_IA64_LTOFF22X:       rtype = R_IA64_LTOFF22X; break;
510
    case BFD_RELOC_IA64_LDXMOV:         rtype = R_IA64_LDXMOV; break;
511
 
512
    case BFD_RELOC_IA64_TPREL22:        rtype = R_IA64_TPREL22; break;
513
    case BFD_RELOC_IA64_TPREL64MSB:     rtype = R_IA64_TPREL64MSB; break;
514
    case BFD_RELOC_IA64_TPREL64LSB:     rtype = R_IA64_TPREL64LSB; break;
515
    case BFD_RELOC_IA64_LTOFF_TP22:     rtype = R_IA64_LTOFF_TP22; break;
516
 
517
    default: return 0;
518
    }
519
  return lookup_howto (rtype);
520
}
521
 
522
/* Given a ELF reloc, return the matching HOWTO structure.  */
523
 
524
static void
525
elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
526
     bfd *abfd ATTRIBUTE_UNUSED;
527
     arelent *bfd_reloc;
528
     ElfNN_Internal_Rela *elf_reloc;
529
{
530
  bfd_reloc->howto = lookup_howto (ELFNN_R_TYPE (elf_reloc->r_info));
531
}
532
 
533
#define PLT_HEADER_SIZE         (3 * 16)
534
#define PLT_MIN_ENTRY_SIZE      (1 * 16)
535
#define PLT_FULL_ENTRY_SIZE     (2 * 16)
536
#define PLT_RESERVED_WORDS      3
537
 
538
static const bfd_byte plt_header[PLT_HEADER_SIZE] =
539
{
540
  0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21,  /*   [MMI]       mov r2=r14;;       */
541
  0xe0, 0x00, 0x08, 0x00, 0x48, 0x00,  /*               addl r14=0,r2      */
542
  0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
543
  0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14,  /*   [MMI]       ld8 r16=[r14],8;;  */
544
  0x10, 0x41, 0x38, 0x30, 0x28, 0x00,  /*               ld8 r17=[r14],8    */
545
  0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
546
  0x11, 0x08, 0x00, 0x1c, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r14]       */
547
  0x60, 0x88, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r17         */
548
  0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
549
};
550
 
551
static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
552
{
553
  0x11, 0x78, 0x00, 0x00, 0x00, 0x24,  /*   [MIB]       mov r15=0          */
554
  0x00, 0x00, 0x00, 0x02, 0x00, 0x00,  /*               nop.i 0x0          */
555
  0x00, 0x00, 0x00, 0x40               /*               br.few 0 <PLT0>;;  */
556
};
557
 
558
static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
559
{
560
  0x0b, 0x78, 0x00, 0x02, 0x00, 0x24,  /*   [MMI]       addl r15=0,r1;;    */
561
  0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0,  /*               ld8 r16=[r15],8    */
562
  0x01, 0x08, 0x00, 0x84,              /*               mov r14=r1;;       */
563
  0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r15]       */
564
  0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
565
  0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
566
};
567
 
568
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
569
#define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
570
#define DYNAMIC_INTERPRETER(abfd) \
571
  (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
572
 
573
/* Select out of range branch fixup type.  Note that Itanium does
574
   not support brl, and so it gets emulated by the kernel.  */
575
#undef USE_BRL
576
 
577
static const bfd_byte oor_brl[16] =
578
{
579
  0x05, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
580
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /*               brl.sptk.few tgt;; */
581
  0x00, 0x00, 0x00, 0xc0
582
};
583
 
584
static const bfd_byte oor_ip[48] =
585
{
586
  0x04, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
587
  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,  /*               movl r15=0         */
588
  0x01, 0x00, 0x00, 0x60,
589
  0x03, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MII]        nop.m 0            */
590
  0x00, 0x01, 0x00, 0x60, 0x00, 0x00,  /*               mov r16=ip;;       */
591
  0xf2, 0x80, 0x00, 0x80,              /*               add r16=r15,r16;;  */
592
  0x11, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MIB]        nop.m 0            */
593
  0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
594
  0x60, 0x00, 0x80, 0x00               /*               br b6;;            */
595
};
596
 
597
/* These functions do relaxation for IA-64 ELF.
598
 
599
   This is primarily to support branches to targets out of range;
600
   relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported.  */
601
 
602
static boolean
603
elfNN_ia64_relax_section (abfd, sec, link_info, again)
604
     bfd *abfd;
605
     asection *sec;
606
     struct bfd_link_info *link_info;
607
     boolean *again;
608
{
609
  struct one_fixup
610
    {
611
      struct one_fixup *next;
612
      asection *tsec;
613
      bfd_vma toff;
614
      bfd_vma trampoff;
615
    };
616
 
617
  Elf_Internal_Shdr *symtab_hdr;
618
  Elf_Internal_Rela *internal_relocs;
619
  Elf_Internal_Rela *free_relocs = NULL;
620
  Elf_Internal_Rela *irel, *irelend;
621
  bfd_byte *contents;
622
  bfd_byte *free_contents = NULL;
623
  ElfNN_External_Sym *extsyms;
624
  ElfNN_External_Sym *free_extsyms = NULL;
625
  struct elfNN_ia64_link_hash_table *ia64_info;
626
  struct one_fixup *fixups = NULL;
627
  boolean changed_contents = false;
628
  boolean changed_relocs = false;
629
 
630
  /* Assume we're not going to change any sizes, and we'll only need
631
     one pass.  */
632
  *again = false;
633
 
634
  /* Nothing to do if there are no relocations.  */
635
  if ((sec->flags & SEC_RELOC) == 0
636
      || sec->reloc_count == 0)
637
    return true;
638
 
639
  /* If this is the first time we have been called for this section,
640
     initialize the cooked size.  */
641
  if (sec->_cooked_size == 0)
642
    sec->_cooked_size = sec->_raw_size;
643
 
644
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
645
 
646
  /* Load the relocations for this section.  */
647
  internal_relocs = (_bfd_elfNN_link_read_relocs
648
                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
649
                      link_info->keep_memory));
650
  if (internal_relocs == NULL)
651
    goto error_return;
652
 
653
  if (! link_info->keep_memory)
654
    free_relocs = internal_relocs;
655
 
656
  ia64_info = elfNN_ia64_hash_table (link_info);
657
  irelend = internal_relocs + sec->reloc_count;
658
 
659
  for (irel = internal_relocs; irel < irelend; irel++)
660
    if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
661
      break;
662
 
663
  /* No branch-type relocations.  */
664
  if (irel == irelend)
665
    {
666
      if (free_relocs != NULL)
667
        free (free_relocs);
668
      return true;
669
    }
670
 
671
  /* Get the section contents.  */
672
  if (elf_section_data (sec)->this_hdr.contents != NULL)
673
    contents = elf_section_data (sec)->this_hdr.contents;
674
  else
675
    {
676
      contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
677
      if (contents == NULL)
678
        goto error_return;
679
      free_contents = contents;
680
 
681
      if (! bfd_get_section_contents (abfd, sec, contents,
682
                                      (file_ptr) 0, sec->_raw_size))
683
        goto error_return;
684
    }
685
 
686
  /* Read this BFD's symbols.  */
687
  if (symtab_hdr->contents != NULL)
688
    extsyms = (ElfNN_External_Sym *) symtab_hdr->contents;
689
  else
690
    {
691
      extsyms = (ElfNN_External_Sym *) bfd_malloc (symtab_hdr->sh_size);
692
      if (extsyms == NULL)
693
        goto error_return;
694
      free_extsyms = extsyms;
695
      if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
696
          || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
697
              != symtab_hdr->sh_size))
698
        goto error_return;
699
    }
700
 
701
  for (; irel < irelend; irel++)
702
    {
703
      bfd_vma symaddr, reladdr, trampoff, toff, roff;
704
      Elf_Internal_Sym isym;
705
      asection *tsec;
706
      struct one_fixup *f;
707
 
708
      if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
709
        continue;
710
 
711
      /* Get the value of the symbol referred to by the reloc.  */
712
      if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
713
        {
714
          /* A local symbol.  */
715
          bfd_elfNN_swap_symbol_in (abfd,
716
                                    extsyms + ELFNN_R_SYM (irel->r_info),
717
                                    &isym);
718
          if (isym.st_shndx == SHN_UNDEF)
719
            continue;   /* We can't do anthing with undefined symbols.  */
720
          else if (isym.st_shndx == SHN_ABS)
721
            tsec = bfd_abs_section_ptr;
722
          else if (isym.st_shndx == SHN_COMMON)
723
            tsec = bfd_com_section_ptr;
724
          else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
725
            tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
726
          else
727
            continue;   /* who knows.  */
728
 
729
          toff = isym.st_value;
730
        }
731
      else
732
        {
733
          unsigned long indx;
734
          struct elf_link_hash_entry *h;
735
          struct elfNN_ia64_dyn_sym_info *dyn_i;
736
 
737
          indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
738
          h = elf_sym_hashes (abfd)[indx];
739
          BFD_ASSERT (h != NULL);
740
 
741
          while (h->root.type == bfd_link_hash_indirect
742
                 || h->root.type == bfd_link_hash_warning)
743
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
744
 
745
          dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
746
 
747
          /* For branches to dynamic symbols, we're interested instead
748
             in a branch to the PLT entry.  */
749
          if (dyn_i && dyn_i->want_plt2)
750
            {
751
              tsec = ia64_info->plt_sec;
752
              toff = dyn_i->plt2_offset;
753
            }
754
          else
755
            {
756
              /* We can't do anthing with undefined symbols.  */
757
              if (h->root.type == bfd_link_hash_undefined
758
                  || h->root.type == bfd_link_hash_undefweak)
759
                continue;
760
 
761
              tsec = h->root.u.def.section;
762
              toff = h->root.u.def.value;
763
            }
764
        }
765
 
766
      symaddr = (tsec->output_section->vma
767
                 + tsec->output_offset
768
                 + toff
769
                 + irel->r_addend);
770
 
771
      roff = irel->r_offset;
772
      reladdr = (sec->output_section->vma
773
                 + sec->output_offset
774
                 + roff) & -4;
775
 
776
      /* If the branch is in range, no need to do anything.  */
777
      if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
778
          && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
779
        continue;
780
 
781
      /* If the branch and target are in the same section, you've
782
         got one honking big section and we can't help you.  You'll
783
         get an error message later.  */
784
      if (tsec == sec)
785
        continue;
786
 
787
      /* Look for an existing fixup to this address.  */
788
      for (f = fixups; f ; f = f->next)
789
        if (f->tsec == tsec && f->toff == toff)
790
          break;
791
 
792
      if (f == NULL)
793
        {
794
          /* Two alternatives: If it's a branch to a PLT entry, we can
795
             make a copy of the FULL_PLT entry.  Otherwise, we'll have
796
             to use a `brl' insn to get where we're going.  */
797
 
798
          int size;
799
 
800
          if (tsec == ia64_info->plt_sec)
801
            size = sizeof (plt_full_entry);
802
          else
803
            {
804
#ifdef USE_BRL
805
              size = sizeof (oor_brl);
806
#else
807
              size = sizeof (oor_ip);
808
#endif
809
            }
810
 
811
          /* Resize the current section to make room for the new branch.  */
812
          trampoff = (sec->_cooked_size + 15) & -16;
813
          contents = (bfd_byte *) bfd_realloc (contents, trampoff + size);
814
          if (contents == NULL)
815
            goto error_return;
816
          sec->_cooked_size = trampoff + size;
817
 
818
          if (tsec == ia64_info->plt_sec)
819
            {
820
              memcpy (contents + trampoff, plt_full_entry, size);
821
 
822
              /* Hijack the old relocation for use as the PLTOFF reloc.  */
823
              irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
824
                                           R_IA64_PLTOFF22);
825
              irel->r_offset = trampoff;
826
            }
827
          else
828
            {
829
#ifdef USE_BRL
830
              memcpy (contents + trampoff, oor_brl, size);
831
              irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
832
                                           R_IA64_PCREL60B);
833
              irel->r_offset = trampoff + 2;
834
#else
835
              memcpy (contents + trampoff, oor_ip, size);
836
              irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
837
                                           R_IA64_PCREL64I);
838
              irel->r_addend -= 16;
839
              irel->r_offset = trampoff + 2;
840
#endif
841
            }
842
 
843
          /* Record the fixup so we don't do it again this section.  */
844
          f = (struct one_fixup *) bfd_malloc (sizeof (*f));
845
          f->next = fixups;
846
          f->tsec = tsec;
847
          f->toff = toff;
848
          f->trampoff = trampoff;
849
          fixups = f;
850
        }
851
      else
852
        {
853
          /* Nop out the reloc, since we're finalizing things here.  */
854
          irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
855
        }
856
 
857
      /* Fix up the existing branch to hit the trampoline.  Hope like
858
         hell this doesn't overflow too.  */
859
      if (elfNN_ia64_install_value (abfd, contents + roff,
860
                                    f->trampoff - (roff & -4),
861
                                    R_IA64_PCREL21B) != bfd_reloc_ok)
862
        goto error_return;
863
 
864
      changed_contents = true;
865
      changed_relocs = true;
866
    }
867
 
868
  /* Clean up and go home.  */
869
  while (fixups)
870
    {
871
      struct one_fixup *f = fixups;
872
      fixups = fixups->next;
873
      free (f);
874
    }
875
 
876
  if (changed_relocs)
877
    elf_section_data (sec)->relocs = internal_relocs;
878
  else if (free_relocs != NULL)
879
    free (free_relocs);
880
 
881
  if (changed_contents)
882
    elf_section_data (sec)->this_hdr.contents = contents;
883
  else if (free_contents != NULL)
884
    {
885
      if (! link_info->keep_memory)
886
        free (free_contents);
887
      else
888
        {
889
          /* Cache the section contents for elf_link_input_bfd.  */
890
          elf_section_data (sec)->this_hdr.contents = contents;
891
        }
892
    }
893
 
894
  if (free_extsyms != NULL)
895
    {
896
      if (! link_info->keep_memory)
897
        free (free_extsyms);
898
      else
899
        {
900
          /* Cache the symbols for elf_link_input_bfd.  */
901
          symtab_hdr->contents = extsyms;
902
        }
903
    }
904
 
905
  *again = changed_contents || changed_relocs;
906
  return true;
907
 
908
 error_return:
909
  if (free_relocs != NULL)
910
    free (free_relocs);
911
  if (free_contents != NULL)
912
    free (free_contents);
913
  if (free_extsyms != NULL)
914
    free (free_extsyms);
915
  return false;
916
}
917
 
918
/* Return true if NAME is an unwind table section name.  */
919
 
920
static inline boolean
921
is_unwind_section_name (name)
922
        const char *name;
923
{
924
  size_t len1, len2, len3;
925
 
926
  len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
927
  len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
928
  len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
929
  return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
930
           && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
931
          || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
932
}
933
 
934
/* Handle an IA-64 specific section when reading an object file.  This
935
   is called when elfcode.h finds a section with an unknown type.  */
936
 
937
static boolean
938
elfNN_ia64_section_from_shdr (abfd, hdr, name)
939
     bfd *abfd;
940
     ElfNN_Internal_Shdr *hdr;
941
     char *name;
942
{
943
  asection *newsect;
944
 
945
  /* There ought to be a place to keep ELF backend specific flags, but
946
     at the moment there isn't one.  We just keep track of the
947
     sections by their name, instead.  Fortunately, the ABI gives
948
     suggested names for all the MIPS specific sections, so we will
949
     probably get away with this.  */
950
  switch (hdr->sh_type)
951
    {
952
    case SHT_IA_64_UNWIND:
953
      break;
954
 
955
    case SHT_IA_64_EXT:
956
      if (strcmp (name, ELF_STRING_ia64_archext) != 0)
957
        return false;
958
      break;
959
 
960
    default:
961
      return false;
962
    }
963
 
964
  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
965
    return false;
966
  newsect = hdr->bfd_section;
967
 
968
  return true;
969
}
970
 
971
/* Convert IA-64 specific section flags to bfd internal section flags.  */
972
 
973
/* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
974
   flag.  */
975
 
976
static boolean
977
elfNN_ia64_section_flags (flags, hdr)
978
     flagword *flags;
979
     ElfNN_Internal_Shdr *hdr;
980
{
981
  if (hdr->sh_flags & SHF_IA_64_SHORT)
982
    *flags |= SEC_SMALL_DATA;
983
 
984
  return true;
985
}
986
 
987
/* Set the correct type for an IA-64 ELF section.  We do this by the
988
   section name, which is a hack, but ought to work.  */
989
 
990
static boolean
991
elfNN_ia64_fake_sections (abfd, hdr, sec)
992
     bfd *abfd ATTRIBUTE_UNUSED;
993
     ElfNN_Internal_Shdr *hdr;
994
     asection *sec;
995
{
996
  register const char *name;
997
 
998
  name = bfd_get_section_name (abfd, sec);
999
 
1000
  if (is_unwind_section_name (name))
1001
    {
1002
      /* We don't have the sections numbered at this point, so sh_info
1003
         is set later, in elfNN_ia64_final_write_processing.  */
1004
      hdr->sh_type = SHT_IA_64_UNWIND;
1005
      hdr->sh_flags |= SHF_LINK_ORDER;
1006
    }
1007
  else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1008
    hdr->sh_type = SHT_IA_64_EXT;
1009
  else if (strcmp (name, ".reloc") == 0)
1010
    /*
1011
     * This is an ugly, but unfortunately necessary hack that is
1012
     * needed when producing EFI binaries on IA-64. It tells
1013
     * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1014
     * containing ELF relocation info.  We need this hack in order to
1015
     * be able to generate ELF binaries that can be translated into
1016
     * EFI applications (which are essentially COFF objects).  Those
1017
     * files contain a COFF ".reloc" section inside an ELFNN object,
1018
     * which would normally cause BFD to segfault because it would
1019
     * attempt to interpret this section as containing relocation
1020
     * entries for section "oc".  With this hack enabled, ".reloc"
1021
     * will be treated as a normal data section, which will avoid the
1022
     * segfault.  However, you won't be able to create an ELFNN binary
1023
     * with a section named "oc" that needs relocations, but that's
1024
     * the kind of ugly side-effects you get when detecting section
1025
     * types based on their names...  In practice, this limitation is
1026
     * unlikely to bite.
1027
     */
1028
    hdr->sh_type = SHT_PROGBITS;
1029
 
1030
  if (sec->flags & SEC_SMALL_DATA)
1031
    hdr->sh_flags |= SHF_IA_64_SHORT;
1032
 
1033
  return true;
1034
}
1035
 
1036
/* The final processing done just before writing out an IA-64 ELF
1037
   object file.  */
1038
 
1039
static void
1040
elfNN_ia64_final_write_processing (abfd, linker)
1041
     bfd *abfd;
1042
     boolean linker ATTRIBUTE_UNUSED;
1043
{
1044
  Elf_Internal_Shdr *hdr;
1045
  const char *sname;
1046
  asection *text_sect, *s;
1047
  size_t len;
1048
 
1049
  for (s = abfd->sections; s; s = s->next)
1050
    {
1051
      hdr = &elf_section_data (s)->this_hdr;
1052
      switch (hdr->sh_type)
1053
        {
1054
        case SHT_IA_64_UNWIND:
1055
          /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1056
             have to do this.  */
1057
          sname = bfd_get_section_name (abfd, s);
1058
          len = sizeof (ELF_STRING_ia64_unwind) - 1;
1059
          if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0)
1060
            {
1061
              sname += len;
1062
 
1063
              if (sname[0] == '\0')
1064
                /* .IA_64.unwind -> .text */
1065
                text_sect = bfd_get_section_by_name (abfd, ".text");
1066
              else
1067
                /* .IA_64.unwindFOO -> FOO */
1068
                text_sect = bfd_get_section_by_name (abfd, sname);
1069
            }
1070
          else if (sname
1071
                   && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
1072
                       strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
1073
            {
1074
              /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1075
              size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
1076
              char *once_name = alloca (len2 + strlen (sname) - len + 1);
1077
 
1078
              memcpy (once_name, ".gnu.linkonce.t.", len2);
1079
              strcpy (once_name + len2, sname + len);
1080
              text_sect = bfd_get_section_by_name (abfd, once_name);
1081
            }
1082
          else
1083
            /* last resort: fall back on .text */
1084
            text_sect = bfd_get_section_by_name (abfd, ".text");
1085
 
1086
          if (text_sect)
1087
            {
1088
              /* The IA-64 processor-specific ABI requires setting
1089
                 sh_link to the unwind section, whereas HP-UX requires
1090
                 sh_info to do so.  For maximum compatibility, we'll
1091
                 set both for now... */
1092
              hdr->sh_link = elf_section_data (text_sect)->this_idx;
1093
              hdr->sh_info = elf_section_data (text_sect)->this_idx;
1094
            }
1095
          break;
1096
        }
1097
    }
1098
}
1099
 
1100
/* Hook called by the linker routine which adds symbols from an object
1101
   file.  We use it to put .comm items in .sbss, and not .bss.  */
1102
 
1103
static boolean
1104
elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1105
     bfd *abfd;
1106
     struct bfd_link_info *info;
1107
     const Elf_Internal_Sym *sym;
1108
     const char **namep ATTRIBUTE_UNUSED;
1109
     flagword *flagsp ATTRIBUTE_UNUSED;
1110
     asection **secp;
1111
     bfd_vma *valp;
1112
{
1113
  if (sym->st_shndx == SHN_COMMON
1114
      && !info->relocateable
1115
      && sym->st_size <= (unsigned) bfd_get_gp_size (abfd))
1116
    {
1117
      /* Common symbols less than or equal to -G nn bytes are
1118
         automatically put into .sbss.  */
1119
 
1120
      asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1121
 
1122
      if (scomm == NULL)
1123
        {
1124
          scomm = bfd_make_section (abfd, ".scommon");
1125
          if (scomm == NULL
1126
              || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1127
                                                       | SEC_IS_COMMON
1128
                                                       | SEC_LINKER_CREATED)))
1129
            return false;
1130
        }
1131
 
1132
      *secp = scomm;
1133
      *valp = sym->st_size;
1134
    }
1135
 
1136
  return true;
1137
}
1138
 
1139
static boolean
1140
elfNN_ia64_aix_vec (const bfd_target *vec)
1141
{
1142
  extern const bfd_target bfd_elfNN_ia64_aix_little_vec;
1143
  extern const bfd_target bfd_elfNN_ia64_aix_big_vec;
1144
 
1145
  return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
1146
          ||  vec == & bfd_elfNN_ia64_aix_big_vec);
1147
}
1148
 
1149
/* Hook called by the linker routine which adds symbols from an object
1150
   file.  We use it to handle OS-specific symbols.  */
1151
 
1152
static boolean
1153
elfNN_ia64_aix_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1154
     bfd *abfd;
1155
     struct bfd_link_info *info;
1156
     const Elf_Internal_Sym *sym;
1157
     const char **namep;
1158
     flagword *flagsp;
1159
     asection **secp;
1160
     bfd_vma *valp;
1161
{
1162
  if (strcmp (*namep, "__GLOB_DATA_PTR") == 0)
1163
    {
1164
      /* Define __GLOB_DATA_PTR when it is encountered.  This is expected to
1165
         be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1166
         no one else should use it b/c it is undocumented.  */
1167
      struct elf_link_hash_entry *h;
1168
 
1169
      h = (struct elf_link_hash_entry *) bfd_link_hash_lookup (info->hash, *namep, false, false, false);
1170
      if (h == NULL)
1171
        {
1172
          struct elf_backend_data *bed;
1173
          struct elfNN_ia64_link_hash_table *ia64_info;
1174
 
1175
          bed = get_elf_backend_data (abfd);
1176
          ia64_info = elfNN_ia64_hash_table (info);
1177
 
1178
          if (!(_bfd_generic_link_add_one_symbol
1179
                (info, abfd, *namep, BSF_GLOBAL,
1180
                 bfd_get_section_by_name (abfd, ".bss"),
1181
                 bed->got_symbol_offset, (const char *) NULL, false,
1182
                 bed->collect, (struct bfd_link_hash_entry **) &h)))
1183
            return false;
1184
 
1185
          h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1186
          h->type = STT_OBJECT;
1187
 
1188
          if (! _bfd_elf_link_record_dynamic_symbol (info, h))
1189
            return false;
1190
        }
1191
 
1192
      return true;
1193
    }
1194
  else if (sym->st_shndx == SHN_LOOS)
1195
    {
1196
      int i;
1197
 
1198
      /* SHN_AIX_SYSCALL: Treat this as any other symbol.  The special symbol
1199
         is only relevant when compiling code for extended system calls.
1200
         Replace the "special" section with .text, if possible.
1201
         Note that these symbols are always assumed to be in .text. */
1202
      for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++)
1203
        {
1204
          asection * sec = bfd_section_from_elf_index (abfd, i);
1205
 
1206
          if (sec && strcmp (sec->name, ".text") == 0)
1207
            {
1208
              *secp = sec;
1209
              break;
1210
            }
1211
        }
1212
 
1213
      if (*secp == NULL)
1214
        *secp = bfd_abs_section_ptr;
1215
 
1216
      *valp = sym->st_size;
1217
 
1218
      return true;
1219
    }
1220
  else
1221
    {
1222
      return elfNN_ia64_add_symbol_hook (abfd, info, sym,
1223
                                         namep, flagsp, secp, valp);
1224
    }
1225
}
1226
 
1227
boolean
1228
elfNN_ia64_aix_link_add_symbols (abfd, info)
1229
     bfd *abfd;
1230
     struct bfd_link_info *info;
1231
{
1232
  /* Make sure dynamic sections are always created.  */
1233
  if (! elf_hash_table (info)->dynamic_sections_created
1234
      && abfd->xvec == info->hash->creator)
1235
    {
1236
      if (! bfd_elfNN_link_create_dynamic_sections (abfd, info))
1237
        return false;
1238
    }
1239
 
1240
  /* Now do the standard call.  */
1241
  return bfd_elfNN_bfd_link_add_symbols (abfd, info);
1242
}
1243
 
1244
/* Return the number of additional phdrs we will need.  */
1245
 
1246
static int
1247
elfNN_ia64_additional_program_headers (abfd)
1248
     bfd *abfd;
1249
{
1250
  asection *s;
1251
  int ret = 0;
1252
 
1253
  /* See if we need a PT_IA_64_ARCHEXT segment.  */
1254
  s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1255
  if (s && (s->flags & SEC_LOAD))
1256
    ++ret;
1257
 
1258
  /* Count how many PT_IA_64_UNWIND segments we need.  */
1259
  for (s = abfd->sections; s; s = s->next)
1260
    if (is_unwind_section_name(s->name) && (s->flags & SEC_LOAD))
1261
      ++ret;
1262
 
1263
  return ret;
1264
}
1265
 
1266
static boolean
1267
elfNN_ia64_modify_segment_map (abfd)
1268
     bfd *abfd;
1269
{
1270
  struct elf_segment_map *m, **pm;
1271
  Elf_Internal_Shdr *hdr;
1272
  asection *s;
1273
 
1274
  /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1275
     all PT_LOAD segments.  */
1276
  s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1277
  if (s && (s->flags & SEC_LOAD))
1278
    {
1279
      for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1280
        if (m->p_type == PT_IA_64_ARCHEXT)
1281
          break;
1282
      if (m == NULL)
1283
        {
1284
          m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1285
          if (m == NULL)
1286
            return false;
1287
 
1288
          m->p_type = PT_IA_64_ARCHEXT;
1289
          m->count = 1;
1290
          m->sections[0] = s;
1291
 
1292
          /* We want to put it after the PHDR and INTERP segments.  */
1293
          pm = &elf_tdata (abfd)->segment_map;
1294
          while (*pm != NULL
1295
                 && ((*pm)->p_type == PT_PHDR
1296
                     || (*pm)->p_type == PT_INTERP))
1297
            pm = &(*pm)->next;
1298
 
1299
          m->next = *pm;
1300
          *pm = m;
1301
        }
1302
    }
1303
 
1304
  /* Install PT_IA_64_UNWIND segments, if needed.  */
1305
  for (s = abfd->sections; s; s = s->next)
1306
    {
1307
      hdr = &elf_section_data (s)->this_hdr;
1308
      if (hdr->sh_type != SHT_IA_64_UNWIND)
1309
        continue;
1310
 
1311
      if (s && (s->flags & SEC_LOAD))
1312
        {
1313
          for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1314
            if (m->p_type == PT_IA_64_UNWIND && m->sections[0] == s)
1315
              break;
1316
 
1317
          if (m == NULL)
1318
            {
1319
              m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
1320
              if (m == NULL)
1321
                return false;
1322
 
1323
              m->p_type = PT_IA_64_UNWIND;
1324
              m->count = 1;
1325
              m->sections[0] = s;
1326
              m->next = NULL;
1327
 
1328
              /* We want to put it last.  */
1329
              pm = &elf_tdata (abfd)->segment_map;
1330
              while (*pm != NULL)
1331
                pm = &(*pm)->next;
1332
              *pm = m;
1333
            }
1334
        }
1335
    }
1336
 
1337
  /* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
1338
     the input sections for each output section in the segment and testing
1339
     for SHF_IA_64_NORECOV on each.  */
1340
  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1341
    if (m->p_type == PT_LOAD)
1342
      {
1343
        int i;
1344
        for (i = m->count - 1; i >= 0; --i)
1345
          {
1346
            struct bfd_link_order *order = m->sections[i]->link_order_head;
1347
            while (order)
1348
              {
1349
                if (order->type == bfd_indirect_link_order)
1350
                  {
1351
                    asection *is = order->u.indirect.section;
1352
                    bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1353
                    if (flags & SHF_IA_64_NORECOV)
1354
                      {
1355
                        m->p_flags |= PF_IA_64_NORECOV;
1356
                        goto found;
1357
                      }
1358
                  }
1359
                order = order->next;
1360
              }
1361
          }
1362
      found:;
1363
      }
1364
 
1365
  return true;
1366
}
1367
 
1368
/* According to the Tahoe assembler spec, all labels starting with a
1369
   '.' are local.  */
1370
 
1371
static boolean
1372
elfNN_ia64_is_local_label_name (abfd, name)
1373
     bfd *abfd ATTRIBUTE_UNUSED;
1374
     const char *name;
1375
{
1376
  return name[0] == '.';
1377
}
1378
 
1379
/* Should we do dynamic things to this symbol?  */
1380
 
1381
static boolean
1382
elfNN_ia64_dynamic_symbol_p (h, info)
1383
     struct elf_link_hash_entry *h;
1384
     struct bfd_link_info *info;
1385
{
1386
  if (h == NULL)
1387
    return false;
1388
 
1389
  while (h->root.type == bfd_link_hash_indirect
1390
         || h->root.type == bfd_link_hash_warning)
1391
    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1392
 
1393
  if (h->dynindx == -1)
1394
    return false;
1395
  switch (ELF_ST_VISIBILITY (h->other))
1396
    {
1397
    case STV_INTERNAL:
1398
    case STV_HIDDEN:
1399
      return false;
1400
    }
1401
 
1402
  if (h->root.type == bfd_link_hash_undefweak
1403
      || h->root.type == bfd_link_hash_defweak)
1404
    return true;
1405
 
1406
  if ((info->shared && !info->symbolic)
1407
      || ((h->elf_link_hash_flags
1408
           & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1409
          == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1410
    return true;
1411
 
1412
  return false;
1413
}
1414
 
1415
static boolean
1416
elfNN_ia64_local_hash_table_init (ht, abfd, new)
1417
     struct elfNN_ia64_local_hash_table *ht;
1418
     bfd *abfd ATTRIBUTE_UNUSED;
1419
     new_hash_entry_func new;
1420
{
1421
  memset (ht, 0, sizeof (*ht));
1422
  return bfd_hash_table_init (&ht->root, new);
1423
}
1424
 
1425
static struct bfd_hash_entry*
1426
elfNN_ia64_new_loc_hash_entry (entry, table, string)
1427
     struct bfd_hash_entry *entry;
1428
     struct bfd_hash_table *table;
1429
     const char *string;
1430
{
1431
  struct elfNN_ia64_local_hash_entry *ret;
1432
  ret = (struct elfNN_ia64_local_hash_entry *) entry;
1433
 
1434
  /* Allocate the structure if it has not already been allocated by a
1435
     subclass.  */
1436
  if (!ret)
1437
    ret = bfd_hash_allocate (table, sizeof (*ret));
1438
 
1439
  if (!ret)
1440
    return 0;
1441
 
1442
  /* Initialize our local data.  All zeros, and definitely easier
1443
     than setting a handful of bit fields.  */
1444
  memset (ret, 0, sizeof (*ret));
1445
 
1446
  /* Call the allocation method of the superclass.  */
1447
  ret = ((struct elfNN_ia64_local_hash_entry *)
1448
         bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1449
 
1450
  return (struct bfd_hash_entry *) ret;
1451
}
1452
 
1453
static struct bfd_hash_entry*
1454
elfNN_ia64_new_elf_hash_entry (entry, table, string)
1455
     struct bfd_hash_entry *entry;
1456
     struct bfd_hash_table *table;
1457
     const char *string;
1458
{
1459
  struct elfNN_ia64_link_hash_entry *ret;
1460
  ret = (struct elfNN_ia64_link_hash_entry *) entry;
1461
 
1462
  /* Allocate the structure if it has not already been allocated by a
1463
     subclass.  */
1464
  if (!ret)
1465
    ret = bfd_hash_allocate (table, sizeof (*ret));
1466
 
1467
  if (!ret)
1468
    return 0;
1469
 
1470
  /* Initialize our local data.  All zeros, and definitely easier
1471
     than setting a handful of bit fields.  */
1472
  memset (ret, 0, sizeof (*ret));
1473
 
1474
  /* Call the allocation method of the superclass.  */
1475
  ret = ((struct elfNN_ia64_link_hash_entry *)
1476
         _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1477
                                     table, string));
1478
 
1479
  return (struct bfd_hash_entry *) ret;
1480
}
1481
 
1482
static void
1483
elfNN_ia64_hash_copy_indirect (xdir, xind)
1484
     struct elf_link_hash_entry *xdir, *xind;
1485
{
1486
  struct elfNN_ia64_link_hash_entry *dir, *ind;
1487
 
1488
  dir = (struct elfNN_ia64_link_hash_entry *)xdir;
1489
  ind = (struct elfNN_ia64_link_hash_entry *)xind;
1490
 
1491
  /* Copy down any references that we may have already seen to the
1492
     symbol which just became indirect.  */
1493
 
1494
  dir->root.elf_link_hash_flags |=
1495
    (ind->root.elf_link_hash_flags
1496
     & (ELF_LINK_HASH_REF_DYNAMIC
1497
        | ELF_LINK_HASH_REF_REGULAR
1498
        | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1499
 
1500
  /* Copy over the got and plt data.  This would have been done
1501
     by check_relocs.  */
1502
 
1503
  if (dir->info == NULL)
1504
    {
1505
      struct elfNN_ia64_dyn_sym_info *dyn_i;
1506
 
1507
      dir->info = dyn_i = ind->info;
1508
      ind->info = NULL;
1509
 
1510
      /* Fix up the dyn_sym_info pointers to the global symbol.  */
1511
      for (; dyn_i; dyn_i = dyn_i->next)
1512
        dyn_i->h = &dir->root;
1513
    }
1514
  BFD_ASSERT (ind->info == NULL);
1515
 
1516
  /* Copy over the dynindx.  */
1517
 
1518
  if (dir->root.dynindx == -1)
1519
    {
1520
      dir->root.dynindx = ind->root.dynindx;
1521
      dir->root.dynstr_index = ind->root.dynstr_index;
1522
      ind->root.dynindx = -1;
1523
      ind->root.dynstr_index = 0;
1524
    }
1525
  BFD_ASSERT (ind->root.dynindx == -1);
1526
}
1527
 
1528
static void
1529
elfNN_ia64_hash_hide_symbol (info, xh)
1530
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
1531
     struct elf_link_hash_entry *xh;
1532
{
1533
  struct elfNN_ia64_link_hash_entry *h;
1534
  struct elfNN_ia64_dyn_sym_info *dyn_i;
1535
 
1536
  h = (struct elfNN_ia64_link_hash_entry *)xh;
1537
 
1538
  h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
1539
  if ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
1540
    h->root.dynindx = -1;
1541
 
1542
  for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1543
    dyn_i->want_plt2 = 0;
1544
}
1545
 
1546
/* Create the derived linker hash table.  The IA-64 ELF port uses this
1547
   derived hash table to keep information specific to the IA-64 ElF
1548
   linker (without using static variables).  */
1549
 
1550
static struct bfd_link_hash_table*
1551
elfNN_ia64_hash_table_create (abfd)
1552
     bfd *abfd;
1553
{
1554
  struct elfNN_ia64_link_hash_table *ret;
1555
 
1556
  ret = bfd_alloc (abfd, sizeof (*ret));
1557
  if (!ret)
1558
    return 0;
1559
  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1560
                                      elfNN_ia64_new_elf_hash_entry))
1561
    {
1562
      bfd_release (abfd, ret);
1563
      return 0;
1564
    }
1565
 
1566
  if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1567
                                         elfNN_ia64_new_loc_hash_entry))
1568
    return 0;
1569
  return &ret->root.root;
1570
}
1571
 
1572
/* Look up an entry in a Alpha ELF linker hash table.  */
1573
 
1574
static INLINE struct elfNN_ia64_local_hash_entry *
1575
elfNN_ia64_local_hash_lookup(table, string, create, copy)
1576
     struct elfNN_ia64_local_hash_table *table;
1577
     const char *string;
1578
     boolean create, copy;
1579
{
1580
  return ((struct elfNN_ia64_local_hash_entry *)
1581
          bfd_hash_lookup (&table->root, string, create, copy));
1582
}
1583
 
1584
/* Traverse both local and global hash tables.  */
1585
 
1586
struct elfNN_ia64_dyn_sym_traverse_data
1587
{
1588
  boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1589
  PTR data;
1590
};
1591
 
1592
static boolean
1593
elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1594
     struct bfd_hash_entry *xentry;
1595
     PTR xdata;
1596
{
1597
  struct elfNN_ia64_link_hash_entry *entry
1598
    = (struct elfNN_ia64_link_hash_entry *) xentry;
1599
  struct elfNN_ia64_dyn_sym_traverse_data *data
1600
    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1601
  struct elfNN_ia64_dyn_sym_info *dyn_i;
1602
 
1603
  for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1604
    if (! (*data->func) (dyn_i, data->data))
1605
      return false;
1606
  return true;
1607
}
1608
 
1609
static boolean
1610
elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1611
     struct bfd_hash_entry *xentry;
1612
     PTR xdata;
1613
{
1614
  struct elfNN_ia64_local_hash_entry *entry
1615
    = (struct elfNN_ia64_local_hash_entry *) xentry;
1616
  struct elfNN_ia64_dyn_sym_traverse_data *data
1617
    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1618
  struct elfNN_ia64_dyn_sym_info *dyn_i;
1619
 
1620
  for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1621
    if (! (*data->func) (dyn_i, data->data))
1622
      return false;
1623
  return true;
1624
}
1625
 
1626
static void
1627
elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1628
     struct elfNN_ia64_link_hash_table *ia64_info;
1629
     boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1630
     PTR data;
1631
{
1632
  struct elfNN_ia64_dyn_sym_traverse_data xdata;
1633
 
1634
  xdata.func = func;
1635
  xdata.data = data;
1636
 
1637
  elf_link_hash_traverse (&ia64_info->root,
1638
                          elfNN_ia64_global_dyn_sym_thunk, &xdata);
1639
  bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1640
                     elfNN_ia64_local_dyn_sym_thunk, &xdata);
1641
}
1642
 
1643
static boolean
1644
elfNN_ia64_create_dynamic_sections (abfd, info)
1645
     bfd *abfd;
1646
     struct bfd_link_info *info;
1647
{
1648
  struct elfNN_ia64_link_hash_table *ia64_info;
1649
  asection *s;
1650
 
1651
  if (! _bfd_elf_create_dynamic_sections (abfd, info))
1652
    return false;
1653
 
1654
  ia64_info = elfNN_ia64_hash_table (info);
1655
 
1656
  ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1657
  ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1658
 
1659
  {
1660
    flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1661
    bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1662
  }
1663
 
1664
  if (!get_pltoff (abfd, info, ia64_info))
1665
    return false;
1666
 
1667
  s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1668
  if (s == NULL
1669
      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1670
                                           | SEC_HAS_CONTENTS
1671
                                           | SEC_IN_MEMORY
1672
                                           | SEC_LINKER_CREATED
1673
                                           | SEC_READONLY))
1674
      || !bfd_set_section_alignment (abfd, s, 3))
1675
    return false;
1676
  ia64_info->rel_pltoff_sec = s;
1677
 
1678
  s = bfd_make_section(abfd, ".rela.got");
1679
  if (s == NULL
1680
      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1681
                                           | SEC_HAS_CONTENTS
1682
                                           | SEC_IN_MEMORY
1683
                                           | SEC_LINKER_CREATED
1684
                                           | SEC_READONLY))
1685
      || !bfd_set_section_alignment (abfd, s, 3))
1686
    return false;
1687
  ia64_info->rel_got_sec = s;
1688
 
1689
  return true;
1690
}
1691
 
1692
/* Find and/or create a descriptor for dynamic symbol info.  This will
1693
   vary based on global or local symbol, and the addend to the reloc.  */
1694
 
1695
static struct elfNN_ia64_dyn_sym_info *
1696
get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1697
     struct elfNN_ia64_link_hash_table *ia64_info;
1698
     struct elf_link_hash_entry *h;
1699
     bfd *abfd;
1700
     const Elf_Internal_Rela *rel;
1701
     boolean create;
1702
{
1703
  struct elfNN_ia64_dyn_sym_info **pp;
1704
  struct elfNN_ia64_dyn_sym_info *dyn_i;
1705
  bfd_vma addend = rel ? rel->r_addend : 0;
1706
 
1707
  if (h)
1708
    pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1709
  else
1710
    {
1711
      struct elfNN_ia64_local_hash_entry *loc_h;
1712
      char *addr_name;
1713
      size_t len;
1714
 
1715
      /* Construct a string for use in the elfNN_ia64_local_hash_table.
1716
         The name describes what was once anonymous memory.  */
1717
 
1718
      len = sizeof (void*)*2 + 1 + sizeof (bfd_vma)*4 + 1 + 1;
1719
      len += 10;        /* %p slop */
1720
 
1721
      addr_name = alloca (len);
1722
      sprintf (addr_name, "%p:%lx", (void *) abfd, ELFNN_R_SYM (rel->r_info));
1723
 
1724
      /* Collect the canonical entry data for this address.  */
1725
      loc_h = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1726
                                            addr_name, create, create);
1727
      BFD_ASSERT (loc_h);
1728
 
1729
      pp = &loc_h->info;
1730
    }
1731
 
1732
  for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1733
    pp = &dyn_i->next;
1734
 
1735
  if (dyn_i == NULL && create)
1736
    {
1737
      dyn_i = (struct elfNN_ia64_dyn_sym_info *)
1738
        bfd_zalloc (abfd, sizeof *dyn_i);
1739
      *pp = dyn_i;
1740
      dyn_i->addend = addend;
1741
    }
1742
 
1743
  return dyn_i;
1744
}
1745
 
1746
static asection *
1747
get_got (abfd, info, ia64_info)
1748
     bfd *abfd;
1749
     struct bfd_link_info *info;
1750
     struct elfNN_ia64_link_hash_table *ia64_info;
1751
{
1752
  asection *got;
1753
  bfd *dynobj;
1754
 
1755
  got = ia64_info->got_sec;
1756
  if (!got)
1757
    {
1758
      flagword flags;
1759
 
1760
      dynobj = ia64_info->root.dynobj;
1761
      if (!dynobj)
1762
        ia64_info->root.dynobj = dynobj = abfd;
1763
      if (!_bfd_elf_create_got_section (dynobj, info))
1764
        return 0;
1765
 
1766
      got = bfd_get_section_by_name (dynobj, ".got");
1767
      BFD_ASSERT (got);
1768
      ia64_info->got_sec = got;
1769
 
1770
      flags = bfd_get_section_flags (abfd, got);
1771
      bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1772
    }
1773
 
1774
  return got;
1775
}
1776
 
1777
/* Create function descriptor section (.opd).  This section is called .opd
1778
   because it contains "official prodecure descriptors".  The "official"
1779
   refers to the fact that these descriptors are used when taking the address
1780
   of a procedure, thus ensuring a unique address for each procedure.  */
1781
 
1782
static asection *
1783
get_fptr (abfd, info, ia64_info)
1784
     bfd *abfd;
1785
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
1786
     struct elfNN_ia64_link_hash_table *ia64_info;
1787
{
1788
  asection *fptr;
1789
  bfd *dynobj;
1790
 
1791
  fptr = ia64_info->fptr_sec;
1792
  if (!fptr)
1793
    {
1794
      dynobj = ia64_info->root.dynobj;
1795
      if (!dynobj)
1796
        ia64_info->root.dynobj = dynobj = abfd;
1797
 
1798
      fptr = bfd_make_section (dynobj, ".opd");
1799
      if (!fptr
1800
          || !bfd_set_section_flags (dynobj, fptr,
1801
                                     (SEC_ALLOC
1802
                                      | SEC_LOAD
1803
                                      | SEC_HAS_CONTENTS
1804
                                      | SEC_IN_MEMORY
1805
                                      | SEC_READONLY
1806
                                      | SEC_LINKER_CREATED))
1807
          || !bfd_set_section_alignment (abfd, fptr, 4))
1808
        {
1809
          BFD_ASSERT (0);
1810
          return NULL;
1811
        }
1812
 
1813
      ia64_info->fptr_sec = fptr;
1814
    }
1815
 
1816
  return fptr;
1817
}
1818
 
1819
static asection *
1820
get_pltoff (abfd, info, ia64_info)
1821
     bfd *abfd;
1822
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
1823
     struct elfNN_ia64_link_hash_table *ia64_info;
1824
{
1825
  asection *pltoff;
1826
  bfd *dynobj;
1827
 
1828
  pltoff = ia64_info->pltoff_sec;
1829
  if (!pltoff)
1830
    {
1831
      dynobj = ia64_info->root.dynobj;
1832
      if (!dynobj)
1833
        ia64_info->root.dynobj = dynobj = abfd;
1834
 
1835
      pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1836
      if (!pltoff
1837
          || !bfd_set_section_flags (dynobj, pltoff,
1838
                                     (SEC_ALLOC
1839
                                      | SEC_LOAD
1840
                                      | SEC_HAS_CONTENTS
1841
                                      | SEC_IN_MEMORY
1842
                                      | SEC_SMALL_DATA
1843
                                      | SEC_LINKER_CREATED))
1844
          || !bfd_set_section_alignment (abfd, pltoff, 4))
1845
        {
1846
          BFD_ASSERT (0);
1847
          return NULL;
1848
        }
1849
 
1850
      ia64_info->pltoff_sec = pltoff;
1851
    }
1852
 
1853
  return pltoff;
1854
}
1855
 
1856
static asection *
1857
get_reloc_section (abfd, ia64_info, sec, create)
1858
     bfd *abfd;
1859
     struct elfNN_ia64_link_hash_table *ia64_info;
1860
     asection *sec;
1861
     boolean create;
1862
{
1863
  const char *srel_name;
1864
  asection *srel;
1865
  bfd *dynobj;
1866
 
1867
  srel_name = (bfd_elf_string_from_elf_section
1868
               (abfd, elf_elfheader(abfd)->e_shstrndx,
1869
                elf_section_data(sec)->rel_hdr.sh_name));
1870
  if (srel_name == NULL)
1871
    return NULL;
1872
 
1873
  BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
1874
               && strcmp (bfd_get_section_name (abfd, sec),
1875
                          srel_name+5) == 0)
1876
              || (strncmp (srel_name, ".rel", 4) == 0
1877
                  && strcmp (bfd_get_section_name (abfd, sec),
1878
                             srel_name+4) == 0));
1879
 
1880
  dynobj = ia64_info->root.dynobj;
1881
  if (!dynobj)
1882
    ia64_info->root.dynobj = dynobj = abfd;
1883
 
1884
  srel = bfd_get_section_by_name (dynobj, srel_name);
1885
  if (srel == NULL && create)
1886
    {
1887
      srel = bfd_make_section (dynobj, srel_name);
1888
      if (srel == NULL
1889
          || !bfd_set_section_flags (dynobj, srel,
1890
                                     (SEC_ALLOC
1891
                                      | SEC_LOAD
1892
                                      | SEC_HAS_CONTENTS
1893
                                      | SEC_IN_MEMORY
1894
                                      | SEC_LINKER_CREATED
1895
                                      | SEC_READONLY))
1896
          || !bfd_set_section_alignment (dynobj, srel, 3))
1897
        return NULL;
1898
    }
1899
 
1900
  return srel;
1901
}
1902
 
1903
static boolean
1904
count_dyn_reloc (abfd, dyn_i, srel, type)
1905
     bfd *abfd;
1906
     struct elfNN_ia64_dyn_sym_info *dyn_i;
1907
     asection *srel;
1908
     int type;
1909
{
1910
  struct elfNN_ia64_dyn_reloc_entry *rent;
1911
 
1912
  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
1913
    if (rent->srel == srel && rent->type == type)
1914
      break;
1915
 
1916
  if (!rent)
1917
    {
1918
      rent = (struct elfNN_ia64_dyn_reloc_entry *)
1919
        bfd_alloc (abfd, sizeof (*rent));
1920
      if (!rent)
1921
        return false;
1922
 
1923
      rent->next = dyn_i->reloc_entries;
1924
      rent->srel = srel;
1925
      rent->type = type;
1926
      rent->count = 0;
1927
      dyn_i->reloc_entries = rent;
1928
    }
1929
  rent->count++;
1930
 
1931
  return true;
1932
}
1933
 
1934
static boolean
1935
elfNN_ia64_check_relocs (abfd, info, sec, relocs)
1936
     bfd *abfd;
1937
     struct bfd_link_info *info;
1938
     asection *sec;
1939
     const Elf_Internal_Rela *relocs;
1940
{
1941
  struct elfNN_ia64_link_hash_table *ia64_info;
1942
  const Elf_Internal_Rela *relend;
1943
  Elf_Internal_Shdr *symtab_hdr;
1944
  const Elf_Internal_Rela *rel;
1945
  asection *got, *fptr, *srel;
1946
 
1947
  if (info->relocateable)
1948
    return true;
1949
 
1950
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1951
  ia64_info = elfNN_ia64_hash_table (info);
1952
 
1953
  got = fptr = srel = NULL;
1954
 
1955
  relend = relocs + sec->reloc_count;
1956
  for (rel = relocs; rel < relend; ++rel)
1957
    {
1958
      enum {
1959
        NEED_GOT = 1,
1960
        NEED_FPTR = 2,
1961
        NEED_PLTOFF = 4,
1962
        NEED_MIN_PLT = 8,
1963
        NEED_FULL_PLT = 16,
1964
        NEED_DYNREL = 32,
1965
        NEED_LTOFF_FPTR = 64,
1966
      };
1967
 
1968
      struct elf_link_hash_entry *h = NULL;
1969
      unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
1970
      struct elfNN_ia64_dyn_sym_info *dyn_i;
1971
      int need_entry;
1972
      boolean maybe_dynamic;
1973
      int dynrel_type = R_IA64_NONE;
1974
 
1975
      if (r_symndx >= symtab_hdr->sh_info)
1976
        {
1977
          /* We're dealing with a global symbol -- find its hash entry
1978
             and mark it as being referenced.  */
1979
          long indx = r_symndx - symtab_hdr->sh_info;
1980
          h = elf_sym_hashes (abfd)[indx];
1981
          while (h->root.type == bfd_link_hash_indirect
1982
                 || h->root.type == bfd_link_hash_warning)
1983
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
1984
 
1985
          h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
1986
        }
1987
 
1988
      /* We can only get preliminary data on whether a symbol is
1989
         locally or externally defined, as not all of the input files
1990
         have yet been processed.  Do something with what we know, as
1991
         this may help reduce memory usage and processing time later.  */
1992
      maybe_dynamic = false;
1993
      if (h && ((info->shared && ! info->symbolic)
1994
                || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
1995
                || h->root.type == bfd_link_hash_defweak
1996
                || elfNN_ia64_aix_vec (abfd->xvec)))
1997
        maybe_dynamic = true;
1998
 
1999
      need_entry = 0;
2000
      switch (ELFNN_R_TYPE (rel->r_info))
2001
        {
2002
        case R_IA64_TPREL22:
2003
        case R_IA64_TPREL64MSB:
2004
        case R_IA64_TPREL64LSB:
2005
        case R_IA64_LTOFF_TP22:
2006
          return false;
2007
 
2008
        case R_IA64_LTOFF_FPTR22:
2009
        case R_IA64_LTOFF_FPTR64I:
2010
        case R_IA64_LTOFF_FPTR64MSB:
2011
        case R_IA64_LTOFF_FPTR64LSB:
2012
          need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2013
          break;
2014
 
2015
        case R_IA64_FPTR64I:
2016
        case R_IA64_FPTR32MSB:
2017
        case R_IA64_FPTR32LSB:
2018
        case R_IA64_FPTR64MSB:
2019
        case R_IA64_FPTR64LSB:
2020
          if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
2021
            need_entry = NEED_FPTR | NEED_DYNREL;
2022
          else
2023
            need_entry = NEED_FPTR;
2024
          dynrel_type = R_IA64_FPTR64LSB;
2025
          break;
2026
 
2027
        case R_IA64_LTOFF22:
2028
        case R_IA64_LTOFF22X:
2029
        case R_IA64_LTOFF64I:
2030
          need_entry = NEED_GOT;
2031
          break;
2032
 
2033
        case R_IA64_PLTOFF22:
2034
        case R_IA64_PLTOFF64I:
2035
        case R_IA64_PLTOFF64MSB:
2036
        case R_IA64_PLTOFF64LSB:
2037
          need_entry = NEED_PLTOFF;
2038
          if (h)
2039
            {
2040
              if (maybe_dynamic)
2041
                need_entry |= NEED_MIN_PLT;
2042
            }
2043
          else
2044
            {
2045
              (*info->callbacks->warning)
2046
                (info, _("@pltoff reloc against local symbol"), 0,
2047
                 abfd, 0, 0);
2048
            }
2049
          break;
2050
 
2051
        case R_IA64_PCREL21B:
2052
        case R_IA64_PCREL60B:
2053
          /* Depending on where this symbol is defined, we may or may not
2054
             need a full plt entry.  Only skip if we know we'll not need
2055
             the entry -- static or symbolic, and the symbol definition
2056
             has already been seen.  */
2057
          if (maybe_dynamic && rel->r_addend == 0)
2058
            need_entry = NEED_FULL_PLT;
2059
          break;
2060
 
2061
        case R_IA64_IMM14:
2062
        case R_IA64_IMM22:
2063
        case R_IA64_IMM64:
2064
        case R_IA64_DIR32MSB:
2065
        case R_IA64_DIR32LSB:
2066
        case R_IA64_DIR64MSB:
2067
        case R_IA64_DIR64LSB:
2068
          /* Shared objects will always need at least a REL relocation.  */
2069
          if (info->shared || maybe_dynamic
2070
              || (elfNN_ia64_aix_vec (abfd->xvec)
2071
                  && (!h || strcmp (h->root.root.string,
2072
                                    "__GLOB_DATA_PTR") != 0)))
2073
            need_entry = NEED_DYNREL;
2074
          dynrel_type = R_IA64_DIR64LSB;
2075
          break;
2076
 
2077
        case R_IA64_IPLTMSB:
2078
        case R_IA64_IPLTLSB:
2079
          /* Shared objects will always need at least a REL relocation.  */
2080
          if (info->shared || maybe_dynamic)
2081
            need_entry = NEED_DYNREL;
2082
          dynrel_type = R_IA64_IPLTLSB;
2083
          break;
2084
 
2085
        case R_IA64_PCREL22:
2086
        case R_IA64_PCREL64I:
2087
        case R_IA64_PCREL32MSB:
2088
        case R_IA64_PCREL32LSB:
2089
        case R_IA64_PCREL64MSB:
2090
        case R_IA64_PCREL64LSB:
2091
          if (maybe_dynamic)
2092
            need_entry = NEED_DYNREL;
2093
          dynrel_type = R_IA64_PCREL64LSB;
2094
          break;
2095
        }
2096
 
2097
      if (!need_entry)
2098
        continue;
2099
 
2100
      if ((need_entry & NEED_FPTR) != 0
2101
          && rel->r_addend)
2102
        {
2103
          (*info->callbacks->warning)
2104
            (info, _("non-zero addend in @fptr reloc"), 0,
2105
             abfd, 0, 0);
2106
        }
2107
 
2108
      dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
2109
 
2110
      /* Record whether or not this is a local symbol.  */
2111
      dyn_i->h = h;
2112
 
2113
      /* Create what's needed.  */
2114
      if (need_entry & NEED_GOT)
2115
        {
2116
          if (!got)
2117
            {
2118
              got = get_got (abfd, info, ia64_info);
2119
              if (!got)
2120
                return false;
2121
            }
2122
          dyn_i->want_got = 1;
2123
        }
2124
      if (need_entry & NEED_FPTR)
2125
        {
2126
          if (!fptr)
2127
            {
2128
              fptr = get_fptr (abfd, info, ia64_info);
2129
              if (!fptr)
2130
                return false;
2131
            }
2132
 
2133
          /* FPTRs for shared libraries are allocated by the dynamic
2134
             linker.  Make sure this local symbol will appear in the
2135
             dynamic symbol table.  */
2136
          if (!h && (info->shared
2137
                     /* AIX also needs one */
2138
                     || elfNN_ia64_aix_vec (abfd->xvec)))
2139
            {
2140
              if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2141
                     (info, abfd, r_symndx)))
2142
                return false;
2143
            }
2144
 
2145
          dyn_i->want_fptr = 1;
2146
        }
2147
      if (need_entry & NEED_LTOFF_FPTR)
2148
        dyn_i->want_ltoff_fptr = 1;
2149
      if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2150
        {
2151
          if (!ia64_info->root.dynobj)
2152
            ia64_info->root.dynobj = abfd;
2153
          h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2154
          dyn_i->want_plt = 1;
2155
        }
2156
      if (need_entry & NEED_FULL_PLT)
2157
        dyn_i->want_plt2 = 1;
2158
      if (need_entry & NEED_PLTOFF)
2159
        dyn_i->want_pltoff = 1;
2160
      if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2161
        {
2162
          if (!srel)
2163
            {
2164
              srel = get_reloc_section (abfd, ia64_info, sec, true);
2165
              if (!srel)
2166
                return false;
2167
            }
2168
          if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2169
            return false;
2170
        }
2171
    }
2172
 
2173
  return true;
2174
}
2175
 
2176
struct elfNN_ia64_allocate_data
2177
{
2178
  struct bfd_link_info *info;
2179
  bfd_size_type ofs;
2180
};
2181
 
2182
/* For cleanliness, and potentially faster dynamic loading, allocate
2183
   external GOT entries first.  */
2184
 
2185
static boolean
2186
allocate_global_data_got (dyn_i, data)
2187
     struct elfNN_ia64_dyn_sym_info *dyn_i;
2188
     PTR data;
2189
{
2190
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2191
 
2192
  if (dyn_i->want_got
2193
      && ! dyn_i->want_fptr
2194
      && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2195
          || (elfNN_ia64_aix_vec (x->info->hash->creator)
2196
              && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2197
                                       "__GLOB_DATA_PTR") != 0))))
2198
     {
2199
       dyn_i->got_offset = x->ofs;
2200
       x->ofs += 8;
2201
     }
2202
  return true;
2203
}
2204
 
2205
/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
2206
 
2207
static boolean
2208
allocate_global_fptr_got (dyn_i, data)
2209
     struct elfNN_ia64_dyn_sym_info *dyn_i;
2210
     PTR data;
2211
{
2212
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2213
 
2214
  if (dyn_i->want_got
2215
      && dyn_i->want_fptr
2216
      && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2217
          || elfNN_ia64_aix_vec (x->info->hash->creator)))
2218
    {
2219
      dyn_i->got_offset = x->ofs;
2220
      x->ofs += 8;
2221
    }
2222
  return true;
2223
}
2224
 
2225
/* Lastly, allocate all the GOT entries for local data.  */
2226
 
2227
static boolean
2228
allocate_local_got (dyn_i, data)
2229
     struct elfNN_ia64_dyn_sym_info *dyn_i;
2230
     PTR data;
2231
{
2232
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2233
 
2234
  if (dyn_i->want_got
2235
      && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2236
            || elfNN_ia64_aix_vec (x->info->hash->creator)))
2237
    {
2238
      dyn_i->got_offset = x->ofs;
2239
      x->ofs += 8;
2240
    }
2241
  return true;
2242
}
2243
 
2244
/* Search for the index of a global symbol in it's defining object file.  */
2245
 
2246
static unsigned long
2247
global_sym_index (h)
2248
     struct elf_link_hash_entry *h;
2249
{
2250
  struct elf_link_hash_entry **p;
2251
  bfd *obj;
2252
 
2253
  BFD_ASSERT (h->root.type == bfd_link_hash_defined
2254
              || h->root.type == bfd_link_hash_defweak);
2255
 
2256
  obj = h->root.u.def.section->owner;
2257
  for (p = elf_sym_hashes (obj); *p != h; ++p)
2258
    continue;
2259
 
2260
  return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2261
}
2262
 
2263
/* Allocate function descriptors.  We can do these for every function
2264
   in a main executable that is not exported.  */
2265
 
2266
static boolean
2267
allocate_fptr (dyn_i, data)
2268
     struct elfNN_ia64_dyn_sym_info *dyn_i;
2269
     PTR data;
2270
{
2271
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2272
 
2273
  if (dyn_i->want_fptr)
2274
    {
2275
      struct elf_link_hash_entry *h = dyn_i->h;
2276
 
2277
      if (h)
2278
        while (h->root.type == bfd_link_hash_indirect
2279
               || h->root.type == bfd_link_hash_warning)
2280
          h = (struct elf_link_hash_entry *) h->root.u.i.link;
2281
 
2282
      if (x->info->shared
2283
          /* AIX needs an FPTR in this case. */
2284
          || (elfNN_ia64_aix_vec (x->info->hash->creator)
2285
              && (!h
2286
                  || h->root.type == bfd_link_hash_defined
2287
                  || h->root.type == bfd_link_hash_defweak)))
2288
        {
2289
          if (h && h->dynindx == -1)
2290
            {
2291
              BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2292
                          || (h->root.type == bfd_link_hash_defweak));
2293
 
2294
              if (!_bfd_elfNN_link_record_local_dynamic_symbol
2295
                    (x->info, h->root.u.def.section->owner,
2296
                     global_sym_index (h)))
2297
                return false;
2298
            }
2299
 
2300
          dyn_i->want_fptr = 0;
2301
        }
2302
      else if (h == NULL || h->dynindx == -1)
2303
        {
2304
          dyn_i->fptr_offset = x->ofs;
2305
          x->ofs += 16;
2306
        }
2307
      else
2308
        dyn_i->want_fptr = 0;
2309
    }
2310
  return true;
2311
}
2312
 
2313
/* Allocate all the minimal PLT entries.  */
2314
 
2315
static boolean
2316
allocate_plt_entries (dyn_i, data)
2317
     struct elfNN_ia64_dyn_sym_info *dyn_i;
2318
     PTR data;
2319
{
2320
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2321
 
2322
  if (dyn_i->want_plt)
2323
    {
2324
      struct elf_link_hash_entry *h = dyn_i->h;
2325
 
2326
      if (h)
2327
        while (h->root.type == bfd_link_hash_indirect
2328
               || h->root.type == bfd_link_hash_warning)
2329
          h = (struct elf_link_hash_entry *) h->root.u.i.link;
2330
 
2331
      /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT.  */
2332
      if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2333
        {
2334
          bfd_size_type offset = x->ofs;
2335
          if (offset == 0)
2336
            offset = PLT_HEADER_SIZE;
2337
          dyn_i->plt_offset = offset;
2338
          x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2339
 
2340
          dyn_i->want_pltoff = 1;
2341
        }
2342
      else
2343
        {
2344
          dyn_i->want_plt = 0;
2345
          dyn_i->want_plt2 = 0;
2346
        }
2347
    }
2348
  return true;
2349
}
2350
 
2351
/* Allocate all the full PLT entries.  */
2352
 
2353
static boolean
2354
allocate_plt2_entries (dyn_i, data)
2355
     struct elfNN_ia64_dyn_sym_info *dyn_i;
2356
     PTR data;
2357
{
2358
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2359
 
2360
  if (dyn_i->want_plt2)
2361
    {
2362
      struct elf_link_hash_entry *h = dyn_i->h;
2363
      bfd_size_type ofs = x->ofs;
2364
 
2365
      dyn_i->plt2_offset = ofs;
2366
      x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2367
 
2368
      while (h->root.type == bfd_link_hash_indirect
2369
             || h->root.type == bfd_link_hash_warning)
2370
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
2371
      dyn_i->h->plt.offset = ofs;
2372
    }
2373
  return true;
2374
}
2375
 
2376
/* Allocate all the PLTOFF entries requested by relocations and
2377
   plt entries.  We can't share space with allocated FPTR entries,
2378
   because the latter are not necessarily addressable by the GP.
2379
   ??? Relaxation might be able to determine that they are.  */
2380
 
2381
static boolean
2382
allocate_pltoff_entries (dyn_i, data)
2383
     struct elfNN_ia64_dyn_sym_info *dyn_i;
2384
     PTR data;
2385
{
2386
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2387
 
2388
  if (dyn_i->want_pltoff)
2389
    {
2390
      dyn_i->pltoff_offset = x->ofs;
2391
      x->ofs += 16;
2392
    }
2393
  return true;
2394
}
2395
 
2396
/* Allocate dynamic relocations for those symbols that turned out
2397
   to be dynamic.  */
2398
 
2399
static boolean
2400
allocate_dynrel_entries (dyn_i, data)
2401
     struct elfNN_ia64_dyn_sym_info *dyn_i;
2402
     PTR data;
2403
{
2404
  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2405
  struct elfNN_ia64_link_hash_table *ia64_info;
2406
  struct elfNN_ia64_dyn_reloc_entry *rent;
2407
  boolean dynamic_symbol, shared;
2408
 
2409
  ia64_info = elfNN_ia64_hash_table (x->info);
2410
  dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2411
    || (elfNN_ia64_aix_vec (x->info->hash->creator)
2412
        /* Don't allocate an entry for __GLOB_DATA_PTR */
2413
        && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2414
          "__GLOB_DATA_PTR") != 0));
2415
  shared = x->info->shared;
2416
 
2417
  /* Take care of the normal data relocations.  */
2418
 
2419
  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2420
    {
2421
      int count = rent->count;
2422
 
2423
      switch (rent->type)
2424
        {
2425
        case R_IA64_FPTR64LSB:
2426
          /* Allocate one iff !want_fptr, which by this point will
2427
             be true only if we're actually allocating one statically
2428
             in the main executable.  */
2429
          if (dyn_i->want_fptr)
2430
            continue;
2431
          break;
2432
        case R_IA64_PCREL64LSB:
2433
          if (!dynamic_symbol)
2434
            continue;
2435
          break;
2436
        case R_IA64_DIR64LSB:
2437
          if (!dynamic_symbol && !shared)
2438
            continue;
2439
          break;
2440
        case R_IA64_IPLTLSB:
2441
          if (!dynamic_symbol && !shared)
2442
            continue;
2443
          /* Use two REL relocations for IPLT relocations
2444
             against local symbols.  */
2445
          if (!dynamic_symbol)
2446
            count *= 2;
2447
          break;
2448
        default:
2449
          abort ();
2450
        }
2451
      rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2452
    }
2453
 
2454
  /* Take care of the GOT and PLT relocations.  */
2455
 
2456
  if (((dynamic_symbol || shared) && dyn_i->want_got)
2457
      || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2458
    ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2459
 
2460
  if (dyn_i->want_pltoff)
2461
    {
2462
      bfd_size_type t = 0;
2463
 
2464
      /* Dynamic symbols get one IPLT relocation.  Local symbols in
2465
         shared libraries get two REL relocations.  Local symbols in
2466
         main applications get nothing.  */
2467
      if (dynamic_symbol)
2468
        t = sizeof (ElfNN_External_Rela);
2469
      else if (shared)
2470
        t = 2 * sizeof (ElfNN_External_Rela);
2471
 
2472
      ia64_info->rel_pltoff_sec->_raw_size += t;
2473
    }
2474
 
2475
  return true;
2476
}
2477
 
2478
static boolean
2479
elfNN_ia64_adjust_dynamic_symbol (info, h)
2480
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
2481
     struct elf_link_hash_entry *h;
2482
{
2483
  /* ??? Undefined symbols with PLT entries should be re-defined
2484
     to be the PLT entry.  */
2485
 
2486
  /* If this is a weak symbol, and there is a real definition, the
2487
     processor independent code will have arranged for us to see the
2488
     real definition first, and we can just use the same value.  */
2489
  if (h->weakdef != NULL)
2490
    {
2491
      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2492
                  || h->weakdef->root.type == bfd_link_hash_defweak);
2493
      h->root.u.def.section = h->weakdef->root.u.def.section;
2494
      h->root.u.def.value = h->weakdef->root.u.def.value;
2495
      return true;
2496
    }
2497
 
2498
  /* If this is a reference to a symbol defined by a dynamic object which
2499
     is not a function, we might allocate the symbol in our .dynbss section
2500
     and allocate a COPY dynamic relocation.
2501
 
2502
     But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2503
     of hackery.  */
2504
 
2505
  return true;
2506
}
2507
 
2508
static boolean
2509
elfNN_ia64_size_dynamic_sections (output_bfd, info)
2510
     bfd *output_bfd;
2511
     struct bfd_link_info *info;
2512
{
2513
  struct elfNN_ia64_allocate_data data;
2514
  struct elfNN_ia64_link_hash_table *ia64_info;
2515
  asection *sec;
2516
  bfd *dynobj;
2517
  boolean reltext = false;
2518
  boolean relplt = false;
2519
 
2520
  dynobj = elf_hash_table(info)->dynobj;
2521
  ia64_info = elfNN_ia64_hash_table (info);
2522
  BFD_ASSERT(dynobj != NULL);
2523
  data.info = info;
2524
 
2525
  /* Set the contents of the .interp section to the interpreter.  */
2526
  if (ia64_info->root.dynamic_sections_created
2527
      && !info->shared)
2528
    {
2529
      sec = bfd_get_section_by_name (dynobj, ".interp");
2530
      BFD_ASSERT (sec != NULL);
2531
      sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2532
      sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
2533
    }
2534
 
2535
  /* Allocate the GOT entries.  */
2536
 
2537
  if (ia64_info->got_sec)
2538
    {
2539
      data.ofs = 0;
2540
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2541
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2542
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2543
      ia64_info->got_sec->_raw_size = data.ofs;
2544
    }
2545
 
2546
  /* Allocate the FPTR entries.  */
2547
 
2548
  if (ia64_info->fptr_sec)
2549
    {
2550
      data.ofs = 0;
2551
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2552
      ia64_info->fptr_sec->_raw_size = data.ofs;
2553
    }
2554
 
2555
  /* Now that we've seen all of the input files, we can decide which
2556
     symbols need plt entries.  Allocate the minimal PLT entries first.
2557
     We do this even though dynamic_sections_created may be false, because
2558
     this has the side-effect of clearing want_plt and want_plt2.  */
2559
 
2560
  data.ofs = 0;
2561
  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2562
 
2563
  ia64_info->minplt_entries = 0;
2564
  if (data.ofs)
2565
    {
2566
      ia64_info->minplt_entries
2567
        = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2568
    }
2569
 
2570
  /* Align the pointer for the plt2 entries.  */
2571
  data.ofs = (data.ofs + 31) & -32;
2572
 
2573
  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2574
  if (data.ofs != 0)
2575
    {
2576
      BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2577
 
2578
      ia64_info->plt_sec->_raw_size = data.ofs;
2579
 
2580
      /* If we've got a .plt, we need some extra memory for the dynamic
2581
         linker.  We stuff these in .got.plt.  */
2582
      sec = bfd_get_section_by_name (dynobj, ".got.plt");
2583
      sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2584
    }
2585
 
2586
  /* Allocate the PLTOFF entries.  */
2587
 
2588
  if (ia64_info->pltoff_sec)
2589
    {
2590
      data.ofs = 0;
2591
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2592
      ia64_info->pltoff_sec->_raw_size = data.ofs;
2593
    }
2594
 
2595
  if (ia64_info->root.dynamic_sections_created)
2596
    {
2597
      /* Allocate space for the dynamic relocations that turned out to be
2598
         required.  */
2599
 
2600
      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2601
    }
2602
 
2603
  /* We have now determined the sizes of the various dynamic sections.
2604
     Allocate memory for them.  */
2605
  for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2606
    {
2607
      boolean strip;
2608
 
2609
      if (!(sec->flags & SEC_LINKER_CREATED))
2610
        continue;
2611
 
2612
      /* If we don't need this section, strip it from the output file.
2613
         There were several sections primarily related to dynamic
2614
         linking that must be create before the linker maps input
2615
         sections to output sections.  The linker does that before
2616
         bfd_elf_size_dynamic_sections is called, and it is that
2617
         function which decides whether anything needs to go into
2618
         these sections.  */
2619
 
2620
      strip = (sec->_raw_size == 0);
2621
 
2622
      if (sec == ia64_info->got_sec)
2623
        strip = false;
2624
      else if (sec == ia64_info->rel_got_sec)
2625
        {
2626
          if (strip)
2627
            ia64_info->rel_got_sec = NULL;
2628
          else
2629
            /* We use the reloc_count field as a counter if we need to
2630
               copy relocs into the output file.  */
2631
            sec->reloc_count = 0;
2632
        }
2633
      else if (sec == ia64_info->fptr_sec)
2634
        {
2635
          if (strip)
2636
            ia64_info->fptr_sec = NULL;
2637
        }
2638
      else if (sec == ia64_info->plt_sec)
2639
        {
2640
          if (strip)
2641
            ia64_info->plt_sec = NULL;
2642
        }
2643
      else if (sec == ia64_info->pltoff_sec)
2644
        {
2645
          if (strip)
2646
            ia64_info->pltoff_sec = NULL;
2647
        }
2648
      else if (sec == ia64_info->rel_pltoff_sec)
2649
        {
2650
          if (strip)
2651
            ia64_info->rel_pltoff_sec = NULL;
2652
          else
2653
            {
2654
              relplt = true;
2655
              /* We use the reloc_count field as a counter if we need to
2656
                 copy relocs into the output file.  */
2657
              sec->reloc_count = 0;
2658
            }
2659
        }
2660
      else
2661
        {
2662
          const char *name;
2663
 
2664
          /* It's OK to base decisions on the section name, because none
2665
             of the dynobj section names depend upon the input files.  */
2666
          name = bfd_get_section_name (dynobj, sec);
2667
 
2668
          if (strcmp (name, ".got.plt") == 0)
2669
            strip = false;
2670
          else if (strncmp (name, ".rel", 4) == 0)
2671
            {
2672
              if (!strip)
2673
                {
2674
                  const char *outname;
2675
                  asection *target;
2676
 
2677
                  /* If this relocation section applies to a read only
2678
                     section, then we probably need a DT_TEXTREL entry.  */
2679
                  outname = bfd_get_section_name (output_bfd,
2680
                                                  sec->output_section);
2681
                  if (outname[4] == 'a')
2682
                    outname += 5;
2683
                  else
2684
                    outname += 4;
2685
 
2686
                  target = bfd_get_section_by_name (output_bfd, outname);
2687
                  if (target != NULL
2688
                      && (target->flags & SEC_READONLY) != 0
2689
                      && (target->flags & SEC_ALLOC) != 0)
2690
                    reltext = true;
2691
 
2692
                  /* We use the reloc_count field as a counter if we need to
2693
                     copy relocs into the output file.  */
2694
                  sec->reloc_count = 0;
2695
                }
2696
            }
2697
          else
2698
            continue;
2699
        }
2700
 
2701
      if (strip)
2702
        _bfd_strip_section_from_output (info, sec);
2703
      else
2704
        {
2705
          /* Allocate memory for the section contents.  */
2706
          sec->contents = (bfd_byte *) bfd_zalloc(dynobj, sec->_raw_size);
2707
          if (sec->contents == NULL && sec->_raw_size != 0)
2708
            return false;
2709
        }
2710
    }
2711
 
2712
  if (elf_hash_table (info)->dynamic_sections_created)
2713
    {
2714
      /* Add some entries to the .dynamic section.  We fill in the values
2715
         later (in finish_dynamic_sections) but we must add the entries now
2716
         so that we get the correct size for the .dynamic section.  */
2717
 
2718
      if (!info->shared)
2719
        {
2720
          /* The DT_DEBUG entry is filled in by the dynamic linker and used
2721
             by the debugger.  */
2722
          if (!bfd_elfNN_add_dynamic_entry (info, DT_DEBUG, 0))
2723
            return false;
2724
        }
2725
 
2726
      if (! bfd_elfNN_add_dynamic_entry (info, DT_IA_64_PLT_RESERVE, 0))
2727
        return false;
2728
      if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTGOT, 0))
2729
        return false;
2730
 
2731
      if (relplt)
2732
        {
2733
          if (! bfd_elfNN_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2734
              || ! bfd_elfNN_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2735
              || ! bfd_elfNN_add_dynamic_entry (info, DT_JMPREL, 0))
2736
            return false;
2737
        }
2738
 
2739
      if (! bfd_elfNN_add_dynamic_entry (info, DT_RELA, 0)
2740
          || ! bfd_elfNN_add_dynamic_entry (info, DT_RELASZ, 0)
2741
          || ! bfd_elfNN_add_dynamic_entry (info, DT_RELAENT,
2742
                                            sizeof (ElfNN_External_Rela)))
2743
        return false;
2744
 
2745
      if (reltext)
2746
        {
2747
          if (! bfd_elfNN_add_dynamic_entry (info, DT_TEXTREL, 0))
2748
            return false;
2749
          info->flags |= DF_TEXTREL;
2750
        }
2751
    }
2752
 
2753
  /* ??? Perhaps force __gp local.  */
2754
 
2755
  return true;
2756
}
2757
 
2758
static bfd_reloc_status_type
2759
elfNN_ia64_install_value (abfd, hit_addr, val, r_type)
2760
     bfd *abfd;
2761
     bfd_byte *hit_addr;
2762
     bfd_vma val;
2763
     unsigned int r_type;
2764
{
2765
  const struct ia64_operand *op;
2766
  int bigendian = 0, shift = 0;
2767
  bfd_vma t0, t1, insn, dword;
2768
  enum ia64_opnd opnd;
2769
  const char *err;
2770
  size_t size = 8;
2771
 
2772
  opnd = IA64_OPND_NIL;
2773
  switch (r_type)
2774
    {
2775
    case R_IA64_NONE:
2776
    case R_IA64_LDXMOV:
2777
      return bfd_reloc_ok;
2778
 
2779
      /* Instruction relocations.  */
2780
 
2781
    case R_IA64_IMM14:          opnd = IA64_OPND_IMM14; break;
2782
 
2783
    case R_IA64_PCREL21F:       opnd = IA64_OPND_TGT25; break;
2784
    case R_IA64_PCREL21M:       opnd = IA64_OPND_TGT25b; break;
2785
    case R_IA64_PCREL60B:       opnd = IA64_OPND_TGT64; break;
2786
    case R_IA64_PCREL21B:
2787
    case R_IA64_PCREL21BI:
2788
      opnd = IA64_OPND_TGT25c;
2789
      break;
2790
 
2791
    case R_IA64_IMM22:
2792
    case R_IA64_GPREL22:
2793
    case R_IA64_LTOFF22:
2794
    case R_IA64_LTOFF22X:
2795
    case R_IA64_PLTOFF22:
2796
    case R_IA64_PCREL22:
2797
    case R_IA64_LTOFF_FPTR22:
2798
      opnd = IA64_OPND_IMM22;
2799
      break;
2800
 
2801
    case R_IA64_IMM64:
2802
    case R_IA64_GPREL64I:
2803
    case R_IA64_LTOFF64I:
2804
    case R_IA64_PLTOFF64I:
2805
    case R_IA64_PCREL64I:
2806
    case R_IA64_FPTR64I:
2807
    case R_IA64_LTOFF_FPTR64I:
2808
      opnd = IA64_OPND_IMMU64;
2809
      break;
2810
 
2811
      /* Data relocations.  */
2812
 
2813
    case R_IA64_DIR32MSB:
2814
    case R_IA64_GPREL32MSB:
2815
    case R_IA64_FPTR32MSB:
2816
    case R_IA64_PCREL32MSB:
2817
    case R_IA64_SEGREL32MSB:
2818
    case R_IA64_SECREL32MSB:
2819
    case R_IA64_LTV32MSB:
2820
      size = 4; bigendian = 1;
2821
      break;
2822
 
2823
    case R_IA64_DIR32LSB:
2824
    case R_IA64_GPREL32LSB:
2825
    case R_IA64_FPTR32LSB:
2826
    case R_IA64_PCREL32LSB:
2827
    case R_IA64_SEGREL32LSB:
2828
    case R_IA64_SECREL32LSB:
2829
    case R_IA64_LTV32LSB:
2830
      size = 4; bigendian = 0;
2831
      break;
2832
 
2833
    case R_IA64_DIR64MSB:
2834
    case R_IA64_GPREL64MSB:
2835
    case R_IA64_PLTOFF64MSB:
2836
    case R_IA64_FPTR64MSB:
2837
    case R_IA64_PCREL64MSB:
2838
    case R_IA64_LTOFF_FPTR64MSB:
2839
    case R_IA64_SEGREL64MSB:
2840
    case R_IA64_SECREL64MSB:
2841
    case R_IA64_LTV64MSB:
2842
      size = 8; bigendian = 1;
2843
      break;
2844
 
2845
    case R_IA64_DIR64LSB:
2846
    case R_IA64_GPREL64LSB:
2847
    case R_IA64_PLTOFF64LSB:
2848
    case R_IA64_FPTR64LSB:
2849
    case R_IA64_PCREL64LSB:
2850
    case R_IA64_LTOFF_FPTR64LSB:
2851
    case R_IA64_SEGREL64LSB:
2852
    case R_IA64_SECREL64LSB:
2853
    case R_IA64_LTV64LSB:
2854
      size = 8; bigendian = 0;
2855
      break;
2856
 
2857
      /* Unsupported / Dynamic relocations.  */
2858
    default:
2859
      return bfd_reloc_notsupported;
2860
    }
2861
 
2862
  switch (opnd)
2863
    {
2864
    case IA64_OPND_IMMU64:
2865
      hit_addr -= (long) hit_addr & 0x3;
2866
      t0 = bfd_get_64 (abfd, hit_addr);
2867
      t1 = bfd_get_64 (abfd, hit_addr + 8);
2868
 
2869
      /* tmpl/s: bits  0.. 5 in t0
2870
         slot 0: bits  5..45 in t0
2871
         slot 1: bits 46..63 in t0, bits 0..22 in t1
2872
         slot 2: bits 23..63 in t1 */
2873
 
2874
      /* First, clear the bits that form the 64 bit constant.  */
2875
      t0 &= ~(0x3ffffLL << 46);
2876
      t1 &= ~(0x7fffffLL
2877
              | ((  (0x07fLL << 13) | (0x1ffLL << 27)
2878
                    | (0x01fLL << 22) | (0x001LL << 21)
2879
                    | (0x001LL << 36)) << 23));
2880
 
2881
      t0 |= ((val >> 22) & 0x03ffffLL) << 46;           /* 18 lsbs of imm41 */
2882
      t1 |= ((val >> 40) & 0x7fffffLL) <<  0;            /* 23 msbs of imm41 */
2883
      t1 |= (  (((val >>  0) & 0x07f) << 13)             /* imm7b */
2884
               | (((val >>  7) & 0x1ff) << 27)          /* imm9d */
2885
               | (((val >> 16) & 0x01f) << 22)          /* imm5c */
2886
               | (((val >> 21) & 0x001) << 21)          /* ic */
2887
               | (((val >> 63) & 0x001) << 36)) << 23;  /* i */
2888
 
2889
      bfd_put_64 (abfd, t0, hit_addr);
2890
      bfd_put_64 (abfd, t1, hit_addr + 8);
2891
      break;
2892
 
2893
    case IA64_OPND_TGT64:
2894
      hit_addr -= (long) hit_addr & 0x3;
2895
      t0 = bfd_get_64 (abfd, hit_addr);
2896
      t1 = bfd_get_64 (abfd, hit_addr + 8);
2897
 
2898
      /* tmpl/s: bits  0.. 5 in t0
2899
         slot 0: bits  5..45 in t0
2900
         slot 1: bits 46..63 in t0, bits 0..22 in t1
2901
         slot 2: bits 23..63 in t1 */
2902
 
2903
      /* First, clear the bits that form the 64 bit constant.  */
2904
      t0 &= ~(0x3ffffLL << 46);
2905
      t1 &= ~(0x7fffffLL
2906
              | ((1LL << 36 | 0xfffffLL << 13) << 23));
2907
 
2908
      val >>= 4;
2909
      t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;        /* 16 lsbs of imm39 */
2910
      t1 |= ((val >> 36) & 0x7fffffLL) << 0;             /* 23 msbs of imm39 */
2911
      t1 |= ((((val >> 0) & 0xfffffLL) << 13)            /* imm20b */
2912
              | (((val >> 59) & 0x1LL) << 36)) << 23;   /* i */
2913
 
2914
      bfd_put_64 (abfd, t0, hit_addr);
2915
      bfd_put_64 (abfd, t1, hit_addr + 8);
2916
      break;
2917
 
2918
    default:
2919
      switch ((long) hit_addr & 0x3)
2920
        {
2921
        case 0: shift =  5; break;
2922
        case 1: shift = 14; hit_addr += 3; break;
2923
        case 2: shift = 23; hit_addr += 6; break;
2924
        case 3: return bfd_reloc_notsupported; /* shouldn't happen...  */
2925
        }
2926
      dword = bfd_get_64 (abfd, hit_addr);
2927
      insn = (dword >> shift) & 0x1ffffffffffLL;
2928
 
2929
      op = elf64_ia64_operands + opnd;
2930
      err = (*op->insert) (op, val, &insn);
2931
      if (err)
2932
        return bfd_reloc_overflow;
2933
 
2934
      dword &= ~(0x1ffffffffffLL << shift);
2935
      dword |= (insn << shift);
2936
      bfd_put_64 (abfd, dword, hit_addr);
2937
      break;
2938
 
2939
    case IA64_OPND_NIL:
2940
      /* A data relocation.  */
2941
      if (bigendian)
2942
        if (size == 4)
2943
          bfd_putb32 (val, hit_addr);
2944
        else
2945
          bfd_putb64 (val, hit_addr);
2946
      else
2947
        if (size == 4)
2948
          bfd_putl32 (val, hit_addr);
2949
        else
2950
          bfd_putl64 (val, hit_addr);
2951
      break;
2952
    }
2953
 
2954
  return bfd_reloc_ok;
2955
}
2956
 
2957
static void
2958
elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
2959
                              dynindx, addend)
2960
     bfd *abfd;
2961
     struct bfd_link_info *info;
2962
     asection *sec;
2963
     asection *srel;
2964
     bfd_vma offset;
2965
     unsigned int type;
2966
     long dynindx;
2967
     bfd_vma addend;
2968
{
2969
  Elf_Internal_Rela outrel;
2970
 
2971
  outrel.r_offset = (sec->output_section->vma
2972
                     + sec->output_offset
2973
                     + offset);
2974
 
2975
  BFD_ASSERT (dynindx != -1);
2976
  outrel.r_info = ELFNN_R_INFO (dynindx, type);
2977
  outrel.r_addend = addend;
2978
 
2979
  if (elf_section_data (sec)->stab_info != NULL)
2980
    {
2981
      /* This may be NULL for linker-generated relocations, as it is
2982
         inconvenient to pass all the bits around.  And this shouldn't
2983
         happen.  */
2984
      BFD_ASSERT (info != NULL);
2985
 
2986
      offset = (_bfd_stab_section_offset
2987
                (abfd, &elf_hash_table (info)->stab_info, sec,
2988
                 &elf_section_data (sec)->stab_info, offset));
2989
      if (offset == (bfd_vma) -1)
2990
        {
2991
          /* Run for the hills.  We shouldn't be outputting a relocation
2992
             for this.  So do what everyone else does and output a no-op.  */
2993
          outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
2994
          outrel.r_addend = 0;
2995
          offset = 0;
2996
        }
2997
      outrel.r_offset = offset;
2998
    }
2999
 
3000
  bfd_elfNN_swap_reloca_out (abfd, &outrel,
3001
                             ((ElfNN_External_Rela *) srel->contents
3002
                              + srel->reloc_count++));
3003
  BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3004
              <= srel->_cooked_size);
3005
}
3006
 
3007
/* Store an entry for target address TARGET_ADDR in the linkage table
3008
   and return the gp-relative address of the linkage table entry.  */
3009
 
3010
static bfd_vma
3011
set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3012
     bfd *abfd;
3013
     struct bfd_link_info *info;
3014
     struct elfNN_ia64_dyn_sym_info *dyn_i;
3015
     long dynindx;
3016
     bfd_vma addend;
3017
     bfd_vma value;
3018
     unsigned int dyn_r_type;
3019
{
3020
  struct elfNN_ia64_link_hash_table *ia64_info;
3021
  asection *got_sec;
3022
 
3023
  ia64_info = elfNN_ia64_hash_table (info);
3024
  got_sec = ia64_info->got_sec;
3025
 
3026
  BFD_ASSERT ((dyn_i->got_offset & 7) == 0);
3027
 
3028
  if (! dyn_i->got_done)
3029
    {
3030
      dyn_i->got_done = true;
3031
 
3032
      /* Store the target address in the linkage table entry.  */
3033
      bfd_put_64 (abfd, value, got_sec->contents + dyn_i->got_offset);
3034
 
3035
      /* Install a dynamic relocation if needed.  */
3036
      if (info->shared
3037
          || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
3038
          || elfNN_ia64_aix_vec (abfd->xvec)
3039
          || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3040
        {
3041
          if (dynindx == -1)
3042
            {
3043
              dyn_r_type = R_IA64_REL64LSB;
3044
              dynindx = 0;
3045
              addend = value;
3046
            }
3047
 
3048
          if (bfd_big_endian (abfd))
3049
            {
3050
              switch (dyn_r_type)
3051
                {
3052
                case R_IA64_REL64LSB:
3053
                  dyn_r_type = R_IA64_REL64MSB;
3054
                  break;
3055
                case R_IA64_DIR64LSB:
3056
                  dyn_r_type = R_IA64_DIR64MSB;
3057
                  break;
3058
                case R_IA64_FPTR64LSB:
3059
                  dyn_r_type = R_IA64_FPTR64MSB;
3060
                  break;
3061
                default:
3062
                  BFD_ASSERT (false);
3063
                  break;
3064
                }
3065
            }
3066
 
3067
          elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3068
                                        ia64_info->rel_got_sec,
3069
                                        dyn_i->got_offset, dyn_r_type,
3070
                                        dynindx, addend);
3071
        }
3072
    }
3073
 
3074
  /* Return the address of the linkage table entry.  */
3075
  value = (got_sec->output_section->vma
3076
           + got_sec->output_offset
3077
           + dyn_i->got_offset);
3078
 
3079
  return value;
3080
}
3081
 
3082
/* Fill in a function descriptor consisting of the function's code
3083
   address and its global pointer.  Return the descriptor's address.  */
3084
 
3085
static bfd_vma
3086
set_fptr_entry (abfd, info, dyn_i, value)
3087
     bfd *abfd;
3088
     struct bfd_link_info *info;
3089
     struct elfNN_ia64_dyn_sym_info *dyn_i;
3090
     bfd_vma value;
3091
{
3092
  struct elfNN_ia64_link_hash_table *ia64_info;
3093
  asection *fptr_sec;
3094
 
3095
  ia64_info = elfNN_ia64_hash_table (info);
3096
  fptr_sec = ia64_info->fptr_sec;
3097
 
3098
  if (!dyn_i->fptr_done)
3099
    {
3100
      dyn_i->fptr_done = 1;
3101
 
3102
      /* Fill in the function descriptor.  */
3103
      bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3104
      bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3105
                  fptr_sec->contents + dyn_i->fptr_offset + 8);
3106
    }
3107
 
3108
  /* Return the descriptor's address.  */
3109
  value = (fptr_sec->output_section->vma
3110
           + fptr_sec->output_offset
3111
           + dyn_i->fptr_offset);
3112
 
3113
  return value;
3114
}
3115
 
3116
/* Fill in a PLTOFF entry consisting of the function's code address
3117
   and its global pointer.  Return the descriptor's address.  */
3118
 
3119
static bfd_vma
3120
set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3121
     bfd *abfd;
3122
     struct bfd_link_info *info;
3123
     struct elfNN_ia64_dyn_sym_info *dyn_i;
3124
     bfd_vma value;
3125
     boolean is_plt;
3126
{
3127
  struct elfNN_ia64_link_hash_table *ia64_info;
3128
  asection *pltoff_sec;
3129
 
3130
  ia64_info = elfNN_ia64_hash_table (info);
3131
  pltoff_sec = ia64_info->pltoff_sec;
3132
 
3133
  /* Don't do anything if this symbol uses a real PLT entry.  In
3134
     that case, we'll fill this in during finish_dynamic_symbol.  */
3135
  if ((! dyn_i->want_plt || is_plt)
3136
      && !dyn_i->pltoff_done)
3137
    {
3138
      bfd_vma gp = _bfd_get_gp_value (abfd);
3139
 
3140
      /* Fill in the function descriptor.  */
3141
      bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3142
      bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3143
 
3144
      /* Install dynamic relocations if needed.  */
3145
      if (!is_plt && info->shared)
3146
        {
3147
          unsigned int dyn_r_type;
3148
 
3149
          if (bfd_big_endian (abfd))
3150
            dyn_r_type = R_IA64_REL64MSB;
3151
          else
3152
            dyn_r_type = R_IA64_REL64LSB;
3153
 
3154
          elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3155
                                        ia64_info->rel_pltoff_sec,
3156
                                        dyn_i->pltoff_offset,
3157
                                        dyn_r_type, 0, value);
3158
          elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3159
                                        ia64_info->rel_pltoff_sec,
3160
                                        dyn_i->pltoff_offset + 8,
3161
                                        dyn_r_type, 0, gp);
3162
        }
3163
 
3164
      dyn_i->pltoff_done = 1;
3165
    }
3166
 
3167
  /* Return the descriptor's address.  */
3168
  value = (pltoff_sec->output_section->vma
3169
           + pltoff_sec->output_offset
3170
           + dyn_i->pltoff_offset);
3171
 
3172
  return value;
3173
}
3174
 
3175
/* Called through qsort to sort the .IA_64.unwind section during a
3176
   non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
3177
   to the output bfd so we can do proper endianness frobbing.  */
3178
 
3179
static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3180
 
3181
static int
3182
elfNN_ia64_unwind_entry_compare (a, b)
3183
     PTR a;
3184
     PTR b;
3185
{
3186
  bfd_vma av, bv;
3187
 
3188
  av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3189
  bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3190
 
3191
  return (av < bv ? -1 : av > bv ? 1 : 0);
3192
}
3193
 
3194
static boolean
3195
elfNN_ia64_final_link (abfd, info)
3196
     bfd *abfd;
3197
     struct bfd_link_info *info;
3198
{
3199
  struct elfNN_ia64_link_hash_table *ia64_info;
3200
  asection *unwind_output_sec;
3201
 
3202
  ia64_info = elfNN_ia64_hash_table (info);
3203
 
3204
  /* Make sure we've got ourselves a nice fat __gp value.  */
3205
  if (!info->relocateable)
3206
    {
3207
      bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3208
      bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3209
      struct elf_link_hash_entry *gp;
3210
      bfd_vma gp_val;
3211
      asection *os;
3212
 
3213
      /* Find the min and max vma of all sections marked short.  Also
3214
         collect min and max vma of any type, for use in selecting a
3215
         nice gp.  */
3216
      for (os = abfd->sections; os ; os = os->next)
3217
        {
3218
          bfd_vma lo, hi;
3219
 
3220
          if ((os->flags & SEC_ALLOC) == 0)
3221
            continue;
3222
 
3223
          lo = os->vma;
3224
          hi = os->vma + os->_raw_size;
3225
          if (hi < lo)
3226
            hi = (bfd_vma) -1;
3227
 
3228
          if (min_vma > lo)
3229
            min_vma = lo;
3230
          if (max_vma < hi)
3231
            max_vma = hi;
3232
          if (os->flags & SEC_SMALL_DATA)
3233
            {
3234
              if (min_short_vma > lo)
3235
                min_short_vma = lo;
3236
              if (max_short_vma < hi)
3237
                max_short_vma = hi;
3238
            }
3239
        }
3240
 
3241
      /* See if the user wants to force a value.  */
3242
      gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3243
                                 false, false);
3244
 
3245
      if (gp
3246
          && (gp->root.type == bfd_link_hash_defined
3247
              || gp->root.type == bfd_link_hash_defweak))
3248
        {
3249
          asection *gp_sec = gp->root.u.def.section;
3250
          gp_val = (gp->root.u.def.value
3251
                    + gp_sec->output_section->vma
3252
                    + gp_sec->output_offset);
3253
        }
3254
      else
3255
        {
3256
          /* Pick a sensible value.  */
3257
 
3258
          asection *got_sec = ia64_info->got_sec;
3259
 
3260
          /* Start with just the address of the .got.  */
3261
          if (got_sec)
3262
            gp_val = got_sec->output_section->vma;
3263
          else if (max_short_vma != 0)
3264
            gp_val = min_short_vma;
3265
          else
3266
            gp_val = min_vma;
3267
 
3268
          /* If it is possible to address the entire image, but we
3269
             don't with the choice above, adjust.  */
3270
          if (max_vma - min_vma < 0x400000
3271
              && max_vma - gp_val <= 0x200000
3272
              && gp_val - min_vma > 0x200000)
3273
            gp_val = min_vma + 0x200000;
3274
          else if (max_short_vma != 0)
3275
            {
3276
              /* If we don't cover all the short data, adjust.  */
3277
              if (max_short_vma - gp_val >= 0x200000)
3278
                gp_val = min_short_vma + 0x200000;
3279
 
3280
              /* If we're addressing stuff past the end, adjust back.  */
3281
              if (gp_val > max_vma)
3282
                gp_val = max_vma - 0x200000 + 8;
3283
            }
3284
        }
3285
 
3286
      /* Validate whether all SHF_IA_64_SHORT sections are within
3287
         range of the chosen GP.  */
3288
 
3289
      if (max_short_vma != 0)
3290
        {
3291
          if (max_short_vma - min_short_vma >= 0x400000)
3292
            {
3293
              (*_bfd_error_handler)
3294
                (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3295
                 bfd_get_filename (abfd),
3296
                 (unsigned long) (max_short_vma - min_short_vma));
3297
              return false;
3298
            }
3299
          else if ((gp_val > min_short_vma
3300
                    && gp_val - min_short_vma > 0x200000)
3301
                   || (gp_val < max_short_vma
3302
                       && max_short_vma - gp_val >= 0x200000))
3303
            {
3304
              (*_bfd_error_handler)
3305
                (_("%s: __gp does not cover short data segment"),
3306
                 bfd_get_filename (abfd));
3307
              return false;
3308
            }
3309
        }
3310
 
3311
      _bfd_set_gp_value (abfd, gp_val);
3312
 
3313
      if (gp)
3314
        {
3315
          gp->root.type = bfd_link_hash_defined;
3316
          gp->root.u.def.value = gp_val;
3317
          gp->root.u.def.section = bfd_abs_section_ptr;
3318
        }
3319
    }
3320
 
3321
  /* If we're producing a final executable, we need to sort the contents
3322
     of the .IA_64.unwind section.  Force this section to be relocated
3323
     into memory rather than written immediately to the output file.  */
3324
  unwind_output_sec = NULL;
3325
  if (!info->relocateable)
3326
    {
3327
      asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3328
      if (s)
3329
        {
3330
          unwind_output_sec = s->output_section;
3331
          unwind_output_sec->contents
3332
            = bfd_malloc (unwind_output_sec->_raw_size);
3333
          if (unwind_output_sec->contents == NULL)
3334
            return false;
3335
        }
3336
    }
3337
 
3338
  /* Invoke the regular ELF backend linker to do all the work.  */
3339
  if (!bfd_elfNN_bfd_final_link (abfd, info))
3340
    return false;
3341
 
3342
  if (unwind_output_sec)
3343
    {
3344
      elfNN_ia64_unwind_entry_compare_bfd = abfd;
3345
      qsort (unwind_output_sec->contents, unwind_output_sec->_raw_size / 24,
3346
             24, elfNN_ia64_unwind_entry_compare);
3347
 
3348
      if (! bfd_set_section_contents (abfd, unwind_output_sec,
3349
                                      unwind_output_sec->contents, 0,
3350
                                      unwind_output_sec->_raw_size))
3351
        return false;
3352
    }
3353
 
3354
  return true;
3355
}
3356
 
3357
static boolean
3358
elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3359
                             contents, relocs, local_syms, local_sections)
3360
     bfd *output_bfd;
3361
     struct bfd_link_info *info;
3362
     bfd *input_bfd;
3363
     asection *input_section;
3364
     bfd_byte *contents;
3365
     Elf_Internal_Rela *relocs;
3366
     Elf_Internal_Sym *local_syms;
3367
     asection **local_sections;
3368
{
3369
  struct elfNN_ia64_link_hash_table *ia64_info;
3370
  Elf_Internal_Shdr *symtab_hdr;
3371
  Elf_Internal_Rela *rel;
3372
  Elf_Internal_Rela *relend;
3373
  asection *srel;
3374
  boolean ret_val = true;       /* for non-fatal errors */
3375
  bfd_vma gp_val;
3376
 
3377
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3378
  ia64_info = elfNN_ia64_hash_table (info);
3379
 
3380
  /* Infect various flags from the input section to the output section.  */
3381
  if (info->relocateable)
3382
    {
3383
      bfd_vma flags;
3384
 
3385
      flags = elf_section_data(input_section)->this_hdr.sh_flags;
3386
      flags &= SHF_IA_64_NORECOV;
3387
 
3388
      elf_section_data(input_section->output_section)
3389
        ->this_hdr.sh_flags |= flags;
3390
    }
3391
 
3392
  gp_val = _bfd_get_gp_value (output_bfd);
3393
  srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3394
 
3395
  rel = relocs;
3396
  relend = relocs + input_section->reloc_count;
3397
  for (; rel < relend; ++rel)
3398
    {
3399
      struct elf_link_hash_entry *h;
3400
      struct elfNN_ia64_dyn_sym_info *dyn_i;
3401
      bfd_reloc_status_type r;
3402
      reloc_howto_type *howto;
3403
      unsigned long r_symndx;
3404
      Elf_Internal_Sym *sym;
3405
      unsigned int r_type;
3406
      bfd_vma value;
3407
      asection *sym_sec;
3408
      bfd_byte *hit_addr;
3409
      boolean dynamic_symbol_p;
3410
      boolean undef_weak_ref;
3411
 
3412
      r_type = ELFNN_R_TYPE (rel->r_info);
3413
      if (r_type > R_IA64_MAX_RELOC_CODE)
3414
        {
3415
          (*_bfd_error_handler)
3416
            (_("%s: unknown relocation type %d"),
3417
             bfd_get_filename (input_bfd), (int)r_type);
3418
          bfd_set_error (bfd_error_bad_value);
3419
          ret_val = false;
3420
          continue;
3421
        }
3422
      howto = lookup_howto (r_type);
3423
      r_symndx = ELFNN_R_SYM (rel->r_info);
3424
 
3425
      if (info->relocateable)
3426
        {
3427
          /* This is a relocateable link.  We don't have to change
3428
             anything, unless the reloc is against a section symbol,
3429
             in which case we have to adjust according to where the
3430
             section symbol winds up in the output section.  */
3431
          if (r_symndx < symtab_hdr->sh_info)
3432
            {
3433
              sym = local_syms + r_symndx;
3434
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
3435
                {
3436
                  sym_sec = local_sections[r_symndx];
3437
                  rel->r_addend += sym_sec->output_offset;
3438
                }
3439
            }
3440
          continue;
3441
        }
3442
 
3443
      /* This is a final link.  */
3444
 
3445
      h = NULL;
3446
      sym = NULL;
3447
      sym_sec = NULL;
3448
      undef_weak_ref = false;
3449
 
3450
      if (r_symndx < symtab_hdr->sh_info)
3451
        {
3452
          /* Reloc against local symbol.  */
3453
          sym = local_syms + r_symndx;
3454
          sym_sec = local_sections[r_symndx];
3455
          value  = (sym_sec->output_section->vma
3456
                    + sym_sec->output_offset
3457
                    + sym->st_value);
3458
        }
3459
      else
3460
        {
3461
          long indx;
3462
 
3463
          /* Reloc against global symbol.  */
3464
          indx = r_symndx - symtab_hdr->sh_info;
3465
          h = elf_sym_hashes (input_bfd)[indx];
3466
          while (h->root.type == bfd_link_hash_indirect
3467
                 || h->root.type == bfd_link_hash_warning)
3468
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
3469
 
3470
          value = 0;
3471
          if (h->root.type == bfd_link_hash_defined
3472
              || h->root.type == bfd_link_hash_defweak)
3473
            {
3474
              sym_sec = h->root.u.def.section;
3475
 
3476
              /* Detect the cases that sym_sec->output_section is
3477
                 expected to be NULL -- all cases in which the symbol
3478
                 is defined in another shared module.  This includes
3479
                 PLT relocs for which we've created a PLT entry and
3480
                 other relocs for which we're prepared to create
3481
                 dynamic relocations.  */
3482
              /* ??? Just accept it NULL and continue.  */
3483
 
3484
              if (sym_sec->output_section != NULL)
3485
                {
3486
                  value = (h->root.u.def.value
3487
                           + sym_sec->output_section->vma
3488
                           + sym_sec->output_offset);
3489
                }
3490
            }
3491
          else if (h->root.type == bfd_link_hash_undefweak)
3492
            undef_weak_ref = true;
3493
          else if (info->shared && !info->symbolic
3494
                   && !info->no_undefined
3495
                   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3496
            ;
3497
          else
3498
            {
3499
              if (! ((*info->callbacks->undefined_symbol)
3500
                     (info, h->root.root.string, input_bfd,
3501
                      input_section, rel->r_offset,
3502
                      (!info->shared || info->no_undefined
3503
                       || ELF_ST_VISIBILITY (h->other)))))
3504
                return false;
3505
              ret_val = false;
3506
              continue;
3507
            }
3508
        }
3509
 
3510
      hit_addr = contents + rel->r_offset;
3511
      value += rel->r_addend;
3512
      dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3513
 
3514
      switch (r_type)
3515
        {
3516
        case R_IA64_NONE:
3517
        case R_IA64_LDXMOV:
3518
          continue;
3519
 
3520
        case R_IA64_IMM14:
3521
        case R_IA64_IMM22:
3522
        case R_IA64_IMM64:
3523
        case R_IA64_DIR32MSB:
3524
        case R_IA64_DIR32LSB:
3525
        case R_IA64_DIR64MSB:
3526
        case R_IA64_DIR64LSB:
3527
          /* Install a dynamic relocation for this reloc.  */
3528
          if ((dynamic_symbol_p || info->shared
3529
               || (elfNN_ia64_aix_vec (info->hash->creator)
3530
                   /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3531
                   && (!h || strcmp (h->root.root.string,
3532
                                     "__GLOB_DATA_PTR") != 0)))
3533
              && (input_section->flags & SEC_ALLOC) != 0)
3534
            {
3535
              unsigned int dyn_r_type;
3536
              long dynindx;
3537
              bfd_vma addend;
3538
 
3539
              BFD_ASSERT (srel != NULL);
3540
 
3541
              /* If we don't need dynamic symbol lookup, find a
3542
                 matching RELATIVE relocation.  */
3543
              dyn_r_type = r_type;
3544
              if (dynamic_symbol_p)
3545
                {
3546
                  dynindx = h->dynindx;
3547
                  addend = rel->r_addend;
3548
                  value = 0;
3549
                }
3550
              else
3551
                {
3552
                  switch (r_type)
3553
                    {
3554
                    case R_IA64_DIR32MSB:
3555
                      dyn_r_type = R_IA64_REL32MSB;
3556
                      break;
3557
                    case R_IA64_DIR32LSB:
3558
                      dyn_r_type = R_IA64_REL32LSB;
3559
                      break;
3560
                    case R_IA64_DIR64MSB:
3561
                      dyn_r_type = R_IA64_REL64MSB;
3562
                      break;
3563
                    case R_IA64_DIR64LSB:
3564
                      dyn_r_type = R_IA64_REL64LSB;
3565
                      break;
3566
 
3567
                    default:
3568
                      /* We can't represent this without a dynamic symbol.
3569
                         Adjust the relocation to be against an output
3570
                         section symbol, which are always present in the
3571
                         dynamic symbol table.  */
3572
                      /* ??? People shouldn't be doing non-pic code in
3573
                         shared libraries.  Hork.  */
3574
                      (*_bfd_error_handler)
3575
                        (_("%s: linking non-pic code in a shared library"),
3576
                         bfd_get_filename (input_bfd));
3577
                      ret_val = false;
3578
                      continue;
3579
                    }
3580
                  dynindx = 0;
3581
                  addend = value;
3582
                }
3583
 
3584
              if (elfNN_ia64_aix_vec (info->hash->creator))
3585
                rel->r_addend = value;
3586
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3587
                                            srel, rel->r_offset, dyn_r_type,
3588
                                            dynindx, addend);
3589
            }
3590
          /* FALLTHRU */
3591
 
3592
        case R_IA64_LTV32MSB:
3593
        case R_IA64_LTV32LSB:
3594
        case R_IA64_LTV64MSB:
3595
        case R_IA64_LTV64LSB:
3596
          r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3597
          break;
3598
 
3599
        case R_IA64_GPREL22:
3600
        case R_IA64_GPREL64I:
3601
        case R_IA64_GPREL32MSB:
3602
        case R_IA64_GPREL32LSB:
3603
        case R_IA64_GPREL64MSB:
3604
        case R_IA64_GPREL64LSB:
3605
          if (dynamic_symbol_p)
3606
            {
3607
              (*_bfd_error_handler)
3608
                (_("%s: @gprel relocation against dynamic symbol %s"),
3609
                 bfd_get_filename (input_bfd), h->root.root.string);
3610
              ret_val = false;
3611
              continue;
3612
            }
3613
          value -= gp_val;
3614
          r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3615
          break;
3616
 
3617
        case R_IA64_LTOFF22:
3618
        case R_IA64_LTOFF22X:
3619
        case R_IA64_LTOFF64I:
3620
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3621
          value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3622
                                 rel->r_addend, value, R_IA64_DIR64LSB);
3623
          value -= gp_val;
3624
          r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3625
          break;
3626
 
3627
        case R_IA64_PLTOFF22:
3628
        case R_IA64_PLTOFF64I:
3629
        case R_IA64_PLTOFF64MSB:
3630
        case R_IA64_PLTOFF64LSB:
3631
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3632
          value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3633
          value -= gp_val;
3634
          r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3635
          break;
3636
 
3637
        case R_IA64_FPTR64I:
3638
        case R_IA64_FPTR32MSB:
3639
        case R_IA64_FPTR32LSB:
3640
        case R_IA64_FPTR64MSB:
3641
        case R_IA64_FPTR64LSB:
3642
          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3643
          if (dyn_i->want_fptr)
3644
            {
3645
              if (!undef_weak_ref)
3646
                value = set_fptr_entry (output_bfd, info, dyn_i, value);
3647
            }
3648
          else
3649
            {
3650
              long dynindx;
3651
 
3652
              /* Otherwise, we expect the dynamic linker to create
3653
                 the entry.  */
3654
 
3655
              if (h)
3656
                {
3657
                  if (h->dynindx != -1)
3658
                    dynindx = h->dynindx;
3659
                  else
3660
                    dynindx = (_bfd_elf_link_lookup_local_dynindx
3661
                               (info, h->root.u.def.section->owner,
3662
                                global_sym_index (h)));
3663
                }
3664
              else
3665
                {
3666
                  dynindx = (_bfd_elf_link_lookup_local_dynindx
3667
                             (info, input_bfd, r_symndx));
3668
                }
3669
 
3670
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3671
                                            srel, rel->r_offset, r_type,
3672
                                            dynindx, rel->r_addend);
3673
              value = 0;
3674
            }
3675
 
3676
          r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3677
          break;
3678
 
3679
        case R_IA64_LTOFF_FPTR22:
3680
        case R_IA64_LTOFF_FPTR64I:
3681
        case R_IA64_LTOFF_FPTR64MSB:
3682
        case R_IA64_LTOFF_FPTR64LSB:
3683
          {
3684
            long dynindx;
3685
 
3686
            dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3687
            if (dyn_i->want_fptr)
3688
              {
3689
                BFD_ASSERT (h == NULL || h->dynindx == -1)
3690
                if (!undef_weak_ref)
3691
                  value = set_fptr_entry (output_bfd, info, dyn_i, value);
3692
                dynindx = -1;
3693
              }
3694
            else
3695
              {
3696
                /* Otherwise, we expect the dynamic linker to create
3697
                   the entry.  */
3698
                if (h)
3699
                  {
3700
                    if (h->dynindx != -1)
3701
                      dynindx = h->dynindx;
3702
                    else
3703
                      dynindx = (_bfd_elf_link_lookup_local_dynindx
3704
                                 (info, h->root.u.def.section->owner,
3705
                                  global_sym_index (h)));
3706
                  }
3707
                else
3708
                  dynindx = (_bfd_elf_link_lookup_local_dynindx
3709
                             (info, input_bfd, r_symndx));
3710
                value = 0;
3711
              }
3712
 
3713
            value = set_got_entry (output_bfd, info, dyn_i, dynindx,
3714
                                   rel->r_addend, value, R_IA64_FPTR64LSB);
3715
            value -= gp_val;
3716
            r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3717
          }
3718
          break;
3719
 
3720
        case R_IA64_PCREL32MSB:
3721
        case R_IA64_PCREL32LSB:
3722
        case R_IA64_PCREL64MSB:
3723
        case R_IA64_PCREL64LSB:
3724
          /* Install a dynamic relocation for this reloc.  */
3725
          if (dynamic_symbol_p
3726
              || elfNN_ia64_aix_vec (info->hash->creator))
3727
            {
3728
              BFD_ASSERT (srel != NULL);
3729
 
3730
              elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3731
                                            srel, rel->r_offset, r_type,
3732
                                            h->dynindx, rel->r_addend);
3733
            }
3734
          goto finish_pcrel;
3735
 
3736
        case R_IA64_PCREL21BI:
3737
        case R_IA64_PCREL21F:
3738
        case R_IA64_PCREL21M:
3739
          /* ??? These two are only used for speculation fixup code.
3740
             They should never be dynamic.  */
3741
          if (dynamic_symbol_p)
3742
            {
3743
              (*_bfd_error_handler)
3744
                (_("%s: dynamic relocation against speculation fixup"),
3745
                 bfd_get_filename (input_bfd));
3746
              ret_val = false;
3747
              continue;
3748
            }
3749
          if (undef_weak_ref)
3750
            {
3751
              (*_bfd_error_handler)
3752
                (_("%s: speculation fixup against undefined weak symbol"),
3753
                 bfd_get_filename (input_bfd));
3754
              ret_val = false;
3755
              continue;
3756
            }
3757
          goto finish_pcrel;
3758
 
3759
        case R_IA64_PCREL21B:
3760
        case R_IA64_PCREL60B:
3761
          /* We should have created a PLT entry for any dynamic symbol.  */
3762
          dyn_i = NULL;
3763
          if (h)
3764
            dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3765
 
3766
          if (dyn_i && dyn_i->want_plt2)
3767
            {
3768
              /* Should have caught this earlier.  */
3769
              BFD_ASSERT (rel->r_addend == 0);
3770
 
3771
              value = (ia64_info->plt_sec->output_section->vma
3772
                       + ia64_info->plt_sec->output_offset
3773
                       + dyn_i->plt2_offset);
3774
            }
3775
          else
3776
            {
3777
              /* Since there's no PLT entry, Validate that this is
3778
                 locally defined.  */
3779
              BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
3780
 
3781
              /* If the symbol is undef_weak, we shouldn't be trying
3782
                 to call it.  There's every chance that we'd wind up
3783
                 with an out-of-range fixup here.  Don't bother setting
3784
                 any value at all.  */
3785
              if (undef_weak_ref)
3786
                continue;
3787
            }
3788
          goto finish_pcrel;
3789
 
3790
        case R_IA64_PCREL22:
3791
        case R_IA64_PCREL64I:
3792
        finish_pcrel:
3793
          /* Make pc-relative.  */
3794
          value -= (input_section->output_section->vma
3795
                    + input_section->output_offset
3796
                    + rel->r_offset) & ~ (bfd_vma) 0x3;
3797
          r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3798
          break;
3799
 
3800
        case R_IA64_SEGREL32MSB:
3801
        case R_IA64_SEGREL32LSB:
3802
        case R_IA64_SEGREL64MSB:
3803
        case R_IA64_SEGREL64LSB:
3804
          {
3805
            struct elf_segment_map *m;
3806
            Elf_Internal_Phdr *p;
3807
 
3808
            /* Find the segment that contains the output_section.  */
3809
            for (m = elf_tdata (output_bfd)->segment_map,
3810
                   p = elf_tdata (output_bfd)->phdr;
3811
                 m != NULL;
3812
                 m = m->next, p++)
3813
              {
3814
                int i;
3815
                for (i = m->count - 1; i >= 0; i--)
3816
                  if (m->sections[i] == sym_sec->output_section)
3817
                    break;
3818
                if (i >= 0)
3819
                  break;
3820
              }
3821
 
3822
            if (m == NULL)
3823
              {
3824
                /* If the input section was discarded from the output, then
3825
                   do nothing.  */
3826
 
3827
                if (bfd_is_abs_section (sym_sec->output_section))
3828
                  r = bfd_reloc_ok;
3829
                else
3830
                  r = bfd_reloc_notsupported;
3831
              }
3832
            else
3833
              {
3834
                /* The VMA of the segment is the vaddr of the associated
3835
                   program header.  */
3836
                if (value > p->p_vaddr)
3837
                  value -= p->p_vaddr;
3838
                else
3839
                  value = 0;
3840
                r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
3841
                                              r_type);
3842
              }
3843
            break;
3844
          }
3845
 
3846
        case R_IA64_SECREL32MSB:
3847
        case R_IA64_SECREL32LSB:
3848
        case R_IA64_SECREL64MSB:
3849
        case R_IA64_SECREL64LSB:
3850
          /* Make output-section relative.  */
3851
          if (value > input_section->output_section->vma)
3852
            value -= input_section->output_section->vma;
3853
          else
3854
            value = 0;
3855
          r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3856
          break;
3857
 
3858
        case R_IA64_IPLTMSB:
3859
        case R_IA64_IPLTLSB:
3860
          /* Install a dynamic relocation for this reloc.  */
3861
          if ((dynamic_symbol_p || info->shared)
3862
              && (input_section->flags & SEC_ALLOC) != 0)
3863
            {
3864
              BFD_ASSERT (srel != NULL);
3865
 
3866
              /* If we don't need dynamic symbol lookup, install two
3867
                 RELATIVE relocations.  */
3868
              if (! dynamic_symbol_p)
3869
                {
3870
                  unsigned int dyn_r_type;
3871
 
3872
                  if (r_type == R_IA64_IPLTMSB)
3873
                    dyn_r_type = R_IA64_REL64MSB;
3874
                  else
3875
                    dyn_r_type = R_IA64_REL64LSB;
3876
 
3877
                  elfNN_ia64_install_dyn_reloc (output_bfd, info,
3878
                                                input_section,
3879
                                                srel, rel->r_offset,
3880
                                                dyn_r_type, 0, value);
3881
                  elfNN_ia64_install_dyn_reloc (output_bfd, info,
3882
                                                input_section,
3883
                                                srel, rel->r_offset + 8,
3884
                                                dyn_r_type, 0, gp_val);
3885
                }
3886
              else
3887
                elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3888
                                              srel, rel->r_offset, r_type,
3889
                                              h->dynindx, rel->r_addend);
3890
            }
3891
 
3892
          if (r_type == R_IA64_IPLTMSB)
3893
            r_type = R_IA64_DIR64MSB;
3894
          else
3895
            r_type = R_IA64_DIR64LSB;
3896
          elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3897
          r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
3898
                                        r_type);
3899
          break;
3900
 
3901
        default:
3902
          r = bfd_reloc_notsupported;
3903
          break;
3904
        }
3905
 
3906
      switch (r)
3907
        {
3908
        case bfd_reloc_ok:
3909
          break;
3910
 
3911
        case bfd_reloc_undefined:
3912
          /* This can happen for global table relative relocs if
3913
             __gp is undefined.  This is a panic situation so we
3914
             don't try to continue.  */
3915
          (*info->callbacks->undefined_symbol)
3916
            (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
3917
          return false;
3918
 
3919
        case bfd_reloc_notsupported:
3920
          {
3921
            const char *name;
3922
 
3923
            if (h)
3924
              name = h->root.root.string;
3925
            else
3926
              {
3927
                name = bfd_elf_string_from_elf_section (input_bfd,
3928
                                                        symtab_hdr->sh_link,
3929
                                                        sym->st_name);
3930
                if (name == NULL)
3931
                  return false;
3932
                if (*name == '\0')
3933
                  name = bfd_section_name (input_bfd, input_section);
3934
              }
3935
            if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
3936
                                              name, input_bfd,
3937
                                              input_section, rel->r_offset))
3938
              return false;
3939
            ret_val = false;
3940
          }
3941
          break;
3942
 
3943
        case bfd_reloc_dangerous:
3944
        case bfd_reloc_outofrange:
3945
        case bfd_reloc_overflow:
3946
        default:
3947
          {
3948
            const char *name;
3949
 
3950
            if (h)
3951
              name = h->root.root.string;
3952
            else
3953
              {
3954
                name = bfd_elf_string_from_elf_section (input_bfd,
3955
                                                        symtab_hdr->sh_link,
3956
                                                        sym->st_name);
3957
                if (name == NULL)
3958
                  return false;
3959
                if (*name == '\0')
3960
                  name = bfd_section_name (input_bfd, input_section);
3961
              }
3962
            if (!(*info->callbacks->reloc_overflow) (info, name,
3963
                                                     howto->name, 0,
3964
                                                     input_bfd,
3965
                                                     input_section,
3966
                                                     rel->r_offset))
3967
              return false;
3968
            ret_val = false;
3969
          }
3970
          break;
3971
        }
3972
    }
3973
 
3974
  return ret_val;
3975
}
3976
 
3977
static boolean
3978
elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
3979
     bfd *output_bfd;
3980
     struct bfd_link_info *info;
3981
     struct elf_link_hash_entry *h;
3982
     Elf_Internal_Sym *sym;
3983
{
3984
  struct elfNN_ia64_link_hash_table *ia64_info;
3985
  struct elfNN_ia64_dyn_sym_info *dyn_i;
3986
 
3987
  ia64_info = elfNN_ia64_hash_table (info);
3988
  dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3989
 
3990
  /* Fill in the PLT data, if required.  */
3991
  if (dyn_i && dyn_i->want_plt)
3992
    {
3993
      Elf_Internal_Rela outrel;
3994
      bfd_byte *loc;
3995
      asection *plt_sec;
3996
      bfd_vma plt_addr, pltoff_addr, gp_val, index;
3997
      ElfNN_External_Rela *rel;
3998
 
3999
      gp_val = _bfd_get_gp_value (output_bfd);
4000
 
4001
      /* Initialize the minimal PLT entry.  */
4002
 
4003
      index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4004
      plt_sec = ia64_info->plt_sec;
4005
      loc = plt_sec->contents + dyn_i->plt_offset;
4006
 
4007
      memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4008
      elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4009
      elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4010
                                R_IA64_PCREL21B);
4011
 
4012
      plt_addr = (plt_sec->output_section->vma
4013
                  + plt_sec->output_offset
4014
                  + dyn_i->plt_offset);
4015
      pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
4016
 
4017
      /* Initialize the FULL PLT entry, if needed.  */
4018
      if (dyn_i->want_plt2)
4019
        {
4020
          loc = plt_sec->contents + dyn_i->plt2_offset;
4021
 
4022
          memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4023
          elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4024
                                    R_IA64_IMM22);
4025
 
4026
          /* Mark the symbol as undefined, rather than as defined in the
4027
             plt section.  Leave the value alone.  */
4028
          /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4029
             first place.  But perhaps elflink.h did some for us.  */
4030
          if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4031
            sym->st_shndx = SHN_UNDEF;
4032
        }
4033
 
4034
      /* Create the dynamic relocation.  */
4035
      outrel.r_offset = pltoff_addr;
4036
      if (bfd_little_endian (output_bfd))
4037
        outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4038
      else
4039
        outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4040
      outrel.r_addend = 0;
4041
 
4042
      /* This is fun.  In the .IA_64.pltoff section, we've got entries
4043
         that correspond both to real PLT entries, and those that
4044
         happened to resolve to local symbols but need to be created
4045
         to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
4046
         relocations for the real PLT should come at the end of the
4047
         section, so that they can be indexed by plt entry at runtime.
4048
 
4049
         We emitted all of the relocations for the non-PLT @pltoff
4050
         entries during relocate_section.  So we can consider the
4051
         existing sec->reloc_count to be the base of the array of
4052
         PLT relocations.  */
4053
 
4054
      rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
4055
      rel += ia64_info->rel_pltoff_sec->reloc_count;
4056
 
4057
      bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
4058
    }
4059
 
4060
  /* Mark some specially defined symbols as absolute.  */
4061
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4062
      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4063
      || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4064
    sym->st_shndx = SHN_ABS;
4065
 
4066
  return true;
4067
}
4068
 
4069
static boolean
4070
elfNN_ia64_finish_dynamic_sections (abfd, info)
4071
     bfd *abfd;
4072
     struct bfd_link_info *info;
4073
{
4074
  struct elfNN_ia64_link_hash_table *ia64_info;
4075
  bfd *dynobj;
4076
 
4077
  ia64_info = elfNN_ia64_hash_table (info);
4078
  dynobj = ia64_info->root.dynobj;
4079
 
4080
  if (elf_hash_table (info)->dynamic_sections_created)
4081
    {
4082
      ElfNN_External_Dyn *dyncon, *dynconend;
4083
      asection *sdyn, *sgotplt;
4084
      bfd_vma gp_val;
4085
 
4086
      sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4087
      sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4088
      BFD_ASSERT (sdyn != NULL);
4089
      dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4090
      dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4091
 
4092
      gp_val = _bfd_get_gp_value (abfd);
4093
 
4094
      for (; dyncon < dynconend; dyncon++)
4095
        {
4096
          Elf_Internal_Dyn dyn;
4097
 
4098
          bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4099
 
4100
          switch (dyn.d_tag)
4101
            {
4102
            case DT_PLTGOT:
4103
              dyn.d_un.d_ptr = gp_val;
4104
              break;
4105
 
4106
            case DT_PLTRELSZ:
4107
              dyn.d_un.d_val = (ia64_info->minplt_entries
4108
                                * sizeof (ElfNN_External_Rela));
4109
              break;
4110
 
4111
            case DT_JMPREL:
4112
              /* See the comment above in finish_dynamic_symbol.  */
4113
              dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4114
                                + ia64_info->rel_pltoff_sec->output_offset
4115
                                + (ia64_info->rel_pltoff_sec->reloc_count
4116
                                   * sizeof (ElfNN_External_Rela)));
4117
              break;
4118
 
4119
            case DT_IA_64_PLT_RESERVE:
4120
              dyn.d_un.d_ptr = (sgotplt->output_section->vma
4121
                                + sgotplt->output_offset);
4122
              break;
4123
 
4124
            case DT_RELASZ:
4125
              /* Do not have RELASZ include JMPREL.  This makes things
4126
                 easier on ld.so.  This is not what the rest of BFD set up.  */
4127
              dyn.d_un.d_val -= (ia64_info->minplt_entries
4128
                                 * sizeof (ElfNN_External_Rela));
4129
              break;
4130
            }
4131
 
4132
          bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4133
        }
4134
 
4135
      /* Initialize the PLT0 entry */
4136
      if (ia64_info->plt_sec)
4137
        {
4138
          bfd_byte *loc = ia64_info->plt_sec->contents;
4139
          bfd_vma pltres;
4140
 
4141
          memcpy (loc, plt_header, PLT_HEADER_SIZE);
4142
 
4143
          pltres = (sgotplt->output_section->vma
4144
                    + sgotplt->output_offset
4145
                    - gp_val);
4146
 
4147
          elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4148
        }
4149
    }
4150
 
4151
  return true;
4152
}
4153
 
4154
/* ELF file flag handling: */
4155
 
4156
/* Function to keep IA-64 specific file flags.  */
4157
static boolean
4158
elfNN_ia64_set_private_flags (abfd, flags)
4159
     bfd *abfd;
4160
     flagword flags;
4161
{
4162
  BFD_ASSERT (!elf_flags_init (abfd)
4163
              || elf_elfheader (abfd)->e_flags == flags);
4164
 
4165
  elf_elfheader (abfd)->e_flags = flags;
4166
  elf_flags_init (abfd) = true;
4167
  return true;
4168
}
4169
 
4170
/* Copy backend specific data from one object module to another */
4171
static boolean
4172
elfNN_ia64_copy_private_bfd_data (ibfd, obfd)
4173
     bfd *ibfd, *obfd;
4174
{
4175
  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4176
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4177
    return true;
4178
 
4179
  BFD_ASSERT (!elf_flags_init (obfd)
4180
              || (elf_elfheader (obfd)->e_flags
4181
                  == elf_elfheader (ibfd)->e_flags));
4182
 
4183
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
4184
  elf_flags_init (obfd) = true;
4185
  return true;
4186
}
4187
 
4188
/* Merge backend specific data from an object file to the output
4189
   object file when linking.  */
4190
static boolean
4191
elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4192
     bfd *ibfd, *obfd;
4193
{
4194
  flagword out_flags;
4195
  flagword in_flags;
4196
  boolean ok = true;
4197
 
4198
  /* Don't even pretend to support mixed-format linking.  */
4199
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4200
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4201
    return false;
4202
 
4203
  in_flags  = elf_elfheader (ibfd)->e_flags;
4204
  out_flags = elf_elfheader (obfd)->e_flags;
4205
 
4206
  if (! elf_flags_init (obfd))
4207
    {
4208
      elf_flags_init (obfd) = true;
4209
      elf_elfheader (obfd)->e_flags = in_flags;
4210
 
4211
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4212
          && bfd_get_arch_info (obfd)->the_default)
4213
        {
4214
          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4215
                                    bfd_get_mach (ibfd));
4216
        }
4217
 
4218
      return true;
4219
    }
4220
 
4221
  /* Check flag compatibility.  */
4222
  if (in_flags == out_flags)
4223
    return true;
4224
 
4225
  /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
4226
  if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4227
    elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4228
 
4229
  if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4230
    {
4231
      (*_bfd_error_handler)
4232
        (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4233
         bfd_get_filename (ibfd));
4234
 
4235
      bfd_set_error (bfd_error_bad_value);
4236
      ok = false;
4237
    }
4238
  if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4239
    {
4240
      (*_bfd_error_handler)
4241
        (_("%s: linking big-endian files with little-endian files"),
4242
         bfd_get_filename (ibfd));
4243
 
4244
      bfd_set_error (bfd_error_bad_value);
4245
      ok = false;
4246
    }
4247
  if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4248
    {
4249
      (*_bfd_error_handler)
4250
        (_("%s: linking 64-bit files with 32-bit files"),
4251
         bfd_get_filename (ibfd));
4252
 
4253
      bfd_set_error (bfd_error_bad_value);
4254
      ok = false;
4255
    }
4256
  if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4257
    {
4258
      (*_bfd_error_handler)
4259
        (_("%s: linking constant-gp files with non-constant-gp files"),
4260
         bfd_get_filename (ibfd));
4261
 
4262
      bfd_set_error (bfd_error_bad_value);
4263
      ok = false;
4264
    }
4265
  if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4266
      != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4267
    {
4268
      (*_bfd_error_handler)
4269
        (_("%s: linking auto-pic files with non-auto-pic files"),
4270
         bfd_get_filename (ibfd));
4271
 
4272
      bfd_set_error (bfd_error_bad_value);
4273
      ok = false;
4274
    }
4275
 
4276
  return ok;
4277
}
4278
 
4279
static boolean
4280
elfNN_ia64_print_private_bfd_data (abfd, ptr)
4281
     bfd *abfd;
4282
     PTR ptr;
4283
{
4284
  FILE *file = (FILE *) ptr;
4285
  flagword flags = elf_elfheader (abfd)->e_flags;
4286
 
4287
  BFD_ASSERT (abfd != NULL && ptr != NULL);
4288
 
4289
  fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4290
           (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4291
           (flags & EF_IA_64_EXT) ? "EXT, " : "",
4292
           (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4293
           (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4294
           (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4295
           (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4296
           (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4297
           (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4298
 
4299
  _bfd_elf_print_private_bfd_data (abfd, ptr);
4300
  return true;
4301
}
4302
 
4303
#define TARGET_LITTLE_SYM               bfd_elfNN_ia64_little_vec
4304
#define TARGET_LITTLE_NAME              "elfNN-ia64-little"
4305
#define TARGET_BIG_SYM                  bfd_elfNN_ia64_big_vec
4306
#define TARGET_BIG_NAME                 "elfNN-ia64-big"
4307
#define ELF_ARCH                        bfd_arch_ia64
4308
#define ELF_MACHINE_CODE                EM_IA_64
4309
#define ELF_MACHINE_ALT1                1999    /* EAS2.3 */
4310
#define ELF_MACHINE_ALT2                1998    /* EAS2.2 */
4311
#define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
4312
 
4313
#define elf_backend_section_from_shdr \
4314
        elfNN_ia64_section_from_shdr
4315
#define elf_backend_section_flags \
4316
        elfNN_ia64_section_flags
4317
#define elf_backend_fake_sections \
4318
        elfNN_ia64_fake_sections
4319
#define elf_backend_final_write_processing \
4320
        elfNN_ia64_final_write_processing
4321
#define elf_backend_add_symbol_hook \
4322
        elfNN_ia64_add_symbol_hook
4323
#define elf_backend_additional_program_headers \
4324
        elfNN_ia64_additional_program_headers
4325
#define elf_backend_modify_segment_map \
4326
        elfNN_ia64_modify_segment_map
4327
#define elf_info_to_howto \
4328
        elfNN_ia64_info_to_howto
4329
 
4330
#define bfd_elfNN_bfd_reloc_type_lookup \
4331
        elfNN_ia64_reloc_type_lookup
4332
#define bfd_elfNN_bfd_is_local_label_name \
4333
        elfNN_ia64_is_local_label_name
4334
#define bfd_elfNN_bfd_relax_section \
4335
        elfNN_ia64_relax_section
4336
 
4337
/* Stuff for the BFD linker: */
4338
#define bfd_elfNN_bfd_link_hash_table_create \
4339
        elfNN_ia64_hash_table_create
4340
#define elf_backend_create_dynamic_sections \
4341
        elfNN_ia64_create_dynamic_sections
4342
#define elf_backend_check_relocs \
4343
        elfNN_ia64_check_relocs
4344
#define elf_backend_adjust_dynamic_symbol \
4345
        elfNN_ia64_adjust_dynamic_symbol
4346
#define elf_backend_size_dynamic_sections \
4347
        elfNN_ia64_size_dynamic_sections
4348
#define elf_backend_relocate_section \
4349
        elfNN_ia64_relocate_section
4350
#define elf_backend_finish_dynamic_symbol \
4351
        elfNN_ia64_finish_dynamic_symbol
4352
#define elf_backend_finish_dynamic_sections \
4353
        elfNN_ia64_finish_dynamic_sections
4354
#define bfd_elfNN_bfd_final_link \
4355
        elfNN_ia64_final_link
4356
 
4357
#define bfd_elfNN_bfd_copy_private_bfd_data \
4358
        elfNN_ia64_copy_private_bfd_data
4359
#define bfd_elfNN_bfd_merge_private_bfd_data \
4360
        elfNN_ia64_merge_private_bfd_data
4361
#define bfd_elfNN_bfd_set_private_flags \
4362
        elfNN_ia64_set_private_flags
4363
#define bfd_elfNN_bfd_print_private_bfd_data \
4364
        elfNN_ia64_print_private_bfd_data
4365
 
4366
#define elf_backend_plt_readonly        1
4367
#define elf_backend_want_plt_sym        0
4368
#define elf_backend_plt_alignment       5
4369
#define elf_backend_got_header_size     0
4370
#define elf_backend_plt_header_size     PLT_HEADER_SIZE
4371
#define elf_backend_want_got_plt        1
4372
#define elf_backend_may_use_rel_p       1
4373
#define elf_backend_may_use_rela_p      1
4374
#define elf_backend_default_use_rela_p  1
4375
#define elf_backend_want_dynbss         0
4376
#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4377
#define elf_backend_hide_symbol         elfNN_ia64_hash_hide_symbol
4378
 
4379
#include "elfNN-target.h"
4380
 
4381
/* AIX-specific vectors.  */
4382
 
4383
#undef  TARGET_LITTLE_SYM
4384
#define TARGET_LITTLE_SYM               bfd_elfNN_ia64_aix_little_vec
4385
#undef  TARGET_LITTLE_NAME
4386
#define TARGET_LITTLE_NAME              "elfNN-ia64-aix-little"
4387
#undef  TARGET_BIG_SYM
4388
#define TARGET_BIG_SYM                  bfd_elfNN_ia64_aix_big_vec
4389
#undef  TARGET_BIG_NAME
4390
#define TARGET_BIG_NAME                 "elfNN-ia64-aix-big"
4391
 
4392
#undef  elf_backend_add_symbol_hook
4393
#define elf_backend_add_symbol_hook     elfNN_ia64_aix_add_symbol_hook
4394
 
4395
#undef  bfd_elfNN_bfd_link_add_symbols
4396
#define bfd_elfNN_bfd_link_add_symbols  elfNN_ia64_aix_link_add_symbols
4397
 
4398
#define elfNN_bed elfNN_ia64_aix_bed
4399
 
4400
#include "elfNN-target.h"

powered by: WebSVN 2.1.0

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