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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [bfd/] [elfxx-ia64.c] - Blame information for rev 1782

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

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

powered by: WebSVN 2.1.0

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