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