Sun Aug 1 22:58:18 1993 Stu Grossman (grossman at cygnus.com)
[deliverable/binutils-gdb.git] / gdb / remote-udi.c
index e2aee26270fe3012507b57e4a1f371bf87732a02..b796e90003b85b87205847dfa684dacff9eb4518 100644 (file)
@@ -27,12 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
  - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
        file to gdb 3.95.  I was unable to get this working on sun3os4
-       with termio, only with sgtty.  Because we are only attempting to
-       use this module to debug our kernel, which is already loaded when
-       gdb is started up, I did not code up the file downloading facilities.  
-       As a result this module has only the stubs to download files. 
-       You should get tagged at compile time if you need to make any 
-       changes/additions.
+       with termio, only with sgtty.
  - Daniel Mann at AMD took the 3.95 adaptions above and replaced
        MiniMON interface with UDI-p interface.   */
  
@@ -49,6 +44,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "target.h"
 #include "29k-share/udi/udiproc.h"
 #include "gdbcmd.h"
+#include "bfd.h"
 
 /* access the register store directly, without going through
    the normal handler functions. This avoids an extra data copy.  */
@@ -56,17 +52,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 static int kiodebug;
 extern int stop_soon_quietly;           /* for wait_for_inferior */
 extern struct value *call_function_by_hand();
-static void udi_resume();
-static void udi_fetch_registers ();
-static void udi_load();
-static void fetch_register ();
-static void udi_store_registers ();
-static int store_register ();
-static int regnum_to_srnum();
-static void  udi_close ();
-static CPUSpace udi_memory_space();
-static int udi_write_inferior_memory();
-static int udi_read_inferior_memory();
+static void udi_resume PARAMS ((int pid, int step, int sig));
+static void udi_fetch_registers PARAMS ((int regno));
+static void udi_load PARAMS ((char *args, int from_tty));
+static void fetch_register PARAMS ((int regno));
+static void udi_store_registers PARAMS ((int regno));
+static int store_register PARAMS ((int regno));
+static int regnum_to_srnum PARAMS ((int regno));
+static void udi_close PARAMS ((int quitting));
+static CPUSpace udi_memory_space PARAMS ((CORE_ADDR addr));
+static int udi_write_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+                                             int len));
+static int udi_read_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+                                            int len));
+static void download PARAMS ((char *load_arg_string, int from_tty));
 char   CoffFileName[100] = "";
 /*
  * Processor types. 
@@ -77,7 +76,7 @@ char   CoffFileName[100] = "";
 #define TYPE_A29050     3
 static  char *processor_name[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
 static  int processor_type=TYPE_UNKNOWN;
-#define FREEZE_MODE     (read_register(CPS_REGNUM) && 0x400)
+#define FREEZE_MODE     (read_register(CPS_REGNUM) & 0x400)
 #define USE_SHADOW_PC  ((processor_type == TYPE_A29050) && FREEZE_MODE) 
 
 #define LLOG_FILE "udi.log"
@@ -96,16 +95,21 @@ extern struct target_ops udi_ops;             /* Forward declaration */
 /* Descriptor for I/O to remote machine.  Initialize it to -1 so that
    udi_open knows that we don't have a file open when the program
    starts.  */
-  UDISessionId udi_session_id = -1;
 
-  CPUOffset    IMemStart = 0;
-  CPUSizeT     IMemSize = 0;
-  CPUOffset    DMemStart = 0;
-  CPUSizeT     DMemSize = 0;
-  CPUOffset    RMemStart = 0;
-  CPUSizeT     RMemSize = 0;
-  UDIUInt32    CPUPRL;
-  UDIUInt32    CoProcPRL;
+UDISessionId udi_session_id = -1;
+
+CPUOffset IMemStart = 0;
+CPUSizeT IMemSize = 0;
+CPUOffset DMemStart = 0;
+CPUSizeT DMemSize = 0;
+CPUOffset RMemStart = 0;
+CPUSizeT RMemSize = 0;
+UDIUInt32 CPUPRL;
+UDIUInt32 CoProcPRL;
+
+UDIMemoryRange address_ranges[2]; /* Text and data */
+UDIResource entry = {0, 0};    /* Entry point */
+CPUSizeT stack_sizes[2];       /* Regular and memory stacks */
 
 #define        SBUF_MAX        1024    /* maximum size of string handling buffer */
 char sbuf[SBUF_MAX];
