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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [ppc-linux-tdep.c] - Blame information for rev 578

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

Line No. Rev Author Line
1 578 markom
/* Target-dependent code for GDB, the GNU debugger.
2
 
3
   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
4
   2000, 2001 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 2 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, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
#include "defs.h"
24
#include "frame.h"
25
#include "inferior.h"
26
#include "symtab.h"
27
#include "target.h"
28
#include "gdbcore.h"
29
#include "gdbcmd.h"
30
#include "symfile.h"
31
#include "objfiles.h"
32
#include "regcache.h"
33
 
34
#include "ppc-tdep.h"
35
 
36
/* The following two instructions are used in the signal trampoline
37
   code on linux/ppc */
38
#define INSTR_LI_R0_0x7777      0x38007777
39
#define INSTR_SC                0x44000002
40
 
41
/* Since the *-tdep.c files are platform independent (i.e, they may be
42
   used to build cross platform debuggers), we can't include system
43
   headers.  Therefore, details concerning the sigcontext structure
44
   must be painstakingly rerecorded.  What's worse, if these details
45
   ever change in the header files, they'll have to be changed here
46
   as well. */
47
 
48
/* __SIGNAL_FRAMESIZE from <asm/ptrace.h> */
49
#define PPC_LINUX_SIGNAL_FRAMESIZE 64
50
 
51
/* From <asm/sigcontext.h>, offsetof(struct sigcontext_struct, regs) == 0x1c */
52
#define PPC_LINUX_REGS_PTR_OFFSET (PPC_LINUX_SIGNAL_FRAMESIZE + 0x1c)
53
 
54
/* From <asm/sigcontext.h>,
55
   offsetof(struct sigcontext_struct, handler) == 0x14 */
56
#define PPC_LINUX_HANDLER_PTR_OFFSET (PPC_LINUX_SIGNAL_FRAMESIZE + 0x14)
57
 
58
/* From <asm/ptrace.h>, values for PT_NIP, PT_R1, and PT_LNK */
59
#define PPC_LINUX_PT_R0         0
60
#define PPC_LINUX_PT_R1         1
61
#define PPC_LINUX_PT_R2         2
62
#define PPC_LINUX_PT_R3         3
63
#define PPC_LINUX_PT_R4         4
64
#define PPC_LINUX_PT_R5         5
65
#define PPC_LINUX_PT_R6         6
66
#define PPC_LINUX_PT_R7         7
67
#define PPC_LINUX_PT_R8         8
68
#define PPC_LINUX_PT_R9         9
69
#define PPC_LINUX_PT_R10        10
70
#define PPC_LINUX_PT_R11        11
71
#define PPC_LINUX_PT_R12        12
72
#define PPC_LINUX_PT_R13        13
73
#define PPC_LINUX_PT_R14        14
74
#define PPC_LINUX_PT_R15        15
75
#define PPC_LINUX_PT_R16        16
76
#define PPC_LINUX_PT_R17        17
77
#define PPC_LINUX_PT_R18        18
78
#define PPC_LINUX_PT_R19        19
79
#define PPC_LINUX_PT_R20        20
80
#define PPC_LINUX_PT_R21        21
81
#define PPC_LINUX_PT_R22        22
82
#define PPC_LINUX_PT_R23        23
83
#define PPC_LINUX_PT_R24        24
84
#define PPC_LINUX_PT_R25        25
85
#define PPC_LINUX_PT_R26        26
86
#define PPC_LINUX_PT_R27        27
87
#define PPC_LINUX_PT_R28        28
88
#define PPC_LINUX_PT_R29        29
89
#define PPC_LINUX_PT_R30        30
90
#define PPC_LINUX_PT_R31        31
91
#define PPC_LINUX_PT_NIP        32
92
#define PPC_LINUX_PT_MSR        33
93
#define PPC_LINUX_PT_CTR        35
94
#define PPC_LINUX_PT_LNK        36
95
#define PPC_LINUX_PT_XER        37
96
#define PPC_LINUX_PT_CCR        38
97
#define PPC_LINUX_PT_MQ         39
98
#define PPC_LINUX_PT_FPR0       48      /* each FP reg occupies 2 slots in this space */
99
#define PPC_LINUX_PT_FPR31 (PPC_LINUX_PT_FPR0 + 2*31)
100
#define PPC_LINUX_PT_FPSCR (PPC_LINUX_PT_FPR0 + 2*32 + 1)
101
 
