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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [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 1181 sfurman
/* Low level interface to ptrace, for the remote server for GDB.
2
   Copyright 1986, 1987, 1993, 1994, 1995, 1999, 2000, 2001, 2002
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
/* Attaching is not supported.  */
91
int
92
myattach (int pid)
93
{
94
  return -1;
95
}
96
 
97
/* Kill the inferior process.  Make us have no inferior.  */
98
 
99
void
100
kill_inferior (void)
101
{
102
  if (inferior_pid == 0)
103
    return;
104
  ptrace (PTRACE_KILL, inferior_pid, 0, 0);
105
  wait (0);
106
 
107
  inferior_pid = 0;
108
}
109
 
110
/* Return nonzero if the given thread is still alive.  */
111
int
112
mythread_alive (int pid)
113
{
114
  /* Arggh.  Apparently pthread_kill only works for threads within
115
     the process that calls pthread_kill.
116
 
117
     We want to avoid the lynx signal extensions as they simply don't
118
     map well to the generic gdb interface we want to keep.
119
 
120
     All we want to do is determine if a particular thread is alive;
121
     it appears as if we can just make a harmless thread specific
122
     ptrace call to do that.  */
123
  return (ptrace (PTRACE_THREADUSER,
124
                  BUILDPID (PIDGET (inferior_pid), pid), 0, 0) != -1);
125
}
126
 
127
/* Wait for process, returns status */
128
 
129
unsigned char
130
mywait (char *status)
131
{
132
  int pid;
133
  union wait w;
134
 
135
  while (1)
136
    {
137
      enable_async_io ();
138
 
139
      pid = wait (&w);
140
 
141
      disable_async_io ();
142
 
143
      if (pid != PIDGET (inferior_pid))
144
        perror_with_name ("wait");
145
 
146
      thread_from_wait = w.w_tid;
147
      inferior_pid = BUILDPID (inferior_pid, w.w_tid);
148
 
149
      if (WIFSTOPPED (w)
150
          && WSTOPSIG (w) == SIGTRAP)
151
        {
152
          int realsig;
153
 
154
          realsig = ptrace (PTRACE_GETTRACESIG, inferior_pid,
155
                            (PTRACE_ARG3_TYPE) 0, 0);
156
 
157
          if (realsig == SIGNEWTHREAD)
158
            {
159
              /* It's a new thread notification.  Nothing to do here since
160
                 the machine independent code in wait_for_inferior will
161
                 add the thread to the thread list and restart the thread
162
                 when pid != inferior_pid and pid is not in the thread list.
163
                 We don't even want to muck with realsig -- the code in
164
                 wait_for_inferior expects SIGTRAP.  */
165
              ;
166
            }
167
        }
168
      break;
169
    }
170
 
171
  if (WIFEXITED (w))
172
    {
173
      *status = 'W';
174
      return ((unsigned char) WEXITSTATUS (w));
175
    }
176
  else if (!WIFSTOPPED (w))
177
    {
178
      *status = 'X';
179
      return ((unsigned char) WTERMSIG (w));
180
    }
181
 
182
  fetch_inferior_registers (0);
183
 
184
  *status = 'T';
185
  return ((unsigned char) WSTOPSIG (w));
186
}
187
 
188
/* Resume execution of the inferior process.
189
   If STEP is nonzero, single-step it.
190
   If SIGNAL is nonzero, give it that signal.  */
191
 
192
void
193
myresume (int step, int signal)
194
{
195
  errno = 0;
196
  ptrace (step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT,
197
          BUILDPID (inferior_pid, cont_thread == -1 ? 0 : cont_thread),
198
          1, signal);
199
  if (errno)
200
    perror_with_name ("ptrace");
201
}
202
 
203
#undef offsetof
204
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
205
 
206
/* Mapping between GDB register #s and offsets into econtext.  Must be
207
   consistent with REGISTER_NAMES macro in various tmXXX.h files. */
208
 
209
#define X(ENTRY)(offsetof(struct econtext, ENTRY))
210
 
211
#ifdef I386
212
/* Mappings from tm-i386v.h */
213
 
214
static int regmap[] =
215
{
216
  X (eax),
217
  X (ecx),
218
  X (edx),
219
  X (ebx),
220
  X (esp),                      /* sp */
221
  X (ebp),                      /* fp */
222
  X (esi),
223
  X (edi),
224
  X (eip),                      /* pc */
225
  X (flags),                    /* ps */
226
  X (cs),
227
  X (ss),
228
  X (ds),
229
  X (es),
230
  X (ecode),                    /* Lynx doesn't give us either fs or gs, so */
231
  X (fault),                    /* we just substitute these two in the hopes
232
                                   that they are useful. */
233
};
234
#endif
235
 
236
#ifdef M68K
237
/* Mappings from tm-m68k.h */
238
 
239
static int regmap[] =
240
{
241
  X (regs[0]),                   /* d0 */
242
  X (regs[1]),                  /* d1 */
243
  X (regs[2]),                  /* d2 */
244
  X (regs[3]),                  /* d3 */
245
  X (regs[4]),                  /* d4 */
246
  X (regs[5]),                  /* d5 */
247
  X (regs[6]),                  /* d6 */
248
  X (regs[7]),                  /* d7 */
249
  X (regs[8]),                  /* a0 */
250
  X (regs[9]),                  /* a1 */
251
  X (regs[10]),                 /* a2 */
252
  X (regs[11]),                 /* a3 */
253
  X (regs[12]),                 /* a4 */
254
  X (regs[13]),                 /* a5 */
255
  X (regs[14]),                 /* fp */
256
  0,                             /* sp */
257
  X (status),                   /* ps */
258
  X (pc),
259
 
260
  X (fregs[0 * 3]),              /* fp0 */
261
  X (fregs[1 * 3]),             /* fp1 */
262
  X (fregs[2 * 3]),             /* fp2 */
263
  X (fregs[3 * 3]),             /* fp3 */
264
  X (fregs[4 * 3]),             /* fp4 */
265
  X (fregs[5 * 3]),             /* fp5 */
266
  X (fregs[6 * 3]),             /* fp6 */
267
  X (fregs[7 * 3]),             /* fp7 */
268
 
269
  X (fcregs[0]),         /* fpcontrol */
270
  X (fcregs[1]),                /* fpstatus */
271
  X (fcregs[2]),                /* fpiaddr */
272
  X (ssw),                      /* fpcode */
273
  X (fault),                    /* fpflags */
274
};
275
#endif
276
 
277
#ifdef SPARC
278
/* Mappings from tm-sparc.h */
279
 
280
#define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
281
 
282
static int regmap[] =
283
{
284
  -1,                           /* g0 */
285
  X (g1),
286
  X (g2),
287
  X (g3),
288
  X (g4),
289
  -1,                           /* g5->g7 aren't saved by Lynx */
290
  -1,
291
  -1,
292
 
293
  X (o[0]),
294
  X (o[1]),
295
  X (o[2]),
296
  X (o[3]),
297
  X (o[4]),
298
  X (o[5]),
299
  X (o[6]),                     /* sp */
300
  X (o[7]),                     /* ra */
301
 
302
  -1, -1, -1, -1, -1, -1, -1, -1,       /* l0 -> l7 */
303
 
304
  -1, -1, -1, -1, -1, -1, -1, -1,       /* i0 -> i7 */
305
 
306
  FX (f.fregs[0]),               /* f0 */
307
  FX (f.fregs[1]),
308
  FX (f.fregs[2]),
309
  FX (f.fregs[3]),
310
  FX (f.fregs[4]),
311
  FX (f.fregs[5]),
312
  FX (f.fregs[6]),
313
  FX (f.fregs[7]),
314
  FX (f.fregs[8]),
315
  FX (f.fregs[9]),
316
  FX (f.fregs[10]),
317
  FX (f.fregs[11]),
318
  FX (f.fregs[12]),
319
  FX (f.fregs[13]),
320
  FX (f.fregs[14]),
321
  FX (f.fregs[15]),
322
  FX (f.fregs[16]),
323
  FX (f.fregs[17]),
324
  FX (f.fregs[18]),
325
  FX (f.fregs[19]),
326
  FX (f.fregs[20]),
327
  FX (f.fregs[21]),
328
  FX (f.fregs[22]),
329
  FX (f.fregs[23]),
330
  FX (f.fregs[24]),
331
  FX (f.fregs[25]),
332
  FX (f.fregs[26]),
333
  FX (f.fregs[27]),
334
  FX (f.fregs[28]),
335
  FX (f.fregs[29]),
336
  FX (f.fregs[30]),
337
  FX (f.fregs[31]),
338
 
339
  X (y),
340
  X (psr),
341
  X (wim),
342
  X (tbr),
343
  X (pc),
344
  X (npc),
345
  FX (fsr),                     /* fpsr */
346
  -1,                           /* cpsr */
347
};
348
#endif
349
 
350
#ifdef SPARC
351
 
352
/* This routine handles some oddball cases for Sparc registers and LynxOS.
353
   In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
354
   It also handles knows where to find the I & L regs on the stack.  */
355
 
356
void
357
fetch_inferior_registers (int regno)
358
{
359
#if 0
360
  int whatregs = 0;
361
 
362
#define WHATREGS_FLOAT 1
363
#define WHATREGS_GEN 2
364
#define WHATREGS_STACK 4
365
 
366
  if (regno == -1)
367
    whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
368
  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
369
    whatregs = WHATREGS_STACK;
370
  else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
371
    whatregs = WHATREGS_FLOAT;
372
  else
373
    whatregs = WHATREGS_GEN;
374
 
375
  if (whatregs & WHATREGS_GEN)
376
    {
377
      struct econtext ec;       /* general regs */
378
      char buf[MAX_REGISTER_RAW_SIZE];
379
      int retval;
380
      int i;
381
 
382
      errno = 0;
383
      retval = ptrace (PTRACE_GETREGS,
384
                       BUILDPID (inferior_pid, general_thread),
385
                       (PTRACE_ARG3_TYPE) & ec,
386
                       0);
387
      if (errno)
388
        perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
389
 
390
      memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
391
      supply_register (G0_REGNUM, buf);
392
      supply_register (TBR_REGNUM, (char *) &ec.tbr);
393
 
394
      memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
395
              4 * REGISTER_RAW_SIZE (G1_REGNUM));
396
      for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
397
        register_valid[i] = 1;
398
 
399
      supply_register (PS_REGNUM, (char *) &ec.psr);
400
      supply_register (Y_REGNUM, (char *) &ec.y);
401
      supply_register (PC_REGNUM, (char *) &ec.pc);
402
      supply_register (NPC_REGNUM, (char *) &ec.npc);
403
      supply_register (WIM_REGNUM, (char *) &ec.wim);
404
 
405
      memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
406
              8 * REGISTER_RAW_SIZE (O0_REGNUM));
407
      for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
408
        register_valid[i] = 1;
409
    }