@@ -121,75 +125,64 @@ typedef   struct  bkpt_entry_str
 static bkpt_entry_t    bkpt_table[BKPT_TABLE_SIZE];
 extern char    dfe_errmsg[];           /* error string */
 
-/*********************************************************** SIGNAL SUPPORT */
-/* Called when SIGALRM signal sent due to alarm() timeout.  */
-#ifndef HAVE_TERMIO
-
-#ifndef __STDC__
-# ifndef volatile
-#  define volatile /**/
-# endif
-#endif
-volatile int n_alarms;
-
-static void
-udi_timer ()
-{
-#if 0
-  if (kiodebug)
-    printf ("udi_timer called\n");
-#endif
-  n_alarms++;
-}
-#endif /* HAVE_TERMIO */
-
 /* malloc'd name of the program on the remote system.  */
 static char *prog_name = NULL;
 
-
 /* Number of SIGTRAPs we need to simulate.  That is, the next
    NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
    SIGTRAP without actually waiting for anything.  */
 
-/******************************************************* UDI_CREATE_INFERIOR */
 /* This is called not only when we first attach, but also when the
    user types "run" after having attached.  */
+
 static void
 udi_create_inferior (execfile, args, env)
      char *execfile;
      char *args;
      char **env;
 {
+  char *args1;
 
   if (execfile)
-  { if (prog_name != NULL)
-       free (prog_name);
-    prog_name = savestring (execfile, strlen (execfile));
-  }
-
-  if (prog_name == 0 /* || exec_bfd == 0 */ )
-    error ("No exec file specified");
+    {
+      if (prog_name != NULL)
+       free (prog_name);
+      prog_name = savestring (execfile, strlen (execfile));
+    }
+  else if (entry.Offset)
+    execfile = "";
+  else
+    error ("No image loaded into target.");
 
-  if (udi_session_id < 0){
-        printf("UDI connection not open yet.\n");
-       return;
-  }
+  if (udi_session_id < 0)
+    {
+      printf("UDI connection not open yet.\n");
+      return;
+    }
 
   inferior_pid = 40000;
 
-#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
-   /* On ultra3 (NYU) we assume the kernel is already running so there is
-    *   no file to download
-    */
-#else
-  udi_load(args, 0);
-#endif  /* !ULTRA3 */
+  if (!entry.Offset)
+    download(execfile, 0);
+
+  args1 = alloca (strlen(execfile) + strlen(args) + 2);
+
+  strcpy (args1, execfile);
+  strcat (args1, " ");
+  strcat (args1, args);
+
+  UDIInitializeProcess (address_ranges,                /* ProcessMemory[] */
+                       (UDIInt)2,              /* NumberOfRanges */
+                       entry,                  /* EntryPoint */
+                       stack_sizes,            /* *StackSizes */
+                       (UDIInt)2,              /* NumberOfStacks */
+                       args1);                 /* ArgString */
 
   init_wait_for_inferior ();
   clear_proceed_status ();
   proceed(-1,-1,0);
 }
