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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [gdb/] [ppc-linux-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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