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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [i386-linux-nat.c] - Blame information for rev 299

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

Line No. Rev Author Line
1 24 jeremybenn
/* Native-dependent code for GNU/Linux i386.
2
 
3
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "defs.h"
22
#include "inferior.h"
23
#include "gdbcore.h"
24
#include "regcache.h"
25
#include "target.h"
26
#include "linux-nat.h"
27
 
28
#include "gdb_assert.h"
29
#include "gdb_string.h"
30
#include <sys/ptrace.h>
31
#include <sys/user.h>
32
#include <sys/procfs.h>
33
 
34
#ifdef HAVE_SYS_REG_H
35
#include <sys/reg.h>
36
#endif
37
 
38
#ifndef ORIG_EAX
39
#define ORIG_EAX -1
40
#endif
41
 
42
#ifdef HAVE_SYS_DEBUGREG_H
43
#include <sys/debugreg.h>
44
#endif
45
 
46
#ifndef DR_FIRSTADDR
47
#define DR_FIRSTADDR 0
48
#endif
49
 
50
#ifndef DR_LASTADDR
51
#define DR_LASTADDR 3
52
#endif
53
 
54
#ifndef DR_STATUS
55
#define DR_STATUS 6
56
#endif
57
 
58
#ifndef DR_CONTROL
59
#define DR_CONTROL 7
60
#endif
61
 
62
/* Prototypes for supply_gregset etc.  */
63
#include "gregset.h"
64
 
65
#include "i387-tdep.h"
66
#include "i386-tdep.h"
67
#include "i386-linux-tdep.h"
68
 
69
/* Defines ps_err_e, struct ps_prochandle.  */
70
#include "gdb_proc_service.h"
71
 
72
 
73
/* The register sets used in GNU/Linux ELF core-dumps are identical to
74
   the register sets in `struct user' that is used for a.out
75
   core-dumps, and is also used by `ptrace'.  The corresponding types
76
   are `elf_gregset_t' for the general-purpose registers (with
77
   `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
78
   for the floating-point registers.
79
 
80
   Those types used to be available under the names `gregset_t' and
81
   `fpregset_t' too, and this file used those names in the past.  But
82
   those names are now used for the register sets used in the
83
   `mcontext_t' type, and have a different size and layout.  */
84
 
85
/* Mapping between the general-purpose registers in `struct user'
86
   format and GDB's register array layout.  */
87
static int regmap[] =
88
{
89
  EAX, ECX, EDX, EBX,
90
  UESP, EBP, ESI, EDI,
91
  EIP, EFL, CS, SS,
92
  DS, ES, FS, GS,
93
  -1, -1, -1, -1,               /* st0, st1, st2, st3 */
94
  -1, -1, -1, -1,               /* st4, st5, st6, st7 */
95
  -1, -1, -1, -1,               /* fctrl, fstat, ftag, fiseg */
96
  -1, -1, -1, -1,               /* fioff, foseg, fooff, fop */
97
  -1, -1, -1, -1,               /* xmm0, xmm1, xmm2, xmm3 */
98
  -1, -1, -1, -1,               /* xmm4, xmm5, xmm6, xmm6 */
99
  -1,                           /* mxcsr */
100
  ORIG_EAX
101
};
102
 
103
/* Which ptrace request retrieves which registers?
104
   These apply to the corresponding SET requests as well.  */
105
 
106
#define GETREGS_SUPPLIES(regno) \
107
  ((0 <= (regno) && (regno) <= 15) || (regno) == I386_LINUX_ORIG_EAX_REGNUM)
108
 
109
#define GETFPXREGS_SUPPLIES(regno) \
110
  (I386_ST0_REGNUM <= (regno) && (regno) < I386_SSE_NUM_REGS)
111
 
112
/* Does the current host support the GETREGS request?  */
113
int have_ptrace_getregs =
114
#ifdef HAVE_PTRACE_GETREGS
115
  1
116
#else
117
 
118
#endif
119
;
120
 
