static struct sim_inferior_data * get_sim_inferior_data (struct inferior *inf, int sim_instance_needed) { SIM_DESC sim_desc = NULL; struct sim_inferior_data *sim_data = (struct sim_inferior_data *) inferior_data (inf, sim_inferior_data_key); /* Try to allocate a new sim instance, if needed. We do this ahead of a potential allocation of a sim_inferior_data struct in order to avoid needlessly allocating that struct in the event that the sim instance allocation fails. */ if (sim_instance_needed == SIM_INSTANCE_NEEDED && (sim_data == NULL || sim_data->gdbsim_desc == NULL)) { struct inferior *idup; sim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, sim_argv); if (sim_desc == NULL) error (_("Unable to create simulator instance for inferior %d."), inf->num); idup = iterate_over_inferiors (check_for_duplicate_sim_descriptor, sim_desc); if (idup != NULL) { /* We don't close the descriptor due to the fact that it's shared with some other inferior. If we were to close it, that might needlessly muck up the other inferior. Of course, it's possible that the damage has already been done... Note that it *will* ultimately be closed during cleanup of the other inferior. */ sim_desc = NULL; error ( _("Inferior %d and inferior %d would have identical simulator state.\n" "(This simulator does not support the running of more than one inferior.)"), inf->num, idup->num); } } if (sim_data == NULL) { sim_data = XCNEW(struct sim_inferior_data); set_inferior_data (inf, sim_inferior_data_key, sim_data); /* Allocate a ptid for this inferior. */ sim_data->remote_sim_ptid = ptid_build (next_pid, 0, next_pid); next_pid++; /* Initialize the other instance variables. */ sim_data->program_loaded = 0; sim_data->gdbsim_desc = sim_desc; sim_data->resume_siggnal = GDB_SIGNAL_0; sim_data->resume_step = 0; }
int create_inferior (char *program, char **argv) { bfd *abfd; int pid = 0; char **new_argv; int nargs; abfd = bfd_openr (program, 0); if (!abfd) { fprintf (stderr, "gdbserver: cannot open %s: %s\n", program, bfd_errmsg (bfd_get_error ())); exit (1); } if (!bfd_check_format (abfd, bfd_object)) { fprintf (stderr, "gdbserver: unknown load format for %s: %s\n", program, bfd_errmsg (bfd_get_error ())); exit (1); } /* Add "-E big" or "-E little" to the argument list depending on the endianness of the program to be loaded. */ for (nargs = 0; argv[nargs] != NULL; nargs++) /* count the args */ ; new_argv = alloca (sizeof (char *) * (nargs + 3)); /* allocate new args */ for (nargs = 0; argv[nargs] != NULL; nargs++) /* copy old to new */ new_argv[nargs] = argv[nargs]; new_argv[nargs] = "-E"; new_argv[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little"; new_argv[nargs + 2] = NULL; argv = new_argv; /* Create an instance of the simulator. */ default_callback.init (&default_callback); gdbsim_desc = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, argv); if (gdbsim_desc == 0) exit (1); /* Load the program into the simulator. */ if (abfd) if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL) mygeneric_load (abfd); /* Create an inferior process in the simulator. This initializes SP. */ sim_create_inferior (gdbsim_desc, abfd, argv, /* env */ NULL); sim_resume (gdbsim_desc, 1, 0); /* execute one instr */ return pid; }
int main (int argc, char **argv) { char *name; char **prog_argv = NULL; struct bfd *prog_bfd; enum sim_stop reason; int sigrc = 0; int single_step = 0; RETSIGTYPE (*prev_sigint) (); myname = argv[0] + strlen (argv[0]); while (myname > argv[0] && myname[-1] != '/') --myname; /* INTERNAL: When MYNAME is `step', single step the simulator instead of allowing it to run free. The sole purpose of this HACK is to allow the sim_resume interface's step argument to be tested without having to build/run gdb. */ if (strlen (myname) > 4 && strcmp (myname - 4, "step") == 0) { single_step = 1; } /* Create an instance of the simulator. */ default_callback.init (&default_callback); sd = sim_open (SIM_OPEN_STANDALONE, &default_callback, NULL, argv); if (sd == 0) exit (1); if (STATE_MAGIC (sd) != SIM_MAGIC_NUMBER) { fprintf (stderr, "Internal error - bad magic number in simulator struct\n"); abort (); } /* We can't set the endianness in the callback structure until sim_config is called, which happens in sim_open. */ default_callback.target_endian = (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE); /* Was there a program to run? */ prog_argv = STATE_PROG_ARGV (sd); prog_bfd = STATE_PROG_BFD (sd); if (prog_argv == NULL || *prog_argv == NULL) usage (); name = *prog_argv; /* For simulators that don't open prog during sim_open() */ if (prog_bfd == NULL) { prog_bfd = bfd_openr (name, 0); if (prog_bfd == NULL) { fprintf (stderr, "%s: can't open \"%s\": %s\n", myname, name, bfd_errmsg (bfd_get_error ())); exit (1); } if (!bfd_check_format (prog_bfd, bfd_object)) { fprintf (stderr, "%s: \"%s\" is not an object file: %s\n", myname, name, bfd_errmsg (bfd_get_error ())); exit (1); } } if (STATE_VERBOSE_P (sd)) printf ("%s %s\n", myname, name); /* Load the program into the simulator. */ if (sim_load (sd, name, prog_bfd, 0) == SIM_RC_FAIL) exit (1); /* Prepare the program for execution. */ #ifdef HAVE_ENVIRON sim_create_inferior (sd, prog_bfd, prog_argv, environ); #else sim_create_inferior (sd, prog_bfd, prog_argv, NULL); #endif /* To accommodate relative file paths, chdir to sysroot now. We mustn't do this until BFD has opened the program, else we wouldn't find the executable if it has a relative file path. */ if (simulator_sysroot[0] != '\0' && chdir (simulator_sysroot) < 0) { fprintf (stderr, "%s: can't change directory to \"%s\"\n", myname, simulator_sysroot); exit (1); } /* Run/Step the program. */ if (single_step) { do { prev_sigint = signal (SIGINT, cntrl_c); sim_resume (sd, 1/*step*/, 0); signal (SIGINT, prev_sigint); sim_stop_reason (sd, &reason, &sigrc); if ((reason == sim_stopped) && (sigrc == sim_signal_to_host (sd, SIM_SIGINT))) break; /* exit on control-C */ } /* remain on breakpoint or signals in oe mode*/ while (((reason == sim_signalled) && (sigrc == sim_signal_to_host (sd, SIM_SIGTRAP))) || ((reason == sim_stopped) && (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT))); } else { do { #if defined (HAVE_SIGACTION) && defined (SA_RESTART) struct sigaction sa, osa; sa.sa_handler = cntrl_c; sigemptyset (&sa.sa_mask); sa.sa_flags = 0; sigaction (SIGINT, &sa, &osa); prev_sigint = osa.sa_handler; #else prev_sigint = signal (SIGINT, cntrl_c); #endif sim_resume (sd, 0, sigrc); signal (SIGINT, prev_sigint); sim_stop_reason (sd, &reason, &sigrc); if ((reason == sim_stopped) && (sigrc == sim_signal_to_host (sd, SIM_SIGINT))) break; /* exit on control-C */ /* remain on signals in oe mode */ } while ((reason == sim_stopped) && (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)); } /* Print any stats the simulator collected. */ if (STATE_VERBOSE_P (sd)) sim_info (sd, 0); /* Shutdown the simulator. */ sim_close (sd, 0); /* If reason is sim_exited, then sigrc holds the exit code which we want to return. If reason is sim_stopped or sim_signalled, then sigrc holds the signal that the simulator received; we want to return that to indicate failure. */ /* Why did we stop? */ switch (reason) { case sim_signalled: case sim_stopped: if (sigrc != 0) fprintf (stderr, "program stopped with signal %d.\n", sigrc); break; case sim_exited: break; default: fprintf (stderr, "program in undefined state (%d:%d)\n", reason, sigrc); break; } return sigrc; }
static void gdbsim_open (char *args, int from_tty) { int len; char *arg_buf; char **argv; if (sr_get_debug ()) printf_filtered ("gdbsim_open: args \"%s\"\n", args ? args : "(null)"); /* Remove current simulator if one exists. Only do this if the simulator has been opened because sim_close requires it. This is important because the call to push_target below will cause sim_close to be called if the simulator is already open, but push_target is called after sim_open! We can't move the call to push_target before the call to sim_open because sim_open may invoke `error'. */ if (gdbsim_desc != NULL) unpush_target (&gdbsim_ops); len = (7 + 1 /* gdbsim */ + strlen (" -E little") + strlen (" --architecture=xxxxxxxxxx") + (args ? strlen (args) : 0) + 50) /* slack */ ; arg_buf = (char *) alloca (len); strcpy (arg_buf, "gdbsim"); /* 7 */ /* Specify the byte order for the target when it is both selectable and explicitly specified by the user (not auto detected). */ switch (selected_byte_order ()) { case BFD_ENDIAN_BIG: strcat (arg_buf, " -E big"); break; case BFD_ENDIAN_LITTLE: strcat (arg_buf, " -E little"); break; case BFD_ENDIAN_UNKNOWN: break; } /* Specify the architecture of the target when it has been explicitly specified */ if (selected_architecture_name () != NULL) { strcat (arg_buf, " --architecture="); strcat (arg_buf, selected_architecture_name ()); } /* finally, any explicit args */ if (args) { strcat (arg_buf, " "); /* 1 */ strcat (arg_buf, args); } argv = buildargv (arg_buf); if (argv == NULL) error ("Insufficient memory available to allocate simulator arg list."); make_cleanup_freeargv (argv); init_callbacks (); gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, argv); if (gdbsim_desc == 0) error ("unable to create simulator instance"); push_target (&gdbsim_ops); target_fetch_registers (-1); printf_filtered ("Connected to the simulator.\n"); }
void handshake(char cmd) { char *p; if (cmd == 'n') { percentage = 0.0; } /* device handshake */ if ((cmd != 'g') && (cmd != 'o')) /* ! --gui and ! --view */ { switch (g_dev) { case dev_wii: /* --wii */ printf("Searching... (Press 1 and 2 on the Wii)\n"); fflush(stdout); if (g_mode == graphical) { percentage += 0.1; update_gui("Press 1 and 2 on the Wii", percentage); } if (wii_search(&wii, 5) < 0) { fprintf(stderr, "Could not find the Wii.\n"); fflush(stderr); exit(1); } printf("Found.\n"); fflush(stdout); if (wii_connect(&wii) < 0) { fprintf(stderr, "Could not connect to the Wii.\n"); fflush(stderr); exit(1); } printf("Connected.\n"); fflush(stdout); if (g_mode == graphical) { percentage += 0.1; if (percentage < 0.5) { update_gui("Make the gesture", percentage); } else { update_gui("Make the same gesture again", percentage); } } wii_set_leds(&wii, 0, 0, 0, 1); signal(SIGALRM, wii_signal_cb); signal(SIGINT, wii_signal_cb); signal(SIGTERM, wii_signal_cb); break; case dev_neo2: /* --neo2 */ if (!neo_open(&neo, neo_accel2)) { fprintf(stderr, "Could not open top accelerometer.\n"); fflush(stderr); exit(1); } printf("Connected.\n"); fflush(stdout); if (g_mode == graphical) { percentage += 0.2; if (percentage < 0.5) { update_gui("Make the gesture", percentage); } else { update_gui("Make the same gesture again", percentage); } } signal(SIGALRM, neo_signal_cb); signal(SIGINT, neo_signal_cb); signal(SIGTERM, neo_signal_cb); break; case dev_neo3: /* --neo3 */ if (!neo_open(&neo, neo_accel3)) { fprintf(stderr, "Could not open bottom accelerometer.\n"); fflush(stderr); exit(1); } printf("Connected.\n"); fflush(stdout); if (g_mode == graphical) { percentage += 0.2; if (percentage < 0.5) { update_gui("Make the gesture", percentage); } else { update_gui("Make the same gesture again", percentage); } } signal(SIGALRM, neo_signal_cb); signal(SIGINT, neo_signal_cb); signal(SIGTERM, neo_signal_cb); break; case dev_sim: /* --sim */ if (!sim_open(&sim, sim_filename)) { fprintf(stderr, "Could not read values from simulation file.\n"); fflush(stderr); exit(1); } printf("Opened.\n"); fflush(stdout); signal(SIGALRM, sim_signal_cb); signal(SIGINT, sim_signal_cb); signal(SIGTERM, sim_signal_cb); break; case dev_none: exit(1); break; } } /* prepare callbacks for requested command */ switch (cmd) { case 'g': /* --gui */ //main_gui(argc, argv, g_dev, dir); break; case 'a': /* --accel */ chdir(dir); wii.handle_recv = cmd_accel_cb; neo.handle_recv = cmd_accel_cb; sim.handle_recv = cmd_accel_cb; break; case 'r': /* --record */ chdir(dir); wii.handle_recv = cmd_record_cb; neo.handle_recv = cmd_record_cb; sim.handle_recv = cmd_record_cb; cmd_record_begin(file); break; case 'n': /* --new */ case 'o': /* --view */ case 'e': /* --train */ chdir(dir); p = rindex(file, '.'); if ((p) && (strcmp(p, ".class") == 0)) { /* class */ if (cmd == 'n') { /* --new class */ wii.handle_recv = cmd_class_cb; neo.handle_recv = cmd_class_cb; sim.handle_recv = cmd_class_cb; handle_class = cmd_class_new_cb; cmd_class_new_begin(file); } else if (cmd == 'o') { /* --view class */ wii.handle_recv = 0; neo.handle_recv = 0; sim.handle_recv = 0; handle_class = 0; cmd_class_view_begin(file); } else if (cmd == 'e') { /* --train class */ wii.handle_recv = cmd_class_cb; neo.handle_recv = cmd_class_cb; sim.handle_recv = cmd_class_cb; handle_class = cmd_class_train_cb; cmd_class_train_begin(file); } } else if ((p) && (strcmp(p, ".model") == 0)) { /* model */ if (cmd == 'n') { /* --new model */ wii.handle_recv = cmd_model_cb; neo.handle_recv = cmd_model_cb; sim.handle_recv = cmd_model_cb; handle_model = cmd_model_new_cb; cmd_model_new_begin(file); } else if (cmd == 'o') { /* --view model */ wii.handle_recv = 0; neo.handle_recv = 0; sim.handle_recv = 0; handle_model = 0; cmd_model_view_begin(file); } else if (cmd == 'e') { /* --train model */ wii.handle_recv = cmd_model_cb; neo.handle_recv = cmd_model_cb; sim.handle_recv = cmd_model_cb; handle_model = cmd_model_train_cb; cmd_model_train_begin(file); } } else if ((p) && (strcmp(p, ".accel") == 0)) { /* accel */ if (cmd == 'o') { /* --view accel */ wii.handle_recv = 0; neo.handle_recv = 0; sim.handle_recv = 0; cmd_accel_view_begin(file); } else { fprintf(stderr, "Unsupported operation for this type of file\n"); fflush(stderr); exit(2); } } else { /* unknown */ fprintf(stderr, "Unrecognized file extension (has to be .class or .model).\n"); exit(1); } break; } if ((cmd != 'g') && (cmd != 'o')) /* ! --gui and ! --view */ { /* begin reading accel values */ switch (g_dev) { case dev_wii: wii_talk(&wii); break; case dev_neo2: case dev_neo3: neo_begin_read(&neo); break; case dev_sim: sim_begin_read(&sim); break; case dev_none: exit(1); break; } } }