Unified · Split
| @@ -212,35 +212,69 @@ static int expand_args(char ***pargv, const char *str) · 211 unmodified lines | ||
| 212 | 212 | return argc; |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | −void exec_other_tcc(TCCState *s, int argc,char **argv,int optarg) | |
| 216 | −{ | |
| 217 | −#ifdef TCC_TARGET_X86_64 | |
| 218 | −#define WIN32_CAST | |
| 219 | − char arg[20]="i386-tcc"; | |
| 220 | − char sep='/',*tcc; | |
| 221 | − if (32 == optarg) {/* -m32 launches 32 bit tcc */ | |
| 222 | −#ifdef TCC_TARGET_PE | |
| 215 | +#if defined(TCC_TARGET_X86_64) || defined (TCC_TARGET_I386) | |
| 216 | + | |
| 223 | 217 | #ifdef _WIN32 |
| 224 | −#define WIN32_CAST (const char**)(const char *) | |
| 225 | − strcpy(arg,"tcc.exe"); | |
| 226 | − sep='\\'; | |
| 218 | +#define CAST (const char * const *) | |
| 227 | 219 | #else |
| 228 | − strcpy(arg,"i386-win32-tcc"); | |
| 220 | +#define CAST (char * const *) | |
| 229 | 221 | #endif |
| 222 | + | |
| 223 | +#if defined(TCC_TARGET_X86_64) | |
| 224 | +#define ARG 32 | |
| 225 | +#define CHILD "i386" | |
| 226 | +#elif defined (TCC_TARGET_I386) | |
| 227 | +#define ARG 64 | |
| 228 | +#define CHILD "x86_64" | |
| 230 | 229 | #endif |
| 231 | − if (!(tcc=strrchr(argv[0],sep))) | |
| 232 | − tcc=argv[0]; | |
| 233 | − else tcc++; | |
| 234 | − if (0<s->verbose) printf("%s->%s\n",tcc,arg); | |
| 235 | − if (strcmp(tcc,arg)) { | |
| 236 | − execvp(arg, WIN32_CAST (argv)); | |
| 237 | − error("cross compiler not found!"); | |
| 238 | − exit(1); | |
| 239 | − } else warning("-m32 infinite loop prevented"); | |
| 240 | − } else warning("usupported option \"-m%s\"",optarg); | |
| 241 | −#undef WIN32_CAST | |
| 242 | −#endif | |
| 230 | + | |
| 231 | +static const char *ssuffix(const char *name, const char sep) | |
| 232 | +{ | |
| 233 | + char *p = strchr(name, sep); | |
| 234 | + return p?p+1:name; | |
| 235 | +} | |
| 236 | + | |
| 237 | +static void exec_other_tcc(TCCState *s, int argc, | |
| 238 | + char **argv,const char *optarg, int optind) | |
| 239 | +{ | |
| 240 | + char child_path[4096],child_name[4096]; | |
| 241 | + char *parent,*child_tcc; | |
| 242 | + int opt = atoi(optarg); | |
| 243 | + if (strlen(argv[0]) > 4000) | |
| 244 | + error("-m%s unsafe path length", ARG); | |
| 245 | + switch (opt) { | |
| 246 | + case ARG + 1: /* oops we called ourselves */ | |
| 247 | + error("-m%s cross compiler not installed", ARG); | |
| 248 | + break; | |
| 249 | + case ARG: | |
| 250 | + { | |
| 251 | + parent = tcc_basename(argv[0]); | |
| 252 | + sprintf(child_name, CHILD "-%s", ssuffix(parent,'-')); | |
| 253 | + if (strcmp(parent, child_name)) { | |
| 254 | + /* child_path = dirname */ | |
| 255 | + pstrcpy(child_path, parent - argv[0] + 1, argv[0]); | |
| 256 | + child_tcc = strchr(child_path, 0); | |
| 257 | + strcpy(child_tcc, child_name); | |
| 258 | + if (0 < s->verbose) | |
| 259 | + printf("%s -m%i -> %s\n", | |
| 260 | + parent, ARG, child_path); | |
| 261 | + sprintf(argv[optind],"-m%i", ARG + 1); /* no loop */ | |
| 262 | + execvp(child_path, CAST argv); | |
| 263 | + sprintf(child_tcc,"tcc%s",tcc_fileextension(parent)); | |
| 264 | + execvp(child_path, CAST argv); | |
| 265 | + error("-m%s cross compiler not found", ARG); | |
| 266 | + } else error("-m%s unsupported configuration", ARG); | |
| 267 | + } | |
| 268 | + case 96 ^ ARG : break; | |
| 269 | + case 96 ^ (ARG + 1): break; | |
| 270 | + default: | |
| 271 | + warning("usupported option \"-m%s\"",optarg); | |
| 272 | + } | |
| 243 | 273 | } |
| 274 | +#undef CAST | |
| 275 | +#undef ARG | |
| 276 | +#undef CHILD | |
| 277 | +#endif | |
| 244 | 278 | |
| 245 | 279 | static int parse_args(TCCState *s, int argc, char **argv) |
| 246 | 280 | { |
| @@ -366,9 +400,11 @@ static int parse_args(TCCState *s, int argc, char **argv) · 119 unmodified lines | ||
| 366 | 400 | case TCC_OPTION_soname: |
| 367 | 401 | s->soname = optarg; |
| 368 | 402 | break; |
| 403 | +#if defined(TCC_TARGET_X86_64) || defined (TCC_TARGET_I386) | |
| 369 | 404 | case TCC_OPTION_m: |
| 370 | − exec_other_tcc(s,argc+1,argv-1,atoi(optarg)); | |
| 405 | + exec_other_tcc(s, argc+1, argv-1, optarg, optind); | |
| 371 | 406 | break; |
| 407 | +#endif | |
| 372 | 408 | case TCC_OPTION_o: |
| 373 | 409 | multiple_files = 1; |
| 374 | 410 | outfile = optarg; |