Пример #1
0
int
main(
int argc,
char **argv,
char **envp)
{
    int i;
    unsigned long j;
    struct arch_flag *arch_flags;
    unsigned long narch_flags;
    enum bool all_archs;
    char **files;

	progname = argv[0];

	arch_flags = NULL;
	narch_flags = 0;
	all_archs = FALSE;

	output = stdout;
	
	cmd_flags.nfiles = 0;
	cmd_flags.c = FALSE;
	cmd_flags.x = FALSE;
	cmd_flags.ofile_name = NULL;
	cmd_flags.ofile_path = NULL;

        files = allocate(sizeof(char *) * argc);
	for(i = 1; i < argc; i++){
	    if(argv[i][0] == '-'){
		if(argv[i][1] == '\0'){
		    for( ; i < argc; i++)
			files[cmd_flags.nfiles++] = argv[i];
		    break;
		}
		if(strcmp(argv[i], "-arch") == 0){
		    if(i + 1 == argc){
			error("missing argument(s) to %s option", argv[i]);
			usage();
		    }
		    if(strcmp("all", argv[i+1]) == 0){
			all_archs = TRUE;
		    }
		    else{
			arch_flags = reallocate(arch_flags,
				(narch_flags + 1) * sizeof(struct arch_flag));
			if(get_arch_from_flag(argv[i+1],
					      arch_flags + narch_flags) == 0){
			    error("unknown architecture specification flag: "
				  "%s %s", argv[i], argv[i+1]);
			    arch_usage();
			    usage();
			}
			narch_flags++;
		    }
		    i++;
		}
		else{
		    for(j = 1; argv[i][j] != '\0'; j++){
			switch(argv[i][j]){
			case 'c':
			    cmd_flags.c = TRUE;
			    break;
			case 'x':
			    cmd_flags.x = TRUE;
			    break;
			case 'n':
			    cmd_flags.n = TRUE;
			    break;
			case 'o':
			    cmd_flags.o = TRUE;
			    break;
			default:
			    error("invalid argument -%c", argv[i][j]);
			    usage();
			}
		    }
		    if(cmd_flags.n == TRUE && cmd_flags.ofile_name == NULL){
			if(i + 1 == argc){
			    error("missing arguments to -n");
			    usage();
			}
			cmd_flags.ofile_name  = upper_string(argv[i+1]);
			i += 1;
		    }
		    if(cmd_flags.o == TRUE && cmd_flags.ofile_path == NULL){
			if(i + 1 == argc){
			    error("missing arguments to -o");
			    usage();
			}
			cmd_flags.ofile_path  = argv[i+1];
			i += 1;
		    }
		}
		continue;
	    }
	    files[cmd_flags.nfiles++] = argv[i];
	}
	if (cmd_flags.ofile_name == NULL) {
	    if (cmd_flags.nfiles == 0)
		cmd_flags.ofile_name = upper_string("a.out");
	    else
		cmd_flags.ofile_name = upper_string(files[0]);
	}
	if (cmd_flags.o == TRUE) {
	    output = fopen(cmd_flags.ofile_path, "w");
	    if (output == NULL) {
		error("couldn't open output file %s\n",cmd_flags.ofile_path);
		output = stdout;
	    }
	}

	for(j = 0; j < cmd_flags.nfiles; j++)
	    ofile_process(files[j], arch_flags, narch_flags, all_archs, FALSE,
			  FALSE, TRUE, nm, &cmd_flags);
	if(cmd_flags.nfiles == 0)
	    ofile_process("a.out",  arch_flags, narch_flags, all_archs, FALSE,
			  FALSE, TRUE, nm, &cmd_flags);

	if (cmd_flags.ofile_name != NULL)
	    free(cmd_flags.ofile_name);
	    
	if(errors == 0)
	    return(EXIT_SUCCESS);
	else
	    return(EXIT_FAILURE);
}
Пример #2
0
int
main(
int argc,
char **argv,
char **envp)
{
    const char *LIB = "../libexec/as/";
    const char *LOCALLIB = "../local/libexec/as/";
    const char *AS = "/as";

    int i, j;
    uint32_t count, verbose, run_clang;
    char *p, c, *arch_name, *as, *as_local;
    char **new_argv;
    const char *CLANG = "clang";
    char *prefix, buf[MAXPATHLEN], resolved_name[PATH_MAX];
    uint32_t bufsize;
    struct arch_flag arch_flag;
    const struct arch_flag *arch_flags, *family_arch_flag;
    enum bool oflag_specified, qflag, Qflag, some_input_files;

	progname = argv[0];
	arch_name = NULL;
	verbose = 0;
	run_clang = 0;
	oflag_specified = FALSE;
	qflag = FALSE;
	Qflag = FALSE;
	some_input_files = FALSE;
	/*
	 * Construct the prefix to the assembler driver.
	 */
	bufsize = MAXPATHLEN;
	p = buf;
	i = _NSGetExecutablePath(p, &bufsize);
	if(i == -1){
	    p = allocate(bufsize);
	    _NSGetExecutablePath(p, &bufsize);
	}
	prefix = realpath(p, resolved_name);
	if(realpath == NULL)
	    system_fatal("realpath(3) for %s failed", p);
	p = rindex(prefix, '/');
	if(p != NULL)
	    p[1] = '\0';
	/*
	 * Process the assembler flags exactly like the assembler would (except
	 * let the assembler complain about multiple flags, bad combinations of
	 * flags, unknown single letter flags and the like).  The main thing
	 * here is to parse out the "-arch <arch_flag>" and to do so the
	 * multiple argument and multiple character flags need to be known how
	 * to be stepped over correctly.
	 */
	for(i = 1; i < argc; i++){
	    /*
	     * The assembler flags start with '-' except that "--" is recognized
	     * as assemble from stdin and that flag "--" is not allowed to be
	     * grouped with other flags (so "-a-" is not the same as "-a --").
	     */
	    if(argv[i][0] == '-' &&
	       !(argv[i][1] == '-' && argv[i][2] == '\0')){
		/*
		 * Treat a single "-" as reading from stdin input also.
		 */
		if(argv[i][1] == '\0')
		    some_input_files = TRUE;
		/*
		 * the assembler allows single letter flags to be grouped
		 * together so "-abc" is the same as "-a -b -c".  So that
		 * logic must be followed here.
		 */
		for(p = &(argv[i][1]); (c = *p); p++){
		    /*
		     * The assembler simply ignores the high bit of flag
		     * characters and not treat them as different characters
		     * as they are (but the argument following the flag
		     * character is not treated this way).  So it's done
		     * here as well to match it.
		     */
		    c &= 0x7F;
		    switch(c){
		    /*
		     * Flags that take a single argument.  The argument is the
		     * rest of the current argument if there is any or the it is
		     * the next argument.  Again errors like missing arguments
		     * are not handled here but left to the assembler.
		     */
		    case 'o':	/* -o name */
			oflag_specified = TRUE;
		    case 'I':	/* -I directory */
		    case 'm':	/* -mc68000, -mc68010 and mc68020 */
		    case 'N':	/* -NEXTSTEP-deployment-target */
			/*
			 * We want to skip the next argv if the value is not
			 * contained in this argv eg: -I dir .
			 */
			if(p[1] == '\0')
			    i++;
			/*
			 * And in case the value is contained in this argv
			 * (eg: -Idir), skip the rest.
			 */
			while(p[1])
			    p++;
			p = " "; /* Finished with this arg. */
			break;
	    	    case 'g':
			if(strcmp(p, "gstabs") == 0 ||
	    		   strcmp(p, "gdwarf2") == 0 ||
			   strcmp(p, "gdwarf-2") == 0){
			    p = " "; /* Finished with this arg. */
			}
			break;
		    case 'd':
			if(strcmp(p, "dynamic") == 0){
			    p = " "; /* Finished with this arg. */
			}
			break;
		    case 's':
			if(strcmp(p, "static") == 0){
			    p = " "; /* Finished with this arg. */
			}
			break;
		    case 'a':
		        if(strcmp(p, "arch_multiple") == 0){
			    p = " "; /* Finished with this arg. */
			}
			if(strcmp(p, "arch") == 0){
			    if(i + 1 >= argc)
				fatal("missing argument to %s option", argv[i]);
			    if(arch_name != NULL)
				fatal("more than one %s option (not allowed, "
				      "use cc(1) instead)", argv[i]);
			    arch_name = argv[i+1];
			    p = " "; /* Finished with this arg. */
			    i++;
			    break;
			}
			/* fall through for non "-arch" */
		    case 'f':
			if(strcmp(p, "force_cpusubtype_ALL") == 0){
			    p = " "; /* Finished with this arg. */
			    break;
			}
		    case 'k':
		    case 'v':
		    case 'W':
		    case 'L':
		    case 'l':
		    default:
			/* just recognize it, do nothing */
			break;
		    case 'q':
			qflag = TRUE;
			break;
		    case 'Q':
			Qflag = TRUE;
			break;
		    case 'V':
			verbose = 1;
			break;
		    }
		}
	    }
	    else{
		some_input_files = TRUE;
	    }
	}

	/*
	 * Construct the name of the assembler to run from the given -arch
	 * <arch_flag> or if none then from the value returned from
	 * get_arch_from_host().
	 */
	if(arch_name == NULL){
	    if(get_arch_from_host(&arch_flag, NULL)){
#if __LP64__
		/*
		 * If runing as a 64-bit binary and on an Intel x86 host
		 * default to the 64-bit assember.
		 */
		if(arch_flag.cputype == CPU_TYPE_I386)
		    arch_flag = *get_arch_family_from_cputype(CPU_TYPE_X86_64);
#endif /* __LP64__ */
		arch_name = arch_flag.name;
	    }
	    else
		fatal("unknown host architecture (can't determine which "
		      "assembler to run)");
	}
	else{
	    /*
	     * Convert a possible machine specific architecture name to a
	     * family name to base the name of the assembler to run.
	     */
	    if(get_arch_from_flag(arch_name, &arch_flag) != 0){
		family_arch_flag =
			get_arch_family_from_cputype(arch_flag.cputype);
		if(family_arch_flag != NULL)
		    arch_name = (char *)(family_arch_flag->name);
	    }

	}

	if(qflag == TRUE && Qflag == TRUE){
	    printf("%s: can't specifiy both -q and -Q\n", progname);
	    exit(1);
	}
	/*
	 * If the environment variable AS_INTEGRATED_ASSEMBLER is set then set
	 * the qflag to call clang(1) with -integrated-as unless the -Q flag is
	 * set and do this for the supported architectures.
	 */
	if(Qflag == FALSE &&
           getenv("AS_INTEGRATED_ASSEMBLER") != NULL &&
	   (arch_flag.cputype == CPU_TYPE_X86_64 ||
	    arch_flag.cputype == CPU_TYPE_I386 ||
	    arch_flag.cputype == CPU_TYPE_ARM64 ||
	    arch_flag.cputype == CPU_TYPE_ARM)){
	    qflag = TRUE;
	}
	if(qflag == TRUE &&
	   (arch_flag.cputype != CPU_TYPE_X86_64 &&
	    arch_flag.cputype != CPU_TYPE_I386 &&
	    arch_flag.cputype != CPU_TYPE_ARM64 &&
	    arch_flag.cputype != CPU_TYPE_ARM)){
	    printf("%s: can't specifiy -q with -arch %s\n", progname,
		   arch_flag.name);
	    exit(1);
	}

	/*
	 * When the target assembler is for arm64, for now:
	 *   rdar://8913781 ARM64: cctools 'as' driver should invoke clang
	 *		    for ARM64 assembly files
	 * use clang.  Later for:
	 *   rdar://8928193 ARM64: Standalone 'as' driver
	 * when there is and llvm-mc based standalone 'as' driver and it is
 	 * in the usual place as the other target assemblers this use of clang
	 * will be removed.
	 */ 
	if(arch_flag.cputype == CPU_TYPE_ARM64){
	    if(Qflag == TRUE){
		printf("%s: can't specifiy -Q with -arch arm64\n", progname);
		exit(1);
	    }
	    run_clang = 1;
	}

#if 0
/*
 * See rdar://9801003 where this will be changed before before NMOs and NMiOS.
 */
	/*
	 * Use the LLVM integrated assembler as the default with the as(1)
	 * driver for Intel (64-bit & 32-bit) as well as ARM for 32-bit too
	 * (64-bit ARM handled above) via running clang.
	 */
	if(arch_flag.cputype == CPU_TYPE_X86_64 ||
	   arch_flag.cputype == CPU_TYPE_I386 ||
	   arch_flag.cputype == CPU_TYPE_ARM)
	    run_clang = 1;
#endif

	/*
	 * Use the clang as the assembler if is the default or asked to with
	 * the -q flag. But don't use it asked to use the system assembler
	 * with the -Q flag.
	 */
	if((run_clang || qflag) && !Qflag &&
	   (arch_flag.cputype == CPU_TYPE_X86_64 ||
	    arch_flag.cputype == CPU_TYPE_I386 ||
	    arch_flag.cputype == CPU_TYPE_ARM64 ||
	    arch_flag.cputype == CPU_TYPE_ARM)){
	    as = makestr(prefix, CLANG, NULL);
	    if(access(as, F_OK) != 0){
		printf("%s: assembler (%s) not installed\n", progname, as);
		exit(1);
	    }
	    new_argv = allocate((argc + 8) * sizeof(char *));
	    new_argv[0] = as;
	    j = 1;
	    /*
	     * Add "-x assembler" in case the input does not end in .s this must
	     * come before "-" or the clang driver will issue an error:
	     * "error: -E or -x required when input is from standard input"
	     */
	    new_argv[j] = "-x";
	    j++;
	    new_argv[j] = "assembler";
	    j++;
	    /*
	     * If we have not seen some some_input_files or a "-" or "--" to
	     * indicate we are assembling stdin add a "-" so clang will
	     * assemble stdin as as(1) would.
	     */
	    if(some_input_files == FALSE){
		new_argv[j] = "-";
		j++;
	    }
	    for(i = 1; i < argc; i++){
		/*
		 * Translate as(1) use of "--" for stdin to clang's use of "-".
		 */
		if(strcmp(argv[i], "--") == 0){
		    new_argv[j] = "-";
		    j++;
		}
		/*
		 * Do not pass command line argument that are Unknown to
		 * to clang.
		 */
		else if(strcmp(argv[i], "-V") != 0 &&
		   strcmp(argv[i], "-q") != 0 &&
		   strcmp(argv[i], "-Q") != 0){
		    new_argv[j] = argv[i];
		    j++;
		}
	    }
	    /*
	     * clang requires a "-o a.out" if not -o is specified.
	     */
	    if(oflag_specified == FALSE){
		new_argv[j] = "-o";
		j++;
		new_argv[j] = "a.out";
		j++;
	    }
	    /* Add -integrated-as or clang will run as(1). */
	    new_argv[j] = "-integrated-as";
	    j++;
	    /* Add -c or clang will run ld(1). */
	    new_argv[j] = "-c";
	    j++;
	    new_argv[j] = NULL;
	    if(execute(new_argv, verbose))
		exit(0);
	    else
		exit(1);
	}

	/*
	 * If this assembler exist try to run it else print an error message.
	 */
	as = makestr(prefix, LIB, arch_name, AS, NULL);
	new_argv = allocate((argc + 1) * sizeof(char *));
	new_argv[0] = as;
	j = 1;
	for(i = 1; i < argc; i++){
	    /*
	     * Do not pass command line argument that are unknown to as.
	     */
	    if(strcmp(argv[i], "-q") != 0 &&
	       strcmp(argv[i], "-Q") != 0){
		new_argv[j] = argv[i];
		j++;
	    }
	}
	new_argv[j] = NULL;
	if(access(as, F_OK) == 0){
	    argv[0] = as;
	    if(execute(new_argv, verbose))
		exit(0);
	    else
		exit(1);
	}
	as_local = makestr(prefix, LOCALLIB, arch_name, AS, NULL);
	new_argv[0] = as_local;
	if(access(as_local, F_OK) == 0){
	    argv[0] = as_local;
	    if(execute(new_argv, verbose))
		exit(0);
	    else
		exit(1);
	}
	printf("%s: assembler (%s or %s) for architecture %s not installed\n",
	       progname, as, as_local, arch_name);
	arch_flags = get_arch_flags();
	count = 0;
	for(i = 0; arch_flags[i].name != NULL; i++){
	    as = makestr(prefix, LIB, arch_flags[i].name, AS, NULL);
	    if(access(as, F_OK) == 0){
		if(count == 0)
		    printf("Installed assemblers are:\n");
		printf("%s for architecture %s\n", as, arch_flags[i].name);
		count++;
	    }
	    else{
		as_local = makestr(prefix, LOCALLIB, arch_flags[i].name, AS,
				   NULL);
		if(access(as_local, F_OK) == 0){
		    if(count == 0)
			printf("Installed assemblers are:\n");
		    printf("%s for architecture %s\n", as_local,
			   arch_flags[i].name);
		    count++;
		}
	    }
	}
	if(count == 0)
	    printf("%s: no assemblers installed\n", progname);
	exit(1);
}
Пример #3
0
/*
 * The codesign_allocate(1) tool has the following usage:
 *
 *	codesign_allocate -i oldfile -a arch size ...  -o newfile
 *
 * Where the oldfile is a Mach-O file that is input for the dynamic linker
 * and it creates or adds an
 */
