|
|
1.1 root 1: #include "string.h"
2: #include <mach/mach.h>
3: #include "stuff/arch.h"
4:
5: /*
6: * The array of all currently know architecture flags (terminated with an entry
7: * with all zeros). Pointer to this returned with get_arch_flags().
8: */
9: static const struct arch_flag arch_flags[] = {
10: { "any", CPU_TYPE_ANY, CPU_SUBTYPE_MULTIPLE },
11: { "little", CPU_TYPE_ANY, CPU_SUBTYPE_LITTLE_ENDIAN },
12: { "big", CPU_TYPE_ANY, CPU_SUBTYPE_BIG_ENDIAN },
13: /* architecture families */
14: { "m68k", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC680x0_ALL },
15: { "m98k", CPU_TYPE_MC98000, CPU_SUBTYPE_MC98000_ALL },
16: { "m88k", CPU_TYPE_MC88000, CPU_SUBTYPE_MC88000_ALL },
17: { "i386", CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL },
18: { "i860", CPU_TYPE_I860, CPU_SUBTYPE_I860_ALL },
19: { "hppa", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_ALL },
20: { "sparc", CPU_TYPE_SPARC, CPU_SUBTYPE_SPARC_ALL },
21: /* specific architecture implementations */
22: { "m68030", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68030_ONLY },
23: { "m68040", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68040 },
24: { "i486", CPU_TYPE_I386, CPU_SUBTYPE_486 },
25: { "i486SX", CPU_TYPE_I386, CPU_SUBTYPE_486SX },
26: { "i586", CPU_TYPE_I386, CPU_SUBTYPE_586 },
27: { "i586SX", CPU_TYPE_I386, CPU_SUBTYPE_586SX },
28: { "hppa7100LC", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_7100LC },
29: { NULL, 0, 0 }
30: };
31:
32: /*
33: * get_arch_from_flag() is passed a name of an architecture flag and returns
34: * zero if that flag is not known and non-zero if the flag is known.
35: * If the pointer to the arch_flag is not NULL it is filled in with the
36: * arch_flag struct that matches the name.
37: */
38: int
39: get_arch_from_flag(
40: char *name,
41: struct arch_flag *arch_flag)
42: {
43: unsigned long i;
44:
45: for(i = 0; arch_flags[i].name != NULL; i++){
46: if(strcmp(arch_flags[i].name, name) == 0){
47: if(arch_flag != NULL)
48: *arch_flag = arch_flags[i];
49: return(1);
50: }
51: }
52: if(arch_flag != NULL)
53: memset(arch_flag, '\0', sizeof(struct arch_flag));
54: return(0);
55: }
56:
57: /*
58: * get_arch_from_host() gets the architecture from the host this is running on
59: * and returns zero if the architecture is not known and zero if the
60: * architecture is known. If the parameters family_arch_flag and
61: * specific_arch_flag are not NULL they get fill in with the family
62: * architecture and specific architecure for the host. If the architecture
63: * is unknown and the parameters are not NULL then all fields are set to zero.
64: */
65: int
66: get_arch_from_host(
67: struct arch_flag *family_arch_flag,
68: struct arch_flag *specific_arch_flag)
69: {
70: struct host_basic_info host_basic_info;
71: unsigned int count;
72: kern_return_t r;
73:
74: if(family_arch_flag != NULL)
75: memset(family_arch_flag, '\0', sizeof(struct arch_flag));
76: if(specific_arch_flag != NULL)
77: memset(specific_arch_flag, '\0', sizeof(struct arch_flag));
78:
79: count = HOST_BASIC_INFO_COUNT;
80: if((r = host_info(host_self(), HOST_BASIC_INFO,
81: (host_info_t)(&host_basic_info),
82: &count)) != KERN_SUCCESS)
83: return(0);
84:
85: if(family_arch_flag != NULL){
86: family_arch_flag->cputype = host_basic_info.cpu_type;
87: }
88: if(specific_arch_flag != NULL){
89: specific_arch_flag->cputype = host_basic_info.cpu_type;
90: specific_arch_flag->cpusubtype = host_basic_info.cpu_subtype;
91: }
92: switch(host_basic_info.cpu_type){
93: case CPU_TYPE_MC680x0:
94: switch(host_basic_info.cpu_subtype){
95: case CPU_SUBTYPE_MC680x0_ALL:
96: case CPU_SUBTYPE_MC68030_ONLY:
97: if(family_arch_flag != NULL){
98: family_arch_flag->name = "m68k";
99: family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
100: }
101: if(specific_arch_flag != NULL){
102: specific_arch_flag->name = "m68030";
103: /*
104: * There is a "bug" in the kernel for compatiblity that on
105: * an 030 machine host_info() returns cpusubtype
106: * CPU_SUBTYPE_MC680x0_ALL and not CPU_SUBTYPE_MC68030_ONLY.
107: */
108: specific_arch_flag->cpusubtype = CPU_SUBTYPE_MC68030_ONLY;
109: }
110: return(1);
111: case CPU_SUBTYPE_MC68040:
112: if(family_arch_flag != NULL){
113: family_arch_flag->name = "m68k";
114: family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
115: }
116: if(specific_arch_flag != NULL)
117: specific_arch_flag->name = "m68040";
118: return(1);
119: }
120: break;
121: case CPU_TYPE_MC98000:
122: switch(host_basic_info.cpu_subtype){
123: case CPU_SUBTYPE_MC98000_ALL:
124: if(family_arch_flag != NULL){
125: family_arch_flag->name = "m98k";
126: family_arch_flag->cpusubtype = CPU_SUBTYPE_MC98000_ALL;
127: }
128: if(specific_arch_flag != NULL)
129: specific_arch_flag->name = "m98k";
130: return(1);
131: }
132: break;
133: case CPU_TYPE_MC88000:
134: switch(host_basic_info.cpu_subtype){
135: case CPU_SUBTYPE_MC88000_ALL:
136: case CPU_SUBTYPE_MC88110:
137: if(family_arch_flag != NULL){
138: family_arch_flag->name = "m88k";
139: family_arch_flag->cpusubtype = CPU_SUBTYPE_MC88000_ALL;
140: }
141: if(specific_arch_flag != NULL)
142: specific_arch_flag->name = "m88k";
143: return(1);
144: }
145: break;
146: case CPU_TYPE_I386:
147: switch(host_basic_info.cpu_subtype){
148: case CPU_SUBTYPE_I386_ALL:
149: /* case CPU_SUBTYPE_386: same value as above */
150: if(family_arch_flag != NULL){
151: family_arch_flag->name = "i386";
152: family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
153: }
154: if(specific_arch_flag != NULL)
155: specific_arch_flag->name = "i386";
156: return(1);
157: case CPU_SUBTYPE_486:
158: if(family_arch_flag != NULL){
159: family_arch_flag->name = "i386";
160: family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
161: }
162: if(specific_arch_flag != NULL)
163: specific_arch_flag->name = "i486";
164: return(1);
165: case CPU_SUBTYPE_486SX:
166: if(family_arch_flag != NULL){
167: family_arch_flag->name = "i386";
168: family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
169: }
170: if(specific_arch_flag != NULL)
171: specific_arch_flag->name = "i486SX";
172: return(1);
173: case CPU_SUBTYPE_586:
174: if(family_arch_flag != NULL){
175: family_arch_flag->name = "i386";
176: family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
177: }
178: if(specific_arch_flag != NULL)
179: specific_arch_flag->name = "i586";
180: return(1);
181: case CPU_SUBTYPE_586SX:
182: if(family_arch_flag != NULL){
183: family_arch_flag->name = "i386";
184: family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
185: }
186: if(specific_arch_flag != NULL)
187: specific_arch_flag->name = "i586SX";
188: return(1);
189: }
190: break;
191: case CPU_TYPE_I860:
192: switch(host_basic_info.cpu_subtype){
193: case CPU_SUBTYPE_I860_ALL:
194: case CPU_SUBTYPE_I860_860:
195: if(family_arch_flag != NULL){
196: family_arch_flag->name = "i860";
197: family_arch_flag->cpusubtype = CPU_SUBTYPE_I860_ALL;
198: }
199: if(specific_arch_flag != NULL)
200: specific_arch_flag->name = "i860";
201: return(1);
202: }
203: break;
204: case CPU_TYPE_HPPA:
205: switch(host_basic_info.cpu_subtype){
206: case CPU_SUBTYPE_HPPA_ALL:
207: if(family_arch_flag != NULL){
208: family_arch_flag->name = "hppa";
209: family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
210: }
211: if(specific_arch_flag != NULL)
212: specific_arch_flag->name = "hppa";
213: return(1);
214: case CPU_SUBTYPE_HPPA_7100LC:
215: if(family_arch_flag != NULL){
216: family_arch_flag->name = "hppa";
217: family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
218: }
219: if(specific_arch_flag != NULL)
220: specific_arch_flag->name = "hppa7100LC";
221: return(1);
222:
223: }
224: break;
225: case CPU_TYPE_SPARC:
226: switch(host_basic_info.cpu_subtype){
227: case /*CPU_SUBTYPE_SPARC_ALL*/0:
228: if(family_arch_flag != NULL){
229: family_arch_flag->name = "sparc";
230: family_arch_flag->cpusubtype = CPU_SUBTYPE_SPARC_ALL;
231: }
232: if(specific_arch_flag != NULL)
233: specific_arch_flag->name = "sparc";
234: return(1);
235: }
236: break;
237: }
238: return(0);
239: }
240:
241: /*
242: * get_arch_flags() returns a pointer to an array of all currently know
243: * architecture flags (terminated with an entry with all zeros).
244: */
245: const struct arch_flag *
246: get_arch_flags(
247: void)
248: {
249: return(arch_flags);
250: }
251:
252: /*
253: * get_arch_name_from_types() returns the name of the architecture for the
254: * specified cputype and cpusubtype if known. If unknown it returns a pointer
255: * to the string "unknown".
256: */
257: const char *
258: get_arch_name_from_types(
259: cpu_type_t cputype,
260: cpu_subtype_t cpusubtype)
261: {
262: unsigned long i;
263:
264: for(i = 0; arch_flags[i].name != NULL; i++){
265: if(arch_flags[i].cputype == cputype &&
266: arch_flags[i].cpusubtype == cpusubtype)
267: return(arch_flags[i].name);
268: }
269: return("unknown");
270: }
271:
272: /*
273: * get_arch_family_from_cputype() returns the family architecture for the
274: * specified cputype if known. If unknown it returns NULL.
275: */
276: const struct arch_flag *
277: get_arch_family_from_cputype(
278: cpu_type_t cputype)
279: {
280: unsigned long i;
281:
282: for(i = 0; arch_flags[i].name != NULL; i++){
283: if(arch_flags[i].cputype == cputype)
284: return(arch_flags + i);
285: }
286: return(NULL);
287: }
288:
289: /*
290: * get_byte_sex_from_flag() returns the byte sex of the architecture for the
291: * specified cputype and cpusubtype if known. If unknown it returns
292: * UNKNOWN_BYTE_SEX. If the bytesex can be determined directly as in the case
293: * of reading a magic number from a file that should be done and this routine
294: * should not be used as it could be out of date.
295: */
296: enum byte_sex
297: get_byte_sex_from_flag(
298: const struct arch_flag *flag)
299: {
300: if(flag->cputype == CPU_TYPE_MC680x0 ||
301: flag->cputype == CPU_TYPE_MC88000 ||
302: flag->cputype == CPU_TYPE_MC98000 ||
303: flag->cputype == CPU_TYPE_HPPA ||
304: flag->cputype == CPU_TYPE_SPARC ||
305: flag->cputype == CPU_TYPE_I860)
306: return BIG_ENDIAN_BYTE_SEX;
307: else if(flag->cputype == CPU_TYPE_I386)
308: return LITTLE_ENDIAN_BYTE_SEX;
309: else
310: return UNKNOWN_BYTE_SEX;
311: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.