|
|
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.