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