]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - contrib/binutils/bfd/cpu-arm.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / contrib / binutils / bfd / cpu-arm.c
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)
4
5    This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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.  */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "libiberty.h"
25
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 **));
32
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.  */
36
37 static const bfd_arch_info_type *
38 compatible (a,b)
39      const bfd_arch_info_type * a;
40      const bfd_arch_info_type * b;
41 {
42   /* If a & b are for different architecture we can do nothing.  */
43   if (a->arch != b->arch)
44       return NULL;
45
46   /* If a & b are for the same machine then all is well.  */
47   if (a->mach == b->mach)
48     return a;
49
50   /* Otherwise if either a or b is the 'default' machine
51      then it can be polymorphed into the other.  */
52   if (a->the_default)
53     return b;
54
55   if (b->the_default)
56     return a;
57
58   /* So far all newer ARM architecture cores are
59      supersets of previous cores.  */
60   if (a->mach < b->mach)
61     return b;
62   else if (a->mach > b->mach)
63     return a;
64
65   /* Never reached!  */
66   return NULL;
67 }
68
69 static struct
70 {
71   unsigned int mach;
72   char *       name;
73 }
74 processors[] =
75 {
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" }
104 };
105
106 static bfd_boolean
107 scan (info, string)
108      const struct bfd_arch_info * info;
109      const char * string;
110 {
111   int  i;
112
113   /* First test for an exact match.  */
114   if (strcasecmp (string, info->printable_name) == 0)
115     return TRUE;
116
117   /* Next check for a processor name instead of an Architecture name.  */
118   for (i = sizeof (processors) / sizeof (processors[0]); i--;)
119     {
120       if (strcasecmp (string, processors [i].name) == 0)
121         break;
122     }
123
124   if (i != -1 && info->mach == processors [i].mach)
125     return TRUE;
126
127   /* Finally check for the default architecture.  */
128   if (strcasecmp (string, "arm") == 0)
129     return info->the_default;
130
131   return FALSE;
132 }
133
134 #define N(number, print, default, next)  \
135 {  32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, scan, next }
136
137 static const bfd_arch_info_type arch_info_struct[] =
138 {
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)
151 };
152
153 const bfd_arch_info_type bfd_arm_arch =
154   N (0, "arm", TRUE, & arch_info_struct[0]);
155
156 /* Support functions used by both the COFF and ELF versions of the ARM port.  */
157
158 /* Handle the merging 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.  */
162
163 bfd_boolean
164 bfd_arm_merge_machines (ibfd, obfd)
165      bfd * ibfd;
166      bfd * obfd;
167 {
168   unsigned int in  = bfd_get_mach (ibfd);
169   unsigned int out = bfd_get_mach (obfd);
170
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);
174
175   /* If the input architecture 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);
181
182   /* If they are the same then nothing needs to be done.  */
183   else if (out == in)
184     ;
185
186   /* Otherwise the general principle that a earlier architecture can be
187      linked with a later architecture to produce a binary that will execute
188      on the later architecture.
189
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))
195     {
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);
201       return FALSE;
202     }
203   else if (out == bfd_mach_arm_ep9312
204            && (in == bfd_mach_arm_XScale || in == bfd_mach_arm_iWMMXt))
205     {
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);
211       return FALSE;
212     }
213   else if (in > out)
214     bfd_set_arch_mach (obfd, bfd_arch_arm, in);
215   /* else
216      Nothing to do.  */
217
218   return TRUE;
219 }
220
221 typedef struct
222 {
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.  */
227 } arm_Note;
228
229 static bfd_boolean
230 arm_check_note (abfd, buffer, buffer_size, expected_name, description_return)
231      bfd *           abfd;
232      char *          buffer;
233      bfd_size_type   buffer_size;
234      const char *    expected_name;
235      char **         description_return;
236 {
237   unsigned long namesz;
238   unsigned long descsz;
239   unsigned long type;
240   char *        descr;
241
242   if (buffer_size < offsetof (arm_Note, name))
243     return FALSE;
244
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);
251
252   /* Check for buffer overflow.  */
253   if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
254     return FALSE;
255
256   if (expected_name == NULL)
257     {
258       if (namesz != 0)
259         return FALSE;
260     }
261   else
262     { 
263       if (namesz != ((strlen (expected_name) + 1 + 3) & ~3))
264         return FALSE;
265       
266       if (strcmp (descr, expected_name) != 0)
267         return FALSE;
268
269       descr += (namesz + 3) & ~3;
270     }
271
272   /* FIXME: We should probably check the type as well.  */
273
274   if (description_return != NULL)
275     * description_return = descr;
276
277   return TRUE;
278 }
279
280 #define NOTE_ARCH_STRING        "arch: "
281
282 bfd_boolean
283 bfd_arm_update_notes (abfd, note_section)
284      bfd * abfd;
285      const char * note_section;
286 {
287   asection *     arm_arch_section;
288   bfd_size_type  buffer_size;
289   char *         buffer;
290   char *         arch_string;
291   char *         expected;
292
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
295      different.  */
296   arm_arch_section = bfd_get_section_by_name (abfd, note_section);
297
298   if (arm_arch_section == NULL)
299     return TRUE;
300
301   buffer_size = arm_arch_section->_raw_size;
302   if (buffer_size == 0)
303     return FALSE;
304
305   buffer = bfd_malloc (buffer_size);
306   if (buffer == NULL)
307     return FALSE;
308   
309   if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
310                                   (file_ptr) 0, buffer_size))
311     goto FAIL;
312
313   /* Parse the note.  */
314   if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
315     goto FAIL;
316
317   /* Check the architecture in the note against the architecture of the bfd.  */
318   switch (bfd_get_mach (abfd))
319     {
320     default:
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;
334     }
335
336   if (strcmp (arch_string, expected) != 0)
337     {
338       strcpy (buffer + offsetof (arm_Note, name) + ((strlen (NOTE_ARCH_STRING) + 3) & ~3), expected);
339
340       if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
341                                       (file_ptr) 0, buffer_size))
342         {
343           (*_bfd_error_handler)
344             (_("warning: unable to update contents of %s section in %s"),
345              note_section, bfd_get_filename (abfd));
346           goto FAIL;
347         }
348     }
349
350   free (buffer);
351   return TRUE;
352
353  FAIL:
354   free (buffer);
355   return FALSE;
356 }
357
358
359 static struct
360 {
361   const char * string;
362   unsigned int mach;
363 }
364 architectures[] =
365 {
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 }
378 };
379
380 /* Extract the machine number stored in a note section.  */
381 unsigned int
382 bfd_arm_get_mach_from_notes (abfd, note_section)
383      bfd * abfd;
384      const char * note_section;
385 {
386   asection *     arm_arch_section;
387   bfd_size_type  buffer_size;
388   char *         buffer;
389   char *         arch_string;
390   int            i;
391
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
394      different.  */
395   arm_arch_section = bfd_get_section_by_name (abfd, note_section);
396
397   if (arm_arch_section == NULL)
398     return bfd_mach_arm_unknown;
399
400   buffer_size = arm_arch_section->_raw_size;
401   if (buffer_size == 0)
402     return bfd_mach_arm_unknown;
403
404   buffer = bfd_malloc (buffer_size);
405   if (buffer == NULL)
406     return bfd_mach_arm_unknown;
407   
408   if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
409                                   (file_ptr) 0, buffer_size))
410     goto FAIL;
411
412   /* Parse the note.  */
413   if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
414     goto FAIL;
415
416   /* Interpret the architecture string.  */
417   for (i = ARRAY_SIZE (architectures); i--;)
418     if (strcmp (arch_string, architectures[i].string) == 0)
419       {
420         free (buffer);
421         return architectures[i].mach;
422       }
423
424  FAIL:
425   free (buffer);
426   return bfd_mach_arm_unknown;
427 }