* avr-tdep.c, hppa-tdep.c, hppabsd-tdep.c, i386-tdep.c,
[deliverable/binutils-gdb.git] / gdb / hppabsd-tdep.c
CommitLineData
0e56aeaf
MK
1/* Target-dependent code for HP PA-RISC BSD's.
2
6aba47ca 3 Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
0e56aeaf
MK
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 2 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, write to the Free Software
197e01b6
EZ
19 Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
0e56aeaf
MK
21
22#include "defs.h"
23#include "arch-utils.h"
e6bb342a 24#include "gdbtypes.h"
dc28f363
MK
25#include "symtab.h"
26#include "objfiles.h"
0e56aeaf
MK
27#include "osabi.h"
28#include "regcache.h"
29#include "regset.h"
dc28f363
MK
30#include "target.h"
31#include "value.h"
0e56aeaf
MK
32
33#include "gdb_assert.h"
34#include "gdb_string.h"
35
dc28f363
MK
36#include "elf/common.h"
37
0e56aeaf
MK
38#include "hppa-tdep.h"
39#include "solib-svr4.h"
40
41/* Core file support. */
42
43/* Sizeof `struct reg' in <machine/reg.h>. */
44#define HPPABSD_SIZEOF_GREGS (34 * 4)
45
46/* Supply register REGNUM from the buffer specified by GREGS and LEN
47 in the general-purpose register set REGSET to register cache
48 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
49
50static void
51hppabsd_supply_gregset (const struct regset *regset, struct regcache *regcache,
52 int regnum, const void *gregs, size_t len)
53{
dc28f363 54 const gdb_byte *regs = gregs;
0e56aeaf
MK
55 size_t offset;
56 int i;
57
58 gdb_assert (len >= HPPABSD_SIZEOF_GREGS);
59
60 for (i = HPPA_R1_REGNUM, offset = 4; i <= HPPA_R31_REGNUM; i++, offset += 4)
61 {
62 if (regnum == -1 || regnum == i)
63 regcache_raw_supply (regcache, i, regs + offset);
64 }
65
66 if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
67 regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
68 if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
69 regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
70 if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
71 regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
72}
73
74/* OpenBSD/hppa register set. */
75
76static struct regset hppabsd_gregset =
77{
78 NULL,
79 hppabsd_supply_gregset
80};
81
82/* Return the appropriate register set for the core section identified
83 by SECT_NAME and SECT_SIZE. */
84
85static const struct regset *
86hppabsd_regset_from_core_section (struct gdbarch *gdbarch,
87 const char *sect_name, size_t sect_size)
88{
89 if (strcmp (sect_name, ".reg") == 0 && sect_size >= HPPABSD_SIZEOF_GREGS)
90 return &hppabsd_gregset;
91
92 return NULL;
93}
94\f
95
dc28f363
MK
96CORE_ADDR
97hppabsd_find_global_pointer (struct value *function)
98{
99 CORE_ADDR faddr = value_as_address (function);
100 struct obj_section *faddr_sec;
101 gdb_byte buf[4];
102
103 /* Is this a plabel? If so, dereference it to get the Global Pointer
104 value. */
105 if (faddr & 2)
106 {
107 if (target_read_memory ((faddr & ~3) + 4, buf, sizeof buf) == 0)
108 return extract_unsigned_integer (buf, sizeof buf);
109 }
110
111 /* If the address is in the .plt section, then the real function
112 hasn't yet been fixed up by the linker so we cannot determine the
113 Global Pointer for that function. */
114 if (in_plt_section (faddr, NULL))
115 return 0;
116
117 faddr_sec = find_pc_section (faddr);
118 if (faddr_sec != NULL)
119 {
120 struct obj_section *sec;
121
122 ALL_OBJFILE_OSECTIONS (faddr_sec->objfile, sec)
123 {
124 if (strcmp (sec->the_bfd_section->name, ".dynamic") == 0)
125 break;
126 }
127
128 if (sec < faddr_sec->objfile->sections_end)
129 {
130 CORE_ADDR addr = sec->addr;
131
132 while (addr < sec->endaddr)
133 {
134 gdb_byte buf[4];
135 LONGEST tag;
136
137 if (target_read_memory (addr, buf, sizeof buf) != 0)
138 break;
139
140 tag = extract_signed_integer (buf, sizeof buf);
141 if (tag == DT_PLTGOT)
142 {
143 CORE_ADDR pltgot;
144
145 if (target_read_memory (addr + 4, buf, sizeof buf) != 0)
146 break;
147
148 /* The OpenBSD ld.so doesn't relocate DT_PLTGOT, so
149 we have to do it ourselves. */
150 pltgot = extract_unsigned_integer (buf, sizeof buf);
151 pltgot += ANOFFSET (sec->objfile->section_offsets,
152 SECT_OFF_TEXT (sec->objfile));
153 return pltgot;
154 }
155
156 if (tag == DT_NULL)
157 break;
158
159 addr += 8;
160 }
161 }
162 }
163
164 return 0;
165}
166\f
167
0e56aeaf
MK
168static void
169hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
170{
171 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
172
ed944ce7
MK
173 /* OpenBSD and NetBSD have a 64-bit 'long double'. */
174 set_gdbarch_long_double_bit (gdbarch, 64);
8da61cc4 175 set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
ed944ce7 176
0e56aeaf
MK
177 /* Core file support. */
178 set_gdbarch_regset_from_core_section
179 (gdbarch, hppabsd_regset_from_core_section);
180
181 /* OpenBSD and NetBSD use ELF. */
182 tdep->is_elf = 1;
34f55018
MK
183 tdep->find_global_pointer = hppabsd_find_global_pointer;
184 tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
185 set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
0e56aeaf 186
ed944ce7 187 /* OpenBSD and NetBSD use SVR4-style shared libraries. */
0e56aeaf
MK
188 set_solib_svr4_fetch_link_map_offsets
189 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
190}
191\f
192
193/* OpenBSD uses uses the traditional NetBSD core file format, even for
194 ports that use ELF. */
195#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
196
197static enum gdb_osabi
198hppabsd_core_osabi_sniffer (bfd *abfd)
199{
200 if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
201 return GDB_OSABI_NETBSD_CORE;
202
203 return GDB_OSABI_UNKNOWN;
204}
205\f
206
207/* Provide a prototype to silence -Wmissing-prototypes. */
208void _initialize_hppabsd_tdep (void);
209
210void
211_initialize_hppabsd_tdep (void)
212{
213 /* BFD doesn't set a flavour for NetBSD style a.out core files. */
214 gdbarch_register_osabi_sniffer (bfd_arch_hppa, bfd_target_unknown_flavour,
215 hppabsd_core_osabi_sniffer);
216
217 gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD_ELF,
218 hppabsd_init_abi);
219 gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_OPENBSD_ELF,
220 hppabsd_init_abi);
221}
This page took 0.3204 seconds and 4 git commands to generate.