OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [gdbserver/] [low-lynx.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* Low level interface to ptrace, for the remote server for GDB.
2
   Copyright (C) 1986, 1987, 1993 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 "server.h"
22
#include "frame.h"
23
#include "inferior.h"
24
 
25
#include <stdio.h>
26
#include <sys/param.h>
27
#include <sys/dir.h>
28
#define LYNXOS
29
#include <sys/mem.h>
30
#include <sys/signal.h>
31
#include <sys/file.h>
32
#include <sys/kernel.h>
33
#ifndef __LYNXOS
34
#define __LYNXOS
35
#endif
36
#include <sys/itimer.h>
37
#include <sys/time.h>
38
#include <sys/resource.h>
39
#include <sys/proc.h>
40
#include <signal.h>
41
#include <sys/ioctl.h>
42
#include <sgtty.h>
43
#include <fcntl.h>
44
#include <sys/wait.h>
45
#include <sys/fpp.h>
46
 
47
static char my_registers[REGISTER_BYTES];
48
char *registers = my_registers;
49
 
50
#include <sys/ptrace.h>
51
 
52
/* Start an inferior process and returns its pid.
53
   ALLARGS is a vector of program-name and args. */
54
 
55
int
56
create_inferior (program, allargs)
57
     char *program;
58
     char **allargs;
59
{
60
  int pid;
61
 
62
  pid = fork ();
63
  if (pid < 0)
64
    perror_with_name ("fork");
65
 
66
  if (pid == 0)
67
    {
68
      int pgrp;
69
 
70
      /* Switch child to it's own process group so that signals won't
71
         directly affect gdbserver. */
72
 
73
      pgrp = getpid ();
74
      setpgrp (0, pgrp);
75
      ioctl (0, TIOCSPGRP, &pgrp);
76
 
77
      ptrace (PTRACE_TRACEME, 0, (PTRACE_ARG3_TYPE) 0, 0);
78
 
79
      execv (program, allargs);
80
 
81
      fprintf (stderr, "GDBserver (process %d):  Cannot exec %s: %s.\n",
82
               getpid (), program,
83
               errno < sys_nerr ? sys_errlist[errno] : "unknown error");
84
      fflush (stderr);
85
      _exit (0177);
86
    }
87
 
88
  return pid;
89
}
90
 
91
/* Kill the inferior process.  Make us have no inferior.  */
92
 
93
void
94
kill_inferior ()
95
{
96
  if (inferior_pid == 0)
97
    return;
98
  ptrace (PTRACE_KILL, inferior_pid, 0, 0);
99
  wait (0);
100
 
101
  inferior_pid = 0;
102
}
103
 
104
/* Return nonzero if the given thread is still alive.  */
105
int
106
mythread_alive (pid)
107
     int pid;
108
{
109
  /* Arggh.  Apparently pthread_kill only works for threads within
110
     the process that calls pthread_kill.
111
 
112
     We want to avoid the lynx signal extensions as they simply don't
113
     map well to the generic gdb interface we want to keep.
114
 
115
     All we want to do is determine if a particular thread is alive;
116
     it appears as if we can just make a harmless thread specific
117
     ptrace call to do that.  */
118
  return (ptrace (PTRACE_THREADUSER,
119
                  BUILDPID (PIDGET (inferior_pid), pid), 0, 0) != -1);
120
}
121
 
122
/* Wait for process, returns status */
123
 
124
unsigned char
125
mywait (status)
126
     char *status;
127
{
128
  int pid;
129
  union wait w;
130
 
131
  while (1)
132
    {
133
      enable_async_io ();
134
 
135
      pid = wait (&w);
136
 
137
      disable_async_io ();
138
 
139
      if (pid != PIDGET (inferior_pid))
140
        perror_with_name ("wait");
141
 
142
      thread_from_wait = w.w_tid;
143
      inferior_pid = BUILDPID (inferior_pid, w.w_tid);
144
 
145
      if (WIFSTOPPED (w)
146
          && WSTOPSIG (w) == SIGTRAP)
147
        {
148
          int realsig;
149
 
150
          realsig = ptrace (PTRACE_GETTRACESIG, inferior_pid,
151
                            (PTRACE_ARG3_TYPE) 0, 0);
152
 
153
          if (realsig == SIGNEWTHREAD)
154
            {
155
              /* It's a new thread notification.  Nothing to do here since
156
                 the machine independent code in wait_for_inferior will
157
                 add the thread to the thread list and restart the thread
158
                 when pid != inferior_pid and pid is not in the thread list.
159
                 We don't even want to muck with realsig -- the code in
160
                 wait_for_inferior expects SIGTRAP.  */
161
              ;
162
            }
163
        }
164
      break;
165
    }
166
 
167
  if (WIFEXITED (w))
168
    {
169
      *status = 'W';
170
      return ((unsigned char) WEXITSTATUS (w));
171
    }
172
  else if (!WIFSTOPPED (w))
173
    {
174
      *status = 'X';
175
      return ((unsigned char) WTERMSIG (w));
176
    }
177
 
178
  fetch_inferior_registers (0);
179
 
180
  *status = 'T';
181
  return ((unsigned char) WSTOPSIG (w));
182
}
183
 
184
/* Resume execution of the inferior process.
185
   If STEP is nonzero, single-step it.
186
   If SIGNAL is nonzero, give it that signal.  */
187
 
188
void
189
myresume (step, signal)
190
     int step;
191
     int signal;
192
{
193
  errno = 0;
194
  ptrace (step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT,
195
          BUILDPID (inferior_pid, cont_thread == -1 ? 0 : cont_thread),
196
          1, signal);
197
  if (errno)
198
    perror_with_name ("ptrace");
199
}
200
 
201
#undef offsetof
202
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
203
 
204
/* Mapping between GDB register #s and offsets into econtext.  Must be
205
   consistent with REGISTER_NAMES macro in various tmXXX.h files. */
206
 
207
#define X(ENTRY)(offsetof(struct econtext, ENTRY))
208
 
209
#ifdef I386
210
/* Mappings from tm-i386v.h */
211
 
212
static int regmap[] =
213
{
214
  X (eax),
215
  X (ecx),
216
  X (edx),
217
  X (ebx),
218
  X (esp),                      /* sp */
219
  X (ebp),                      /* fp */
220
  X (esi),
221
  X (edi),
222
  X (eip),                      /* pc */
223
  X (flags),                    /* ps */
224
  X (cs),
225
  X (ss),
226
  X (ds),
227
  X (es),
228
  X (ecode),                    /* Lynx doesn't give us either fs or gs, so */
229
  X (fault),                    /* we just substitute these two in the hopes
230
                                   that they are useful. */
231
};
232
#endif
233
 
234
#ifdef M68K
235
/* Mappings from tm-m68k.h */
236
 
237
static int regmap[] =
238
{
239
  X (regs[0]),                   /* d0 */
240
  X (regs[1]),                  /* d1 */
241
  X (regs[2]),                  /* d2 */
242
  X (regs[3]),                  /* d3 */
243
  X (regs[4]),                  /* d4 */
244
  X (regs[5]),                  /* d5 */
245
  X (regs[6]),                  /* d6 */
246
  X (regs[7]),                  /* d7 */
247
  X (regs[8]),                  /* a0 */
248
  X (regs[9]),                  /* a1 */
249
  X (regs[10]),                 /* a2 */
250
  X (regs[11]),                 /* a3 */
251
  X (regs[12]),                 /* a4 */
252
  X (regs[13]),                 /* a5 */
253
  X (regs[14]),                 /* fp */
254
  0,                             /* sp */
255
  X (status),                   /* ps */
256
  X (pc),
257
 
258
  X (fregs[0 * 3]),              /* fp0 */
259
  X (fregs[1 * 3]),             /* fp1 */
260
  X (fregs[2 * 3]),             /* fp2 */
261
  X (fregs[3 * 3]),             /* fp3 */
262
  X (fregs[4 * 3]),             /* fp4 */
263
  X (fregs[5 * 3]),             /* fp5 */
264
  X (fregs[6 * 3]),             /* fp6 */
265
  X (fregs[7 * 3]),             /* fp7 */
266
 
267
  X (fcregs[0]),         /* fpcontrol */
268
  X (fcregs[1]),                /* fpstatus */
269
  X (fcregs[2]),                /* fpiaddr */
270
  X (ssw),                      /* fpcode */
271
  X (fault),                    /* fpflags */
272
};
273
#endif
274
 
275
#ifdef SPARC
276
/* Mappings from tm-sparc.h */
277
 
278
#define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
279
 
280
static int regmap[] =
281
{
282
  -1,                           /* g0 */
283
  X (g1),
284
  X (g2),
285
  X (g3),
286
  X (g4),
287
  -1,                           /* g5->g7 aren't saved by Lynx */
288
  -1,
289
  -1,
290
 
291
  X (o[0]),
292
  X (o[1]),
293
  X (o[2]),
294
  X (o[3]),
295
  X (o[4]),
296
  X (o[5]),
297
  X (o[6]),                     /* sp */
298
  X (o[7]),                     /* ra */
299
 
300
  -1, -1, -1, -1, -1, -1, -1, -1,       /* l0 -> l7 */
301
 
302
  -1, -1, -1, -1, -1, -1, -1, -1,       /* i0 -> i7 */
303
 
304
  FX (f.fregs[0]),               /* f0 */
305
  FX (f.fregs[1]),
306
  FX (f.fregs[2]),
307
  FX (f.fregs[3]),
308
  FX (f.fregs[4]),
309
  FX (f.fregs[5]),
310
  FX (f.fregs[6]),
311
  FX (f.fregs[7]),
312
  FX (f.fregs[8]),
313
  FX (f.fregs[9]),
314
  FX (f.fregs[10]),
315
  FX (f.fregs[11]),
316
  FX (f.fregs[12]),
317
  FX (f.fregs[13]),
318
  FX (f.fregs[14]),
319
  FX (f.fregs[15]),
320
  FX (f.fregs[16]),
321
  FX (f.fregs[17]),
322
  FX (f.fregs[18]),
323
  FX (f.fregs[19]),
324
  FX (f.fregs[20]),
325
  FX (f.fregs[21]),
326
  FX (f.fregs[22]),
327
  FX (f.fregs[23]),
328
  FX (f.fregs[24]),
329
  FX (f.fregs[25]),
330
  FX (f.fregs[26]),
331
  FX (f.fregs[27]),
332
  FX (f.fregs[28]),
333
  FX (f.fregs[29]),
334
  FX (f.fregs[30]),
335
  FX (f.fregs[31]),
336
 
337
  X (y),
338
  X (psr),
339
  X (wim),
340
  X (tbr),
341
  X (pc),
342
  X (npc),
343
  FX (fsr),                     /* fpsr */
344
  -1,                           /* cpsr */
345
};
346
#endif
347
 
348
#ifdef SPARC
349
 
350
/* This routine handles some oddball cases for Sparc registers and LynxOS.
351
   In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
352
   It also handles knows where to find the I & L regs on the stack.  */
353
 
354
void
355
fetch_inferior_registers (regno)
356
     int regno;
357
{
358
#if 0
359
  int whatregs = 0;
360
 
361
#define WHATREGS_FLOAT 1
362
#define WHATREGS_GEN 2
363
#define WHATREGS_STACK 4
364
 
365
  if (regno == -1)
366
    whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
367
  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
368
    whatregs = WHATREGS_STACK;
369
  else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
370
    whatregs = WHATREGS_FLOAT;
371
  else
372
    whatregs = WHATREGS_GEN;
373
 
374
  if (whatregs & WHATREGS_GEN)
375
    {
376
      struct econtext ec;       /* general regs */
377
      char buf[MAX_REGISTER_RAW_SIZE];
378
      int retval;
379
      int i;
380
 
381
      errno = 0;
382
      retval = ptrace (PTRACE_GETREGS,
383
                       BUILDPID (inferior_pid, general_thread),
384
                       (PTRACE_ARG3_TYPE) & ec,
385
                       0);
386
      if (errno)
387
        perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
388
 
389
      memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
390
      supply_register (G0_REGNUM, buf);
391
      supply_register (TBR_REGNUM, (char *) &ec.tbr);
392
 
393
      memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
394
              4 * REGISTER_RAW_SIZE (G1_REGNUM));
395
      for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
396
        register_valid[i] = 1;
397
 
398
      supply_register (PS_REGNUM, (char *) &ec.psr);
399
      supply_register (Y_REGNUM, (char *) &ec.y);
400
      supply_register (PC_REGNUM, (char *) &ec.pc);
401
      supply_register (NPC_REGNUM, (char *) &ec.npc);
402
      supply_register (WIM_REGNUM, (char *) &ec.wim);
403
 
404
      memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
405
              8 * REGISTER_RAW_SIZE (O0_REGNUM));
406
      for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
407
        register_valid[i] = 1;
408
    }
