1 /* BFD library support routines for architectures.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Hacked by John Gilmore of Cygnus Support.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
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.
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.
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
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
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 *}
89 static char *prt_num_mach ();
90 static boolean
scan_num_mach ();
91 static char *prt_960_mach ();
92 static boolean
scan_960_mach ();
95 enum bfd_architecture arch
;
97 char *(*mach_print
)();
98 boolean (*mach_scan
)();
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
},
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 bfd_printable_arch_mach.
126 *; PROTO(CONST char *,bfd_printable_arch_mach,
127 (enum bfd_architecture arch, unsigned long machine));
131 DEFUN(bfd_printable_arch_mach
,(arch
, machine
),
132 enum bfd_architecture arch AND
133 unsigned long machine
)
135 struct arch_print
*ap
;
137 for (ap
= arch_print
; ap
->astr
; ap
++) {
138 if (ap
->arch
== arch
) {
141 return (*ap
->mach_print
)(ap
, machine
);
148 prt_num_mach (ap
, machine
)
149 struct arch_print
*ap
;
150 unsigned long machine
;
152 static char result
[20];
154 sprintf(result
, "%s:%ld", ap
->astr
, (long) machine
);
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 *));
166 DEFUN(bfd_scan_arch_mach
,(string
, archp
, machinep
),
167 CONST
char *string AND
168 enum bfd_architecture
*archp AND
169 unsigned long *machinep
)
171 struct arch_print
*ap
;
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])
178 len
= strlen (ap
->astr
);
179 if (!strncmp (ap
->astr
, string
, len
)) {
180 /* We found the architecture, now see about the machine type */
183 if (string
[len
] != '\0') {
184 if (ap
->mach_scan (string
+len
, ap
, archp
, machinep
, 1))
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))
203 scan_num_mach (string
, ap
, archp
, machinep
, archspec
)
205 struct arch_print
*ap
;
206 enum bfd_architecture
*archp
;
207 unsigned long *machinep
;
210 enum bfd_architecture arch
;
211 unsigned long machine
;
216 /* Architecture already specified, now go for machine type. */
217 if (string
[0] != ':')
219 /* We'll take any valid number that occupies the entire string */
220 if (1 != sscanf (string
+1, "%lu%c", &machine
, &achar
))
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
))
236 case 68050: arch
= bfd_arch_m68k
; break;
237 case 68000: arch
= bfd_arch_m68k
; machine
= 0; break;
240 case 960: arch
= bfd_arch_i960
; machine
= 0; break;
243 case 80386: arch
= bfd_arch_i386
; machine
= 0; break;
244 case 486: arch
= bfd_arch_i386
; break;
246 case 29000: arch
= bfd_arch_a29k
; machine
= 0; break;
254 case 32532: arch
= bfd_arch_ns32k
; break;
255 case 32000: arch
= bfd_arch_ns32k
; machine
= 0; break;
258 case 80860: arch
= bfd_arch_i860
; machine
= 0; break;
260 default: return false;
271 /* Intel 960 machine variants. */
274 prt_960_mach (ap
, machine
)
275 struct arch_print
*ap
;
276 unsigned long machine
;
278 static char result
[20];
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;
289 return prt_num_mach (ap
, machine
);
291 sprintf (result
, "%s:%s", ap
->astr
, str
);
296 scan_960_mach (string
, ap
, archp
, machinep
, archspec
)
298 struct arch_print
*ap
;
299 enum bfd_architecture
*archp
;
300 unsigned long *machinep
;
303 unsigned long machine
;
307 if (string
[0] != ':')
310 if (string
[0] == '\0')
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 */
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
;
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.
350 This routine returns @code{true} if the bfds are of compatible type,
351 otherwise @code{false}.
352 *; PROTO(boolean, bfd_arch_compatible,
355 enum bfd_architecture *archp,
356 unsigned long *machinep));
360 DEFUN(bfd_arch_compatible
,(abfd
, bbfd
, archp
, machinep
),
363 enum bfd_architecture
*archp AND
364 unsigned long *machinep
)
366 enum bfd_architecture archa
, archb
;
367 unsigned long macha
, machb
;
370 archa
= bfd_get_architecture (abfd
);
371 archb
= bfd_get_architecture (bbfd
);
372 macha
= bfd_get_machine (abfd
);
373 machb
= bfd_get_machine (bbfd
);
375 if (archb
== bfd_arch_unknown
)
377 else if (archa
== bfd_arch_unknown
)
379 else if (archa
!= archb
)
380 return false; /* Not compatible */
382 /* Architectures are the same. Check machine types. */
383 if (macha
== machb
) /* Same machine type */
385 else if (machb
== 0) /* B is default */
387 else if (macha
== 0) /* A is default */
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). */
395 /* The i960 has two distinct subspecies which may not interbreed:
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
) {
408 else if (machb
== bfd_mach_i960_ca
) {
409 if (macha
!= bfd_mach_i960_ca
&&
410 macha
!= bfd_mach_i960_core
) {
416 /* This must be from the bottom row, so take the higest */
417 pick_a
= (macha
> machb
);
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. */
428 pick_a
= (macha
> machb
);
431 /* By default, pick first file's type, for lack of something better. */
437 /* Set result based on our pick */
451 /*proto* bfd_set_arch_mach
454 #define bfd_set_arch_mach(abfd, arch, mach) \
455 BFD_SEND (abfd, _bfd_set_arch_mach,\