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