int
main(
    int argc,
    char **argv,
    char **envp)
{
    uint32_t i;
    char *input, *output, *endp;
    struct arch *archs;
    uint32_t narchs;

    progname = argv[0];
    input = NULL;
    output = NULL;
    archs = NULL;
    narchs = 0;
    for(i = 1; i < argc; i++) {
        if(strcmp(argv[i], "-i") == 0) {
            if(i + 1 == argc) {
                error("missing argument to: %s option", argv[i]);
                usage();
            }
            if(input != NULL) {
                error("more than one: %s option specified", argv[i]);
                usage();
            }
            input = argv[i+1];
            i++;
        }
        else if(strcmp(argv[i], "-o") == 0) {
            if(i + 1 == argc) {
                error("missing argument to: %s option", argv[i]);
                usage();
            }
            if(output != NULL) {
                error("more than one: %s option specified", argv[i]);
                usage();
            }
            output = argv[i+1];
            i++;
        }
        else if(strcmp(argv[i], "-a") == 0) {
            if(i + 2 == argc) {
                error("missing argument(s) to: %s option", argv[i]);
                usage();
            }
            else {
                arch_signs = reallocate(arch_signs,
                                        (narch_signs + 1) * sizeof(struct arch_sign));
                if(get_arch_from_flag(argv[i+1],
                                      &(arch_signs[narch_signs].arch_flag)) == 0) {
                    error("unknown architecture specification flag: "
                          "%s %s %s", argv[i], argv[i+1], argv[i+2]);
                    arch_usage();
                    usage();
                }
                arch_signs[narch_signs].datasize =
                    strtoul(argv[i+2], &endp, 0);
                if(*endp != '\0')
                    fatal("size for '-a %s %s' not a proper number",
                          argv[i+1], argv[i+2]);
                if((arch_signs[narch_signs].datasize % 16) != 0)
                    fatal("size for '-a %s %s' not a multiple of 16",
                          argv[i+1], argv[i+2]);
                arch_signs[narch_signs].found = FALSE;
                narch_signs++;
                i += 2;
            }
        }
        else if(strcmp(argv[i], "-A") == 0) {
            if(i + 3 == argc) {
                error("missing argument(s) to: %s option", argv[i]);
                usage();
            }
            else {
                arch_signs = reallocate(arch_signs,
                                        (narch_signs + 1) * sizeof(struct arch_sign));

                arch_signs[narch_signs].arch_flag.cputype =
                    strtoul(argv[i+1], &endp, 0);
                if(*endp != '\0')
                    fatal("cputype for '-A %s %s %s' not a proper number",
                          argv[i+1], argv[i+2], argv[i+3]);

                arch_signs[narch_signs].arch_flag.cpusubtype =
                    strtoul(argv[i+2], &endp, 0);
                if(*endp != '\0')
                    fatal("cpusubtype for '-A %s %s %s' not a proper "
                          "number", argv[i+1], argv[i+2], argv[i+3]);

                arch_signs[narch_signs].arch_flag.name = (char *)
                        get_arch_name_from_types(
                            arch_signs[narch_signs].arch_flag.cputype,
                            arch_signs[narch_signs].arch_flag.cpusubtype);

                arch_signs[narch_signs].datasize =
                    strtoul(argv[i+3], &endp, 0);
                if(*endp != '\0')
                    fatal("size for '-A %s %s %s' not a proper number",
                          argv[i+1], argv[i+2], argv[i+3]);
                if((arch_signs[narch_signs].datasize % 16) != 0)
                    fatal("size for '-A %s %s %s' not a multiple of 16",
                          argv[i+1], argv[i+2], argv[i+3]);

                arch_signs[narch_signs].found = FALSE;
                narch_signs++;
                i += 3;
            }
        }
        else {
            error("unknown flag: %s", argv[i]);
            usage();
        }
    }
    if(input == NULL || output == NULL || narch_signs == 0)
        usage();

    breakout(input, &archs, &narchs, FALSE);
    if(errors)
        exit(EXIT_FAILURE);

    checkout(archs, narchs);

    process(archs, narchs);

    for(i = 0; i < narch_signs; i++) {
        if(arch_signs[i].found == FALSE)
            fatal("input file: %s does not contain a matching architecture "
                  "for specified '-a %s %u' option", input,
                  arch_signs[i].arch_flag.name, arch_signs[i].datasize);
    }

    writeout(archs, narchs, output, 0777, TRUE, FALSE, FALSE, NULL);

    if(errors)
        return(EXIT_FAILURE);
    else
        return(EXIT_SUCCESS);
}
Пример #4
0
/*
 * The ctf_insert(1) tool has the following usage:
 *
 *	ctf_insert input -arch arch ctf_file ...  -o output
 * 
 * Where the input is a Mach-O file that is the ctf_file(s) are to be inserted
 * into and output is the file to be created.
 */