102
static int ppc_linux_at_sigtramp_return_path (CORE_ADDR pc);
103
 
104
/* Determine if pc is in a signal trampoline...
105
 
106
   Ha!  That's not what this does at all.  wait_for_inferior in infrun.c
107
   calls IN_SIGTRAMP in order to detect entry into a signal trampoline
108
   just after delivery of a signal.  But on linux, signal trampolines
109
   are used for the return path only.  The kernel sets things up so that
110
   the signal handler is called directly.
111
 
112
   If we use in_sigtramp2() in place of in_sigtramp() (see below)
113
   we'll (often) end up with stop_pc in the trampoline and prev_pc in
114
   the (now exited) handler.  The code there will cause a temporary
115
   breakpoint to be set on prev_pc which is not very likely to get hit
116
   again.
117
 
118
   If this is confusing, think of it this way...  the code in
119
   wait_for_inferior() needs to be able to detect entry into a signal
120
   trampoline just after a signal is delivered, not after the handler
121
   has been run.
122
 
123
   So, we define in_sigtramp() below to return 1 if the following is
124
   true:
125
 
126
   1) The previous frame is a real signal trampoline.
127
 
128
   - and -
129
 
130
   2) pc is at the first or second instruction of the corresponding
131
   handler.
132
 
133
   Why the second instruction?  It seems that wait_for_inferior()
134
   never sees the first instruction when single stepping.  When a
135
   signal is delivered while stepping, the next instruction that
136
   would've been stepped over isn't, instead a signal is delivered and
137
   the first instruction of the handler is stepped over instead.  That
138
   puts us on the second instruction.  (I added the test for the
139
   first instruction long after the fact, just in case the observed
140
   behavior is ever fixed.)
141
 
142
   IN_SIGTRAMP is called from blockframe.c as well in order to set
143
   the signal_handler_caller flag.  Because of our strange definition
144
   of in_sigtramp below, we can't rely on signal_handler_caller getting
145
   set correctly from within blockframe.c.  This is why we take pains
146
   to set it in init_extra_frame_info().  */
147
 
148
int
149
ppc_linux_in_sigtramp (CORE_ADDR pc, char *func_name)
150
{
151
  CORE_ADDR lr;
152
  CORE_ADDR sp;
153
  CORE_ADDR tramp_sp;
154
  char buf[4];
155
  CORE_ADDR handler;
156
 
157
  lr = read_register (PPC_LR_REGNUM);
158
  if (!ppc_linux_at_sigtramp_return_path (lr))
159
    return 0;
160
 
161
  sp = read_register (SP_REGNUM);
162
 
163
  if (target_read_memory (sp, buf, sizeof (buf)) != 0)
164
    return 0;
165
 
166
  tramp_sp = extract_unsigned_integer (buf, 4);
167
 
168
  if (target_read_memory (tramp_sp + PPC_LINUX_HANDLER_PTR_OFFSET, buf,
169
                          sizeof (buf)) != 0)
170
    return 0;
171
 
172
  handler = extract_unsigned_integer (buf, 4);
173
 
174
  return (pc == handler || pc == handler + 4);
175
}
176
 
177
/*
178
 * The signal handler trampoline is on the stack and consists of exactly
179
 * two instructions.  The easiest and most accurate way of determining
180
 * whether the pc is in one of these trampolines is by inspecting the
181
 * instructions.  It'd be faster though if we could find a way to do this
182
 * via some simple address comparisons.
183
 */
184
static int
185
ppc_linux_at_sigtramp_return_path (CORE_ADDR pc)
186
{
187
  char buf[12];
188
  unsigned long pcinsn;
189
  if (target_read_memory (pc - 4, buf, sizeof (buf)) != 0)
190
    return 0;
191
 
192
  /* extract the instruction at the pc */
193
  pcinsn = extract_unsigned_integer (buf + 4, 4);
194
 
195
  return (
196
           (pcinsn == INSTR_LI_R0_0x7777
197
            && extract_unsigned_integer (buf + 8, 4) == INSTR_SC)
198
           ||
199
           (pcinsn == INSTR_SC
200
            && extract_unsigned_integer (buf, 4) == INSTR_LI_R0_0x7777));
201
}
202
 
