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