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

  1. /* Native support for Motorola 88k running Harris CX/UX.
  2.    Copyright 1988, 1990, 1991, 1992, 1993, 1994 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.  
  24. #include <sys/types.h>
  25. #include <sys/param.h>
  26. #include <sys/dir.h>
  27. #include <signal.h>
  28. #include "gdbcore.h"
  29. #include <sys/user.h>
  30.  
  31. #include "bfd.h"
  32. #include "symfile.h"
  33. #include "objfiles.h"
  34. #include "symtab.h"
  35.  
  36. #ifndef USER            /* added to support BCS ptrace_user */
  37. #define USER ptrace_user
  38. #endif
  39. #include <sys/ioctl.h>
  40. #include <fcntl.h>
  41. #include <sys/file.h>
  42. #include <sys/stat.h>
  43.  
  44. #include "symtab.h"
  45. #include "setjmp.h"
  46. #include "value.h"
  47.  
  48. #include <sys/ptrace.h>
  49.  
  50. /* CX/UX provides them already, but as word offsets instead of char offsets */
  51. #define SXIP_OFFSET (PT_SXIP * 4)
  52. #define SNIP_OFFSET (PT_SNIP * 4)
  53. #define SFIP_OFFSET (PT_SFIP * 4)
  54. #define PSR_OFFSET  (PT_PSR  * sizeof(int))
  55. #define FPSR_OFFSET (PT_FPSR * sizeof(int))
  56. #define FPCR_OFFSET (PT_FPCR * sizeof(int))
  57.  
  58. #define XREGADDR(r) (((char *)&u.pt_x0-(char *)&u) + \
  59.                      ((r)-X0_REGNUM)*sizeof(X_REGISTER_RAW_TYPE))
  60.  
  61. extern int have_symbol_file_p();
  62.  
  63. extern jmp_buf stack_jmp;
  64.  
  65. extern int errno;
  66. extern char registers[REGISTER_BYTES];
  67.  
  68. void
  69. fetch_inferior_registers (regno)
  70.      int regno;        /* Original value discarded */
  71. {
  72.   register unsigned int regaddr;
  73.   char buf[MAX_REGISTER_RAW_SIZE];
  74.   register int i;
  75.  
  76.   struct USER u;
  77.   unsigned int offset;
  78.  
  79.   offset = (char *) &u.pt_r0 - (char *) &u; 
  80.   regaddr = offset; /* byte offset to r0;*/
  81.  
  82. /*  offset = ptrace (3, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */
  83.   for (regno = 0; regno < PC_REGNUM; regno++)
  84.     {
  85.       /*regaddr = register_addr (regno, offset);*/
  86.     /* 88k enhancement  */
  87.         
  88.       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
  89.      {
  90.        *(int *) &buf[i] = ptrace (3, inferior_pid,
  91.                      (PTRACE_ARG3_TYPE) regaddr, 0);
  92.        regaddr += sizeof (int);
  93.      }
  94.       supply_register (regno, buf);
  95.     }
  96.     /* now load up registers 32-37; special pc registers */
  97.     *(int *) &buf[0] = ptrace (3, inferior_pid,
  98.                    (PTRACE_ARG3_TYPE) PSR_OFFSET,0);
  99.     supply_register (PSR_REGNUM, buf);
  100.     *(int *) &buf[0] = ptrace (3, inferior_pid,
  101.                    (PTRACE_ARG3_TYPE) FPSR_OFFSET,0);
  102.     supply_register (FPSR_REGNUM, buf);
  103.     *(int *) &buf[0] = ptrace (3, inferior_pid,
  104.                    (PTRACE_ARG3_TYPE) FPCR_OFFSET,0);
  105.     supply_register (FPCR_REGNUM, buf);
  106.     *(int *) &buf[0] = ptrace (3,inferior_pid,
  107.                    (PTRACE_ARG3_TYPE) SXIP_OFFSET ,0);
  108.     supply_register (SXIP_REGNUM, buf);
  109.     *(int *) &buf[0] = ptrace (3, inferior_pid,
  110.                    (PTRACE_ARG3_TYPE) SNIP_OFFSET,0);
  111.     supply_register (SNIP_REGNUM, buf);
  112.     *(int *) &buf[0] = ptrace (3, inferior_pid,
  113.                    (PTRACE_ARG3_TYPE) SFIP_OFFSET,0);
  114.     supply_register (SFIP_REGNUM, buf);
  115.  
  116.     if (target_is_m88110) 
  117.       {
  118.         for (regaddr = XREGADDR(X0_REGNUM), regno = X0_REGNUM;
  119.              regno < NUM_REGS; 
  120.              regno++, regaddr += 16)
  121.           {
  122.             X_REGISTER_RAW_TYPE xval;
  123.  
  124.             *(int *) &xval.w1 = ptrace (3, inferior_pid,
  125.                                         (PTRACE_ARG3_TYPE) regaddr, 0);
  126.             *(int *) &xval.w2 = ptrace (3, inferior_pid,
  127.                                         (PTRACE_ARG3_TYPE) (regaddr+4), 0);
  128.             *(int *) &xval.w3 = ptrace (3, inferior_pid,
  129.                                         (PTRACE_ARG3_TYPE) (regaddr+8), 0);
  130.             *(int *) &xval.w4 = ptrace (3, inferior_pid,
  131.                                         (PTRACE_ARG3_TYPE) (regaddr+12), 0);
  132.             supply_register(regno, (void *)&xval);
  133.           }
  134.       }
  135. }
  136.  
  137. /* Store our register values back into the inferior.
  138.    If REGNO is -1, do this for all registers.
  139.    Otherwise, REGNO specifies which register (so we can save time).  */
  140.  
  141. void
  142. store_inferior_registers (regno)
  143.      int regno;
  144. {
  145.   register unsigned int regaddr;
  146.   char buf[80];
  147.  
  148.   struct USER u;
  149.  
  150.   unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
  151.  
  152.   regaddr = offset;
  153.  
  154.   /* Don't try to deal with EXIP_REGNUM or ENIP_REGNUM, because I think either
  155.      svr3 doesn't run on an 88110, or the kernel isolates the different (not
  156.      completely sure this is true, but seems to be.  */
  157.   if (regno >= 0)
  158.     {
  159.       /*      regaddr = register_addr (regno, offset); */
  160.       if (regno < PC_REGNUM)
  161.     { 
  162.       regaddr = offset + regno * sizeof (int);
  163.       errno = 0;
  164.       ptrace (6, inferior_pid,
  165.           (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
  166.       if (errno != 0)
  167.         {
  168.           sprintf (buf, "writing register number %d", regno);
  169.           perror_with_name (buf);
  170.         }
  171.     }
  172.       else if (regno == PSR_REGNUM)
  173.         ptrace (6, inferior_pid,
  174.         (PTRACE_ARG3_TYPE) PSR_OFFSET, read_register(regno));
  175.       else if (regno == FPSR_REGNUM)
  176.         ptrace (6, inferior_pid,
  177.         (PTRACE_ARG3_TYPE) FPSR_OFFSET, read_register(regno));
  178.       else if (regno == FPCR_REGNUM)
  179.         ptrace (6, inferior_pid,
  180.             (PTRACE_ARG3_TYPE) FPCR_OFFSET, read_register(regno));
  181.       else if (regno == SXIP_REGNUM)
  182.     ptrace (6, inferior_pid,
  183.         (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register(regno));
  184.       else if (regno == SNIP_REGNUM)
  185.     ptrace (6, inferior_pid,
  186.         (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register(regno));
  187.       else if (regno == SFIP_REGNUM)
  188.     ptrace (6, inferior_pid,
  189.         (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register(regno));
  190.       else if (target_is_m88110 && regno < NUM_REGS)
  191.         {
  192.           X_REGISTER_RAW_TYPE xval;
  193.           
  194.           read_register_bytes(REGISTER_BYTE(regno), (char *)&xval, 
  195.                               sizeof(X_REGISTER_RAW_TYPE));
  196.           regaddr = XREGADDR(regno);
  197.           ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, xval.w1);
  198.           ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr+4, xval.w2);
  199.           ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr+8, xval.w3);
  200.           ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr+12, xval.w4);
  201.         }
  202.       else
  203.     printf_unfiltered ("Bad register number for store_inferior routine\n");
  204.     }
  205.   else
  206.     { 
  207.       for (regno = 0; regno < PC_REGNUM; regno++)
  208.     {
  209.       /*      regaddr = register_addr (regno, offset); */
  210.       errno = 0;
  211.       regaddr = offset + regno * sizeof (int);
  212.       ptrace (6, inferior_pid,
  213.           (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
  214.       if (errno != 0)
  215.         {
  216.           sprintf (buf, "writing register number %d", regno);
  217.           perror_with_name (buf);
  218.         }
  219.     }
  220.       ptrace (6, inferior_pid,
  221.               (PTRACE_ARG3_TYPE) PSR_OFFSET, read_register(regno));
  222.       ptrace (6, inferior_pid,
  223.               (PTRACE_ARG3_TYPE) FPSR_OFFSET,read_register(regno));
  224.       ptrace (6, inferior_pid,
  225.               (PTRACE_ARG3_TYPE) FPCR_OFFSET,read_register(regno));
  226.       ptrace (6,inferior_pid,
  227.           (PTRACE_ARG3_TYPE) SXIP_OFFSET,read_register(SXIP_REGNUM));
  228.       ptrace (6,inferior_pid,
  229.           (PTRACE_ARG3_TYPE) SNIP_OFFSET,read_register(SNIP_REGNUM));
  230.       ptrace (6,inferior_pid,
  231.           (PTRACE_ARG3_TYPE) SFIP_OFFSET,read_register(SFIP_REGNUM));
  232.       if (target_is_m88110)
  233.         {
  234.           for (regno = X0_REGNUM; regno < NUM_REGS; regno++) 
  235.             {
  236.               X_REGISTER_RAW_TYPE xval;
  237.      
  238.               read_register_bytes(REGISTER_BYTE(regno), (char *)&xval, 
  239.                                   sizeof(X_REGISTER_RAW_TYPE));
  240.               regaddr = XREGADDR(regno);
  241.               ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, xval.w1);
  242.               ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) (regaddr+4), xval.w2);
  243.               ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) (regaddr+8), xval.w3);
  244.               ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) (regaddr+12), xval.w4);
  245.             }
  246.         }
  247.     }
  248. }
  249.  
  250. /* blockend is the address of the end of the user structure */
  251.  
  252. m88k_register_u_addr (blockend, regnum)
  253.      int blockend, regnum;
  254. {
  255.   struct USER u;
  256.   int ustart = blockend - sizeof (struct USER);
  257.  
  258.   if (regnum < PSR_REGNUM)
  259.       return (ustart + ((int) &u.pt_r0 - (int) &u) +
  260.               REGISTER_SIZE * regnum);
  261.   else if (regnum == PSR_REGNUM)
  262.       return (ustart + ((int) &u.pt_psr) - (int) &u);
  263.   else if (regnum == FPSR_REGNUM)
  264.       return (ustart + ((int) &u.pt_fpsr) - (int) &u);
  265.   else if (regnum == FPCR_REGNUM)
  266.       return (ustart + ((int) &u.pt_fpcr) - (int) &u);
  267.   else if (regnum == SXIP_REGNUM)
  268.       return (ustart + SXIP_OFFSET);
  269.   else if (regnum == SNIP_REGNUM)
  270.       return (ustart + SNIP_OFFSET);
  271.   else if (regnum == SFIP_REGNUM)
  272.       return (ustart + SFIP_OFFSET);
  273.   else if (target_is_m88110) 
  274.       return (ustart + ((int) &u.pt_x0 - (int) &u) +   /* Must be X register */
  275.                sizeof(u.pt_x0) * (regnum - X0_REGNUM));
  276.   else
  277.       return (blockend + REGISTER_SIZE * regnum);
  278. }
  279.  
  280. #ifdef USE_PROC_FS
  281.  
  282. #include <sys/procfs.h>
  283.  
  284. /*  Given a pointer to a general register set in /proc format (gregset_t *),
  285.     unpack the register contents and supply them as gdb's idea of the current
  286.     register values. */
  287.  
  288. void
  289. supply_gregset (gregsetp)
  290.      gregset_t *gregsetp;
  291. {
  292.     register int regi;
  293.     register greg_t *regp = (greg_t *) gregsetp;
  294.  
  295.     for (regi=0; regi <= SP_REGNUM; regi++)
  296.     supply_register (regi, (char *) (regp + regi));
  297.  
  298.     supply_register (SXIP_REGNUM, (char *) (regp + R_XIP));
  299.     supply_register (SNIP_REGNUM, (char *) (regp + R_NIP));
  300.     supply_register (SFIP_REGNUM, (char *) (regp + R_FIP));
  301.     supply_register (PSR_REGNUM, (char *) (regp + R_PSR));
  302.     supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
  303.     supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
  304. }
  305.  
  306. void
  307. fill_gregset (gregsetp, regno)
  308.      gregset_t *gregsetp;
  309.      int regno;
  310. {
  311.     int regi;
  312.     register greg_t *regp = (greg_t *) gregsetp;
  313.     extern char registers[];
  314.  
  315.     for (regi = 0 ; regi <= R_R31 ; regi++)
  316.     if ((regno == -1) || (regno == regi))
  317.         *(regp + regi) = *(int *) ®isters[REGISTER_BYTE(regi)];
  318.  
  319.     if ((regno == -1) || (regno == SXIP_REGNUM))
  320.     *(regp + R_XIP) = *(int *) ®isters[REGISTER_BYTE(SXIP_REGNUM)];
  321.     if ((regno == -1) || (regno == SNIP_REGNUM))
  322.     *(regp + R_NIP) = *(int *) ®isters[REGISTER_BYTE(SNIP_REGNUM)];
  323.     if ((regno == -1) || (regno == SFIP_REGNUM))
  324.     *(regp + R_FIP) = *(int *) ®isters[REGISTER_BYTE(SFIP_REGNUM)];
  325.     if ((regno == -1) || (regno == PSR_REGNUM))
  326.     *(regp + R_PSR) = *(int *) ®isters[REGISTER_BYTE(PSR_REGNUM)];
  327.     if ((regno == -1) || (regno == FPSR_REGNUM))
  328.     *(regp + R_FPSR) = *(int *) ®isters[REGISTER_BYTE(FPSR_REGNUM)];
  329.     if ((regno == -1) || (regno == FPCR_REGNUM))
  330.     *(regp + R_FPCR) = *(int *) ®isters[REGISTER_BYTE(FPCR_REGNUM)];
  331. }
  332.  
  333. #endif /* USE_PROC_FS */
  334.  
  335. /* This support adds the equivalent of adb's % command.  When
  336.    the `add-shared-symbol-files' command is given, this routine scans 
  337.    the dynamic linker's link map and reads the minimal symbols
  338.    from each shared object file listed in the map. */
  339.  
  340. struct link_map {
  341.   unsigned long l_addr;        /* address at which object is mapped */
  342.   char *l_name;            /* full name of loaded object */
  343.   void *l_ld;            /* dynamic structure of object */
  344.   struct link_map *l_next;    /* next link object */
  345.   struct link_map *l_prev;    /* previous link object */
  346. };
  347.  
  348. #define LINKS_MAP_POINTER "_ld_tail"
  349. #define LIBC_FILE "/usr/lib/libc.so.1"
  350. #define SHARED_OFFSET 0xf0001000
  351.  
  352. #ifndef PATH_MAX
  353. #define PATH_MAX 1023        /* maximum size of path name on OS */
  354. #endif
  355.  
  356. void
  357. add_shared_symbol_files ()
  358. {
  359.   void *desc;
  360.   struct link_map *ld_map, *lm, lms;
  361.   struct minimal_symbol *minsym; 
  362.   struct objfile *objfile;
  363.   char *path_name;
  364.  
  365.   if (! inferior_pid)
  366.     {
  367.       warning ("The program has not yet been started.");
  368.       return;
  369.     }
  370.  
  371.   objfile = symbol_file_add (LIBC_FILE, 0, 0, 0, 0, 1);
  372.   minsym = lookup_minimal_symbol (LINKS_MAP_POINTER, objfile);
  373.  
  374.   ld_map = (struct link_map *)
  375.     read_memory_integer (((int)SYMBOL_VALUE_ADDRESS(minsym) + SHARED_OFFSET), 4);
  376.   lm = ld_map;
  377.   while (lm)
  378.     {
  379.       int local_errno = 0;
  380.  
  381.       read_memory ((CORE_ADDR)lm, (char*)&lms, sizeof (struct link_map));
  382.       if (lms.l_name)
  383.     {
  384.       if (target_read_string ((CORE_ADDR)lms.l_name, &path_name, 
  385.                                   PATH_MAX, &local_errno))
  386.         {
  387.           symbol_file_add (path_name, 1, lms.l_addr, 0, 0, 0);
  388.               free(path_name);
  389.         }
  390.     }
  391.       /* traverse links in reverse order so that we get the
  392.      the symbols the user actually gets. */
  393.       lm = lms.l_prev;
  394.     }
  395.  
  396.   /* Getting new symbols may change our opinion about what is
  397.      frameless.  */
  398.   reinit_frame_cache ();
  399. }
  400.  
  401. #if defined(_ES_MP)
  402.  
  403. #include <sys/regset.h>
  404.  
  405. unsigned int
  406. m88k_harris_core_register_addr (regno, reg_ptr)
  407.      int regno, reg_ptr;
  408. {
  409.    unsigned int word_offset;
  410.  
  411.    switch (regno)
  412.      {
  413.      case PSR_REGNUM:
  414.        word_offset = R_EPSR;
  415.        break;
  416.      case FPSR_REGNUM:
  417.        word_offset = R_FPSR;
  418.        break;
  419.      case FPCR_REGNUM:
  420.        word_offset = R_FPCR;
  421.        break;
  422.      case SXIP_REGNUM:
  423.        word_offset = R_EXIP;
  424.        break;
  425.      case SNIP_REGNUM:
  426.        word_offset = R_ENIP;
  427.        break;
  428.      case SFIP_REGNUM:
  429.        word_offset = R_EFIP;
  430.        break;
  431.      default:
  432.        if (regno <= FP_REGNUM) 
  433.      word_offset = regno;
  434.        else 
  435.      word_offset = ((regno - X0_REGNUM) * 4);
  436.      }
  437.    return (word_offset * 4);
  438. }
  439.  
  440. #endif /* _ES_MP */
  441.  
  442. void
  443. _initialize_m88k_nat()
  444. {
  445. #ifdef _ES_MP
  446.    /* Enable 88110 support, as we don't support the 88100 under ES/MP.  */
  447.  
  448.    target_is_m88110 = 1;
  449. #elif defined(_CX_UX)
  450.    /* Determine whether we're running on an 88100 or an 88110.  */
  451.    target_is_m88110 = (sinfo(SYSMACHINE,0) == SYS5800);
  452. #endif /* _CX_UX */
  453. }
  454.  
  455. #ifdef _ES_MP
  456. /* Given a pointer to a general register set in /proc format (gregset_t *),
  457.    unpack the register contents and supply them as gdb's idea of the current
  458.    register values. */
  459.  
  460. void
  461. supply_gregset (gregsetp)
  462.      gregset_t *gregsetp;
  463. {
  464.   register int regi;
  465.   register greg_t *regp = (greg_t *) gregsetp;
  466.  
  467.   for (regi = 0 ; regi < R_R31 ; regi++)
  468.     {
  469.       supply_register (regi, (char *) (regp + regi));
  470.     }
  471.   supply_register (PSR_REGNUM,  (char *) (regp + R_EPSR));
  472.   supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
  473.   supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
  474.   supply_register (SXIP_REGNUM, (char *) (regp + R_EXIP));
  475.   supply_register (SNIP_REGNUM, (char *) (regp + R_ENIP));
  476.   supply_register (SFIP_REGNUM, (char *) (regp + R_EFIP));
  477. }
  478.  
  479. /* Given a pointer to a floating point register set in /proc format
  480.    (fpregset_t *), unpack the register contents and supply them as gdb's
  481.    idea of the current floating point register values.  */
  482.  
  483. void 
  484. supply_fpregset (fpregsetp)
  485.      fpregset_t *fpregsetp;
  486. {
  487.   register int regi;
  488.   char *from;
  489.   
  490.   for (regi = FP0_REGNUM ; regi <= FPLAST_REGNUM ; regi++)
  491.     {
  492.       from = (char *) &((*fpregsetp)[regi-FP0_REGNUM]);
  493.       supply_register (regi, from);
  494.     }
  495. }
  496.  
  497. #endif /* _ES_MP */
  498.  
  499. #ifdef _CX_UX
  500.  
  501. #include <sys/regset.h>
  502.  
  503. unsigned int m88k_harris_core_register_addr(int regno, int reg_ptr)
  504. {
  505.    unsigned int word_offset;
  506.  
  507.    switch (regno) {
  508.     case PSR_REGNUM  : word_offset = R_PSR;  break;
  509.     case FPSR_REGNUM : word_offset = R_FPSR; break;
  510.     case FPCR_REGNUM : word_offset = R_FPCR; break;
  511.     case SXIP_REGNUM : word_offset = R_XIP;  break;
  512.     case SNIP_REGNUM : word_offset = R_NIP;  break;
  513.     case SFIP_REGNUM : word_offset = R_FIP;  break;
  514.     default :
  515.       if (regno <= FP_REGNUM) 
  516.             word_offset = regno;
  517.       else 
  518.             word_offset = ((regno - X0_REGNUM) * 4) + R_X0;
  519.    }
  520.    return (word_offset * 4);
  521. }
  522.  
  523. #endif /* _CX_UX */
  524.