Merge devo/bfd with GDB's bfd.
[deliverable/binutils-gdb.git] / bfd / archures.c
CommitLineData
4a81b561
DHW
1/* BFD library support routines for architectures. */
2
3/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
4
5This file is part of BFD, the Binary File Diddler.
6
7BFD is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 1, or (at your option)
10any later version.
11
12BFD is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with BFD; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/* $Id$ */
22
23#include "sysdep.h"
24#include "bfd.h"
25#include "archures.h"
26
27static char *prt_num_mach ();
28static boolean scan_num_mach ();
29static char *prt_960_mach ();
30static boolean scan_960_mach ();
31
32struct arch_print {
33 enum bfd_architecture arch;
34 char *astr;
35 char *(*mach_print)();
36 boolean (*mach_scan)();
37} arch_print[] = {
38
39 {bfd_arch_unknown, "unknown", prt_num_mach, scan_num_mach},
40 {bfd_arch_obscure, "obscure", prt_num_mach, scan_num_mach},
41 {bfd_arch_m68k, "m68k", prt_num_mach, scan_num_mach},
42 {bfd_arch_vax, "vax", prt_num_mach, scan_num_mach},
43 {bfd_arch_i960, "i960", prt_960_mach, scan_960_mach},
44 {bfd_arch_a29k, "a29k", prt_num_mach, scan_num_mach},
45 {bfd_arch_sparc, "sparc", prt_num_mach, scan_num_mach},
46 {bfd_arch_mips, "mips", prt_num_mach, scan_num_mach},
47 {bfd_arch_i386, "i386", prt_num_mach, scan_num_mach},
48 {bfd_arch_ns32k, "ns32k", prt_num_mach, scan_num_mach},
49 {bfd_arch_tahoe, "tahoe", prt_num_mach, scan_num_mach},
50 {bfd_arch_i860, "i860", prt_num_mach, scan_num_mach},
51 {bfd_arch_romp, "romp", prt_num_mach, scan_num_mach},
52 {bfd_arch_alliant, "alliant", prt_num_mach, scan_num_mach},
53 {bfd_arch_convex, "convex", prt_num_mach, scan_num_mach},
54 {bfd_arch_m88k, "m88k", prt_num_mach, scan_num_mach},
55 {bfd_arch_pyramid, "pyramid", prt_num_mach, scan_num_mach},
4cddd1c9
SC
56 {bfd_arch_h8_300, "H8/300", prt_num_mach, scan_num_mach},
57 {bfd_arch_unknown, (char *)0, prt_num_mach, scan_num_mach},
4a81b561
DHW
58};
59
60/* Return a printable string representing the architecture and machine
61 type. The result is only good until the next call to
62 bfd_printable_arch_mach. */
63
64char *
65bfd_printable_arch_mach (arch, machine)
66 enum bfd_architecture arch;
67 unsigned long machine;
68{
69 struct arch_print *ap;
70
71 for (ap = arch_print; ap->astr; ap++) {
72 if (ap->arch == arch) {
73 if (machine == 0)
74 return ap->astr;
75 return (*ap->mach_print)(ap, machine);
76 }
77 }
78 return "UNKNOWN!";
79}
80
81static char *
82prt_num_mach (ap, machine)
83 struct arch_print *ap;
84 unsigned long machine;
85{
86 static char result[20];
87
88 sprintf(result, "%s:%ld", ap->astr, (long) machine);
89 return result;
90}
91
92/* Scan a string and attempt to turn it into an archive and machine type
93 combination. */
94
95boolean
4cddd1c9
SC
96DEFUN(bfd_scan_arch_mach,(string, archp, machinep),
97 CONST char *string AND
98 enum bfd_architecture *archp AND
99 unsigned long *machinep)
4a81b561
DHW
100{
101 struct arch_print *ap;
102 int len;
103
104 /* First look for an architecture, possibly followed by machtype. */
105 for (ap = arch_print; ap->astr; ap++) {
106 if (ap->astr[0] != string[0])
107 continue;
108 len = strlen (ap->astr);
109 if (!strncmp (ap->astr, string, len)) {
110 /* We found the architecture, now see about the machine type */
111 if (archp)
112 *archp = ap->arch;
113 if (string[len] != '\0') {
114 if (ap->mach_scan (string+len, ap, archp, machinep, 1))
115 return true;
116 }
117 if (machinep)
118 *machinep = 0;
119 return true;
120 }
121 }
122
123 /* Couldn't find an architecture -- try for just a machine type */
124 for (ap = arch_print; ap->astr; ap++) {
125 if (ap->mach_scan (string, ap, archp, machinep, 0))
126 return true;
127 }
128
129 return false;
130}
131
132static boolean
133scan_num_mach (string, ap, archp, machinep, archspec)
134 char *string;
135 struct arch_print *ap;
136 enum bfd_architecture *archp;
137 unsigned long *machinep;
138 int archspec;
139{
140 enum bfd_architecture arch;
141 unsigned long machine;
142 char achar;
143
144 if (archspec) {
145
146 /* Architecture already specified, now go for machine type. */
147 if (string[0] != ':')
148 return false;
149 /* We'll take any valid number that occupies the entire string */
150 if (1 != sscanf (string+1, "%lu%c", &machine, &achar))
151 return false;
152 arch = ap->arch;
153
154 } else {
155
156 /* We couldn't identify an architecture prefix. Perhaps the entire
157 thing is a machine type. Be a lot picker. */
158 if (1 != sscanf (string, "%lu%c", &machine, &achar))
159 return false;
160 switch (machine) {
161 case 68010:
162 case 68020:
163 case 68030:
164 case 68040:
165 case 68332:
166 case 68050: arch = bfd_arch_m68k; break;
167 case 68000: arch = bfd_arch_m68k; machine = 0; break;
168
169 case 80960:
170 case 960: arch = bfd_arch_i960; machine = 0; break;
171
172 case 386:
173 case 80386: arch = bfd_arch_i386; machine = 0; break;
174 case 486: arch = bfd_arch_i386; break;
175
176 case 29000: arch = bfd_arch_a29k; machine = 0; break;
177
178 case 32016:
179 case 32032:
180 case 32132:
181 case 32232:
182 case 32332:
183 case 32432:
184 case 32532: arch = bfd_arch_ns32k; break;
185 case 32000: arch = bfd_arch_ns32k; machine = 0; break;
186
187 case 860:
188 case 80860: arch = bfd_arch_i860; machine = 0; break;
189
190 default: return false;
191 }
192 }
193
194 if (archp)
195 *archp = arch;
196 if (machinep)
197 *machinep = machine;
198 return true;
199}
200\f
201/* Intel 960 machine variants. */
202
203static char *
204prt_960_mach (ap, machine)
205 struct arch_print *ap;
206 unsigned long machine;
207{
208 static char result[20];
209 char *str;
210
211 switch (machine) {
212 case bfd_mach_i960_core: str = "core"; break;
213 case bfd_mach_i960_kb_sb: str = "kb"; break;
214 case bfd_mach_i960_mc: str = "mc"; break;
215 case bfd_mach_i960_xa: str = "xa"; break;
216 case bfd_mach_i960_ca: str = "ca"; break;
217 case bfd_mach_i960_ka_sa: str = "ka"; break;
218 default:
219 return prt_num_mach (ap, machine);
220 }
221 sprintf (result, "%s:%s", ap->astr, str);
222 return result;
223}
224
225static boolean
226scan_960_mach (string, ap, archp, machinep, archspec)
227 char *string;
228 struct arch_print *ap;
229 enum bfd_architecture *archp;
230 unsigned long *machinep;
231 int archspec;
232{
233 unsigned long machine;
234
235 if (!archspec)
236 return false;
237 if (string[0] != ':')
238 return false;
239 string++;
240 if (string[0] == '\0')
241 return false;
242 if (string[0] == 'c' && string[1] == 'o' && string[2] == 'r' &&
243 string[3] == 'e' && string[4] == '\0')
244 machine = bfd_mach_i960_core;
245 else if (string[1] == '\0' || string[2] != '\0') /* rest are 2-char */
246 return false;
247 else if (string[0] == 'k' && string[1] == 'b')
248 machine = bfd_mach_i960_kb_sb;
249 else if (string[0] == 's' && string[1] == 'b')
250 machine = bfd_mach_i960_kb_sb;
251 else if (string[0] == 'm' && string[1] == 'c')
252 machine = bfd_mach_i960_mc;
253 else if (string[0] == 'x' && string[1] == 'a')
254 machine = bfd_mach_i960_xa;
255 else if (string[0] == 'c' && string[1] == 'a')
256 machine = bfd_mach_i960_ca;
257 else if (string[0] == 'k' && string[1] == 'a')
258 machine = bfd_mach_i960_ka_sa;
259 else if (string[0] == 's' && string[1] == 'a')
260 machine = bfd_mach_i960_ka_sa;
261 else
262 return false;
263
264 if (archp)
265 *archp = ap->arch;
266 if (machinep)
267 *machinep = machine;
268 return true;
269}
270
271
272\f
273/* Determine whether two BFDs' architectures and machine types are
274 compatible. Return merged architecture and machine type if nonnull
275 pointers. */
276
277boolean
278bfd_arch_compatible (abfd, bbfd, archp, machinep)
279 bfd *abfd;
280 bfd *bbfd;
281 enum bfd_architecture *archp;
282 unsigned long *machinep;
283{
284 enum bfd_architecture archa, archb;
285 unsigned long macha, machb;
286 int pick_a;
287
288 archa = bfd_get_architecture (abfd);
289 archb = bfd_get_architecture (bbfd);
290 macha = bfd_get_machine (abfd);
291 machb = bfd_get_machine (bbfd);
292
293 if (archb == bfd_arch_unknown)
294 pick_a = 1;
295 else if (archa == bfd_arch_unknown)
296 pick_a = 0;
297 else if (archa != archb)
298 return false; /* Not compatible */
299 else {
300 /* Architectures are the same. Check machine types. */
301 if (macha == machb) /* Same machine type */
302 pick_a = 1;
303 else if (machb == 0) /* B is default */
304 pick_a = 1;
305 else if (macha == 0) /* A is default */
306 pick_a = 0;
307 else switch (archa) {
308 /* If particular machine types of one architecture are not
309 compatible with each other, this is the place to put those tests
310 (returning false if incompatible). */
fc723380
JG
311
312 case bfd_arch_i960:
313 /* The i960 has two distinct subspecies which may not interbreed:
314 CORE CA
315 CORE KA KB MC
316 Any architecture on the same line is compatible, the one on
317 the right is the least restrictive. */
318 /* So, if either is a ca then the other must be a be core or ca */
319 if (macha == bfd_mach_i960_ca) {
320 if (machb != bfd_mach_i960_ca &&
321 machb != bfd_mach_i960_core) {
322 return false;
323 }
324 pick_a = 1;
4a81b561 325 }
fc723380
JG
326 else if (machb == bfd_mach_i960_ca) {
327 if (macha != bfd_mach_i960_ca &&
328 macha != bfd_mach_i960_core) {
329 return false;
330 }
331 pick_a = 0;
4a81b561 332 }
fc723380
JG
333 else {
334 /* This must be from the bottom row, so take the higest */
335 pick_a = (macha > machb);
336 }
337 break;
4a81b561
DHW
338
339 /* For these chips, as far as we care, "lower" numbers are included
340 by "higher" numbers, e.g. merge 68010 and 68020 into 68020,
341 386 and 486 into 486, etc. This will need to change
342 if&when we care about things like 68332. */
343 case bfd_arch_m68k:
344 case bfd_arch_ns32k:
345 case bfd_arch_i386:
346 pick_a = (macha > machb);
347 break;
348
349 /* By default, pick first file's type, for lack of something better. */
350 default:
351 pick_a = 1;
352 }
353 }
354
355 /* Set result based on our pick */
356 if (!pick_a) {
357 archa = archb;
358 macha = machb;
359 }
360 if (archp)
361 *archp = archa;
362 if (machinep)
363 *machinep = macha;
364
365 return true;
366}
This page took 0.038426 seconds and 4 git commands to generate.