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

Subversion Repositories or1k

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

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) 1995, 1996 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 "defs.h"
22
#include <sys/wait.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
#include <sys/ptrace.h>
30
#include <sys/user.h>
31
#include <signal.h>
32
#include <sys/ioctl.h>
33
#include <fcntl.h>
34
 
35
/***************Begin MY defs*********************/
36
int quit_flag = 0;
37
static char my_registers[REGISTER_BYTES];
38
char *registers = my_registers;
39
 
40
/* Index within `registers' of the first byte of the space for
41
   register N.  */
42
 
43
 
44
char buf2[MAX_REGISTER_RAW_SIZE];
45
/***************End MY defs*********************/
46
 
47
#ifdef HAVE_SYS_REG_H
48
#include <sys/reg.h>
49
#endif
50
 
51
/* Default the type of the ptrace transfer to int.  */
52
#ifndef PTRACE_XFER_TYPE
53
#define PTRACE_XFER_TYPE int
54
#endif
55
 
56
extern char **environ;
57
extern int errno;
58
extern int inferior_pid;
59
void quit (), perror_with_name ();
60
int query ();
61
 
62
static void initialize_arch (void);
63
 
64
/* Start an inferior process and returns its pid.
65
   ALLARGS is a vector of program-name and args.
66
   ENV is the environment vector to pass.  */
67
 
68
int
69
create_inferior (program, allargs)
70
     char *program;
71
     char **allargs;
72
{
73
  int pid;
74
 
75
  pid = fork ();
76
  if (pid < 0)
77
    perror_with_name ("fork");
78
 
79
  if (pid == 0)
80
    {
81
      ptrace (PTRACE_TRACEME, 0, 0, 0);
82
 
83
      execv (program, allargs);
84
 
85
      fprintf (stderr, "Cannot exec %s: %s.\n", program,
86
               errno < sys_nerr ? sys_errlist[errno] : "unknown error");
87
      fflush (stderr);
88
      _exit (0177);
89
    }
90
 
91
  return pid;
92
}
93
 
94
/* Kill the inferior process.  Make us have no inferior.  */
95
 
96
void
97
kill_inferior ()
98
{
99
  if (inferior_pid == 0)
100
    return;
101
  ptrace (PTRACE_KILL, inferior_pid, 0, 0);
102
  wait (0);
103
/*************inferior_died ();****VK**************/
104
}
105
 
106
/* Return nonzero if the given thread is still alive.  */
107
int
108
mythread_alive (pid)
109
     int pid;
110
{
111
  return 1;
112
}
113
 
114
/* Wait for process, returns status */
115
 
116
unsigned char
117
mywait (status)
118
     char *status;
119
{
120
  int pid;
121
  union wait w;
122
 
123
  pid = wait (&w);
124
  if (pid != inferior_pid)
125
    perror_with_name ("wait");
126
 
127
  if (WIFEXITED (w))
128
    {
129
      fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
130
      *status = 'W';
131
      return ((unsigned char) WEXITSTATUS (w));
132
    }
133
  else if (!WIFSTOPPED (w))
134
    {
135
      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
136
      *status = 'X';
137
      return ((unsigned char) WTERMSIG (w));
138
    }
139
 
140
  fetch_inferior_registers (0);
141
 
142
  *status = 'T';
143
  return ((unsigned char) WSTOPSIG (w));
144
}
145
 
146
/* Resume execution of the inferior process.
147
   If STEP is nonzero, single-step it.
148
   If SIGNAL is nonzero, give it that signal.  */
149
 
150
void
151
myresume (step, signal)
152
     int step;
153
     int signal;
154
{
155
  errno = 0;
156
  ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
157
  if (errno)
158
    perror_with_name ("ptrace");
159
}
160
 
161
 
162
#if !defined (offsetof)
163
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
164
#endif
165
 
