1
/* BFD support for the ARM processor
2
Copyright 1994, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
3
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5
This file is part of BFD, the Binary File Descriptor library.
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24
#include "libiberty.h"
26
static const bfd_arch_info_type * compatible
27
PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
28
static bfd_boolean scan
29
PARAMS ((const struct bfd_arch_info *, const char *));
30
static bfd_boolean arm_check_note
31
PARAMS ((bfd *, char *, bfd_size_type, const char *, char **));
33
/* This routine is provided two arch_infos and works out which ARM
34
machine which would be compatible with both and returns a pointer
35
to its info structure. */
37
static const bfd_arch_info_type *
39
const bfd_arch_info_type * a;
40
const bfd_arch_info_type * b;
42
/* If a & b are for different architecture we can do nothing. */
43
if (a->arch != b->arch)
46
/* If a & b are for the same machine then all is well. */
47
if (a->mach == b->mach)
50
/* Otherwise if either a or b is the 'default' machine
51
then it can be polymorphed into the other. */
58
/* So far all newer ARM architecture cores are
59
supersets of previous cores. */
60
if (a->mach < b->mach)
62
else if (a->mach > b->mach)
76
{ bfd_mach_arm_2, "arm2" },
77
{ bfd_mach_arm_2a, "arm250" },
78
{ bfd_mach_arm_2a, "arm3" },
79
{ bfd_mach_arm_3, "arm6" },
80
{ bfd_mach_arm_3, "arm60" },
81
{ bfd_mach_arm_3, "arm600" },
82
{ bfd_mach_arm_3, "arm610" },
83
{ bfd_mach_arm_3, "arm7" },
84
{ bfd_mach_arm_3, "arm710" },
85
{ bfd_mach_arm_3, "arm7500" },
86
{ bfd_mach_arm_3, "arm7d" },
87
{ bfd_mach_arm_3, "arm7di" },
88
{ bfd_mach_arm_3M, "arm7dm" },
89
{ bfd_mach_arm_3M, "arm7dmi" },
90
{ bfd_mach_arm_4T, "arm7tdmi" },
91
{ bfd_mach_arm_4, "arm8" },
92
{ bfd_mach_arm_4, "arm810" },
93
{ bfd_mach_arm_4, "arm9" },
94
{ bfd_mach_arm_4, "arm920" },
95
{ bfd_mach_arm_4T, "arm920t" },
96
{ bfd_mach_arm_4T, "arm9tdmi" },
97
{ bfd_mach_arm_4, "sa1" },
98
{ bfd_mach_arm_4, "strongarm"},
99
{ bfd_mach_arm_4, "strongarm110" },
100
{ bfd_mach_arm_4, "strongarm1100" },
101
{ bfd_mach_arm_XScale, "xscale" },
102
{ bfd_mach_arm_ep9312, "ep9312" },
103
{ bfd_mach_arm_iWMMXt, "iwmmxt" }
108
const struct bfd_arch_info * info;
113
/* First test for an exact match. */
114
if (strcasecmp (string, info->printable_name) == 0)
117
/* Next check for a processor name instead of an Architecture name. */
118
for (i = sizeof (processors) / sizeof (processors[0]); i--;)
120
if (strcasecmp (string, processors [i].name) == 0)
124
if (i != -1 && info->mach == processors [i].mach)
127
/* Finally check for the default architecture. */
128
if (strcasecmp (string, "arm") == 0)
129
return info->the_default;
134
#define N(number, print, default, next) \
135
{ 32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, scan, next }
137
static const bfd_arch_info_type arch_info_struct[] =
139
N (bfd_mach_arm_2, "armv2", FALSE, & arch_info_struct[1]),
140
N (bfd_mach_arm_2a, "armv2a", FALSE, & arch_info_struct[2]),
141
N (bfd_mach_arm_3, "armv3", FALSE, & arch_info_struct[3]),
142
N (bfd_mach_arm_3M, "armv3m", FALSE, & arch_info_struct[4]),
143
N (bfd_mach_arm_4, "armv4", FALSE, & arch_info_struct[5]),
144
N (bfd_mach_arm_4T, "armv4t", FALSE, & arch_info_struct[6]),
145
N (bfd_mach_arm_5, "armv5", FALSE, & arch_info_struct[7]),
146
N (bfd_mach_arm_5T, "armv5t", FALSE, & arch_info_struct[8]),
147
N (bfd_mach_arm_5TE, "armv5te", FALSE, & arch_info_struct[9]),
148
N (bfd_mach_arm_XScale, "xscale", FALSE, & arch_info_struct[10]),
149
N (bfd_mach_arm_ep9312, "ep9312", FALSE, & arch_info_struct[11]),
150
N (bfd_mach_arm_iWMMXt,"iwmmxt", FALSE, NULL)
153
const bfd_arch_info_type bfd_arm_arch =
154
N (0, "arm", TRUE, & arch_info_struct[0]);
156
/* Support functions used by both the COFF and ELF versions of the ARM port. */
158
/* Handle the mergeing of the 'machine' settings of input file IBFD
159
and an output file OBFD. These values actually represent the
160
different possible ARM architecture variants.
161
Returns TRUE if they were merged successfully or FALSE otherwise. */
164
bfd_arm_merge_machines (ibfd, obfd)
168
unsigned int in = bfd_get_mach (ibfd);
169
unsigned int out = bfd_get_mach (obfd);
171
/* If the output architecture is unknown, we now have a value to set. */
172
if (out == bfd_mach_arm_unknown)
173
bfd_set_arch_mach (obfd, bfd_arch_arm, in);
175
/* If the input architecure is unknown,
176
then so must be the output architecture. */
177
else if (in == bfd_mach_arm_unknown)
178
/* FIXME: We ought to have some way to
179
override this on the command line. */
180
bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);
182
/* If they are the same then nothing needs to be done. */
186
/* Otherwise the general principle that a earlier architecture can be
187
linked with a later architecure to produce a binary that will execute
188
on the later architecture.
190
We fail however if we attempt to link a Cirrus EP9312 binary with an
191
Intel XScale binary, since these architecture have co-processors which
192
will not both be present on the same physical hardware. */
193
else if (in == bfd_mach_arm_ep9312
194
&& (out == bfd_mach_arm_XScale || out == bfd_mach_arm_iWMMXt))
196
_bfd_error_handler (_("\
197
ERROR: %s is compiled for the EP9312, whereas %s is compiled for XScale"),
198
bfd_archive_filename (ibfd),
199
bfd_get_filename (obfd));
200
bfd_set_error (bfd_error_wrong_format);
203
else if (out == bfd_mach_arm_ep9312
204
&& (in == bfd_mach_arm_XScale || in == bfd_mach_arm_iWMMXt))
206
_bfd_error_handler (_("\
207
ERROR: %s is compiled for the EP9312, whereas %s is compiled for XScale"),
208
bfd_archive_filename (obfd),
209
bfd_get_filename (ibfd));
210
bfd_set_error (bfd_error_wrong_format);
214
bfd_set_arch_mach (obfd, bfd_arch_arm, in);
223
unsigned char namesz[4]; /* Size of entry's owner string. */
224
unsigned char descsz[4]; /* Size of the note descriptor. */
225
unsigned char type[4]; /* Interpretation of the descriptor. */
226
char name[1]; /* Start of the name+desc data. */
230
arm_check_note (abfd, buffer, buffer_size, expected_name, description_return)
233
bfd_size_type buffer_size;
234
const char * expected_name;
235
char ** description_return;
237
unsigned long namesz;
238
unsigned long descsz;
242
if (buffer_size < offsetof (arm_Note, name))
245
/* We have to extract the values this way to allow for a
246
host whose endian-ness is different from the target. */
247
namesz = bfd_get_32 (abfd, buffer);
248
descsz = bfd_get_32 (abfd, buffer + offsetof (arm_Note, descsz));
249
type = bfd_get_32 (abfd, buffer + offsetof (arm_Note, type));
250
descr = buffer + offsetof (arm_Note, name);
252
/* Check for buffer overflow. */
253
if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
256
if (expected_name == NULL)
263
if (namesz != ((strlen (expected_name) + 1 + 3) & ~3))
266
if (strcmp (descr, expected_name) != 0)
269
descr += (namesz + 3) & ~3;
272
/* FIXME: We should probably check the type as well. */
274
if (description_return != NULL)
275
* description_return = descr;
280
#define NOTE_ARCH_STRING "arch: "
283
bfd_arm_update_notes (abfd, note_section)
285
const char * note_section;
287
asection * arm_arch_section;
288
bfd_size_type buffer_size;
293
/* Look for a note section. If one is present check the architecture
294
string encoded in it, and set it to the current architecture if it is
296
arm_arch_section = bfd_get_section_by_name (abfd, note_section);
298
if (arm_arch_section == NULL)
301
buffer_size = arm_arch_section->_raw_size;
302
if (buffer_size == 0)
305
buffer = bfd_malloc (buffer_size);
309
if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
310
(file_ptr) 0, buffer_size))
313
/* Parse the note. */
314
if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
317
/* Check the architecture in the note against the architecture of the bfd. */
318
switch (bfd_get_mach (abfd))
321
case bfd_mach_arm_unknown: expected = "unknown"; break;
322
case bfd_mach_arm_2: expected = "armv2"; break;
323
case bfd_mach_arm_2a: expected = "armv2a"; break;
324
case bfd_mach_arm_3: expected = "armv3"; break;
325
case bfd_mach_arm_3M: expected = "armv3M"; break;
326
case bfd_mach_arm_4: expected = "armv4"; break;
327
case bfd_mach_arm_4T: expected = "armv4t"; break;
328
case bfd_mach_arm_5: expected = "armv5"; break;
329
case bfd_mach_arm_5T: expected = "armv5t"; break;
330
case bfd_mach_arm_5TE: expected = "armv5te"; break;
331
case bfd_mach_arm_XScale: expected = "XScale"; break;
332
case bfd_mach_arm_ep9312: expected = "ep9312"; break;
333
case bfd_mach_arm_iWMMXt: expected = "iWMMXt"; break;
336
if (strcmp (arch_string, expected) != 0)
338
strcpy (buffer + offsetof (arm_Note, name) + ((strlen (NOTE_ARCH_STRING) + 3) & ~3), expected);
340
if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
341
(file_ptr) 0, buffer_size))
343
(*_bfd_error_handler)
344
(_("warning: unable to update contents of %s section in %s"),
345
note_section, bfd_get_filename (abfd));
366
{ "armv2", bfd_mach_arm_2 },
367
{ "armv2a", bfd_mach_arm_2a },
368
{ "armv3", bfd_mach_arm_3 },
369
{ "armv3M", bfd_mach_arm_3M },
370
{ "armv4", bfd_mach_arm_4 },
371
{ "armv4t", bfd_mach_arm_4T },
372
{ "armv5", bfd_mach_arm_5 },
373
{ "armv5t", bfd_mach_arm_5T },
374
{ "armv5te", bfd_mach_arm_5TE },
375
{ "XScale", bfd_mach_arm_XScale },
376
{ "ep9312", bfd_mach_arm_ep9312 },
377
{ "iWMMXt", bfd_mach_arm_iWMMXt }
380
/* Extract the machine number stored in a note section. */
382
bfd_arm_get_mach_from_notes (abfd, note_section)
384
const char * note_section;
386
asection * arm_arch_section;
387
bfd_size_type buffer_size;
392
/* Look for a note section. If one is present check the architecture
393
string encoded in it, and set it to the current architecture if it is
395
arm_arch_section = bfd_get_section_by_name (abfd, note_section);
397
if (arm_arch_section == NULL)
398
return bfd_mach_arm_unknown;
400
buffer_size = arm_arch_section->_raw_size;
401
if (buffer_size == 0)
402
return bfd_mach_arm_unknown;
404
buffer = bfd_malloc (buffer_size);
406
return bfd_mach_arm_unknown;
408
if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
409
(file_ptr) 0, buffer_size))
412
/* Parse the note. */
413
if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
416
/* Interpret the architecture string. */
417
for (i = ARRAY_SIZE (architectures); i--;)
418
if (strcmp (arch_string, architectures[i].string) == 0)
421
return architectures[i].mach;
426
return bfd_mach_arm_unknown;