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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [gdb/] [hppa-linux-tdep.c] - Blame information for rev 25

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 jlechner
/* Target-dependent code for GNU/Linux running on PA-RISC, for GDB.
2
 
3
   Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
#include "gdbcore.h"
22
#include "osabi.h"
23
#include "target.h"
24
#include "objfiles.h"
25
#include "solib-svr4.h"
26
#include "glibc-tdep.h"
27
#include "frame-unwind.h"
28
#include "trad-frame.h"
29
#include "dwarf2-frame.h"
30
#include "value.h"
31
#include "regset.h"
32
#include "regcache.h"
33
#include "hppa-tdep.h"
34
 
35
#include "elf/common.h"
36
 
37
#if 0
38
/* Convert DWARF register number REG to the appropriate register
39
   number used by GDB.  */
40
static int
41
hppa_dwarf_reg_to_regnum (int reg)
42
{
43
  /* registers 0 - 31 are the same in both sets */
44
  if (reg < 32)
45
    return reg;
46
 
47
  /* dwarf regs 32 to 85 are fpregs 4 - 31 */
48
  if (reg >= 32 && reg <= 85)
49
    return HPPA_FP4_REGNUM + (reg - 32);
50
 
51
  warning (_("Unmapped DWARF Register #%d encountered."), reg);
52
  return -1;
53
}
54
#endif
55
 
56
static void
57
hppa_linux_target_write_pc (struct regcache *regcache, CORE_ADDR v)
58
{
59
  /* Probably this should be done by the kernel, but it isn't.  */
60
  regcache_cooked_write_unsigned (regcache, HPPA_PCOQ_HEAD_REGNUM, v | 0x3);
61
  regcache_cooked_write_unsigned (regcache, HPPA_PCOQ_TAIL_REGNUM, (v + 4) | 0x3);
62
}
63
 
64
/* An instruction to match.  */
65
struct insn_pattern
66
{
67
  unsigned int data;            /* See if it matches this....  */
68
  unsigned int mask;            /* ... with this mask.  */
69
};
70
 
71
static struct insn_pattern hppa_sigtramp[] = {
72
  /* ldi 0, %r25 or ldi 1, %r25 */
73
  { 0x34190000, 0xfffffffd },
74
  /* ldi __NR_rt_sigreturn, %r20 */
75
  { 0x3414015a, 0xffffffff },
76
  /* be,l 0x100(%sr2, %r0), %sr0, %r31 */
77
  { 0xe4008200, 0xffffffff },
78
  /* nop */
79
  { 0x08000240, 0xffffffff },
80
  { 0, 0 }
81
};
82
 
83
#define HPPA_MAX_INSN_PATTERN_LEN (4)
84
 
85
/* Return non-zero if the instructions at PC match the series
86
   described in PATTERN, or zero otherwise.  PATTERN is an array of
87
   'struct insn_pattern' objects, terminated by an entry whose mask is
88
   zero.
89
 
90
   When the match is successful, fill INSN[i] with what PATTERN[i]
91
   matched.  */
92
static int
93
insns_match_pattern (CORE_ADDR pc,
94
                     struct insn_pattern *pattern,
95
                     unsigned int *insn)
96
{
97
  int i;
98
  CORE_ADDR npc = pc;
99
 
100
  for (i = 0; pattern[i].mask; i++)
101
    {
102
      char buf[4];
103
 
104
      read_memory_nobpt (npc, buf, 4);
105
      insn[i] = extract_unsigned_integer (buf, 4);
106
      if ((insn[i] & pattern[i].mask) == pattern[i].data)
107
        npc += 4;
108
      else
109
        return 0;
110
    }
111
  return 1;
112
}
113
 
114
/* Signal frames.  */
115
 
116
/* (This is derived from MD_FALLBACK_FRAME_STATE_FOR in gcc.)
117
 
118
   Unfortunately, because of various bugs and changes to the kernel,
119
   we have several cases to deal with.
120
 
121
   In 2.4, the signal trampoline is 4 bytes, and pc should point directly at
122
   the beginning of the trampoline and struct rt_sigframe.
123
 
124
   In <= 2.6.5-rc2-pa3, the signal trampoline is 9 bytes, and pc points at
125
   the 4th word in the trampoline structure.  This is wrong, it should point
126
   at the 5th word.  This is fixed in 2.6.5-rc2-pa4.
127
 
128
   To detect these cases, we first take pc, align it to 64-bytes
129
   to get the beginning of the signal frame, and then check offsets 0, 4
130
   and 5 to see if we found the beginning of the trampoline.  This will
131
   tell us how to locate the sigcontext structure.
132
 
133
   Note that with a 2.4 64-bit kernel, the signal context is not properly
134
   passed back to userspace so the unwind will not work correctly.  */
