coff-arm.c revision 1.1.1.11 1 1.1 skrll /* BFD back-end for ARM COFF files.
2 1.1.1.11 christos Copyright (C) 1990-2025 Free Software Foundation, Inc.
3 1.1 skrll Written by Cygnus Support.
4 1.1 skrll
5 1.1 skrll This file is part of BFD, the Binary File Descriptor library.
6 1.1 skrll
7 1.1 skrll This program is free software; you can redistribute it and/or modify
8 1.1 skrll it under the terms of the GNU General Public License as published by
9 1.1 skrll the Free Software Foundation; either version 3 of the License, or
10 1.1 skrll (at your option) any later version.
11 1.1 skrll
12 1.1 skrll This program is distributed in the hope that it will be useful,
13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 skrll GNU General Public License for more details.
16 1.1 skrll
17 1.1 skrll You should have received a copy of the GNU General Public License
18 1.1 skrll along with this program; if not, write to the Free Software
19 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 skrll MA 02110-1301, USA. */
21 1.1 skrll
22 1.1 skrll #include "sysdep.h"
23 1.1 skrll #include "bfd.h"
24 1.1 skrll #include "libbfd.h"
25 1.1 skrll #include "coff/arm.h"
26 1.1 skrll #include "coff/internal.h"
27 1.1.1.8 christos #include "cpu-arm.h"
28 1.1.1.8 christos #include "coff-arm.h"
29 1.1 skrll
30 1.1 skrll #ifdef COFF_WITH_PE
31 1.1 skrll #include "coff/pe.h"
32 1.1 skrll #endif
33 1.1 skrll
34 1.1 skrll #include "libcoff.h"
35 1.1 skrll
36 1.1.1.8 christos /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
37 1.1.1.8 christos #define OCTETS_PER_BYTE(ABFD, SEC) 1
38 1.1.1.8 christos
39 1.1 skrll /* Macros for manipulation the bits in the flags field of the coff data
40 1.1 skrll structure. */
41 1.1 skrll #define APCS_26_FLAG(abfd) \
42 1.1 skrll (coff_data (abfd)->flags & F_APCS_26)
43 1.1 skrll
44 1.1 skrll #define APCS_FLOAT_FLAG(abfd) \
45 1.1 skrll (coff_data (abfd)->flags & F_APCS_FLOAT)
46 1.1 skrll
47 1.1 skrll #define PIC_FLAG(abfd) \
48 1.1 skrll (coff_data (abfd)->flags & F_PIC)
49 1.1 skrll
50 1.1 skrll #define APCS_SET(abfd) \
51 1.1 skrll (coff_data (abfd)->flags & F_APCS_SET)
52 1.1 skrll
53 1.1 skrll #define SET_APCS_FLAGS(abfd, flgs) \
54 1.1 skrll do \
55 1.1 skrll { \
56 1.1 skrll coff_data (abfd)->flags &= ~(F_APCS_26 | F_APCS_FLOAT | F_PIC); \
57 1.1 skrll coff_data (abfd)->flags |= (flgs) | F_APCS_SET; \
58 1.1 skrll } \
59 1.1 skrll while (0)
60 1.1 skrll
61 1.1 skrll #define INTERWORK_FLAG(abfd) \
62 1.1 skrll (coff_data (abfd)->flags & F_INTERWORK)
63 1.1 skrll
64 1.1 skrll #define INTERWORK_SET(abfd) \
65 1.1 skrll (coff_data (abfd)->flags & F_INTERWORK_SET)
66 1.1 skrll
67 1.1 skrll #define SET_INTERWORK_FLAG(abfd, flg) \
68 1.1 skrll do \
69 1.1 skrll { \
70 1.1 skrll coff_data (abfd)->flags &= ~F_INTERWORK; \
71 1.1 skrll coff_data (abfd)->flags |= (flg) | F_INTERWORK_SET; \
72 1.1 skrll } \
73 1.1 skrll while (0)
74 1.1 skrll
75 1.1 skrll #ifndef NUM_ELEM
76 1.1 skrll #define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0]))
77 1.1 skrll #endif
78 1.1 skrll
79 1.1 skrll typedef enum {bunknown, b9, b12, b23} thumb_pcrel_branchtype;
80 1.1 skrll /* Some typedefs for holding instructions. */
81 1.1 skrll typedef unsigned long int insn32;
82 1.1 skrll typedef unsigned short int insn16;
83 1.1 skrll
84 1.1 skrll /* The linker script knows the section names for placement.
85 1.1 skrll The entry_names are used to do simple name mangling on the stubs.
86 1.1 skrll Given a function name, and its type, the stub can be found. The
87 1.1 skrll name can be changed. The only requirement is the %s be present. */
88 1.1 skrll
89 1.1 skrll #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
90 1.1 skrll #define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb"
91 1.1 skrll
92 1.1 skrll #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
93 1.1 skrll #define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm"
94 1.1 skrll
95 1.1 skrll /* Used by the assembler. */
96 1.1 skrll
97 1.1 skrll static bfd_reloc_status_type
98 1.1 skrll coff_arm_reloc (bfd *abfd,
99 1.1 skrll arelent *reloc_entry,
100 1.1 skrll asymbol *symbol ATTRIBUTE_UNUSED,
101 1.1 skrll void * data,
102 1.1.1.8 christos asection *input_section,
103 1.1 skrll bfd *output_bfd,
104 1.1 skrll char **error_message ATTRIBUTE_UNUSED)
105 1.1 skrll {
106 1.1 skrll symvalue diff;
107 1.1 skrll
108 1.1 skrll if (output_bfd == NULL)
109 1.1 skrll return bfd_reloc_continue;
110 1.1 skrll
111 1.1 skrll diff = reloc_entry->addend;
112 1.1 skrll
113 1.1 skrll #define DOIT(x) \
114 1.1 skrll x = ((x & ~howto->dst_mask) \
115 1.1 skrll | (((x & howto->src_mask) + diff) & howto->dst_mask))
116 1.1 skrll
117 1.1.1.6 christos if (diff != 0)
118 1.1.1.6 christos {
119 1.1.1.6 christos reloc_howto_type *howto = reloc_entry->howto;
120 1.1.1.8 christos bfd_size_type octets = (reloc_entry->address
121 1.1.1.8 christos * OCTETS_PER_BYTE (abfd, input_section));
122 1.1.1.8 christos unsigned char *addr = (unsigned char *) data + octets;
123 1.1 skrll
124 1.1.1.8 christos if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
125 1.1.1.6 christos return bfd_reloc_outofrange;
126 1.1 skrll
127 1.1.1.9 christos switch (bfd_get_reloc_size (howto))
128 1.1.1.6 christos {
129 1.1.1.9 christos case 1:
130 1.1.1.6 christos {
131 1.1.1.6 christos char x = bfd_get_8 (abfd, addr);
132 1.1.1.6 christos DOIT (x);
133 1.1.1.6 christos bfd_put_8 (abfd, x, addr);
134 1.1.1.6 christos }
135 1.1.1.6 christos break;
136 1.1 skrll
137 1.1.1.9 christos case 2:
138 1.1.1.6 christos {
139 1.1.1.6 christos short x = bfd_get_16 (abfd, addr);
140 1.1.1.6 christos DOIT (x);
141 1.1.1.6 christos bfd_put_16 (abfd, (bfd_vma) x, addr);
142 1.1.1.6 christos }
143 1.1.1.6 christos break;
144 1.1 skrll
145 1.1.1.9 christos case 4:
146 1.1.1.6 christos {
147 1.1.1.6 christos long x = bfd_get_32 (abfd, addr);
148 1.1.1.6 christos DOIT (x);
149 1.1.1.6 christos bfd_put_32 (abfd, (bfd_vma) x, addr);
150 1.1 skrll }
151 1.1.1.6 christos break;
152 1.1.1.6 christos
153 1.1.1.6 christos default:
154 1.1.1.6 christos abort ();
155 1.1.1.6 christos }
156 1.1.1.6 christos }
157 1.1 skrll
158 1.1 skrll /* Now let bfd_perform_relocation finish everything up. */
159 1.1 skrll return bfd_reloc_continue;
160 1.1 skrll }
161 1.1 skrll
162 1.1 skrll /* If USER_LABEL_PREFIX is defined as "_" (see coff_arm_is_local_label_name()
163 1.1 skrll in this file), then TARGET_UNDERSCORE should be defined, otherwise it
164 1.1 skrll should not. */
165 1.1 skrll #ifndef TARGET_UNDERSCORE
166 1.1 skrll #define TARGET_UNDERSCORE '_'
167 1.1 skrll #endif
168 1.1 skrll
169 1.1 skrll #ifndef PCRELOFFSET
170 1.1.1.9 christos #define PCRELOFFSET true
171 1.1 skrll #endif
172 1.1 skrll
173 1.1 skrll /* These most certainly belong somewhere else. Just had to get rid of
174 1.1 skrll the manifest constants in the code. */
175 1.1 skrll
176 1.1 skrll #ifdef ARM_WINCE
177 1.1 skrll
178 1.1 skrll #define ARM_26D 0
179 1.1 skrll #define ARM_32 1
180 1.1 skrll #define ARM_RVA32 2
181 1.1 skrll #define ARM_26 3
182 1.1 skrll #define ARM_THUMB12 4
183 1.1 skrll #define ARM_SECTION 14
184 1.1 skrll #define ARM_SECREL 15
185 1.1 skrll
186 1.1 skrll #else
187 1.1 skrll
188 1.1.1.6 christos #define ARM_8 0
189 1.1.1.6 christos #define ARM_16 1
190 1.1.1.6 christos #define ARM_32 2
191 1.1.1.6 christos #define ARM_26 3
192 1.1 skrll #define ARM_DISP8 4
193 1.1 skrll #define ARM_DISP16 5
194 1.1 skrll #define ARM_DISP32 6
195 1.1.1.6 christos #define ARM_26D 7
196 1.1 skrll /* 8 is unused. */
197 1.1 skrll #define ARM_NEG16 9
198 1.1 skrll #define ARM_NEG32 10
199 1.1 skrll #define ARM_RVA32 11
200 1.1 skrll #define ARM_THUMB9 12
201 1.1 skrll #define ARM_THUMB12 13
202 1.1 skrll #define ARM_THUMB23 14
203 1.1 skrll
204 1.1 skrll #endif
205 1.1 skrll
206 1.1 skrll static bfd_reloc_status_type aoutarm_fix_pcrel_26_done
207 1.1 skrll (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
208 1.1 skrll static bfd_reloc_status_type aoutarm_fix_pcrel_26
209 1.1 skrll (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
210 1.1 skrll static bfd_reloc_status_type coff_thumb_pcrel_12
211 1.1 skrll (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
212 1.1 skrll #ifndef ARM_WINCE
213 1.1 skrll static bfd_reloc_status_type coff_thumb_pcrel_9
214 1.1 skrll (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
215 1.1 skrll static bfd_reloc_status_type coff_thumb_pcrel_23
216 1.1 skrll (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
217 1.1 skrll #endif
218 1.1 skrll
219 1.1 skrll static reloc_howto_type aoutarm_std_reloc_howto[] =
220 1.1 skrll {
221 1.1 skrll #ifdef ARM_WINCE
222 1.1 skrll HOWTO (ARM_26D,
223 1.1 skrll 2,
224 1.1.1.9 christos 4,
225 1.1 skrll 24,
226 1.1.1.9 christos true,
227 1.1 skrll 0,
228 1.1 skrll complain_overflow_dont,
229 1.1 skrll aoutarm_fix_pcrel_26_done,
230 1.1 skrll "ARM_26D",
231 1.1.1.9 christos true, /* partial_inplace. */
232 1.1 skrll 0x00ffffff,
233 1.1 skrll 0x0,
234 1.1 skrll PCRELOFFSET),
235 1.1 skrll HOWTO (ARM_32,
236 1.1 skrll 0,
237 1.1.1.9 christos 4,
238 1.1 skrll 32,
239 1.1.1.9 christos false,
240 1.1 skrll 0,
241 1.1 skrll complain_overflow_bitfield,
242 1.1 skrll coff_arm_reloc,
243 1.1 skrll "ARM_32",
244 1.1.1.9 christos true, /* partial_inplace. */
245 1.1 skrll 0xffffffff,
246 1.1 skrll 0xffffffff,
247 1.1 skrll PCRELOFFSET),
248 1.1 skrll HOWTO (ARM_RVA32,
249 1.1 skrll 0,
250 1.1.1.9 christos 4,
251 1.1 skrll 32,
252 1.1.1.9 christos false,
253 1.1 skrll 0,
254 1.1 skrll complain_overflow_bitfield,
255 1.1 skrll coff_arm_reloc,
256 1.1 skrll "ARM_RVA32",
257 1.1.1.9 christos true, /* partial_inplace. */
258 1.1 skrll 0xffffffff,
259 1.1 skrll 0xffffffff,
260 1.1 skrll PCRELOFFSET),
261 1.1 skrll HOWTO (ARM_26,
262 1.1 skrll 2,
263 1.1.1.9 christos 4,
264 1.1 skrll 24,
265 1.1.1.9 christos true,
266 1.1 skrll 0,
267 1.1 skrll complain_overflow_signed,
268 1.1 skrll aoutarm_fix_pcrel_26 ,
269 1.1 skrll "ARM_26",
270 1.1.1.9 christos false,
271 1.1 skrll 0x00ffffff,
272 1.1 skrll 0x00ffffff,
273 1.1 skrll PCRELOFFSET),
274 1.1 skrll HOWTO (ARM_THUMB12,
275 1.1 skrll 1,
276 1.1.1.9 christos 2,
277 1.1 skrll 11,
278 1.1.1.9 christos true,
279 1.1 skrll 0,
280 1.1 skrll complain_overflow_signed,
281 1.1 skrll coff_thumb_pcrel_12 ,
282 1.1 skrll "ARM_THUMB12",
283 1.1.1.9 christos false,
284 1.1 skrll 0x000007ff,
285 1.1 skrll 0x000007ff,
286 1.1 skrll PCRELOFFSET),
287 1.1 skrll EMPTY_HOWTO (-1),
288 1.1 skrll EMPTY_HOWTO (-1),
289 1.1 skrll EMPTY_HOWTO (-1),
290 1.1 skrll EMPTY_HOWTO (-1),
291 1.1 skrll EMPTY_HOWTO (-1),
292 1.1 skrll EMPTY_HOWTO (-1),
293 1.1 skrll EMPTY_HOWTO (-1),
294 1.1 skrll EMPTY_HOWTO (-1),
295 1.1 skrll EMPTY_HOWTO (-1),
296 1.1 skrll HOWTO (ARM_SECTION,
297 1.1 skrll 0,
298 1.1.1.9 christos 2,
299 1.1 skrll 16,
300 1.1.1.9 christos false,
301 1.1 skrll 0,
302 1.1 skrll complain_overflow_bitfield,
303 1.1 skrll coff_arm_reloc,
304 1.1 skrll "ARM_SECTION",
305 1.1.1.9 christos true, /* partial_inplace. */
306 1.1 skrll 0x0000ffff,
307 1.1 skrll 0x0000ffff,
308 1.1 skrll PCRELOFFSET),
309 1.1 skrll HOWTO (ARM_SECREL,
310 1.1 skrll 0,
311 1.1.1.9 christos 4,
312 1.1 skrll 32,
313 1.1.1.9 christos false,
314 1.1 skrll 0,
315 1.1 skrll complain_overflow_bitfield,
316 1.1 skrll coff_arm_reloc,
317 1.1 skrll "ARM_SECREL",
318 1.1.1.9 christos true, /* partial_inplace. */
319 1.1 skrll 0xffffffff,
320 1.1 skrll 0xffffffff,
321 1.1 skrll PCRELOFFSET),
322 1.1 skrll #else /* not ARM_WINCE */
323 1.1 skrll HOWTO (ARM_8,
324 1.1 skrll 0,
325 1.1.1.9 christos 1,
326 1.1 skrll 8,
327 1.1.1.9 christos false,
328 1.1 skrll 0,
329 1.1 skrll complain_overflow_bitfield,
330 1.1 skrll coff_arm_reloc,
331 1.1 skrll "ARM_8",
332 1.1.1.9 christos true,
333 1.1 skrll 0x000000ff,
334 1.1 skrll 0x000000ff,
335 1.1 skrll PCRELOFFSET),
336 1.1 skrll HOWTO (ARM_16,
337 1.1 skrll 0,
338 1.1.1.9 christos 2,
339 1.1 skrll 16,
340 1.1.1.9 christos false,
341 1.1 skrll 0,
342 1.1 skrll complain_overflow_bitfield,
343 1.1 skrll coff_arm_reloc,
344 1.1 skrll "ARM_16",
345 1.1.1.9 christos true,
346 1.1 skrll 0x0000ffff,
347 1.1 skrll 0x0000ffff,
348 1.1 skrll PCRELOFFSET),
349 1.1 skrll HOWTO (ARM_32,
350 1.1 skrll 0,
351 1.1.1.9 christos 4,
352 1.1 skrll 32,
353 1.1.1.9 christos false,
354 1.1 skrll 0,
355 1.1 skrll complain_overflow_bitfield,
356 1.1 skrll coff_arm_reloc,
357 1.1 skrll "ARM_32",
358 1.1.1.9 christos true,
359 1.1 skrll 0xffffffff,
360 1.1 skrll 0xffffffff,
361 1.1 skrll PCRELOFFSET),
362 1.1 skrll HOWTO (ARM_26,
363 1.1 skrll 2,
364 1.1.1.9 christos 4,
365 1.1 skrll 24,
366 1.1.1.9 christos true,
367 1.1 skrll 0,
368 1.1 skrll complain_overflow_signed,
369 1.1 skrll aoutarm_fix_pcrel_26 ,
370 1.1 skrll "ARM_26",
371 1.1.1.9 christos false,
372 1.1 skrll 0x00ffffff,
373 1.1 skrll 0x00ffffff,
374 1.1 skrll PCRELOFFSET),
375 1.1 skrll HOWTO (ARM_DISP8,
376 1.1 skrll 0,
377 1.1.1.9 christos 1,
378 1.1 skrll 8,
379 1.1.1.9 christos true,
380 1.1 skrll 0,
381 1.1 skrll complain_overflow_signed,
382 1.1 skrll coff_arm_reloc,
383 1.1 skrll "ARM_DISP8",
384 1.1.1.9 christos true,
385 1.1 skrll 0x000000ff,
386 1.1 skrll 0x000000ff,
387 1.1.1.9 christos true),
388 1.1 skrll HOWTO (ARM_DISP16,
389 1.1 skrll 0,
390 1.1.1.9 christos 2,
391 1.1 skrll 16,
392 1.1.1.9 christos true,
393 1.1 skrll 0,
394 1.1 skrll complain_overflow_signed,
395 1.1 skrll coff_arm_reloc,
396 1.1 skrll "ARM_DISP16",
397 1.1.1.9 christos true,
398 1.1 skrll 0x0000ffff,
399 1.1 skrll 0x0000ffff,
400 1.1.1.9 christos true),
401 1.1 skrll HOWTO (ARM_DISP32,
402 1.1 skrll 0,
403 1.1.1.9 christos 4,
404 1.1 skrll 32,
405 1.1.1.9 christos true,
406 1.1 skrll 0,
407 1.1 skrll complain_overflow_signed,
408 1.1 skrll coff_arm_reloc,
409 1.1 skrll "ARM_DISP32",
410 1.1.1.9 christos true,
411 1.1 skrll 0xffffffff,
412 1.1 skrll 0xffffffff,
413 1.1.1.9 christos true),
414 1.1 skrll HOWTO (ARM_26D,
415 1.1 skrll 2,
416 1.1.1.9 christos 4,
417 1.1 skrll 24,
418 1.1.1.9 christos false,
419 1.1 skrll 0,
420 1.1 skrll complain_overflow_dont,
421 1.1 skrll aoutarm_fix_pcrel_26_done,
422 1.1 skrll "ARM_26D",
423 1.1.1.9 christos true,
424 1.1 skrll 0x00ffffff,
425 1.1 skrll 0x0,
426 1.1.1.9 christos false),
427 1.1 skrll /* 8 is unused */
428 1.1 skrll EMPTY_HOWTO (-1),
429 1.1 skrll HOWTO (ARM_NEG16,
430 1.1 skrll 0,
431 1.1.1.9 christos -2,
432 1.1 skrll 16,
433 1.1.1.9 christos false,
434 1.1 skrll 0,
435 1.1 skrll complain_overflow_bitfield,
436 1.1 skrll coff_arm_reloc,
437 1.1 skrll "ARM_NEG16",
438 1.1.1.9 christos true,
439 1.1 skrll 0x0000ffff,
440 1.1 skrll 0x0000ffff,
441 1.1.1.9 christos false),
442 1.1 skrll HOWTO (ARM_NEG32,
443 1.1 skrll 0,
444 1.1.1.9 christos -4,
445 1.1 skrll 32,
446 1.1.1.9 christos false,
447 1.1 skrll 0,
448 1.1 skrll complain_overflow_bitfield,
449 1.1 skrll coff_arm_reloc,
450 1.1 skrll "ARM_NEG32",
451 1.1.1.9 christos true,
452 1.1 skrll 0xffffffff,
453 1.1 skrll 0xffffffff,
454 1.1.1.9 christos false),
455 1.1 skrll HOWTO (ARM_RVA32,
456 1.1 skrll 0,
457 1.1.1.9 christos 4,
458 1.1 skrll 32,
459 1.1.1.9 christos false,
460 1.1 skrll 0,
461 1.1 skrll complain_overflow_bitfield,
462 1.1 skrll coff_arm_reloc,
463 1.1 skrll "ARM_RVA32",
464 1.1.1.9 christos true,
465 1.1 skrll 0xffffffff,
466 1.1 skrll 0xffffffff,
467 1.1 skrll PCRELOFFSET),
468 1.1 skrll HOWTO (ARM_THUMB9,
469 1.1 skrll 1,
470 1.1.1.9 christos 2,
471 1.1 skrll 8,
472 1.1.1.9 christos true,
473 1.1 skrll 0,
474 1.1 skrll complain_overflow_signed,
475 1.1 skrll coff_thumb_pcrel_9 ,
476 1.1 skrll "ARM_THUMB9",
477 1.1.1.9 christos false,
478 1.1 skrll 0x000000ff,
479 1.1 skrll 0x000000ff,
480 1.1 skrll PCRELOFFSET),
481 1.1 skrll HOWTO (ARM_THUMB12,
482 1.1 skrll 1,
483 1.1.1.9 christos 2,
484 1.1 skrll 11,
485 1.1.1.9 christos true,
486 1.1 skrll 0,
487 1.1 skrll complain_overflow_signed,
488 1.1 skrll coff_thumb_pcrel_12 ,
489 1.1 skrll "ARM_THUMB12",
490 1.1.1.9 christos false,
491 1.1 skrll 0x000007ff,
492 1.1 skrll 0x000007ff,
493 1.1 skrll PCRELOFFSET),
494 1.1 skrll HOWTO (ARM_THUMB23,
495 1.1 skrll 1,
496 1.1.1.9 christos 4,
497 1.1 skrll 22,
498 1.1.1.9 christos true,
499 1.1 skrll 0,
500 1.1 skrll complain_overflow_signed,
501 1.1 skrll coff_thumb_pcrel_23 ,
502 1.1 skrll "ARM_THUMB23",
503 1.1.1.9 christos false,
504 1.1 skrll 0x07ff07ff,
505 1.1 skrll 0x07ff07ff,
506 1.1 skrll PCRELOFFSET)
507 1.1 skrll #endif /* not ARM_WINCE */
508 1.1 skrll };
509 1.1 skrll
510 1.1 skrll #define NUM_RELOCS NUM_ELEM (aoutarm_std_reloc_howto)
511 1.1 skrll
512 1.1 skrll #ifdef COFF_WITH_PE
513 1.1 skrll /* Return TRUE if this relocation should
514 1.1 skrll appear in the output .reloc section. */
515 1.1 skrll
516 1.1.1.9 christos static bool
517 1.1 skrll in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
518 1.1 skrll reloc_howto_type * howto)
519 1.1 skrll {
520 1.1 skrll return !howto->pc_relative && howto->type != ARM_RVA32;
521 1.1 skrll }
522 1.1 skrll #endif
523 1.1 skrll
524 1.1 skrll #define RTYPE2HOWTO(cache_ptr, dst) \
525 1.1 skrll (cache_ptr)->howto = \
526 1.1 skrll (dst)->r_type < NUM_RELOCS \
527 1.1 skrll ? aoutarm_std_reloc_howto + (dst)->r_type \
528 1.1 skrll : NULL
529 1.1 skrll
530 1.1 skrll #define coff_rtype_to_howto coff_arm_rtype_to_howto
531 1.1 skrll
532 1.1 skrll static reloc_howto_type *
533 1.1 skrll coff_arm_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
534 1.1 skrll asection *sec,
535 1.1 skrll struct internal_reloc *rel,
536 1.1 skrll struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
537 1.1 skrll struct internal_syment *sym ATTRIBUTE_UNUSED,
538 1.1 skrll bfd_vma *addendp)
539 1.1 skrll {
540 1.1 skrll reloc_howto_type * howto;
541 1.1 skrll
542 1.1 skrll if (rel->r_type >= NUM_RELOCS)
543 1.1 skrll return NULL;
544 1.1 skrll
545 1.1 skrll howto = aoutarm_std_reloc_howto + rel->r_type;
546 1.1 skrll
547 1.1 skrll if (rel->r_type == ARM_RVA32)
548 1.1 skrll *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
549 1.1 skrll
550 1.1 skrll #if defined COFF_WITH_PE && defined ARM_WINCE
551 1.1 skrll if (rel->r_type == ARM_SECREL)
552 1.1 skrll {
553 1.1 skrll bfd_vma osect_vma;
554 1.1 skrll
555 1.1 skrll if (h && (h->type == bfd_link_hash_defined
556 1.1 skrll || h->type == bfd_link_hash_defweak))
557 1.1 skrll osect_vma = h->root.u.def.section->output_section->vma;
558 1.1 skrll else
559 1.1 skrll {
560 1.1 skrll int i;
561 1.1 skrll
562 1.1 skrll /* Sigh, the only way to get the section to offset against
563 1.1 skrll is to find it the hard way. */
564 1.1 skrll
565 1.1 skrll for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
566 1.1 skrll sec = sec->next;
567 1.1 skrll
568 1.1 skrll osect_vma = sec->output_section->vma;
569 1.1 skrll }
570 1.1 skrll
571 1.1 skrll *addendp -= osect_vma;
572 1.1 skrll }
573 1.1 skrll #endif
574 1.1 skrll
575 1.1 skrll return howto;
576 1.1 skrll }
577 1.1 skrll
578 1.1 skrll /* Used by the assembler. */
579 1.1 skrll
580 1.1 skrll static bfd_reloc_status_type
581 1.1 skrll aoutarm_fix_pcrel_26_done (bfd *abfd ATTRIBUTE_UNUSED,
582 1.1 skrll arelent *reloc_entry ATTRIBUTE_UNUSED,
583 1.1 skrll asymbol *symbol ATTRIBUTE_UNUSED,
584 1.1 skrll void * data ATTRIBUTE_UNUSED,
585 1.1 skrll asection *input_section ATTRIBUTE_UNUSED,
586 1.1 skrll bfd *output_bfd ATTRIBUTE_UNUSED,
587 1.1 skrll char **error_message ATTRIBUTE_UNUSED)
588 1.1 skrll {
589 1.1 skrll /* This is dead simple at present. */
590 1.1 skrll return bfd_reloc_ok;
591 1.1 skrll }
592 1.1 skrll
593 1.1 skrll /* Used by the assembler. */
594 1.1 skrll
595 1.1 skrll static bfd_reloc_status_type
596 1.1 skrll aoutarm_fix_pcrel_26 (bfd *abfd,
597 1.1 skrll arelent *reloc_entry,
598 1.1 skrll asymbol *symbol,
599 1.1 skrll void * data,
600 1.1 skrll asection *input_section,
601 1.1 skrll bfd *output_bfd,
602 1.1 skrll char **error_message ATTRIBUTE_UNUSED)
603 1.1 skrll {
604 1.1 skrll bfd_vma relocation;
605 1.1 skrll bfd_size_type addr = reloc_entry->address;
606 1.1 skrll long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
607 1.1 skrll bfd_reloc_status_type flag = bfd_reloc_ok;
608 1.1 skrll
609 1.1 skrll /* If this is an undefined symbol, return error. */
610 1.1.1.3 christos if (bfd_is_und_section (symbol->section)
611 1.1 skrll && (symbol->flags & BSF_WEAK) == 0)
612 1.1 skrll return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
613 1.1 skrll
614 1.1 skrll /* If the sections are different, and we are doing a partial relocation,
615 1.1 skrll just ignore it for now. */
616 1.1 skrll if (symbol->section->name != input_section->name
617 1.1 skrll && output_bfd != (bfd *)NULL)
618 1.1 skrll return bfd_reloc_continue;
619 1.1 skrll
620 1.1 skrll relocation = (target & 0x00ffffff) << 2;
621 1.1 skrll relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend. */
622 1.1 skrll relocation += symbol->value;
623 1.1 skrll relocation += symbol->section->output_section->vma;
624 1.1 skrll relocation += symbol->section->output_offset;
625 1.1 skrll relocation += reloc_entry->addend;
626 1.1 skrll relocation -= input_section->output_section->vma;
627 1.1 skrll relocation -= input_section->output_offset;
628 1.1 skrll relocation -= addr;
629 1.1 skrll
630 1.1 skrll if (relocation & 3)
631 1.1 skrll return bfd_reloc_overflow;
632 1.1 skrll
633 1.1 skrll /* Check for overflow. */
634 1.1 skrll if (relocation & 0x02000000)
635 1.1 skrll {
636 1.1 skrll if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
637 1.1 skrll flag = bfd_reloc_overflow;
638 1.1 skrll }
639 1.1 skrll else if (relocation & ~(bfd_vma) 0x03ffffff)
640 1.1 skrll flag = bfd_reloc_overflow;
641 1.1 skrll
642 1.1 skrll target &= ~0x00ffffff;
643 1.1 skrll target |= (relocation >> 2) & 0x00ffffff;
644 1.1 skrll bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
645 1.1 skrll
646 1.1 skrll /* Now the ARM magic... Change the reloc type so that it is marked as done.
647 1.1 skrll Strictly this is only necessary if we are doing a partial relocation. */
648 1.1 skrll reloc_entry->howto = &aoutarm_std_reloc_howto[ARM_26D];
649 1.1 skrll
650 1.1 skrll return flag;
651 1.1 skrll }
652 1.1 skrll
653 1.1 skrll static bfd_reloc_status_type
654 1.1 skrll coff_thumb_pcrel_common (bfd *abfd,
655 1.1 skrll arelent *reloc_entry,
656 1.1 skrll asymbol *symbol,
657 1.1 skrll void * data,
658 1.1 skrll asection *input_section,
659 1.1 skrll bfd *output_bfd,
660 1.1 skrll char **error_message ATTRIBUTE_UNUSED,
661 1.1 skrll thumb_pcrel_branchtype btype)
662 1.1 skrll {
663 1.1 skrll bfd_vma relocation = 0;
664 1.1 skrll bfd_size_type addr = reloc_entry->address;
665 1.1 skrll long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
666 1.1 skrll bfd_reloc_status_type flag = bfd_reloc_ok;
667 1.1 skrll bfd_vma dstmsk;
668 1.1 skrll bfd_vma offmsk;
669 1.1 skrll bfd_vma signbit;
670 1.1 skrll
671 1.1 skrll /* NOTE: This routine is currently used by GAS, but not by the link
672 1.1 skrll phase. */
673 1.1 skrll switch (btype)
674 1.1 skrll {
675 1.1 skrll case b9:
676 1.1 skrll dstmsk = 0x000000ff;
677 1.1 skrll offmsk = 0x000001fe;
678 1.1 skrll signbit = 0x00000100;
679 1.1 skrll break;
680 1.1 skrll
681 1.1 skrll case b12:
682 1.1 skrll dstmsk = 0x000007ff;
683 1.1 skrll offmsk = 0x00000ffe;
684 1.1 skrll signbit = 0x00000800;
685 1.1 skrll break;
686 1.1 skrll
687 1.1 skrll case b23:
688 1.1 skrll dstmsk = 0x07ff07ff;
689 1.1 skrll offmsk = 0x007fffff;
690 1.1 skrll signbit = 0x00400000;
691 1.1 skrll break;
692 1.1 skrll
693 1.1 skrll default:
694 1.1 skrll abort ();
695 1.1 skrll }
696 1.1 skrll
697 1.1 skrll /* If this is an undefined symbol, return error. */
698 1.1.1.3 christos if (bfd_is_und_section (symbol->section)
699 1.1 skrll && (symbol->flags & BSF_WEAK) == 0)
700 1.1 skrll return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
701 1.1 skrll
702 1.1 skrll /* If the sections are different, and we are doing a partial relocation,
703 1.1 skrll just ignore it for now. */
704 1.1 skrll if (symbol->section->name != input_section->name
705 1.1 skrll && output_bfd != (bfd *)NULL)
706 1.1 skrll return bfd_reloc_continue;
707 1.1 skrll
708 1.1 skrll switch (btype)
709 1.1 skrll {
710 1.1 skrll case b9:
711 1.1 skrll case b12:
712 1.1 skrll relocation = ((target & dstmsk) << 1);
713 1.1 skrll break;
714 1.1 skrll
715 1.1 skrll case b23:
716 1.1 skrll if (bfd_big_endian (abfd))
717 1.1 skrll relocation = ((target & 0x7ff) << 1) | ((target & 0x07ff0000) >> 4);
718 1.1 skrll else
719 1.1 skrll relocation = ((target & 0x7ff) << 12) | ((target & 0x07ff0000) >> 15);
720 1.1 skrll break;
721 1.1 skrll
722 1.1 skrll default:
723 1.1 skrll abort ();
724 1.1 skrll }
725 1.1 skrll
726 1.1 skrll relocation = (relocation ^ signbit) - signbit; /* Sign extend. */
727 1.1 skrll relocation += symbol->value;
728 1.1 skrll relocation += symbol->section->output_section->vma;
729 1.1 skrll relocation += symbol->section->output_offset;
730 1.1 skrll relocation += reloc_entry->addend;
731 1.1 skrll relocation -= input_section->output_section->vma;
732 1.1 skrll relocation -= input_section->output_offset;
733 1.1 skrll relocation -= addr;
734 1.1 skrll
735 1.1 skrll if (relocation & 1)
736 1.1 skrll return bfd_reloc_overflow;
737 1.1 skrll
738 1.1 skrll /* Check for overflow. */
739 1.1 skrll if (relocation & signbit)
740 1.1 skrll {
741 1.1 skrll if ((relocation & ~offmsk) != ~offmsk)
742 1.1 skrll flag = bfd_reloc_overflow;
743 1.1 skrll }
744 1.1 skrll else if (relocation & ~offmsk)
745 1.1 skrll flag = bfd_reloc_overflow;
746 1.1 skrll
747 1.1 skrll target &= ~dstmsk;
748 1.1 skrll switch (btype)
749 1.1 skrll {
750 1.1 skrll case b9:
751 1.1 skrll case b12:
752 1.1 skrll target |= (relocation >> 1);
753 1.1 skrll break;
754 1.1 skrll
755 1.1 skrll case b23:
756 1.1 skrll if (bfd_big_endian (abfd))
757 1.1 skrll target |= (((relocation & 0xfff) >> 1)
758 1.1 skrll | ((relocation << 4) & 0x07ff0000));
759 1.1 skrll else
760 1.1 skrll target |= (((relocation & 0xffe) << 15)
761 1.1 skrll | ((relocation >> 12) & 0x7ff));
762 1.1 skrll break;
763 1.1 skrll
764 1.1 skrll default:
765 1.1 skrll abort ();
766 1.1 skrll }
767 1.1 skrll
768 1.1 skrll bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr);
769 1.1 skrll
770 1.1 skrll /* Now the ARM magic... Change the reloc type so that it is marked as done.
771 1.1 skrll Strictly this is only necessary if we are doing a partial relocation. */
772 1.1 skrll reloc_entry->howto = & aoutarm_std_reloc_howto [ARM_26D];
773 1.1 skrll
774 1.1 skrll /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations. */
775 1.1 skrll return flag;
776 1.1 skrll }
777 1.1 skrll
778 1.1 skrll #ifndef ARM_WINCE
779 1.1 skrll static bfd_reloc_status_type
780 1.1 skrll coff_thumb_pcrel_23 (bfd *abfd,
781 1.1 skrll arelent *reloc_entry,
782 1.1 skrll asymbol *symbol,
783 1.1 skrll void * data,
784 1.1 skrll asection *input_section,
785 1.1 skrll bfd *output_bfd,
786 1.1 skrll char **error_message)
787 1.1 skrll {
788 1.1 skrll return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
789 1.1.1.6 christos input_section, output_bfd, error_message,
790 1.1 skrll b23);
791 1.1 skrll }
792 1.1 skrll
793 1.1 skrll static bfd_reloc_status_type
794 1.1 skrll coff_thumb_pcrel_9 (bfd *abfd,
795 1.1 skrll arelent *reloc_entry,
796 1.1 skrll asymbol *symbol,
797 1.1 skrll void * data,
798 1.1 skrll asection *input_section,
799 1.1 skrll bfd *output_bfd,
800 1.1 skrll char **error_message)
801 1.1 skrll {
802 1.1 skrll return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
803 1.1.1.6 christos input_section, output_bfd, error_message,
804 1.1 skrll b9);
805 1.1 skrll }
806 1.1 skrll #endif /* not ARM_WINCE */
807 1.1 skrll
808 1.1 skrll static bfd_reloc_status_type
809 1.1 skrll coff_thumb_pcrel_12 (bfd *abfd,
810 1.1 skrll arelent *reloc_entry,
811 1.1 skrll asymbol *symbol,
812 1.1 skrll void * data,
813 1.1 skrll asection *input_section,
814 1.1 skrll bfd *output_bfd,
815 1.1 skrll char **error_message)
816 1.1 skrll {
817 1.1 skrll return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
818 1.1.1.6 christos input_section, output_bfd, error_message,
819 1.1 skrll b12);
820 1.1 skrll }
821 1.1 skrll
822 1.1.1.8 christos static reloc_howto_type *
823 1.1 skrll coff_arm_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
824 1.1 skrll {
825 1.1 skrll #define ASTD(i,j) case i: return aoutarm_std_reloc_howto + j
826 1.1 skrll
827 1.1 skrll if (code == BFD_RELOC_CTOR)
828 1.1.1.2 christos switch (bfd_arch_bits_per_address (abfd))
829 1.1 skrll {
830 1.1 skrll case 32:
831 1.1.1.6 christos code = BFD_RELOC_32;
832 1.1.1.6 christos break;
833 1.1 skrll default:
834 1.1 skrll return NULL;
835 1.1 skrll }
836 1.1 skrll
837 1.1 skrll switch (code)
838 1.1 skrll {
839 1.1 skrll #ifdef ARM_WINCE
840 1.1.1.6 christos ASTD (BFD_RELOC_32, ARM_32);
841 1.1.1.6 christos ASTD (BFD_RELOC_RVA, ARM_RVA32);
842 1.1.1.6 christos ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26);
843 1.1 skrll ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
844 1.1.1.6 christos ASTD (BFD_RELOC_32_SECREL, ARM_SECREL);
845 1.1 skrll #else
846 1.1.1.6 christos ASTD (BFD_RELOC_8, ARM_8);
847 1.1.1.6 christos ASTD (BFD_RELOC_16, ARM_16);
848 1.1.1.6 christos ASTD (BFD_RELOC_32, ARM_32);
849 1.1.1.6 christos ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26);
850 1.1.1.6 christos ASTD (BFD_RELOC_ARM_PCREL_BLX, ARM_26);
851 1.1.1.6 christos ASTD (BFD_RELOC_8_PCREL, ARM_DISP8);
852 1.1.1.6 christos ASTD (BFD_RELOC_16_PCREL, ARM_DISP16);
853 1.1.1.6 christos ASTD (BFD_RELOC_32_PCREL, ARM_DISP32);
854 1.1.1.6 christos ASTD (BFD_RELOC_RVA, ARM_RVA32);
855 1.1 skrll ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9, ARM_THUMB9);
856 1.1 skrll ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
857 1.1 skrll ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23);
858 1.1.1.6 christos ASTD (BFD_RELOC_THUMB_PCREL_BLX, ARM_THUMB23);
859 1.1 skrll #endif
860 1.1 skrll default: return NULL;
861 1.1 skrll }
862 1.1 skrll }
863 1.1 skrll
864 1.1 skrll static reloc_howto_type *
865 1.1 skrll coff_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
866 1.1 skrll const char *r_name)
867 1.1 skrll {
868 1.1 skrll unsigned int i;
869 1.1 skrll
870 1.1 skrll for (i = 0;
871 1.1 skrll i < (sizeof (aoutarm_std_reloc_howto)
872 1.1 skrll / sizeof (aoutarm_std_reloc_howto[0]));
873 1.1 skrll i++)
874 1.1 skrll if (aoutarm_std_reloc_howto[i].name != NULL
875 1.1 skrll && strcasecmp (aoutarm_std_reloc_howto[i].name, r_name) == 0)
876 1.1 skrll return &aoutarm_std_reloc_howto[i];
877 1.1 skrll
878 1.1 skrll return NULL;
879 1.1 skrll }
880 1.1 skrll
881 1.1 skrll #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
882 1.1.1.6 christos #define COFF_PAGE_SIZE 0x1000
883 1.1 skrll
884 1.1 skrll /* Turn a howto into a reloc nunmber. */
885 1.1 skrll #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
886 1.1.1.6 christos #define BADMAG(x) ARMBADMAG(x)
887 1.1.1.6 christos #define ARM 1 /* Customize coffcode.h. */
888 1.1 skrll
889 1.1 skrll #ifndef ARM_WINCE
890 1.1 skrll /* Make sure that the 'r_offset' field is copied properly
891 1.1 skrll so that identical binaries will compare the same. */
892 1.1 skrll #define SWAP_IN_RELOC_OFFSET H_GET_32
893 1.1 skrll #define SWAP_OUT_RELOC_OFFSET H_PUT_32
894 1.1 skrll #endif
895 1.1 skrll
896 1.1 skrll /* Extend the coff_link_hash_table structure with a few ARM specific fields.
897 1.1 skrll This allows us to store global data here without actually creating any
898 1.1 skrll global variables, which is a no-no in the BFD world. */
899 1.1 skrll struct coff_arm_link_hash_table
900 1.1 skrll {
901 1.1 skrll /* The original coff_link_hash_table structure. MUST be first field. */
902 1.1 skrll struct coff_link_hash_table root;
903 1.1 skrll
904 1.1 skrll /* The size in bytes of the section containing the Thumb-to-ARM glue. */
905 1.1 skrll bfd_size_type thumb_glue_size;
906 1.1 skrll
907 1.1 skrll /* The size in bytes of the section containing the ARM-to-Thumb glue. */
908 1.1 skrll bfd_size_type arm_glue_size;
909 1.1 skrll
910 1.1 skrll /* An arbitrary input BFD chosen to hold the glue sections. */
911 1.1 skrll bfd * bfd_of_glue_owner;
912 1.1 skrll
913 1.1 skrll /* Support interworking with old, non-interworking aware ARM code. */
914 1.1.1.6 christos int support_old_code;
915 1.1 skrll };
916 1.1 skrll
917 1.1 skrll /* Get the ARM coff linker hash table from a link_info structure. */
918 1.1 skrll #define coff_arm_hash_table(info) \
919 1.1 skrll ((struct coff_arm_link_hash_table *) ((info)->hash))
920 1.1 skrll
921 1.1 skrll /* Create an ARM coff linker hash table. */
922 1.1 skrll
923 1.1 skrll static struct bfd_link_hash_table *
924 1.1 skrll coff_arm_link_hash_table_create (bfd * abfd)
925 1.1 skrll {
926 1.1 skrll struct coff_arm_link_hash_table * ret;
927 1.1.1.9 christos size_t amt = sizeof (struct coff_arm_link_hash_table);
928 1.1 skrll
929 1.1.1.4 christos ret = bfd_zmalloc (amt);
930 1.1 skrll if (ret == NULL)
931 1.1 skrll return NULL;
932 1.1 skrll
933 1.1 skrll if (!_bfd_coff_link_hash_table_init (&ret->root,
934 1.1 skrll abfd,
935 1.1 skrll _bfd_coff_link_hash_newfunc,
936 1.1 skrll sizeof (struct coff_link_hash_entry)))
937 1.1 skrll {
938 1.1 skrll free (ret);
939 1.1 skrll return NULL;
940 1.1 skrll }
941 1.1 skrll
942 1.1 skrll return & ret->root.root;
943 1.1 skrll }
944 1.1 skrll
945 1.1.1.9 christos static bool
946 1.1 skrll arm_emit_base_file_entry (struct bfd_link_info *info,
947 1.1 skrll bfd *output_bfd,
948 1.1 skrll asection *input_section,
949 1.1 skrll bfd_vma reloc_offset)
950 1.1 skrll {
951 1.1 skrll bfd_vma addr = (reloc_offset
952 1.1 skrll - input_section->vma
953 1.1 skrll + input_section->output_offset
954 1.1 skrll + input_section->output_section->vma);
955 1.1 skrll
956 1.1.1.10 christos if (obj_pe (output_bfd))
957 1.1 skrll addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
958 1.1 skrll if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
959 1.1.1.9 christos return true;
960 1.1 skrll
961 1.1 skrll bfd_set_error (bfd_error_system_call);
962 1.1.1.9 christos return false;
963 1.1 skrll }
964 1.1 skrll
965 1.1 skrll #ifndef ARM_WINCE
967 1.1 skrll /* The thumb form of a long branch is a bit finicky, because the offset
968 1.1 skrll encoding is split over two fields, each in it's own instruction. They
969 1.1 skrll can occur in any order. So given a thumb form of long branch, and an
970 1.1 skrll offset, insert the offset into the thumb branch and return finished
971 1.1 skrll instruction.
972 1.1 skrll
973 1.1 skrll It takes two thumb instructions to encode the target address. Each has
974 1.1 skrll 11 bits to invest. The upper 11 bits are stored in one (identified by
975 1.1 skrll H-0.. see below), the lower 11 bits are stored in the other (identified
976 1.1 skrll by H-1).
977 1.1 skrll
978 1.1 skrll Combine together and shifted left by 1 (it's a half word address) and
979 1.1 skrll there you have it.
980 1.1 skrll
981 1.1 skrll Op: 1111 = F,
982 1.1 skrll H-0, upper address-0 = 000
983 1.1 skrll Op: 1111 = F,
984 1.1 skrll H-1, lower address-0 = 800
985 1.1 skrll
986 1.1 skrll They can be ordered either way, but the arm tools I've seen always put
987 1.1 skrll the lower one first. It probably doesn't matter. krk (at) cygnus.com
988 1.1 skrll
989 1.1 skrll XXX: Actually the order does matter. The second instruction (H-1)
990 1.1 skrll moves the computed address into the PC, so it must be the second one
991 1.1 skrll in the sequence. The problem, however is that whilst little endian code
992 1.1 skrll stores the instructions in HI then LOW order, big endian code does the
993 1.1 skrll reverse. nickc (at) cygnus.com. */
994 1.1 skrll
995 1.1 skrll #define LOW_HI_ORDER 0xF800F000
996 1.1 skrll #define HI_LOW_ORDER 0xF000F800
997 1.1 skrll
998 1.1 skrll static insn32
999 1.1 skrll insert_thumb_branch (insn32 br_insn, int rel_off)
1000 1.1 skrll {
1001 1.1 skrll unsigned int low_bits;
1002 1.1 skrll unsigned int high_bits;
1003 1.1 skrll
1004 1.1 skrll BFD_ASSERT ((rel_off & 1) != 1);
1005 1.1.1.6 christos
1006 1.1.1.6 christos rel_off >>= 1; /* Half word aligned address. */
1007 1.1 skrll low_bits = rel_off & 0x000007FF; /* The bottom 11 bits. */
1008 1.1 skrll high_bits = (rel_off >> 11) & 0x000007FF; /* The top 11 bits. */
1009 1.1 skrll
1010 1.1 skrll if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
1011 1.1 skrll br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
1012 1.1 skrll else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
1013 1.1 skrll br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
1014 1.1 skrll else
1015 1.1 skrll /* FIXME: the BFD library should never abort except for internal errors
1016 1.1 skrll - it should return an error status. */
1017 1.1 skrll abort (); /* Error - not a valid branch instruction form. */
1018 1.1 skrll
1019 1.1 skrll return br_insn;
1020 1.1 skrll }
1021 1.1 skrll
1022 1.1 skrll
1023 1.1 skrll static struct coff_link_hash_entry *
1025 1.1 skrll find_thumb_glue (struct bfd_link_info *info,
1026 1.1 skrll const char *name,
1027 1.1 skrll bfd *input_bfd)
1028 1.1 skrll {
1029 1.1.1.9 christos char *tmp_name;
1030 1.1 skrll struct coff_link_hash_entry *myh;
1031 1.1 skrll size_t amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1032 1.1 skrll
1033 1.1 skrll tmp_name = bfd_malloc (amt);
1034 1.1 skrll
1035 1.1 skrll BFD_ASSERT (tmp_name);
1036 1.1 skrll
1037 1.1 skrll sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1038 1.1.1.9 christos
1039 1.1 skrll myh = coff_link_hash_lookup
1040 1.1 skrll (coff_hash_table (info), tmp_name, false, false, true);
1041 1.1 skrll
1042 1.1.1.7 christos if (myh == NULL)
1043 1.1 skrll /* xgettext:c-format */
1044 1.1 skrll _bfd_error_handler (_("%pB: unable to find THUMB glue '%s' for `%s'"),
1045 1.1 skrll input_bfd, tmp_name, name);
1046 1.1 skrll
1047 1.1 skrll free (tmp_name);
1048 1.1 skrll
1049 1.1 skrll return myh;
1050 1.1 skrll }
1051 1.1 skrll #endif /* not ARM_WINCE */
1052 1.1 skrll
1053 1.1 skrll static struct coff_link_hash_entry *
1054 1.1 skrll find_arm_glue (struct bfd_link_info *info,
1055 1.1 skrll const char *name,
1056 1.1 skrll bfd *input_bfd)
1057 1.1 skrll {
1058 1.1.1.9 christos char *tmp_name;
1059 1.1 skrll struct coff_link_hash_entry * myh;
1060 1.1 skrll size_t amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1061 1.1 skrll
1062 1.1 skrll tmp_name = bfd_malloc (amt);
1063 1.1 skrll
1064 1.1 skrll BFD_ASSERT (tmp_name);
1065 1.1 skrll
1066 1.1 skrll sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1067 1.1.1.9 christos
1068 1.1 skrll myh = coff_link_hash_lookup
1069 1.1 skrll (coff_hash_table (info), tmp_name, false, false, true);
1070 1.1 skrll
1071 1.1.1.7 christos if (myh == NULL)
1072 1.1 skrll /* xgettext:c-format */
1073 1.1 skrll _bfd_error_handler (_("%pB: unable to find ARM glue '%s' for `%s'"),
1074 1.1 skrll input_bfd, tmp_name, name);
1075 1.1 skrll
1076 1.1 skrll free (tmp_name);
1077 1.1 skrll
1078 1.1 skrll return myh;
1079 1.1 skrll }
1080 1.1 skrll
1081 1.1 skrll /*
1082 1.1 skrll ARM->Thumb glue:
1083 1.1 skrll
1084 1.1 skrll .arm
1085 1.1 skrll __func_from_arm:
1086 1.1 skrll ldr r12, __func_addr
1087 1.1.1.6 christos bx r12
1088 1.1 skrll __func_addr:
1089 1.1 skrll .word func @ behave as if you saw a ARM_32 reloc
1090 1.1 skrll */
1091 1.1 skrll
1092 1.1 skrll #define ARM2THUMB_GLUE_SIZE 12
1093 1.1 skrll static const insn32 a2t1_ldr_insn = 0xe59fc000;
1094 1.1 skrll static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
1095 1.1 skrll static const insn32 a2t3_func_addr_insn = 0x00000001;
1096 1.1 skrll
1097 1.1 skrll /*
1098 1.1 skrll Thumb->ARM: Thumb->(non-interworking aware) ARM
1099 1.1 skrll
1100 1.1 skrll .thumb .thumb
1101 1.1 skrll .align 2 .align 2
1102 1.1 skrll __func_from_thumb: __func_from_thumb:
1103 1.1 skrll bx pc push {r6, lr}
1104 1.1 skrll nop ldr r6, __func_addr
1105 1.1.1.6 christos .arm mov lr, pc
1106 1.1 skrll __func_change_to_arm: bx r6
1107 1.1.1.6 christos b func .arm
1108 1.1.1.6 christos __func_back_to_thumb:
1109 1.1.1.6 christos ldmia r13! {r6, lr}
1110 1.1.1.6 christos bx lr
1111 1.1 skrll __func_addr:
1112 1.1 skrll .word func
1113 1.1 skrll */
1114 1.1 skrll
1115 1.1 skrll #define THUMB2ARM_GLUE_SIZE (globals->support_old_code ? 20 : 8)
1116 1.1 skrll #ifndef ARM_WINCE
1117 1.1 skrll static const insn16 t2a1_bx_pc_insn = 0x4778;
1118 1.1 skrll static const insn16 t2a2_noop_insn = 0x46c0;
1119 1.1 skrll static const insn32 t2a3_b_insn = 0xea000000;
1120 1.1 skrll
1121 1.1 skrll static const insn16 t2a1_push_insn = 0xb540;
1122 1.1 skrll static const insn16 t2a2_ldr_insn = 0x4e03;
1123 1.1 skrll static const insn16 t2a3_mov_insn = 0x46fe;
1124 1.1 skrll static const insn16 t2a4_bx_insn = 0x4730;
1125 1.1 skrll static const insn32 t2a5_pop_insn = 0xe8bd4040;
1126 1.1 skrll static const insn32 t2a6_bx_insn = 0xe12fff1e;
1127 1.1 skrll #endif
1128 1.1 skrll
1129 1.1 skrll /* TODO:
1130 1.1 skrll We should really create new local (static) symbols in destination
1131 1.1 skrll object for each stub we create. We should also create local
1132 1.1 skrll (static) symbols within the stubs when switching between ARM and
1133 1.1 skrll Thumb code. This will ensure that the debugger and disassembler
1134 1.1 skrll can present a better view of stubs.
1135 1.1 skrll
1136 1.1 skrll We can treat stubs like literal sections, and for the THUMB9 ones
1137 1.1 skrll (short addressing range) we should be able to insert the stubs
1138 1.1 skrll between sections. i.e. the simplest approach (since relocations
1139 1.1 skrll are done on a section basis) is to dump the stubs at the end of
1140 1.1 skrll processing a section. That way we can always try and minimise the
1141 1.1 skrll offset to and from a stub. However, this does not map well onto
1142 1.1 skrll the way that the linker/BFD does its work: mapping all input
1143 1.1 skrll sections to output sections via the linker script before doing
1144 1.1 skrll all the processing.
1145 1.1 skrll
1146 1.1 skrll Unfortunately it may be easier to just to disallow short range
1147 1.1 skrll Thumb->ARM stubs (i.e. no conditional inter-working branches,
1148 1.1 skrll only branch-and-link (BL) calls. This will simplify the processing
1149 1.1 skrll since we can then put all of the stubs into their own section.
1150 1.1 skrll
1151 1.1 skrll TODO:
1152 1.1 skrll On a different subject, rather than complaining when a
1153 1.1 skrll branch cannot fit in the number of bits available for the
1154 1.1 skrll instruction we should generate a trampoline stub (needed to
1155 1.1 skrll address the complete 32bit address space). */
1156 1.1 skrll
1157 1.1.1.8 christos /* The standard COFF backend linker does not cope with the special
1158 1.1 skrll Thumb BRANCH23 relocation. The alternative would be to split the
1159 1.1 skrll BRANCH23 into separate HI23 and LO23 relocations. However, it is a
1160 1.1 skrll bit simpler simply providing our own relocation driver. */
1161 1.1 skrll
1162 1.1 skrll /* The reloc processing routine for the ARM/Thumb COFF linker. NOTE:
1163 1.1 skrll This code is a very slightly modified copy of
1164 1.1 skrll _bfd_coff_generic_relocate_section. It would be a much more
1165 1.1 skrll maintainable solution to have a MACRO that could be expanded within
1166 1.1 skrll _bfd_coff_generic_relocate_section that would only be provided for
1167 1.1 skrll ARM/Thumb builds. It is only the code marked THUMBEXTENSION that
1168 1.1.1.9 christos is different from the original. */
1169 1.1 skrll
1170 1.1 skrll static bool
1171 1.1 skrll coff_arm_relocate_section (bfd *output_bfd,
1172 1.1 skrll struct bfd_link_info *info,
1173 1.1 skrll bfd *input_bfd,
1174 1.1 skrll asection *input_section,
1175 1.1 skrll bfd_byte *contents,
1176 1.1 skrll struct internal_reloc *relocs,
1177 1.1 skrll struct internal_syment *syms,
1178 1.1 skrll asection **sections)
1179 1.1 skrll {
1180 1.1 skrll struct internal_reloc * rel;
1181 1.1 skrll struct internal_reloc * relend;
1182 1.1 skrll #ifndef ARM_WINCE
1183 1.1 skrll bfd_vma high_address = bfd_get_section_limit (input_bfd, input_section);
1184 1.1 skrll #endif
1185 1.1 skrll
1186 1.1 skrll rel = relocs;
1187 1.1 skrll relend = rel + input_section->reloc_count;
1188 1.1 skrll
1189 1.1.1.6 christos for (; rel < relend; rel++)
1190 1.1.1.6 christos {
1191 1.1 skrll int done = 0;
1192 1.1.1.6 christos long symndx;
1193 1.1.1.6 christos struct coff_link_hash_entry * h;
1194 1.1.1.6 christos struct internal_syment * sym;
1195 1.1.1.6 christos bfd_vma addend;
1196 1.1.1.6 christos bfd_vma val;
1197 1.1.1.6 christos reloc_howto_type * howto;
1198 1.1 skrll bfd_reloc_status_type rstat;
1199 1.1 skrll bfd_vma h_val;
1200 1.1 skrll
1201 1.1 skrll symndx = rel->r_symndx;
1202 1.1 skrll
1203 1.1 skrll if (symndx == -1)
1204 1.1 skrll {
1205 1.1 skrll h = NULL;
1206 1.1 skrll sym = NULL;
1207 1.1 skrll }
1208 1.1 skrll else
1209 1.1 skrll {
1210 1.1 skrll h = obj_coff_sym_hashes (input_bfd)[symndx];
1211 1.1 skrll sym = syms + symndx;
1212 1.1 skrll }
1213 1.1.1.6 christos
1214 1.1.1.6 christos /* COFF treats common symbols in one of two ways. Either the
1215 1.1.1.6 christos size of the symbol is included in the section contents, or it
1216 1.1 skrll is not. We assume that the size is not included, and force
1217 1.1 skrll the rtype_to_howto function to adjust the addend as needed. */
1218 1.1 skrll
1219 1.1 skrll if (sym != NULL && sym->n_scnum != 0)
1220 1.1 skrll addend = - sym->n_value;
1221 1.1 skrll else
1222 1.1 skrll addend = 0;
1223 1.1 skrll
1224 1.1 skrll howto = coff_rtype_to_howto (input_bfd, input_section, rel, h,
1225 1.1.1.9 christos sym, &addend);
1226 1.1 skrll if (howto == NULL)
1227 1.1 skrll return false;
1228 1.1.1.6 christos
1229 1.1.1.6 christos /* The relocation_section function will skip pcrel_offset relocs
1230 1.1.1.6 christos when doing a relocatable link. However, we want to convert
1231 1.1.1.6 christos ARM_26 to ARM_26D relocs if possible. We return a fake howto in
1232 1.1.1.6 christos this case without pcrel_offset set, and adjust the addend to
1233 1.1 skrll compensate. 'partial_inplace' is also set, since we want 'done'
1234 1.1.1.6 christos relocations to be reflected in section's data. */
1235 1.1.1.6 christos if (rel->r_type == ARM_26
1236 1.1.1.6 christos && h != NULL
1237 1.1 skrll && bfd_link_relocatable (info)
1238 1.1.1.6 christos && (h->root.type == bfd_link_hash_defined
1239 1.1 skrll || h->root.type == bfd_link_hash_defweak)
1240 1.1.1.6 christos && (h->root.u.def.section->output_section
1241 1.1.1.6 christos == input_section->output_section))
1242 1.1 skrll {
1243 1.1.1.6 christos static reloc_howto_type fake_arm26_reloc =
1244 1.1.1.9 christos HOWTO (ARM_26,
1245 1.1.1.6 christos 2,
1246 1.1.1.9 christos 4,
1247 1.1.1.6 christos 24,
1248 1.1.1.6 christos true,
1249 1.1.1.6 christos 0,
1250 1.1.1.6 christos complain_overflow_signed,
1251 1.1.1.9 christos aoutarm_fix_pcrel_26 ,
1252 1.1.1.6 christos "ARM_26",
1253 1.1.1.6 christos true,
1254 1.1.1.9 christos 0x00ffffff,
1255 1.1 skrll 0x00ffffff,
1256 1.1.1.6 christos false);
1257 1.1 skrll
1258 1.1.1.6 christos addend -= rel->r_vaddr - input_section->vma;
1259 1.1.1.6 christos #ifdef ARM_WINCE
1260 1.1.1.6 christos /* FIXME: I don't know why, but the hack is necessary for correct
1261 1.1 skrll generation of bl's instruction offset. */
1262 1.1.1.6 christos addend -= 8;
1263 1.1.1.6 christos #endif
1264 1.1 skrll howto = & fake_arm26_reloc;
1265 1.1 skrll }
1266 1.1 skrll
1267 1.1 skrll #ifdef ARM_WINCE
1268 1.1.1.4 christos /* MS ARM-CE makes the reloc relative to the opcode's pc, not
1269 1.1 skrll the next opcode's pc, so is off by one. */
1270 1.1 skrll if (howto->pc_relative && !bfd_link_relocatable (info))
1271 1.1 skrll addend -= 8;
1272 1.1 skrll #endif
1273 1.1.1.6 christos
1274 1.1.1.6 christos /* If we are doing a relocatable link, then we can just ignore
1275 1.1.1.6 christos a PC relative reloc that is pcrel_offset. It will already
1276 1.1 skrll have the correct value. If this is not a relocatable link,
1277 1.1.1.6 christos then we should ignore the symbol value. */
1278 1.1.1.6 christos if (howto->pc_relative && howto->pcrel_offset)
1279 1.1.1.6 christos {
1280 1.1 skrll if (bfd_link_relocatable (info))
1281 1.1 skrll continue;
1282 1.1.1.7 christos /* FIXME - it is not clear which targets need this next test
1283 1.1.1.7 christos and which do not. It is known that it is needed for the
1284 1.1 skrll VxWorks targets but it is also known that it was suppressed
1285 1.1 skrll for other ARM targets. This ought to be sorted out one day. */
1286 1.1 skrll #ifdef ARM_COFF_BUGFIX
1287 1.1 skrll /* We must not ignore the symbol value. If the symbol is
1288 1.1 skrll within the same section, the relocation should have already
1289 1.1 skrll been fixed, but if it is not, we'll be handed a reloc into
1290 1.1 skrll the beginning of the symbol's section, so we must not cancel
1291 1.1.1.6 christos out the symbol's value, otherwise we'll be adding it in
1292 1.1.1.6 christos twice. */
1293 1.1 skrll if (sym != NULL && sym->n_scnum != 0)
1294 1.1.1.6 christos addend += sym->n_value;
1295 1.1 skrll #endif
1296 1.1 skrll }
1297 1.1 skrll
1298 1.1 skrll val = 0;
1299 1.1 skrll
1300 1.1 skrll if (h == NULL)
1301 1.1 skrll {
1302 1.1 skrll asection *sec;
1303 1.1 skrll
1304 1.1 skrll if (symndx == -1)
1305 1.1 skrll {
1306 1.1 skrll sec = bfd_abs_section_ptr;
1307 1.1 skrll val = 0;
1308 1.1 skrll }
1309 1.1 skrll else
1310 1.1.1.6 christos {
1311 1.1 skrll sec = sections[symndx];
1312 1.1 skrll val = (sec->output_section->vma
1313 1.1 skrll + sec->output_offset
1314 1.1 skrll + sym->n_value
1315 1.1 skrll - sec->vma);
1316 1.1 skrll }
1317 1.1 skrll }
1318 1.1.1.6 christos else
1319 1.1.1.6 christos {
1320 1.1.1.6 christos /* We don't output the stubs if we are generating a
1321 1.1 skrll relocatable output file, since we may as well leave the
1322 1.1 skrll stub generation to the final linker pass. If we fail to
1323 1.1.1.6 christos verify that the name is defined, we'll try to build stubs
1324 1.1 skrll for an undefined name... */
1325 1.1 skrll if (! bfd_link_relocatable (info)
1326 1.1.1.6 christos && ( h->root.type == bfd_link_hash_defined
1327 1.1 skrll || h->root.type == bfd_link_hash_defweak))
1328 1.1 skrll {
1329 1.1 skrll asection * h_sec = h->root.u.def.section;
1330 1.1 skrll const char * name = h->root.root.string;
1331 1.1 skrll
1332 1.1 skrll /* h locates the symbol referenced in the reloc. */
1333 1.1 skrll h_val = (h->root.u.def.value
1334 1.1 skrll + h_sec->output_section->vma
1335 1.1.1.6 christos + h_sec->output_offset);
1336 1.1.1.6 christos
1337 1.1.1.6 christos if (howto->type == ARM_26)
1338 1.1.1.2 christos {
1339 1.1 skrll if ( h->symbol_class == C_THUMBSTATFUNC
1340 1.1 skrll || h->symbol_class == C_THUMBEXTFUNC)
1341 1.1.1.6 christos {
1342 1.1.1.6 christos /* Arm code calling a Thumb function. */
1343 1.1.1.6 christos unsigned long int tmp;
1344 1.1.1.6 christos bfd_vma my_offset;
1345 1.1.1.6 christos asection * s;
1346 1.1 skrll long int ret_offset;
1347 1.1 skrll struct coff_link_hash_entry * myh;
1348 1.1 skrll struct coff_arm_link_hash_table * globals;
1349 1.1 skrll
1350 1.1.1.9 christos myh = find_arm_glue (info, name, input_bfd);
1351 1.1 skrll if (myh == NULL)
1352 1.1 skrll return false;
1353 1.1 skrll
1354 1.1 skrll globals = coff_arm_hash_table (info);
1355 1.1 skrll
1356 1.1 skrll BFD_ASSERT (globals != NULL);
1357 1.1 skrll BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1358 1.1 skrll
1359 1.1 skrll my_offset = myh->root.u.def.value;
1360 1.1 skrll
1361 1.1 skrll s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1362 1.1 skrll ARM2THUMB_GLUE_SECTION_NAME);
1363 1.1 skrll BFD_ASSERT (s != NULL);
1364 1.1 skrll BFD_ASSERT (s->contents != NULL);
1365 1.1 skrll BFD_ASSERT (s->output_section != NULL);
1366 1.1 skrll
1367 1.1 skrll if ((my_offset & 0x01) == 0x01)
1368 1.1 skrll {
1369 1.1 skrll if (h_sec->owner != NULL
1370 1.1 skrll && INTERWORK_SET (h_sec->owner)
1371 1.1 skrll && ! INTERWORK_FLAG (h_sec->owner))
1372 1.1.1.7 christos _bfd_error_handler
1373 1.1.1.7 christos /* xgettext:c-format */
1374 1.1.1.6 christos (_("%pB(%s): warning: interworking not enabled; "
1375 1.1 skrll "first occurrence: %pB: arm call to thumb"),
1376 1.1 skrll h_sec->owner, name, input_bfd);
1377 1.1 skrll
1378 1.1 skrll --my_offset;
1379 1.1 skrll myh->root.u.def.value = my_offset;
1380 1.1 skrll
1381 1.1 skrll bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn,
1382 1.1 skrll s->contents + my_offset);
1383 1.1 skrll
1384 1.1 skrll bfd_put_32 (output_bfd, (bfd_vma) a2t2_bx_r12_insn,
1385 1.1 skrll s->contents + my_offset + 4);
1386 1.1 skrll
1387 1.1 skrll /* It's a thumb address. Add the low order bit. */
1388 1.1 skrll bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
1389 1.1.1.6 christos s->contents + my_offset + 8);
1390 1.1 skrll
1391 1.1 skrll if (info->base_file
1392 1.1.1.9 christos && !arm_emit_base_file_entry (info, output_bfd,
1393 1.1 skrll s, my_offset + 8))
1394 1.1 skrll return false;
1395 1.1 skrll }
1396 1.1 skrll
1397 1.1 skrll BFD_ASSERT (my_offset <= globals->arm_glue_size);
1398 1.1 skrll
1399 1.1 skrll tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1400 1.1 skrll - input_section->vma);
1401 1.1 skrll
1402 1.1 skrll tmp = tmp & 0xFF000000;
1403 1.1 skrll
1404 1.1 skrll /* Somehow these are both 4 too far, so subtract 8. */
1405 1.1 skrll ret_offset =
1406 1.1 skrll s->output_offset
1407 1.1 skrll + my_offset
1408 1.1 skrll + s->output_section->vma
1409 1.1 skrll - (input_section->output_offset
1410 1.1 skrll + input_section->output_section->vma
1411 1.1 skrll + rel->r_vaddr)
1412 1.1 skrll - 8;
1413 1.1 skrll
1414 1.1 skrll tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
1415 1.1 skrll
1416 1.1 skrll bfd_put_32 (output_bfd, (bfd_vma) tmp,
1417 1.1 skrll contents + rel->r_vaddr - input_section->vma);
1418 1.1.1.6 christos done = 1;
1419 1.1 skrll }
1420 1.1 skrll }
1421 1.1 skrll
1422 1.1.1.6 christos #ifndef ARM_WINCE
1423 1.1.1.6 christos /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */
1424 1.1.1.6 christos else if (howto->type == ARM_THUMB23)
1425 1.1.1.2 christos {
1426 1.1.1.2 christos if ( h->symbol_class == C_EXT
1427 1.1 skrll || h->symbol_class == C_STAT
1428 1.1 skrll || h->symbol_class == C_LABEL)
1429 1.1.1.6 christos {
1430 1.1.1.6 christos /* Thumb code calling an ARM function. */
1431 1.1.1.6 christos asection * s = 0;
1432 1.1.1.6 christos bfd_vma my_offset;
1433 1.1.1.6 christos unsigned long int tmp;
1434 1.1.1.6 christos long int ret_offset;
1435 1.1 skrll struct coff_link_hash_entry * myh;
1436 1.1 skrll struct coff_arm_link_hash_table * globals;
1437 1.1 skrll
1438 1.1.1.9 christos myh = find_thumb_glue (info, name, input_bfd);
1439 1.1 skrll if (myh == NULL)
1440 1.1 skrll return false;
1441 1.1 skrll
1442 1.1 skrll globals = coff_arm_hash_table (info);
1443 1.1 skrll
1444 1.1 skrll BFD_ASSERT (globals != NULL);
1445 1.1 skrll BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1446 1.1 skrll
1447 1.1 skrll my_offset = myh->root.u.def.value;
1448 1.1 skrll
1449 1.1 skrll s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
1450 1.1 skrll THUMB2ARM_GLUE_SECTION_NAME);
1451 1.1 skrll
1452 1.1 skrll BFD_ASSERT (s != NULL);
1453 1.1 skrll BFD_ASSERT (s->contents != NULL);
1454 1.1 skrll BFD_ASSERT (s->output_section != NULL);
1455 1.1 skrll
1456 1.1 skrll if ((my_offset & 0x01) == 0x01)
1457 1.1 skrll {
1458 1.1 skrll if (h_sec->owner != NULL
1459 1.1 skrll && INTERWORK_SET (h_sec->owner)
1460 1.1 skrll && ! INTERWORK_FLAG (h_sec->owner)
1461 1.1 skrll && ! globals->support_old_code)
1462 1.1.1.7 christos _bfd_error_handler
1463 1.1.1.7 christos /* xgettext:c-format */
1464 1.1.1.7 christos (_("%pB(%s): warning: interworking not enabled; "
1465 1.1.1.7 christos "first occurrence: %pB: thumb call to arm; "
1466 1.1.1.6 christos "consider relinking with --support-old-code "
1467 1.1 skrll "enabled"),
1468 1.1 skrll h_sec->owner, name, input_bfd);
1469 1.1 skrll
1470 1.1 skrll -- my_offset;
1471 1.1 skrll myh->root.u.def.value = my_offset;
1472 1.1 skrll
1473 1.1 skrll if (globals->support_old_code)
1474 1.1 skrll {
1475 1.1 skrll bfd_put_16 (output_bfd, (bfd_vma) t2a1_push_insn,
1476 1.1 skrll s->contents + my_offset);
1477 1.1 skrll
1478 1.1 skrll bfd_put_16 (output_bfd, (bfd_vma) t2a2_ldr_insn,
1479 1.1 skrll s->contents + my_offset + 2);
1480 1.1 skrll
1481 1.1 skrll bfd_put_16 (output_bfd, (bfd_vma) t2a3_mov_insn,
1482 1.1 skrll s->contents + my_offset + 4);
1483 1.1 skrll
1484 1.1 skrll bfd_put_16 (output_bfd, (bfd_vma) t2a4_bx_insn,
1485 1.1 skrll s->contents + my_offset + 6);
1486 1.1 skrll
1487 1.1 skrll bfd_put_32 (output_bfd, (bfd_vma) t2a5_pop_insn,
1488 1.1 skrll s->contents + my_offset + 8);
1489 1.1 skrll
1490 1.1 skrll bfd_put_32 (output_bfd, (bfd_vma) t2a6_bx_insn,
1491 1.1 skrll s->contents + my_offset + 12);
1492 1.1 skrll
1493 1.1 skrll /* Store the address of the function in the last word of the stub. */
1494 1.1 skrll bfd_put_32 (output_bfd, h_val,
1495 1.1.1.6 christos s->contents + my_offset + 16);
1496 1.1 skrll
1497 1.1 skrll if (info->base_file
1498 1.1 skrll && !arm_emit_base_file_entry (info,
1499 1.1.1.9 christos output_bfd, s,
1500 1.1 skrll my_offset + 16))
1501 1.1 skrll return false;
1502 1.1 skrll }
1503 1.1 skrll else
1504 1.1 skrll {
1505 1.1 skrll bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn,
1506 1.1 skrll s->contents + my_offset);
1507 1.1 skrll
1508 1.1 skrll bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn,
1509 1.1 skrll s->contents + my_offset + 2);
1510 1.1 skrll
1511 1.1 skrll ret_offset =
1512 1.1 skrll /* Address of destination of the stub. */
1513 1.1 skrll ((bfd_signed_vma) h_val)
1514 1.1 skrll - ((bfd_signed_vma)
1515 1.1 skrll /* Offset from the start of the current section to the start of the stubs. */
1516 1.1 skrll (s->output_offset
1517 1.1 skrll /* Offset of the start of this stub from the start of the stubs. */
1518 1.1 skrll + my_offset
1519 1.1 skrll /* Address of the start of the current section. */
1520 1.1 skrll + s->output_section->vma)
1521 1.1 skrll /* The branch instruction is 4 bytes into the stub. */
1522 1.1 skrll + 4
1523 1.1 skrll /* ARM branches work from the pc of the instruction + 8. */
1524 1.1 skrll + 8);
1525 1.1 skrll
1526 1.1 skrll bfd_put_32 (output_bfd,
1527 1.1 skrll (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
1528 1.1 skrll s->contents + my_offset + 4);
1529 1.1 skrll
1530 1.1 skrll }
1531 1.1 skrll }
1532 1.1 skrll
1533 1.1 skrll BFD_ASSERT (my_offset <= globals->thumb_glue_size);
1534 1.1 skrll
1535 1.1 skrll /* Now go back and fix up the original BL insn to point
1536 1.1 skrll to here. */
1537 1.1 skrll ret_offset =
1538 1.1 skrll s->output_offset
1539 1.1 skrll + my_offset
1540 1.1 skrll - (input_section->output_offset
1541 1.1 skrll + rel->r_vaddr)
1542 1.1 skrll -4;
1543 1.1 skrll
1544 1.1 skrll tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
1545 1.1 skrll - input_section->vma);
1546 1.1 skrll
1547 1.1 skrll bfd_put_32 (output_bfd,
1548 1.1 skrll (bfd_vma) insert_thumb_branch (tmp,
1549 1.1 skrll ret_offset),
1550 1.1 skrll contents + rel->r_vaddr - input_section->vma);
1551 1.1.1.6 christos
1552 1.1.1.6 christos done = 1;
1553 1.1 skrll }
1554 1.1.1.6 christos }
1555 1.1 skrll #endif
1556 1.1.1.6 christos }
1557 1.1.1.6 christos
1558 1.1.1.6 christos /* If the relocation type and destination symbol does not
1559 1.1 skrll fall into one of the above categories, then we can just
1560 1.1 skrll perform a direct link. */
1561 1.1 skrll
1562 1.1 skrll if (done)
1563 1.1 skrll rstat = bfd_reloc_ok;
1564 1.1 skrll else
1565 1.1 skrll if ( h->root.type == bfd_link_hash_defined
1566 1.1 skrll || h->root.type == bfd_link_hash_defweak)
1567 1.1 skrll {
1568 1.1 skrll asection *sec;
1569 1.1 skrll
1570 1.1 skrll sec = h->root.u.def.section;
1571 1.1 skrll val = (h->root.u.def.value
1572 1.1 skrll + sec->output_section->vma
1573 1.1 skrll + sec->output_offset);
1574 1.1.1.4 christos }
1575 1.1.1.5 christos
1576 1.1.1.5 christos else if (! bfd_link_relocatable (info))
1577 1.1.1.9 christos (*info->callbacks->undefined_symbol)
1578 1.1 skrll (info, h->root.root.string, input_bfd, input_section,
1579 1.1 skrll rel->r_vaddr - input_section->vma, true);
1580 1.1 skrll }
1581 1.1 skrll
1582 1.1 skrll /* Emit a reloc if the backend thinks it needs it. */
1583 1.1 skrll if (info->base_file
1584 1.1 skrll && sym
1585 1.1 skrll && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)
1586 1.1.1.9 christos && !arm_emit_base_file_entry (info, output_bfd, input_section,
1587 1.1 skrll rel->r_vaddr))
1588 1.1 skrll return false;
1589 1.1 skrll
1590 1.1 skrll if (done)
1591 1.1 skrll rstat = bfd_reloc_ok;
1592 1.1.1.4 christos #ifndef ARM_WINCE
1593 1.1 skrll /* Only perform this fix during the final link, not a relocatable link. */
1594 1.1.1.6 christos else if (! bfd_link_relocatable (info)
1595 1.1.1.6 christos && howto->type == ARM_THUMB23)
1596 1.1.1.6 christos {
1597 1.1.1.6 christos /* This is pretty much a copy of what the default
1598 1.1.1.6 christos _bfd_final_link_relocate and _bfd_relocate_contents
1599 1.1.1.6 christos routines do to perform a relocation, with special
1600 1.1.1.6 christos processing for the split addressing of the Thumb BL
1601 1.1.1.6 christos instruction. Again, it would probably be simpler adding a
1602 1.1 skrll ThumbBRANCH23 specific macro expansion into the default
1603 1.1.1.6 christos code. */
1604 1.1 skrll
1605 1.1 skrll bfd_vma address = rel->r_vaddr - input_section->vma;
1606 1.1 skrll
1607 1.1.1.6 christos if (address > high_address)
1608 1.1.1.6 christos rstat = bfd_reloc_outofrange;
1609 1.1.1.6 christos else
1610 1.1 skrll {
1611 1.1.1.9 christos bfd_vma relocation = val + addend;
1612 1.1 skrll int size = bfd_get_reloc_size (howto);
1613 1.1 skrll bool overflow = false;
1614 1.1 skrll bfd_byte *location = contents + address;
1615 1.1 skrll bfd_vma x = bfd_get_32 (input_bfd, location);
1616 1.1 skrll bfd_vma src_mask = 0x007FFFFE;
1617 1.1 skrll bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
1618 1.1 skrll bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
1619 1.1 skrll bfd_vma check;
1620 1.1 skrll bfd_signed_vma signed_check;
1621 1.1 skrll bfd_vma add;
1622 1.1 skrll bfd_signed_vma signed_add;
1623 1.1 skrll
1624 1.1.1.6 christos BFD_ASSERT (size == 4);
1625 1.1.1.6 christos
1626 1.1.1.6 christos /* howto->pc_relative should be TRUE for type 14 BRANCH23. */
1627 1.1 skrll relocation -= (input_section->output_section->vma
1628 1.1.1.6 christos + input_section->output_offset);
1629 1.1.1.6 christos
1630 1.1 skrll /* howto->pcrel_offset should be TRUE for type 14 BRANCH23. */
1631 1.1 skrll relocation -= address;
1632 1.1 skrll
1633 1.1 skrll /* No need to negate the relocation with BRANCH23. */
1634 1.1 skrll /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23. */
1635 1.1 skrll /* howto->rightshift == 1 */
1636 1.1 skrll
1637 1.1 skrll /* Drop unwanted bits from the value we are relocating to. */
1638 1.1 skrll check = relocation >> howto->rightshift;
1639 1.1 skrll
1640 1.1 skrll /* If this is a signed value, the rightshift just dropped
1641 1.1 skrll leading 1 bits (assuming twos complement). */
1642 1.1 skrll if ((bfd_signed_vma) relocation >= 0)
1643 1.1 skrll signed_check = check;
1644 1.1 skrll else
1645 1.1 skrll signed_check = (check
1646 1.1 skrll | ((bfd_vma) - 1
1647 1.1 skrll & ~((bfd_vma) - 1 >> howto->rightshift)));
1648 1.1 skrll
1649 1.1 skrll /* Get the value from the object file. */
1650 1.1 skrll if (bfd_big_endian (input_bfd))
1651 1.1 skrll add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
1652 1.1 skrll else
1653 1.1 skrll add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
1654 1.1 skrll
1655 1.1 skrll /* Get the value from the object file with an appropriate sign.
1656 1.1 skrll The expression involving howto->src_mask isolates the upper
1657 1.1 skrll bit of src_mask. If that bit is set in the value we are
1658 1.1 skrll adding, it is negative, and we subtract out that number times
1659 1.1 skrll two. If src_mask includes the highest possible bit, then we
1660 1.1 skrll can not get the upper bit, but that does not matter since
1661 1.1 skrll signed_add needs no adjustment to become negative in that
1662 1.1 skrll case. */
1663 1.1 skrll signed_add = add;
1664 1.1 skrll
1665 1.1 skrll if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
1666 1.1 skrll signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
1667 1.1 skrll
1668 1.1 skrll /* howto->bitpos == 0 */
1669 1.1 skrll /* Add the value from the object file, shifted so that it is a
1670 1.1 skrll straight number. */
1671 1.1 skrll signed_check += signed_add;
1672 1.1 skrll relocation += signed_add;
1673 1.1 skrll
1674 1.1 skrll BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
1675 1.1 skrll
1676 1.1 skrll /* Assumes two's complement. */
1677 1.1.1.9 christos if ( signed_check > reloc_signed_max
1678 1.1 skrll || signed_check < reloc_signed_min)
1679 1.1 skrll overflow = true;
1680 1.1 skrll
1681 1.1 skrll /* Put the relocation into the correct bits.
1682 1.1 skrll For a BLX instruction, make sure that the relocation is rounded up
1683 1.1 skrll to a word boundary. This follows the semantics of the instruction
1684 1.1 skrll which specifies that bit 1 of the target address will come from bit
1685 1.1.1.6 christos 1 of the base address. */
1686 1.1 skrll if (bfd_big_endian (input_bfd))
1687 1.1 skrll {
1688 1.1 skrll if ((x & 0x1800) == 0x0800 && (relocation & 0x02))
1689 1.1 skrll relocation += 2;
1690 1.1 skrll relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
1691 1.1.1.6 christos }
1692 1.1 skrll else
1693 1.1 skrll {
1694 1.1 skrll if ((x & 0x18000000) == 0x08000000 && (relocation & 0x02))
1695 1.1 skrll relocation += 2;
1696 1.1 skrll relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
1697 1.1 skrll }
1698 1.1 skrll
1699 1.1 skrll /* Add the relocation to the correct bits of X. */
1700 1.1 skrll x = ((x & ~howto->dst_mask) | relocation);
1701 1.1 skrll
1702 1.1 skrll /* Put the relocated value back in the object file. */
1703 1.1 skrll bfd_put_32 (input_bfd, x, location);
1704 1.1.1.6 christos
1705 1.1.1.6 christos rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
1706 1.1 skrll }
1707 1.1 skrll }
1708 1.1.1.6 christos #endif
1709 1.1.1.6 christos else
1710 1.1.1.6 christos if (bfd_link_relocatable (info) && ! howto->partial_inplace)
1711 1.1 skrll rstat = bfd_reloc_ok;
1712 1.1 skrll else
1713 1.1 skrll rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
1714 1.1 skrll contents,
1715 1.1 skrll rel->r_vaddr - input_section->vma,
1716 1.1.1.4 christos val, addend);
1717 1.1 skrll /* Only perform this fix during the final link, not a relocatable link. */
1718 1.1 skrll if (! bfd_link_relocatable (info)
1719 1.1 skrll && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
1720 1.1 skrll {
1721 1.1.1.9 christos /* Determine if we need to set the bottom bit of a relocated address
1722 1.1 skrll because the address is the address of a Thumb code symbol. */
1723 1.1 skrll int patchit = false;
1724 1.1.1.2 christos
1725 1.1.1.2 christos if (h != NULL
1726 1.1 skrll && ( h->symbol_class == C_THUMBSTATFUNC
1727 1.1.1.9 christos || h->symbol_class == C_THUMBEXTFUNC))
1728 1.1 skrll {
1729 1.1 skrll patchit = true;
1730 1.1 skrll }
1731 1.1 skrll else if (sym != NULL
1732 1.1 skrll && sym->n_scnum > N_UNDEF)
1733 1.1 skrll {
1734 1.1 skrll /* No hash entry - use the symbol instead. */
1735 1.1.1.9 christos if ( sym->n_sclass == C_THUMBSTATFUNC
1736 1.1 skrll || sym->n_sclass == C_THUMBEXTFUNC)
1737 1.1 skrll patchit = true;
1738 1.1 skrll }
1739 1.1 skrll
1740 1.1 skrll if (patchit)
1741 1.1.1.6 christos {
1742 1.1 skrll bfd_byte * location = contents + rel->r_vaddr - input_section->vma;
1743 1.1 skrll bfd_vma x = bfd_get_32 (input_bfd, location);
1744 1.1 skrll
1745 1.1 skrll bfd_put_32 (input_bfd, x | 1, location);
1746 1.1 skrll }
1747 1.1 skrll }
1748 1.1 skrll
1749 1.1 skrll switch (rstat)
1750 1.1 skrll {
1751 1.1 skrll default:
1752 1.1 skrll abort ();
1753 1.1 skrll case bfd_reloc_ok:
1754 1.1.1.6 christos break;
1755 1.1.1.6 christos case bfd_reloc_outofrange:
1756 1.1.1.7 christos _bfd_error_handler
1757 1.1.1.7 christos /* xgettext:c-format */
1758 1.1.1.9 christos (_("%pB: bad reloc address %#" PRIx64 " in section `%pA'"),
1759 1.1 skrll input_bfd, (uint64_t) rel->r_vaddr, input_section);
1760 1.1 skrll return false;
1761 1.1 skrll case bfd_reloc_overflow:
1762 1.1 skrll {
1763 1.1 skrll const char *name;
1764 1.1 skrll char buf[SYMNMLEN + 1];
1765 1.1 skrll
1766 1.1 skrll if (symndx == -1)
1767 1.1 skrll name = "*ABS*";
1768 1.1 skrll else if (h != NULL)
1769 1.1 skrll name = NULL;
1770 1.1 skrll else
1771 1.1 skrll {
1772 1.1.1.9 christos name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
1773 1.1 skrll if (name == NULL)
1774 1.1 skrll return false;
1775 1.1.1.5 christos }
1776 1.1.1.5 christos
1777 1.1.1.5 christos (*info->callbacks->reloc_overflow)
1778 1.1.1.5 christos (info, (h ? &h->root : NULL), name, howto->name,
1779 1.1 skrll (bfd_vma) 0, input_bfd, input_section,
1780 1.1 skrll rel->r_vaddr - input_section->vma);
1781 1.1 skrll }
1782 1.1 skrll }
1783 1.1.1.9 christos }
1784 1.1 skrll
1785 1.1 skrll return true;
1786 1.1 skrll }
1787 1.1 skrll
1788 1.1.1.9 christos #ifndef COFF_IMAGE_WITH_PE
1789 1.1 skrll
1790 1.1 skrll bool
1791 1.1.1.6 christos bfd_arm_allocate_interworking_sections (struct bfd_link_info * info)
1792 1.1.1.6 christos {
1793 1.1 skrll asection * s;
1794 1.1 skrll bfd_byte * foo;
1795 1.1 skrll struct coff_arm_link_hash_table * globals;
1796 1.1 skrll
1797 1.1 skrll globals = coff_arm_hash_table (info);
1798 1.1 skrll
1799 1.1 skrll BFD_ASSERT (globals != NULL);
1800 1.1 skrll
1801 1.1 skrll if (globals->arm_glue_size != 0)
1802 1.1 skrll {
1803 1.1 skrll BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1804 1.1 skrll
1805 1.1 skrll s = bfd_get_section_by_name
1806 1.1 skrll (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1807 1.1 skrll
1808 1.1 skrll BFD_ASSERT (s != NULL);
1809 1.1 skrll
1810 1.1 skrll foo = bfd_alloc (globals->bfd_of_glue_owner, globals->arm_glue_size);
1811 1.1 skrll
1812 1.1.1.11 christos s->size = globals->arm_glue_size;
1813 1.1 skrll s->contents = foo;
1814 1.1 skrll s->alloced = 1;
1815 1.1 skrll }
1816 1.1 skrll
1817 1.1 skrll if (globals->thumb_glue_size != 0)
1818 1.1 skrll {
1819 1.1 skrll BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1820 1.1 skrll
1821 1.1 skrll s = bfd_get_section_by_name
1822 1.1 skrll (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1823 1.1 skrll
1824 1.1 skrll BFD_ASSERT (s != NULL);
1825 1.1 skrll
1826 1.1 skrll foo = bfd_alloc (globals->bfd_of_glue_owner, globals->thumb_glue_size);
1827 1.1 skrll
1828 1.1.1.11 christos s->size = globals->thumb_glue_size;
1829 1.1 skrll s->contents = foo;
1830 1.1 skrll s->alloced = 1;
1831 1.1.1.9 christos }
1832 1.1 skrll
1833 1.1 skrll return true;
1834 1.1 skrll }
1835 1.1.1.6 christos
1836 1.1 skrll static void
1837 1.1 skrll record_arm_to_thumb_glue (struct bfd_link_info * info,
1838 1.1.1.6 christos struct coff_link_hash_entry * h)
1839 1.1.1.6 christos {
1840 1.1.1.6 christos const char * name = h->root.root.string;
1841 1.1.1.6 christos register asection * s;
1842 1.1.1.6 christos char * tmp_name;
1843 1.1 skrll struct coff_link_hash_entry * myh;
1844 1.1 skrll struct bfd_link_hash_entry * bh;
1845 1.1.1.9 christos struct coff_arm_link_hash_table * globals;
1846 1.1 skrll bfd_vma val;
1847 1.1 skrll size_t amt;
1848 1.1 skrll
1849 1.1 skrll globals = coff_arm_hash_table (info);
1850 1.1 skrll
1851 1.1 skrll BFD_ASSERT (globals != NULL);
1852 1.1 skrll BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1853 1.1 skrll
1854 1.1 skrll s = bfd_get_section_by_name
1855 1.1 skrll (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
1856 1.1 skrll
1857 1.1 skrll BFD_ASSERT (s != NULL);
1858 1.1 skrll
1859 1.1 skrll amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
1860 1.1 skrll tmp_name = bfd_malloc (amt);
1861 1.1 skrll
1862 1.1 skrll BFD_ASSERT (tmp_name);
1863 1.1 skrll
1864 1.1 skrll sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
1865 1.1.1.9 christos
1866 1.1 skrll myh = coff_link_hash_lookup
1867 1.1 skrll (coff_hash_table (info), tmp_name, false, false, true);
1868 1.1 skrll
1869 1.1 skrll if (myh != NULL)
1870 1.1 skrll {
1871 1.1 skrll free (tmp_name);
1872 1.1 skrll /* We've already seen this guy. */
1873 1.1 skrll return;
1874 1.1 skrll }
1875 1.1 skrll
1876 1.1 skrll /* The only trick here is using globals->arm_glue_size as the value. Even
1877 1.1 skrll though the section isn't allocated yet, this is where we will be putting
1878 1.1 skrll it. */
1879 1.1.1.11 christos bh = NULL;
1880 1.1.1.11 christos val = globals->arm_glue_size + 1;
1881 1.1 skrll _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1882 1.1 skrll BSF_GLOBAL, s, val, NULL, true, false, &bh);
1883 1.1 skrll
1884 1.1 skrll free (tmp_name);
1885 1.1 skrll
1886 1.1 skrll globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
1887 1.1 skrll
1888 1.1 skrll return;
1889 1.1 skrll }
1890 1.1 skrll
1891 1.1.1.6 christos #ifndef ARM_WINCE
1892 1.1 skrll static void
1893 1.1 skrll record_thumb_to_arm_glue (struct bfd_link_info * info,
1894 1.1.1.6 christos struct coff_link_hash_entry * h)
1895 1.1.1.6 christos {
1896 1.1.1.6 christos const char * name = h->root.root.string;
1897 1.1.1.6 christos asection * s;
1898 1.1.1.6 christos char * tmp_name;
1899 1.1 skrll struct coff_link_hash_entry * myh;
1900 1.1 skrll struct bfd_link_hash_entry * bh;
1901 1.1.1.9 christos struct coff_arm_link_hash_table * globals;
1902 1.1 skrll bfd_vma val;
1903 1.1 skrll size_t amt;
1904 1.1 skrll
1905 1.1 skrll globals = coff_arm_hash_table (info);
1906 1.1 skrll
1907 1.1 skrll BFD_ASSERT (globals != NULL);
1908 1.1 skrll BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
1909 1.1 skrll
1910 1.1 skrll s = bfd_get_section_by_name
1911 1.1 skrll (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
1912 1.1 skrll
1913 1.1 skrll BFD_ASSERT (s != NULL);
1914 1.1 skrll
1915 1.1 skrll amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
1916 1.1 skrll tmp_name = bfd_malloc (amt);
1917 1.1 skrll
1918 1.1 skrll BFD_ASSERT (tmp_name);
1919 1.1 skrll
1920 1.1 skrll sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
1921 1.1.1.9 christos
1922 1.1 skrll myh = coff_link_hash_lookup
1923 1.1 skrll (coff_hash_table (info), tmp_name, false, false, true);
1924 1.1 skrll
1925 1.1 skrll if (myh != NULL)
1926 1.1 skrll {
1927 1.1 skrll free (tmp_name);
1928 1.1 skrll /* We've already seen this guy. */
1929 1.1 skrll return;
1930 1.1 skrll }
1931 1.1 skrll
1932 1.1.1.11 christos bh = NULL;
1933 1.1.1.11 christos val = globals->thumb_glue_size + 1;
1934 1.1 skrll _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1935 1.1 skrll BSF_GLOBAL, s, val, NULL, true, false, &bh);
1936 1.1 skrll
1937 1.1.1.2 christos /* If we mark it 'thumb', the disassembler will do a better job. */
1938 1.1 skrll myh = (struct coff_link_hash_entry *) bh;
1939 1.1 skrll myh->symbol_class = C_THUMBEXTFUNC;
1940 1.1 skrll
1941 1.1 skrll free (tmp_name);
1942 1.1 skrll
1943 1.1 skrll /* Allocate another symbol to mark where we switch to arm mode. */
1944 1.1 skrll
1945 1.1 skrll #define CHANGE_TO_ARM "__%s_change_to_arm"
1946 1.1 skrll #define BACK_FROM_ARM "__%s_back_from_arm"
1947 1.1 skrll
1948 1.1 skrll amt = strlen (name) + strlen (CHANGE_TO_ARM) + 1;
1949 1.1 skrll tmp_name = bfd_malloc (amt);
1950 1.1 skrll
1951 1.1 skrll BFD_ASSERT (tmp_name);
1952 1.1 skrll
1953 1.1 skrll sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
1954 1.1 skrll
1955 1.1.1.11 christos bh = NULL;
1956 1.1.1.11 christos val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
1957 1.1 skrll _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
1958 1.1 skrll BSF_LOCAL, s, val, NULL, true, false, &bh);
1959 1.1 skrll
1960 1.1 skrll free (tmp_name);
1961 1.1 skrll
1962 1.1 skrll globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
1963 1.1 skrll
1964 1.1 skrll return;
1965 1.1 skrll }
1966 1.1 skrll #endif /* not ARM_WINCE */
1967 1.1 skrll
1968 1.1 skrll /* Select a BFD to be used to hold the sections used by the glue code.
1969 1.1 skrll This function is called from the linker scripts in ld/emultempl/
1970 1.1.1.9 christos {armcoff/pe}.em */
1971 1.1.1.6 christos
1972 1.1 skrll bool
1973 1.1 skrll bfd_arm_get_bfd_for_interworking (bfd * abfd,
1974 1.1 skrll struct bfd_link_info * info)
1975 1.1.1.6 christos {
1976 1.1.1.6 christos struct coff_arm_link_hash_table * globals;
1977 1.1 skrll flagword flags;
1978 1.1 skrll asection * sec;
1979 1.1 skrll
1980 1.1.1.4 christos /* If we are only performing a partial link do not bother
1981 1.1.1.9 christos getting a bfd to hold the glue. */
1982 1.1 skrll if (bfd_link_relocatable (info))
1983 1.1 skrll return true;
1984 1.1 skrll
1985 1.1 skrll globals = coff_arm_hash_table (info);
1986 1.1 skrll
1987 1.1 skrll BFD_ASSERT (globals != NULL);
1988 1.1.1.9 christos
1989 1.1 skrll if (globals->bfd_of_glue_owner != NULL)
1990 1.1 skrll return true;
1991 1.1 skrll
1992 1.1 skrll sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
1993 1.1 skrll
1994 1.1 skrll if (sec == NULL)
1995 1.1 skrll {
1996 1.1 skrll flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
1997 1.1 skrll | SEC_CODE | SEC_READONLY);
1998 1.1 skrll sec = bfd_make_section_with_flags (abfd, ARM2THUMB_GLUE_SECTION_NAME,
1999 1.1.1.8 christos flags);
2000 1.1.1.9 christos if (sec == NULL
2001 1.1 skrll || !bfd_set_section_alignment (sec, 2))
2002 1.1 skrll return false;
2003 1.1 skrll }
2004 1.1 skrll
2005 1.1 skrll sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
2006 1.1 skrll
2007 1.1 skrll if (sec == NULL)
2008 1.1 skrll {
2009 1.1 skrll flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
2010 1.1 skrll | SEC_CODE | SEC_READONLY);
2011 1.1 skrll sec = bfd_make_section_with_flags (abfd, THUMB2ARM_GLUE_SECTION_NAME,
2012 1.1 skrll flags);
2013 1.1.1.8 christos
2014 1.1.1.9 christos if (sec == NULL
2015 1.1 skrll || !bfd_set_section_alignment (sec, 2))
2016 1.1 skrll return false;
2017 1.1 skrll }
2018 1.1 skrll
2019 1.1 skrll /* Save the bfd for later use. */
2020 1.1.1.9 christos globals->bfd_of_glue_owner = abfd;
2021 1.1 skrll
2022 1.1 skrll return true;
2023 1.1.1.9 christos }
2024 1.1.1.6 christos
2025 1.1 skrll bool
2026 1.1.1.6 christos bfd_arm_process_before_allocation (bfd * abfd,
2027 1.1 skrll struct bfd_link_info * info,
2028 1.1 skrll int support_old_code)
2029 1.1 skrll {
2030 1.1 skrll asection * sec;
2031 1.1 skrll struct coff_arm_link_hash_table * globals;
2032 1.1 skrll
2033 1.1.1.4 christos /* If we are only performing a partial link do not bother
2034 1.1.1.9 christos to construct any glue. */
2035 1.1 skrll if (bfd_link_relocatable (info))
2036 1.1 skrll return true;
2037 1.1 skrll
2038 1.1 skrll /* Here we have a bfd that is to be included on the link. We have a hook
2039 1.1 skrll to do reloc rummaging, before section sizes are nailed down. */
2040 1.1 skrll _bfd_coff_get_external_symbols (abfd);
2041 1.1 skrll
2042 1.1 skrll globals = coff_arm_hash_table (info);
2043 1.1 skrll
2044 1.1 skrll BFD_ASSERT (globals != NULL);
2045 1.1 skrll BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
2046 1.1 skrll
2047 1.1 skrll globals->support_old_code = support_old_code;
2048 1.1 skrll
2049 1.1 skrll /* Rummage around all the relocs and map the glue vectors. */
2050 1.1 skrll sec = abfd->sections;
2051 1.1.1.9 christos
2052 1.1 skrll if (sec == NULL)
2053 1.1 skrll return true;
2054 1.1 skrll
2055 1.1 skrll for (; sec != NULL; sec = sec->next)
2056 1.1 skrll {
2057 1.1 skrll struct internal_reloc * i;
2058 1.1 skrll struct internal_reloc * rel;
2059 1.1 skrll
2060 1.1 skrll if (sec->reloc_count == 0)
2061 1.1 skrll continue;
2062 1.1 skrll
2063 1.1 skrll /* Load the relocs. */
2064 1.1 skrll /* FIXME: there may be a storage leak here. */
2065 1.1 skrll i = _bfd_coff_read_internal_relocs (abfd, sec, 1, 0, 0, 0);
2066 1.1 skrll
2067 1.1 skrll BFD_ASSERT (i != 0);
2068 1.1 skrll
2069 1.1.1.6 christos for (rel = i; rel < i + sec->reloc_count; ++rel)
2070 1.1.1.6 christos {
2071 1.1.1.6 christos unsigned short r_type = rel->r_type;
2072 1.1 skrll long symndx;
2073 1.1 skrll struct coff_link_hash_entry * h;
2074 1.1 skrll
2075 1.1 skrll symndx = rel->r_symndx;
2076 1.1 skrll
2077 1.1 skrll /* If the relocation is not against a symbol it cannot concern us. */
2078 1.1 skrll if (symndx == -1)
2079 1.1 skrll continue;
2080 1.1 skrll
2081 1.1 skrll /* If the index is outside of the range of our table, something has gone wrong. */
2082 1.1.1.6 christos if (symndx >= obj_conv_table_size (abfd))
2083 1.1.1.7 christos {
2084 1.1 skrll /* xgettext:c-format */
2085 1.1 skrll _bfd_error_handler (_("%pB: illegal symbol index in reloc: %ld"),
2086 1.1 skrll abfd, symndx);
2087 1.1 skrll continue;
2088 1.1 skrll }
2089 1.1 skrll
2090 1.1 skrll h = obj_coff_sym_hashes (abfd)[symndx];
2091 1.1 skrll
2092 1.1 skrll /* If the relocation is against a static symbol it must be within
2093 1.1 skrll the current section and so cannot be a cross ARM/Thumb relocation. */
2094 1.1 skrll if (h == NULL)
2095 1.1 skrll continue;
2096 1.1 skrll
2097 1.1 skrll switch (r_type)
2098 1.1 skrll {
2099 1.1 skrll case ARM_26:
2100 1.1 skrll /* This one is a call from arm code. We need to look up
2101 1.1 skrll the target of the call. If it is a thumb target, we
2102 1.1.1.2 christos insert glue. */
2103 1.1 skrll
2104 1.1 skrll if (h->symbol_class == C_THUMBEXTFUNC)
2105 1.1 skrll record_arm_to_thumb_glue (info, h);
2106 1.1 skrll break;
2107 1.1 skrll
2108 1.1 skrll #ifndef ARM_WINCE
2109 1.1 skrll case ARM_THUMB23:
2110 1.1 skrll /* This one is a call from thumb code. We used to look
2111 1.1 skrll for ARM_THUMB9 and ARM_THUMB12 as well. We need to look
2112 1.1 skrll up the target of the call. If it is an arm target, we
2113 1.1 skrll insert glue. If the symbol does not exist it will be
2114 1.1 skrll given a class of C_EXT and so we will generate a stub
2115 1.1 skrll for it. This is not really a problem, since the link
2116 1.1.1.2 christos is doomed anyway. */
2117 1.1 skrll
2118 1.1 skrll switch (h->symbol_class)
2119 1.1 skrll {
2120 1.1 skrll case C_EXT:
2121 1.1 skrll case C_STAT:
2122 1.1 skrll case C_LABEL:
2123 1.1 skrll record_thumb_to_arm_glue (info, h);
2124 1.1 skrll break;
2125 1.1 skrll default:
2126 1.1 skrll ;
2127 1.1 skrll }
2128 1.1 skrll break;
2129 1.1 skrll #endif
2130 1.1 skrll
2131 1.1 skrll default:
2132 1.1 skrll break;
2133 1.1 skrll }
2134 1.1 skrll }
2135 1.1.1.9 christos }
2136 1.1 skrll
2137 1.1 skrll return true;
2138 1.1 skrll }
2139 1.1 skrll
2140 1.1.1.6 christos #endif /* ! defined (COFF_IMAGE_WITH_PE) */
2141 1.1.1.6 christos
2142 1.1.1.6 christos #define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup
2143 1.1.1.6 christos #define coff_bfd_reloc_name_lookup coff_arm_reloc_name_lookup
2144 1.1 skrll #define coff_relocate_section coff_arm_relocate_section
2145 1.1.1.6 christos #define coff_bfd_is_local_label_name coff_arm_is_local_label_name
2146 1.1 skrll #define coff_adjust_symndx coff_arm_adjust_symndx
2147 1.1 skrll #define coff_link_output_has_begun coff_arm_link_output_has_begun
2148 1.1 skrll #define coff_final_link_postscript coff_arm_final_link_postscript
2149 1.1.1.6 christos #define coff_bfd_merge_private_bfd_data coff_arm_merge_private_bfd_data
2150 1.1.1.6 christos #define coff_bfd_print_private_bfd_data coff_arm_print_private_bfd_data
2151 1.1 skrll #define coff_bfd_set_private_flags _bfd_coff_arm_set_private_flags
2152 1.1 skrll #define coff_bfd_copy_private_bfd_data coff_arm_copy_private_bfd_data
2153 1.1 skrll #define coff_bfd_link_hash_table_create coff_arm_link_hash_table_create
2154 1.1 skrll
2155 1.1 skrll /* When doing a relocatable link, we want to convert ARM_26 relocs
2156 1.1.1.9 christos into ARM_26D relocs. */
2157 1.1 skrll
2158 1.1 skrll static bool
2159 1.1 skrll coff_arm_adjust_symndx (bfd *obfd ATTRIBUTE_UNUSED,
2160 1.1 skrll struct bfd_link_info *info ATTRIBUTE_UNUSED,
2161 1.1 skrll bfd *ibfd,
2162 1.1.1.9 christos asection *sec,
2163 1.1 skrll struct internal_reloc *irel,
2164 1.1 skrll bool *adjustedp)
2165 1.1 skrll {
2166 1.1 skrll if (irel->r_type == ARM_26)
2167 1.1 skrll {
2168 1.1 skrll struct coff_link_hash_entry *h;
2169 1.1 skrll
2170 1.1 skrll h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
2171 1.1 skrll if (h != NULL
2172 1.1 skrll && (h->root.type == bfd_link_hash_defined
2173 1.1 skrll || h->root.type == bfd_link_hash_defweak)
2174 1.1 skrll && h->root.u.def.section->output_section == sec->output_section)
2175 1.1.1.9 christos irel->r_type = ARM_26D;
2176 1.1.1.9 christos }
2177 1.1 skrll *adjustedp = false;
2178 1.1 skrll return true;
2179 1.1 skrll }
2180 1.1 skrll
2181 1.1 skrll /* Called when merging the private data areas of two BFDs.
2182 1.1 skrll This is important as it allows us to detect if we are
2183 1.1 skrll attempting to merge binaries compiled for different ARM
2184 1.1.1.9 christos targets, eg different CPUs or different APCS's. */
2185 1.1.1.6 christos
2186 1.1 skrll static bool
2187 1.1.1.6 christos coff_arm_merge_private_bfd_data (bfd * ibfd, struct bfd_link_info *info)
2188 1.1 skrll {
2189 1.1 skrll bfd *obfd = info->output_bfd;
2190 1.1 skrll BFD_ASSERT (ibfd != NULL && obfd != NULL);
2191 1.1.1.9 christos
2192 1.1 skrll if (ibfd == obfd)
2193 1.1 skrll return true;
2194 1.1 skrll
2195 1.1 skrll /* If the two formats are different we cannot merge anything.
2196 1.1 skrll This is not an error, since it is permissable to change the
2197 1.1 skrll input and output formats. */
2198 1.1.1.9 christos if ( ibfd->xvec->flavour != bfd_target_coff_flavour
2199 1.1 skrll || obfd->xvec->flavour != bfd_target_coff_flavour)
2200 1.1 skrll return true;
2201 1.1 skrll
2202 1.1 skrll /* Determine what should happen if the input ARM architecture
2203 1.1.1.9 christos does not match the output ARM architecture. */
2204 1.1 skrll if (! bfd_arm_merge_machines (ibfd, obfd))
2205 1.1 skrll return false;
2206 1.1 skrll
2207 1.1 skrll /* Verify that the APCS is the same for the two BFDs. */
2208 1.1 skrll if (APCS_SET (ibfd))
2209 1.1 skrll {
2210 1.1 skrll if (APCS_SET (obfd))
2211 1.1 skrll {
2212 1.1 skrll /* If the src and dest have different APCS flag bits set, fail. */
2213 1.1 skrll if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
2214 1.1 skrll {
2215 1.1.1.9 christos _bfd_error_handler
2216 1.1.1.9 christos /* xgettext: c-format */
2217 1.1.1.6 christos (_("error: %pB is compiled for APCS-%d, "
2218 1.1.1.6 christos "whereas %pB is compiled for APCS-%d"),
2219 1.1 skrll ibfd, APCS_26_FLAG (ibfd) ? 26 : 32,
2220 1.1 skrll obfd, APCS_26_FLAG (obfd) ? 26 : 32
2221 1.1 skrll );
2222 1.1.1.9 christos
2223 1.1 skrll bfd_set_error (bfd_error_wrong_format);
2224 1.1 skrll return false;
2225 1.1 skrll }
2226 1.1 skrll
2227 1.1 skrll if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
2228 1.1 skrll {
2229 1.1.1.9 christos if (APCS_FLOAT_FLAG (ibfd))
2230 1.1.1.9 christos /* xgettext: c-format */
2231 1.1.1.9 christos _bfd_error_handler
2232 1.1.1.9 christos (_("error: %pB passes floats in float registers, "
2233 1.1 skrll "whereas %pB passes them in integer registers"),
2234 1.1 skrll ibfd, obfd);
2235 1.1.1.9 christos else
2236 1.1.1.9 christos /* xgettext: c-format */
2237 1.1.1.9 christos _bfd_error_handler
2238 1.1.1.9 christos (_("error: %pB passes floats in integer registers, "
2239 1.1 skrll "whereas %pB passes them in float registers"),
2240 1.1 skrll ibfd, obfd);
2241 1.1.1.9 christos
2242 1.1 skrll bfd_set_error (bfd_error_wrong_format);
2243 1.1 skrll return false;
2244 1.1 skrll }
2245 1.1 skrll
2246 1.1 skrll if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
2247 1.1 skrll {
2248 1.1.1.9 christos if (PIC_FLAG (ibfd))
2249 1.1.1.9 christos /* xgettext: c-format */
2250 1.1.1.9 christos _bfd_error_handler
2251 1.1.1.9 christos (_("error: %pB is compiled as position independent code, "
2252 1.1 skrll "whereas target %pB is absolute position"),
2253 1.1 skrll ibfd, obfd);
2254 1.1.1.9 christos else
2255 1.1.1.9 christos /* xgettext: c-format */
2256 1.1.1.9 christos _bfd_error_handler
2257 1.1.1.9 christos (_("error: %pB is compiled as absolute position code, "
2258 1.1 skrll "whereas target %pB is position independent"),
2259 1.1 skrll ibfd, obfd);
2260 1.1.1.9 christos
2261 1.1 skrll bfd_set_error (bfd_error_wrong_format);
2262 1.1 skrll return false;
2263 1.1 skrll }
2264 1.1 skrll }
2265 1.1 skrll else
2266 1.1 skrll {
2267 1.1 skrll SET_APCS_FLAGS (obfd, APCS_26_FLAG (ibfd) | APCS_FLOAT_FLAG (ibfd) | PIC_FLAG (ibfd));
2268 1.1 skrll
2269 1.1 skrll /* Set up the arch and fields as well as these are probably wrong. */
2270 1.1 skrll bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2271 1.1 skrll }
2272 1.1 skrll }
2273 1.1 skrll
2274 1.1 skrll /* Check the interworking support. */
2275 1.1 skrll if (INTERWORK_SET (ibfd))
2276 1.1 skrll {
2277 1.1 skrll if (INTERWORK_SET (obfd))
2278 1.1 skrll {
2279 1.1 skrll /* If the src and dest differ in their interworking issue a warning. */
2280 1.1 skrll if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd))
2281 1.1 skrll {
2282 1.1.1.9 christos if (INTERWORK_FLAG (ibfd))
2283 1.1.1.9 christos /* xgettext: c-format */
2284 1.1.1.6 christos _bfd_error_handler (_("warning: %pB supports interworking, "
2285 1.1 skrll "whereas %pB does not"),
2286 1.1 skrll ibfd, obfd);
2287 1.1.1.9 christos else
2288 1.1.1.9 christos /* xgettext: c-format */
2289 1.1.1.9 christos _bfd_error_handler
2290 1.1.1.9 christos (_("warning: %pB does not support interworking, "
2291 1.1 skrll "whereas %pB does"),
2292 1.1 skrll ibfd, obfd);
2293 1.1 skrll }
2294 1.1 skrll }
2295 1.1 skrll else
2296 1.1 skrll {
2297 1.1 skrll SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
2298 1.1 skrll }
2299 1.1.1.9 christos }
2300 1.1 skrll
2301 1.1 skrll return true;
2302 1.1 skrll }
2303 1.1 skrll
2304 1.1.1.9 christos /* Display the flags field. */
2305 1.1 skrll
2306 1.1 skrll static bool
2307 1.1 skrll coff_arm_print_private_bfd_data (bfd * abfd, void * ptr)
2308 1.1 skrll {
2309 1.1 skrll FILE * file = (FILE *) ptr;
2310 1.1 skrll
2311 1.1 skrll BFD_ASSERT (abfd != NULL && ptr != NULL);
2312 1.1 skrll
2313 1.1 skrll fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags);
2314 1.1 skrll
2315 1.1 skrll if (APCS_SET (abfd))
2316 1.1 skrll {
2317 1.1 skrll /* xgettext: APCS is ARM Procedure Call Standard, it should not be translated. */
2318 1.1 skrll fprintf (file, " [APCS-%d]", APCS_26_FLAG (abfd) ? 26 : 32);
2319 1.1 skrll
2320 1.1 skrll if (APCS_FLOAT_FLAG (abfd))
2321 1.1 skrll fprintf (file, _(" [floats passed in float registers]"));
2322 1.1 skrll else
2323 1.1 skrll fprintf (file, _(" [floats passed in integer registers]"));
2324 1.1 skrll
2325 1.1 skrll if (PIC_FLAG (abfd))
2326 1.1 skrll fprintf (file, _(" [position independent]"));
2327 1.1 skrll else
2328 1.1 skrll fprintf (file, _(" [absolute position]"));
2329 1.1 skrll }
2330 1.1 skrll
2331 1.1 skrll if (! INTERWORK_SET (abfd))
2332 1.1 skrll fprintf (file, _(" [interworking flag not initialised]"));
2333 1.1 skrll else if (INTERWORK_FLAG (abfd))
2334 1.1 skrll fprintf (file, _(" [interworking supported]"));
2335 1.1 skrll else
2336 1.1 skrll fprintf (file, _(" [interworking not supported]"));
2337 1.1 skrll
2338 1.1.1.9 christos fputc ('\n', file);
2339 1.1 skrll
2340 1.1 skrll return true;
2341 1.1 skrll }
2342 1.1 skrll
2343 1.1 skrll /* Copies the given flags into the coff_tdata.flags field.
2344 1.1 skrll Typically these flags come from the f_flags[] field of
2345 1.1 skrll the COFF filehdr structure, which contains important,
2346 1.1 skrll target specific information.
2347 1.1 skrll Note: Although this function is static, it is explicitly
2348 1.1.1.9 christos called from both coffcode.h and peicode.h. */
2349 1.1 skrll
2350 1.1 skrll static bool
2351 1.1 skrll _bfd_coff_arm_set_private_flags (bfd * abfd, flagword flags)
2352 1.1 skrll {
2353 1.1 skrll flagword flag;
2354 1.1 skrll
2355 1.1 skrll BFD_ASSERT (abfd != NULL);
2356 1.1 skrll
2357 1.1 skrll flag = (flags & F_APCS26) ? F_APCS_26 : 0;
2358 1.1 skrll
2359 1.1 skrll /* Make sure that the APCS field has not been initialised to the opposite
2360 1.1 skrll value. */
2361 1.1 skrll if (APCS_SET (abfd)
2362 1.1.1.6 christos && ( (APCS_26_FLAG (abfd) != flag)
2363 1.1 skrll || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT))
2364 1.1.1.9 christos || (PIC_FLAG (abfd) != (flags & F_PIC))
2365 1.1 skrll ))
2366 1.1 skrll return false;
2367 1.1 skrll
2368 1.1 skrll flag |= (flags & (F_APCS_FLOAT | F_PIC));
2369 1.1 skrll
2370 1.1 skrll SET_APCS_FLAGS (abfd, flag);
2371 1.1 skrll
2372 1.1 skrll flag = (flags & F_INTERWORK);
2373 1.1 skrll
2374 1.1 skrll /* If the BFD has already had its interworking flag set, but it
2375 1.1 skrll is different from the value that we have been asked to set,
2376 1.1 skrll then assume that that merged code will not support interworking
2377 1.1 skrll and set the flag accordingly. */
2378 1.1 skrll if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag))
2379 1.1.1.7 christos {
2380 1.1 skrll if (flag)
2381 1.1 skrll _bfd_error_handler (_("warning: not setting interworking flag of %pB since it has already been specified as non-interworking"),
2382 1.1.1.7 christos abfd);
2383 1.1 skrll else
2384 1.1 skrll _bfd_error_handler (_("warning: clearing the interworking flag of %pB due to outside request"),
2385 1.1 skrll abfd);
2386 1.1 skrll flag = 0;
2387 1.1 skrll }
2388 1.1 skrll
2389 1.1.1.9 christos SET_INTERWORK_FLAG (abfd, flag);
2390 1.1 skrll
2391 1.1 skrll return true;
2392 1.1 skrll }
2393 1.1 skrll
2394 1.1 skrll /* Copy the important parts of the target specific data
2395 1.1.1.9 christos from one instance of a BFD to another. */
2396 1.1 skrll
2397 1.1 skrll static bool
2398 1.1 skrll coff_arm_copy_private_bfd_data (bfd * src, bfd * dest)
2399 1.1 skrll {
2400 1.1 skrll BFD_ASSERT (src != NULL && dest != NULL);
2401 1.1.1.9 christos
2402 1.1 skrll if (src == dest)
2403 1.1 skrll return true;
2404 1.1 skrll
2405 1.1 skrll /* If the destination is not in the same format as the source, do not do
2406 1.1.1.9 christos the copy. */
2407 1.1 skrll if (src->xvec != dest->xvec)
2408 1.1 skrll return true;
2409 1.1 skrll
2410 1.1 skrll /* Copy the flags field. */
2411 1.1 skrll if (APCS_SET (src))
2412 1.1 skrll {
2413 1.1 skrll if (APCS_SET (dest))
2414 1.1 skrll {
2415 1.1.1.9 christos /* If the src and dest have different APCS flag bits set, fail. */
2416 1.1 skrll if (APCS_26_FLAG (dest) != APCS_26_FLAG (src))
2417 1.1 skrll return false;
2418 1.1.1.9 christos
2419 1.1 skrll if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src))
2420 1.1 skrll return false;
2421 1.1.1.9 christos
2422 1.1 skrll if (PIC_FLAG (dest) != PIC_FLAG (src))
2423 1.1 skrll return false;
2424 1.1 skrll }
2425 1.1 skrll else
2426 1.1 skrll SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src)
2427 1.1 skrll | PIC_FLAG (src));
2428 1.1 skrll }
2429 1.1 skrll
2430 1.1 skrll if (INTERWORK_SET (src))
2431 1.1 skrll {
2432 1.1 skrll if (INTERWORK_SET (dest))
2433 1.1 skrll {
2434 1.1 skrll /* If the src and dest have different interworking flags then turn
2435 1.1 skrll off the interworking bit. */
2436 1.1 skrll if (INTERWORK_FLAG (dest) != INTERWORK_FLAG (src))
2437 1.1 skrll {
2438 1.1 skrll if (INTERWORK_FLAG (dest))
2439 1.1.1.9 christos {
2440 1.1.1.9 christos /* xgettext:c-format */
2441 1.1.1.9 christos _bfd_error_handler
2442 1.1.1.9 christos (_("warning: clearing the interworking flag of %pB "
2443 1.1.1.9 christos "because non-interworking code in %pB has been "
2444 1.1 skrll "linked with it"),
2445 1.1 skrll dest, src);
2446 1.1 skrll }
2447 1.1 skrll
2448 1.1 skrll SET_INTERWORK_FLAG (dest, 0);
2449 1.1 skrll }
2450 1.1 skrll }
2451 1.1 skrll else
2452 1.1 skrll {
2453 1.1 skrll SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src));
2454 1.1 skrll }
2455 1.1.1.9 christos }
2456 1.1 skrll
2457 1.1 skrll return true;
2458 1.1 skrll }
2459 1.1 skrll
2460 1.1 skrll /* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
2461 1.1 skrll *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h. */
2462 1.1 skrll #ifndef LOCAL_LABEL_PREFIX
2463 1.1 skrll #define LOCAL_LABEL_PREFIX ""
2464 1.1 skrll #endif
2465 1.1 skrll #ifndef USER_LABEL_PREFIX
2466 1.1 skrll #define USER_LABEL_PREFIX "_"
2467 1.1 skrll #endif
2468 1.1 skrll
2469 1.1 skrll /* Like _bfd_coff_is_local_label_name, but
2470 1.1 skrll a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be
2471 1.1 skrll non-local.
2472 1.1 skrll b) Allow other prefixes than ".", e.g. an empty prefix would cause all
2473 1.1.1.9 christos labels of the form Lxxx to be stripped. */
2474 1.1.1.6 christos
2475 1.1 skrll static bool
2476 1.1 skrll coff_arm_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
2477 1.1 skrll const char * name)
2478 1.1 skrll {
2479 1.1 skrll #ifdef USER_LABEL_PREFIX
2480 1.1 skrll if (USER_LABEL_PREFIX[0] != 0)
2481 1.1 skrll {
2482 1.1 skrll size_t len = strlen (USER_LABEL_PREFIX);
2483 1.1.1.9 christos
2484 1.1 skrll if (strncmp (name, USER_LABEL_PREFIX, len) == 0)
2485 1.1 skrll return false;
2486 1.1 skrll }
2487 1.1 skrll #endif
2488 1.1 skrll
2489 1.1 skrll #ifdef LOCAL_LABEL_PREFIX
2490 1.1 skrll /* If there is a prefix for local labels then look for this.
2491 1.1 skrll If the prefix exists, but it is empty, then ignore the test. */
2492 1.1 skrll
2493 1.1 skrll if (LOCAL_LABEL_PREFIX[0] != 0)
2494 1.1 skrll {
2495 1.1 skrll size_t len = strlen (LOCAL_LABEL_PREFIX);
2496 1.1.1.9 christos
2497 1.1 skrll if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0)
2498 1.1 skrll return false;
2499 1.1 skrll
2500 1.1 skrll /* Perform the checks below for the rest of the name. */
2501 1.1 skrll name += len;
2502 1.1 skrll }
2503 1.1 skrll #endif
2504 1.1 skrll
2505 1.1 skrll return name[0] == 'L';
2506 1.1 skrll }
2507 1.1 skrll
2508 1.1 skrll /* This piece of machinery exists only to guarantee that the bfd that holds
2509 1.1 skrll the glue section is written last.
2510 1.1 skrll
2511 1.1 skrll This does depend on bfd_make_section attaching a new section to the
2512 1.1.1.9 christos end of the section list for the bfd. */
2513 1.1 skrll
2514 1.1 skrll static bool
2515 1.1 skrll coff_arm_link_output_has_begun (bfd * sub, struct coff_final_link_info * info)
2516 1.1 skrll {
2517 1.1 skrll return (sub->output_has_begun
2518 1.1 skrll || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner);
2519 1.1.1.9 christos }
2520 1.1 skrll
2521 1.1 skrll static bool
2522 1.1 skrll coff_arm_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED,
2523 1.1 skrll struct coff_final_link_info * pfinfo)
2524 1.1 skrll {
2525 1.1 skrll struct coff_arm_link_hash_table * globals;
2526 1.1 skrll
2527 1.1 skrll globals = coff_arm_hash_table (pfinfo->info);
2528 1.1 skrll
2529 1.1 skrll BFD_ASSERT (globals != NULL);
2530 1.1 skrll
2531 1.1 skrll if (globals->bfd_of_glue_owner != NULL)
2532 1.1.1.9 christos {
2533 1.1 skrll if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner))
2534 1.1.1.9 christos return false;
2535 1.1 skrll
2536 1.1 skrll globals->bfd_of_glue_owner->output_has_begun = true;
2537 1.1 skrll }
2538 1.1 skrll
2539 1.1 skrll return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
2540 1.1 skrll }
2541 1.1 skrll
2542 1.1 skrll #ifndef bfd_pe_print_pdata
2543 1.1 skrll #define bfd_pe_print_pdata NULL
2544 1.1 skrll #endif
2545 1.1 skrll
2546 1.1 skrll #include "coffcode.h"
2547 1.1.1.4 christos
2548 1.1 skrll #ifndef TARGET_LITTLE_SYM
2549 1.1 skrll #define TARGET_LITTLE_SYM arm_coff_le_vec
2550 1.1 skrll #endif
2551 1.1 skrll #ifndef TARGET_LITTLE_NAME
2552 1.1 skrll #define TARGET_LITTLE_NAME "coff-arm-little"
2553 1.1.1.4 christos #endif
2554 1.1 skrll #ifndef TARGET_BIG_SYM
2555 1.1 skrll #define TARGET_BIG_SYM arm_coff_be_vec
2556 1.1 skrll #endif
2557 1.1 skrll #ifndef TARGET_BIG_NAME
2558 1.1 skrll #define TARGET_BIG_NAME "coff-arm-big"
2559 1.1 skrll #endif
2560 1.1 skrll
2561 1.1 skrll #ifndef TARGET_UNDERSCORE
2562 1.1 skrll #define TARGET_UNDERSCORE 0
2563 1.1 skrll #endif
2564 1.1 skrll
2565 1.1 skrll #ifndef EXTRA_S_FLAGS
2566 1.1 skrll #ifdef COFF_WITH_PE
2567 1.1 skrll #define EXTRA_S_FLAGS (SEC_CODE | SEC_LINK_ONCE | SEC_LINK_DUPLICATES)
2568 1.1 skrll #else
2569 1.1 skrll #define EXTRA_S_FLAGS SEC_CODE
2570 1.1 skrll #endif
2571 1.1 skrll #endif
2572 1.1 skrll
2573 1.1 skrll /* Forward declaration for use initialising alternative_target field. */
2574 1.1 skrll extern const bfd_target TARGET_BIG_SYM ;
2575 1.1 skrll
2576 1.1 skrll /* Target vectors. */
2577 CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_BIG_SYM, COFF_SWAP_TABLE)
2578 CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_LITTLE_SYM, COFF_SWAP_TABLE)
2579