203
CORE_ADDR
204
ppc_linux_skip_trampoline_code (CORE_ADDR pc)
205
{
206
  char buf[4];
207
  struct obj_section *sect;
208
  struct objfile *objfile;
209
  unsigned long insn;
210
  CORE_ADDR plt_start = 0;
211
  CORE_ADDR symtab = 0;
212
  CORE_ADDR strtab = 0;
213
  int num_slots = -1;
214
  int reloc_index = -1;
215
  CORE_ADDR plt_table;
216
  CORE_ADDR reloc;
217
  CORE_ADDR sym;
218
  long symidx;
219
  char symname[1024];
220
  struct minimal_symbol *msymbol;
221
 
222
  /* Find the section pc is in; return if not in .plt */
223
  sect = find_pc_section (pc);
224
  if (!sect || strcmp (sect->the_bfd_section->name, ".plt") != 0)
225
    return 0;
226
 
227
  objfile = sect->objfile;
228
 
229
  /* Pick up the instruction at pc.  It had better be of the
230
     form
231
     li r11, IDX
232
 
233
     where IDX is an index into the plt_table.  */
234
 
235
  if (target_read_memory (pc, buf, 4) != 0)
236
    return 0;
237
  insn = extract_unsigned_integer (buf, 4);
238
 
239
  if ((insn & 0xffff0000) != 0x39600000 /* li r11, VAL */ )
240
    return 0;
241
 
242
  reloc_index = (insn << 16) >> 16;
243
 
244
  /* Find the objfile that pc is in and obtain the information
245
     necessary for finding the symbol name. */
246
  for (sect = objfile->sections; sect < objfile->sections_end; ++sect)
247
    {
248
      const char *secname = sect->the_bfd_section->name;
249
      if (strcmp (secname, ".plt") == 0)
250
        plt_start = sect->addr;
251
      else if (strcmp (secname, ".rela.plt") == 0)
252
        num_slots = ((int) sect->endaddr - (int) sect->addr) / 12;
253
      else if (strcmp (secname, ".dynsym") == 0)
254
        symtab = sect->addr;
255
      else if (strcmp (secname, ".dynstr") == 0)
256
        strtab = sect->addr;
257
    }
258
 
259
  /* Make sure we have all the information we need. */
260
  if (plt_start == 0 || num_slots == -1 || symtab == 0 || strtab == 0)
261
    return 0;
262
 
263
  /* Compute the value of the plt table */
264
  plt_table = plt_start + 72 + 8 * num_slots;
265
 
266
  /* Get address of the relocation entry (Elf32_Rela) */
267
  if (target_read_memory (plt_table + reloc_index, buf, 4) != 0)
268
    return 0;
269
  reloc = extract_address (buf, 4);
270
 
271
  sect = find_pc_section (reloc);
272
  if (!sect)
273
    return 0;
274
 
275
  if (strcmp (sect->the_bfd_section->name, ".text") == 0)
276
    return reloc;
277
 
278
  /* Now get the r_info field which is the relocation type and symbol
279
     index. */
280
  if (target_read_memory (reloc + 4, buf, 4) != 0)
281
    return 0;
282
  symidx = extract_unsigned_integer (buf, 4);
283
 
284
  /* Shift out the relocation type leaving just the symbol index */
285
  /* symidx = ELF32_R_SYM(symidx); */
286
  symidx = symidx >> 8;
287
 
288
  /* compute the address of the symbol */
289
  sym = symtab + symidx * 4;
290
 
291
  /* Fetch the string table index */
292
  if (target_read_memory (sym, buf, 4) != 0)
293
    return 0;
294
  symidx = extract_unsigned_integer (buf, 4);
295
 
296
  /* Fetch the string; we don't know how long it is.  Is it possible
297
     that the following will fail because we're trying to fetch too
298
     much? */
299
  if (target_read_memory (strtab + symidx, symname, sizeof (symname)) != 0)
300
    return 0;
301
 
302
  /* This might not work right if we have multiple symbols with the
303
     same name; the only way to really get it right is to perform
304
     the same sort of lookup as the dynamic linker. */
305
  msymbol = lookup_minimal_symbol_text (symname, NULL, NULL);
306
  if (!msymbol)
307
    return 0;
308
 
309
  return SYMBOL_VALUE_ADDRESS (msymbol);
310
}
311
 
