--- trunk/src/emul.c 2007/10/08 16:18:22 9 +++ trunk/src/emul.c 2007/10/08 16:18:27 10 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: emul.c,v 1.203 2005/06/03 07:39:27 debug Exp $ + * $Id: emul.c,v 1.211 2005/06/26 11:36:28 debug Exp $ * * Emulation startup and misc. routines. */ @@ -46,6 +46,7 @@ #include "debugger.h" #include "device.h" #include "diskimage.h" +#include "exec_elf.h" #include "machine.h" #include "memory.h" #include "mips_cpu_types.h" @@ -645,6 +646,7 @@ /* Sane default values: */ e->n_machines = 0; + e->next_serial_nr = 1; if (name != NULL) { e->name = strdup(name); @@ -832,6 +834,9 @@ m->cpu_family = cpu_family_ptr_by_number(m->arch); + if (m->arch != ARCH_MIPS) + m->bintrans_enable = 0; + machine_memsize_fix(m); /* @@ -894,6 +899,20 @@ } debug("\n"); +#if 0 + /* Special case: The Playstation Portable has an additional CPU: */ + if (m->machine_type == MACHINE_PSP) { + debug("cpu%i: ", m->ncpus); + m->cpus[m->ncpus] = cpu_new(m->memory, m, + 0 /* use 0 here to show info with debug() */, + "Allegrex" /* TODO */); + if (m->bintrans_enable) + bintrans_init_cpu(m->cpus[m->ncpus]); + debug("\n"); + m->ncpus ++; + } +#endif + if (m->use_random_bootstrap_cpu) m->bootstrap_cpu = random() % m->ncpus; else @@ -966,9 +985,8 @@ } /* - * Another special hack for temporary files; running gunzip - * on them, if they have a gzip header. TODO: Change this - * into some kind of generic support for gzipped files! + * gzipped files are automagically gunzipped: + * NOTE/TODO: This isn't secure. system() is used. */ tmp_f = fopen(name_to_load, "r"); if (tmp_f != NULL) { @@ -976,18 +994,82 @@ memset(buf, 0, sizeof(buf)); fread(buf, 1, sizeof(buf), tmp_f); if (buf[0]==0x1f && buf[1]==0x8b) { - char *zz = malloc(strlen(name_to_load)*2 + 100); + size_t zzlen = strlen(name_to_load)*2 + 100; + char *zz = malloc(zzlen); debug("gunziping %s\n", name_to_load); - sprintf(zz, "mv %s %s.gz", name_to_load, - name_to_load); - system(zz); - sprintf(zz, "gunzip %s.gz", name_to_load); - system(zz); + /* + * gzip header found. If this was a file + * extracted from, say, a CDROM image, then it + * already has a temporary name. Otherwise we + * have to gunzip into a temporary file. + */ + if (remove_after_load) { + snprintf(zz, zzlen, "mv %s %s.gz", + name_to_load, name_to_load); + system(zz); + snprintf(zz, zzlen, "gunzip %s.gz", + name_to_load); + system(zz); + } else { + /* gunzip into new temp file: */ + int tmpfile_handle; + char *new_temp_name = + strdup("/tmp/gxemul.XXXXXXXXXXXX"); + tmpfile_handle = mkstemp(new_temp_name); + close(tmpfile_handle); + snprintf(zz, zzlen, "gunzip -c '%s' > " + "%s", name_to_load, new_temp_name); + system(zz); + name_to_load = new_temp_name; + remove_after_load = 1; + } free(zz); } fclose(tmp_f); } + /* + * Ugly (but usable) hack for Playstation Portable: If the + * filename ends with ".pbp" and the file contains an ELF + * header, then extract the ELF file into a temporary file. + */ + if (strlen(name_to_load) > 4 && strcasecmp(name_to_load + + strlen(name_to_load) - 4, ".pbp") == 0 && + (tmp_f = fopen(name_to_load, "r")) != NULL) { + off_t filesize, j, found=0; + unsigned char *buf; + fseek(tmp_f, 0, SEEK_END); + filesize = ftello(tmp_f); + fseek(tmp_f, 0, SEEK_SET); + buf = malloc(filesize); + if (buf == NULL) { + fprintf(stderr, "out of memory while trying" + " to read %s\n", name_to_load); + exit(1); + } + fread(buf, 1, filesize, tmp_f); + fclose(tmp_f); + /* Search for the ELF header, from offset 1 (!): */ + for (j=1; jarch) { case ARCH_X86: @@ -1048,7 +1130,8 @@ break; case ARCH_ARM: - cpu->pc &= 0xffffffff; + cpu->pc &= 0xfffffffc; + cpu->cd.arm.r[ARM_PC] = cpu->pc; break; case ARCH_X86: @@ -1180,7 +1263,8 @@ cd.urisc.wordlen/8 - 1 - i]; } - sprintf(tmps, "0x%%0%illx", cpu->cd.urisc.wordlen / 4); + snprintf(tmps, sizeof(tmps), "0x%%0%illx", + cpu->cd.urisc.wordlen / 4); debug(tmps, (long long)entrypoint); cpu->pc = entrypoint; } @@ -1248,9 +1332,9 @@ debug("Simple setup...\n"); debug_indentation(iadd); - /* Create a network: */ + /* Create a simple network: */ emul->net = net_init(emul, NET_INIT_FLAG_GATEWAY, - "10.0.0.0", 8); + "10.0.0.0", 8, NULL, 0, 0); } else { /* Userland pseudo-machine: */ debug("Syscall emulation (userland-only) setup...\n");