Mon Aug 19 13:48:22 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
[binutils-gdb.git] / bfd / archures.c
1 /* BFD library support routines for architectures.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Hacked by John Gilmore of Cygnus Support.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 /*doc*
22 @section Architectures
23 BFD's idea of an architecture is implimented in @code{archures.c}. BFD
24 keeps two atoms in a BFD describing the architecture of the data
25 attatched to the BFD, the @code{enum bfd_architecture arch} field and
26 the @code{unsigned long machine} field.
27 */
28
29 /*proto* bfd_architecture
30 This enum gives the object file's CPU
31 architecture, in a global sense. E.g. what processor family does it
32 belong to? There is another field, which indicates what processor
33 within the family is in use. The machine gives a number which
34 distingushes different versions of the architecture, containing for
35 example 2 and 3 for Intel i960 KA and i960 KB, and 68020 and 68030 for
36 Motorola 68020 and 68030.
37
38 *+
39 enum bfd_architecture
40 {
41 bfd_arch_unknown, {* File arch not known *}
42 bfd_arch_obscure, {* Arch known, not one of these *}
43 bfd_arch_m68k, {* Motorola 68xxx *}
44 bfd_arch_vax, {* DEC Vax *}
45 bfd_arch_i960, {* Intel 960 *}
46 {* The order of the following is important.
47 lower number indicates a machine type that
48 only accepts a subset of the instructions
49 available to machines with higher numbers.
50 The exception is the "ca", which is
51 incompatible with all other machines except
52 "core". *}
53
54 #define bfd_mach_i960_core 1
55 #define bfd_mach_i960_ka_sa 2
56 #define bfd_mach_i960_kb_sb 3
57 #define bfd_mach_i960_mc 4
58 #define bfd_mach_i960_xa 5
59 #define bfd_mach_i960_ca 6
60
61 bfd_arch_a29k, {* AMD 29000 *}
62 bfd_arch_sparc, {* SPARC *}
63 bfd_arch_mips, {* MIPS Rxxxx *}
64 bfd_arch_i386, {* Intel 386 *}
65 bfd_arch_ns32k, {* National Semiconductor 32xxx *}
66 bfd_arch_tahoe, {* CCI/Harris Tahoe *}
67 bfd_arch_i860, {* Intel 860 *}
68 bfd_arch_romp, {* IBM ROMP RS/6000 *}
69 bfd_arch_alliant, {* Alliant *}
70 bfd_arch_convex, {* Convex *}
71 bfd_arch_m88k, {* Motorola 88xxx *}
72 bfd_arch_pyramid, {* Pyramid Technology *}
73 bfd_arch_h8_300, {* Hitachi H8/300 *}
74 bfd_arch_last
75 };
76 *-
77
78 stuff
79
80 */
81
82
83
84 /* $Id$ */
85
86 #include <sysdep.h>
87 #include "bfd.h"
88
89 static char *prt_num_mach ();
90 static boolean scan_num_mach ();
91 static char *prt_960_mach ();
92 static boolean scan_960_mach ();
93
94 struct arch_print {
95 enum bfd_architecture arch;
96 char *astr;
97 char *(*mach_print)();
98 boolean (*mach_scan)();
99 } arch_print[] = {
100
101 {bfd_arch_unknown, "unknown", prt_num_mach, scan_num_mach},
102 {bfd_arch_obscure, "obscure", prt_num_mach, scan_num_mach},
103 {bfd_arch_m68k, "m68k", prt_num_mach, scan_num_mach},
104 {bfd_arch_vax, "vax", prt_num_mach, scan_num_mach},
105 {bfd_arch_i960, "i960", prt_960_mach, scan_960_mach},
106 {bfd_arch_a29k, "a29k", prt_num_mach, scan_num_mach},
107 {bfd_arch_sparc, "sparc", prt_num_mach, scan_num_mach},
108 {bfd_arch_mips, "mips", prt_num_mach, scan_num_mach},
109 {bfd_arch_i386, "i386", prt_num_mach, scan_num_mach},
110 {bfd_arch_ns32k, "ns32k", prt_num_mach, scan_num_mach},
111 {bfd_arch_tahoe, "tahoe", prt_num_mach, scan_num_mach},
112 {bfd_arch_i860, "i860", prt_num_mach, scan_num_mach},
113 {bfd_arch_romp, "romp", prt_num_mach, scan_num_mach},
114 {bfd_arch_alliant, "alliant", prt_num_mach, scan_num_mach},
115 {bfd_arch_convex, "convex", prt_num_mach, scan_num_mach},
116 {bfd_arch_m88k, "m88k", prt_num_mach, scan_num_mach},
117 {bfd_arch_pyramid, "pyramid", prt_num_mach, scan_num_mach},
118 {bfd_arch_h8_300, "H8/300", prt_num_mach, scan_num_mach},
119 {bfd_arch_unknown, (char *)0, prt_num_mach, scan_num_mach},
120 };
121
122 /*proto* bfd_prinable_arch_mach
123 Return a printable string representing the architecture and machine
124 type. The result is only good until the next call to
125 @code{bfd_printable_arch_mach}.
126 *; PROTO(CONST char *,bfd_printable_arch_mach,
127 (enum bfd_architecture arch, unsigned long machine));
128 */
129
130 CONST char *
131 DEFUN(bfd_printable_arch_mach,(arch, machine),
132 enum bfd_architecture arch AND
133 unsigned long machine)
134 {
135 struct arch_print *ap;
136
137 for (ap = arch_print; ap->astr; ap++) {
138 if (ap->arch == arch) {
139 if (machine == 0)
140 return ap->astr;
141 return (*ap->mach_print)(ap, machine);
142 }
143 }
144 return "UNKNOWN!";
145 }
146
147 static char *
148 prt_num_mach (ap, machine)
149 struct arch_print *ap;
150 unsigned long machine;
151 {
152 static char result[20];
153
154 sprintf(result, "%s:%ld", ap->astr, (long) machine);
155 return result;
156 }
157
158 /*proto*
159 *i bfd_scan_arch_mach
160 Scan a string and attempt to turn it into an archive and machine type combination.
161 *; PROTO(boolean, bfd_scan_arch_mach,
162 (CONST char *, enum bfd_architecture *, unsigned long *));
163 */
164
165 boolean
166 DEFUN(bfd_scan_arch_mach,(string, archp, machinep),
167 CONST char *string AND
168 enum bfd_architecture *archp AND
169 unsigned long *machinep)
170 {
171 struct arch_print *ap;
172 int len;
173
174 /* First look for an architecture, possibly followed by machtype. */
175 for (ap = arch_print; ap->astr; ap++) {
176 if (ap->astr[0] != string[0])
177 continue;
178 len = strlen (ap->astr);
179 if (!strncmp (ap->astr, string, len)) {
180 /* We found the architecture, now see about the machine type */
181 if (archp)
182 *archp = ap->arch;
183 if (string[len] != '\0') {
184 if (ap->mach_scan (string+len, ap, archp, machinep, 1))
185 return true;
186 }
187 if (machinep)
188 *machinep = 0;
189 return true;
190 }
191 }
192
193 /* Couldn't find an architecture -- try for just a machine type */
194 for (ap = arch_print; ap->astr; ap++) {
195 if (ap->mach_scan (string, ap, archp, machinep, 0))
196 return true;
197 }
198
199 return false;
200 }
201
202 static boolean
203 scan_num_mach (string, ap, archp, machinep, archspec)
204 char *string;
205 struct arch_print *ap;
206 enum bfd_architecture *archp;
207 unsigned long *machinep;
208 int archspec;
209 {
210 enum bfd_architecture arch;
211 unsigned long machine;
212 char achar;
213
214 if (archspec) {
215
216 /* Architecture already specified, now go for machine type. */
217 if (string[0] != ':')
218 return false;
219 /* We'll take any valid number that occupies the entire string */
220 if (1 != sscanf (string+1, "%lu%c", &machine, &achar))
221 return false;
222 arch = ap->arch;
223
224 } else {
225
226 /* We couldn't identify an architecture prefix. Perhaps the entire
227 thing is a machine type. Be a lot picker. */
228 if (1 != sscanf (string, "%lu%c", &machine, &achar))
229 return false;
230 switch (machine) {
231 case 68010:
232 case 68020:
233 case 68030:
234 case 68040:
235 case 68332:
236 case 68050: arch = bfd_arch_m68k; break;
237 case 68000: arch = bfd_arch_m68k; machine = 0; break;
238
239 case 80960:
240 case 960: arch = bfd_arch_i960; machine = 0; break;
241
242 case 386:
243 case 80386: arch = bfd_arch_i386; machine = 0; break;
244 case 486: arch = bfd_arch_i386; break;
245
246 case 29000: arch = bfd_arch_a29k; machine = 0; break;
247
248 case 32016:
249 case 32032:
250 case 32132:
251 case 32232:
252 case 32332:
253 case 32432:
254 case 32532: arch = bfd_arch_ns32k; break;
255 case 32000: arch = bfd_arch_ns32k; machine = 0; break;
256
257 case 860:
258 case 80860: arch = bfd_arch_i860; machine = 0; break;
259
260 default: return false;
261 }
262 }
263
264 if (archp)
265 *archp = arch;
266 if (machinep)
267 *machinep = machine;
268 return true;
269 }
270 \f
271 /* Intel 960 machine variants. */
272
273 static char *
274 prt_960_mach (ap, machine)
275 struct arch_print *ap;
276 unsigned long machine;
277 {
278 static char result[20];
279 char *str;
280
281 switch (machine) {
282 case bfd_mach_i960_core: str = "core"; break;
283 case bfd_mach_i960_kb_sb: str = "kb"; break;
284 case bfd_mach_i960_mc: str = "mc"; break;
285 case bfd_mach_i960_xa: str = "xa"; break;
286 case bfd_mach_i960_ca: str = "ca"; break;
287 case bfd_mach_i960_ka_sa: str = "ka"; break;
288 default:
289 return prt_num_mach (ap, machine);
290 }
291 sprintf (result, "%s:%s", ap->astr, str);
292 return result;
293 }
294
295 static boolean
296 scan_960_mach (string, ap, archp, machinep, archspec)
297 char *string;
298 struct arch_print *ap;
299 enum bfd_architecture *archp;
300 unsigned long *machinep;
301 int archspec;
302 {
303 unsigned long machine;
304
305 if (!archspec)
306 return false;
307 if (string[0] != ':')
308 return false;
309 string++;
310 if (string[0] == '\0')
311 return false;
312 if (string[0] == 'c' && string[1] == 'o' && string[2] == 'r' &&
313 string[3] == 'e' && string[4] == '\0')
314 machine = bfd_mach_i960_core;
315 else if (string[1] == '\0' || string[2] != '\0') /* rest are 2-char */
316 return false;
317 else if (string[0] == 'k' && string[1] == 'b')
318 machine = bfd_mach_i960_kb_sb;
319 else if (string[0] == 's' && string[1] == 'b')
320 machine = bfd_mach_i960_kb_sb;
321 else if (string[0] == 'm' && string[1] == 'c')
322 machine = bfd_mach_i960_mc;
323 else if (string[0] == 'x' && string[1] == 'a')
324 machine = bfd_mach_i960_xa;
325 else if (string[0] == 'c' && string[1] == 'a')
326 machine = bfd_mach_i960_ca;
327 else if (string[0] == 'k' && string[1] == 'a')
328 machine = bfd_mach_i960_ka_sa;
329 else if (string[0] == 's' && string[1] == 'a')
330 machine = bfd_mach_i960_ka_sa;
331 else
332 return false;
333
334 if (archp)
335 *archp = ap->arch;
336 if (machinep)
337 *machinep = machine;
338 return true;
339 }
340
341
342 \f
343 /*proto*
344 *i bfd_arch_compatible
345 This routine is used to determine whether two BFDs' architectures and machine types are
346 compatible. It calculates the lowest common denominator between the
347 two architectures and machine types implied by the BFDs and sets the
348 objects pointed at by @var{archp} and @var{machine} if non NULL.
349
350 This routine returns @code{true} if the BFDs are of compatible type,
351 otherwise @code{false}.
352 *; PROTO(boolean, bfd_arch_compatible,
353 (bfd *abfd,
354 bfd *bbfd,
355 enum bfd_architecture *archp,
356 unsigned long *machinep));
357 *-*/
358
359 boolean
360 DEFUN(bfd_arch_compatible,(abfd, bbfd, archp, machinep),
361 bfd *abfd AND
362 bfd *bbfd AND
363 enum bfd_architecture *archp AND
364 unsigned long *machinep)
365 {
366 enum bfd_architecture archa, archb;
367 unsigned long macha, machb;
368 int pick_a;
369
370 archa = bfd_get_architecture (abfd);
371 archb = bfd_get_architecture (bbfd);
372 macha = bfd_get_machine (abfd);
373 machb = bfd_get_machine (bbfd);
374
375 if (archb == bfd_arch_unknown)
376 pick_a = 1;
377 else if (archa == bfd_arch_unknown)
378 pick_a = 0;
379 else if (archa != archb)
380 return false; /* Not compatible */
381 else {
382 /* Architectures are the same. Check machine types. */
383 if (macha == machb) /* Same machine type */
384 pick_a = 1;
385 else if (machb == 0) /* B is default */
386 pick_a = 1;
387 else if (macha == 0) /* A is default */
388 pick_a = 0;
389 else switch (archa) {
390 /* If particular machine types of one architecture are not
391 compatible with each other, this is the place to put those tests
392 (returning false if incompatible). */
393
394 case bfd_arch_i960:
395 /* The i960 has two distinct subspecies which may not interbreed:
396 CORE CA
397 CORE KA KB MC
398 Any architecture on the same line is compatible, the one on
399 the right is the least restrictive. */
400 /* So, if either is a ca then the other must be a be core or ca */
401 if (macha == bfd_mach_i960_ca) {
402 if (machb != bfd_mach_i960_ca &&
403 machb != bfd_mach_i960_core) {
404 return false;
405 }
406 pick_a = 1;
407 }
408 else if (machb == bfd_mach_i960_ca) {
409 if (macha != bfd_mach_i960_ca &&
410 macha != bfd_mach_i960_core) {
411 return false;
412 }
413 pick_a = 0;
414 }
415 else {
416 /* This must be from the bottom row, so take the higest */
417 pick_a = (macha > machb);
418 }
419 break;
420
421 /* For these chips, as far as we care, "lower" numbers are included
422 by "higher" numbers, e.g. merge 68010 and 68020 into 68020,
423 386 and 486 into 486, etc. This will need to change
424 if&when we care about things like 68332. */
425 case bfd_arch_m68k:
426 case bfd_arch_ns32k:
427 case bfd_arch_i386:
428 pick_a = (macha > machb);
429 break;
430
431 /* By default, pick first file's type, for lack of something better. */
432 default:
433 pick_a = 1;
434 }
435 }
436
437 /* Set result based on our pick */
438 if (!pick_a) {
439 archa = archb;
440 macha = machb;
441 }
442 if (archp)
443 *archp = archa;
444 if (machinep)
445 *machinep = macha;
446
447 return true;
448 }
449
450
451 /*proto* bfd_set_arch_mach
452 Set atch mach
453 *+
454 #define bfd_set_arch_mach(abfd, arch, mach) \
455 BFD_SEND (abfd, _bfd_set_arch_mach,\
456 (abfd, arch, mach))
457 *-
458 */
459
460
461 foo() { }
462
463
464