121
/* Does the current host support the GETFPXREGS request?  The header
122
   file may or may not define it, and even if it is defined, the
123
   kernel will return EIO if it's running on a pre-SSE processor.
124
 
125
   My instinct is to attach this to some architecture- or
126
   target-specific data structure, but really, a particular GDB
127
   process can only run on top of one kernel at a time.  So it's okay
128
   for this to be a simple variable.  */
129
int have_ptrace_getfpxregs =
130
#ifdef HAVE_PTRACE_GETFPXREGS
131
  1
132
#else
133
 
134
#endif
135
;
136
 
137
 
138
/* Accessing registers through the U area, one at a time.  */
139
 
140
/* Fetch one register.  */
141
 
142
static void
143
fetch_register (struct regcache *regcache, int regno)
144
{
145
  int tid;
146
  int val;
147
 
148
  gdb_assert (!have_ptrace_getregs);
149
  if (regmap[regno] == -1)
150
    {
151
      regcache_raw_supply (regcache, regno, NULL);
152
      return;
153
    }
154
 
155
  /* GNU/Linux LWP ID's are process ID's.  */
156
  tid = TIDGET (inferior_ptid);
157
  if (tid == 0)
158
    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
159
 
160
  errno = 0;
161
  val = ptrace (PTRACE_PEEKUSER, tid, 4 * regmap[regno], 0);
162
  if (errno != 0)
163
    error (_("Couldn't read register %s (#%d): %s."),
164
           gdbarch_register_name (get_regcache_arch (regcache), regno),
165
           regno, safe_strerror (errno));
166
 
167
  regcache_raw_supply (regcache, regno, &val);
168
}
169
 
170
/* Store one register. */
171
 
172
static void
173
store_register (const struct regcache *regcache, int regno)
174
{
175
  int tid;
176
  int val;
177
 
178
  gdb_assert (!have_ptrace_getregs);
179
  if (regmap[regno] == -1)
180
    return;
181
 
182
  /* GNU/Linux LWP ID's are process ID's.  */
183
  tid = TIDGET (inferior_ptid);
184
  if (tid == 0)
185
    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
186
 
187
  errno = 0;
188
  regcache_raw_collect (regcache, regno, &val);
189
  ptrace (PTRACE_POKEUSER, tid, 4 * regmap[regno], val);
190
  if (errno != 0)
191
    error (_("Couldn't write register %s (#%d): %s."),
192
           gdbarch_register_name (get_regcache_arch (regcache), regno),
193
           regno, safe_strerror (errno));
194
}
195
 
196
 
197
/* Transfering the general-purpose registers between GDB, inferiors
198
   and core files.  */
199
 
200
/* Fill GDB's register array with the general-purpose register values
201
   in *GREGSETP.  */
202
 
203
void
204
supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
205
{
206
  const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
207
  int i;
208
 
209
  for (i = 0; i < I386_NUM_GREGS; i++)
210
    regcache_raw_supply (regcache, i, regp + regmap[i]);
211
 
212
  if (I386_LINUX_ORIG_EAX_REGNUM
213
        < gdbarch_num_regs (get_regcache_arch (regcache)))
214
    regcache_raw_supply (regcache, I386_LINUX_ORIG_EAX_REGNUM,
215
                         regp + ORIG_EAX);
216
}
217
 
218
/* Fill register REGNO (if it is a general-purpose register) in
219
   *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
220
   do this for all registers.  */
221
 
222
void
223
fill_gregset (const struct regcache *regcache,
224
              elf_gregset_t *gregsetp, int regno)
225
{
226
  elf_greg_t *regp = (elf_greg_t *) gregsetp;
227
  int i;
228
 
229
  for (i = 0; i < I386_NUM_GREGS; i++)
230
    if (regno == -1 || regno == i)
231
      regcache_raw_collect (regcache, i, regp + regmap[i]);
232
 
233
  if ((regno == -1 || regno == I386_LINUX_ORIG_EAX_REGNUM)
234
      && I386_LINUX_ORIG_EAX_REGNUM
235
           < gdbarch_num_regs (get_regcache_arch (regcache)))
236
    regcache_raw_collect (regcache, I386_LINUX_ORIG_EAX_REGNUM,
237
                          regp + ORIG_EAX);
238
}
239
 