410
 
411
  if (whatregs & WHATREGS_STACK)
412
    {
413
      CORE_ADDR sp;
414
      int i;
415
 
416
      sp = read_register (SP_REGNUM);
417
 
418
      target_xfer_memory (sp + FRAME_SAVED_I0,
419
                          &registers[REGISTER_BYTE (I0_REGNUM)],
420
                          8 * REGISTER_RAW_SIZE (I0_REGNUM), 0);
421
      for (i = I0_REGNUM; i <= I7_REGNUM; i++)
422
        register_valid[i] = 1;
423
 
424
      target_xfer_memory (sp + FRAME_SAVED_L0,
425
                          &registers[REGISTER_BYTE (L0_REGNUM)],
426
                          8 * REGISTER_RAW_SIZE (L0_REGNUM), 0);
427
      for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
428
        register_valid[i] = 1;
429
    }
430
 
431
  if (whatregs & WHATREGS_FLOAT)
432
    {
433
      struct fcontext fc;       /* fp regs */
434
      int retval;
435
      int i;
436
 
437
      errno = 0;
438
      retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
439
                       0);
440
      if (errno)
441
        perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
442
 
443
      memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
444
              32 * REGISTER_RAW_SIZE (FP0_REGNUM));
445
      for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
446
        register_valid[i] = 1;