312
/* The rs6000 version of FRAME_SAVED_PC will almost work for us.  The
313
   signal handler details are different, so we'll handle those here
314
   and call the rs6000 version to do the rest. */
315
CORE_ADDR
316
ppc_linux_frame_saved_pc (struct frame_info *fi)
317
{
318
  if (fi->signal_handler_caller)
319
    {
320
      CORE_ADDR regs_addr =
321
        read_memory_integer (fi->frame + PPC_LINUX_REGS_PTR_OFFSET, 4);
322
      /* return the NIP in the regs array */
323
      return read_memory_integer (regs_addr + 4 * PPC_LINUX_PT_NIP, 4);
324
    }
325
  else if (fi->next && fi->next->signal_handler_caller)
326
    {
327
      CORE_ADDR regs_addr =
328
        read_memory_integer (fi->next->frame + PPC_LINUX_REGS_PTR_OFFSET, 4);
329
      /* return LNK in the regs array */
330
      return read_memory_integer (regs_addr + 4 * PPC_LINUX_PT_LNK, 4);
331
    }
332
  else
333
    return rs6000_frame_saved_pc (fi);
334
}
335
 
336
void
337
ppc_linux_init_extra_frame_info (int fromleaf, struct frame_info *fi)
338
{
339
  rs6000_init_extra_frame_info (fromleaf, fi);
340
 
341
  if (fi->next != 0)
342
    {
343
      /* We're called from get_prev_frame_info; check to see if
344
         this is a signal frame by looking to see if the pc points
345
         at trampoline code */
346
      if (ppc_linux_at_sigtramp_return_path (fi->pc))
347
        fi->signal_handler_caller = 1;
348
      else
349
        fi->signal_handler_caller = 0;
350
    }
351
}
352
 
353
int
354
ppc_linux_frameless_function_invocation (struct frame_info *fi)
355
{
356
  /* We'll find the wrong thing if we let
357
     rs6000_frameless_function_invocation () search for a signal trampoline */
358
  if (ppc_linux_at_sigtramp_return_path (fi->pc))
359
    return 0;
360
  else
361
    return rs6000_frameless_function_invocation (fi);
362
}
363
 
