import gdb-1999-07-07 post reformat
[deliverable/binutils-gdb.git] / gdb / arm-xdep.c
CommitLineData
c906108c
SS
1/* Acorn Risc Machine host machine support.
2 Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20#include "defs.h"
21#include "frame.h"
22#include "inferior.h"
23#include "arm-opcode.h"
24
25#include <sys/param.h>
26#include <sys/dir.h>
27#include <signal.h>
28#include <sys/ioctl.h>
29#include <sys/ptrace.h>
30#include <machine/reg.h>
31
32#define N_TXTADDR(hdr) 0x8000
33#define N_DATADDR(hdr) (hdr.a_text + 0x8000)
34
35#include "gdbcore.h"
36
37#include <sys/user.h> /* After a.out.h */
38#include <sys/file.h>
39#include "gdb_stat.h"
40
41#include <errno.h>
42
43void
44fetch_inferior_registers (regno)
45 int regno; /* Original value discarded */
46{
47 register unsigned int regaddr;
48 char buf[MAX_REGISTER_RAW_SIZE];
49 register int i;
50
51 struct user u;
52 unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
53 offset = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0)
54 - KERNEL_U_ADDR;
55
56 registers_fetched ();
57
58 for (regno = 0; regno < 16; regno++)
59 {
60 regaddr = offset + regno * 4;
61 *(int *)&buf[0] = ptrace (PT_READ_U, inferior_pid,
62 (PTRACE_ARG3_TYPE) regaddr, 0);
63 if (regno == PC_REGNUM)
64 *(int *)&buf[0] = GET_PC_PART(*(int *)&buf[0]);
65 supply_register (regno, buf);
66 }
67 *(int *)&buf[0] = ptrace (PT_READ_U, inferior_pid,
68 (PTRACE_ARG3_TYPE) (offset + PC*4), 0);
69 supply_register (PS_REGNUM, buf); /* set virtual register ps same as pc */
70
71 /* read the floating point registers */
72 offset = (char *) &u.u_fp_regs - (char *)&u;
73 *(int *)buf = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0);
74 supply_register (FPS_REGNUM, buf);
75 for (regno = 16; regno < 24; regno++) {
76 regaddr = offset + 4 + 12 * (regno - 16);
77 for (i = 0; i < 12; i += sizeof(int))
78 *(int *) &buf[i] = ptrace (PT_READ_U, inferior_pid,
79 (PTRACE_ARG3_TYPE) (regaddr + i), 0);
80 supply_register (regno, buf);
81 }
82}
83
84/* Store our register values back into the inferior.
85 If REGNO is -1, do this for all registers.
86 Otherwise, REGNO specifies which register (so we can save time). */
87
88void
89store_inferior_registers (regno)
90 int regno;
91{
92 register unsigned int regaddr;
93 char buf[80];
94
95 struct user u;
96 unsigned long value;
97 unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
98 offset = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0)
99 - KERNEL_U_ADDR;
100
101 if (regno >= 0) {
102 if (regno >= 16) return;
103 regaddr = offset + 4 * regno;
104 errno = 0;
105 value = read_register(regno);
106 if (regno == PC_REGNUM)
107 value = SET_PC_PART(read_register (PS_REGNUM), value);
108 ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, value);
109 if (errno != 0)
110 {
111 sprintf (buf, "writing register number %d", regno);
112 perror_with_name (buf);
113 }
114 }
115 else for (regno = 0; regno < 15; regno++)
116 {
117 regaddr = offset + regno * 4;
118 errno = 0;
119 value = read_register(regno);
120 if (regno == PC_REGNUM)
121 value = SET_PC_PART(read_register (PS_REGNUM), value);
122 ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, value);
123 if (errno != 0)
124 {
125 sprintf (buf, "writing all regs, number %d", regno);
126 perror_with_name (buf);
127 }
128 }
129}
130\f
131/* Work with core dump and executable files, for GDB.
132 This code would be in corefile.c if it weren't machine-dependent. */
133
134/* Structure to describe the chain of shared libraries used
135 by the execfile.
136 e.g. prog shares Xt which shares X11 which shares c. */
137
138struct shared_library {
139 struct exec_header header;
140 char name[SHLIBLEN];
141 CORE_ADDR text_start; /* CORE_ADDR of 1st byte of text, this file */
142 long data_offset; /* offset of data section in file */
143 int chan; /* file descriptor for the file */
144 struct shared_library *shares; /* library this one shares */
145};
146static struct shared_library *shlib = 0;
147
148/* Hook for `exec_file_command' command to call. */
149
150extern void (*exec_file_display_hook) ();
151
152static CORE_ADDR unshared_text_start;
153
154/* extended header from exec file (for shared library info) */
155
156static struct exec_header exec_header;
157\f
158void
159core_file_command (filename, from_tty)
160 char *filename;
161 int from_tty;
162{
163 int val;
c906108c
SS
164
165 /* Discard all vestiges of any previous core file
166 and mark data and stack spaces as empty. */
167
168 if (corefile)
169 free (corefile);
170 corefile = 0;
171
172 if (corechan >= 0)
173 close (corechan);
174 corechan = -1;
175
176 data_start = 0;
177 data_end = 0;
178 stack_start = STACK_END_ADDR;
179 stack_end = STACK_END_ADDR;
180
181 /* Now, if a new core file was specified, open it and digest it. */
182
183 if (filename)
184 {
185 filename = tilde_expand (filename);
186 make_cleanup (free, filename);
187
188 if (have_inferior_p ())
189 error ("To look at a core file, you must kill the program with \"kill\".");
190 corechan = open (filename, O_RDONLY, 0);
191 if (corechan < 0)
192 perror_with_name (filename);
193 /* 4.2-style (and perhaps also sysV-style) core dump file. */
194 {
195 struct user u;
196
197 unsigned int reg_offset, fp_reg_offset;
198
199 val = myread (corechan, &u, sizeof u);
200 if (val < 0)
201 perror_with_name ("Not a core file: reading upage");
202 if (val != sizeof u)
203 error ("Not a core file: could only read %d bytes", val);
204
205 /* We are depending on exec_file_command having been called
206 previously to set exec_data_start. Since the executable
207 and the core file share the same text segment, the address
208 of the data segment will be the same in both. */
209 data_start = exec_data_start;
210
211 data_end = data_start + NBPG * u.u_dsize;
212 stack_start = stack_end - NBPG * u.u_ssize;
213 data_offset = NBPG * UPAGES;
214 stack_offset = NBPG * (UPAGES + u.u_dsize);
215
216 /* Some machines put an absolute address in here and some put
217 the offset in the upage of the regs. */
218 reg_offset = (int) u.u_ar0;
219 if (reg_offset > NBPG * UPAGES)
220 reg_offset -= KERNEL_U_ADDR;
221 fp_reg_offset = (char *) &u.u_fp_regs - (char *)&u;
222
223 /* I don't know where to find this info.
224 So, for now, mark it as not available. */
225 N_SET_MAGIC (core_aouthdr, 0);
226
227 /* Read the register values out of the core file and store
228 them where `read_register' will find them. */
229
230 {
231 register int regno;
232
233 for (regno = 0; regno < NUM_REGS; regno++)
234 {
235 char buf[MAX_REGISTER_RAW_SIZE];
236
237 if (regno < 16)
238 val = lseek (corechan, reg_offset + 4 * regno, 0);
239 else if (regno < 24)
240 val = lseek (corechan, fp_reg_offset + 4 + 12*(regno - 24), 0);
241 else if (regno == 24)
242 val = lseek (corechan, fp_reg_offset, 0);
243 else if (regno == 25)
244 val = lseek (corechan, reg_offset + 4 * PC, 0);
245 if (val < 0
246 || (val = myread (corechan, buf, sizeof buf)) < 0)
247 {
248 char * buffer = (char *) alloca (strlen (REGISTER_NAME (regno))
249 + 30);
250 strcpy (buffer, "Reading register ");
251 strcat (buffer, REGISTER_NAME (regno));
252
253 perror_with_name (buffer);
254 }
255
256 if (regno == PC_REGNUM)
257 *(int *)buf = GET_PC_PART(*(int *)buf);
258 supply_register (regno, buf);
259 }
260 }
261 }
262 if (filename[0] == '/')
263 corefile = savestring (filename, strlen (filename));
264 else
265 {
266 corefile = concat (current_directory, "/", filename, NULL);
267 }
268
269 flush_cached_frames ();
270 select_frame (get_current_frame (), 0);
271 validate_files ();
272 }
273 else if (from_tty)
274 printf ("No core file now.\n");
275}
276
277#if 0
278/* Work with core dump and executable files, for GDB.
279 This code would be in corefile.c if it weren't machine-dependent. */
280
281/* Structure to describe the chain of shared libraries used
282 by the execfile.
283 e.g. prog shares Xt which shares X11 which shares c. */
284
285struct shared_library {
286 struct exec_header header;
287 char name[SHLIBLEN];
288 CORE_ADDR text_start; /* CORE_ADDR of 1st byte of text, this file */
289 long data_offset; /* offset of data section in file */
290 int chan; /* file descriptor for the file */
291 struct shared_library *shares; /* library this one shares */
292};
293static struct shared_library *shlib = 0;
294
295/* Hook for `exec_file_command' command to call. */
296
297extern void (*exec_file_display_hook) ();
298
299static CORE_ADDR unshared_text_start;
300
301/* extended header from exec file (for shared library info) */
302
303static struct exec_header exec_header;
304
305void
306exec_file_command (filename, from_tty)
307 char *filename;
308 int from_tty;
309{
310 int val;
311
312 /* Eliminate all traces of old exec file.
313 Mark text segment as empty. */
314
315 if (execfile)
316 free (execfile);
317 execfile = 0;
318 data_start = 0;
319 data_end -= exec_data_start;
320 text_start = 0;
321 unshared_text_start = 0;
322 text_end = 0;
323 exec_data_start = 0;
324 exec_data_end = 0;
325 if (execchan >= 0)
326 close (execchan);
327 execchan = -1;
328 if (shlib) {
329 close_shared_library(shlib);
330 shlib = 0;
331 }
332
333 /* Now open and digest the file the user requested, if any. */
334
335 if (filename)
336 {
337 filename = tilde_expand (filename);
338 make_cleanup (free, filename);
339
340 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
341 &execfile);
342 if (execchan < 0)
343 perror_with_name (filename);
344
345 {
346 struct stat st_exec;
347
348#ifdef HEADER_SEEK_FD
349 HEADER_SEEK_FD (execchan);
350#endif
351
352 val = myread (execchan, &exec_header, sizeof exec_header);
353 exec_aouthdr = exec_header.a_exec;
354
355 if (val < 0)
356 perror_with_name (filename);
357
358 text_start = 0x8000;
359
360 /* Look for shared library if needed */
361 if (exec_header.a_exec.a_magic & MF_USES_SL)
362 shlib = open_shared_library(exec_header.a_shlibname, text_start);
363
364 text_offset = N_TXTOFF (exec_aouthdr);
365 exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
366
367 if (shlib) {
368 unshared_text_start = shared_text_end(shlib) & ~0x7fff;
369 stack_start = shlib->header.a_exec.a_sldatabase;
370 stack_end = STACK_END_ADDR;
371 } else
372 unshared_text_start = 0x8000;
373 text_end = unshared_text_start + exec_aouthdr.a_text;
374
375 exec_data_start = unshared_text_start + exec_aouthdr.a_text;
376 exec_data_end = exec_data_start + exec_aouthdr.a_data;
377
378 data_start = exec_data_start;
379 data_end += exec_data_start;
380
381 fstat (execchan, &st_exec);
382 exec_mtime = st_exec.st_mtime;
383 }
384
385 validate_files ();
386 }
387 else if (from_tty)
388 printf ("No executable file now.\n");
389
390 /* Tell display code (if any) about the changed file name. */
391 if (exec_file_display_hook)
392 (*exec_file_display_hook) (filename);
393}
394#endif
395
396#if 0
397/* Read from the program's memory (except for inferior processes).
398 This function is misnamed, since it only reads, never writes; and
399 since it will use the core file and/or executable file as necessary.
400
401 It should be extended to write as well as read, FIXME, for patching files.
402
403 Return 0 if address could be read, EIO if addresss out of bounds. */
404
405int
406xfer_core_file (memaddr, myaddr, len)
407 CORE_ADDR memaddr;
408 char *myaddr;
409 int len;
410{
411 register int i;
412 register int val;
413 int xferchan;
414 char **xferfile;
415 int fileptr;
416 int returnval = 0;
417
418 while (len > 0)
419 {
420 xferfile = 0;
421 xferchan = 0;
422
423 /* Determine which file the next bunch of addresses reside in,
424 and where in the file. Set the file's read/write pointer
425 to point at the proper place for the desired address
426 and set xferfile and xferchan for the correct file.
427
428 If desired address is nonexistent, leave them zero.
429
430 i is set to the number of bytes that can be handled
431 along with the next address.
432
433 We put the most likely tests first for efficiency. */
434
435 /* Note that if there is no core file
436 data_start and data_end are equal. */
437 if (memaddr >= data_start && memaddr < data_end)
438 {
439 i = min (len, data_end - memaddr);
440 fileptr = memaddr - data_start + data_offset;
441 xferfile = &corefile;
442 xferchan = corechan;
443 }
444 /* Note that if there is no core file
445 stack_start and stack_end define the shared library data. */
446 else if (memaddr >= stack_start && memaddr < stack_end)
447 {
448 if (corechan < 0) {
449 struct shared_library *lib;
450 for (lib = shlib; lib; lib = lib->shares)
451 if (memaddr >= lib->header.a_exec.a_sldatabase &&
452 memaddr < lib->header.a_exec.a_sldatabase +
453 lib->header.a_exec.a_data)
454 break;
455 if (lib) {
456 i = min (len, lib->header.a_exec.a_sldatabase +
457 lib->header.a_exec.a_data - memaddr);
458 fileptr = lib->data_offset + memaddr -
459 lib->header.a_exec.a_sldatabase;
460 xferfile = execfile;
461 xferchan = lib->chan;
462 }
463 } else {
464 i = min (len, stack_end - memaddr);
465 fileptr = memaddr - stack_start + stack_offset;
466 xferfile = &corefile;
467 xferchan = corechan;
468 }
469 }
470 else if (corechan < 0
471 && memaddr >= exec_data_start && memaddr < exec_data_end)
472 {
473 i = min (len, exec_data_end - memaddr);
474 fileptr = memaddr - exec_data_start + exec_data_offset;
475 xferfile = &execfile;
476 xferchan = execchan;
477 }
478 else if (memaddr >= text_start && memaddr < text_end)
479 {
480 struct shared_library *lib;
481 for (lib = shlib; lib; lib = lib->shares)
482 if (memaddr >= lib->text_start &&
483 memaddr < lib->text_start + lib->header.a_exec.a_text)
484 break;
485 if (lib) {
486 i = min (len, lib->header.a_exec.a_text +
487 lib->text_start - memaddr);
488 fileptr = memaddr - lib->text_start + text_offset;
489 xferfile = &execfile;
490 xferchan = lib->chan;
491 } else {
492 i = min (len, text_end - memaddr);
493 fileptr = memaddr - unshared_text_start + text_offset;
494 xferfile = &execfile;
495 xferchan = execchan;
496 }
497 }
498 else if (memaddr < text_start)
499 {
500 i = min (len, text_start - memaddr);
501 }
502 else if (memaddr >= text_end
503 && memaddr < (corechan >= 0? data_start : exec_data_start))
504 {
505 i = min (len, data_start - memaddr);
506 }
507 else if (corechan >= 0
508 && memaddr >= data_end && memaddr < stack_start)
509 {
510 i = min (len, stack_start - memaddr);
511 }
512 else if (corechan < 0 && memaddr >= exec_data_end)
513 {
514 i = min (len, - memaddr);
515 }
516 else if (memaddr >= stack_end && stack_end != 0)
517 {
518 i = min (len, - memaddr);
519 }
520 else
521 {
522 /* Address did not classify into one of the known ranges.
523 This shouldn't happen; we catch the endpoints. */
524 fatal ("Internal: Bad case logic in xfer_core_file.");
525 }
526
527 /* Now we know which file to use.
528 Set up its pointer and transfer the data. */
529 if (xferfile)
530 {
531 if (*xferfile == 0)
532 if (xferfile == &execfile)
533 error ("No program file to examine.");
534 else
535 error ("No core dump file or running program to examine.");
536 val = lseek (xferchan, fileptr, 0);
537 if (val < 0)
538 perror_with_name (*xferfile);
539 val = myread (xferchan, myaddr, i);
540 if (val < 0)
541 perror_with_name (*xferfile);
542 }
543 /* If this address is for nonexistent memory,
544 read zeros if reading, or do nothing if writing.
545 Actually, we never right. */
546 else
547 {
548 memset (myaddr, '\0', i);
549 returnval = EIO;
550 }
551
552 memaddr += i;
553 myaddr += i;
554 len -= i;
555 }
556 return returnval;
557}
558#endif
This page took 0.049102 seconds and 4 git commands to generate.