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