135
static CORE_ADDR
136
hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc)
137
{
138
  unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN];
139
  int offs = 0;
140
  int try;
141
  /* offsets to try to find the trampoline */
142
  static int pcoffs[] = { 0, 4*4, 5*4 };
143
  /* offsets to the rt_sigframe structure */
144
  static int sfoffs[] = { 4*4, 10*4, 10*4 };
145
  CORE_ADDR sp;
146
 
147
  /* Most of the time, this will be correct.  The one case when this will
148
     fail is if the user defined an alternate stack, in which case the
149
     beginning of the stack will not be align_down (pc, 64).  */
150
  sp = align_down (pc, 64);
151
 
152
  /* rt_sigreturn trampoline:
153
     3419000x ldi 0, %r25 or ldi 1, %r25   (x = 0 or 2)
154
     3414015a ldi __NR_rt_sigreturn, %r20
155
     e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31
156
     08000240 nop  */
157
 
158
  for (try = 0; try < ARRAY_SIZE (pcoffs); try++)
159
    {
160
      if (insns_match_pattern (sp + pcoffs[try], hppa_sigtramp, dummy))
161
        {
162
          offs = sfoffs[try];
163
          break;
164
        }
165
    }
166
 
167
  if (offs == 0)
168
    {
169
      if (insns_match_pattern (pc, hppa_sigtramp, dummy))
170
        {
171
          /* sigaltstack case: we have no way of knowing which offset to
172
             use in this case; default to new kernel handling. If this is
173
             wrong the unwinding will fail.  */
174
          try = 2;
175
          sp = pc - pcoffs[try];
176
        }
177
      else
178
      {
179
        return 0;
180
      }
181
    }
182
 
183
  /* sp + sfoffs[try] points to a struct rt_sigframe, which contains
184
     a struct siginfo and a struct ucontext.  struct ucontext contains
185
     a struct sigcontext. Return an offset to this sigcontext here.  Too
186
     bad we cannot include system specific headers :-(.
187
     sizeof(struct siginfo) == 128
188
     offsetof(struct ucontext, uc_mcontext) == 24.  */
189
  return sp + sfoffs[try] + 128 + 24;
190
}
191
 
192
struct hppa_linux_sigtramp_unwind_cache
193
{
194
  CORE_ADDR base;
195
  struct trad_frame_saved_reg *saved_regs;
196
};
197
 
198
static struct hppa_linux_sigtramp_unwind_cache *
199
hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
200
                                        void **this_cache)
201
{
202
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
203
  struct hppa_linux_sigtramp_unwind_cache *info;
204
  CORE_ADDR pc, scptr;
205
  int i;
206
 
207
  if (*this_cache)
208
    return *this_cache;
209
 
210
  info = FRAME_OBSTACK_ZALLOC (struct hppa_linux_sigtramp_unwind_cache);
211
  *this_cache = info;
212
  info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
213
 
214
  pc = frame_pc_unwind (next_frame);
215
  scptr = hppa_linux_sigtramp_find_sigcontext (pc);
216
 
217
  /* structure of struct sigcontext:
218
 
219
     struct sigcontext {
220
        unsigned long sc_flags;
221
        unsigned long sc_gr[32];
222
        unsigned long long sc_fr[32];
223
        unsigned long sc_iasq[2];
224
        unsigned long sc_iaoq[2];
225
        unsigned long sc_sar;           */
226
 
227
  /* Skip sc_flags.  */
228
  scptr += 4;
229
 
230
  /* GR[0] is the psw, we don't restore that.  */
231
  scptr += 4;
232
 
233
  /* General registers.  */
234
  for (i = 1; i < 32; i++)
235
    {
236
      info->saved_regs[HPPA_R0_REGNUM + i].addr = scptr;
237
      scptr += 4;
238
    }
239
 
240
  /* Pad.  */
241
  scptr += 4;
242
 
243
  /* FP regs; FP0-3 are not restored.  */
244
  scptr += (8 * 4);
245
 
246
  for (i = 4; i < 32; i++)
247
    {
248
      info->saved_regs[HPPA_FP0_REGNUM + (i * 2)].addr = scptr;
249
      scptr += 4;
250
      info->saved_regs[HPPA_FP0_REGNUM + (i * 2) + 1].addr = scptr;
251
      scptr += 4;
252
    }
253
 
254
  /* IASQ/IAOQ. */
255
  info->saved_regs[HPPA_PCSQ_HEAD_REGNUM].addr = scptr;
256
  scptr += 4;
257
  info->saved_regs[HPPA_PCSQ_TAIL_REGNUM].addr = scptr;
258
  scptr += 4;
259
 
260
  info->saved_regs[HPPA_PCOQ_HEAD_REGNUM].addr = scptr;
261
  scptr += 4;
262
  info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].addr = scptr;
