/* main.c --- main function for stand-alone M32C simulator. Copyright (C) 2005-2018 Free Software Foundation, Inc. Contributed by Red Hat, Inc. This file is part of the GNU simulators. 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 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, see . */ #include "config.h" #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_TCP_H #define HAVE_networking #endif #endif #endif #ifdef HAVE_networking #include #include #include #endif #include "bfd.h" #include "cpu.h" #include "mem.h" #include "misc.h" #include "load.h" #include "trace.h" #ifdef TIMER_A #include "int.h" #include "timer_a.h" #endif #ifdef HAVE_networking extern int m32c_console_ofd; extern int m32c_console_ifd; #endif int m32c_disassemble = 0; static unsigned int cycles = 0; static void done (int exit_code) { if (verbose) { stack_heap_stats (); mem_usage_stats (); printf ("insns: %14s\n", comma (cycles)); } exit (exit_code); } #ifdef HAVE_networking static void setup_tcp_console (char *portname) { int port = atoi (portname); struct sockaddr_in address; int isocket; socklen_t as; unsigned char *a; if (port < 1024) { printf ("invalid port number %d\n", port); exit (1); } printf ("waiting for tcp console on port %d\n", port); memset (&address, 0, sizeof (address)); address.sin_family = AF_INET; address.sin_port = htons (port); isocket = socket (AF_INET, SOCK_STREAM, 0); if (isocket == -1) { perror ("socket"); exit (1); } if (bind (isocket, (struct sockaddr *) &address, sizeof (address))) { perror ("bind"); exit (1); } listen (isocket, 2); printf ("waiting for connection...\n"); as = sizeof (address); m32c_console_ifd = accept (isocket, (struct sockaddr *) &address, &as); if (m32c_console_ifd == -1) { perror ("accept"); exit (1); } a = (unsigned char *) (&address.sin_addr.s_addr); printf ("connection from %d.%d.%d.%d\n", a[0], a[1], a[2], a[3]); m32c_console_ofd = m32c_console_ifd; } #endif int main (int argc, char **argv) { int o; int save_trace; bfd *prog; #ifdef HAVE_networking char *console_port_s = 0; #endif setbuf (stdout, 0); in_gdb = 0; while ((o = getopt (argc, argv, "tc:vdm:C")) != -1) switch (o) { case 't': trace++; break; case 'c': #ifdef HAVE_networking console_port_s = optarg; #else fprintf (stderr, "Nework console not available in this build.\n"); #endif break; case 'C': #ifdef HAVE_TERMIOS_H m32c_use_raw_console = 1; #else fprintf (stderr, "Raw console not available in this build.\n"); #endif break; case 'v': verbose++; break; case 'd': m32c_disassemble++; break; case 'm': if (strcmp (optarg, "r8c") == 0 || strcmp (optarg, "m16c") == 0) default_machine = bfd_mach_m16c; else if (strcmp (optarg, "m32cm") == 0 || strcmp (optarg, "m32c") == 0) default_machine = bfd_mach_m32c; else { fprintf (stderr, "Invalid machine: %s\n", optarg); exit (1); } break; case '?': fprintf (stderr, "usage: run [-v] [-C] [-c port] [-t] [-d] [-m r8c|m16c|m32cm|m32c]" " program\n"); exit (1); } prog = bfd_openr (argv[optind], 0); if (!prog) { fprintf (stderr, "Can't read %s\n", argv[optind]); exit (1); } if (!bfd_check_format (prog, bfd_object)) { fprintf (stderr, "%s not a m32c program\n", argv[optind]); exit (1); } save_trace = trace; trace = 0; m32c_load (prog); trace = save_trace; #ifdef HAVE_networking if (console_port_s) setup_tcp_console (console_port_s); #endif sim_disasm_init (prog); while (1) { int rc; if (trace) printf ("\n"); if (m32c_disassemble) sim_disasm_one (); enable_counting = verbose; cycles++; rc = decode_opcode (); enable_counting = 0; if (M32C_HIT_BREAK (rc)) done (1); else if (M32C_EXITED (rc)) done (M32C_EXIT_STATUS (rc)); else assert (M32C_STEPPED (rc)); trace_register_changes (); #ifdef TIMER_A update_timer_a (); #endif } }