240
#ifdef HAVE_PTRACE_GETREGS
241
 
242
/* Fetch all general-purpose registers from process/thread TID and
243
   store their values in GDB's register array.  */
244
 
245
static void
246
fetch_regs (struct regcache *regcache, int tid)
247
{
248
  elf_gregset_t regs;
249
  elf_gregset_t *regs_p = &regs;
250
 
251
  if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
252
    {
253
      if (errno == EIO)
254
        {
255
          /* The kernel we're running on doesn't support the GETREGS
256
             request.  Reset `have_ptrace_getregs'.  */
257
          have_ptrace_getregs = 0;
258
          return;
259
        }
260
 
261
      perror_with_name (_("Couldn't get registers"));
262
    }
263
 
264
  supply_gregset (regcache, (const elf_gregset_t *) regs_p);
265
}
266
 
267
/* Store all valid general-purpose registers in GDB's register array
268
   into the process/thread specified by TID.  */
269
 
270
static void
271
store_regs (const struct regcache *regcache, int tid, int regno)
272
{
273
  elf_gregset_t regs;
274
 
275
  if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
276
    perror_with_name (_("Couldn't get registers"));
277
 
278
  fill_gregset (regcache, &regs, regno);
279
 
280
  if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
281
    perror_with_name (_("Couldn't write registers"));
282
}
283
 
284
#else
285
 
286
static void fetch_regs (struct regcache *regcache, int tid) {}
287
static void store_regs (const struct regcache *regcache, int tid, int regno) {}
288
 
289
#endif
290
 
291
 
292
/* Transfering floating-point registers between GDB, inferiors and cores.  */
293
 
294
/* Fill GDB's register array with the floating-point register values in
295
   *FPREGSETP.  */
296
 
297
void
298
supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
299
{
300
  i387_supply_fsave (regcache, -1, fpregsetp);
301
}
302
 
303
/* Fill register REGNO (if it is a floating-point register) in
304
   *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
305
   do this for all registers.  */
306
 
307
void
308
fill_fpregset (const struct regcache *regcache,
309
               elf_fpregset_t *fpregsetp, int regno)
310
{
311
  i387_collect_fsave (regcache, regno, fpregsetp);
312
}
313
 
314
#ifdef HAVE_PTRACE_GETREGS
315
 
316
/* Fetch all floating-point registers from process/thread TID and store
317
   thier values in GDB's register array.  */
318
 
319
static void
320
fetch_fpregs (struct regcache *regcache, int tid)
321
{
322
  elf_fpregset_t fpregs;
323
 
324
  if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
325
    perror_with_name (_("Couldn't get floating point status"));
326
 
327
  supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
328
}
329
 
330
/* Store all valid floating-point registers in GDB's register array
331
   into the process/thread specified by TID.  */
332
 
333
static void
334
store_fpregs (const struct regcache *regcache, int tid, int regno)
335
{
336
  elf_fpregset_t fpregs;
337
 
338
  if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
339
    perror_with_name (_("Couldn't get floating point status"));
340
 
341
  fill_fpregset (regcache, &fpregs, regno);
342
 
343
  if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
344
    perror_with_name (_("Couldn't write floating point status"));
345
}
346
 
347
#else
348
 
349
static void fetch_fpregs (struct regcache *regcache, int tid) {}
350
static void store_fpregs (const struct regcache *regcache, int tid, int regno) {}
351
 
352
#endif
353
 
354
 
355
/* Transfering floating-point and SSE registers to and from GDB.  */
356
 
357
#ifdef HAVE_PTRACE_GETFPXREGS
358
 
359
/* Fill GDB's register array with the floating-point and SSE register
360
   values in *FPXREGSETP.  */
361
 
362
void
363
supply_fpxregset (struct regcache *regcache,
364
                  const elf_fpxregset_t *fpxregsetp)
365
{
366
  i387_supply_fxsave (regcache, -1, fpxregsetp);
367
}
368
 
