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

Subversion Repositories or1k

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

powered by: WebSVN 2.1.0

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