cpu-arm.c revision 1.7 1 1.1 christos /* BFD support for the ARM processor
2 1.7 christos Copyright (C) 1994-2017 Free Software Foundation, Inc.
3 1.1 christos Contributed by Richard Earnshaw (rwe (at) pegasus.esprit.ec.org)
4 1.1 christos
5 1.1 christos This file is part of BFD, the Binary File Descriptor library.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; if not, write to the Free Software
19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 christos MA 02110-1301, USA. */
21 1.1 christos
22 1.1 christos #include "sysdep.h"
23 1.1 christos #include "bfd.h"
24 1.1 christos #include "libbfd.h"
25 1.1 christos #include "libiberty.h"
26 1.1 christos
27 1.1 christos /* This routine is provided two arch_infos and works out which ARM
28 1.1 christos machine which would be compatible with both and returns a pointer
29 1.1 christos to its info structure. */
30 1.1 christos
31 1.1 christos static const bfd_arch_info_type *
32 1.1 christos compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
33 1.1 christos {
34 1.1 christos /* If a & b are for different architecture we can do nothing. */
35 1.1 christos if (a->arch != b->arch)
36 1.1 christos return NULL;
37 1.1 christos
38 1.1 christos /* If a & b are for the same machine then all is well. */
39 1.1 christos if (a->mach == b->mach)
40 1.1 christos return a;
41 1.1 christos
42 1.1 christos /* Otherwise if either a or b is the 'default' machine
43 1.1 christos then it can be polymorphed into the other. */
44 1.1 christos if (a->the_default)
45 1.1 christos return b;
46 1.1 christos
47 1.1 christos if (b->the_default)
48 1.1 christos return a;
49 1.1 christos
50 1.1 christos /* So far all newer ARM architecture cores are
51 1.1 christos supersets of previous cores. */
52 1.1 christos if (a->mach < b->mach)
53 1.1 christos return b;
54 1.1 christos else if (a->mach > b->mach)
55 1.1 christos return a;
56 1.1 christos
57 1.1 christos /* Never reached! */
58 1.1 christos return NULL;
59 1.1 christos }
60 1.1 christos
61 1.1 christos static struct
62 1.1 christos {
63 1.1 christos unsigned int mach;
64 1.1 christos char * name;
65 1.1 christos }
66 1.1 christos processors[] =
67 1.1 christos {
68 1.1 christos { bfd_mach_arm_2, "arm2" },
69 1.1 christos { bfd_mach_arm_2a, "arm250" },
70 1.1 christos { bfd_mach_arm_2a, "arm3" },
71 1.1 christos { bfd_mach_arm_3, "arm6" },
72 1.1 christos { bfd_mach_arm_3, "arm60" },
73 1.1 christos { bfd_mach_arm_3, "arm600" },
74 1.1 christos { bfd_mach_arm_3, "arm610" },
75 1.1 christos { bfd_mach_arm_3, "arm7" },
76 1.1 christos { bfd_mach_arm_3, "arm710" },
77 1.1 christos { bfd_mach_arm_3, "arm7500" },
78 1.1 christos { bfd_mach_arm_3, "arm7d" },
79 1.1 christos { bfd_mach_arm_3, "arm7di" },
80 1.1 christos { bfd_mach_arm_3M, "arm7dm" },
81 1.1 christos { bfd_mach_arm_3M, "arm7dmi" },
82 1.1 christos { bfd_mach_arm_4T, "arm7tdmi" },
83 1.1 christos { bfd_mach_arm_4, "arm8" },
84 1.1 christos { bfd_mach_arm_4, "arm810" },
85 1.1 christos { bfd_mach_arm_4, "arm9" },
86 1.1 christos { bfd_mach_arm_4, "arm920" },
87 1.1 christos { bfd_mach_arm_4T, "arm920t" },
88 1.1 christos { bfd_mach_arm_4T, "arm9tdmi" },
89 1.1 christos { bfd_mach_arm_4, "sa1" },
90 1.1 christos { bfd_mach_arm_4, "strongarm"},
91 1.1 christos { bfd_mach_arm_4, "strongarm110" },
92 1.1 christos { bfd_mach_arm_4, "strongarm1100" },
93 1.1 christos { bfd_mach_arm_XScale, "xscale" },
94 1.1 christos { bfd_mach_arm_ep9312, "ep9312" },
95 1.1 christos { bfd_mach_arm_iWMMXt, "iwmmxt" },
96 1.6 christos { bfd_mach_arm_iWMMXt2, "iwmmxt2" },
97 1.6 christos { bfd_mach_arm_unknown, "arm_any" }
98 1.1 christos };
99 1.1 christos
100 1.1 christos static bfd_boolean
101 1.1 christos scan (const struct bfd_arch_info *info, const char *string)
102 1.1 christos {
103 1.1 christos int i;
104 1.1 christos
105 1.1 christos /* First test for an exact match. */
106 1.1 christos if (strcasecmp (string, info->printable_name) == 0)
107 1.1 christos return TRUE;
108 1.1 christos
109 1.1 christos /* Next check for a processor name instead of an Architecture name. */
110 1.1 christos for (i = sizeof (processors) / sizeof (processors[0]); i--;)
111 1.1 christos {
112 1.1 christos if (strcasecmp (string, processors [i].name) == 0)
113 1.1 christos break;
114 1.1 christos }
115 1.1 christos
116 1.1 christos if (i != -1 && info->mach == processors [i].mach)
117 1.1 christos return TRUE;
118 1.1 christos
119 1.1 christos /* Finally check for the default architecture. */
120 1.1 christos if (strcasecmp (string, "arm") == 0)
121 1.1 christos return info->the_default;
122 1.1 christos
123 1.1 christos return FALSE;
124 1.1 christos }
125 1.1 christos
126 1.1 christos #define N(number, print, default, next) \
127 1.1 christos { 32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, \
128 1.1 christos scan, bfd_arch_default_fill, next }
129 1.1 christos
130 1.1 christos static const bfd_arch_info_type arch_info_struct[] =
131 1.1 christos {
132 1.6 christos N (bfd_mach_arm_2, "armv2", FALSE, & arch_info_struct[1]),
133 1.6 christos N (bfd_mach_arm_2a, "armv2a", FALSE, & arch_info_struct[2]),
134 1.6 christos N (bfd_mach_arm_3, "armv3", FALSE, & arch_info_struct[3]),
135 1.6 christos N (bfd_mach_arm_3M, "armv3m", FALSE, & arch_info_struct[4]),
136 1.6 christos N (bfd_mach_arm_4, "armv4", FALSE, & arch_info_struct[5]),
137 1.6 christos N (bfd_mach_arm_4T, "armv4t", FALSE, & arch_info_struct[6]),
138 1.6 christos N (bfd_mach_arm_5, "armv5", FALSE, & arch_info_struct[7]),
139 1.6 christos N (bfd_mach_arm_5T, "armv5t", FALSE, & arch_info_struct[8]),
140 1.6 christos N (bfd_mach_arm_5TE, "armv5te", FALSE, & arch_info_struct[9]),
141 1.6 christos N (bfd_mach_arm_XScale, "xscale", FALSE, & arch_info_struct[10]),
142 1.6 christos N (bfd_mach_arm_ep9312, "ep9312", FALSE, & arch_info_struct[11]),
143 1.6 christos N (bfd_mach_arm_iWMMXt, "iwmmxt", FALSE, & arch_info_struct[12]),
144 1.6 christos N (bfd_mach_arm_iWMMXt2, "iwmmxt2", FALSE, & arch_info_struct[13]),
145 1.6 christos N (bfd_mach_arm_unknown, "arm_any", FALSE, NULL)
146 1.1 christos };
147 1.1 christos
148 1.1 christos const bfd_arch_info_type bfd_arm_arch =
149 1.1 christos N (0, "arm", TRUE, & arch_info_struct[0]);
150 1.1 christos
151 1.1 christos /* Support functions used by both the COFF and ELF versions of the ARM port. */
152 1.1 christos
153 1.1 christos /* Handle the merging of the 'machine' settings of input file IBFD
154 1.1 christos and an output file OBFD. These values actually represent the
155 1.1 christos different possible ARM architecture variants.
156 1.1 christos Returns TRUE if they were merged successfully or FALSE otherwise. */
157 1.1 christos
158 1.1 christos bfd_boolean
159 1.1 christos bfd_arm_merge_machines (bfd *ibfd, bfd *obfd)
160 1.1 christos {
161 1.1 christos unsigned int in = bfd_get_mach (ibfd);
162 1.1 christos unsigned int out = bfd_get_mach (obfd);
163 1.1 christos
164 1.1 christos /* If the output architecture is unknown, we now have a value to set. */
165 1.1 christos if (out == bfd_mach_arm_unknown)
166 1.1 christos bfd_set_arch_mach (obfd, bfd_arch_arm, in);
167 1.1 christos
168 1.1 christos /* If the input architecture is unknown,
169 1.1 christos then so must be the output architecture. */
170 1.1 christos else if (in == bfd_mach_arm_unknown)
171 1.1 christos /* FIXME: We ought to have some way to
172 1.1 christos override this on the command line. */
173 1.1 christos bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);
174 1.1 christos
175 1.1 christos /* If they are the same then nothing needs to be done. */
176 1.1 christos else if (out == in)
177 1.1 christos ;
178 1.1 christos
179 1.1 christos /* Otherwise the general principle that a earlier architecture can be
180 1.1 christos linked with a later architecture to produce a binary that will execute
181 1.1 christos on the later architecture.
182 1.1 christos
183 1.1 christos We fail however if we attempt to link a Cirrus EP9312 binary with an
184 1.1 christos Intel XScale binary, since these architecture have co-processors which
185 1.1 christos will not both be present on the same physical hardware. */
186 1.1 christos else if (in == bfd_mach_arm_ep9312
187 1.1 christos && (out == bfd_mach_arm_XScale
188 1.1 christos || out == bfd_mach_arm_iWMMXt
189 1.1 christos || out == bfd_mach_arm_iWMMXt2))
190 1.1 christos {
191 1.7 christos /* xgettext: c-format */
192 1.1 christos _bfd_error_handler (_("\
193 1.1 christos error: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
194 1.1 christos ibfd, obfd);
195 1.1 christos bfd_set_error (bfd_error_wrong_format);
196 1.1 christos return FALSE;
197 1.1 christos }
198 1.1 christos else if (out == bfd_mach_arm_ep9312
199 1.1 christos && (in == bfd_mach_arm_XScale
200 1.1 christos || in == bfd_mach_arm_iWMMXt
201 1.1 christos || in == bfd_mach_arm_iWMMXt2))
202 1.1 christos {
203 1.7 christos /* xgettext: c-format */
204 1.1 christos _bfd_error_handler (_("\
205 1.1 christos error: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
206 1.1 christos obfd, ibfd);
207 1.1 christos bfd_set_error (bfd_error_wrong_format);
208 1.1 christos return FALSE;
209 1.1 christos }
210 1.1 christos else if (in > out)
211 1.1 christos bfd_set_arch_mach (obfd, bfd_arch_arm, in);
212 1.1 christos /* else
213 1.1 christos Nothing to do. */
214 1.1 christos
215 1.1 christos return TRUE;
216 1.1 christos }
217 1.1 christos
218 1.1 christos typedef struct
219 1.1 christos {
220 1.1 christos unsigned char namesz[4]; /* Size of entry's owner string. */
221 1.1 christos unsigned char descsz[4]; /* Size of the note descriptor. */
222 1.1 christos unsigned char type[4]; /* Interpretation of the descriptor. */
223 1.1 christos char name[1]; /* Start of the name+desc data. */
224 1.1 christos } arm_Note;
225 1.1 christos
226 1.1 christos static bfd_boolean
227 1.1 christos arm_check_note (bfd *abfd,
228 1.1 christos bfd_byte *buffer,
229 1.1 christos bfd_size_type buffer_size,
230 1.1 christos const char *expected_name,
231 1.1 christos char **description_return)
232 1.1 christos {
233 1.1 christos unsigned long namesz;
234 1.1 christos unsigned long descsz;
235 1.1 christos unsigned long type;
236 1.1 christos char * descr;
237 1.1 christos
238 1.1 christos if (buffer_size < offsetof (arm_Note, name))
239 1.1 christos return FALSE;
240 1.1 christos
241 1.1 christos /* We have to extract the values this way to allow for a
242 1.1 christos host whose endian-ness is different from the target. */
243 1.1 christos namesz = bfd_get_32 (abfd, buffer);
244 1.1 christos descsz = bfd_get_32 (abfd, buffer + offsetof (arm_Note, descsz));
245 1.1 christos type = bfd_get_32 (abfd, buffer + offsetof (arm_Note, type));
246 1.1 christos descr = (char *) buffer + offsetof (arm_Note, name);
247 1.1 christos
248 1.1 christos /* Check for buffer overflow. */
249 1.1 christos if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
250 1.1 christos return FALSE;
251 1.1 christos
252 1.1 christos if (expected_name == NULL)
253 1.1 christos {
254 1.1 christos if (namesz != 0)
255 1.1 christos return FALSE;
256 1.1 christos }
257 1.1 christos else
258 1.1 christos {
259 1.1 christos if (namesz != ((strlen (expected_name) + 1 + 3) & ~3))
260 1.1 christos return FALSE;
261 1.1 christos
262 1.1 christos if (strcmp (descr, expected_name) != 0)
263 1.1 christos return FALSE;
264 1.1 christos
265 1.1 christos descr += (namesz + 3) & ~3;
266 1.1 christos }
267 1.1 christos
268 1.1 christos /* FIXME: We should probably check the type as well. */
269 1.1 christos (void) type;
270 1.1 christos
271 1.1 christos if (description_return != NULL)
272 1.1 christos * description_return = descr;
273 1.1 christos
274 1.1 christos return TRUE;
275 1.1 christos }
276 1.1 christos
277 1.1 christos #define NOTE_ARCH_STRING "arch: "
278 1.1 christos
279 1.1 christos bfd_boolean
280 1.1 christos bfd_arm_update_notes (bfd *abfd, const char *note_section)
281 1.1 christos {
282 1.1 christos asection * arm_arch_section;
283 1.1 christos bfd_size_type buffer_size;
284 1.1 christos bfd_byte * buffer;
285 1.1 christos char * arch_string;
286 1.1 christos char * expected;
287 1.1 christos
288 1.1 christos /* Look for a note section. If one is present check the architecture
289 1.1 christos string encoded in it, and set it to the current architecture if it is
290 1.1 christos different. */
291 1.1 christos arm_arch_section = bfd_get_section_by_name (abfd, note_section);
292 1.1 christos
293 1.1 christos if (arm_arch_section == NULL)
294 1.1 christos return TRUE;
295 1.1 christos
296 1.1 christos buffer_size = arm_arch_section->size;
297 1.1 christos if (buffer_size == 0)
298 1.1 christos return FALSE;
299 1.1 christos
300 1.1 christos if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
301 1.1 christos goto FAIL;
302 1.1 christos
303 1.1 christos /* Parse the note. */
304 1.1 christos if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
305 1.1 christos goto FAIL;
306 1.1 christos
307 1.1 christos /* Check the architecture in the note against the architecture of the bfd. */
308 1.1 christos switch (bfd_get_mach (abfd))
309 1.1 christos {
310 1.1 christos default:
311 1.1 christos case bfd_mach_arm_unknown: expected = "unknown"; break;
312 1.1 christos case bfd_mach_arm_2: expected = "armv2"; break;
313 1.1 christos case bfd_mach_arm_2a: expected = "armv2a"; break;
314 1.1 christos case bfd_mach_arm_3: expected = "armv3"; break;
315 1.1 christos case bfd_mach_arm_3M: expected = "armv3M"; break;
316 1.1 christos case bfd_mach_arm_4: expected = "armv4"; break;
317 1.1 christos case bfd_mach_arm_4T: expected = "armv4t"; break;
318 1.1 christos case bfd_mach_arm_5: expected = "armv5"; break;
319 1.1 christos case bfd_mach_arm_5T: expected = "armv5t"; break;
320 1.1 christos case bfd_mach_arm_5TE: expected = "armv5te"; break;
321 1.1 christos case bfd_mach_arm_XScale: expected = "XScale"; break;
322 1.1 christos case bfd_mach_arm_ep9312: expected = "ep9312"; break;
323 1.1 christos case bfd_mach_arm_iWMMXt: expected = "iWMMXt"; break;
324 1.1 christos case bfd_mach_arm_iWMMXt2: expected = "iWMMXt2"; break;
325 1.1 christos }
326 1.1 christos
327 1.1 christos if (strcmp (arch_string, expected) != 0)
328 1.1 christos {
329 1.1 christos strcpy ((char *) buffer + (offsetof (arm_Note, name)
330 1.1 christos + ((strlen (NOTE_ARCH_STRING) + 3) & ~3)),
331 1.1 christos expected);
332 1.1 christos
333 1.1 christos if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
334 1.1 christos (file_ptr) 0, buffer_size))
335 1.1 christos {
336 1.7 christos _bfd_error_handler
337 1.7 christos /* xgettext: c-format */
338 1.7 christos (_("warning: unable to update contents of %s section in %B"),
339 1.7 christos note_section, abfd);
340 1.1 christos goto FAIL;
341 1.1 christos }
342 1.1 christos }
343 1.1 christos
344 1.1 christos free (buffer);
345 1.1 christos return TRUE;
346 1.1 christos
347 1.1 christos FAIL:
348 1.1 christos if (buffer != NULL)
349 1.1 christos free (buffer);
350 1.1 christos return FALSE;
351 1.1 christos }
352 1.1 christos
353 1.1 christos
354 1.1 christos static struct
355 1.1 christos {
356 1.1 christos const char * string;
357 1.1 christos unsigned int mach;
358 1.1 christos }
359 1.1 christos architectures[] =
360 1.1 christos {
361 1.1 christos { "armv2", bfd_mach_arm_2 },
362 1.1 christos { "armv2a", bfd_mach_arm_2a },
363 1.1 christos { "armv3", bfd_mach_arm_3 },
364 1.1 christos { "armv3M", bfd_mach_arm_3M },
365 1.1 christos { "armv4", bfd_mach_arm_4 },
366 1.1 christos { "armv4t", bfd_mach_arm_4T },
367 1.1 christos { "armv5", bfd_mach_arm_5 },
368 1.1 christos { "armv5t", bfd_mach_arm_5T },
369 1.1 christos { "armv5te", bfd_mach_arm_5TE },
370 1.1 christos { "XScale", bfd_mach_arm_XScale },
371 1.1 christos { "ep9312", bfd_mach_arm_ep9312 },
372 1.1 christos { "iWMMXt", bfd_mach_arm_iWMMXt },
373 1.6 christos { "iWMMXt2", bfd_mach_arm_iWMMXt2 },
374 1.6 christos { "arm_any", bfd_mach_arm_unknown }
375 1.1 christos };
376 1.1 christos
377 1.1 christos /* Extract the machine number stored in a note section. */
378 1.1 christos unsigned int
379 1.1 christos bfd_arm_get_mach_from_notes (bfd *abfd, const char *note_section)
380 1.1 christos {
381 1.1 christos asection * arm_arch_section;
382 1.1 christos bfd_size_type buffer_size;
383 1.1 christos bfd_byte * buffer;
384 1.1 christos char * arch_string;
385 1.1 christos int i;
386 1.1 christos
387 1.1 christos /* Look for a note section. If one is present check the architecture
388 1.1 christos string encoded in it, and set it to the current architecture if it is
389 1.1 christos different. */
390 1.1 christos arm_arch_section = bfd_get_section_by_name (abfd, note_section);
391 1.1 christos
392 1.1 christos if (arm_arch_section == NULL)
393 1.1 christos return bfd_mach_arm_unknown;
394 1.1 christos
395 1.1 christos buffer_size = arm_arch_section->size;
396 1.1 christos if (buffer_size == 0)
397 1.1 christos return bfd_mach_arm_unknown;
398 1.1 christos
399 1.1 christos if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
400 1.1 christos goto FAIL;
401 1.1 christos
402 1.1 christos /* Parse the note. */
403 1.1 christos if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
404 1.1 christos goto FAIL;
405 1.1 christos
406 1.1 christos /* Interpret the architecture string. */
407 1.1 christos for (i = ARRAY_SIZE (architectures); i--;)
408 1.1 christos if (strcmp (arch_string, architectures[i].string) == 0)
409 1.1 christos {
410 1.1 christos free (buffer);
411 1.1 christos return architectures[i].mach;
412 1.1 christos }
413 1.1 christos
414 1.1 christos FAIL:
415 1.1 christos if (buffer != NULL)
416 1.1 christos free (buffer);
417 1.1 christos return bfd_mach_arm_unknown;
418 1.1 christos }
419 1.1 christos
420 1.1 christos bfd_boolean
421 1.1 christos bfd_is_arm_special_symbol_name (const char * name, int type)
422 1.1 christos {
423 1.1 christos /* The ARM compiler outputs several obsolete forms. Recognize them
424 1.1 christos in addition to the standard $a, $t and $d. We are somewhat loose
425 1.1 christos in what we accept here, since the full set is not documented. */
426 1.1 christos if (!name || name[0] != '$')
427 1.1 christos return FALSE;
428 1.1 christos if (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
429 1.1 christos type &= BFD_ARM_SPECIAL_SYM_TYPE_MAP;
430 1.1 christos else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
431 1.1 christos type &= BFD_ARM_SPECIAL_SYM_TYPE_TAG;
432 1.1 christos else if (name[1] >= 'a' && name[1] <= 'z')
433 1.1 christos type &= BFD_ARM_SPECIAL_SYM_TYPE_OTHER;
434 1.1 christos else
435 1.1 christos return FALSE;
436 1.1 christos
437 1.1 christos return (type != 0 && (name[2] == 0 || name[2] == '.'));
438 1.1 christos }
439 1.1 christos
440