409
 
410
  if (whatregs & WHATREGS_STACK)
411
    {
412
      CORE_ADDR sp;
413
      int i;
414
 
415
      sp = read_register (SP_REGNUM);
416
 
417
      target_xfer_memory (sp + FRAME_SAVED_I0,
418
                          &registers[REGISTER_BYTE (I0_REGNUM)],
419
                          8 * REGISTER_RAW_SIZE (I0_REGNUM), 0);
420
      for (i = I0_REGNUM; i <= I7_REGNUM; i++)
421
        register_valid[i] = 1;
422
 
423
      target_xfer_memory (sp + FRAME_SAVED_L0,
424
                          &registers[REGISTER_BYTE (L0_REGNUM)],
425
                          8 * REGISTER_RAW_SIZE (L0_REGNUM), 0);
426
      for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
427
        register_valid[i] = 1;
428
    }
429
 
430
  if (whatregs & WHATREGS_FLOAT)
431
    {
432
      struct fcontext fc;       /* fp regs */
433
      int retval;
434
      int i;
435
 
436
      errno = 0;
437
      retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
438
                       0);
439
      if (errno)
440
        perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
441
 
442
      memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
443
              32 * REGISTER_RAW_SIZE (FP0_REGNUM));
444
      for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
445
        register_valid[i] = 1;
