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