int
main(
int argc,
char **argv,
char **envp)
{
    uint32_t i;
    char *input, *output, *contents;
    struct arch *archs;
    uint32_t narchs;
    struct stat stat_buf;
    int fd;

	progname = argv[0];
	input = NULL;
	output = NULL;
	archs = NULL;
	narchs = 0;
	for(i = 1; i < argc; i++){
	    if(strcmp(argv[i], "-o") == 0){
		if(i + 1 == argc){
		    error("missing argument to: %s option", argv[i]);
		    usage();
		}
		if(output != NULL){
		    error("more than one: %s option specified", argv[i]);
		    usage();
		}
		output = argv[i+1];
		i++;
	    }
	    else if(strcmp(argv[i], "-arch") == 0){
		if(i + 2 == argc){
		    error("missing argument(s) to: %s option", argv[i]);
		    usage();
		}
		else{
		    arch_ctfs = reallocate(arch_ctfs,
			    (narch_ctfs + 1) * sizeof(struct arch_ctf));
		    if(get_arch_from_flag(argv[i+1],
				  &(arch_ctfs[narch_ctfs].arch_flag)) == 0){
			error("unknown architecture specification flag: "
			      "%s %s %s", argv[i], argv[i+1], argv[i+2]);
			arch_usage();
			usage();
		    }
		    if((fd = open(argv[i+2], O_RDONLY, 0)) == -1)
			system_fatal("can't open file: %s", argv[i+2]);
		    if(fstat(fd, &stat_buf) == -1)
			system_fatal("can't stat file: %s", argv[i+2]);
		    /*
		     * For some reason mapping files with zero size fails
		     * so it has to be handled specially.
		     */
		    contents = NULL;
		    if(stat_buf.st_size != 0){
			contents = mmap(0, stat_buf.st_size,
					PROT_READ|PROT_WRITE,
				        MAP_FILE|MAP_PRIVATE, fd, 0);
			if((intptr_t)contents == -1)
			    system_error("can't map file : %s", argv[i+2]);
		    }
		    arch_ctfs[narch_ctfs].filename = argv[i+2];
		    arch_ctfs[narch_ctfs].contents = contents;
		    arch_ctfs[narch_ctfs].size = stat_buf.st_size;
		    arch_ctfs[narch_ctfs].arch_found = FALSE;
		    narch_ctfs++;
		    i += 2;
		}
	    }
	    else{
		if(input != NULL){
		    error("more than one input file file: %s specified",
			  input);
		    usage();
		}
		input = argv[i];
	    }
	}
	if(input == NULL || output == NULL || narch_ctfs == 0)
	    usage();

	breakout(input, &archs, &narchs, FALSE);
	if(errors)
	    exit(EXIT_FAILURE);

	checkout(archs, narchs);

	process(archs, narchs);

	for(i = 0; i < narch_ctfs; i++){
	    if(arch_ctfs[i].arch_found == FALSE)
		fatal("input file: %s does not contain a matching architecture "
		      "for specified '-arch %s %s' option", input,
		      arch_ctfs[i].arch_flag.name, arch_ctfs[i].filename);
	}

	writeout(archs, narchs, output, 0777, TRUE, FALSE, FALSE, FALSE, NULL);

	if(errors)
	    return(EXIT_FAILURE);
	else
	    return(EXIT_SUCCESS);
}
Пример #5
0
int
main(
int argc,
char **argv,
char **envp)
{
    int i;
    enum bool args_left;
    struct flags flag;
    struct arch_flag *arch_flags;
    unsigned long narch_flags;
    enum bool all_archs;

	progname = argv[0];
	arch_flags = NULL;
	narch_flags = 0;
	all_archs = FALSE;

	flag.nfiles = 0;
	flag.m = FALSE;
	flag.l = FALSE;
	flag.x = FALSE;

	for(i = 1; i < argc; i++){
	    if(argv[i][0] == '-'){
		if(argv[i][1] == '\0'){
		    flag.nfiles += argc - i - 1;
		    break;
		}
		if(strcmp(argv[i], "-m") == 0){
		    flag.m = TRUE;
		    continue;
		}
		if(strcmp(argv[i], "-l") == 0){
		    flag.l = TRUE;
		    flag.m = TRUE;
		    continue;
		}
		if(strcmp(argv[i], "-x") == 0){
		    flag.x = TRUE;
		    flag.m = TRUE;
		    continue;
		}
		if(strcmp(argv[i], "-arch") == 0){
		    if(i + 1 == argc){
			error("missing argument(s) to %s option", argv[i]);
			usage();
		    }
		    if(strcmp("all", argv[i+1]) == 0){
			all_archs = TRUE;
		    }
		    else{
			arch_flags = reallocate(arch_flags,
				(narch_flags + 1) * sizeof(struct arch_flag));
			if(get_arch_from_flag(argv[i+1],
					      arch_flags + narch_flags) == 0){
			    error("unknown architecture specification flag: "
				  "%s %s", argv[i], argv[i+1]);
			    arch_usage();
			    usage();
			}
			narch_flags++;
		    }
		    i++;
		    continue;
		}
	    }
	    flag.nfiles++;
	}

	if(flag.m == FALSE)
	    printf("__TEXT\t__DATA\t__OBJC\tothers\tdec\thex\n");

	args_left = TRUE;
	for (i = 1; i < argc; i++) {
	    if(args_left == TRUE && argv[i][0] == '-'){
		if(argv[i][1] == '\0'){
		    args_left = FALSE;
		    continue;
		}
		if(strcmp(argv[i], "-m") == 0)
		    continue;
		if(strcmp(argv[i], "-l") == 0)
		    continue;
		if(strcmp(argv[i], "-x") == 0)
		    continue;
		if(strcmp(argv[i], "-arch") == 0){
		    i++;
		    continue;
		}
	    }
	    ofile_process(argv[i], arch_flags, narch_flags, all_archs, FALSE,
			  TRUE, TRUE, size, &flag);
	}
	if(flag.nfiles == 0)
	    ofile_process("a.out", arch_flags, narch_flags, all_archs, FALSE,
			  TRUE, TRUE, size, &flag);
	if(errors == 0)
	    return(EXIT_SUCCESS);
	else
	    return(EXIT_FAILURE);
}
Пример #6
0
int
main(
int argc,
char **argv,
char **envp)
{
    struct flags flags;
    int i;
    uint32_t j, nfiles;
    char *endp;
    struct arch_flag *arch_flags;
    uint32_t narch_flags;
    enum bool all_archs, rest_args_files, use_member_syntax;
    struct stat stat_buf;

	progname = argv[0];

	nfiles = 0;
	arch_flags = NULL;
	narch_flags = 0;
	all_archs = FALSE;

	flags.treat_as_data = FALSE;
	flags.print_offsets = FALSE;
	flags.offset_format = NULL;
	flags.all_sections = FALSE;
	flags.minimum_length = 4;

	rest_args_files = FALSE;
	for(i = 1; i < argc; i++){
	    if(rest_args_files == FALSE && argv[i][0] == '-'){
		if(argv[i][1] == '\0')
		    flags.treat_as_data = TRUE;
		else if(strcmp(argv[i], "--") == 0)
		    rest_args_files = TRUE;
		else if(strcmp(argv[i], "-arch") == 0){
		    if(i + 1 == argc){
			error("missing argument(s) to %s option", argv[i]);
			usage();
		    }
		    if(strcmp("all", argv[i+1]) == 0){
			all_archs = TRUE;
		    }
		    else{
			arch_flags = reallocate(arch_flags,
				(narch_flags + 1) * sizeof(struct arch_flag));
			if(get_arch_from_flag(argv[i+1],
					      arch_flags + narch_flags) == 0){
			    error("unknown architecture specification flag: "
				  "%s %s", argv[i], argv[i+1]);
			    arch_usage();
			    usage();
			}
			narch_flags++;
		    }
		    i++;
		}
		else if(strcmp(argv[i], "-n") == 0){
		    if(i + 1 == argc){
			error("missing argument to %s option", argv[i]);
			usage();
		    }
		    flags.minimum_length = strtoul(argv[i+1], &endp, 10);
		    if(*endp != '\0'){
			error("invalid decimal number in option: %s %s",
			      argv[i], argv[i+1]);
			usage();
		    }
		    i++;
		}
		else if(strcmp(argv[i], "-t") == 0){
		    if(i + 1 == argc){
			error("missing argument to %s option", argv[i]);
			usage();
		    }
		    if(argv[i+1][1] != '\0'){
			error("invalid argument to option: %s %s",
			      argv[i], argv[i+1]);
			usage();
		    }
		    switch(argv[i+1][0]){
		    case 'd':
			flags.print_offsets = TRUE;
			flags.offset_format = "%d";
			break;
		    case 'o':
			flags.print_offsets = TRUE;
			flags.offset_format = "%o";
			break;
		    case 'x':
			flags.print_offsets = TRUE;
			flags.offset_format = "%x";
			break;
		    default:
			error("invalid argument to option: %s %s",
			      argv[i], argv[i+1]);
			usage();
		    }
		    i++;
		}
		else{
		    endp = NULL;
		    for(j = 1; argv[i][j] != '\0' && endp == NULL; j++){
			switch(argv[i][j]){
			case 'o':
			    flags.print_offsets = TRUE;
			    flags.offset_format = "%7lu";
			    break;
			case 'a':
			    flags.all_sections = TRUE;
			    break;
			default:
			    if(!isdigit(argv[i][j])){
				error("unknown flag: %s", argv[i]);
				usage();
			    }
			    flags.minimum_length = strtoul(argv[i]+j,&endp,10);
			    if(*endp != '\0'){
				error("invalid decimal number in flag: %s",
				argv[i]);
				usage();
			    }
			}
		    }
		}
	    }
	    else{
		nfiles++;
	    }
	}

	/*
	 * Process the file or stdin if there are no files.
	 */
	rest_args_files = FALSE;
	if(nfiles != 0){
	    for(i = 1; i < argc; i++){
		if(argv[i][0] != '-' || rest_args_files == TRUE){
		    if(flags.treat_as_data == TRUE){
			if(freopen(argv[i], "r", stdin) == NULL)
			    system_error("can't open: %s", argv[i]);
			rewind(stdin);
			find(UINT_MAX, &flags);
		    }
		    else{
			/*
			 * If there's a filename that's an exact match then use
			 * that, else fall back to the member syntax.
			 */
			if(stat(argv[i], &stat_buf) == 0)
			    use_member_syntax = FALSE;
			else
			    use_member_syntax = TRUE;
			ofile_process(argv[i], arch_flags, narch_flags,
				      all_archs, TRUE, TRUE, use_member_syntax,
				      ofile_processor,&flags);
		    }
		}
		else if(strcmp(argv[i], "-arch") == 0 ||
			strcmp(argv[i], "-n") == 0 ||
			strcmp(argv[i], "-t") == 0)
		    i++;
		else if(strcmp(argv[i], "--") == 0)
		    rest_args_files = TRUE;
	    }
	}
	else{
	    find(UINT_MAX, &flags);
	}
	if(errors == 0)
	    return(EXIT_SUCCESS);
	else
	    return(EXIT_FAILURE);
}
Пример #7
0
int
main(
int argc,
char **argv,
char **envp)
{
    const char *LIB = "../libexec/as/";
    const char *LOCALLIB = "../local/libexec/as/";
    const char *AS = "/as";
    const char *LLVM_MC = "llvm-mc";

    int i, j;
    uint32_t count, verbose, run_llvm_mc;
    char *p, c, *arch_name, *as, *as_local;
    char **llvm_mc_argv;
    char *prefix, buf[MAXPATHLEN], resolved_name[PATH_MAX];
    unsigned long bufsize;
    struct arch_flag arch_flag;
    const struct arch_flag *arch_flags, *family_arch_flag;
    enum bool oflag_specified;

	progname = argv[0];
	arch_name = NULL;
	verbose = 0;
	run_llvm_mc = 0;
	oflag_specified = FALSE;
	/*
	 * Construct the prefix to the assembler driver.
	 */
	bufsize = MAXPATHLEN;
	p = buf;
	i = _NSGetExecutablePath(p, &bufsize);
	if(i == -1){
	    p = allocate(bufsize);
	    _NSGetExecutablePath(p, &bufsize);
	}
	prefix = realpath(p, resolved_name);
	if(realpath == NULL)
	    system_fatal("realpath(3) for %s failed", p);
	p = rindex(prefix, '/');
	if(p != NULL)
	    p[1] = '\0';
	/*
	 * Process the assembler flags exactly like the assembler would (except
	 * let the assembler complain about multiple flags, bad combinations of
	 * flags, unknown single letter flags and the like).  The main thing
	 * here is to parse out the "-arch <arch_flag>" and to do so the
	 * multiple argument and multiple character flags need to be known how
	 * to be stepped over correctly.
	 */
	for(i = 1; i < argc; i++){
	    /*
	     * The assembler flags start with '-' except that "--" is recognized
	     * as assemble from stdin and that flag "--" is not allowed to be
	     * grouped with other flags (so "-a-" is not the same as "-a --").
	     */
	    if(argv[i][0] == '-' &&
	       !(argv[i][1] == '-' && argv[i][2] == '0')){
		/*
		 * the assembler allows single letter flags to be grouped
		 * together so "-abc" is the same as "-a -b -c".  So that
		 * logic must be followed here.
		 */
		for(p = &(argv[i][1]); (c = *p); p++){
		    /*
		     * The assembler simply ignores the high bit of flag
		     * characters and not treat them as different characters
		     * as they are (but the argument following the flag
		     * character is not treated this way).  So it's done
		     * here as well to match it.
		     */
		    c &= 0x7F;
		    switch(c){
		    /*
		     * Flags that take a single argument.  The argument is the
		     * rest of the current argument if there is any or the it is
		     * the next argument.  Again errors like missing arguments
		     * are not handled here but left to the assembler.
		     */
		    case 'o':	/* -o name */
			oflag_specified = TRUE;
		    case 'I':	/* -I directory */
		    case 'm':	/* -mc68000, -mc68010 and mc68020 */
		    case 'N':	/* -NEXTSTEP-deployment-target */
			if(p[1] == '\0')
			    i++;
			break;

		    case 'a':
			if(strcmp(p, "arch") == 0){
			    if(i + 1 >= argc)
				fatal("missing argument to %s option", argv[i]);
			    if(arch_name != NULL)
				fatal("more than one %s option (not allowed, "
				      "use cc(1) instead)", argv[i]);
			    arch_name = argv[i+1];
			    break;
			}
			/* fall through for non "-arch" */
		    case 'f':
		    case 'k':
		    case 'g':
		    case 'v':
		    case 'W':
		    case 'L':
		    default:
			/* just recognize it, do nothing */
			break;
		    case 'l':
			if(strcmp(p, "llvm-mc") == 0)
			    run_llvm_mc = i;
			/* also just recognize 'l' and do nothing */
			break;
		    case 'V':
			verbose = 1;
			break;
		    }
		}
	    }
	}

	/*
	 * If the -llvm-mc flag was specified then run llvm-mc from the same
	 * directory as the driver.
	 */
	if(run_llvm_mc != 0){
	    as = makestr(prefix, LLVM_MC, NULL);
	    if(access(as, F_OK) != 0){
		printf("%s: assembler (%s) not installed\n", progname, as);
		exit(1);
	    }
	    llvm_mc_argv = allocate(argc + 3);
	    llvm_mc_argv[0] = as;
	    j = 1;
	    for(i = 1; i < argc; i++){
		/*
		 * Do not pass -llvm-mc
		 */
		if(i != run_llvm_mc){
		    /*
		     * Do not pass command line argument that are Unknown to
		     * to llvm-mc.
		     */
		    if(strcmp(argv[i], "-v") != 0 &&
		       strcmp(argv[i], "-V") != 0 &&
		       strcmp(argv[i], "-force_cpusubtype_ALL") != 0){
			llvm_mc_argv[j] = argv[i];
			j++;
		    }
		}
	    }
	    /*
	     * Add -filetype=obj or llvm-mc will write to stdout.
	     */
	    llvm_mc_argv[j] = "-filetype=obj";
	    j++;
	    /*
	     * llvm-mc requires a "-o a.out" if not -o is specified.
	     */
	    if(oflag_specified == FALSE){
		llvm_mc_argv[j] = "-o";
		j++;
		llvm_mc_argv[j] = "a.out";
		j++;
	    }
	    llvm_mc_argv[j] = NULL;
	    if(execute(llvm_mc_argv, verbose))
		exit(0);
	    else
		exit(1);
	}

	/*
	 * Construct the name of the assembler to run from the given -arch
	 * <arch_flag> or if none then from the value returned from
	 * get_arch_from_host().
	 */
	if(arch_name == NULL){
	    if(get_arch_from_host(&arch_flag, NULL)){
#if __LP64__
		/*
		 * If runing as a 64-bit binary and on an Intel x86 host
		 * default to the 64-bit assember.
		 */
		if(arch_flag.cputype == CPU_TYPE_I386)
		    arch_flag = *get_arch_family_from_cputype(CPU_TYPE_X86_64);
#endif /* __LP64__ */
		arch_name = arch_flag.name;
	    }
	    else
		fatal("unknown host architecture (can't determine which "
		      "assembler to run)");
	}
	else{
	    /*
	     * Convert a possible machine specific architecture name to a
	     * family name to base the name of the assembler to run.
	     */
	    if(get_arch_from_flag(arch_name, &arch_flag) != 0){
		family_arch_flag =
			get_arch_family_from_cputype(arch_flag.cputype);
		if(family_arch_flag != NULL)
		    arch_name = (char *)(family_arch_flag->name);
	    }

	}
	/*
	 * If this assembler exist try to run it else print an error message.
	 */
	as = makestr(prefix, LIB, arch_name, AS, NULL);
	if(access(as, F_OK) == 0){
	    argv[0] = as;
	    if(execute(argv, verbose))
		exit(0);
	    else
		exit(1);
	}
	as_local = makestr(prefix, LOCALLIB, arch_name, AS, NULL);
	if(access(as_local, F_OK) == 0){
	    argv[0] = as_local;
	    if(execute(argv, verbose))
		exit(0);
	    else
		exit(1);
	}
	printf("%s: assembler (%s or %s) for architecture %s not installed\n",
	       progname, as, as_local, arch_name);
	arch_flags = get_arch_flags();
	count = 0;
	for(i = 0; arch_flags[i].name != NULL; i++){
	    as = makestr(prefix, LIB, arch_flags[i].name, AS, NULL);
	    if(access(as, F_OK) == 0){
		if(count == 0)
		    printf("Installed assemblers are:\n");
		printf("%s for architecture %s\n", as, arch_flags[i].name);
		count++;
	    }
	    else{
		as_local = makestr(prefix, LOCALLIB, arch_flags[i].name, AS,
				   NULL);
		if(access(as_local, F_OK) == 0){
		    if(count == 0)
			printf("Installed assemblers are:\n");
		    printf("%s for architecture %s\n", as_local,
			   arch_flags[i].name);
		    count++;
		}
	    }
	}
	if(count == 0)
	    printf("%s: no assemblers installed\n", progname);
	exit(1);
}
Пример #8
0
int
main(
int argc,
char **argv,
char **envp)
{
    int i;
    struct cmd_flags cmd_flags;
    unsigned long j, table_size;
    struct arch_flag *arch_flags;
    unsigned long narch_flags;
    enum bool all_archs;
    char **files;

	progname = argv[0];

	arch_flags = NULL;
	narch_flags = 0;
	all_archs = FALSE;

	cmd_flags.nfiles = 0;
	cmd_flags.rldtype = FALSE;
	cmd_flags.detail = FALSE;
	cmd_flags.verification = FALSE;
	cmd_flags.trey = FALSE;
	cmd_flags.check_dynamic_binary = TRUE;

        files = allocate(sizeof(char *) * argc);
	for(i = 1; i < argc; i++){
	    if(argv[i][0] == '-'){
		if(argv[i][1] == '\0'){
		    for( ; i < argc; i++)
			files[cmd_flags.nfiles++] = argv[i];
		    break;
		}
		else if(strcmp(argv[i], "-arch") == 0){
		    if(i + 1 == argc){
			error("missing argument(s) to %s option", argv[i]);
			usage();
		    }
		    if(strcmp("all", argv[i+1]) == 0){
			all_archs = TRUE;
		    }
		    else{
			arch_flags = reallocate(arch_flags,
				(narch_flags + 1) * sizeof(struct arch_flag));
			if(get_arch_from_flag(argv[i+1],
					      arch_flags + narch_flags) == 0){
			    error("unknown architecture specification flag: "
				  "%s %s", argv[i], argv[i+1]);
			    arch_usage();
			    usage();
			}
			narch_flags++;
		    }
		    i++;
		}
		else if(strcmp(argv[i], "-dylib_table") == 0){
		    if(i + 1 == argc){
			error("missing argument(s) to %s option", argv[i]);
			usage();
		    }
		    if(dylib_table_name != NULL){
			error("more than one: %s option", argv[i]);
			usage();
		    }
		    dylib_table_name = argv[i+1];
		    dylib_table = parse_dylib_table(argv[i+1], argv[i],
						    argv[i+1]);
		    i++;
		}
		else if(strcmp(argv[i], "-seg_addr_table") == 0){
		    if(i + 1 == argc){
			error("missing argument(s) to %s option", argv[i]);
			usage();
		    }
		    if(seg_addr_table_specified == TRUE){
			error("more than one: %s option", argv[i]);
			usage();
		    }
		    seg_addr_table_specified = TRUE;
		    seg_addr_table_name = argv[i+1];
		    seg_addr_table = parse_seg_addr_table(argv[i+1],
					      argv[i], argv[i+1], &table_size);
		    i++;
		}
		else if(strcmp(argv[i], "-seg_addr_table_filename") == 0){
		    if(i + 1 == argc){
			error("missing argument(s) to %s option", argv[i]);
			usage();
		    }
		    if(seg_addr_table_filename != NULL){
			error("more than one: %s option", argv[i]);
			usage();
		    }
		    seg_addr_table_filename = argv[i+1];
		    i++;
		}
		else{
		    for(j = 1; argv[i][j] != '\0'; j++){
			switch(argv[i][j]){
			case 'r':
			    cmd_flags.rldtype = TRUE;
			    break;
			case 'd':
			    cmd_flags.detail = TRUE;
			    break;
			case 'v':
			    cmd_flags.verification = TRUE;
			    break;
			case 't':
			    cmd_flags.trey = TRUE;
			    break;
			case 'b':
			    cmd_flags.check_dynamic_binary = TRUE;
			    break;
			default:
			    error("invalid argument -%c", argv[i][j]);
			    usage();
			}
		    }
		}
		continue;
	    }
	    files[cmd_flags.nfiles++] = argv[i];
	}

	if(arch_flags == NULL)
	    all_archs = TRUE;

	if(cmd_flags.nfiles != 1)
	    usage();

	for(j = 0; j < cmd_flags.nfiles; j++)
	    ofile_process(files[j], arch_flags, narch_flags, all_archs, TRUE,
			  TRUE, FALSE, checksyms, &cmd_flags);

	if(errors == 0)
	    return(exit_status);
	else
	    return(EXIT_FAILURE);
}