166
/* U_REGS_OFFSET is the offset of the registers within the u area.  */
167
#if !defined (U_REGS_OFFSET)
168
#define U_REGS_OFFSET \
169
  ptrace (PT_READ_U, inferior_pid, \
170
          (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
171
    - KERNEL_U_ADDR
172
#endif
173
 
174
#ifdef I386_GNULINUX_TARGET
175
/* i386_register_raw_size[i] is the number of bytes of storage in the
176
   actual machine representation for register i.  */
177
int i386_register_raw_size[MAX_NUM_REGS] = {
178
   4,  4,  4,  4,
179
   4,  4,  4,  4,
180
   4,  4,  4,  4,
181
   4,  4,  4,  4,
182
  10, 10, 10, 10,
183
  10, 10, 10, 10,
184
   4,  4,  4,  4,
185
   4,  4,  4,  4,
186
  16, 16, 16, 16,
187
  16, 16, 16, 16,
188
   4
189
};
190
 
191
int i386_register_byte[MAX_NUM_REGS];
192
 
193
static void
194
initialize_arch ()
195
{
196
  /* Initialize the table saying where each register starts in the
197
     register file.  */
198
  {
199
    int i, offset;
200
 
201
    offset = 0;
202
    for (i = 0; i < MAX_NUM_REGS; i++)
203
      {
204
        i386_register_byte[i] = offset;
205
        offset += i386_register_raw_size[i];
206
      }
207
  }
208
}
209
 
210
/* this table must line up with REGISTER_NAMES in tm-i386v.h */
211
/* symbols like 'EAX' come from <sys/reg.h> */
212
static int regmap[] =
213
{
214
  EAX, ECX, EDX, EBX,
215
  UESP, EBP, ESI, EDI,
216
  EIP, EFL, CS, SS,
217
  DS, ES, FS, GS,
218
};
219
 
220
int
221
i386_register_u_addr (blockend, regnum)
222
     int blockend;
223
     int regnum;
224
{
225
#if 0
226
  /* this will be needed if fp registers are reinstated */
227
  /* for now, you can look at them with 'info float'
228
   * sys5 wont let you change them with ptrace anyway
229
   */
230
  if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM)
231
    {
232
      int ubase, fpstate;
233
      struct user u;
234
      ubase = blockend + 4 * (SS + 1) - KSTKSZ;
235
      fpstate = ubase + ((char *) &u.u_fpstate - (char *) &u);
236
      return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
237
    }
238
  else
239
#endif
240
    return (blockend + 4 * regmap[regnum]);
241
 
242
}
243
#elif defined(TARGET_M68K)
244
static void
245
initialize_arch ()
246
{
247
  return;
248
}
249
 
250
/* This table must line up with REGISTER_NAMES in tm-m68k.h */
251
static int regmap[] =
252
{
253
#ifdef PT_D0
254
  PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
255
  PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
256
  PT_SR, PT_PC,
257
#else
258
  14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15,
259
  17, 18,
260
#endif
261
#ifdef PT_FP0
262
  PT_FP0, PT_FP1, PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7,
263
  PT_FPCR, PT_FPSR, PT_FPIAR
264
#else
265
  21, 24, 27, 30, 33, 36, 39, 42, 45, 46, 47
266
#endif
267
};
268
 
269
/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
270
   is stored.  */
271
 
272
int
273
m68k_linux_register_u_addr (blockend, regnum)
274
     int blockend;
275
     int regnum;
276
{
277
  return (blockend + 4 * regmap[regnum]);
278
}
279
#elif defined(IA64_GNULINUX_TARGET)
280
#undef NUM_FREGS
281
#define NUM_FREGS 0
282
 
283
#include <asm/ptrace_offsets.h>
284
 
285
static int u_offsets[] =
286
  {
287
    /* general registers */
288
    -1,         /* gr0 not available; i.e, it's always zero */
289
    PT_R1,
290
    PT_R2,
291
    PT_R3,
292
    PT_R4,
293
    PT_R5,
294
    PT_R6,
295
    PT_R7,
296
    PT_R8,
297
    PT_R9,
298
    PT_R10,
299
    PT_R11,
300
    PT_R12,
301
    PT_R13,
302
    PT_R14,
303
    PT_R15,
304
    PT_R16,
305
    PT_R17,
306
    PT_R18,
307
    PT_R19,
308
    PT_R20,
309
    PT_R21,
310
    PT_R22,
311
    PT_R23,
312
    PT_R24,
313
    PT_R25,
314
    PT_R26,
315
    PT_R27,
316
    PT_R28,
317
    PT_R29,
318
    PT_R30,
319
    PT_R31,
320
    /* gr32 through gr127 not directly available via the ptrace interface */
321
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
322
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
323
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
324
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
325
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
326
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
327
    /* Floating point registers */
328
    -1, -1,     /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */
329
    PT_F2,
330
    PT_F3,
331
    PT_F4,
332
    PT_F5,
333
    PT_F6,
334
    PT_F7,
335
    PT_F8,
336
    PT_F9,
337
    PT_F10,
338
    PT_F11,
339
    PT_F12,
340
    PT_F13,
341
    PT_F14,
342
    PT_F15,
343
    PT_F16,
344
    PT_F17,
345
    PT_F18,
346
    PT_F19,
347
    PT_F20,
348
    PT_F21,
349
    PT_F22,
350
    PT_F23,
351
    PT_F24,
352
    PT_F25,
353
    PT_F26,
354
    PT_F27,
355
    PT_F28,
356
    PT_F29,
357
    PT_F30,
358
    PT_F31,
359
    PT_F32,
360
    PT_F33,
361
    PT_F34,
362
    PT_F35,
363
    PT_F36,
364
    PT_F37,
365
    PT_F38,
366
    PT_F39,
367
    PT_F40,
368
    PT_F41,
369
    PT_F42,
370
    PT_F43,
371
    PT_F44,
372
    PT_F45,
373
    PT_F46,
374
    PT_F47,
375
    PT_F48,
376
    PT_F49,
377
    PT_F50,
378
    PT_F51,
379
    PT_F52,
380
    PT_F53,
381
    PT_F54,
382
    PT_F55,
383
    PT_F56,
384
    PT_F57,
385
    PT_F58,
386
    PT_F59,
387
    PT_F60,
388
    PT_F61,
389
    PT_F62,
390
    PT_F63,
391
    PT_F64,
392
    PT_F65,
393
    PT_F66,
394
    PT_F67,
395
    PT_F68,
396
    PT_F69,
397
    PT_F70,
398
    PT_F71,
399
    PT_F72,
400
    PT_F73,
401
    PT_F74,
402
    PT_F75,
403
    PT_F76,
404
    PT_F77,
405
    PT_F78,
406
    PT_F79,
407
    PT_F80,
408
    PT_F81,
409
    PT_F82,
410
    PT_F83,
411
    PT_F84,
412
    PT_F85,
413
    PT_F86,
414
    PT_F87,
415
    PT_F88,
416
    PT_F89,
417
    PT_F90,
418
    PT_F91,
419
    PT_F92,
420
    PT_F93,
421
    PT_F94,
422
    PT_F95,
423
    PT_F96,
424
    PT_F97,
425
    PT_F98,
426
    PT_F99,
427
    PT_F100,
428
    PT_F101,
429
    PT_F102,
430
    PT_F103,
431
    PT_F104,
432
    PT_F105,
433
    PT_F106,
434
    PT_F107,
435
    PT_F108,
436
    PT_F109,
437
    PT_F110,
438
    PT_F111,
439
    PT_F112,
440
    PT_F113,
441
    PT_F114,
442
    PT_F115,
443
    PT_F116,
444
    PT_F117,
445
    PT_F118,
446
    PT_F119,
447
    PT_F120,
448
    PT_F121,
449
    PT_F122,
450
    PT_F123,
451
    PT_F124,
452
    PT_F125,
453
    PT_F126,
454
    PT_F127,
455
    /* predicate registers - we don't fetch these individually */
456
    -1, -1, -1, -1, -1, -1, -1, -1,
457
    -1, -1, -1, -1, -1, -1, -1, -1,
458
    -1, -1, -1, -1, -1, -1, -1, -1,
459
    -1, -1, -1, -1, -1, -1, -1, -1,
460
    -1, -1, -1, -1, -1, -1, -1, -1,
461
    -1, -1, -1, -1, -1, -1, -1, -1,
462
    -1, -1, -1, -1, -1, -1, -1, -1,
463
    -1, -1, -1, -1, -1, -1, -1, -1,
464
    /* branch registers */
465
    PT_B0,
466
    PT_B1,
467
    PT_B2,
468
    PT_B3,
469
    PT_B4,
470
    PT_B5,
471
    PT_B6,
472
    PT_B7,
473
    /* virtual frame pointer and virtual return address pointer */
474
    -1, -1,
475
    /* other registers */
476
    PT_PR,
477
    PT_CR_IIP,  /* ip */
478
    PT_CR_IPSR, /* psr */
479
    PT_CR_IFS,  /* cfm */
480
    /* kernel registers not visible via ptrace interface (?) */
481
    -1, -1, -1, -1, -1, -1, -1, -1,
482
    /* hole */
483
    -1, -1, -1, -1, -1, -1, -1, -1,
484
    PT_AR_RSC,
485
    PT_AR_BSP,
486
    PT_AR_BSPSTORE,
487
    PT_AR_RNAT,
488
    -1,
489
    -1,         /* Not available: FCR, IA32 floating control register */
490
    -1, -1,
491
    -1,         /* Not available: EFLAG */
492
    -1,         /* Not available: CSD */
493
    -1,         /* Not available: SSD */
494
    -1,         /* Not available: CFLG */
495
    -1,         /* Not available: FSR */
496
    -1,         /* Not available: FIR */
497
    -1,         /* Not available: FDR */
498
    -1,
499
    PT_AR_CCV,
500
    -1, -1, -1,
501
    PT_AR_UNAT,
502
    -1, -1, -1,
503
    PT_AR_FPSR,
504
    -1, -1, -1,
505
    -1,         /* Not available: ITC */
506
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
507
    -1, -1, -1, -1, -1, -1, -1, -1, -1,
508
    PT_AR_PFS,
509
    PT_AR_LC,
510
    -1,         /* Not available: EC, the Epilog Count register */
511
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
512
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
513
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
514
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
515
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
516
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
517
    -1,
518
    /* nat bits - not fetched directly; instead we obtain these bits from
519
       either rnat or unat or from memory. */
520
    -1, -1, -1, -1, -1, -1, -1, -1,
521
    -1, -1, -1, -1, -1, -1, -1, -1,
522
    -1, -1, -1, -1, -1, -1, -1, -1,
523
    -1, -1, -1, -1, -1, -1, -1, -1,
524
    -1, -1, -1, -1, -1, -1, -1, -1,
525
    -1, -1, -1, -1, -1, -1, -1, -1,
526
    -1, -1, -1, -1, -1, -1, -1, -1,
527
    -1, -1, -1, -1, -1, -1, -1, -1,
528
    -1, -1, -1, -1, -1, -1, -1, -1,
529
    -1, -1, -1, -1, -1, -1, -1, -1,
530
    -1, -1, -1, -1, -1, -1, -1, -1,
531
    -1, -1, -1, -1, -1, -1, -1, -1,
532
    -1, -1, -1, -1, -1, -1, -1, -1,
533
    -1, -1, -1, -1, -1, -1, -1, -1,
534
    -1, -1, -1, -1, -1, -1, -1, -1,
535
    -1, -1, -1, -1, -1, -1, -1, -1,
536
  };
537
 
538
int
539
ia64_register_u_addr (int blockend, int regnum)
540
{
541
  int addr;
542
 
543
  if (regnum < 0 || regnum >= NUM_REGS)
544
    error ("Invalid register number %d.", regnum);
545
 
546
  addr = u_offsets[regnum];
547
  if (addr == -1)
548
    addr = 0;
549
 
550
  return addr;
551
}
552
 
553
static void
554
initialize_arch ()
555
{
556
  return;
557
}
558
#endif
559
 
560
CORE_ADDR
561
register_addr (regno, blockend)
562
     int regno;
563
     CORE_ADDR blockend;
564
{
565
  CORE_ADDR addr;
566
 
567
  if (regno < 0 || regno >= ARCH_NUM_REGS)
568
    error ("Invalid register number %d.", regno);
569
 
570
  REGISTER_U_ADDR (addr, blockend, regno);
571
 
572
  return addr;
573
}
574
 
575
/* Fetch one register.  */
576
 
577
static void
578
fetch_register (regno)
579
     int regno;
580
{
581
  CORE_ADDR regaddr;
582
  register int i;
583
 
584
  /* Offset of registers within the u area.  */
585
  unsigned int offset;
586
 
587
  offset = U_REGS_OFFSET;
588
 
589
  regaddr = register_addr (regno, offset);
590
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
591
    {
592
      errno = 0;
593
      *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i] =
594
        ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0);
595
      regaddr += sizeof (PTRACE_XFER_TYPE);
596
      if (errno != 0)
597
        {
598
          /* Warning, not error, in case we are attached; sometimes the
599
             kernel doesn't let us at the registers.  */
600
          char *err = strerror (errno);
601
          char *msg = alloca (strlen (err) + 128);
602
          sprintf (msg, "reading register %d: %s", regno, err);
603
          error (msg);
604
          goto error_exit;
605
        }
606
    }