369
/* Fill register REGNO (if it is a floating-point or SSE register) in
370
   *FPXREGSETP with the value in GDB's register array.  If REGNO is
371
   -1, do this for all registers.  */
372
 
373
void
374
fill_fpxregset (const struct regcache *regcache,
375
                elf_fpxregset_t *fpxregsetp, int regno)
376
{
377
  i387_collect_fxsave (regcache, regno, fpxregsetp);
378
}
379
 
380
/* Fetch all registers covered by the PTRACE_GETFPXREGS request from
381
   process/thread TID and store their values in GDB's register array.
382
   Return non-zero if successful, zero otherwise.  */
383
 
384
static int
385
fetch_fpxregs (struct regcache *regcache, int tid)
386
{
387
  elf_fpxregset_t fpxregs;
388
 
389
  if (! have_ptrace_getfpxregs)
390
    return 0;
391
 
392
  if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0)
393
    {
394
      if (errno == EIO)
395
        {
396
          have_ptrace_getfpxregs = 0;
397
          return 0;
398
        }
399
 
400
      perror_with_name (_("Couldn't read floating-point and SSE registers"));
401
    }
402
 
403
  supply_fpxregset (regcache, (const elf_fpxregset_t *) &fpxregs);
404
  return 1;
405
}
406
 
407
/* Store all valid registers in GDB's register array covered by the
408
   PTRACE_SETFPXREGS request into the process/thread specified by TID.
409
   Return non-zero if successful, zero otherwise.  */
410
 
411
static int
412
store_fpxregs (const struct regcache *regcache, int tid, int regno)
413
{
414
  elf_fpxregset_t fpxregs;
415
 
416
  if (! have_ptrace_getfpxregs)
417
    return 0;
418
 
419
  if (ptrace (PTRACE_GETFPXREGS, tid, 0, &fpxregs) == -1)
420
    {
421
      if (errno == EIO)
422
        {
423
          have_ptrace_getfpxregs = 0;
424
          return 0;
425
        }
426
 
427
      perror_with_name (_("Couldn't read floating-point and SSE registers"));
428
    }
429
 
430
  fill_fpxregset (regcache, &fpxregs, regno);
431
 
432
  if (ptrace (PTRACE_SETFPXREGS, tid, 0, &fpxregs) == -1)
433
    perror_with_name (_("Couldn't write floating-point and SSE registers"));
434
 
435
  return 1;
436
}
437
 
438
#else
439
 
440
static int fetch_fpxregs (struct regcache *regcache, int tid) { return 0; }
441
static int store_fpxregs (const struct regcache *regcache, int tid, int regno) { return 0; }
442
 
443
#endif /* HAVE_PTRACE_GETFPXREGS */
444
 
445
 
446
/* Transferring arbitrary registers between GDB and inferior.  */
447
 
448
/* Fetch register REGNO from the child process.  If REGNO is -1, do
449
   this for all registers (including the floating point and SSE
450
   registers).  */
451
 
452
static void
453
i386_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
454
{
455
  int tid;
456
 
457
  /* Use the old method of peeking around in `struct user' if the
458
     GETREGS request isn't available.  */
459
  if (!have_ptrace_getregs)
460
    {
461
      int i;
462
 
463
      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
464
        if (regno == -1 || regno == i)
465
          fetch_register (regcache, i);
466
 
467
      return;
468
    }
469
 
470
  /* GNU/Linux LWP ID's are process ID's.  */
471
  tid = TIDGET (inferior_ptid);
472
  if (tid == 0)
473
    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
474
 
475
  /* Use the PTRACE_GETFPXREGS request whenever possible, since it
476
     transfers more registers in one system call, and we'll cache the
477
     results.  But remember that fetch_fpxregs can fail, and return
478
     zero.  */
479
  if (regno == -1)
480
    {
481
      fetch_regs (regcache, tid);
482
 
483
      /* The call above might reset `have_ptrace_getregs'.  */
484
      if (!have_ptrace_getregs)
485
        {
486
          i386_linux_fetch_inferior_registers (regcache, regno);
487
          return;
488
        }
489
 
490
      if (fetch_fpxregs (regcache, tid))
491
        return;
492
      fetch_fpregs (regcache, tid);
493
      return;
494
    }
495
 
496
  if (GETREGS_SUPPLIES (regno))
497
    {
498
      fetch_regs (regcache, tid);
499
      return;
500
    }
501
 
502
  if (GETFPXREGS_SUPPLIES (regno))
503
    {
504
      if (fetch_fpxregs (regcache, tid))
505
        return;
506
 
507
      /* Either our processor or our kernel doesn't support the SSE
508
         registers, so read the FP registers in the traditional way,
509
         and fill the SSE registers with dummy values.  It would be
510
         more graceful to handle differences in the register set using
511
         gdbarch.  Until then, this will at least make things work
512
         plausibly.  */
513
      fetch_fpregs (regcache, tid);
514
      return;
515
    }
516
 
517
  internal_error (__FILE__, __LINE__,
518
                  _("Got request for bad register number %d."), regno);
519
}
520
 
