1 /* Target-dependent code for HP PA-RISC BSD's.
3 Copyright 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 #include "arch-utils.h"
32 #include "gdb_assert.h"
33 #include "gdb_string.h"
35 #include "elf/common.h"
37 #include "hppa-tdep.h"
38 #include "solib-svr4.h"
40 /* Core file support. */
42 /* Sizeof `struct reg' in <machine/reg.h>. */
43 #define HPPABSD_SIZEOF_GREGS (34 * 4)
45 /* Supply register REGNUM from the buffer specified by GREGS and LEN
46 in the general-purpose register set REGSET to register cache
47 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
50 hppabsd_supply_gregset (const struct regset
*regset
, struct regcache
*regcache
,
51 int regnum
, const void *gregs
, size_t len
)
53 const gdb_byte
*regs
= gregs
;
57 gdb_assert (len
>= HPPABSD_SIZEOF_GREGS
);
59 for (i
= HPPA_R1_REGNUM
, offset
= 4; i
<= HPPA_R31_REGNUM
; i
++, offset
+= 4)
61 if (regnum
== -1 || regnum
== i
)
62 regcache_raw_supply (regcache
, i
, regs
+ offset
);
65 if (regnum
== -1 || regnum
== HPPA_SAR_REGNUM
)
66 regcache_raw_supply (regcache
, HPPA_SAR_REGNUM
, regs
);
67 if (regnum
== -1 || regnum
== HPPA_PCOQ_HEAD_REGNUM
)
68 regcache_raw_supply (regcache
, HPPA_PCOQ_HEAD_REGNUM
, regs
+ 32 * 4);
69 if (regnum
== -1 || regnum
== HPPA_PCOQ_TAIL_REGNUM
)
70 regcache_raw_supply (regcache
, HPPA_PCOQ_TAIL_REGNUM
, regs
+ 33 * 4);
73 /* OpenBSD/hppa register set. */
75 static struct regset hppabsd_gregset
=
78 hppabsd_supply_gregset
81 /* Return the appropriate register set for the core section identified
82 by SECT_NAME and SECT_SIZE. */
84 static const struct regset
*
85 hppabsd_regset_from_core_section (struct gdbarch
*gdbarch
,
86 const char *sect_name
, size_t sect_size
)
88 if (strcmp (sect_name
, ".reg") == 0 && sect_size
>= HPPABSD_SIZEOF_GREGS
)
89 return &hppabsd_gregset
;
96 hppabsd_find_global_pointer (struct value
*function
)
98 CORE_ADDR faddr
= value_as_address (function
);
99 struct obj_section
*faddr_sec
;
102 /* Is this a plabel? If so, dereference it to get the Global Pointer
106 if (target_read_memory ((faddr
& ~3) + 4, buf
, sizeof buf
) == 0)
107 return extract_unsigned_integer (buf
, sizeof buf
);
110 /* If the address is in the .plt section, then the real function
111 hasn't yet been fixed up by the linker so we cannot determine the
112 Global Pointer for that function. */
113 if (in_plt_section (faddr
, NULL
))
116 faddr_sec
= find_pc_section (faddr
);
117 if (faddr_sec
!= NULL
)
119 struct obj_section
*sec
;
121 ALL_OBJFILE_OSECTIONS (faddr_sec
->objfile
, sec
)
123 if (strcmp (sec
->the_bfd_section
->name
, ".dynamic") == 0)
127 if (sec
< faddr_sec
->objfile
->sections_end
)
129 CORE_ADDR addr
= sec
->addr
;
131 while (addr
< sec
->endaddr
)
136 if (target_read_memory (addr
, buf
, sizeof buf
) != 0)
139 tag
= extract_signed_integer (buf
, sizeof buf
);
140 if (tag
== DT_PLTGOT
)
144 if (target_read_memory (addr
+ 4, buf
, sizeof buf
) != 0)
147 /* The OpenBSD ld.so doesn't relocate DT_PLTGOT, so
148 we have to do it ourselves. */
149 pltgot
= extract_unsigned_integer (buf
, sizeof buf
);
150 pltgot
+= ANOFFSET (sec
->objfile
->section_offsets
,
151 SECT_OFF_TEXT (sec
->objfile
));
168 hppabsd_init_abi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
170 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
172 /* Core file support. */
173 set_gdbarch_regset_from_core_section
174 (gdbarch
, hppabsd_regset_from_core_section
);
176 /* OpenBSD and NetBSD use ELF. */
177 tdep
->find_global_pointer
= hppabsd_find_global_pointer
;
180 /* OpenBSD and NetBSD uses SVR4-style shared libraries. */
181 set_solib_svr4_fetch_link_map_offsets
182 (gdbarch
, svr4_ilp32_fetch_link_map_offsets
);
186 /* OpenBSD uses uses the traditional NetBSD core file format, even for
187 ports that use ELF. */
188 #define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
190 static enum gdb_osabi
191 hppabsd_core_osabi_sniffer (bfd
*abfd
)
193 if (strcmp (bfd_get_target (abfd
), "netbsd-core") == 0)
194 return GDB_OSABI_NETBSD_CORE
;
196 return GDB_OSABI_UNKNOWN
;
200 /* Provide a prototype to silence -Wmissing-prototypes. */
201 void _initialize_hppabsd_tdep (void);
204 _initialize_hppabsd_tdep (void)
206 /* BFD doesn't set a flavour for NetBSD style a.out core files. */
207 gdbarch_register_osabi_sniffer (bfd_arch_hppa
, bfd_target_unknown_flavour
,
208 hppabsd_core_osabi_sniffer
);
210 gdbarch_register_osabi (bfd_arch_hppa
, 0, GDB_OSABI_NETBSD_ELF
,
212 gdbarch_register_osabi (bfd_arch_hppa
, 0, GDB_OSABI_OPENBSD_ELF
,