607
error_exit:;
608
}
609
 
610
/* Fetch all registers, or just one, from the child process.  */
611
 
612
void
613
fetch_inferior_registers (regno)
614
     int regno;
615
{
616
  if (regno == -1 || regno == 0)
617
    for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++)
618
      fetch_register (regno);
619
  else
620
    fetch_register (regno);
621
}
622
 
623
/* Store our register values back into the inferior.
624
   If REGNO is -1, do this for all registers.
625
   Otherwise, REGNO specifies which register (so we can save time).  */
626
 
627
void
628
store_inferior_registers (regno)
629
     int regno;
630
{
631
  CORE_ADDR regaddr;
632
  int i;
633
  unsigned int offset = U_REGS_OFFSET;
634
 
635
  if (regno >= 0)
636
    {
637
#if 0
638
      if (CANNOT_STORE_REGISTER (regno))
639
        return;
640
#endif
641
      regaddr = register_addr (regno, offset);
642
      errno = 0;
643
#if 0
644
      if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
645
        {
646
          scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
647
          ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
648
                  scratch, 0);
649
          if (errno != 0)
650
            {
651
              /* Error, even if attached.  Failing to write these two
652
                 registers is pretty serious.  */
653
              sprintf (buf, "writing register number %d", regno);
654
              perror_with_name (buf);
655
            }
656
        }
657
      else
658
#endif
659
        for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
660
          {
661
            errno = 0;
662
            ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
663
                    *(int *) &registers[REGISTER_BYTE (regno) + i]);
664
            if (errno != 0)
665
              {
666
                /* Warning, not error, in case we are attached; sometimes the
667
                   kernel doesn't let us at the registers.  */
668
                char *err = strerror (errno);
669
                char *msg = alloca (strlen (err) + 128);
670
                sprintf (msg, "writing register %d: %s",
671
                         regno, err);
672
                error (msg);
673
                return;
674
              }
675
            regaddr += sizeof (int);
676
          }
