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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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