1bb16d227Schristos /* main.c --- main function for stand-alone M32C simulator. 2bb16d227Schristos 3*8b657b07Schristos Copyright (C) 2005-2023 Free Software Foundation, Inc. 4bb16d227Schristos Contributed by Red Hat, Inc. 5bb16d227Schristos 6bb16d227Schristos This file is part of the GNU simulators. 7bb16d227Schristos 8bb16d227Schristos This program is free software; you can redistribute it and/or modify 9bb16d227Schristos it under the terms of the GNU General Public License as published by 10bb16d227Schristos the Free Software Foundation; either version 3 of the License, or 11bb16d227Schristos (at your option) any later version. 12bb16d227Schristos 13bb16d227Schristos This program is distributed in the hope that it will be useful, 14bb16d227Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 15bb16d227Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16bb16d227Schristos GNU General Public License for more details. 17bb16d227Schristos 18bb16d227Schristos You should have received a copy of the GNU General Public License 19bb16d227Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20bb16d227Schristos 21*8b657b07Schristos /* This must come before any other includes. */ 22*8b657b07Schristos #include "defs.h" 23bb16d227Schristos 24bb16d227Schristos #include <stdio.h> 25bb16d227Schristos #include <string.h> 26bb16d227Schristos #include <stdlib.h> 27bb16d227Schristos #include <unistd.h> 28bb16d227Schristos #include <assert.h> 29bb16d227Schristos #include <setjmp.h> 30bb16d227Schristos #include <signal.h> 31bb16d227Schristos #include <sys/types.h> 32*8b657b07Schristos #include <getopt.h> 33bb16d227Schristos 34bb16d227Schristos #ifdef HAVE_SYS_SOCKET_H 35bb16d227Schristos #ifdef HAVE_NETINET_IN_H 36bb16d227Schristos #ifdef HAVE_NETINET_TCP_H 37bb16d227Schristos #define HAVE_networking 38bb16d227Schristos #endif 39bb16d227Schristos #endif 40bb16d227Schristos #endif 41bb16d227Schristos 42bb16d227Schristos #ifdef HAVE_networking 43bb16d227Schristos #include <sys/socket.h> 44bb16d227Schristos #include <netinet/in.h> 45bb16d227Schristos #include <netinet/tcp.h> 46bb16d227Schristos #endif 47bb16d227Schristos 48bb16d227Schristos 49bb16d227Schristos #include "bfd.h" 50bb16d227Schristos 51bb16d227Schristos #include "cpu.h" 52bb16d227Schristos #include "mem.h" 53bb16d227Schristos #include "misc.h" 54bb16d227Schristos #include "load.h" 55bb16d227Schristos #include "trace.h" 56bb16d227Schristos #ifdef TIMER_A 57bb16d227Schristos #include "int.h" 58bb16d227Schristos #include "timer_a.h" 59bb16d227Schristos #endif 60bb16d227Schristos 61bb16d227Schristos #ifdef HAVE_networking 62bb16d227Schristos extern int m32c_console_ofd; 63bb16d227Schristos extern int m32c_console_ifd; 64bb16d227Schristos #endif 65bb16d227Schristos 66bb16d227Schristos int m32c_disassemble = 0; 67bb16d227Schristos static unsigned int cycles = 0; 68bb16d227Schristos 69bb16d227Schristos static void 70bb16d227Schristos done (int exit_code) 71bb16d227Schristos { 72bb16d227Schristos if (verbose) 73bb16d227Schristos { 74bb16d227Schristos stack_heap_stats (); 75bb16d227Schristos mem_usage_stats (); 76bb16d227Schristos printf ("insns: %14s\n", comma (cycles)); 77bb16d227Schristos } 78bb16d227Schristos exit (exit_code); 79bb16d227Schristos } 80bb16d227Schristos 81bb16d227Schristos #ifdef HAVE_networking 82bb16d227Schristos static void 83bb16d227Schristos setup_tcp_console (char *portname) 84bb16d227Schristos { 85bb16d227Schristos int port = atoi (portname); 86bb16d227Schristos struct sockaddr_in address; 87bb16d227Schristos int isocket; 88bb16d227Schristos socklen_t as; 89bb16d227Schristos unsigned char *a; 90bb16d227Schristos 91bb16d227Schristos if (port < 1024) 92bb16d227Schristos { 93bb16d227Schristos printf ("invalid port number %d\n", port); 94bb16d227Schristos exit (1); 95bb16d227Schristos } 96bb16d227Schristos printf ("waiting for tcp console on port %d\n", port); 97bb16d227Schristos 98bb16d227Schristos memset (&address, 0, sizeof (address)); 99bb16d227Schristos address.sin_family = AF_INET; 100bb16d227Schristos address.sin_port = htons (port); 101bb16d227Schristos 102bb16d227Schristos isocket = socket (AF_INET, SOCK_STREAM, 0); 103bb16d227Schristos if (isocket == -1) 104bb16d227Schristos { 105bb16d227Schristos perror ("socket"); 106bb16d227Schristos exit (1); 107bb16d227Schristos } 108bb16d227Schristos 109bb16d227Schristos if (bind (isocket, (struct sockaddr *) &address, sizeof (address))) 110bb16d227Schristos { 111bb16d227Schristos perror ("bind"); 112bb16d227Schristos exit (1); 113bb16d227Schristos } 114bb16d227Schristos listen (isocket, 2); 115bb16d227Schristos 116bb16d227Schristos printf ("waiting for connection...\n"); 117bb16d227Schristos as = sizeof (address); 118bb16d227Schristos m32c_console_ifd = accept (isocket, (struct sockaddr *) &address, &as); 119bb16d227Schristos if (m32c_console_ifd == -1) 120bb16d227Schristos { 121bb16d227Schristos perror ("accept"); 122bb16d227Schristos exit (1); 123bb16d227Schristos } 124bb16d227Schristos a = (unsigned char *) (&address.sin_addr.s_addr); 125bb16d227Schristos printf ("connection from %d.%d.%d.%d\n", a[0], a[1], a[2], a[3]); 126bb16d227Schristos m32c_console_ofd = m32c_console_ifd; 127bb16d227Schristos } 128bb16d227Schristos #endif 129bb16d227Schristos 130bb16d227Schristos int 131bb16d227Schristos main (int argc, char **argv) 132bb16d227Schristos { 133bb16d227Schristos int o; 134bb16d227Schristos int save_trace; 135bb16d227Schristos bfd *prog; 136bb16d227Schristos #ifdef HAVE_networking 137bb16d227Schristos char *console_port_s = 0; 138bb16d227Schristos #endif 139*8b657b07Schristos static const struct option longopts[] = { { 0 } }; 140bb16d227Schristos 141bb16d227Schristos setbuf (stdout, 0); 142bb16d227Schristos 143bb16d227Schristos in_gdb = 0; 144bb16d227Schristos 145*8b657b07Schristos while ((o = getopt_long (argc, argv, "tc:vdm:C", longopts, NULL)) 146*8b657b07Schristos != -1) 147bb16d227Schristos switch (o) 148bb16d227Schristos { 149bb16d227Schristos case 't': 150bb16d227Schristos trace++; 151bb16d227Schristos break; 152bb16d227Schristos case 'c': 153bb16d227Schristos #ifdef HAVE_networking 154bb16d227Schristos console_port_s = optarg; 155bb16d227Schristos #else 156bb16d227Schristos fprintf (stderr, "Nework console not available in this build.\n"); 157bb16d227Schristos #endif 158bb16d227Schristos break; 159bb16d227Schristos case 'C': 160bb16d227Schristos #ifdef HAVE_TERMIOS_H 161bb16d227Schristos m32c_use_raw_console = 1; 162bb16d227Schristos #else 163bb16d227Schristos fprintf (stderr, "Raw console not available in this build.\n"); 164bb16d227Schristos #endif 165bb16d227Schristos break; 166bb16d227Schristos case 'v': 167bb16d227Schristos verbose++; 168bb16d227Schristos break; 169bb16d227Schristos case 'd': 170bb16d227Schristos m32c_disassemble++; 171bb16d227Schristos break; 172bb16d227Schristos case 'm': 173bb16d227Schristos if (strcmp (optarg, "r8c") == 0 || strcmp (optarg, "m16c") == 0) 174bb16d227Schristos default_machine = bfd_mach_m16c; 175bb16d227Schristos else if (strcmp (optarg, "m32cm") == 0 176bb16d227Schristos || strcmp (optarg, "m32c") == 0) 177bb16d227Schristos default_machine = bfd_mach_m32c; 178bb16d227Schristos else 179bb16d227Schristos { 180bb16d227Schristos fprintf (stderr, "Invalid machine: %s\n", optarg); 181bb16d227Schristos exit (1); 182bb16d227Schristos } 183bb16d227Schristos break; 184bb16d227Schristos case '?': 185bb16d227Schristos fprintf (stderr, 186bb16d227Schristos "usage: run [-v] [-C] [-c port] [-t] [-d] [-m r8c|m16c|m32cm|m32c]" 187bb16d227Schristos " program\n"); 188bb16d227Schristos exit (1); 189bb16d227Schristos } 190bb16d227Schristos 191bb16d227Schristos prog = bfd_openr (argv[optind], 0); 192bb16d227Schristos if (!prog) 193bb16d227Schristos { 194bb16d227Schristos fprintf (stderr, "Can't read %s\n", argv[optind]); 195bb16d227Schristos exit (1); 196bb16d227Schristos } 197bb16d227Schristos 198bb16d227Schristos if (!bfd_check_format (prog, bfd_object)) 199bb16d227Schristos { 200bb16d227Schristos fprintf (stderr, "%s not a m32c program\n", argv[optind]); 201bb16d227Schristos exit (1); 202bb16d227Schristos } 203bb16d227Schristos 204bb16d227Schristos save_trace = trace; 205bb16d227Schristos trace = 0; 206bb16d227Schristos m32c_load (prog); 207bb16d227Schristos trace = save_trace; 208bb16d227Schristos 209bb16d227Schristos #ifdef HAVE_networking 210bb16d227Schristos if (console_port_s) 211bb16d227Schristos setup_tcp_console (console_port_s); 212bb16d227Schristos #endif 213bb16d227Schristos 214bb16d227Schristos sim_disasm_init (prog); 215bb16d227Schristos 216bb16d227Schristos while (1) 217bb16d227Schristos { 218bb16d227Schristos int rc; 219bb16d227Schristos 220bb16d227Schristos if (trace) 221bb16d227Schristos printf ("\n"); 222bb16d227Schristos 223bb16d227Schristos if (m32c_disassemble) 224bb16d227Schristos sim_disasm_one (); 225bb16d227Schristos 226bb16d227Schristos enable_counting = verbose; 227bb16d227Schristos cycles++; 228bb16d227Schristos rc = decode_opcode (); 229bb16d227Schristos enable_counting = 0; 230bb16d227Schristos 231bb16d227Schristos if (M32C_HIT_BREAK (rc)) 232bb16d227Schristos done (1); 233bb16d227Schristos else if (M32C_EXITED (rc)) 234bb16d227Schristos done (M32C_EXIT_STATUS (rc)); 235bb16d227Schristos else 236bb16d227Schristos assert (M32C_STEPPED (rc)); 237bb16d227Schristos 238bb16d227Schristos trace_register_changes (); 239bb16d227Schristos 240bb16d227Schristos #ifdef TIMER_A 241bb16d227Schristos update_timer_a (); 242bb16d227Schristos #endif 243bb16d227Schristos } 244bb16d227Schristos } 245