447
 
448
      supply_register (FPS_REGNUM, (char *) &fc.fsr);
449
    }
450
#endif
451
}
452
 
453
/* This routine handles storing of the I & L regs for the Sparc.  The trick
454
   here is that they actually live on the stack.  The really tricky part is
455
   that when changing the stack pointer, the I & L regs must be written to
456
   where the new SP points, otherwise the regs will be incorrect when the
457
   process is started up again.   We assume that the I & L regs are valid at
458
   this point.  */
459
 
460
void
461
store_inferior_registers (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 (void)
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 (int ignored)
595
{
596
  int regno;
597
  unsigned long reg;
598
  unsigned long ecp;
599
 
600
  ecp = lynx_registers_addr ();
601
 
602
  for (regno = 0; regno < NUM_REGS; regno++)
603
    {
604
      int ptrace_fun = PTRACE_PEEKTHREAD;
605
 
606
#ifdef PTRACE_PEEKUSP
607
      ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
608
#endif
609
 
610
      errno = 0;
611
      reg = ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
612
                    (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), 0);
613
      if (errno)
614
        perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
615
 
616
      *(unsigned long *) &registers[REGISTER_BYTE (regno)] = reg;
617
    }
618
}
619
 
620
/* Store our register values back into the inferior.
621
   If REGNO is -1, do this for all registers.
622
   Otherwise, REGNO specifies which register (so we can save time).  */