-/******************************************************* UDI_MOURN_INFERIOR */
+
 static void
 udi_mourn()
 {
@@ -201,7 +194,7 @@ udi_mourn()
 ** Open a connection to remote TIP.
    NAME is the socket domain used for communication with the TIP,
    then a space and the socket name or TIP-host name.
-   '<udi_udi_config_id> [progname]' for example.
+   '<udi_udi_config_id>' for example.
  */
 
 /* XXX - need cleanups for udiconnect for various failures!!! */
@@ -212,57 +205,35 @@ udi_open (name, from_tty)
      char *name;
      int from_tty;
 {
-  unsigned int prl;
-  char         *p;
-  int          cnt;
+  unsigned int prl;
+  char *p;
+  int cnt;
   UDIMemoryRange KnownMemory[10];
-  UDIUInt32    ChipVersions[10];
-  UDIInt       NumberOfRanges = 10;
-  UDIInt       NumberOfChips = 10;
-  UDIPId       PId;
-  UDIUInt32    TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
+  UDIUInt32 ChipVersions[10];
+  UDIInt NumberOfRanges = 10;
+  UDIInt NumberOfChips = 10;
+  UDIPId PId;
+  UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
 
   target_preopen(from_tty);
 
-  /* Find the first whitespace character, it separates udi_config_id
-     from prog_name.  */
-  if(!name) goto erroid;
-    for (p = name;
-         *p != '\0' && !isspace (*p); p++)
-      ;
-  if (*p == '\0')
-erroid:
-    error("Usage: target udi config_id progname, where config_id appears in udi_soc file");
-
-  udi_config_id = (char*)malloc (p - name + 1);
-  strncpy (udi_config_id, name, p - name);
-  udi_config_id[p - name] = '\0';
-
-  /* Skip over the whitespace after udi_config_id */
-  for (; isspace (*p); p++)
-    /*EMPTY*/;
-  
-  if (prog_name != NULL)
-    free (prog_name);
-  prog_name = savestring (p, strlen (p));
+  entry.Offset = 0;
 
-  if (UDIConnect(udi_config_id, &udi_session_id))
-    error("UDIConnect() failed: %s\n", dfe_errmsg);
+  for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
+    bkpt_table[cnt].Type = 0;
 
-  push_target (&udi_ops);
+  if (udi_config_id)
+    free (udi_config_id);
 
-#ifndef HAVE_TERMIO
-#ifndef NO_SIGINTERRUPT
-  /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
-     the read.  */
-  if (siginterrupt (SIGALRM, 1) != 0)
-    error ("udi_open: siginterrupt() %s", safe_strerror(errno));
-#endif
+  if (!name)
+    error("Usage: target udi config_id, where config_id appears in udi_soc file");
 
-  /* Set up read timeout timer.  */
-  if ((void (*)) signal (SIGALRM, udi_timer) == (void (*)) -1)
-    error ("udi_open: signal() %s", safe_strerror(errno));
-#endif
+  udi_config_id = strdup (strtok (name, " \t"));
+
+  if (UDIConnect (udi_config_id, &udi_session_id))
+    error("UDIConnect() failed: %s\n", dfe_errmsg);
+
+  push_target (&udi_ops);
 
 #if defined (LOG_FILE)
   log_file = fopen (LOG_FILE, "w");
@@ -272,80 +243,77 @@ erroid:
   /*
   ** Initialize target configuration structure (global)
   */
-  if(UDIGetTargetConfig( KnownMemory, &NumberOfRanges,
-               ChipVersions, &NumberOfChips))
+  if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
+                         ChipVersions, &NumberOfChips))
     error ("UDIGetTargetConfig() failed");
-  if(NumberOfChips > 2)
-    fprintf(stderr,"Taret has more than one processor\n");
-  for(cnt=0; cnt<NumberOfRanges; cnt++)
-  {     switch(KnownMemory[cnt].Space)
+  if (NumberOfChips > 2)
+    fprintf(stderr,"Target has more than one processor\n");
+  for (cnt=0; cnt < NumberOfRanges; cnt++)
+    {
+      switch(KnownMemory[cnt].Space)
        {
-       default: fprintf(stderr, "UDIGetTargetConfig() unknown memory space\n");
-               break;
+       default:
+         fprintf(stderr, "UDIGetTargetConfig() unknown memory space\n");
+         break;
        case UDI29KCP_S:
-               break;
+         break;
        case UDI29KIROMSpace:
-               RMemStart = KnownMemory[cnt].Offset;
-               RMemSize = KnownMemory[cnt].Size;
-               break;
+         RMemStart = KnownMemory[cnt].Offset;
+         RMemSize = KnownMemory[cnt].Size;
+         break;
        case UDI29KIRAMSpace:
-               IMemStart = KnownMemory[cnt].Offset;
-               IMemSize = KnownMemory[cnt].Size;
-               break;
+         IMemStart = KnownMemory[cnt].Offset;
+         IMemSize = KnownMemory[cnt].Size;
+         break;
        case UDI29KDRAMSpace:
-               DMemStart = KnownMemory[cnt].Offset;
-               DMemSize = KnownMemory[cnt].Size;
-               break;
+         DMemStart = KnownMemory[cnt].Offset;
+         DMemSize = KnownMemory[cnt].Size;
+         break;
        }
-  }
+    }
 
   /* Determine the processor revision level */
-  prl = (unsigned int)read_register(CFG_REGNUM) >> 24;
+  prl = (unsigned int)read_register (CFG_REGNUM) >> 24;
   if ((prl&0xe0) == 0)