446
 
447
      supply_register (FPS_REGNUM, (char *) &fc.fsr);
448
    }
449
#endif
450
}
451
 
452
/* This routine handles storing of the I & L regs for the Sparc.  The trick
453
   here is that they actually live on the stack.  The really tricky part is
454
   that when changing the stack pointer, the I & L regs must be written to
455
   where the new SP points, otherwise the regs will be incorrect when the
456
   process is started up again.   We assume that the I & L regs are valid at
457
   this point.  */
458
 
459
void
460
store_inferior_registers (regno)
461
     int regno;
462
{
463
#if 0
464
  int whatregs = 0;
465
 
466
  if (regno == -1)
467
    whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
468
  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
469
    whatregs = WHATREGS_STACK;
470
  else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
471
    whatregs = WHATREGS_FLOAT;
472
  else if (regno == SP_REGNUM)
473
    whatregs = WHATREGS_STACK | WHATREGS_GEN;
474
  else
475
    whatregs = WHATREGS_GEN;
476
 
477
  if (whatregs & WHATREGS_GEN)
478
    {
479
      struct econtext ec;       /* general regs */
480
      int retval;
481
 
482
      ec.tbr = read_register (TBR_REGNUM);
483
      memcpy (&ec.g1, &registers[REGISTER_BYTE (G1_REGNUM)],
484
              4 * REGISTER_RAW_SIZE (G1_REGNUM));
485
 
486
      ec.psr = read_register (PS_REGNUM);
487
      ec.y = read_register (Y_REGNUM);
488
      ec.pc = read_register (PC_REGNUM);
489
      ec.npc = read_register (NPC_REGNUM);
490
      ec.wim = read_register (WIM_REGNUM);
491
 
492
      memcpy (ec.o, &registers[REGISTER_BYTE (O0_REGNUM)],
493
              8 * REGISTER_RAW_SIZE (O0_REGNUM));
494
 
495
      errno = 0;
496
      retval = ptrace (PTRACE_SETREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & ec,
497
                       0);
498
      if (errno)
499
        perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
500
    }
501
 
502
  if (whatregs & WHATREGS_STACK)
503
    {
504
      int regoffset;
505
      CORE_ADDR sp;
506
 
507
      sp = read_register (SP_REGNUM);
508
 
509
      if (regno == -1 || regno == SP_REGNUM)
510
        {
511
          if (!register_valid[L0_REGNUM + 5])
512
            abort ();
513
          target_xfer_memory (sp + FRAME_SAVED_I0,
514
                              &registers[REGISTER_BYTE (I0_REGNUM)],
515
                              8 * REGISTER_RAW_SIZE (I0_REGNUM), 1);
516
 
517
          target_xfer_memory (sp + FRAME_SAVED_L0,
518
                              &registers[REGISTER_BYTE (L0_REGNUM)],
519
                              8 * REGISTER_RAW_SIZE (L0_REGNUM), 1);
520
        }
521
      else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
522
        {
523
          if (!register_valid[regno])
524
            abort ();
525
          if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7)
526
            regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM)
527
              + FRAME_SAVED_L0;
528
          else
529
            regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM)