521
/* Store register REGNO back into the child process.  If REGNO is -1,
522
   do this for all registers (including the floating point and SSE
523
   registers).  */
524
static void
525
i386_linux_store_inferior_registers (struct regcache *regcache, int regno)
526
{
527
  int tid;
528
 
529
  /* Use the old method of poking around in `struct user' if the
530
     SETREGS request isn't available.  */
531
  if (!have_ptrace_getregs)
532
    {
533
      int i;
534
 
535
      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
536
        if (regno == -1 || regno == i)
537
          store_register (regcache, i);
538
 
539
      return;
540
    }
541
 
542
  /* GNU/Linux LWP ID's are process ID's.  */
543
  tid = TIDGET (inferior_ptid);
544
  if (tid == 0)
545
    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
546
 
547
  /* Use the PTRACE_SETFPXREGS requests whenever possible, since it
548
     transfers more registers in one system call.  But remember that
549
     store_fpxregs can fail, and return zero.  */
550
  if (regno == -1)
551
    {
552
      store_regs (regcache, tid, regno);
553
      if (store_fpxregs (regcache, tid, regno))
554
        return;
555
      store_fpregs (regcache, tid, regno);
556
      return;
557
    }
558
 
559
  if (GETREGS_SUPPLIES (regno))
560
    {
561
      store_regs (regcache, tid, regno);
562
      return;
563
    }
564
 
565
  if (GETFPXREGS_SUPPLIES (regno))
566
    {
567
      if (store_fpxregs (regcache, tid, regno))
568
        return;
569
 
570
      /* Either our processor or our kernel doesn't support the SSE
571
         registers, so just write the FP registers in the traditional
572
         way.  */
573
      store_fpregs (regcache, tid, regno);
574
      return;
575
    }
576
 
577
  internal_error (__FILE__, __LINE__,
578
                  _("Got request to store bad register number %d."), regno);
579
}
580
 
581
 
582
/* Support for debug registers.  */
583
 
584
static unsigned long i386_linux_dr[DR_CONTROL + 1];
585
 
586
static unsigned long
587
i386_linux_dr_get (ptid_t ptid, int regnum)
588
{
589
  int tid;
590
  unsigned long value;
591
 
592
  tid = TIDGET (ptid);
593
  if (tid == 0)
594
    tid = PIDGET (ptid);
595
 
596
  /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
597
     ptrace call fails breaks debugging remote targets.  The correct
598
     way to fix this is to add the hardware breakpoint and watchpoint
599
     stuff to the target vector.  For now, just return zero if the
600
     ptrace call fails.  */
601
  errno = 0;
602
  value = ptrace (PTRACE_PEEKUSER, tid,
603
                  offsetof (struct user, u_debugreg[regnum]), 0);
604
  if (errno != 0)
605
#if 0
606
    perror_with_name (_("Couldn't read debug register"));
607
#else
608
    return 0;
609
#endif
610
 
611
  return value;
612
}
613
 
