|
|
1.1 root 1: /*
2: * The assembler driver that lives in /bin/as and runs the assembler for the
3: * "-arch <arch_flag>" (if given) in /lib/<arch_flag>/as or in
4: * /usr/local/lib/<arch_flag>/as. Or runs the assembler for the host
5: * architecture as returned by get_arch_from_host(). The driver only checks
6: * to make sure their are not multiple arch_flags and then passes all flags to
7: * the assembler it will run.
8: */
9: #include "stdio.h"
10: #include "stdlib.h"
11: #include "string.h"
12: #include "libc.h"
13: #include <sys/file.h>
14: #include <mach/mach.h>
15: #include "stuff/arch.h"
16: #include "stuff/errors.h"
17: #include "stuff/execute.h"
18: #include "stuff/allocate.h"
19:
20: /* used by error calls (exported) */
21: char *progname = NULL;
22:
23: void
24: main(
25: int argc,
26: char **argv,
27: char **envp)
28: {
29: const char *LIB = "/lib/";
30: const char *LOCALLIB = "/usr/local/lib/";
31: const char *AS = "/as";
32:
33: unsigned long i, count, verbose;
34: char *p, c, *arch_name, *as, *as_local;
35: struct arch_flag arch_flag;
36: const struct arch_flag *arch_flags, *family_arch_flag;
37:
38: progname = argv[0];
39: arch_name = NULL;
40: verbose = 0;
41: /*
42: * Process the assembler flags exactly like the assembler would (except
43: * let the assembler complain about multiple flags, bad combinations of
44: * flags, unknown single letter flags and the like). The main thing
45: * here is to parse out the "-arch <arch_flag>" and to do so the
46: * multiple argument and multiple character flags need to be known how
47: * to be stepped over correctly.
48: */
49: for(i = 1; i < argc; i++){
50: /*
51: * The assembler flags start with '-' except that "--" is recognized
52: * as assemble from stdin and that flag "--" is not allowed to be
53: * grouped with other flags (so "-a-" is not the same as "-a --").
54: */
55: if(argv[i][0] == '-' &&
56: !(argv[i][1] == '-' && argv[i][2] == '0')){
57: /*
58: * the assembler allows single letter flags to be grouped
59: * together so "-abc" is the same as "-a -b -c". So that
60: * logic must be followed here.
61: */
62: for(p = &(argv[i][1]); (c = *p); p++){
63: /*
64: * The assembler simply ignores the high bit of flag
65: * characters and not treat them as different characters
66: * as they are (but the argument following the flag
67: * character is not treated this way). So it's done
68: * here as well to match it.
69: */
70: c &= 0x7F;
71: switch(c){
72: /*
73: * Flags that take a single argument. The argument is the
74: * rest of the current argument if there is any or the it is
75: * the next argument. Again errors like missing arguments
76: * are not handled here but left to the assembler.
77: */
78: case 'o': /* -o name */
79: case 'I': /* -I directory */
80: case 'm': /* -mc68000, -mc68010 and mc68020 */
81: case 'N': /* -NEXTSTEP-deployment-target */
82: if(p[1] == '\0')
83: i++;
84: break;
85:
86: case 'a':
87: if(strcmp(p, "arch") == 0){
88: if(i + 1 >= argc)
89: fatal("missing argument to %s option", argv[i]);
90: if(arch_name != NULL)
91: fatal("more than one %s option (not allowed, "
92: "use cc(1) instead)", argv[i]);
93: arch_name = argv[i+1];
94: break;
95: }
96: /* fall through for non "-arch" */
97: case 'f':
98: case 'k':
99: case 'g':
100: case 'v':
101: case 'W':
102: case 'L':
103: case 'l':
104: default:
105: /* just recognize it, do nothing */
106: break;
107: case 'V':
108: verbose = 1;
109: break;
110: }
111: }
112: }
113: }
114:
115: /*
116: * Construct the name of the assembler to run from the given -arch
117: * <arch_flag> or if none then from the value returned from
118: * get_arch_from_host().
119: */
120: if(arch_name == NULL){
121: if(get_arch_from_host(&arch_flag, NULL))
122: arch_name = arch_flag.name;
123: else
124: fatal("known host architecture (can't determine which assembler"
125: " to run)");
126: }
127: else{
128: /*
129: * Convert a possible machine specific architecture name to a
130: * family name to base the name of the assembler to run.
131: */
132: if(get_arch_from_flag(arch_name, &arch_flag) != 0){
133: family_arch_flag =
134: get_arch_family_from_cputype(arch_flag.cputype);
135: if(family_arch_flag != NULL)
136: arch_name = (char *)(family_arch_flag->name);
137: }
138:
139: }
140: as = makestr(LIB, arch_name, AS, NULL);
141:
142: /*
143: * If this assembler exist try to run it else print an error message.
144: */
145: if(access(as, F_OK) == 0){
146: argv[0] = as;
147: if(execute(argv, verbose))
148: exit(0);
149: else
150: exit(1);
151: }
152: as_local = makestr(LOCALLIB, arch_name, AS, NULL);
153: if(access(as_local, F_OK) == 0){
154: argv[0] = as_local;
155: if(execute(argv, verbose))
156: exit(0);
157: else
158: exit(1);
159: }
160: else{
161: printf("%s: assembler (%s or %s) for architecture %s not "
162: "installed\n", progname, as, as_local, arch_name);
163: arch_flags = get_arch_flags();
164: count = 0;
165: for(i = 0; arch_flags[i].name != NULL; i++){
166: as = makestr(LIB, arch_flags[i].name, AS, NULL);
167: if(access(as, F_OK) == 0){
168: if(count == 0)
169: printf("Installed assemblers are:\n");
170: printf("%s for architecture %s\n", as, arch_flags[i].name);
171: count++;
172: }
173: else{
174: as_local = makestr(LOCALLIB, arch_flags[i].name, AS, NULL);
175: if(access(as_local, F_OK) == 0){
176: if(count == 0)
177: printf("Installed assemblers are:\n");
178: printf("%s for architecture %s\n", as_local,
179: arch_flags[i].name);
180: count++;
181: }
182: }
183: }
184: if(count == 0)
185: printf("%s: no assemblers installed\n", progname);
186: exit(1);
187: }
188: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.