-  {   fprintf_filtered(stderr,
-               "Remote debugging Am29000 rev %c\n",'A'+(prl&0x1f));
+    {
+      fprintf_filtered (stderr,
+                       "Remote debugging Am29000 rev %c\n",'A'+(prl&0x1f));
       processor_type = TYPE_A29000;
-  } else if ((prl&0xe0) == 0x40)       /* 29030 = 0x4* */
-  {   fprintf_filtered(stderr,
-               "Remote debugging Am2903* rev %c\n",'A'+(prl&0x1f));
+    }
+  else if ((prl&0xe0) == 0x40)       /* 29030 = 0x4* */
+    {
+      fprintf_filtered (stderr,
+                       "Remote debugging Am2903* rev %c\n",'A'+(prl&0x1f));
       processor_type = TYPE_A29030;
-  } else if ((prl&0xe0) == 0x20)       /* 29050 = 0x2* */
-  {   fprintf_filtered(stderr,
-               "Remote debugging Am29050 rev %c\n",'A'+(prl&0x1f));
+    }
+  else if ((prl&0xe0) == 0x20)       /* 29050 = 0x2* */
+    {
+      fprintf_filtered (stderr,
+                       "Remote debugging Am29050 rev %c\n",'A'+(prl&0x1f));
       processor_type = TYPE_A29050;
-  } else {
+    }
+  else
+    {
       processor_type = TYPE_UNKNOWN;
-      fprintf_filtered(stderr,"WARNING: processor type unknown.\n");
-  }
-  if(UDICreateProcess(&PId))
+      fprintf_filtered (stderr,"WARNING: processor type unknown.\n");
+    }
+  if (UDICreateProcess (&PId))
      fprintf(stderr, "UDICreateProcess() failed\n");
 
   /* Print out some stuff, letting the user now what's going on */
-  if(UDICapabilities( &TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
-       &TIPIPCId, sbuf))
+  if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
+                      &TIPIPCId, sbuf))
     error ("UDICapabilities() failed");
-  if (from_tty) {
-    printf_filtered("Remote debugging an %s connected via UDI socket,\n\
+  if (from_tty)
+    {
+      printf_filtered ("Remote debugging an %s connected via UDI socket,\n\
  DFE-IPC version %x.%x.%x  TIP-IPC version %x.%x.%x  TIP version %x.%x.%x\n %s\n",
-       processor_name[processor_type],
-       (DFEIPCId>>8)&0xf, (DFEIPCId>>4)&0xf, DFEIPCId&0xf,
-       (TIPIPCId>>8)&0xf, (TIPIPCId>>4)&0xf, TIPIPCId&0xf,
-       (TargetId>>8)&0xf, (TargetId>>4)&0xf, TargetId&0xf,
-       sbuf);
-#ifdef ULTRA3
-    /* FIXME: can this restriction be removed? */
-    printf_filtered("Remote debugging using virtual addresses works only\n");
-    printf_filtered(" when virtual addresses map 1:1 to physical addresses.\n");
-#endif
-  }
-#ifdef ULTRA3
-  if (processor_type != TYPE_A29050) {
-        fprintf_filtered(stderr,
-        "Freeze-mode debugging can only be done on an Am29050,\n");
-        fprintf_filtered(stderr,
-        " unless GDB is being used with a 29K simulator.\n");
-  }
-#endif
+                      processor_name[processor_type],
+                      (DFEIPCId>>8)&0xf, (DFEIPCId>>4)&0xf, DFEIPCId&0xf,
+                      (TIPIPCId>>8)&0xf, (TIPIPCId>>4)&0xf, TIPIPCId&0xf,
+                      (TargetId>>8)&0xf, (TargetId>>4)&0xf, TargetId&0xf,
+                      sbuf);
+    }
 }
 
 /******************************************************************* UDI_CLOSE
@@ -356,15 +324,13 @@ static void
 udi_close (quitting)   /*FIXME: how is quitting used */
      int quitting;
 {
-  int  Terminate = -1;
-
   if (udi_session_id < 0)
-    error ("Can't close udi connection: not debugging remotely.");
+    return;
 
   /* We should never get here if there isn't something valid in
-     udi_session_id.
+     udi_session_id. */
 
-  if(UDIDisconnect(udi_stream, Terminate);)
+  if (UDIDisconnect (udi_session_id, UDITerminateSession))
     error ("UDIDisconnect() failed in udi_close");
 
   /* Do not try to close udi_session_id again, later in the program.  */
@@ -396,6 +362,7 @@ udi_attach (args, from_tty)
   UDISizeT     Size = 4;
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
+  UDIError     err;
 
   if (udi_session_id < 0)
       error ("UDI connection not opened yet, use the 'target udi' command.\n");
@@ -404,9 +371,9 @@ udi_attach (args, from_tty)
       printf ("Attaching to remote program %s...\n", prog_name);
 
   UDIStop();
-  From.Space = 11;
-  From.Offset = UDI29KSpecialRegs;
-  if(UDIRead(From, &PC_adds, Count, Size, &CountDone, HostEndian))
+  From.Space = UDI29KSpecialRegs;
+  From.Offset = 11;
+  if (err = UDIRead(From, &PC_adds, Count, Size, &CountDone, HostEndian))
     error ("UDIRead failed in udi_attach");
   printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
 }
