2002-03-27 Daniel Jacobowitz <drow@mvista.com>
[deliverable/binutils-gdb.git] / gdb / gdbserver / low-sim.c
CommitLineData
c906108c 1/* Low level interface to simulators, for the remote server for GDB.
db728ff7 2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
b6ba6518 3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c 21
c906108c 22#include "server.h"
f29d9b6d 23#include "bfd.h"
c5aa993b
JM
24#include "callback.h" /* GDB simulator callback interface */
25#include "remote-sim.h" /* GDB simulator interface */
c906108c
SS
26
27extern int remote_debug;
28
29extern host_callback default_callback; /* in sim/common/callback.c */
30
5c44784c
JM
31static char my_registers[REGISTER_BYTES] __attribute__ ((aligned));
32char * registers = my_registers;
c906108c 33
c5aa993b 34int target_byte_order; /* used by simulator */
c906108c
SS
35
36/* We record the result of sim_open so we can pass it
37 back to the other sim_foo routines. */
38static SIM_DESC gdbsim_desc = 0;
39
40/* This version of "load" should be usable for any simulator that
41 does not support loading itself. */
42
43static void
f29d9b6d 44mygeneric_load (bfd *loadfile_bfd)
c906108c
SS
45{
46 asection *s;
47
c5aa993b 48 for (s = loadfile_bfd->sections; s; s = s->next)
c906108c 49 {
c5aa993b 50 if (s->flags & SEC_LOAD)
c906108c
SS
51 {
52 bfd_size_type size;
53
54 size = bfd_get_section_size_before_reloc (s);
55 if (size > 0)
56 {
57 char *buffer;
58 bfd_vma lma; /* use load address, not virtual address */
59
60 buffer = xmalloc (size);
61 lma = s->lma;
62
63 /* Is this really necessary? I guess it gives the user something
c5aa993b 64 to look at during a long download. */
c906108c
SS
65 printf ("Loading section %s, size 0x%lx lma 0x%lx\n",
66 bfd_get_section_name (loadfile_bfd, s),
67 (unsigned long) size,
c5aa993b 68 (unsigned long) lma); /* chops high 32 bits. FIXME!! */
c906108c
SS
69
70 bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
71
72 write_inferior_memory (lma, buffer, size);
73 free (buffer);
74 }
75 }
76 }
77
78 printf ("Start address 0x%lx\n",
c5aa993b 79 (unsigned long) loadfile_bfd->start_address);
c906108c
SS
80
81 /* We were doing this in remote-mips.c, I suspect it is right
82 for other targets too. */
c5aa993b 83 /* write_pc (loadfile_bfd->start_address); *//* FIXME!! */
c906108c
SS
84}
85
86int
fba45db2 87create_inferior (char *program, char **argv)
c906108c
SS
88{
89 bfd *abfd;
90 int pid = 0;
c906108c
SS
91 char **new_argv;
92 int nargs;
c906108c
SS
93
94 abfd = bfd_openr (program, 0);
c5aa993b 95 if (!abfd)
c906108c 96 {
c5aa993b 97 fprintf (stderr, "gdbserver: can't open %s: %s\n",
c906108c
SS
98 program, bfd_errmsg (bfd_get_error ()));
99 exit (1);
100 }
101
102 if (!bfd_check_format (abfd, bfd_object))
103 {
104 fprintf (stderr, "gdbserver: unknown load format for %s: %s\n",
105 program, bfd_errmsg (bfd_get_error ()));
106 exit (1);
107 }
108
c906108c
SS
109 /* Add "-E big" or "-E little" to the argument list depending on the
110 endianness of the program to be loaded. */
111 for (nargs = 0; argv[nargs] != NULL; nargs++) /* count the args */
112 ;
113 new_argv = alloca (sizeof (char *) * (nargs + 3)); /* allocate new args */
114 for (nargs = 0; argv[nargs] != NULL; nargs++) /* copy old to new */
115 new_argv[nargs] = argv[nargs];
116 new_argv[nargs] = "-E";
117 new_argv[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
118 new_argv[nargs + 2] = NULL;
119 argv = new_argv;
c906108c
SS
120
121 /* Create an instance of the simulator. */
122 default_callback.init (&default_callback);
123 gdbsim_desc = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, argv);
124 if (gdbsim_desc == 0)
125 exit (1);
126
127 /* Load the program into the simulator. */
128 if (abfd)
129 if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL)
f29d9b6d 130 mygeneric_load (abfd);
c906108c
SS
131
132 /* Create an inferior process in the simulator. This initializes SP. */
133 sim_create_inferior (gdbsim_desc, abfd, argv, /* env */ NULL);
134 sim_resume (gdbsim_desc, 1, 0); /* execute one instr */
135 return pid;
136}
137
45b7b345
DJ
138/* Attaching is not supported. */
139int
140myattach (int pid)
141{
142 return -1;
143}
144
c906108c
SS
145/* Kill the inferior process. Make us have no inferior. */
146
147void
fba45db2 148kill_inferior (void)
c906108c
SS
149{
150 sim_close (gdbsim_desc, 0);
151 default_callback.shutdown (&default_callback);
152}
153
154/* Fetch one register. */
155
156static void
fba45db2 157fetch_register (int regno)
c906108c
SS
158{
159 sim_fetch_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
160 REGISTER_RAW_SIZE (regno));
161}
162
163/* Fetch all registers, or just one, from the child process. */
164
165void
fba45db2 166fetch_inferior_registers (int regno)
c906108c
SS
167{
168 if (regno == -1 || regno == 0)
c5aa993b 169 for (regno = 0; regno < NUM_REGS /*-NUM_FREGS*/ ; regno++)
c906108c
SS
170 fetch_register (regno);
171 else
172 fetch_register (regno);
173}
174
175/* Store our register values back into the inferior.
176 If REGNO is -1, do this for all registers.
177 Otherwise, REGNO specifies which register (so we can save time). */
178
179void
fba45db2 180store_inferior_registers (int regno)
c906108c 181{
c5aa993b 182 if (regno == -1)
c906108c
SS
183 {
184 for (regno = 0; regno < NUM_REGS; regno++)
185 store_inferior_registers (regno);
186 }
187 else
188 sim_store_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
189 REGISTER_RAW_SIZE (regno));
190}
191
192/* Return nonzero if the given thread is still alive. */
193int
fba45db2 194mythread_alive (int pid)
c906108c
SS
195{
196 return 1;
197}
198
199/* Wait for process, returns status */
200
201unsigned char
fba45db2 202mywait (char *status)
c906108c
SS
203{
204 int sigrc;
205 enum sim_stop reason;
206
207 sim_stop_reason (gdbsim_desc, &reason, &sigrc);
208 switch (reason)
209 {
210 case sim_exited:
211 if (remote_debug)
212 printf ("\nChild exited with retcode = %x \n", sigrc);
213 *status = 'W';
214 return sigrc;
215
216#if 0
217 case sim_stopped:
218 if (remote_debug)
219 printf ("\nChild terminated with signal = %x \n", sigrc);
220 *status = 'X';
221 return sigrc;
222#endif
223
c5aa993b 224 default: /* should this be sim_signalled or sim_stopped? FIXME!! */
c906108c
SS
225 if (remote_debug)
226 printf ("\nChild received signal = %x \n", sigrc);
227 fetch_inferior_registers (0);
228 *status = 'T';
229 return (unsigned char) sigrc;
230 }
231}
232
233/* Resume execution of the inferior process.
234 If STEP is nonzero, single-step it.
235 If SIGNAL is nonzero, give it that signal. */
236
237void
fba45db2 238myresume (int step, int signo)
c906108c
SS
239{
240 /* Should be using target_signal_to_host() or signal numbers in target.h
241 to convert GDB signal number to target signal number. */
242 sim_resume (gdbsim_desc, step, signo);
243}
244
245/* Copy LEN bytes from inferior's memory starting at MEMADDR
246 to debugger memory starting at MYADDR. */
247
248void
fba45db2 249read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
250{
251 sim_read (gdbsim_desc, memaddr, myaddr, len);
252}
253
254/* Copy LEN bytes of data from debugger memory at MYADDR
255 to inferior's memory at MEMADDR.
256 On failure (cannot write the inferior)
257 returns the value of errno. */
258
259int
fba45db2 260write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c 261{
c5aa993b 262 sim_write (gdbsim_desc, memaddr, myaddr, len); /* should check for error. FIXME!! */
c906108c
SS
263 return 0;
264}
265
c906108c 266void
fba45db2 267initialize_low (void)
c906108c 268{
c906108c 269}
This page took 0.165472 seconds and 4 git commands to generate.