263
  scptr += 4;
264
 
265
  info->base = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
266
 
267
  return info;
268
}
269
 
270
static void
271
hppa_linux_sigtramp_frame_this_id (struct frame_info *next_frame,
272
                                   void **this_prologue_cache,
273
                                   struct frame_id *this_id)
274
{
275
  struct hppa_linux_sigtramp_unwind_cache *info
276
    = hppa_linux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
277
  *this_id = frame_id_build (info->base, frame_pc_unwind (next_frame));
278
}
279
 
280
static void
281
hppa_linux_sigtramp_frame_prev_register (struct frame_info *next_frame,
282
                                         void **this_prologue_cache,
283
                                         int regnum, int *optimizedp,
284
                                         enum lval_type *lvalp,
285
                                         CORE_ADDR *addrp,
286
                                         int *realnump, gdb_byte *valuep)
287
{
288
  struct hppa_linux_sigtramp_unwind_cache *info
289
    = hppa_linux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
290
  hppa_frame_prev_register_helper (next_frame, info->saved_regs, regnum,
291
                                   optimizedp, lvalp, addrp, realnump, valuep);
292
}
293
 
294
static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
295
  SIGTRAMP_FRAME,
296
  hppa_linux_sigtramp_frame_this_id,
297
  hppa_linux_sigtramp_frame_prev_register
298
};
299
 
300
/* hppa-linux always uses "new-style" rt-signals.  The signal handler's return
301
   address should point to a signal trampoline on the stack.  The signal
302
   trampoline is embedded in a rt_sigframe structure that is aligned on
303
   the stack.  We take advantage of the fact that sp must be 64-byte aligned,
304
   and the trampoline is small, so by rounding down the trampoline address
305
   we can find the beginning of the struct rt_sigframe.  */
306
static const struct frame_unwind *
307
hppa_linux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
308
{
309
  CORE_ADDR pc = frame_pc_unwind (next_frame);
310
 
311
  if (hppa_linux_sigtramp_find_sigcontext (pc))
312
    return &hppa_linux_sigtramp_frame_unwind;
313
 
314
  return NULL;
315
}
316
 
317
/* Attempt to find (and return) the global pointer for the given
318
   function.
319
 
320
   This is a rather nasty bit of code searchs for the .dynamic section
321
   in the objfile corresponding to the pc of the function we're trying
322
   to call.  Once it finds the addresses at which the .dynamic section
323
   lives in the child process, it scans the Elf32_Dyn entries for a
324
   DT_PLTGOT tag.  If it finds one of these, the corresponding
325
   d_un.d_ptr value is the global pointer.  */
326
 
