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