1/* main.c -- top level of ARMulator: ARM6 Instruction Emulator. 2 Copyright (C) 1994 Advanced RISC Machines Ltd. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 17 18/**********************************************************************/ 19/* Forks the ARMulator and hangs on a socket passing on RDP messages */ 20/* down a pipe to the ARMulator which translates them into RDI calls. */ 21/**********************************************************************/ 22 23#include <stdio.h> 24#include <string.h> 25#include <sys/types.h> 26#include <sys/socket.h> 27#include <netinet/in.h> 28#include <signal.h> 29#include <netdb.h> 30#include <unistd.h> 31 32#include "armdefs.h" 33#include "dbg_rdi.h" 34#include "dbg_conf.h" 35 36#define MAXHOSTNAMELENGTH 64 37 38/* Read and write routines down sockets and pipes */ 39 40void MYread_chars (int sock, void *p, int n); 41unsigned char MYread_char (int sock); 42ARMword MYread_word (int sock); 43void MYread_FPword (int sock, char *putinhere); 44 45void MYwrite_word (int sock, ARMword i); 46void MYwrite_string (int sock, char *s); 47void MYwrite_FPword (int sock, char *fromhere); 48void MYwrite_char (int sock, unsigned char c); 49 50void passon (int source, int dest, int n); 51 52 53/* Mother and child processes */ 54void parent (void); 55void kid (void); 56 57/* The child process id. */ 58pid_t child; 59 60/* The socket to the debugger */ 61int debugsock; 62 63/* The pipes between the two processes */ 64int mumkid[2]; 65int kidmum[2]; 66 67/* A pipe for handling SWI return values that goes straight from the */ 68/* parent to the ARMulator host interface, bypassing the childs RDP */ 69/* to RDI interpreter */ 70int DebuggerARMul[2]; 71 72/* The maximum number of file descriptors */ 73int nfds; 74 75/* The socket handle */ 76int sockethandle; 77 78/* The machine name */ 79char localhost[MAXHOSTNAMELENGTH + 1]; 80 81/* The socket number */ 82unsigned int socketnumber; 83 84/**************************************************************/ 85/* Takes one argument: the socket number. */ 86/* Opens a socket to the debugger, and once opened spawns the */ 87/* ARMulator and sets up a couple of pipes. */ 88/**************************************************************/ 89int 90main (int argc, char *argv[]) 91{ 92 int i; 93 struct sockaddr_in devil, isa; 94 struct hostent *hp; 95 96 97 if (argc == 1) 98 { 99 fprintf (stderr, "No socket number\n"); 100 return 1; 101 } 102 103 sscanf (argv[1], "%d", &socketnumber); 104 if (!socketnumber || socketnumber > 0xffff) 105 { 106 fprintf (stderr, "Invalid socket number: %d\n", socketnumber); 107 return 1; 108 } 109 110 gethostname (localhost, MAXHOSTNAMELENGTH); 111 hp = gethostbyname (localhost); 112 if (!hp) 113 { 114 fprintf (stderr, "Cannot get local host info\n"); 115 return 1; 116 } 117 118 /* Open a socket */ 119 sockethandle = socket (hp->h_addrtype, SOCK_STREAM, 0); 120 if (sockethandle < 0) 121 { 122 perror ("socket"); 123 return 1; 124 } 125 126 devil.sin_family = hp->h_addrtype; 127 devil.sin_port = htons (socketnumber); 128 devil.sin_addr.s_addr = 0; 129 for (i = 0; i < sizeof (devil.sin_zero); i++) 130 devil.sin_zero[i] = '\000'; 131 memcpy (&devil.sin_addr, hp->h_addr_list[0], hp->h_length); 132 133 if (bind (sockethandle, &devil, sizeof (devil)) < 0) 134 { 135 perror ("bind"); 136 return 1; 137 } 138 139 /* May only accept one debugger at once */ 140 141 if (listen (sockethandle, 0)) 142 { 143 perror ("listen"); 144 return 1; 145 } 146 147 fprintf (stderr, "Waiting for connection from debugger..."); 148 149 debugsock = accept (sockethandle, &isa, &i); 150 if (debugsock < 0) 151 { 152 perror ("accept"); 153 return 1; 154 } 155 156 fprintf (stderr, " done.\nConnection Established.\n"); 157 158 nfds = getdtablesize (); 159 160 if (pipe (mumkid)) 161 { 162 perror ("pipe"); 163 return 1; 164 } 165 if (pipe (kidmum)) 166 { 167 perror ("pipe"); 168 return 1; 169 } 170 171 if (pipe (DebuggerARMul)) 172 { 173 perror ("pipe"); 174 return 1; 175 } 176 177#ifdef DEBUG 178 fprintf (stderr, "Created pipes ok\n"); 179#endif 180 181 child = fork (); 182 183#ifdef DEBUG 184 fprintf (stderr, "fork() ok\n"); 185#endif 186 187 if (child == 0) 188 kid (); 189 if (child != -1) 190 parent (); 191 192 perror ("fork"); 193 return 1; 194} 195