X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fppc%2Fmain.c;h=667c02f2d43ab36b225f62a33e064d3a0141f922;hb=2951f6c068f961a2ea1de892fc82cf0229af67da;hp=122794007ac8a3f592d69e156d53824ff4b30ea3;hpb=22ddef466ef2afd6b2ce7b51046628d926cd0253;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/ppc/main.c b/sim/ppc/main.c index 122794007a..667c02f2d4 100644 --- a/sim/ppc/main.c +++ b/sim/ppc/main.c @@ -1,10 +1,10 @@ /* This file is part of the program psim. - Copyright (C) 1994-1995, Andrew Cagney + Copyright (C) 1994-1997, Andrew Cagney This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -13,27 +13,63 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + along with this program; if not, see . */ #include -#include #include -#include +#include + +#include #include "psim.h" +#include "options.h" +#include "device.h" /* FIXME: psim should provide the interface */ +#include "events.h" /* FIXME: psim should provide the interface */ + +#include "bfd.h" +#include "gdb/callback.h" +#include "gdb/remote-sim.h" + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +#include + +#if !defined(O_NDELAY) || !defined(F_GETFL) || !defined(F_SETFL) +#undef WITH_STDIO +#define WITH_STDIO DO_USE_STDIO +#endif + extern char **environ; -extern char *optarg; -extern int optind; -extern int optopt; -extern int opterr; + +static psim *simulation = NULL; + + +void +sim_io_poll_quit (void) +{ + /* nothing to do */ +} void -printf_filtered(const char *msg, ...) +sim_io_printf_filtered(const char *msg, ...) { va_list ap; va_start(ap, msg); @@ -42,114 +78,241 @@ printf_filtered(const char *msg, ...) } void -error (char *msg, ...) +error (const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + vprintf(msg, ap); + printf("\n"); + va_end(ap); + + /* any final clean up */ + if (ppc_trace[trace_print_info] && simulation != NULL) + psim_print_info (simulation, ppc_trace[trace_print_info]); + + exit (1); +} + +int +sim_io_write_stdout(const char *buf, + int sizeof_buf) +{ + switch (CURRENT_STDIO) { + case DO_USE_STDIO: + { + int i; + for (i = 0; i < sizeof_buf; i++) { + putchar(buf[i]); + } + return i; + } + break; + case DONT_USE_STDIO: + return write(1, buf, sizeof_buf); + break; + default: + error("sim_io_write_stdout: invalid switch\n"); + } + return 0; +} + +int +sim_io_write_stderr(const char *buf, + int sizeof_buf) +{ + switch (CURRENT_STDIO) { + case DO_USE_STDIO: + { + int i; + for (i = 0; i < sizeof_buf; i++) { + fputc(buf[i], stderr); + } + return i; + } + break; + case DONT_USE_STDIO: + return write(2, buf, sizeof_buf); + break; + default: + error("sim_io_write_stdout: invalid switch\n"); + } + return 0; +} + +int +sim_io_read_stdin(char *buf, + int sizeof_buf) +{ + switch (CURRENT_STDIO) { + case DO_USE_STDIO: + if (sizeof_buf > 1) { + if (fgets(buf, sizeof_buf, stdin) != NULL) + return strlen(buf); + } + else if (sizeof_buf == 1) { + char b[2]; + if (fgets(b, sizeof(b), stdin) != NULL) { + memcpy(buf, b, strlen(b)); + return strlen(b); + } + } + else if (sizeof_buf == 0) + return 0; + return sim_io_eof; + break; + case DONT_USE_STDIO: +#if defined(O_NDELAY) && defined(F_GETFL) && defined(F_SETFL) + { + /* check for input */ + int flags; + int status; + int nr_read; + int result; + /* get the old status */ + flags = fcntl(0, F_GETFL, 0); + if (flags == -1) { + perror("sim_io_read_stdin"); + return sim_io_eof; + } + /* temp, disable blocking IO */ + status = fcntl(0, F_SETFL, flags | O_NDELAY); + if (status == -1) { + perror("sim_io_read_stdin"); + return sim_io_eof; + } + /* try for input */ + nr_read = read(0, buf, sizeof_buf); + if (nr_read > 0 + || (nr_read == 0 && sizeof_buf == 0)) + result = nr_read; + else if (nr_read == 0) + result = sim_io_eof; + else { /* nr_read < 0 */ + if (errno == EAGAIN) + result = sim_io_not_ready; + else + result = sim_io_eof; + } + /* return to regular vewing */ + status = fcntl(0, F_SETFL, flags); + if (status == -1) { + perror("sim_io_read_stdin"); + return sim_io_eof; + } + return result; + } + break; +#endif + default: + error("sim_io_read_stdin: invalid switch\n"); + break; + } + return 0; +} + +void +sim_io_flush_stdoutput(void) +{ + switch (CURRENT_STDIO) { + case DO_USE_STDIO: + fflush (stdout); + break; + case DONT_USE_STDIO: + break; + default: + error("sim_io_flush_stdoutput: invalid switch\n"); + break; + } +} + +void +sim_io_error (SIM_DESC sd, const char *msg, ...) { va_list ap; va_start(ap, msg); vprintf(msg, ap); + printf("\n"); va_end(ap); + + /* any final clean up */ + if (ppc_trace[trace_print_info] && simulation != NULL) + psim_print_info (simulation, ppc_trace[trace_print_info]); + exit (1); } + void * zalloc(long size) { void *memory = malloc(size); if (memory == NULL) - error("zmalloc failed\n"); - bzero(memory, size); + error("zalloc failed\n"); + memset(memory, 0, size); return memory; } -void -zfree(void *chunk) -{ - free(chunk); -} +/* When a CNTRL-C occures, queue an event to shut down the simulation */ -static void -usage(void) +static RETSIGTYPE +cntrl_c(int sig) { - error ("Usage: psim [ -a -p -c -C -s -i -I -t -g ] [ ... ]\n"); + psim_stop (simulation); } + int main(int argc, char **argv) { - psim *system; const char *name_of_file; char *arg_; - unsigned_word stack_pointer; psim_status status; - int letter; - int i; - int print_info = 0; + device *root = psim_tree(); - /* check for arguments -- note sim_calls.c also contains argument processing - code for the simulator linked within gdb. */ - while ((letter = getopt (argc, argv, "acCiIpstg")) != EOF) - { - switch (letter) { - case 'a': - for (i = 0; i < nr_trace; i++) - ppc_trace[i] = 1; - break; - case 'p': - ppc_trace[trace_cpu] = ppc_trace[trace_semantics] = 1; - break; - case 'c': - ppc_trace[trace_core] = 1; - break; - case 'C': - ppc_trace[trace_console_device] = 1; - break; - case 's': - ppc_trace[trace_create_stack] = 1; - break; - case 'i': - ppc_trace[trace_icu_device] = 1; - break; - case 'I': - print_info = 1; - break; - case 't': - ppc_trace[trace_device_tree] = 1; - break; - case 'g': - ppc_trace[trace_gdb] = 1; - break; - default: - usage(); - } + /* parse the arguments */ + argv = psim_options (root, argv + 1, SIM_OPEN_STANDALONE); + if (argv[0] == NULL) { + if (ppc_trace[trace_opts]) { + print_options (); + return 0; + } else { + psim_usage (0, 0, SIM_OPEN_STANDALONE); } - if (optind >= argc) - usage(); - name_of_file = argv[optind]; + } + name_of_file = argv[0]; + + if (ppc_trace[trace_opts]) + print_options (); /* create the simulator */ - system = psim_create(name_of_file, ((WITH_SMP > 0) ? WITH_SMP : 1)); + simulation = psim_create(name_of_file, root); /* fudge the environment so that _=prog-name */ - arg_ = (char*)zalloc(strlen(argv[optind]) + strlen("_=") + 1); + arg_ = (char*)zalloc(strlen(argv[0]) + strlen("_=") + 1); strcpy(arg_, "_="); - strcat(arg_, argv[optind]); + strcat(arg_, argv[0]); putenv(arg_); /* initialize it */ - psim_init(system); - psim_stack(system, &argv[optind], environ); + psim_init(simulation); + psim_stack(simulation, argv, environ); - psim_run(system); + { + RETSIGTYPE (*prev) (); + prev = signal(SIGINT, cntrl_c); + psim_run(simulation); + signal(SIGINT, prev); + } /* any final clean up */ - if (print_info) - psim_print_info (system, 1); + if (ppc_trace[trace_print_info]) + psim_print_info (simulation, ppc_trace[trace_print_info]); /* why did we stop */ - status = psim_get_status(system); + status = psim_get_status(simulation); switch (status.reason) { case was_continuing: - error("psim: continuing while stoped!\n"); + error("psim: continuing while stopped!\n"); return 0; case was_trap: error("psim: no trap insn\n"); @@ -158,8 +321,8 @@ main(int argc, char **argv) return status.signal; case was_signalled: printf ("%s: Caught signal %d at address 0x%lx\n", - name_of_file, (int)status.signal, - (long)status.program_counter); + name_of_file, (int)status.signal, + (long)status.program_counter); return status.signal; default: error("unknown halt condition\n");