]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/arm-xdep.c
Initial creation of sourceware repository
[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, 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
43 void
44 fetch_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
88 void
89 store_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
138 struct 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 };
146 static struct shared_library *shlib = 0;
147
148 /* Hook for `exec_file_command' command to call. */
149
150 extern void (*exec_file_display_hook) ();
151
152 static CORE_ADDR unshared_text_start;
153
154 /* extended header from exec file (for shared library info) */
155
156 static struct exec_header exec_header;
157 \f
158 void
159 core_file_command (filename, from_tty)
160 char *filename;
161 int from_tty;
162 {
163 int val;
164 extern char registers[];
165
166 /* Discard all vestiges of any previous core file
167 and mark data and stack spaces as empty. */
168
169 if (corefile)
170 free (corefile);
171 corefile = 0;
172
173 if (corechan >= 0)
174 close (corechan);
175 corechan = -1;
176
177 data_start = 0;
178 data_end = 0;
179 stack_start = STACK_END_ADDR;
180 stack_end = STACK_END_ADDR;
181
182 /* Now, if a new core file was specified, open it and digest it. */
183
184 if (filename)
185 {
186 filename = tilde_expand (filename);
187 make_cleanup (free, filename);
188
189 if (have_inferior_p ())
190 error ("To look at a core file, you must kill the program with \"kill\".");
191 corechan = open (filename, O_RDONLY, 0);
192 if (corechan < 0)
193 perror_with_name (filename);
194 /* 4.2-style (and perhaps also sysV-style) core dump file. */
195 {
196 struct user u;
197
198 unsigned int reg_offset, fp_reg_offset;
199
200 val = myread (corechan, &u, sizeof u);
201 if (val < 0)
202 perror_with_name ("Not a core file: reading upage");
203 if (val != sizeof u)
204 error ("Not a core file: could only read %d bytes", val);
205
206 /* We are depending on exec_file_command having been called
207 previously to set exec_data_start. Since the executable
208 and the core file share the same text segment, the address
209 of the data segment will be the same in both. */
210 data_start = exec_data_start;
211
212 data_end = data_start + NBPG * u.u_dsize;
213 stack_start = stack_end - NBPG * u.u_ssize;
214 data_offset = NBPG * UPAGES;
215 stack_offset = NBPG * (UPAGES + u.u_dsize);
216
217 /* Some machines put an absolute address in here and some put
218 the offset in the upage of the regs. */
219 reg_offset = (int) u.u_ar0;
220 if (reg_offset > NBPG * UPAGES)
221 reg_offset -= KERNEL_U_ADDR;
222 fp_reg_offset = (char *) &u.u_fp_regs - (char *)&u;
223
224 /* I don't know where to find this info.
225 So, for now, mark it as not available. */
226 N_SET_MAGIC (core_aouthdr, 0);
227
228 /* Read the register values out of the core file and store
229 them where `read_register' will find them. */
230
231 {
232 register int regno;
233
234 for (regno = 0; regno < NUM_REGS; regno++)
235 {
236 char buf[MAX_REGISTER_RAW_SIZE];
237
238 if (regno < 16)
239 val = lseek (corechan, reg_offset + 4 * regno, 0);
240 else if (regno < 24)
241 val = lseek (corechan, fp_reg_offset + 4 + 12*(regno - 24), 0);
242 else if (regno == 24)
243 val = lseek (corechan, fp_reg_offset, 0);
244 else if (regno == 25)
245 val = lseek (corechan, reg_offset + 4 * PC, 0);
246 if (val < 0
247 || (val = myread (corechan, buf, sizeof buf)) < 0)
248 {
249 char * buffer = (char *) alloca (strlen (REGISTER_NAME (regno))
250 + 30);
251 strcpy (buffer, "Reading register ");
252 strcat (buffer, REGISTER_NAME (regno));
253
254 perror_with_name (buffer);
255 }
256
257 if (regno == PC_REGNUM)
258 *(int *)buf = GET_PC_PART(*(int *)buf);
259 supply_register (regno, buf);
260 }
261 }
262 }
263 if (filename[0] == '/')
264 corefile = savestring (filename, strlen (filename));
265 else
266 {
267 corefile = concat (current_directory, "/", filename, NULL);
268 }
269
270 flush_cached_frames ();
271 select_frame (get_current_frame (), 0);
272 validate_files ();
273 }
274 else if (from_tty)
275 printf ("No core file now.\n");
276 }
277
278 #if 0
279 /* Work with core dump and executable files, for GDB.
280 This code would be in corefile.c if it weren't machine-dependent. */
281
282 /* Structure to describe the chain of shared libraries used
283 by the execfile.
284 e.g. prog shares Xt which shares X11 which shares c. */
285
286 struct shared_library {
287 struct exec_header header;
288 char name[SHLIBLEN];
289 CORE_ADDR text_start; /* CORE_ADDR of 1st byte of text, this file */
290 long data_offset; /* offset of data section in file */
291 int chan; /* file descriptor for the file */
292 struct shared_library *shares; /* library this one shares */
293 };
294 static struct shared_library *shlib = 0;
295
296 /* Hook for `exec_file_command' command to call. */
297
298 extern void (*exec_file_display_hook) ();
299
300 static CORE_ADDR unshared_text_start;
301
302 /* extended header from exec file (for shared library info) */
303
304 static struct exec_header exec_header;
305
306 void
307 exec_file_command (filename, from_tty)
308 char *filename;
309 int from_tty;
310 {
311 int val;
312
313 /* Eliminate all traces of old exec file.
314 Mark text segment as empty. */
315
316 if (execfile)
317 free (execfile);
318 execfile = 0;
319 data_start = 0;
320 data_end -= exec_data_start;
321 text_start = 0;
322 unshared_text_start = 0;
323 text_end = 0;
324 exec_data_start = 0;
325 exec_data_end = 0;
326 if (execchan >= 0)
327 close (execchan);
328 execchan = -1;
329 if (shlib) {
330 close_shared_library(shlib);
331 shlib = 0;
332 }
333
334 /* Now open and digest the file the user requested, if any. */
335
336 if (filename)
337 {
338 filename = tilde_expand (filename);
339 make_cleanup (free, filename);
340
341 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
342 &execfile);
343 if (execchan < 0)
344 perror_with_name (filename);
345
346 {
347 struct stat st_exec;
348
349 #ifdef HEADER_SEEK_FD
350 HEADER_SEEK_FD (execchan);
351 #endif
352
353 val = myread (execchan, &exec_header, sizeof exec_header);
354 exec_aouthdr = exec_header.a_exec;
355
356 if (val < 0)
357 perror_with_name (filename);
358
359 text_start = 0x8000;
360
361 /* Look for shared library if needed */
362 if (exec_header.a_exec.a_magic & MF_USES_SL)
363 shlib = open_shared_library(exec_header.a_shlibname, text_start);
364
365 text_offset = N_TXTOFF (exec_aouthdr);
366 exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
367
368 if (shlib) {
369 unshared_text_start = shared_text_end(shlib) & ~0x7fff;
370 stack_start = shlib->header.a_exec.a_sldatabase;
371 stack_end = STACK_END_ADDR;
372 } else
373 unshared_text_start = 0x8000;
374 text_end = unshared_text_start + exec_aouthdr.a_text;
375
376 exec_data_start = unshared_text_start + exec_aouthdr.a_text;
377 exec_data_end = exec_data_start + exec_aouthdr.a_data;
378
379 data_start = exec_data_start;
380 data_end += exec_data_start;
381
382 fstat (execchan, &st_exec);
383 exec_mtime = st_exec.st_mtime;
384 }
385
386 validate_files ();
387 }
388 else if (from_tty)
389 printf ("No executable file now.\n");
390
391 /* Tell display code (if any) about the changed file name. */
392 if (exec_file_display_hook)
393 (*exec_file_display_hook) (filename);
394 }
395 #endif
396
397 #if 0
398 /* Read from the program's memory (except for inferior processes).
399 This function is misnamed, since it only reads, never writes; and
400 since it will use the core file and/or executable file as necessary.
401
402 It should be extended to write as well as read, FIXME, for patching files.
403
404 Return 0 if address could be read, EIO if addresss out of bounds. */
405
406 int
407 xfer_core_file (memaddr, myaddr, len)
408 CORE_ADDR memaddr;
409 char *myaddr;
410 int len;
411 {
412 register int i;
413 register int val;
414 int xferchan;
415 char **xferfile;
416 int fileptr;
417 int returnval = 0;
418
419 while (len > 0)
420 {
421 xferfile = 0;
422 xferchan = 0;
423
424 /* Determine which file the next bunch of addresses reside in,
425 and where in the file. Set the file's read/write pointer
426 to point at the proper place for the desired address
427 and set xferfile and xferchan for the correct file.
428
429 If desired address is nonexistent, leave them zero.
430
431 i is set to the number of bytes that can be handled
432 along with the next address.
433
434 We put the most likely tests first for efficiency. */
435
436 /* Note that if there is no core file
437 data_start and data_end are equal. */
438 if (memaddr >= data_start && memaddr < data_end)
439 {
440 i = min (len, data_end - memaddr);
441 fileptr = memaddr - data_start + data_offset;
442 xferfile = &corefile;
443 xferchan = corechan;
444 }
445 /* Note that if there is no core file
446 stack_start and stack_end define the shared library data. */
447 else if (memaddr >= stack_start && memaddr < stack_end)
448 {
449 if (corechan < 0) {
450 struct shared_library *lib;
451 for (lib = shlib; lib; lib = lib->shares)
452 if (memaddr >= lib->header.a_exec.a_sldatabase &&
453 memaddr < lib->header.a_exec.a_sldatabase +
454 lib->header.a_exec.a_data)
455 break;
456 if (lib) {
457 i = min (len, lib->header.a_exec.a_sldatabase +
458 lib->header.a_exec.a_data - memaddr);
459 fileptr = lib->data_offset + memaddr -
460 lib->header.a_exec.a_sldatabase;
461 xferfile = execfile;
462 xferchan = lib->chan;
463 }
464 } else {
465 i = min (len, stack_end - memaddr);
466 fileptr = memaddr - stack_start + stack_offset;
467 xferfile = &corefile;
468 xferchan = corechan;
469 }
470 }
471 else if (corechan < 0
472 && memaddr >= exec_data_start && memaddr < exec_data_end)
473 {
474 i = min (len, exec_data_end - memaddr);
475 fileptr = memaddr - exec_data_start + exec_data_offset;
476 xferfile = &execfile;
477 xferchan = execchan;
478 }
479 else if (memaddr >= text_start && memaddr < text_end)
480 {
481 struct shared_library *lib;
482 for (lib = shlib; lib; lib = lib->shares)
483 if (memaddr >= lib->text_start &&
484 memaddr < lib->text_start + lib->header.a_exec.a_text)
485 break;
486 if (lib) {
487 i = min (len, lib->header.a_exec.a_text +
488 lib->text_start - memaddr);
489 fileptr = memaddr - lib->text_start + text_offset;
490 xferfile = &execfile;
491 xferchan = lib->chan;
492 } else {
493 i = min (len, text_end - memaddr);
494 fileptr = memaddr - unshared_text_start + text_offset;
495 xferfile = &execfile;
496 xferchan = execchan;
497 }
498 }
499 else if (memaddr < text_start)
500 {
501 i = min (len, text_start - memaddr);
502 }
503 else if (memaddr >= text_end
504 && memaddr < (corechan >= 0? data_start : exec_data_start))
505 {
506 i = min (len, data_start - memaddr);
507 }
508 else if (corechan >= 0
509 && memaddr >= data_end && memaddr < stack_start)
510 {
511 i = min (len, stack_start - memaddr);
512 }
513 else if (corechan < 0 && memaddr >= exec_data_end)
514 {
515 i = min (len, - memaddr);
516 }
517 else if (memaddr >= stack_end && stack_end != 0)
518 {
519 i = min (len, - memaddr);
520 }
521 else
522 {
523 /* Address did not classify into one of the known ranges.
524 This shouldn't happen; we catch the endpoints. */
525 fatal ("Internal: Bad case logic in xfer_core_file.");
526 }
527
528 /* Now we know which file to use.
529 Set up its pointer and transfer the data. */
530 if (xferfile)
531 {
532 if (*xferfile == 0)
533 if (xferfile == &execfile)
534 error ("No program file to examine.");
535 else
536 error ("No core dump file or running program to examine.");
537 val = lseek (xferchan, fileptr, 0);
538 if (val < 0)
539 perror_with_name (*xferfile);
540 val = myread (xferchan, myaddr, i);
541 if (val < 0)
542 perror_with_name (*xferfile);
543 }
544 /* If this address is for nonexistent memory,
545 read zeros if reading, or do nothing if writing.
546 Actually, we never right. */
547 else
548 {
549 memset (myaddr, '\0', i);
550 returnval = EIO;
551 }
552
553 memaddr += i;
554 myaddr += i;
555 len -= i;
556 }
557 return returnval;
558 }
559 #endif