677
    }
678
  else
679
    for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++)
680
      store_inferior_registers (regno);
681
}
682
 
683
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
684
   in the NEW_SUN_PTRACE case.
685
   It ought to be straightforward.  But it appears that writing did
686
   not write the data that I specified.  I cannot understand where
687
   it got the data that it actually did write.  */
688
 
689
/* Copy LEN bytes from inferior's memory starting at MEMADDR
690
   to debugger memory starting at MYADDR.  */
691
 
692
void
693
read_inferior_memory (memaddr, myaddr, len)
694
     CORE_ADDR memaddr;
695
     char *myaddr;
696
     int len;
697
{
698
  register int i;
699
  /* Round starting address down to longword boundary.  */
700
  register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE);
701
  /* Round ending address up; get number of longwords that makes.  */
702
  register int count
703
    = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
704
      / sizeof (PTRACE_XFER_TYPE);
705
  /* Allocate buffer of that many longwords.  */
706
  register PTRACE_XFER_TYPE *buffer
707
    = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
708
 
709
  /* Read all the longwords */
710
  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
711
    {
712
      buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
713
    }
714
 
715
  /* Copy appropriate bytes out of the buffer.  */
716
  memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
717
}
718
 
719
/* Copy LEN bytes of data from debugger memory at MYADDR
720
   to inferior's memory at MEMADDR.
721
   On failure (cannot write the inferior)
722
   returns the value of errno.  */
