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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [i386-linux-nat.c] - Blame information for rev 862

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

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

powered by: WebSVN 2.1.0

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