530
              + FRAME_SAVED_I0;
531
          target_xfer_memory (sp + regoffset, &registers[REGISTER_BYTE (regno)],
532
                              REGISTER_RAW_SIZE (regno), 1);
533
        }
534
    }
535
 
536
  if (whatregs & WHATREGS_FLOAT)
537
    {
538
      struct fcontext fc;       /* fp regs */
539
      int retval;
540
 
541
/* We read fcontext first so that we can get good values for fq_t... */
542
      errno = 0;
543
      retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
544
                       0);
545
      if (errno)
546
        perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
547
 
548
      memcpy (fc.f.fregs, &registers[REGISTER_BYTE (FP0_REGNUM)],
549
              32 * REGISTER_RAW_SIZE (FP0_REGNUM));
550
 
551
      fc.fsr = read_register (FPS_REGNUM);
552
 
553
      errno = 0;
554
      retval = ptrace (PTRACE_SETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
555
                       0);
556
      if (errno)
557
        perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
558
    }
559
#endif
560
}
561
#endif /* SPARC */
562
 
563
#ifndef SPARC
564
 
565
/* Return the offset relative to the start of the per-thread data to the
566
   saved context block.  */
567
 
568
static unsigned long
569
lynx_registers_addr ()
570
{
571
  CORE_ADDR stblock;
572
  int ecpoff = offsetof (st_t, ecp);
573
  CORE_ADDR ecp;
574
 
575
  errno = 0;
576
  stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, BUILDPID (inferior_pid, general_thread),
577
                                (PTRACE_ARG3_TYPE) 0, 0);