614
static void
615
i386_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
616
{
617
  int tid;
618
 
619
  tid = TIDGET (ptid);
620
  if (tid == 0)
621
    tid = PIDGET (ptid);
622
 
623
  errno = 0;
624
  ptrace (PTRACE_POKEUSER, tid,
625
          offsetof (struct user, u_debugreg[regnum]), value);
626
  if (errno != 0)
627
    perror_with_name (_("Couldn't write debug register"));
628
}
629
 
630
void
631
i386_linux_dr_set_control (unsigned long control)
632
{
633
  struct lwp_info *lp;
634
  ptid_t ptid;
635
 
636
  i386_linux_dr[DR_CONTROL] = control;
637
  ALL_LWPS (lp, ptid)
638
    i386_linux_dr_set (ptid, DR_CONTROL, control);
639
}
640
 
641
void
642
i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
643
{
644
  struct lwp_info *lp;
645
  ptid_t ptid;
646
 
647
  gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
648
 
649
  i386_linux_dr[DR_FIRSTADDR + regnum] = addr;
650
  ALL_LWPS (lp, ptid)
651
    i386_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
652
}
653
 
654
void
655
i386_linux_dr_reset_addr (int regnum)
656
{
657
  i386_linux_dr_set_addr (regnum, 0);
658
}
659
 
660
unsigned long
661
i386_linux_dr_get_status (void)
662
{
663
  return i386_linux_dr_get (inferior_ptid, DR_STATUS);
664
}
665
 
666
static void
667
i386_linux_new_thread (ptid_t ptid)
668
{
669
  int i;
670
 
671
  for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
672
    i386_linux_dr_set (ptid, i, i386_linux_dr[i]);
673
 
674
  i386_linux_dr_set (ptid, DR_CONTROL, i386_linux_dr[DR_CONTROL]);
675
}
676
 
677
 
678
/* Called by libthread_db.  Returns a pointer to the thread local
679
   storage (or its descriptor).  */
680
 
681
ps_err_e
682
ps_get_thread_area (const struct ps_prochandle *ph,
683
                    lwpid_t lwpid, int idx, void **base)
684
{
685
  /* NOTE: cagney/2003-08-26: The definition of this buffer is found
686
     in the kernel header <asm-i386/ldt.h>.  It, after padding, is 4 x
687
     4 byte integers in size: `entry_number', `base_addr', `limit',
688
     and a bunch of status bits.
689
 
690
     The values returned by this ptrace call should be part of the
691
     regcache buffer, and ps_get_thread_area should channel its
692
     request through the regcache.  That way remote targets could
693
     provide the value using the remote protocol and not this direct
694
     call.
695
 
696
     Is this function needed?  I'm guessing that the `base' is the
697
     address of a a descriptor that libthread_db uses to find the
698
     thread local address base that GDB needs.  Perhaps that
699
     descriptor is defined by the ABI.  Anyway, given that
700
     libthread_db calls this function without prompting (gdb
701
     requesting tls base) I guess it needs info in there anyway.  */
702
  unsigned int desc[4];
703
  gdb_assert (sizeof (int) == 4);
704
 
705
#ifndef PTRACE_GET_THREAD_AREA
706
#define PTRACE_GET_THREAD_AREA 25
707
#endif
708
 
709
  if (ptrace (PTRACE_GET_THREAD_AREA, lwpid,
710
              (void *) idx, (unsigned long) &desc) < 0)
711
    return PS_ERR;
712
 
713
  *(int *)base = desc[1];
714
  return PS_OK;
715
}
716
 
717
 
718
/* The instruction for a GNU/Linux system call is:
719
       int $0x80
720
   or 0xcd 0x80.  */
721
 
722
static const unsigned char linux_syscall[] = { 0xcd, 0x80 };
723
 
724
#define LINUX_SYSCALL_LEN (sizeof linux_syscall)
725
 
726
/* The system call number is stored in the %eax register.  */
727
#define LINUX_SYSCALL_REGNUM I386_EAX_REGNUM
728
 
729
/* We are specifically interested in the sigreturn and rt_sigreturn
730
   system calls.  */
731
 