623
 
624
void
625
store_inferior_registers (int ignored)
626
{
627
  int regno;
628
  unsigned long reg;
629
  unsigned long ecp;
630
 
631
  ecp = lynx_registers_addr ();
632
 
633
  for (regno = 0; regno < NUM_REGS; regno++)
634
    {
635
      int ptrace_fun = PTRACE_POKEUSER;
636
 
637
#ifdef PTRACE_POKEUSP
638
      ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
639
#endif
640
 
641
      reg = *(unsigned long *) &registers[REGISTER_BYTE (regno)];
642
 
643
      errno = 0;
644
      ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
645
              (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), reg);
646
      if (errno)
647
        perror_with_name ("PTRACE_POKEUSER");
648
    }
649
}
650
 
651
#endif /* ! SPARC */
652
 
653
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
654
   in the NEW_SUN_PTRACE case.
655
   It ought to be straightforward.  But it appears that writing did
656
   not write the data that I specified.  I cannot understand where
657
   it got the data that it actually did write.  */
658
 
659
/* Copy LEN bytes from inferior's memory starting at MEMADDR
660
   to debugger memory starting at MYADDR.  */
661
 
662
void
663
read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
664
{
665
  register int i;
666
  /* Round starting address down to longword boundary.  */
667
  register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
668
  /* Round ending address up; get number of longwords that makes.  */
669
  register int count
670
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
671
  /* Allocate buffer of that many longwords.  */
672
  register int *buffer = (int *) alloca (count * sizeof (int));
673
 
674
  /* Read all the longwords */
675
  for (i = 0; i < count; i++, addr += sizeof (int))
676
    {
677
      buffer[i] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
678
    }
679
 
680
  /* Copy appropriate bytes out of the buffer.  */
681
  memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
682
}
683
 
684
/* Copy LEN bytes of data from debugger memory at MYADDR
685
   to inferior's memory at MEMADDR.
686
   On failure (cannot write the inferior)
687
   returns the value of errno.  */
688
 
689
int
690
write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
691
{
692
  register int i;
693
  /* Round starting address down to longword boundary.  */
694
  register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
695
  /* Round ending address up; get number of longwords that makes.  */
696
  register int count
697
  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
698
  /* Allocate buffer of that many longwords.  */
699
  register int *buffer = (int *) alloca (count * sizeof (int));
700
  extern int errno;
701
 
702
  /* Fill start and end extra bytes of buffer with existing memory data.  */
703
 
704
  buffer[0] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
705
 
706
  if (count > 1)
707
    {
708
      buffer[count - 1]
709
        = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread),
710
                  addr + (count - 1) * sizeof (int), 0);
711
    }
712
 
713
  /* Copy data to be written over corresponding part of buffer */
714
 
715
  memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
716
 
717
  /* Write the entire buffer.  */
718
 
719
  for (i = 0; i < count; i++, addr += sizeof (int))
720
    {
721
      while (1)
722
        {
723
          errno = 0;
724
          ptrace (PTRACE_POKETEXT, BUILDPID (inferior_pid, general_thread), addr, buffer[i]);
725
          if (errno)
726
            {
727
              fprintf (stderr, "\
728
ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n",
729
                       errno, BUILDPID (inferior_pid, general_thread),
730
                       addr, buffer[i]);
731
              fprintf (stderr, "Sleeping for 1 second\n");
732
              sleep (1);
733
            }
734
          else
735
            break;
736
        }
737
    }
738
 
739
  return 0;
740
}
741
 
742
void
743
initialize_low (void)
744
{
745
}

powered by: WebSVN 2.1.0

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