723
 
724
int
725
write_inferior_memory (memaddr, myaddr, len)
726
     CORE_ADDR memaddr;
727
     char *myaddr;
728
     int len;
729
{
730
  register int i;
731
  /* Round starting address down to longword boundary.  */
732
  register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE);
733
  /* Round ending address up; get number of longwords that makes.  */
734
  register int count
735
  = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE);
736
  /* Allocate buffer of that many longwords.  */
737
  register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
738
  extern int errno;
739
 
740
  /* Fill start and end extra bytes of buffer with existing memory data.  */
741
 
742
  buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
743
 
744
  if (count > 1)
745
    {
746
      buffer[count - 1]
747
        = ptrace (PTRACE_PEEKTEXT, inferior_pid,
748
                  addr + (count - 1) * sizeof (PTRACE_XFER_TYPE), 0);
749
    }
750
 
751
  /* Copy data to be written over corresponding part of buffer */
752
 
753
  memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
754
 
755
  /* Write the entire buffer.  */
756
 
757
  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
758
    {
759
      errno = 0;
760
      ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]);
761
      if (errno)
762
        return errno;
763
    }
764
 
765
  return 0;
766
}
767
 
768
void
769
initialize_low ()
770
{
771
  initialize_arch ();
772
}

powered by: WebSVN 2.1.0

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