327
static CORE_ADDR
328
hppa_linux_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
329
{
330
  struct obj_section *faddr_sect;
331
  CORE_ADDR faddr;
332
 
333
  faddr = value_as_address (function);
334
 
335
  /* Is this a plabel? If so, dereference it to get the gp value.  */
336
  if (faddr & 2)
337
    {
338
      int status;
339
      char buf[4];
340
 
341
      faddr &= ~3;
342
 
343
      status = target_read_memory (faddr + 4, buf, sizeof (buf));
344
      if (status == 0)
345
        return extract_unsigned_integer (buf, sizeof (buf));
346
    }
347
 
348
  /* If the address is in the plt section, then the real function hasn't
349
     yet been fixed up by the linker so we cannot determine the gp of
350
     that function.  */
351
  if (in_plt_section (faddr, NULL))
352
    return 0;
353
 
354
  faddr_sect = find_pc_section (faddr);
355
  if (faddr_sect != NULL)
356
    {
357
      struct obj_section *osect;
358
 
359
      ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
360
        {
361
          if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
362
            break;
363
        }
364
 
365
      if (osect < faddr_sect->objfile->sections_end)
366
        {
367
          CORE_ADDR addr;
368
 
369
          addr = osect->addr;
370
          while (addr < osect->endaddr)
371
            {
372
              int status;
373
              LONGEST tag;
374
              char buf[4];
375
 
376
              status = target_read_memory (addr, buf, sizeof (buf));
377
              if (status != 0)
378
                break;
379
              tag = extract_signed_integer (buf, sizeof (buf));
380
 
381
              if (tag == DT_PLTGOT)
382
                {
383
                  CORE_ADDR global_pointer;
384
 
385
                  status = target_read_memory (addr + 4, buf, sizeof (buf));
386
                  if (status != 0)
387
                    break;
388
                  global_pointer = extract_unsigned_integer (buf, sizeof (buf));
389
 
390
                  /* The payoff... */
391
                  return global_pointer;
392
                }
393
 
394
              if (tag == DT_NULL)
395
                break;
396
 
397
              addr += 8;
398
            }
399
        }
400
    }
401
  return 0;
402
}
403
 
404
/*
405
 * Registers saved in a coredump:
406
 * gr0..gr31
407
 * sr0..sr7
408
 * iaoq0..iaoq1
409
 * iasq0..iasq1
410
 * sar, iir, isr, ior, ipsw
411
 * cr0, cr24..cr31
412
 * cr8,9,12,13
413
 * cr10, cr15
414
 */
415
 
416
#define GR_REGNUM(_n)   (HPPA_R0_REGNUM+_n)
417
#define TR_REGNUM(_n)   (HPPA_TR0_REGNUM+_n)
418
static const int greg_map[] =
419
  {
420
    GR_REGNUM(0), GR_REGNUM(1), GR_REGNUM(2), GR_REGNUM(3),
421
    GR_REGNUM(4), GR_REGNUM(5), GR_REGNUM(6), GR_REGNUM(7),
422
    GR_REGNUM(8), GR_REGNUM(9), GR_REGNUM(10), GR_REGNUM(11),
423
    GR_REGNUM(12), GR_REGNUM(13), GR_REGNUM(14), GR_REGNUM(15),
424
    GR_REGNUM(16), GR_REGNUM(17), GR_REGNUM(18), GR_REGNUM(19),
425
    GR_REGNUM(20), GR_REGNUM(21), GR_REGNUM(22), GR_REGNUM(23),
426
    GR_REGNUM(24), GR_REGNUM(25), GR_REGNUM(26), GR_REGNUM(27),
427
    GR_REGNUM(28), GR_REGNUM(29), GR_REGNUM(30), GR_REGNUM(31),
428
 
429
    HPPA_SR4_REGNUM+1, HPPA_SR4_REGNUM+2, HPPA_SR4_REGNUM+3, HPPA_SR4_REGNUM+4,
430
    HPPA_SR4_REGNUM, HPPA_SR4_REGNUM+5, HPPA_SR4_REGNUM+6, HPPA_SR4_REGNUM+7,
431
 
432
    HPPA_PCOQ_HEAD_REGNUM, HPPA_PCOQ_TAIL_REGNUM,
433
    HPPA_PCSQ_HEAD_REGNUM, HPPA_PCSQ_TAIL_REGNUM,
434
 
435
    HPPA_SAR_REGNUM, HPPA_IIR_REGNUM, HPPA_ISR_REGNUM, HPPA_IOR_REGNUM,
436
    HPPA_IPSW_REGNUM, HPPA_RCR_REGNUM,
437
 
438
    TR_REGNUM(0), TR_REGNUM(1), TR_REGNUM(2), TR_REGNUM(3),
439
    TR_REGNUM(4), TR_REGNUM(5), TR_REGNUM(6), TR_REGNUM(7),
440
 
441
    HPPA_PID0_REGNUM, HPPA_PID1_REGNUM, HPPA_PID2_REGNUM, HPPA_PID3_REGNUM,
442
    HPPA_CCR_REGNUM, HPPA_EIEM_REGNUM,
443
  };
