home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / gdb-4.14-src.lha / gdb-4.14 / gdb / i386aix-nat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-28  |  7.9 KB  |  344 lines

  1. /* Intel 386 native support.
  2.    Copyright (C) 1988, 1989, 1991, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "frame.h"
  22. #include "inferior.h"
  23. #include "language.h"
  24. #include "gdbcore.h"
  25.  
  26. #ifdef USG
  27. #include <sys/types.h>
  28. #endif
  29.  
  30. #include <sys/param.h>
  31. #include <sys/dir.h>
  32. #include <signal.h>
  33. #include <sys/user.h>
  34. #include <sys/ioctl.h>
  35. #include <fcntl.h>
  36.  
  37. #include <sys/file.h>
  38. #include <sys/stat.h>
  39.  
  40. #include <stddef.h>
  41. #include <sys/ptrace.h>
  42.  
  43. /* Does AIX define this in <errno.h>?  */
  44. extern int errno;
  45.  
  46. #ifndef NO_SYS_REG_H
  47. #include <sys/reg.h>
  48. #endif
  49.  
  50. #include "floatformat.h"
  51.  
  52. #include "target.h"
  53.  
  54.  
  55. /* this table must line up with REGISTER_NAMES in tm-i386v.h */
  56. /* symbols like 'EAX' come from <sys/reg.h> */
  57. static int regmap[] = 
  58. {
  59.   EAX, ECX, EDX, EBX,
  60.   USP, EBP, ESI, EDI,
  61.   EIP, EFL, CS, SS,
  62.   DS, ES, FS, GS,
  63. };
  64.  
  65. /* blockend is the value of u.u_ar0, and points to the
  66.  * place where GS is stored
  67.  */
  68.  
  69. int
  70. i386_register_u_addr (blockend, regnum)
  71.      int blockend;
  72.      int regnum;
  73. {
  74. #if 0
  75.   /* this will be needed if fp registers are reinstated */
  76.   /* for now, you can look at them with 'info float'
  77.    * sys5 wont let you change them with ptrace anyway
  78.    */
  79.   if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM) 
  80.     {
  81.       int ubase, fpstate;
  82.       struct user u;
  83.       ubase = blockend + 4 * (SS + 1) - KSTKSZ;
  84.       fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u);
  85.       return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
  86.     } 
  87.   else
  88. #endif
  89.     return (blockend + 4 * regmap[regnum]);
  90.   
  91. }
  92.  
  93. /* The code below only work on the aix ps/2 (i386-ibm-aix) -
  94.  * mtranle@paris - Sat Apr 11 10:34:12 1992
  95.  */
  96.  
  97. struct env387 
  98. {
  99.   unsigned short control;
  100.   unsigned short r0;
  101.   unsigned short status;
  102.   unsigned short r1;
  103.   unsigned short tag;
  104.   unsigned short r2;
  105.   unsigned long eip;
  106.   unsigned short code_seg;
  107.   unsigned short opcode;
  108.   unsigned long operand;
  109.   unsigned short operand_seg;
  110.   unsigned short r3;
  111.   unsigned char regs[8][10];
  112. };
  113.  
  114. static
  115. print_387_status (status, ep)
  116.      unsigned short status;
  117.      struct env387 *ep;
  118. {
  119.   int i;
  120.   int bothstatus;
  121.   int top;
  122.   int fpreg;
  123.   unsigned char *p;
  124.   
  125.   bothstatus = ((status != 0) && (ep->status != 0));
  126.   if (status != 0) 
  127.     {
  128.       if (bothstatus)
  129.     printf_unfiltered ("u: ");
  130.       print_387_status_word (status);
  131.     }
  132.   
  133.   if (ep->status != 0) 
  134.     {
  135.       if (bothstatus)
  136.     printf_unfiltered ("e: ");
  137.       print_387_status_word (ep->status);
  138.     }
  139.   
  140.   print_387_control_word (ep->control);
  141.   printf_unfiltered ("last exception: ");
  142.   printf_unfiltered ("opcode %s; ", local_hex_string(ep->opcode));
  143.   printf_unfiltered ("pc %s:", local_hex_string(ep->code_seg));
  144.   printf_unfiltered ("%s; ", local_hex_string(ep->eip));
  145.   printf_unfiltered ("operand %s", local_hex_string(ep->operand_seg));
  146.   printf_unfiltered (":%s\n", local_hex_string(ep->operand));
  147.  
  148.   top = ((ep->status >> 11) & 7);
  149.  
  150.   printf_unfiltered ("regno  tag  msb              lsb  value\n");
  151.   for (fpreg = 7; fpreg >= 0; fpreg--) 
  152.     {
  153.       double val;
  154.  
  155.       printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
  156.  
  157.       switch ((ep->tag >> ((7 - fpreg) * 2)) & 3) 
  158.     {
  159.     case 0: printf_unfiltered ("valid "); break;
  160.     case 1: printf_unfiltered ("zero  "); break;
  161.     case 2: printf_unfiltered ("trap  "); break;
  162.     case 3: printf_unfiltered ("empty "); break;
  163.     }
  164.       for (i = 9; i >= 0; i--)
  165.     printf_unfiltered ("%02x", ep->regs[fpreg][i]);
  166.       
  167.       i387_to_double ((char *)ep->regs[fpreg], (char *)&val);
  168.       printf_unfiltered ("  %#g\n", val);
  169.     }
  170. }
  171.  
  172. static struct env387 core_env387;
  173.  
  174. void
  175. i386_float_info ()
  176. {
  177.   struct env387 fps;
  178.   int fpsaved = 0;
  179.   /* We need to reverse the order of the registers.  Apparently AIX stores
  180.      the highest-numbered ones first.  */
  181.   struct env387 fps_fixed;
  182.   int i;
  183.  
  184.   if (inferior_pid)
  185.     {
  186.       char buf[10];
  187.       unsigned short status;
  188.  
  189.       ptrace (PT_READ_FPR, inferior_pid, buf, offsetof(struct env387, status));
  190.       memcpy (&status, buf, sizeof (status));
  191.       fpsaved = status;
  192.     }
  193.   else
  194.     {
  195.       if ((fpsaved = core_env387.status) != 0)
  196.     memcpy(&fps, &core_env387, sizeof(fps));
  197.     }
  198.   
  199.   if (fpsaved == 0) 
  200.     {
  201.       printf_unfiltered ("no floating point status saved\n");
  202.       return;
  203.     }
  204.  
  205.   if (inferior_pid)
  206.     {
  207.       int offset;
  208.       for (offset = 0; offset < sizeof(fps); offset += 10)
  209.     {
  210.       char buf[10];
  211.       ptrace (PT_READ_FPR, inferior_pid, buf, offset);
  212.       memcpy ((char *)&fps.control + offset, buf,
  213.           MIN(10, sizeof(fps) - offset));
  214.     }
  215.     } 
  216.   fps_fixed = fps;
  217.   for (i = 0; i < 8; ++i)
  218.     memcpy (fps_fixed.regs[i], fps.regs[7 - i], 10);
  219.   print_387_status (0, &fps_fixed);
  220. }
  221.  
  222. /* Fetch one register.  */
  223. static void
  224. fetch_register (regno)
  225.      int regno;
  226. {
  227.   char buf[MAX_REGISTER_RAW_SIZE];
  228.   if (regno < FP0_REGNUM)
  229.     *(int *)buf = ptrace (PT_READ_GPR, inferior_pid,
  230.               PT_REG(regmap[regno]), 0, 0);
  231.   else
  232.     ptrace (PT_READ_FPR, inferior_pid, buf,
  233.         (regno - FP0_REGNUM)*10 + offsetof(struct env387, regs));
  234.   supply_register (regno, buf);
  235. }
  236.  
  237. void
  238. fetch_inferior_registers (regno)
  239.      int regno;
  240. {
  241.   if (regno < 0)
  242.     for (regno = 0; regno < NUM_REGS; regno++)
  243.       fetch_register (regno);
  244.   else
  245.     fetch_register (regno);
  246. }
  247.  
  248. /* store one register */
  249. static void
  250. store_register (regno)
  251.      int regno;
  252. {
  253.   char buf[80];
  254.   extern char registers[];
  255.   errno = 0;
  256.   if (regno < FP0_REGNUM)
  257.     ptrace (PT_WRITE_GPR, inferior_pid, PT_REG(regmap[regno]),
  258.         *(int *) ®isters[REGISTER_BYTE (regno)], 0);
  259.   else
  260.     ptrace (PT_WRITE_FPR, inferior_pid, ®isters[REGISTER_BYTE (regno)],
  261.         (regno - FP0_REGNUM)*10 + offsetof(struct env387, regs));
  262.  
  263.   if (errno != 0)
  264.     {
  265.       sprintf (buf, "writing register number %d", regno);
  266.       perror_with_name (buf);
  267.     }
  268. }
  269.  
  270. /* Store our register values back into the inferior.
  271.    If REGNO is -1, do this for all registers.
  272.    Otherwise, REGNO specifies which register (so we can save time).  */
  273. void
  274. store_inferior_registers (regno)
  275.      int regno;
  276. {
  277.   if (regno < 0)
  278.     for (regno = 0; regno < NUM_REGS; regno++)
  279.       store_register (regno);
  280.   else
  281.     store_register (regno);
  282. }
  283.  
  284. #ifndef CD_AX            /* defined in sys/i386/coredump.h */
  285. # define CD_AX    0
  286. # define CD_BX    1
  287. # define CD_CX    2
  288. # define CD_DX    3
  289. # define CD_SI    4
  290. # define CD_DI    5
  291. # define CD_BP    6
  292. # define CD_SP    7
  293. # define CD_FL    8
  294. # define CD_IP    9
  295. # define CD_CS    10
  296. # define CD_DS    11
  297. # define CD_ES    12
  298. # define CD_FS    13
  299. # define CD_GS    14
  300. # define CD_SS    15
  301. #endif
  302.  
  303. /*
  304.  * The order here in core_regmap[] has to be the same as in 
  305.  * regmap[] above.
  306.  */
  307. static int core_regmap[] = 
  308. {
  309.   CD_AX, CD_CX, CD_DX, CD_BX,
  310.   CD_SP, CD_BP, CD_SI, CD_DI,
  311.   CD_IP, CD_FL, CD_CS, CD_SS,
  312.   CD_DS, CD_ES, CD_FS, CD_GS,
  313. };
  314.  
  315. void
  316. fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
  317.      char *core_reg_sect;
  318.      unsigned core_reg_size;
  319.      int which;
  320.      unsigned int reg_addr;    /* ignored */
  321. {
  322.  
  323.   if (which == 0)
  324.     {
  325.       /* Integer registers */
  326.  
  327. #define cd_regs(n) ((int *)core_reg_sect)[n]
  328. #define regs(n) *((int *) ®isters[REGISTER_BYTE (n)])
  329.  
  330.       int i;
  331.       for (i = 0; i < FP0_REGNUM; i++)
  332.     regs(i) = cd_regs(core_regmap[i]);
  333.     }
  334.   else if (which == 2)
  335.     {
  336.       /* Floating point registers */
  337.  
  338.       if (core_reg_size >= sizeof (core_env387))
  339.     memcpy (&core_env387, core_reg_sect, core_reg_size);
  340.       else
  341.     fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n");
  342.     }
  343. }
  344.