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