OSDN Git Service

Ensure bfd_close after bfd_openw so we don't get multiple bfd_openw
[pf3gnuchains/pf3gnuchains4x.git] / gdb / arm-linux-nat.c
1 /* GNU/Linux on ARM native support.
2    Copyright 1999, 2000 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 "inferior.h"
23 #include "gdbcore.h"
24 #include "gdb_string.h"
25
26 #include <sys/user.h>
27 #include <sys/ptrace.h>
28 #include <sys/utsname.h>
29 #include <sys/procfs.h>
30
31 extern int arm_apcs_32;
32
33 #define         typeNone                0x00
34 #define         typeSingle              0x01
35 #define         typeDouble              0x02
36 #define         typeExtended            0x03
37 #define         FPWORDS                 28
38 #define         CPSR_REGNUM             16
39
40 typedef union tagFPREG
41   {
42     unsigned int fSingle;
43     unsigned int fDouble[2];
44     unsigned int fExtended[3];
45   }
46 FPREG;
47
48 typedef struct tagFPA11
49   {
50     FPREG fpreg[8];             /* 8 floating point registers */
51     unsigned int fpsr;          /* floating point status register */
52     unsigned int fpcr;          /* floating point control register */
53     unsigned char fType[8];     /* type of floating point value held in
54                                    floating point registers.  */
55     int initflag;               /* NWFPE initialization flag.  */
56   }
57 FPA11;
58
59 /* The following variables are used to determine the version of the
60    underlying Linux operating system.  Examples:
61
62    Linux 2.0.35                 Linux 2.2.12
63    os_version = 0x00020023      os_version = 0x0002020c
64    os_major = 2                 os_major = 2
65    os_minor = 0                 os_minor = 2
66    os_release = 35              os_release = 12
67
68    Note: os_version = (os_major << 16) | (os_minor << 8) | os_release
69
70    These are initialized using get_linux_version() from
71    _initialize_arm_linux_nat().  */
72
73 static unsigned int os_version, os_major, os_minor, os_release;
74
75 /* On Linux, threads are implemented as pseudo-processes, in which
76    case we may be tracing more than one process at a time.  In that
77    case, inferior_pid will contain the main process ID and the
78    individual thread (process) ID mashed together.  These macros are
79    used to separate them out.  These definitions should be overridden
80    if thread support is included.  */
81
82 #if !defined (PIDGET)   /* Default definition for PIDGET/TIDGET.  */
83 #define PIDGET(PID)     PID
84 #define TIDGET(PID)     0
85 #endif
86
87 int
88 get_thread_id (int inferior_pid)
89 {
90   int tid = TIDGET (inferior_pid);
91   if (0 == tid) tid = inferior_pid;
92   return tid;
93 }
94 #define GET_THREAD_ID(PID)      get_thread_id ((PID));
95
96 static void
97 fetch_nwfpe_single (unsigned int fn, FPA11 * fpa11)
98 {
99   unsigned int mem[3];
100
101   mem[0] = fpa11->fpreg[fn].fSingle;
102   mem[1] = 0;
103   mem[2] = 0;
104   supply_register (F0_REGNUM + fn, (char *) &mem[0]);
105 }
106
107 static void
108 fetch_nwfpe_double (unsigned int fn, FPA11 * fpa11)
109 {
110   unsigned int mem[3];
111
112   mem[0] = fpa11->fpreg[fn].fDouble[1];
113   mem[1] = fpa11->fpreg[fn].fDouble[0];
114   mem[2] = 0;
115   supply_register (F0_REGNUM + fn, (char *) &mem[0]);
116 }
117
118 static void
119 fetch_nwfpe_none (unsigned int fn)
120 {
121   unsigned int mem[3] =
122   {0, 0, 0};
123
124   supply_register (F0_REGNUM + fn, (char *) &mem[0]);
125 }
126
127 static void
128 fetch_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
129 {
130   unsigned int mem[3];
131
132   mem[0] = fpa11->fpreg[fn].fExtended[0];       /* sign & exponent */
133   mem[1] = fpa11->fpreg[fn].fExtended[2];       /* ls bits */
134   mem[2] = fpa11->fpreg[fn].fExtended[1];       /* ms bits */
135   supply_register (F0_REGNUM + fn, (char *) &mem[0]);
136 }
137
138 static void
139 fetch_nwfpe_register (int regno, FPA11 * fpa11)
140 {
141    int fn = regno - F0_REGNUM;
142
143    switch (fpa11->fType[fn])
144      {
145      case typeSingle:
146        fetch_nwfpe_single (fn, fpa11);
147        break;
148
149      case typeDouble:
150        fetch_nwfpe_double (fn, fpa11);
151        break;
152
153      case typeExtended:
154        fetch_nwfpe_extended (fn, fpa11);
155        break;
156
157      default:
158        fetch_nwfpe_none (fn);
159      }
160 }
161
162 static void
163 store_nwfpe_single (unsigned int fn, FPA11 * fpa11)
164 {
165   unsigned int mem[3];
166
167   read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
168   fpa11->fpreg[fn].fSingle = mem[0];
169   fpa11->fType[fn] = typeSingle;
170 }
171
172 static void
173 store_nwfpe_double (unsigned int fn, FPA11 * fpa11)
174 {
175   unsigned int mem[3];
176
177   read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
178   fpa11->fpreg[fn].fDouble[1] = mem[0];
179   fpa11->fpreg[fn].fDouble[0] = mem[1];
180   fpa11->fType[fn] = typeDouble;
181 }
182
183 void
184 store_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
185 {
186   unsigned int mem[3];
187
188   read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
189   fpa11->fpreg[fn].fExtended[0] = mem[0];       /* sign & exponent */
190   fpa11->fpreg[fn].fExtended[2] = mem[1];       /* ls bits */
191   fpa11->fpreg[fn].fExtended[1] = mem[2];       /* ms bits */
192   fpa11->fType[fn] = typeDouble;
193 }
194
195 void
196 store_nwfpe_register (int regno, FPA11 * fpa11)
197 {
198   if (register_valid[regno])
199     {
200        unsigned int fn = regno - F0_REGNUM;
201        switch (fpa11->fType[fn])
202          {
203          case typeSingle:
204            store_nwfpe_single (fn, fpa11);
205            break;
206
207          case typeDouble:
208            store_nwfpe_double (fn, fpa11);
209            break;
210
211          case typeExtended:
212            store_nwfpe_extended (fn, fpa11);
213            break;
214          }
215     }
216 }
217
218
219 /* Get the value of a particular register from the floating point
220    state of the process and store it into registers[].  */
221
222 static void
223 fetch_fpregister (int regno)
224 {
225   int ret, tid;
226   FPA11 fp;
227   
228   /* Get the thread id for the ptrace call.  */
229   tid = GET_THREAD_ID (inferior_pid);
230
231   /* Read the floating point state.  */
232   ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
233   if (ret < 0)
234     {
235       warning ("Unable to fetch floating point register.");
236       return;
237     }
238
239   /* Fetch fpsr.  */
240   if (FPS_REGNUM == regno)
241     supply_register (FPS_REGNUM, (char *) &fp.fpsr);
242
243   /* Fetch the floating point register.  */
244   if (regno >= F0_REGNUM && regno <= F7_REGNUM)
245     {
246       int fn = regno - F0_REGNUM;
247
248       switch (fp.fType[fn])
249         {
250         case typeSingle:
251           fetch_nwfpe_single (fn, &fp);
252           break;
253
254         case typeDouble:
255             fetch_nwfpe_double (fn, &fp);
256           break;
257
258         case typeExtended:
259             fetch_nwfpe_extended (fn, &fp);
260           break;
261
262         default:
263             fetch_nwfpe_none (fn);
264         }
265     }
266 }
267
268 /* Get the whole floating point state of the process and store it
269    into registers[].  */
270
271 static void
272 fetch_fpregs (void)
273 {
274   int ret, regno, tid;
275   FPA11 fp;
276
277   /* Get the thread id for the ptrace call.  */
278   tid = GET_THREAD_ID (inferior_pid);
279   
280   /* Read the floating point state.  */
281   ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
282   if (ret < 0)
283     {
284       warning ("Unable to fetch the floating point registers.");
285       return;
286     }
287
288   /* Fetch fpsr.  */
289   supply_register (FPS_REGNUM, (char *) &fp.fpsr);
290
291   /* Fetch the floating point registers.  */
292   for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
293     {
294       int fn = regno - F0_REGNUM;
295
296       switch (fp.fType[fn])
297         {
298         case typeSingle:
299           fetch_nwfpe_single (fn, &fp);
300           break;
301
302         case typeDouble:
303           fetch_nwfpe_double (fn, &fp);
304           break;
305
306         case typeExtended:
307           fetch_nwfpe_extended (fn, &fp);
308           break;
309
310         default:
311           fetch_nwfpe_none (fn);
312         }
313     }
314 }
315
316 /* Save a particular register into the floating point state of the
317    process using the contents from registers[].  */
318
319 static void
320 store_fpregister (int regno)
321 {
322   int ret, tid;
323   FPA11 fp;
324
325   /* Get the thread id for the ptrace call.  */
326   tid = GET_THREAD_ID (inferior_pid);
327   
328   /* Read the floating point state.  */
329   ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
330   if (ret < 0)
331     {
332       warning ("Unable to fetch the floating point registers.");
333       return;
334     }
335
336   /* Store fpsr.  */
337   if (FPS_REGNUM == regno && register_valid[FPS_REGNUM])
338     read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
339
340   /* Store the floating point register.  */
341   if (regno >= F0_REGNUM && regno <= F7_REGNUM)
342     {
343       store_nwfpe_register (regno, &fp);
344     }
345
346   ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp);
347   if (ret < 0)
348     {
349       warning ("Unable to store floating point register.");
350       return;
351     }
352 }
353
354 /* Save the whole floating point state of the process using
355    the contents from registers[].  */
356
357 static void
358 store_fpregs (void)
359 {
360   int ret, regno, tid;
361   FPA11 fp;
362
363   /* Get the thread id for the ptrace call.  */
364   tid = GET_THREAD_ID (inferior_pid);
365   
366   /* Read the floating point state.  */
367   ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
368   if (ret < 0)
369     {
370       warning ("Unable to fetch the floating point registers.");
371       return;
372     }
373
374   /* Store fpsr.  */
375   if (register_valid[FPS_REGNUM])
376     read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
377
378   /* Store the floating point registers.  */
379   for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
380     {
381       fetch_nwfpe_register (regno, &fp);
382     }
383
384   ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp);
385   if (ret < 0)
386     {
387       warning ("Unable to store floating point registers.");
388       return;
389     }
390 }
391
392 /* Fetch a general register of the process and store into
393    registers[].  */
394
395 static void
396 fetch_register (int regno)
397 {
398   int ret, tid;
399   struct pt_regs regs;
400
401   /* Get the thread id for the ptrace call.  */
402   tid = GET_THREAD_ID (inferior_pid);
403   
404   ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
405   if (ret < 0)
406     {
407       warning ("Unable to fetch general register.");
408       return;
409     }
410
411   if (regno >= A1_REGNUM && regno < PC_REGNUM)
412     supply_register (regno, (char *) &regs.uregs[regno]);
413
414   if (PS_REGNUM == regno)
415     {
416       if (arm_apcs_32)
417         supply_register (PS_REGNUM, (char *) &regs.uregs[CPSR_REGNUM]);
418       else
419         supply_register (PS_REGNUM, (char *) &regs.uregs[PC_REGNUM]);
420     }
421     
422   if (PC_REGNUM == regno)
423     { 
424       regs.uregs[PC_REGNUM] = ADDR_BITS_REMOVE (regs.uregs[PC_REGNUM]);
425       supply_register (PC_REGNUM, (char *) &regs.uregs[PC_REGNUM]);
426     }
427 }
428
429 /* Fetch all general registers of the process and store into
430    registers[].  */
431
432 static void
433 fetch_regs (void)
434 {
435   int ret, regno, tid;
436   struct pt_regs regs;
437
438   /* Get the thread id for the ptrace call.  */
439   tid = GET_THREAD_ID (inferior_pid);
440   
441   ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
442   if (ret < 0)
443     {
444       warning ("Unable to fetch general registers.");
445       return;
446     }
447
448   for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
449     supply_register (regno, (char *) &regs.uregs[regno]);
450
451   if (arm_apcs_32)
452     supply_register (PS_REGNUM, (char *) &regs.uregs[CPSR_REGNUM]);
453   else
454     supply_register (PS_REGNUM, (char *) &regs.uregs[PC_REGNUM]);
455
456   regs.uregs[PC_REGNUM] = ADDR_BITS_REMOVE (regs.uregs[PC_REGNUM]);
457   supply_register (PC_REGNUM, (char *) &regs.uregs[PC_REGNUM]);
458 }
459
460 /* Store all general registers of the process from the values in
461    registers[].  */
462
463 static void
464 store_register (int regno)
465 {
466   int ret, tid;
467   struct pt_regs regs;
468   
469   if (!register_valid[regno])
470     return;
471
472   /* Get the thread id for the ptrace call.  */
473   tid = GET_THREAD_ID (inferior_pid);
474   
475   /* Get the general registers from the process.  */
476   ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
477   if (ret < 0)
478     {
479       warning ("Unable to fetch general registers.");
480       return;
481     }
482
483   if (regno >= A1_REGNUM && regno <= PC_REGNUM)
484     read_register_gen (regno, (char *) &regs.uregs[regno]);
485
486   ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
487   if (ret < 0)
488     {
489       warning ("Unable to store general register.");
490       return;
491     }
492 }
493
494 static void
495 store_regs (void)
496 {
497   int ret, regno, tid;
498   struct pt_regs regs;
499
500   /* Get the thread id for the ptrace call.  */
501   tid = GET_THREAD_ID (inferior_pid);
502   
503   /* Fetch the general registers.  */
504   ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
505   if (ret < 0)
506     {
507       warning ("Unable to fetch general registers.");
508       return;
509     }
510
511   for (regno = A1_REGNUM; regno <= PC_REGNUM; regno++)
512     {
513       if (register_valid[regno])
514         read_register_gen (regno, (char *) &regs.uregs[regno]);
515     }
516
517   ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
518
519   if (ret < 0)
520     {
521       warning ("Unable to store general registers.");
522       return;
523     }
524 }
525
526 /* Fetch registers from the child process.  Fetch all registers if
527    regno == -1, otherwise fetch all general registers or all floating
528    point registers depending upon the value of regno.  */
529
530 void
531 fetch_inferior_registers (int regno)
532 {
533   if (-1 == regno)
534     {
535       fetch_regs ();
536       fetch_fpregs ();
537     }
538   else 
539     {
540       if (regno < F0_REGNUM || regno > FPS_REGNUM)
541         fetch_register (regno);
542
543       if (regno >= F0_REGNUM && regno <= FPS_REGNUM)
544         fetch_fpregister (regno);
545     }
546 }
547
548 /* Store registers back into the inferior.  Store all registers if
549    regno == -1, otherwise store all general registers or all floating
550    point registers depending upon the value of regno.  */
551
552 void
553 store_inferior_registers (int regno)
554 {
555   if (-1 == regno)
556     {
557       store_regs ();
558       store_fpregs ();
559     }
560   else
561     {
562       if ((regno < F0_REGNUM) || (regno > FPS_REGNUM))
563         store_register (regno);
564
565       if ((regno >= F0_REGNUM) && (regno <= FPS_REGNUM))
566         store_fpregister (regno);
567     }
568 }
569
570 /* Fill register regno (if it is a general-purpose register) in
571    *gregsetp with the appropriate value from GDB's register array.
572    If regno is -1, do this for all registers.  */
573
574 void
575 fill_gregset (gregset_t *gregsetp, int regno)
576 {
577   if (-1 == regno)
578     {
579       int regnum;
580       for (regnum = A1_REGNUM; regnum <= PC_REGNUM; regnum++) 
581         if (register_valid[regnum])
582           read_register_gen (regnum, (char *) &(*gregsetp)[regnum]);
583     }
584   else if (regno >= A1_REGNUM && regno <= PC_REGNUM)
585     {
586       if (register_valid[regno])
587         read_register_gen (regno, (char *) &(*gregsetp)[regno]);
588     }
589
590   if (PS_REGNUM == regno || -1 == regno)
591     {
592       if (register_valid[regno] || -1 == regno)
593         {
594           if (arm_apcs_32)
595             read_register_gen (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]);
596           else
597             read_register_gen (PC_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]);
598         }
599     }
600         
601 }
602
603 /* Fill GDB's register array with the general-purpose register values
604    in *gregsetp.  */
605
606 void
607 supply_gregset (gregset_t *gregsetp)
608 {
609   int regno, reg_pc;
610
611   for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
612     supply_register (regno, (char *) &(*gregsetp)[regno]);
613
614   if (arm_apcs_32)
615     supply_register (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]);
616   else
617     supply_register (PS_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]);
618
619   reg_pc = ADDR_BITS_REMOVE ((CORE_ADDR)(*gregsetp)[PC_REGNUM]);
620   supply_register (PC_REGNUM, (char *) &reg_pc);
621 }
622
623 /* Fill register regno (if it is a floating-point register) in
624    *fpregsetp with the appropriate value from GDB's register array.
625    If regno is -1, do this for all registers.  */
626
627 void
628 fill_fpregset (fpregset_t *fpregsetp, int regno)
629 {
630   FPA11 *fp = (FPA11 *) fpregsetp;
631   
632   if (-1 == regno)
633     {
634        int regnum;
635        for (regnum = F0_REGNUM; regnum <= F7_REGNUM; regnum++)
636          store_nwfpe_register (regnum, fp);
637     }
638   else if (regno >= F0_REGNUM && regno <= F7_REGNUM)
639     {
640       store_nwfpe_register (regno, fp);
641       return;
642     }
643
644   /* Store fpsr.  */
645   if (register_valid[FPS_REGNUM])
646     if (FPS_REGNUM == regno || -1 == regno)
647       read_register_gen (FPS_REGNUM, (char *) &fp->fpsr);
648 }
649
650 /* Fill GDB's register array with the floating-point register values
651    in *fpregsetp.  */
652
653 void
654 supply_fpregset (fpregset_t *fpregsetp)
655 {
656   int regno;
657   FPA11 *fp = (FPA11 *) fpregsetp;
658
659   /* Fetch fpsr.  */
660   supply_register (FPS_REGNUM, (char *) &fp->fpsr);
661
662   /* Fetch the floating point registers.  */
663   for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
664     {
665       fetch_nwfpe_register (regno, fp);
666     }
667 }
668
669 int
670 arm_linux_kernel_u_size (void)
671 {
672   return (sizeof (struct user));
673 }
674
675 static unsigned int
676 get_linux_version (unsigned int *vmajor,
677                    unsigned int *vminor,
678                    unsigned int *vrelease)
679 {
680   struct utsname info;
681   char *pmajor, *pminor, *prelease, *tail;
682
683   if (-1 == uname (&info))
684     {
685       warning ("Unable to determine Linux version.");
686       return -1;
687     }
688
689   pmajor = strtok (info.release, ".");
690   pminor = strtok (NULL, ".");
691   prelease = strtok (NULL, ".");
692
693   *vmajor = (unsigned int) strtoul (pmajor, &tail, 0);
694   *vminor = (unsigned int) strtoul (pminor, &tail, 0);
695   *vrelease = (unsigned int) strtoul (prelease, &tail, 0);
696
697   return ((*vmajor << 16) | (*vminor << 8) | *vrelease);
698 }
699
700 void
701 _initialize_arm_linux_nat (void)
702 {
703   os_version = get_linux_version (&os_major, &os_minor, &os_release);
704 }