2 * The assembler driver that lives in /bin/as and runs the assembler for the
3 * "-arch <arch_flag>" (if given) in /usr/libexec/gcc/darwin/<arch_flag>/as or
4 * in /usr/local/libexec/gcc/darwin/<arch_flag>/as. Or runs the assembler for
5 * the host architecture as returned by get_arch_from_host(). The driver only
6 * checks to make sure their are not multiple arch_flags and then passes all
7 * flags to the assembler it will run.
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 #include <mach-o/dyld.h>
21 /* used by error calls (exported) */
22 char *progname
= NULL
;
33 #if defined(__OPENSTEP__) || defined(__HERA__) || \
34 defined(__GONZO_BUNSEN_BEAKER__) || defined(__KODIAK__)
37 "../libexec/gcc/darwin/";
39 const char *LOCALLIB
=
40 #if defined(__OPENSTEP__) || defined(__HERA__) || \
41 defined(__GONZO_BUNSEN_BEAKER__) || defined(__KODIAK__)
44 "../local/libexec/gcc/darwin/";
47 const char *AS
= "/as";
50 unsigned long count
, verbose
;
51 char *p
, c
, *arch_name
, *as
, *as_local
;
52 char *prefix
, buf
[MAXPATHLEN
], resolved_name
[PATH_MAX
];
54 struct arch_flag arch_flag
;
55 const struct arch_flag
*arch_flags
, *family_arch_flag
;
62 * Construct the prefix to the assembler driver.
66 i
= _NSGetExecutablePath(p
, &bufsize
);
68 p
= allocate(bufsize
);
69 _NSGetExecutablePath(p
, &bufsize
);
71 prefix
= realpath(p
, resolved_name
);
72 p
= rindex(prefix
, '/');
79 * Process the assembler flags exactly like the assembler would (except
80 * let the assembler complain about multiple flags, bad combinations of
81 * flags, unknown single letter flags and the like). The main thing
82 * here is to parse out the "-arch <arch_flag>" and to do so the
83 * multiple argument and multiple character flags need to be known how
84 * to be stepped over correctly.
86 for(i
= 1; i
< argc
; i
++){
88 * The assembler flags start with '-' except that "--" is recognized
89 * as assemble from stdin and that flag "--" is not allowed to be
90 * grouped with other flags (so "-a-" is not the same as "-a --").
92 if(argv
[i
][0] == '-' &&
93 !(argv
[i
][1] == '-' && argv
[i
][2] == '0')){
95 * the assembler allows single letter flags to be grouped
96 * together so "-abc" is the same as "-a -b -c". So that
97 * logic must be followed here.
99 for(p
= &(argv
[i
][1]); (c
= *p
); p
++){
101 * The assembler simply ignores the high bit of flag
102 * characters and not treat them as different characters
103 * as they are (but the argument following the flag
104 * character is not treated this way). So it's done
105 * here as well to match it.
110 * Flags that take a single argument. The argument is the
111 * rest of the current argument if there is any or the it is
112 * the next argument. Again errors like missing arguments
113 * are not handled here but left to the assembler.
115 case 'o': /* -o name */
116 case 'I': /* -I directory */
117 case 'm': /* -mc68000, -mc68010 and mc68020 */
118 case 'N': /* -NEXTSTEP-deployment-target */
124 if(strcmp(p
, "arch") == 0){
126 fatal("missing argument to %s option", argv
[i
]);
127 if(arch_name
!= NULL
)
128 fatal("more than one %s option (not allowed, "
129 "use cc(1) instead)", argv
[i
]);
130 arch_name
= argv
[i
+1];
133 /* fall through for non "-arch" */
142 /* just recognize it, do nothing */
153 * Construct the name of the assembler to run from the given -arch
154 * <arch_flag> or if none then from the value returned from
155 * get_arch_from_host().
157 if(arch_name
== NULL
){
158 if(get_arch_from_host(&arch_flag
, NULL
))
159 arch_name
= arch_flag
.name
;
161 fatal("unknown host architecture (can't determine which "
162 "assembler to run)");
166 * Convert a possible machine specific architecture name to a
167 * family name to base the name of the assembler to run.
169 if(get_arch_from_flag(arch_name
, &arch_flag
) != 0){
171 get_arch_family_from_cputype(arch_flag
.cputype
);
172 if(family_arch_flag
!= NULL
)
173 arch_name
= (char *)(family_arch_flag
->name
);
177 as
= makestr(prefix
, LIB
, arch_name
, AS
, NULL
);
180 * If this assembler exist try to run it else print an error message.
182 if(access(as
, F_OK
) == 0){
184 if(execute(argv
, verbose
))
191 as_local
= makestr(prefix
, LOCALLIB
, arch_name
, AS
, NULL
);
192 if(access(as_local
, F_OK
) == 0){
194 if(execute(argv
, verbose
))
202 printf("%s: assembler (%s or %s) for architecture %s not "
203 "installed\n", progname
, as
, as_local
, arch_name
);
204 arch_flags
= get_arch_flags();
206 for(i
= 0; arch_flags
[i
].name
!= NULL
; i
++){
207 as
= makestr(prefix
, LIB
, arch_flags
[i
].name
, AS
, NULL
);
208 if(access(as
, F_OK
) == 0){
210 printf("Installed assemblers are:\n");
211 printf("%s for architecture %s\n", as
, arch_flags
[i
].name
);
216 as_local
= makestr(prefix
, LOCALLIB
, arch_flags
[i
].name
,
218 if(access(as_local
, F_OK
) == 0){
220 printf("Installed assemblers are:\n");
221 printf("%s for architecture %s\n", as_local
,
229 printf("%s: no assemblers installed\n", progname
);