732
#ifndef SYS_sigreturn
733
#define SYS_sigreturn           0x77
734
#endif
735
#ifndef SYS_rt_sigreturn
736
#define SYS_rt_sigreturn        0xad
737
#endif
738
 
739
/* Offset to saved processor flags, from <asm/sigcontext.h>.  */
740
#define LINUX_SIGCONTEXT_EFLAGS_OFFSET (64)
741
 
742
/* Resume execution of the inferior process.
743
   If STEP is nonzero, single-step it.
744
   If SIGNAL is nonzero, give it that signal.  */
745
 
746
static void
747
i386_linux_resume (ptid_t ptid, int step, enum target_signal signal)
748
{
749
  int pid = PIDGET (ptid);
750
 
751
  int request = PTRACE_CONT;
752
 
753
  if (step)
754
    {
755
      struct regcache *regcache = get_thread_regcache (pid_to_ptid (pid));
756
      ULONGEST pc;
757
      gdb_byte buf[LINUX_SYSCALL_LEN];
758
 
759
      request = PTRACE_SINGLESTEP;
760
 
761
      regcache_cooked_read_unsigned
762
        (regcache, gdbarch_pc_regnum (get_regcache_arch (regcache)), &pc);
763
 
764
      /* Returning from a signal trampoline is done by calling a
765
         special system call (sigreturn or rt_sigreturn, see
766
         i386-linux-tdep.c for more information).  This system call
767
         restores the registers that were saved when the signal was
768
         raised, including %eflags.  That means that single-stepping
769
         won't work.  Instead, we'll have to modify the signal context
770
         that's about to be restored, and set the trace flag there.  */
771
 
772
      /* First check if PC is at a system call.  */
773
      if (read_memory_nobpt (pc, buf, LINUX_SYSCALL_LEN) == 0
774
          && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0)
775
        {
776
          ULONGEST syscall;
777
          regcache_cooked_read_unsigned (regcache,
778
                                         LINUX_SYSCALL_REGNUM, &syscall);
779
 
780
          /* Then check the system call number.  */
781
          if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn)
782
            {
783
              ULONGEST sp, addr;
784
              unsigned long int eflags;
785
 
786
              regcache_cooked_read_unsigned (regcache, I386_ESP_REGNUM, &sp);
787
              if (syscall == SYS_rt_sigreturn)
788
                addr = read_memory_integer (sp + 8, 4) + 20;
789
              else
790
                addr = sp;
791
 
792
              /* Set the trace flag in the context that's about to be
793
                 restored.  */
794
              addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET;
795
              read_memory (addr, (gdb_byte *) &eflags, 4);
796
              eflags |= 0x0100;
797
              write_memory (addr, (gdb_byte *) &eflags, 4);
798
            }
799
        }
800
    }
801
 
802
  if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1)
803
    perror_with_name (("ptrace"));
804
}
805
 
806
static void (*super_post_startup_inferior) (ptid_t ptid);
807
 
808
static void
809
i386_linux_child_post_startup_inferior (ptid_t ptid)
810
{
811
  i386_cleanup_dregs ();
812
  super_post_startup_inferior (ptid);
813
}
814
 
815
void
816
_initialize_i386_linux_nat (void)
817
{
818
  struct target_ops *t;
819
 
820
  /* Fill in the generic GNU/Linux methods.  */
821
  t = linux_target ();
822
 
823
  /* Override the default ptrace resume method.  */
824
  t->to_resume = i386_linux_resume;
825
 
826
  /* Override the GNU/Linux inferior startup hook.  */
827
  super_post_startup_inferior = t->to_post_startup_inferior;
828
  t->to_post_startup_inferior = i386_linux_child_post_startup_inferior;
829
 
830
  /* Add our register access methods.  */
831
  t->to_fetch_registers = i386_linux_fetch_inferior_registers;
832
  t->to_store_registers = i386_linux_store_inferior_registers;
833
 
834
  /* Register the target.  */
835
  linux_nat_add_target (t);
836
  linux_nat_set_new_thread (t, i386_linux_new_thread);
837
}

powered by: WebSVN 2.1.0

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