@@ -419,10 +386,14 @@ udi_detach (args,from_tty)
      char *args;
      int from_tty;
 {
+
   remove_breakpoints();                /* Just in case there were any left in */
-  if(UDIDisconnect(udi_session_id))
+
+  if (UDIDisconnect (udi_session_id, UDIContinueSession))
     error ("UDIDisconnect() failed in udi_detach");
+
   pop_target();                /* calls udi_close to do the real work */
+
   if (from_tty)
     printf ("Ending remote debugging\n");
 }
@@ -432,8 +403,8 @@ udi_detach (args,from_tty)
 ** Tell the remote machine to resume.  */
 
 static void
-udi_resume (step, sig)
-     int step, sig;
+udi_resume (pid, step, sig)
+     int pid, step, sig;
 {
   UDIError tip_error;
   UDIUInt32 Steps = 1;
@@ -489,7 +460,7 @@ udi_wait (status)
        {
        case UDIStdoutReady:
          if (UDIGetStdout (sbuf, (UDISizeT)SBUF_MAX, &CountDone))
-           error ("UDIGetStdin() failed in udi_wait");
+           error ("UDIGetStdout() failed in udi_wait");
          fwrite (sbuf, 1, CountDone, stdout);
          fflush(stdout);
          continue;
@@ -499,9 +470,13 @@ udi_wait (status)
          fflush(stderr);
          continue;
        case UDIStdinNeeded:
-         printf("DEBUG: stdin requested ... continue\n");
-         /*    UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
+         scanf ("%s", sbuf);
+         i = strlen (sbuf);
+         UDIPutStdin (sbuf, (UDISizeT)i, &CountDone);
          continue;
+       case UDIRunning:
+         /* In spite of the fact that we told UDIWait to wait forever, it will
+            return spuriously sometimes.  */
        case UDIStdinModeX:
          continue;
        default:
@@ -570,14 +545,11 @@ udi_wait (status)
     case UDINotExecuting:
       WSETSTOP ((*status), SIGTERM);
       break;
-    case UDIRunning:
-      WSETSTOP ((*status), SIGILL);
-      break;
     case UDIStopped:
       WSETSTOP ((*status), SIGTSTP);
       break;
     case UDIWarned:
-      WSETSTOP ((*status), SIGLOST);
+      WSETSTOP ((*status), SIGURG);
       break;
     case UDIStepped:
     case UDIBreak:
@@ -613,6 +585,7 @@ int regno;
   UDISizeT     Size = 4;
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
+  UDIError     err;
   int          i;
 
   if (regno >= 0)  {
@@ -626,7 +599,7 @@ int regno;
   From.Offset = 1;
   To = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
   Count = 1;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   register_valid[GR1_REGNUM] = 1;
@@ -639,7 +612,7 @@ int regno;
   From.Offset = 64;
   To = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
   Count = 32;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
@@ -653,7 +626,7 @@ int regno;
   From.Offset = 96;
   To = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
   Count = 32;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
@@ -665,7 +638,7 @@ int regno;
   From.Offset = 0;
   To = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
   Count = 128;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
@@ -677,7 +650,7 @@ int regno;
   From.Offset = 0;
   To = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
   Count = 15;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
@@ -694,7 +667,7 @@ int regno;
     From.Offset = 128;
     To = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
     Count = 135-128 + 1;
-    if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+    if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
       error("UDIRead() failed in udi_fetch_registers");
 
     for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
@@ -947,82 +920,275 @@ udi_remove_breakpoint (addr, contents_cache)
   error("UDIClearBreakpoint returned error code %d\n", err);
 }
 
-/***************************************************************** UDI_KILL */
 static void
 udi_kill(arg,from_tty)
-char    *arg;
-int     from_tty;
+     char *arg;
+     int from_tty;
 {
-       char    buf[4];
 
-#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
-       /* We don't ever kill the kernel */
-       if (from_tty) {
-               printf_filtered("Kernel not killed, but left in current state.\n");
-               printf_filtered("Use detach to leave kernel running.\n");
-       }
-#else
-       UDIStop();
-       inferior_pid = 0;
-       if (from_tty) {
-               printf("Target has been stopped.");
-       }
-       pop_target();
-#endif 
-}
+#if 0
+/*
+UDIStop does not really work as advertised.  It causes the TIP to close it's
+connection, which usually results in GDB dying with a SIGPIPE.  For now, we
+just invoke udi_close, which seems to get things right.
+*/
+  UDIStop();
 
+  udi_session_id = -1;
+  inferior_pid = 0;
 
+  if (from_tty)
+    printf("Target has been stopped.");
+#else
+  udi_close(0);
+#endif
+  pop_target();
+}
 
-/***************************************************************** UDI_LOAD */
 /* 
- * Load a program into the target.
- */
+   Load a program into the target.  Args are: `program {options}'.  The options
+   are used to control loading of the program, and are NOT passed onto the
+   loaded code as arguments.  (You need to use the `run' command to do that.)
+
+   The options are:
+               -ms %d  Set mem stack size to %d
+               -rs %d  Set regular stack size to %d
+               -i      send init info (default)
+               -noi    don't send init info
+               -[tT]   Load Text section
+               -[dD]   Load Data section
+               -[bB]   Load BSS section
+               -[lL]   Load Lit section
+  */
+
 static void
-udi_load(arg_string,from_tty)
-char   *arg_string;
-int    from_tty;
+download(load_arg_string, from_tty)
+     char *load_arg_string;
+     int from_tty;
 {
-#define MAX_TOKENS 25
-#define BUFFER_SIZE 256
-   int token_count;
-   char        *token[MAX_TOKENS];
-   char        cmd_line[BUFFER_SIZE];
+#define DEFAULT_MEM_STACK_SIZE                 0x6000
+#define DEFAULT_REG_STACK_SIZE                 0x2000
+
+  char *token;
+  char *filename;
+  asection *section;
+  bfd *pbfd;
+  UDIError err;
+  int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
+
+  address_ranges[0].Space = UDI29KIRAMSpace;
+  address_ranges[0].Offset = 0xffffffff;
+  address_ranges[0].Size = 0;
+
+  address_ranges[1].Space = UDI29KDRAMSpace;
+  address_ranges[1].Offset = 0xffffffff;
+  address_ranges[1].Size = 0;
+
+  stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
+  stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
 
   dont_repeat ();
 
-#if defined(KERNEL_DEBUGGING) && defined(ULTRA3)
-  printf("The kernel had better be loaded already!  Loading not done.\n");
-#else
-  if (prog_name == 0)
-    error ("No program name");
-  arg_string = tilde_expand (arg_string);
-  sprintf(cmd_line,"y %s %s", prog_name, arg_string);
-
-  token_count = 0;
-  token[0] = cmd_line;
-
-  if (cmd_line[0] != '\0')
-  { token[token_count] = strtok(cmd_line, " \t,;\n\r");
-
-    if (token[token_count] != NULL)
-    { do {
-            token_count = token_count + 1;
-            token[token_count] = strtok((char *) NULL, " \t,;\n\r");
-         } while ((token[token_count] != NULL) &&
-                     (token_count < MAX_TOKENS));
+  filename = strtok(load_arg_string, " \t");
+  if (!filename)
+    error ("Must specify at least a file name with the load command");
+
+  filename = tilde_expand (filename);
+  make_cleanup (free, filename);
+
+  while (token = strtok (NULL, " \t"))
+    {
+      if (token[0] == '-')
+       {
+         token++;
+
+         if (STREQ (token, "ms"))
+           stack_sizes[1] = atol (strtok (NULL, " \t"));
+         else if (STREQ (token, "rs"))
+           stack_sizes[0] = atol (strtok (NULL, " \t"));
+         else
+           {
+             load_text = load_data = load_bss = load_lit = 0;
+
+             while (*token)
+               {
+                 switch (*token++)
+                   {
+                   case 't':
+                   case 'T':
+                     load_text = 1;
+                     break;
+                   case 'd':
+                   case 'D':
+                     load_data = 1;
+                     break;
+                   case 'b':
+                   case 'B':
+                     load_bss = 1;
+                     break;
+                   case 'l':
+                   case 'L':
+                     load_lit = 1;
+                     break;
+                   default:
+                     error ("Unknown UDI load option -%s", token-1);
+                   }
+               }
+           }
+       }
     }
-    else
-         *token[0] = '\0';
-  }
-  make_cleanup (free, arg_string);
+
+  pbfd = bfd_openr (filename, 0);
+
+  if (!pbfd) 
+    perror_with_name (filename);
+  
+  make_cleanup (bfd_close, pbfd);
+
   QUIT;
   immediate_quit++;
-  if(yank_cmd(token, token_count))
-       error("Failure when tring to load program");
+
+  if (!bfd_check_format (pbfd, bfd_object)) 
+    error ("It doesn't seem to be an object file");
+  
+  for (section = pbfd->sections; section; section = section->next) 
+    {
+      if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
+       {
+         UDIResource To;
+         UDICount Count;
+         unsigned long section_size, section_end;
+         const char *section_name;
+
+         section_name = bfd_get_section_name (pbfd, section);
+         if (STREQ (section_name, ".text") && !load_text)
+           continue;
+         else if (STREQ (section_name, ".data") && !load_data)
+           continue;
+         else if (STREQ (section_name, ".bss") && !load_bss)
+           continue;
+         else if (STREQ (section_name, ".lit") && !load_lit)
+           continue;
+
+         To.Offset = bfd_get_section_vma (pbfd, section);
+         section_size = bfd_section_size (pbfd, section);
+         section_end = To.Offset + section_size;
+
+         printf("[Loading section %s at %x (%d bytes)]\n",
+                section_name,
+                To.Offset,
+                section_size);
+
+         if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
+           {
+             To.Space = UDI29KIRAMSpace;
+
+             address_ranges[0].Offset = min (address_ranges[0].Offset,
+                                             To.Offset);
+             address_ranges[0].Size = max (address_ranges[0].Size,
+                                           section_end
+                                           - address_ranges[0].Offset);
+           }
+         else
+           {
+             To.Space = UDI29KDRAMSpace;
+
+             address_ranges[1].Offset = min (address_ranges[1].Offset,
+                                             To.Offset);
+             address_ranges[1].Size = max (address_ranges[1].Size,
+                                           section_end
+                                           - address_ranges[1].Offset);
+           }
+
+         if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
+           {
+             file_ptr fptr;
+
+             fptr = 0;
+
+             while (section_size > 0)
+               {
+                 char buffer[1024];
+
+                 Count = min (section_size, 1024);
+
+                 bfd_get_section_contents (pbfd, section, buffer, fptr,
+                                           Count);
+
+                 err = UDIWrite ((UDIHostMemPtr)buffer, /* From */
+                                 To,                   /* To */
+                                 Count,                /* Count */
+                                 (UDISizeT)1,          /* Size */
+                                 &Count,               /* CountDone */
+                                 (UDIBool)0);          /* HostEndian */
+                 if (err)
+                   error ("UDIWrite failed, error = %d", err);
+
+                 To.Offset += Count;
+                 fptr += Count;
+                 section_size -= Count;
+               }
+           }
+         else                  /* BSS */
+           {
+             UDIResource From;
+             unsigned long zero = 0;
+
+             /* Write a zero byte at the vma */
+             err = UDIWrite ((UDIHostMemPtr)&zero,     /* From */
+                             To,                       /* To */
+                             (UDICount)1,              /* Count */
+                             (UDISizeT)4,              /* Size */
+                             &Count,                   /* CountDone */
+                             (UDIBool)0);              /* HostEndian */
+             if (err)
+               error ("UDIWrite failed, error = %d", err);
+
+             From = To;
+             To.Offset+=4;
+
+             /* Now, duplicate it for the length of the BSS */
+             err = UDICopy (From,                      /* From */
+                            To,                        /* To */
+                            (UDICount)(section_size/4 - 1), /* Count */
+                            (UDISizeT)4,               /* Size */
+                            &Count,                    /* CountDone */
+                            (UDIBool)1);               /* Direction */
+             if (err)
+               {
+                 char message[100];
+                 int xerr;
+
+                 xerr = UDIGetErrorMsg(err, 100, message, &Count);
+                 if (!xerr)
+                   fprintf (stderr, "Error is %s\n", message);
+                 else
+                   fprintf (stderr, "xerr is %d\n", xerr);
+                 error ("UDICopy failed, error = %d", err);
+               }
+           }
+
+       }
+    }
+
+  entry.Space = UDI29KIRAMSpace;
+  entry.Offset = bfd_get_start_address (pbfd);
+  
   immediate_quit--;
-  symbol_file_add (prog_name, from_tty, 0, 0, 0, 0);/*DEBUG need to add text_addr */
-#endif
+}
+
+/* User interface to download an image into the remote target.  See download()
+ * for details on args.
+ */
+
+static void
+udi_load(args, from_tty)
+     char *args;
+     int from_tty;
+{
+  download (args, from_tty);
 
+  symbol_file_add (strtok (args, " \t"), from_tty, 0, 0, 0, 0);
 }
 
 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
@@ -1042,7 +1208,7 @@ udi_write_inferior_memory (memaddr, myaddr, len)
   UDICount     CountDone = 0;
   UDIBool      HostEndian = 0;
   
-  To.Space = udi_memory_space(memaddr);        
+  To.Space = udi_memory_space(memaddr);
   From = (UDIUInt32*)myaddr;
 
   while (nwritten < len)
@@ -1077,6 +1243,7 @@ udi_read_inferior_memory(memaddr, myaddr, len)
   UDISizeT     Size = 1;
   UDICount     CountDone = 0;
   UDIBool      HostEndian = 0;
+  UDIError     err;
   
   From.Space = udi_memory_space(memaddr);      
   To = (UDIUInt32*)myaddr;
@@ -1085,8 +1252,8 @@ udi_read_inferior_memory(memaddr, myaddr, len)
   {    Count = len - nread;
        if (Count > MAXDATA) Count = MAXDATA;
        From.Offset = memaddr + nread;
-        if(UDIRead(From, To, Count, Size, &CountDone, HostEndian))
-       {  error("UDIWrite() failed in udi_read_inferrior_memory");
+        if(err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+       {  error("UDIRead() failed in udi_read_inferrior_memory");
           break;       
        }
        else
@@ -1120,6 +1287,7 @@ fetch_register (regno)
   UDISizeT     Size = 4;
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
+  UDIError     err;
   int                  result;
 
   if (regno == GR1_REGNUM)
@@ -1160,7 +1328,7 @@ fetch_register (regno)
       From.Offset = regnum_to_srnum(regno); 
     }
 
-  if (UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   supply_register(regno, (char *) &To);
@@ -1282,7 +1450,7 @@ int       regno;
  */
 static CPUSpace
 udi_memory_space(addr)
-CORE_ADDR      *addr;
+CORE_ADDR      addr;
 {
        UDIUInt32 tstart = IMemStart;
        UDIUInt32 tend   = tstart + IMemSize;  
@@ -1316,7 +1484,25 @@ int   QuietMode = 0;             /* used for debugging */
 static struct target_ops udi_ops = {
         "udi",
        "Remote UDI connected TIP",
-       "Remote debug an AMD 29k using UDI socket connection to TIP process",
+       "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
+Arguments are\n\
+`configuration-id AF_INET hostname port-number'\n\
+    To connect via the network, where hostname and port-number specify the\n\
+    host and port where you can connect via UDI.\n\
+    configuration-id is unused.\n\
+\n\
+`configuration-id AF_UNIX socket-name tip-program'\n\
+    To connect using a local connection to the \"tip.exe\" program which is\n\
+    supplied by AMD.  If socket-name specifies an AF_UNIX socket then the\n\
+    tip program must already be started; connect to it using that socket.\n\
+    If not, start up tip-program, which should be the name of the tip\n\
+    program.  If appropriate, the PATH environment variable is searched.\n\
+    configuration-id is unused.\n\
+\n\
+`configuration-id'\n\
+    Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
+    are files containing lines in the above formats.  configuration-id is\n\
+    used to pick which line of the file to use.",
         udi_open,
        udi_close,
         udi_attach,
This page took 0.035684 seconds and 4 git commands to generate.