364
void
365
ppc_linux_frame_init_saved_regs (struct frame_info *fi)
366
{
367
  if (fi->signal_handler_caller)
368
    {
369
      CORE_ADDR regs_addr;
370
      int i;
371
      if (fi->saved_regs)
372
        return;
373
 
374
      frame_saved_regs_zalloc (fi);
375
 
376
      regs_addr =
377
        read_memory_integer (fi->frame + PPC_LINUX_REGS_PTR_OFFSET, 4);
378
      fi->saved_regs[PC_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_NIP;
379
      fi->saved_regs[PPC_PS_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_MSR;
380
      fi->saved_regs[PPC_CR_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_CCR;
381
      fi->saved_regs[PPC_LR_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_LNK;
382
      fi->saved_regs[PPC_CTR_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_CTR;
383
      fi->saved_regs[PPC_XER_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_XER;
384
      fi->saved_regs[PPC_MQ_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_MQ;
385
      for (i = 0; i < 32; i++)
386
        fi->saved_regs[PPC_GP0_REGNUM + i] = regs_addr + 4 * PPC_LINUX_PT_R0 + 4 * i;
387
      for (i = 0; i < 32; i++)
388
        fi->saved_regs[FP0_REGNUM + i] = regs_addr + 4 * PPC_LINUX_PT_FPR0 + 8 * i;
389
    }
390
  else
391
    rs6000_frame_init_saved_regs (fi);
392
}
393
 
394
CORE_ADDR
395
ppc_linux_frame_chain (struct frame_info *thisframe)
396
{
397
  /* Kernel properly constructs the frame chain for the handler */
398
  if (thisframe->signal_handler_caller)
399
    return read_memory_integer ((thisframe)->frame, 4);
400
  else
401
    return rs6000_frame_chain (thisframe);
402
}
403
 
404
/* FIXME: Move the following to rs6000-tdep.c (or some other file where
405
   it may be used generically by ports which use either the SysV ABI or
406
   the EABI */
407
 
408
/* round2 rounds x up to the nearest multiple of s assuming that s is a
409
   power of 2 */
410
 
411
#undef round2
412
#define round2(x,s) ((((long) (x) - 1) & ~(long)((s)-1)) + (s))
413
 
414
/* Pass the arguments in either registers, or in the stack. Using the
415
   ppc sysv ABI, the first eight words of the argument list (that might
416
   be less than eight parameters if some parameters occupy more than one
417
   word) are passed in r3..r10 registers.  float and double parameters are
418
   passed in fpr's, in addition to that. Rest of the parameters if any
419
   are passed in user stack.
420
 
421
   If the function is returning a structure, then the return address is passed
422
   in r3, then the first 7 words of the parametes can be passed in registers,
423
   starting from r4. */
424
 
425
CORE_ADDR
426
ppc_sysv_abi_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
427
                             int struct_return, CORE_ADDR struct_addr)
428
{
429
  int argno;
430
  int greg, freg;
431
  int argstkspace;
432
  int structstkspace;
433
  int argoffset;
434
  int structoffset;
435
  value_ptr arg;
436
  struct type *type;
437
  int len;
438
  char old_sp_buf[4];
439
  CORE_ADDR saved_sp;
440
 
441
  greg = struct_return ? 4 : 3;
442
  freg = 1;
443
  argstkspace = 0;
444
  structstkspace = 0;
445
 
446
  /* Figure out how much new stack space is required for arguments
447
     which don't fit in registers.  Unlike the PowerOpen ABI, the
448
     SysV ABI doesn't reserve any extra space for parameters which
449
     are put in registers. */
450
  for (argno = 0; argno < nargs; argno++)
451
    {
452
      arg = args[argno];
453
      type = check_typedef (VALUE_TYPE (arg));
454
      len = TYPE_LENGTH (type);
455
 
456
      if (TYPE_CODE (type) == TYPE_CODE_FLT)
457
        {
458
          if (freg <= 8)
459
            freg++;
460
          else
461
            {
462
              /* SysV ABI converts floats to doubles when placed in
463
                 memory and requires 8 byte alignment */
464
              if (argstkspace & 0x4)
465
                argstkspace += 4;
466
              argstkspace += 8;
467
            }
468
        }
469
      else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8)   /* long long */
470
        {
471
          if (greg > 9)
472
            {
473
              greg = 11;
474
              if (argstkspace & 0x4)
475
                argstkspace += 4;
476
              argstkspace += 8;
477
            }
478
          else
479
            {
480
              if ((greg & 1) == 0)
481
                greg++;
482
              greg += 2;
483
            }
484
        }
485
      else
486
        {
487
          if (len > 4
488
              || TYPE_CODE (type) == TYPE_CODE_STRUCT
489
              || TYPE_CODE (type) == TYPE_CODE_UNION)
490
            {
491
              /* Rounding to the nearest multiple of 8 may not be necessary,
492
                 but it is safe.  Particularly since we don't know the
493
                 field types of the structure */
494
              structstkspace += round2 (len, 8);
495
            }
496
          if (greg <= 10)
497
            greg++;
498
          else
499
            argstkspace += 4;
500
        }
501
    }
502
 
503
  /* Get current SP location */
504
  saved_sp = read_sp ();
505
 
506
  sp -= argstkspace + structstkspace;
507
 
508
  /* Allocate space for backchain and callee's saved lr */
509
  sp -= 8;
510
 
511
  /* Make sure that we maintain 16 byte alignment */
512
  sp &= ~0x0f;
513
 
514
  /* Update %sp before proceeding any further */
515
  write_register (SP_REGNUM, sp);
516
 
517
  /* write the backchain */
518
  store_address (old_sp_buf, 4, saved_sp);
519
  write_memory (sp, old_sp_buf, 4);
520
 
521
  argoffset = 8;
522
  structoffset = argoffset + argstkspace;
523
  freg = 1;
524
  greg = 3;
525
  /* Fill in r3 with the return structure, if any */
526
  if (struct_return)
527
    {
528
      char val_buf[4];
529
      store_address (val_buf, 4, struct_addr);
530
      memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
531
      greg++;
532
    }
533
  /* Now fill in the registers and stack... */
534
  for (argno = 0; argno < nargs; argno++)
535
    {
536
      arg = args[argno];
537
      type = check_typedef (VALUE_TYPE (arg));
538
      len = TYPE_LENGTH (type);
539
 
540
      if (TYPE_CODE (type) == TYPE_CODE_FLT)
541
        {
542
          if (freg <= 8)
543
            {
544
              if (len > 8)
545
                printf_unfiltered (
546
                                    "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
547
              memcpy (&registers[REGISTER_BYTE (FP0_REGNUM + freg)],
548
                      VALUE_CONTENTS (arg), len);
549
              freg++;
550
            }
551
          else
552
            {
553
              /* SysV ABI converts floats to doubles when placed in
554
                 memory and requires 8 byte alignment */
555
              /* FIXME: Convert floats to doubles */
556
              if (argoffset & 0x4)
557
                argoffset += 4;
558
              write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
559
              argoffset += 8;
560
            }
561
        }
562
      else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8)   /* long long */
563
        {
564
          if (greg > 9)
565
            {
566
              greg = 11;
567
              if (argoffset & 0x4)
568
                argoffset += 4;
569
              write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
570
              argoffset += 8;
571
            }
572
          else
573
            {
574
              if ((greg & 1) == 0)
575
                greg++;
576
 
577
              memcpy (&registers[REGISTER_BYTE (greg)],
578
                      VALUE_CONTENTS (arg), 4);
579
              memcpy (&registers[REGISTER_BYTE (greg + 1)],
580
                      VALUE_CONTENTS (arg) + 4, 4);
581
              greg += 2;
582
            }
583
        }
584
      else
585
        {
586
          char val_buf[4];
587
          if (len > 4
588
              || TYPE_CODE (type) == TYPE_CODE_STRUCT
589
              || TYPE_CODE (type) == TYPE_CODE_UNION)
590
            {
591
              write_memory (sp + structoffset, VALUE_CONTENTS (arg), len);
592
              store_address (val_buf, 4, sp + structoffset);
593
              structoffset += round2 (len, 8);
594
            }
595
          else
596
            {
597
              memset (val_buf, 0, 4);
598
              memcpy (val_buf, VALUE_CONTENTS (arg), len);
599
            }
600
          if (greg <= 10)
601
            {
602
              *(int *) &registers[REGISTER_BYTE (greg)] = 0;
603
              memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
604
              greg++;
605
            }
606
          else
607
            {
608
              write_memory (sp + argoffset, val_buf, 4);
609
              argoffset += 4;
610
            }
611
        }
612
    }
613
 
614
  target_store_registers (-1);
615
  return sp;
616
}
617
 
618
/* ppc_linux_memory_remove_breakpoints attempts to remove a breakpoint
619
   in much the same fashion as memory_remove_breakpoint in mem-break.c,
620
   but is careful not to write back the previous contents if the code
621
   in question has changed in between inserting the breakpoint and
622
   removing it.
623
 
624
   Here is the problem that we're trying to solve...
625
 
626
   Once upon a time, before introducing this function to remove
627
   breakpoints from the inferior, setting a breakpoint on a shared
628
   library function prior to running the program would not work
629
   properly.  In order to understand the problem, it is first
630
   necessary to understand a little bit about dynamic linking on
631
   this platform.
632
 
633
   A call to a shared library function is accomplished via a bl
634
   (branch-and-link) instruction whose branch target is an entry
635
   in the procedure linkage table (PLT).  The PLT in the object
636
   file is uninitialized.  To gdb, prior to running the program, the
637
   entries in the PLT are all zeros.
638
 
639
   Once the program starts running, the shared libraries are loaded
640
   and the procedure linkage table is initialized, but the entries in
641
   the table are not (necessarily) resolved.  Once a function is
642
   actually called, the code in the PLT is hit and the function is
643
   resolved.  In order to better illustrate this, an example is in
644
   order; the following example is from the gdb testsuite.
645
 
646
        We start the program shmain.
647
 
648
            [kev@arroyo testsuite]$ ../gdb gdb.base/shmain
649
            [...]
650
 
651
        We place two breakpoints, one on shr1 and the other on main.
652
 
653
            (gdb) b shr1
654
            Breakpoint 1 at 0x100409d4
655
            (gdb) b main
656
            Breakpoint 2 at 0x100006a0: file gdb.base/shmain.c, line 44.
657
 
658
        Examine the instruction (and the immediatly following instruction)
659
        upon which the breakpoint was placed.  Note that the PLT entry
660
        for shr1 contains zeros.
661
 
662
            (gdb) x/2i 0x100409d4
663
            0x100409d4 <shr1>:      .long 0x0
664
            0x100409d8 <shr1+4>:    .long 0x0
665
 
666
        Now run 'til main.
667
 
668
            (gdb) r
669
            Starting program: gdb.base/shmain
670
            Breakpoint 1 at 0xffaf790: file gdb.base/shr1.c, line 19.
671
 
672
            Breakpoint 2, main ()
673
                at gdb.base/shmain.c:44
674
            44        g = 1;
675
 
676
        Examine the PLT again.  Note that the loading of the shared
677
        library has initialized the PLT to code which loads a constant
678
        (which I think is an index into the GOT) into r11 and then
679
        branchs a short distance to the code which actually does the
680
        resolving.
681
 
682
            (gdb) x/2i 0x100409d4
683
            0x100409d4 <shr1>:      li      r11,4
684
            0x100409d8 <shr1+4>:    b       0x10040984 <sg+4>
685
            (gdb) c
686
            Continuing.
687
 
688
            Breakpoint 1, shr1 (x=1)
689
                at gdb.base/shr1.c:19
690
            19        l = 1;
691
 
692
        Now we've hit the breakpoint at shr1.  (The breakpoint was
693
        reset from the PLT entry to the actual shr1 function after the
694
        shared library was loaded.) Note that the PLT entry has been
695
        resolved to contain a branch that takes us directly to shr1.
696
        (The real one, not the PLT entry.)
697
 
698
            (gdb) x/2i 0x100409d4
699
            0x100409d4 <shr1>:      b       0xffaf76c <shr1>
700
            0x100409d8 <shr1+4>:    b       0x10040984 <sg+4>
701
 
702
   The thing to note here is that the PLT entry for shr1 has been
703
   changed twice.
704
 
705
   Now the problem should be obvious.  GDB places a breakpoint (a
706
   trap instruction) on the zero value of the PLT entry for shr1.
707
   Later on, after the shared library had been loaded and the PLT
708
   initialized, GDB gets a signal indicating this fact and attempts
709
   (as it always does when it stops) to remove all the breakpoints.
710
 
711
   The breakpoint removal was causing the former contents (a zero
712
   word) to be written back to the now initialized PLT entry thus
713
   destroying a portion of the initialization that had occurred only a
714
   short time ago.  When execution continued, the zero word would be
715
   executed as an instruction an an illegal instruction trap was
716
   generated instead.  (0 is not a legal instruction.)
717
 
718
   The fix for this problem was fairly straightforward.  The function
719
   memory_remove_breakpoint from mem-break.c was copied to this file,
720
   modified slightly, and renamed to ppc_linux_memory_remove_breakpoint.
721
   In tm-linux.h, MEMORY_REMOVE_BREAKPOINT is defined to call this new
722
   function.
723
 
724
   The differences between ppc_linux_memory_remove_breakpoint () and
725
   memory_remove_breakpoint () are minor.  All that the former does
726
   that the latter does not is check to make sure that the breakpoint
727
   location actually contains a breakpoint (trap instruction) prior
728
   to attempting to write back the old contents.  If it does contain
729
   a trap instruction, we allow the old contents to be written back.
730
   Otherwise, we silently do nothing.
731
 
732
   The big question is whether memory_remove_breakpoint () should be
733
   changed to have the same functionality.  The downside is that more
734
   traffic is generated for remote targets since we'll have an extra
735
   fetch of a memory word each time a breakpoint is removed.
736
 
737
   For the time being, we'll leave this self-modifying-code-friendly
738
   version in ppc-linux-tdep.c, but it ought to be migrated somewhere
739
   else in the event that some other platform has similar needs with
740
   regard to removing breakpoints in some potentially self modifying
741
   code.  */
742
int
743
ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
744
{
745
  unsigned char *bp;
746
  int val;
747
  int bplen;
748
  char old_contents[BREAKPOINT_MAX];
749
 
750
  /* Determine appropriate breakpoint contents and size for this address.  */
751
  bp = BREAKPOINT_FROM_PC (&addr, &bplen);
752
  if (bp == NULL)
753
    error ("Software breakpoints not implemented for this target.");
754
 
755
  val = target_read_memory (addr, old_contents, bplen);
756
 
757
  /* If our breakpoint is no longer at the address, this means that the
758
     program modified the code on us, so it is wrong to put back the
759
     old value */
760
  if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
761
    val = target_write_memory (addr, contents_cache, bplen);
762
 
763
  return val;
764
}

powered by: WebSVN 2.1.0

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