578
  if (errno)
579
    perror_with_name ("PTRACE_THREADUSER");
580
 
581
  ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, BUILDPID (inferior_pid, general_thread),
582
                            (PTRACE_ARG3_TYPE) ecpoff, 0);
583
  if (errno)
584
    perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
585
 
586
  return ecp - stblock;
587
}
588
 
589
/* Fetch one or more registers from the inferior.  REGNO == -1 to get
590
   them all.  We actually fetch more than requested, when convenient,
591
   marking them as valid so we won't fetch them again.  */
592
 
593
void
594
fetch_inferior_registers (ignored)
595
     int ignored;
596
{
597
  int regno;
598
  unsigned long reg;
599
  unsigned long ecp;
600
 
601
  ecp = lynx_registers_addr ();
602
 
603
  for (regno = 0; regno < NUM_REGS; regno++)
604
    {
605
      int ptrace_fun = PTRACE_PEEKTHREAD;
606
 
607
#ifdef PTRACE_PEEKUSP
608
      ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
609
#endif
610
 
611
      errno = 0;
612
      reg = ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
613
                    (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), 0);
614
      if (errno)
615
        perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
616
 
617
      *(unsigned long *) &registers[REGISTER_BYTE (regno)] = reg;
618
    }
619
}
620
 
621
/* Store our register values back into the inferior.
622
   If REGNO is -1, do this for all registers.
623
   Otherwise, REGNO specifies which register (so we can save time).  */