444
 
445
static void
446
hppa_linux_supply_regset (const struct regset *regset,
447
                          struct regcache *regcache,
448
                          int regnum, const void *regs, size_t len)
449
{
450
  struct gdbarch *arch = get_regcache_arch (regcache);
451
  struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
452
  const char *buf = regs;
453
  int i, offset;
454
 
455
  offset = 0;
456
  for (i = 0; i < ARRAY_SIZE (greg_map); i++)
457
    {
458
      if (regnum == greg_map[i] || regnum == -1)
459
        regcache_raw_supply (regcache, greg_map[i], buf + offset);
460
 
461
      offset += tdep->bytes_per_address;
462
    }
463
}
464
 
465
static void
466
hppa_linux_supply_fpregset (const struct regset *regset,
467
                            struct regcache *regcache,
468
                            int regnum, const void *regs, size_t len)
469
{
470
  const char *buf = regs;
471
  int i, offset;
472
 
473
  offset = 0;
474
  for (i = 0; i < 31; i++)
475
    {
476
      if (regnum == HPPA_FP0_REGNUM + i || regnum == -1)
477
        regcache_raw_supply (regcache, HPPA_FP0_REGNUM + i,
478
                             buf + offset);
479
      offset += 8;
480
    }
481
}
482
 
483
/* HPPA Linux kernel register set.  */
484
static struct regset hppa_linux_regset =
485
{
486
  NULL,
487
  hppa_linux_supply_regset
488
};
489
 
490
static struct regset hppa_linux_fpregset =
491
{
492
  NULL,
493
  hppa_linux_supply_fpregset
494
};
495
 
496
static const struct regset *
497
hppa_linux_regset_from_core_section (struct gdbarch *gdbarch,
498
                                     const char *sect_name,
499
                                     size_t sect_size)
500
{
501
  if (strcmp (sect_name, ".reg") == 0)
502
    return &hppa_linux_regset;
503
  else if (strcmp (sect_name, ".reg2") == 0)
504
    return &hppa_linux_fpregset;
505
 
506
  return NULL;
507
}
508
 
509
 
510
/* Forward declarations.  */
511
extern initialize_file_ftype _initialize_hppa_linux_tdep;
512
 
513
static void
514
hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
515
{
516
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
517
 
518
  /* GNU/Linux is always ELF.  */
519
  tdep->is_elf = 1;
520
 
521
  tdep->find_global_pointer = hppa_linux_find_global_pointer;
522
 
523
  set_gdbarch_write_pc (gdbarch, hppa_linux_target_write_pc);
524
 
525
  frame_unwind_append_sniffer (gdbarch, hppa_linux_sigtramp_unwind_sniffer);
526
 
527
  /* GNU/Linux uses SVR4-style shared libraries.  */
528
  set_solib_svr4_fetch_link_map_offsets
529
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
530
 
531
  tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
532
  set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
533
 
534
  /* GNU/Linux uses the dynamic linker included in the GNU C Library.  */
535
  set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
536
 
537
  /* On hppa-linux, currently, sizeof(long double) == 8.  There has been
538
     some discussions to support 128-bit long double, but it requires some
539
     more work in gcc and glibc first.  */
540
  set_gdbarch_long_double_bit (gdbarch, 64);
541
 
542
  set_gdbarch_regset_from_core_section
543
    (gdbarch, hppa_linux_regset_from_core_section);
544
 
545
#if 0
546
  /* Dwarf-2 unwinding support.  Not yet working.  */
547
  set_gdbarch_dwarf_reg_to_regnum (gdbarch, hppa_dwarf_reg_to_regnum);
548
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, hppa_dwarf_reg_to_regnum);
549
  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
550
  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
551
#endif
552
 
553
  /* Enable TLS support.  */
554
  set_gdbarch_fetch_tls_load_module_address (gdbarch,
555
                                             svr4_fetch_objfile_link_map);
556
}
557
 
558
void
559
_initialize_hppa_linux_tdep (void)
560
{
561
  gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_LINUX, hppa_linux_init_abi);
562
  gdbarch_register_osabi (bfd_arch_hppa, bfd_mach_hppa20w, GDB_OSABI_LINUX, hppa_linux_init_abi);
563
}

powered by: WebSVN 2.1.0

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