#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include "as.h"
#include "input-scrub.h"
#include "symbols.h"
#include "sections.h"
#include "read.h"
#include "md.h"
#include "messages.h"
#include "xmalloc.h"
#include "layout.h"
#include "write_object.h"
char flagseen[128] = { 0 };
int force_cpusubtype_ALL = 0;
cpu_subtype_t archflag_cpusubtype = -1;
char *specific_archflag = NULL;
int subsections_via_symbols = 0;
struct directory_stack include_defaults[] = {
#ifdef __OPENSTEP__
{ 0, "/NextDeveloper/Headers/" },
{ 0, "/LocalDeveloper/Headers/" },
#endif
{ 0, NULL }
};
struct directory_stack *include = NULL;
static struct directory_stack *include_tail = NULL;
extern char apple_version[];
static char version_string[] = "GNU assembler version 1.38\n";
static int sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
static void got_sig(
int sig);
static void perform_an_assembly_pass(
int argc,
char **argv);
char *progname = NULL;
int
main(
int argc,
char **argv,
char **envp)
{
int work_argc;
char **work_argv;
char *arg;
char a;
char *out_file_name;
int i;
struct directory_stack *dirtmp;
progname = argv[0];
for(i = 0; sig[i] != 0; i++)
if(signal(sig[i], SIG_IGN) != SIG_IGN)
signal(sig[i], got_sig);
memset(flagseen, '\0', sizeof(flagseen));
out_file_name = "a.out";
flagseen[(int)'k'] = TRUE;
work_argc = argc - 1;
work_argv = argv + 1;
for( ; work_argc-- ; work_argv++){
arg = *work_argv;
if(*arg != '-')
continue;
if(strcmp(arg, "--gstabs") == 0){
flagseen[(int)'g'] = TRUE;
*work_argv = NULL;
continue;
}
if(strcmp(arg, "--gdwarf2") == 0){
as_fatal("%s: I don't understand %s flag!", progname, arg);
}
if (arg[1] == '-' && arg[2] == 0) {
*work_argv = "";
continue;
}
arg++;
while((a = *arg)){
arg ++;
a &= 0x7F;
if(flagseen[(int)a] && (a != 'I') && (a != 'a') && (a != 'f') &&
(a != 'd') && (a != 's') && (a != 'k'))
as_warn("%s: Flag option -%c has already been seen!",
progname, a);
if(a != 'f' && a != 'n')
flagseen[(int)a] = TRUE;
switch(a){
case 'f':
if(strcmp(arg-1, "force_cpusubtype_ALL") == 0){
force_cpusubtype_ALL = 1;
arg = "";
break;
}
flagseen[(int)a] = TRUE;
break;
case 'L':
break;
case 'o':
if(*arg != '\0')
out_file_name = arg;
else if(work_argc){
*work_argv = NULL;
work_argc--;
out_file_name = *++work_argv;
}
else
as_warn("%s: I expected a filename after -o. \"%s\" "
"assumed.", progname, out_file_name);
arg = "";
break;
case 'R':
as_warn("%s: -R option not supported (use the "
".const directive)", progname);
flagseen['R'] = FALSE;
break;
case 'v':
fprintf(stderr,"Apple Computer, Inc. version "
"%s, ", apple_version);
fprintf(stderr, version_string);
if(*arg && strcmp(arg,"ersion"))
as_warn("Unknown -v option ignored");
while(*arg)
arg++;
break;
case 'W':
break;
case 'I':
dirtmp = (struct directory_stack *)
xmalloc(sizeof(struct directory_stack));
dirtmp->next = 0;
if(include == 0)
include = dirtmp;
else
include_tail->next = dirtmp;
include_tail = dirtmp;
if(*arg)
dirtmp->fname = arg;
else if (work_argc){
*work_argv = NULL;
work_argc--;
dirtmp->fname = *++work_argv;
}
else
as_warn("I expected a filename after -I.");
arg = "";
break;
case 'g':
break;
case 'n':
#ifdef PPC
if(strcmp(arg-1, "no_ppc601") == 0)
goto unknown_flag;
#endif
flagseen[(int)a] = TRUE;
break;
#ifdef PPC
case 'p':
if(strcmp(arg-1, "ppcasm") == 0)
goto unknown_flag;
#endif
case 'd':
if(strcmp(arg-1, "dynamic") == 0){
arg = "";
flagseen[(int)'k'] = TRUE;
break;
}
goto unknown_flag;
case 's':
if(strcmp(arg-1, "static") == 0){
arg = "";
flagseen[(int)'k'] = FALSE;
break;
}
goto unknown_flag;
case 'N':
if(strcmp(arg-1, "NEXTSTEP-deployment-target") == 0){
arg = "";
if(work_argc){
*work_argv = NULL;
work_argc--;
work_argv++;
if(strcmp(*work_argv, "3.3") == 0){
flagseen[(int)'k'] = TRUE;
}
else if(strcmp(*work_argv, "3.2") == 0){
flagseen[(int)'k'] = FALSE;
}
else{
as_fatal("I expected '3.2' or '3.3' after "
"-NEXTSTEP-deployment-target.");
}
}
else
as_fatal("I expected a <release_tag> "
"after -NEXTSTEP-deployment-target.");
break;
}
goto unknown_flag;
case 'k':
break;
case 'V':
break;
case 'a':
if(strcmp(arg-1, "arch_multiple") == 0){
arch_multiple = 1;
arg = "";
break;
}
else if(strcmp(arg-1, "arch") == 0){
arg = "";
if(work_argc){
*work_argv = NULL;
work_argc--;
work_argv++;
#ifdef M68K
if(strcmp(*work_argv, "m68030") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_MC68030_ONLY)
as_fatal("can't specify both "
"-arch m68030 and -arch "
"m68040");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_MC68030_ONLY;
}
else if(strcmp(*work_argv,
"m68040") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_MC68040)
as_fatal("can't specify both "
"-arch m68030 and -arch "
"m68040");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_MC68040;
}
else if(strcmp(*work_argv, "m68k") != 0)
as_fatal("I expected 'm68k', "
"'m68030' or 'm68040' after "
"-arch for this assembler.");
#endif
#ifdef M88K
if(strcmp(*work_argv, "m88k") != 0)
as_fatal("I expected 'm88k' after "
"-arch for this assembler.");
#endif
#if defined(PPC) && !defined(ARCH64)
if(strcmp(*work_argv, "ppc601") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_601)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_601;
}
else if(strcmp(*work_argv,
"ppc603") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_603)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_603;
}
else if(strcmp(*work_argv,
"ppc603e") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_603e)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_603e;
}
else if(strcmp(*work_argv,
"ppc603ev") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_603ev)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_603ev;
}
else if(strcmp(*work_argv,
"ppc604") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_604)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_604;
}
else if(strcmp(*work_argv,
"ppc604e") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_604e)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_604e;
}
else if(strcmp(*work_argv,
"ppc750") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_750)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_750;
}
else if(strcmp(*work_argv,
"ppc7400") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_7400)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_7400;
}
else if(strcmp(*work_argv,
"ppc7450") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_7450)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_7450;
}
else if(strcmp(*work_argv,
"ppc970") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_970)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_970;
}
else if(strcmp(*work_argv, "ppc") != 0 &&
strcmp(*work_argv, "m98k") != 0)
as_fatal("I expected 'ppc' after "
"-arch for this assembler.");
#endif
#if defined(PPC) && defined(ARCH64)
if(strcmp(*work_argv,
"ppc970-64") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_POWERPC_970)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_POWERPC_970;
}
else
#endif
#if defined(PPC) && defined(ARCH64)
if(strcmp(*work_argv, "ppc64") != 0)
as_fatal("I expected 'ppc64' after "
"-arch for this assembler.");
#endif
#ifdef I860
if(strcmp(*work_argv, "i860") != 0)
as_fatal("I expected 'i860' after "
"-arch for this assembler.");
#endif
#ifdef I386
if(strcmp(*work_argv, "i486") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_486)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_486;
}
else if(strcmp(*work_argv,
"i486SX") == 0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_486SX)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_486SX;
}
else if(strcmp(*work_argv, "i586") ==0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_586)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_586;
}
else if(strcmp(*work_argv, "pentium") ==0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_PENT)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_PENT;
}
else if(strcmp(*work_argv, "pentpro") ==0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_PENTPRO)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_PENTPRO;
}
else if(strcmp(*work_argv, "i686") ==0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_PENTPRO)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_PENTPRO;
}
else if(strcmp(*work_argv, "pentIIm3") ==0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_PENTII_M3)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_PENTII_M3;
}
else if(strcmp(*work_argv, "pentIIm5") ==0){
if(archflag_cpusubtype != -1 &&
archflag_cpusubtype !=
CPU_SUBTYPE_PENTII_M5)
as_fatal("can't specify more "
"than one -arch flag ");
specific_archflag = *work_argv;
archflag_cpusubtype =
CPU_SUBTYPE_PENTII_M5;
}
else if(strcmp(*work_argv, "i386") != 0)
as_fatal("I expected 'i386', 'i486', 'i486SX', "
"'i586', 'pentium', 'i686', 'pentpro', "
"'pentIIm3', or 'pentIIm5' after -arch "
"for this assembler.");
#endif
#ifdef HPPA
if(strcmp(*work_argv, "hppa") != 0)
as_fatal("I expected 'hppa' after "
"-arch for this assembler.");
#endif
#ifdef SPARC
if(strcmp(*work_argv, "sparc") != 0)
as_fatal("I expected 'sparc' after "
"-arch for this assembler.");
#endif
}
else
as_fatal("I expected an <arch_type> "
"after -arch.");
break;
}
default:
unknown_flag:
--arg;
if(md_parse_option(&arg, &work_argc, &work_argv) == 0)
as_warn("%s: I don't understand '%c' flag!", progname,
a);
if(arg && *arg)
arg++;
break;
}
}
*work_argv = NULL;
}
if(flagseen['g'] == TRUE && flagseen['n'] == TRUE)
as_fatal("-g can't be specified if -n is specified");
if(force_cpusubtype_ALL && specific_archflag)
archflag_cpusubtype = -1;
#ifdef OLD_PROJECTBUILDER_INTERFACE
check_for_ProjectBuilder();
#endif
symbol_begin();
sections_begin();
read_begin();
#ifdef PPC
if(flagseen[(int)'p'] == TRUE)
ppcasm_read_begin();
#endif
md_begin();
input_scrub_begin();
perform_an_assembly_pass(argc, argv);
if(seen_at_least_1_file() && bad_error != TRUE){
layout_addresses();
write_object(out_file_name);
}
input_scrub_end();
md_end();
return(bad_error);
}
static
void
perform_an_assembly_pass(
int argc,
char **argv)
{
char *buffer;
int saw_a_file;
saw_a_file = 0;
argv++;
argc--;
while(argc--){
if(*argv){
if((buffer = input_scrub_new_file(*argv))){
saw_a_file++;
read_a_source_file(buffer);
}
}
argv++;
}
if(!saw_a_file)
if((buffer = input_scrub_new_file("")))
read_a_source_file(buffer);
}
static
void
got_sig(
int sig)
{
as_bad("Interrupted by signal %d",sig);
exit(1);
}