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