624
 
625
void
626
store_inferior_registers (ignored)
627
     int ignored;
628
{
629
  int regno;
630
  unsigned long reg;
631
  unsigned long ecp;
632
 
633
  ecp = lynx_registers_addr ();
634
 
635
  for (regno = 0; regno < NUM_REGS; regno++)
636
    {
637
      int ptrace_fun = PTRACE_POKEUSER;
638
 
639
#ifdef PTRACE_POKEUSP
640
      ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
641
#endif
642
 
643
      reg = *(unsigned long *) &registers[REGISTER_BYTE (regno)];
644
 
645
      errno = 0;
646
      ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
647
              (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), reg);
648
      if (errno)
649
        perror_with_name ("PTRACE_POKEUSER");
650
    }
651
}
652
 
653
#endif /* ! SPARC */
654
 
655
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
656
   in the NEW_SUN_PTRACE case.
657
   It ought to be straightforward.  But it appears that writing did
658
   not write the data that I specified.  I cannot understand where
659
   it got the data that it actually did write.  */
660
 
661
/* Copy LEN bytes from inferior's memory starting at MEMADDR
662
   to debugger memory starting at MYADDR.  */
663
 
664
void
665
read_inferior_memory (memaddr, myaddr, len)
666
     CORE_ADDR memaddr;
667
     char *myaddr;
668
     int len;
669
{
670
  register int i;
671
  /* Round starting address down to longword boundary.  */
672
  register CORE_ADDR addr = memaddr & -sizeof (int);
673
  /* Round ending address up; get number of longwords that makes.  */
674
  register int count
675
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
676
  /* Allocate buffer of that many longwords.  */
677
  register int *buffer = (int *) alloca (count * sizeof (int));
678
 
679
  /* Read all the longwords */
680
  for (i = 0; i < count; i++, addr += sizeof (int))
681
    {
682
      buffer[i] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
683
    }
684
 
685
  /* Copy appropriate bytes out of the buffer.  */
686
  memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
687
}
688
 
689
/* Copy LEN bytes of data from debugger memory at MYADDR
690
   to inferior's memory at MEMADDR.
691
   On failure (cannot write the inferior)
692
   returns the value of errno.  */
693
 
694
int
695
write_inferior_memory (memaddr, myaddr, len)
696
     CORE_ADDR memaddr;
697
     char *myaddr;
698
     int len;
699
{
700
  register int i;
701
  /* Round starting address down to longword boundary.  */
702
  register CORE_ADDR addr = memaddr & -sizeof (int);
703
  /* Round ending address up; get number of longwords that makes.  */
704
  register int count
705
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
706
  /* Allocate buffer of that many longwords.  */
707
  register int *buffer = (int *) alloca (count * sizeof (int));
708
  extern int errno;
709
 
710
  /* Fill start and end extra bytes of buffer with existing memory data.  */
711
 
712
  buffer[0] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
713
 
714
  if (count > 1)
715
    {
716
      buffer[count - 1]
717
        = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread),
718
                  addr + (count - 1) * sizeof (int), 0);
719
    }
720
 
721
  /* Copy data to be written over corresponding part of buffer */
722
 
723
  memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
724
 
725
  /* Write the entire buffer.  */
726
 
727
  for (i = 0; i < count; i++, addr += sizeof (int))
728
    {
729
      while (1)
730
        {
731
          errno = 0;
732
          ptrace (PTRACE_POKETEXT, BUILDPID (inferior_pid, general_thread), addr, buffer[i]);
733
          if (errno)
734
            {
735
              fprintf (stderr, "\
736
ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n",
737
                       errno, BUILDPID (inferior_pid, general_thread),
738
                       addr, buffer[i]);
739
              fprintf (stderr, "Sleeping for 1 second\n");
740
              sleep (1);
741
            }
742
          else
743
            break;
744
        }
745
    }
746
 
747
  return 0;
748
}
749
 
750
void
751
initialize_low ()
752
{
753
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.