unsigned read(void* buf, unsigned len) { auto allowed = std::min(len, read_available()); memcpy(buf, read_begin(), allowed); mNumRead += allowed; return allowed; }
int main( int argc, char **argv, char **envp) { int work_argc; /* variable copy of argc */ char **work_argv; /* variable copy of argv */ char *arg; /* an arg to program */ char a; /* an arg flag (after -) */ char *out_file_name;/* name of object file, argument to -o if specified */ int i; struct directory_stack *dirtmp; progname = argv[0]; /* * Set up to catch the signals listed in sig[] that are not ignored. */ for(i = 0; sig[i] != 0; i++) if(signal(sig[i], SIG_IGN) != SIG_IGN) signal(sig[i], got_sig); /* * Set the default for the flags that will be parsed. */ memset(flagseen, '\0', sizeof(flagseen)); /* aint seen nothing yet */ out_file_name = "a.out"; /* default .o file */ /* This is the -dynamic flag, which is now the default */ flagseen[(int)'k'] = TRUE; /* * Parse arguments, but we are only interested in flags. * When we find a flag, we process it then make it's argv[] NULL. * This helps any future argv[] scanners avoid what we processed. * Since it is easy to do here we interpret the special arg "-" * to mean "use stdin" and we set that argv[] pointing to "". * After we have munged argv[], the only things left are source file * name(s) and ""(s) denoting stdin. These file names are used * (perhaps more than once) later. */ work_argc = argc - 1; /* don't count argv[0] */ work_argv = argv + 1; /* skip argv[0] */ for( ; work_argc-- ; work_argv++){ /* work_argv points to this argument */ arg = *work_argv; /* Filename. We need it later. */ if(*arg != '-') continue; if(strcmp(arg, "--gstabs") == 0){ /* generate stabs for debugging assembly code */ flagseen[(int)'g'] = TRUE; *work_argv = NULL; /* NULL means 'not a file-name' */ continue; } if(strcmp(arg, "--gdwarf2") == 0){ as_fatal("%s: I don't understand %s flag!", progname, arg); } /* Keep scanning args looking for flags. */ if (arg[1] == '-' && arg[2] == 0) { /* "--" as an argument means read STDIN */ /* on this scan, we don't want to think about filenames */ *work_argv = ""; /* Code that means 'use stdin'. */ continue; } /* This better be a switch ( -l where l is a letter. */ arg++; /* -> letter. */ /* scan all the 1-char flags */ while((a = *arg)){ arg ++; /* arg -> after letter. */ a &= 0x7F; /* ascii only please */ 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 = ""; /* Finished with this arg. */ break; } /* -f means fast - no need for "app" preprocessor. */ flagseen[(int)a] = TRUE; break; case 'L': /* -L means keep L* symbols */ break; case 'o': if(*arg != '\0') /* Rest of argument is object file-name. */ out_file_name = arg; else if(work_argc){ /* Want next arg for a file-name. */ *work_argv = NULL; /* This is not a file-name. */ work_argc--; out_file_name = *++work_argv; } else as_warn("%s: I expected a filename after -o. \"%s\" " "assumed.", progname, out_file_name); arg = ""; /* Finished with this arg. */ break; case 'R': /* -R means put data into text segment */ 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++; /* Skip the rest */ break; case 'W': /* -W means don't warn about things */ break; case 'I': /* Add directory to path for includes */ dirtmp = (struct directory_stack *) xmalloc(sizeof(struct directory_stack)); /* New one goes on the end */ dirtmp->next = 0; if(include == 0) include = dirtmp; else include_tail->next = dirtmp; /* Tail follows the last one */ include_tail = dirtmp; /* Rest of argument is include file-name. */ if(*arg) dirtmp->fname = arg; else if (work_argc){ /* Want next arg for a file-name. */ /* This is not a file-name. */ *work_argv = NULL; work_argc--; dirtmp->fname = *++work_argv; } else as_warn("I expected a filename after -I."); arg = ""; /* Finished with this arg. */ break; case 'g': /* generate stabs for debugging assembly code */ break; case 'n': #ifdef PPC if(strcmp(arg-1, "no_ppc601") == 0) goto unknown_flag; #endif /* no default .text section */ 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 = ""; /* Finished with this arg. */ flagseen[(int)'k'] = TRUE; break; } goto unknown_flag; case 's': if(strcmp(arg-1, "static") == 0){ arg = ""; /* Finished with this arg. */ flagseen[(int)'k'] = FALSE; break; } goto unknown_flag; case 'N': if(strcmp(arg-1, "NEXTSTEP-deployment-target") == 0){ arg = ""; /* Finished with this arg. */ /* Want next arg for a <release_tag> */ if(work_argc){ /* This, "-NEXTST..." is not a file-name. */ *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': /* use new features incompatible with 3.2 */ break; case 'V': /* as driver's -V, verbose, flag */ break; case 'a': if(strcmp(arg-1, "arch_multiple") == 0){ arch_multiple = 1; arg = ""; /* Finished with this arg. */ break; } else if(strcmp(arg-1, "arch") == 0){ arg = ""; /* Finished with this arg. */ /* Want next arg for a <arch_type> */ if(work_argc){ /* This, "-arch" is not a file-name. */ *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 /* defined(PPC) && !defined(ARCH64) */ #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 #if defined(I386) && !defined(ARCH64) 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, "pentium4") ==0){ if(archflag_cpusubtype != -1 && archflag_cpusubtype != CPU_SUBTYPE_PENTIUM_4) as_fatal("can't specify more " "than one -arch flag "); specific_archflag = *work_argv; archflag_cpusubtype = CPU_SUBTYPE_PENTIUM_4; } 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 #if defined(I386) && defined(ARCH64) if(strcmp(*work_argv, "x86_64") != 0) as_fatal("I expected 'x86_64' 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; } /* fall through for non -arch flag */ 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; } } /* * We have just processed a "-..." arg, which was not a * file-name. Smash it so the * things that look for filenames won't ever see it. * * Whatever work_argv points to, it has already been used * as part of a flag, so DON'T re-use it as a filename. */ *work_argv = NULL; /* NULL means 'not a file-name' */ } if(flagseen['g'] == TRUE && flagseen['n'] == TRUE) as_fatal("-g can't be specified if -n is specified"); /* * If we haven't seen a -force_cpusubtype_ALL or an -arch flag for a * specific architecture then let the machine instructions in the * assembly determine the cpusubtype of the output file. */ if(force_cpusubtype_ALL_for_cputype(md_cputype) == TRUE) force_cpusubtype_ALL = TRUE; if(force_cpusubtype_ALL && specific_archflag) archflag_cpusubtype = -1; /* * Test to see if the AS_SECURE_LOG_FILE environment * variable is set and save the value. */ secure_log_file = getenv("AS_SECURE_LOG_FILE"); /* * Call the initialization routines. */ #ifdef OLD_PROJECTBUILDER_INTERFACE check_for_ProjectBuilder(); /* messages.c */ #endif /* OLD_PROJECTBUILDER_INTERFACE */ symbol_begin(); /* symbols.c */ sections_begin(); /* sections.c */ read_begin(); /* read.c */ #ifdef PPC if(flagseen[(int)'p'] == TRUE) ppcasm_read_begin(); /* read.c */ #endif /* PPC */ md_begin(); /* MACHINE.c */ input_scrub_begin(); /* input_scrub.c */ /* Here with flags set up in flagseen[]. */ perform_an_assembly_pass(argc, argv); /* Assemble it. */ if(seen_at_least_1_file() && bad_error != TRUE){ layout_addresses(); write_object(out_file_name); } input_scrub_end(); md_end(); /* MACHINE.c */ return(bad_error); /* WIN */ }