+2016-11-22 Simon Marchi <simon.marchi@polymtl.ca>
+
+ * Makefile.in (ALL_64_TARGET_OBS, ALL_TARGET_OBS,
+ HFILES_NO_SRCDIR, ALLDEPFILES): Rename files.
+ * alphabsd-nat.c: Rename to ...
+ * alpha-bsd-nat.c: ... this, adjust include.
+ * alphabsd-tdep.c: Rename to ...
+ * alpha-bsd-tdep.c: ... this, adjust include.
+ * alphabsd-tdep.h: Rename to ...
+ * alpha-bsd-tdep.h: ... this, adjust include barrier and comment.
+ * alphafbsd-tdep.c: Rename to ...
+ * alpha-fbsd-tdep.c: ... this.
+ * alphanbsd-tdep.c: Rename to ...
+ * alpha-nbsd-tdep.c: ... this, adjust include.
+ * alphaobsd-tdep.c: Rename to ...
+ * alpha-obsd-tdep.c: ... this, adjust include.
+ * amd64bsd-nat.c: Rename to ...
+ * amd64-bsd-nat.c: ... this, adjust include.
+ * amd64fbsd-nat.c: Rename to ...
+ * amd64-fbsd-nat.c: ... this, adjust include.
+ * amd64fbsd-tdep.c: Rename to ...
+ * amd64-fbsd-tdep.c: ... this, adjust include.
+ * amd64nbsd-nat.c: Rename to ...
+ * amd64-nbsd-nat.c: ... this.
+ * amd64nbsd-tdep.c: Rename to ...
+ * amd64-nbsd-tdep.c: ... this.
+ * amd64obsd-nat.c: Rename to ...
+ * amd64-obsd-nat.c: ... this.
+ * amd64obsd-tdep.c: Rename to ...
+ * amd64-obsd-tdep.c: ... this.
+ * amd64-tdep.h: Update comments.
+ * armbsd-tdep.c: Rename to ...
+ * arm-bsd-tdep.c: ... this.
+ * armnbsd-nat.c: Rename to ...
+ * arm-nbsd-nat.c: ... this.
+ * armnbsd-tdep.c: Rename to ...
+ * arm-nbsd-tdep.c: ... this.
+ * armobsd-tdep.c: Rename to ...
+ * arm-obsd-tdep.c: ... this.
+ * arm-tdep.h: Update comments.
+ * hppabsd-tdep.c: Rename to ...
+ * hppa-bsd-tdep.c: ... this, adjust include.
+ * hppabsd-tdep.h: Rename to ...
+ * hppa-bsd-tdep.h: ... this, adjust include barrier and comment.
+ * hppanbsd-nat.c: Rename to ...
+ * hppa-nbsd-nat.c: ... this.
+ * hppanbsd-tdep.c: Rename to ...
+ * hppa-nbsd-tdep.c: ... this, adjust include.
+ * hppaobsd-nat.c: Rename to ...
+ * hppa-obsd-nat.c: ... this.
+ * hppaobsd-tdep.c: Rename to ...
+ * hppa-obsd-tdep.c: ... this, adjust include.
+ * i386bsd-nat.c: Rename to ...
+ * i386-bsd-nat.c: ... this, adjust include.
+ * i386bsd-nat.h: Rename to ...
+ * i386-bsd-nat.h: ... this, adjust include barrier and comment.
+ * i386bsd-tdep.c: Rename to ...
+ * i386-bsd-tdep.c: ... this.
+ * i386fbsd-nat.c: Rename to ...
+ * i386-fbsd-nat.c: ... this, adjust include.
+ * i386fbsd-tdep.c: Rename to ...
+ * i386-fbsd-tdep.c: ... this, adjust include.
+ * i386fbsd-tdep.h: Rename to ...
+ * i386-fbsd-tdep.h: ... this, adjust include barrier and comment.
+ * i386gnu-nat.c: Rename to ...
+ * i386-gnu-nat.c: ... this.
+ * i386gnu-tdep.c: Rename to ...
+ * i386-gnu-tdep.c: ... this.
+ * i386nbsd-nat.c: Rename to ...
+ * i386-nbsd-nat.c: ... this, adjust include.
+ * i386nbsd-tdep.c: Rename to ...
+ * i386-nbsd-tdep.c: ... this.
+ * i386obsd-nat.c: Rename to ...
+ * i386-obsd-nat.c: ... this, adjust include.
+ * i386obsd-tdep.c: Rename to ...
+ * i386-obsd-tdep.c: ... this.
+ * i386v4-nat.c: Rename to ...
+ * i386-v4-nat.c: ... this.
+ * i386-tdep.h: Update comments.
+ * m68k-tdep.h: Update comments.
+ * m68kbsd-nat.c: Rename to ...
+ * m68k-bsd-nat.c: ... this.
+ * m68kbsd-tdep.c: Rename to ...
+ * m68k-bsd-tdep.c: ... this.
+ * m68klinux-nat.c: Rename to ...
+ * m68k-linux-nat.c: ... this.
+ * m68klinux-tdep.c: Rename to ...
+ * m68k-linux-tdep.c: ... this.
+ * m88kbsd-nat.c: Rename to ...
+ * m88k-bsd-nat.c: ... this.
+ * mipsnbsd-nat.c: Rename to ...
+ * mips-nbsd-nat.c: ... this, adjust include.
+ * mipsnbsd-tdep.c: Rename to ...
+ * mips-nbsd-tdep.c: ... this, adjust include.
+ * mipsnbsd-tdep.h: Rename to ...
+ * mips-nbsd-tdep.h: ... this, adjust include barrier and comment.
+ * mips64obsd-nat.c: Rename to ...
+ * mips64-obsd-nat.c: ... this.
+ * mips64obsd-tdep.c: Rename to ...
+ * mips64-obsd-tdep.c: ... this.
+ * ppcfbsd-nat.c: Rename to ...
+ * ppc-fbsd-nat.c: ... this, adjust include.
+ * ppcfbsd-tdep.c: Rename to ...
+ * ppc-fbsd-tdep.c: ... this, adjust include.
+ * ppcfbsd-tdep.h: Rename to ...
+ * ppc-fbsd-tdep.h: ... this, adjust include barrier and comment.
+ * ppcnbsd-nat.c: Rename to ...
+ * ppc-nbsd-nat.c: ... this, adjust include.
+ * ppcnbsd-tdep.c: Rename to ...
+ * ppc-nbsd-tdep.c: ... this, adjust include.
+ * ppcnbsd-tdep.h: Rename to ...
+ * ppc-nbsd-tdep.h: ... this, adjust include barrier and comment.
+ * ppcobsd-nat.c: Rename to ...
+ * ppc-obsd-nat.c: ... this, adjust include.
+ * ppcobsd-tdep.c: Rename to ...
+ * ppc-obsd-tdep.c: ... this, adjust include.
+ * ppcobsd-tdep.h: Rename to ...
+ * ppc-obsd-tdep.h: ... this, adjust include barrier and comment.
+ * shnbsd-nat.c: Rename to ...
+ * sh-nbsd-nat.c: ... this.
+ * shnbsd-tdep.c: Rename to ...
+ * sh-nbsd-tdep.c: ... this.
+ * sparcnbsd-nat.c: Rename to ...
+ * sparc-nbsd-nat.c: ... this.
+ * sparcnbsd-tdep.c: Rename to ...
+ * sparc-nbsd-tdep.c: ... this.
+ * sparcobsd-tdep.c: Rename to ...
+ * sparc-obsd-tdep.c: ... this.
+ * sparc64fbsd-nat.c: Rename to ...
+ * sparc64-fbsd-nat.c: ... this.
+ * sparc64fbsd-tdep.c: Rename to ...
+ * sparc64-fbsd-tdep.c: ... this.
+ * sparc64nbsd-nat.c: Rename to ...
+ * sparc64-nbsd-nat.c: ... this.
+ * sparc64nbsd-tdep.c: Rename to ...
+ * sparc64-nbsd-tdep.c: ... this.
+ * sparc64obsd-nat.c: Rename to ...
+ * sparc64-obsd-nat.c: ... this.
+ * sparc64obsd-tdep.c: Rename to ...
+ * sparc64-obsd-tdep.c: ... this.
+ * sparc64-tdep.h: Update comments.
+ * vaxbsd-nat.c: Rename to ...
+ * vax-bsd-nat.c: ... this.
+ * vaxnbsd-tdep.c: Rename to ...
+ * vax-nbsd-tdep.c: ... this.
+ * vaxobsd-tdep.c: Rename to ...
+ * vax-obsd-tdep.c: ... this.
+ * x86bsd-nat.h: Rename to ...
+ * x86-bsd-nat.h: ... this, adjust include barrier and comment.
+ * x86bsd-nat.c: Rename to ...
+ * x86-bsd-nat.c: ... this, adjust include.
+ * configure.tgt: Update renamed files.
+ * config/alpha/fbsd.mh: Update renamed files.
+ * config/alpha/nbsd.mh: Update renamed files.
+ * config/arm/nbsdelf.mh: Update renamed files.
+ * config/djgpp/fnchange.lst: Update renamed files.
+ * config/i386/fbsd.mh: Update renamed files.
+ * config/i386/fbsd64.mh: Update renamed files.
+ * config/i386/i386gnu.mh: Update renamed files.
+ * config/i386/i386sol2.mh: Update renamed files.
+ * config/i386/nbsd64.mh: Update renamed files.
+ * config/i386/nbsdelf.mh: Update renamed files.
+ * config/i386/obsd.mh: Update renamed files.
+ * config/i386/obsd64.mh: Update renamed files.
+ * config/i386/sol2-64.mh: Update renamed files.
+ * config/m68k/linux.mh: Update renamed files.
+ * config/m68k/nbsdelf.mh: Update renamed files.
+ * config/m68k/obsd.mh: Update renamed files.
+ * config/m88k/obsd.mh: Update renamed files.
+ * config/mips/nbsd.mh: Update renamed files.
+ * config/mips/obsd64.mh: Update renamed files.
+ * config/pa/nbsd.mh: Update renamed files.
+ * config/pa/obsd.mh: Update renamed files.
+ * config/powerpc/fbsd.mh: Update renamed files.
+ * config/powerpc/nbsd.mh: Update renamed files.
+ * config/powerpc/obsd.mh: Update renamed files.
+ * config/sh/nbsd.mh: Update renamed files.
+ * config/sparc/fbsd.mh: Update renamed files.
+ * config/sparc/nbsd64.mh: Update renamed files.
+ * config/sparc/nbsdelf.mh: Update renamed files.
+ * config/sparc/obsd64.mh: Update renamed files.
+ * config/vax/nbsdelf.mh: Update renamed files.
+ * config/vax/obsd.mh: Update renamed files.
+
2016-11-22 Simon Marchi <simon.marchi@polymtl.ca>
* Makefile.in: Add comment about file lists ordering.
aarch64-linux-tdep.o \
aarch64-newlib-tdep.o \
aarch64-tdep.o \
+ alpha-bsd-tdep.o \
+ alpha-fbsd-tdep.o \
alpha-linux-tdep.o \
alpha-mdebug-tdep.o \
+ alpha-nbsd-tdep.o \
+ alpha-obsd-tdep.o \
alpha-tdep.o \
- alphabsd-tdep.o \
- alphafbsd-tdep.o \
- alphanbsd-tdep.o \
- alphaobsd-tdep.o \
amd64-darwin-tdep.o \
amd64-dicos-tdep.o \
+ amd64-fbsd-tdep.o \
amd64-linux-tdep.o \
+ amd64-nbsd-tdep.o \
+ amd64-obsd-tdep.o \
amd64-sol2-tdep.o \
amd64-tdep.o \
amd64-windows-tdep.o \
- amd64fbsd-tdep.o \
- amd64nbsd-tdep.o \
- amd64obsd-tdep.o \
ia64-linux-tdep.o \
ia64-tdep.o \
ia64-vms-tdep.o \
- mips64obsd-tdep.o \
+ mips64-obsd-tdep.o \
+ sparc64-fbsd-tdep.o \
sparc64-linux-tdep.o \
+ sparc64-nbsd-tdep.o \
+ sparc64-obsd-tdep.o \
sparc64-sol2-tdep.o \
- sparc64-tdep.o \
- sparc64fbsd-tdep.o \
- sparc64nbsd-tdep.o \
- sparc64obsd-tdep.o
+ sparc64-tdep.o
# All other target-dependent objects files (used with --enable-targets=all).
ALL_TARGET_OBS = \
arc-tdep.o \
arm.o \
+ arm-bsd-tdep.o \
arm-get-next-pcs.o \
arm-linux.o \
arm-linux-tdep.o \
+ arm-nbsd-tdep.o \
+ arm-obsd-tdep.o \
arm-symbian-tdep.o \
arm-tdep.o \
arm-wince-tdep.o \
- armbsd-tdep.o \
- armnbsd-tdep.o \
- armobsd-tdep.o \
avr-tdep.o \
bfin-linux-tdep.o \
bfin-tdep.o \
ft32-tdep.o \
glibc-tdep.o \
h8300-tdep.o \
+ hppa-bsd-tdep.o \
hppa-linux-tdep.o \
+ hppa-nbsd-tdep.o \
+ hppa-obsd-tdep.o \
hppa-tdep.o \
- hppabsd-tdep.o \
- hppanbsd-tdep.o \
- hppaobsd-tdep.o \
+ i386-bsd-tdep.o \
i386-cygwin-tdep.o \
i386-darwin-tdep.o \
i386-dicos-tdep.o \
+ i386-fbsd-tdep.o \
+ i386-gnu-tdep.o \
i386-linux-tdep.o \
+ i386-nbsd-tdep.o \
i386-nto-tdep.o \
+ i386-obsd-tdep.o \
i386-sol2-tdep.o \
i386-tdep.o \
- i386bsd-tdep.o \
- i386fbsd-tdep.o \
- i386gnu-tdep.o \
- i386nbsd-tdep.o \
- i386obsd-tdep.o \
i387-tdep.o \
iq2000-tdep.o \
linux-record.o \
m32r-linux-tdep.o \
m32r-tdep.o \
m68hc11-tdep.o \
+ m68k-bsd-tdep.o \
+ m68k-linux-tdep.o \
m68k-tdep.o \
- m68kbsd-tdep.o \
- m68klinux-tdep.o \
m88k-tdep.o \
mep-tdep.o \
microblaze-linux-tdep.o \
microblaze-tdep.o \
mips-linux-tdep.o \
+ mips-nbsd-tdep.o \
mips-sde-tdep.o \
mips-tdep.o \
- mipsnbsd-tdep.o \
mn10300-linux-tdep.o \
mn10300-tdep.o \
moxie-tdep.o \
nios2-tdep.o \
nto-tdep.o \
obsd-tdep.o \
+ ppc-fbsd-tdep.o \
ppc-linux-tdep.o \
+ ppc-nbsd-tdep.o \
+ ppc-obsd-tdep.o \
ppc-ravenscar-thread.o \
ppc-sysv-tdep.o \
ppc64-tdep.o \
- ppcfbsd-tdep.o \
- ppcnbsd-tdep.o \
- ppcobsd-tdep.o \
ravenscar-thread.o \
rl78-tdep.o \
rs6000-aix-tdep.o \
s390-linux-tdep.o \
score-tdep.o \
sh-linux-tdep.o \
+ sh-nbsd-tdep.o \
sh-tdep.o \
sh64-tdep.o \
- shnbsd-tdep.o \
sol2-tdep.o \
solib-aix.o \
solib-darwin.o \
solib-spu.o \
solib-svr4.o \
sparc-linux-tdep.o \
+ sparc-nbsd-tdep.o \
+ sparc-obsd-tdep.o \
sparc-ravenscar-thread.o \
sparc-sol2-tdep.o \
sparc-tdep.o \
- sparcnbsd-tdep.o \
- sparcobsd-tdep.o \
spu-multiarch.o \
spu-tdep.o \
symfile-mem.o \
tilegx-linux-tdep.o \
tilegx-tdep.o \
v850-tdep.o \
+ vax-nbsd-tdep.o \
+ vax-obsd-tdep.o \
vax-tdep.o \
- vaxnbsd-tdep.o \
- vaxobsd-tdep.o \
windows-tdep.o \
xcoffread.o \
xstormy16-tdep.o \
aarch64-tdep.h \
ada-lang.h \
addrmap.h \
+ alpha-bsd-tdep.h \
alpha-tdep.h \
- alphabsd-tdep.h \
amd64-darwin-tdep.h \
amd64-linux-tdep.h \
amd64-nat.h \
gnu-nat.h \
go-lang.h \
gregset.h \
+ hppa-bsd-tdep.h \
hppa-linux-offsets.h \
hppa-tdep.h \
- hppabsd-tdep.h \
+ i386-bsd-nat.h \
i386-darwin-tdep.h \
i386-linux-nat.h \
i386-linux-tdep.h \
i386-tdep.h \
- i386bsd-nat.h \
i387-tdep.h \
ia64-libunwind-tdep.h \
ia64-tdep.h \
memrange.h \
microblaze-tdep.h \
mips-linux-tdep.h \
+ mips-nbsd-tdep.h \
mips-tdep.h \
- mipsnbsd-tdep.h \
mn10300-tdep.h \
moxie-tdep.h \
nbsd-nat.h \
osdata.h \
p-lang.h \
parser-defs.h \
+ ppc-fbsd-tdep.h \
ppc-linux-tdep.h \
+ ppc-nbsd-tdep.h \
+ ppc-obsd-tdep.h \
ppc-ravenscar-thread.h \
ppc-tdep.h \
ppc64-tdep.h \
- ppcfbsd-tdep.h \
- ppcnbsd-tdep.h \
- ppcobsd-tdep.h \
probe.h \
proc-utils.h \
procfs.h \
vax-tdep.h \
windows-nat.h \
windows-tdep.h \
+ x86-bsd-nat.h \
x86-linux-nat.h \
x86-nat.h \
- x86bsd-nat.h \
xcoffread.h \
xml-support.h \
xml-syscall.h \
aarch64-newlib-tdep.c \
aarch64-tdep.c \
aix-thread.c \
+ alpha-bsd-nat.c \
+ alpha-bsd-tdep.c \
+ alpha-fbsd-tdep.c \
alpha-linux-nat.c \
alpha-linux-tdep.c \
alpha-mdebug-tdep.c \
+ alpha-nbsd-tdep.c \
+ alpha-obsd-tdep.c \
alpha-tdep.c \
- alphabsd-nat.c \
- alphabsd-tdep.c \
- alphafbsd-tdep.c \
- alphanbsd-tdep.c \
- alphaobsd-tdep.c \
+ amd64-bsd-nat.c \
amd64-darwin-tdep.c \
amd64-dicos-tdep.c \
+ amd64-fbsd-nat.c \
+ amd64-fbsd-tdep.c \
amd64-linux-nat.c \
amd64-linux-tdep.c \
amd64-nat.c \
+ amd64-nbsd-nat.c \
+ amd64-nbsd-tdep.c \
+ amd64-obsd-nat.c \
+ amd64-obsd-tdep.c \
amd64-sol2-tdep.c \
amd64-tdep.c \
- amd64bsd-nat.c \
- amd64fbsd-nat.c \
- amd64fbsd-tdep.c \
- amd64nbsd-nat.c \
- amd64nbsd-tdep.c \
- amd64obsd-nat.c \
- amd64obsd-tdep.c \
arc-tdep.c \
arm.c \
+ arm-bsd-tdep.c \
arm-get-next-pcs.c \
arm-linux.c \
arm-linux-nat.c \
arm-linux-tdep.c \
+ arm-nbsd-nat.c \
+ arm-nbsd-tdep.c \
+ arm-obsd-tdep.c \
arm-symbian-tdep.c \
arm-tdep.c \
- armbsd-tdep.c \
- armnbsd-nat.c \
- armnbsd-tdep.c \
- armobsd-tdep.c \
avr-tdep.c \
bfin-linux-tdep.c \
bfin-tdep.c \
glibc-tdep.c \
go32-nat.c \
h8300-tdep.c \
+ hppa-bsd-tdep.c \
hppa-linux-nat.c \
hppa-linux-tdep.c \
+ hppa-nbsd-nat.c \
+ hppa-nbsd-tdep.c \
+ hppa-obsd-nat.c \
+ hppa-obsd-tdep.c \
hppa-tdep.c \
- hppabsd-tdep.c \
- hppanbsd-nat.c \
- hppanbsd-tdep.c \
- hppaobsd-nat.c \
- hppaobsd-tdep.c \
+ i386-bsd-nat.c \
+ i386-bsd-tdep.c \
i386-cygwin-tdep.c \
i386-darwin-nat.c \
i386-darwin-tdep.c \
i386-dicos-tdep.c \
+ i386-fbsd-nat.c \
+ i386-fbsd-tdep.c \
+ i386-gnu-nat.c \
+ i386-gnu-tdep.c \
i386-linux-nat.c \
i386-linux-tdep.c \
+ i386-nbsd-nat.c \
+ i386-nbsd-tdep.c \
+ i386-obsd-nat.c \
+ i386-obsd-tdep.c \
i386-sol2-nat.c \
i386-sol2-tdep.c \
i386-tdep.c \
- i386bsd-nat.c \
- i386bsd-tdep.c \
- i386fbsd-nat.c \
- i386fbsd-tdep.c \
- i386gnu-nat.c \
- i386gnu-tdep.c \
- i386nbsd-nat.c \
- i386nbsd-tdep.c \
- i386obsd-nat.c \
- i386obsd-tdep.c \
- i386v4-nat.c \
+ i386-v4-nat.c \
i387-tdep.c \
ia64-libunwind-tdep.c \
ia64-linux-nat.c \
m32r-linux-tdep.c \
m32r-tdep.c \
m68hc11-tdep.c \
+ m68k-bsd-nat.c \
+ m68k-bsd-tdep.c \
+ m68k-linux-nat.c \
+ m68k-linux-tdep.c \
m68k-tdep.c \
- m68kbsd-nat.c \
- m68kbsd-tdep.c \
- m68klinux-nat.c \
- m68klinux-tdep.c \
+ m88k-bsd-nat.c \
m88k-tdep.c \
- m88kbsd-nat.c \
microblaze-linux-tdep.c \
microblaze-tdep.c \
mingw-hdep.c \
mips-linux-nat.c \
mips-linux-tdep.c \
+ mips-nbsd-nat.c \
+ mips-nbsd-tdep.c \
mips-sde-tdep.c \
mips-tdep.c \
- mips64obsd-nat.c \
- mips64obsd-tdep.c \
- mipsnbsd-nat.c \
- mipsnbsd-tdep.c \
+ mips64-obsd-nat.c \
+ mips64-obsd-tdep.c \
msp430-tdep.c \
nbsd-nat.c \
nbsd-tdep.c \
obsd-nat.c \
obsd-tdep.c \
posix-hdep.c \
+ ppc-fbsd-nat.c \
+ ppc-fbsd-tdep.c \
ppc-linux-nat.c \
ppc-linux-tdep.c \
+ ppc-nbsd-nat.c \
+ ppc-nbsd-tdep.c \
+ ppc-obsd-nat.c \
+ ppc-obsd-tdep.c \
ppc-ravenscar-thread.c \
ppc-sysv-tdep.c \
ppc64-tdep.c \
- ppcfbsd-nat.c \
- ppcfbsd-tdep.c \
- ppcnbsd-nat.c \
- ppcnbsd-tdep.c \
- ppcobsd-nat.c \
- ppcobsd-tdep.c \
procfs.c \
ravenscar-thread.c \
remote-sim.c \
ser-mingw.c \
ser-pipe.c \
ser-tcp.c \
+ sh-nbsd-nat.c \
+ sh-nbsd-tdep.c \
sh-tdep.c \
sh64-tdep.c \
- shnbsd-nat.c \
- shnbsd-tdep.c \
sol2-tdep.c \
solib-aix.c \
solib-spu.c \
sparc-linux-nat.c \
sparc-linux-tdep.c \
sparc-nat.c \
+ sparc-nbsd-nat.c \
+ sparc-nbsd-tdep.c \
+ sparc-obsd-tdep.c \
sparc-ravenscar-thread.c \
sparc-sol2-nat.c \
sparc-sol2-tdep.c \
sparc-tdep.c \
+ sparc64-fbsd-nat.c \
+ sparc64-fbsd-tdep.c \
sparc64-linux-nat.c \
sparc64-linux-tdep.c \
sparc64-nat.c \
+ sparc64-nbsd-nat.c \
+ sparc64-nbsd-tdep.c \
+ sparc64-obsd-nat.c \
+ sparc64-obsd-tdep.c \
sparc64-sol2-tdep.c \
sparc64-tdep.c \
- sparc64fbsd-nat.c \
- sparc64fbsd-tdep.c \
- sparc64nbsd-nat.c \
- sparc64nbsd-tdep.c \
- sparc64obsd-nat.c \
- sparc64obsd-tdep.c \
- sparcnbsd-nat.c \
- sparcnbsd-tdep.c \
- sparcobsd-tdep.c \
spu-linux-nat.c \
spu-multiarch.c \
spu-tdep.c \
tilegx-linux-tdep.c \
tilegx-tdep.c \
v850-tdep.c \
+ vax-bsd-nat.c \
+ vax-nbsd-tdep.c \
vax-tdep.c \
- vaxbsd-nat.c \
- vaxnbsd-tdep.c \
windows-nat.c \
windows-tdep.c \
x86-nat.c \
--- /dev/null
+/* Native-dependent code for Alpha BSD's.
+
+ Copyright (C) 2000-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "alpha-tdep.h"
+#include "alpha-bsd-tdep.h"
+#include "inf-ptrace.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+
+#ifndef HAVE_GREGSET_T
+typedef struct reg gregset_t;
+#endif
+
+#ifndef HAVE_FPREGSET_T
+typedef struct fpreg fpregset_t;
+#endif
+
+#include "gregset.h"
+
+/* Provide *regset() wrappers around the generic Alpha BSD register
+ supply/fill routines. */
+
+void
+supply_gregset (struct regcache *regcache, const gregset_t *gregsetp)
+{
+ alphabsd_supply_reg (regcache, (const char *) gregsetp, -1);
+}
+
+void
+fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno)
+{
+ alphabsd_fill_reg (regcache, (char *) gregsetp, regno);
+}
+
+void
+supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
+{
+ alphabsd_supply_fpreg (regcache, (const char *) fpregsetp, -1);
+}
+
+void
+fill_fpregset (const struct regcache *regcache,
+ fpregset_t *fpregsetp, int regno)
+{
+ alphabsd_fill_fpreg (regcache, (char *) fpregsetp, regno);
+}
+\f
+/* Determine if PT_GETREGS fetches this register. */
+
+static int
+getregs_supplies (int regno)
+{
+ return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM)
+ || regno >= ALPHA_PC_REGNUM);
+}
+
+/* Fetch register REGNO from the inferior. If REGNO is -1, do this
+ for all registers (including the floating point registers). */
+
+static void
+alphabsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg gregs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ alphabsd_supply_reg (regcache, (char *) &gregs, regno);
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1
+ || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno);
+ }
+}
+
+/* Store register REGNO back into the inferior. If REGNO is -1, do
+ this for all registers (including the floating point registers). */
+
+static void
+alphabsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ if (regno == -1 || getregs_supplies (regno))
+ {
+ struct reg gregs;
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ alphabsd_fill_reg (regcache, (char *) &gregs, regno);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1
+ || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno);
+
+ if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+ }
+}
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/signal.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ int regnum;
+
+ /* The following is true for OpenBSD 3.9:
+
+ The pcb contains the register state at the context switch inside
+ cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_hw.apcb_ksp == 0)
+ return 0;
+
+ regcache_raw_supply (regcache, ALPHA_SP_REGNUM, &pcb->pcb_hw.apcb_ksp);
+
+ for (regnum = ALPHA_S0_REGNUM; regnum < ALPHA_A0_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum,
+ &pcb->pcb_context[regnum - ALPHA_S0_REGNUM]);
+ regcache_raw_supply (regcache, ALPHA_RA_REGNUM, &pcb->pcb_context[7]);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_alphabsd_nat (void);
+
+void
+_initialize_alphabsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = alphabsd_fetch_inferior_registers;
+ t->to_store_registers = alphabsd_store_inferior_registers;
+ add_target (t);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (alphabsd_supply_pcb);
+}
--- /dev/null
+/* Common target dependent code Alpha BSD's.
+
+ Copyright (C) 2000-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "regcache.h"
+
+#include "alpha-tdep.h"
+#include "alpha-bsd-tdep.h"
+
+/* Conviently, GDB uses the same register numbering as the
+ ptrace register structure used by BSD on Alpha. */
+
+void
+alphabsd_supply_reg (struct regcache *regcache, const char *regs, int regno)
+{
+ /* PC is at slot 32; UNIQUE not present. */
+ alpha_supply_int_regs (regcache, regno, regs, regs + 31 * 8, NULL);
+}
+
+void
+alphabsd_fill_reg (const struct regcache *regcache, char *regs, int regno)
+{
+ /* PC is at slot 32; UNIQUE not present. */
+ alpha_fill_int_regs (regcache, regno, regs, regs + 31 * 8, NULL);
+}
+
+void
+alphabsd_supply_fpreg (struct regcache *regcache,
+ const char *fpregs, int regno)
+{
+ /* FPCR is at slot 33; slot 32 unused. */
+ alpha_supply_fp_regs (regcache, regno, fpregs, fpregs + 32 * 8);
+}
+
+void
+alphabsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno)
+{
+ /* FPCR is at slot 33; slot 32 unused. */
+ alpha_fill_fp_regs (regcache, regno, fpregs, fpregs + 32 * 8);
+}
--- /dev/null
+/* Common target dependent code for Alpha BSD's.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef ALPHA_BSD_TDEP_H
+#define ALPHA_BSD_TDEP_H
+
+struct regcache;
+
+void alphabsd_supply_reg (struct regcache *, const char *, int);
+void alphabsd_fill_reg (const struct regcache *, char *, int);
+
+void alphabsd_supply_fpreg (struct regcache *, const char *, int);
+void alphabsd_fill_fpreg (const struct regcache *, char *, int);
+\f
+
+/* Functions exported from alpha-nbsd-tdep.c. */
+
+/* Iterate over supported core file register note sections. */
+void alphanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache);
+
+#endif /* alpha-bsd-tdep.h */
--- /dev/null
+/* Target-dependent code for FreeBSD/alpha.
+
+ Copyright (C) 2001-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "value.h"
+#include "osabi.h"
+
+#include "alpha-tdep.h"
+#include "solib-svr4.h"
+
+static int
+alphafbsd_return_in_memory (struct type *type)
+{
+ enum type_code code;
+ int i;
+
+ /* All aggregate types that won't fit in a register must be returned
+ in memory. */
+ if (TYPE_LENGTH (type) > ALPHA_REGISTER_SIZE)
+ return 1;
+
+ /* The only aggregate types that can be returned in a register are
+ structs and unions. Arrays must be returned in memory. */
+ code = TYPE_CODE (type);
+ if (code != TYPE_CODE_STRUCT && code != TYPE_CODE_UNION)
+ return 1;
+
+ /* We need to check if this struct/union is "integer" like. For
+ this to be true, the offset of each adressable subfield must be
+ zero. Note that bit fields are not addressable. */
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ /* If the field bitsize is non-zero, it isn't adressable. */
+ if (TYPE_FIELD_BITPOS (type, i) != 0
+ && TYPE_FIELD_BITSIZE (type, i) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+\f
+
+/* Support for signal handlers. */
+
+/* Return whether PC is in a BSD sigtramp routine. */
+
+CORE_ADDR alphafbsd_sigtramp_start = 0x11ffff68;
+CORE_ADDR alphafbsd_sigtramp_end = 0x11ffffe0;
+
+static int
+alphafbsd_pc_in_sigtramp (struct gdbarch *gdbarch,
+ CORE_ADDR pc, const char *func_name)
+{
+ return (pc >= alphafbsd_sigtramp_start && pc < alphafbsd_sigtramp_end);
+}
+
+static LONGEST
+alphafbsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ return pc - alphafbsd_sigtramp_start;
+}
+
+/* Assuming THIS_FRAME is the frame of a BSD sigtramp routine,
+ return the address of the associated sigcontext structure. */
+
+static CORE_ADDR
+alphafbsd_sigcontext_addr (struct frame_info *this_frame)
+{
+ return get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM) + 24;
+}
+
+/* FreeBSD 5.0-RELEASE or later. */
+
+static void
+alphafbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* FIXME: Should activate generic FreeBSD support here with
+ fbsd_init_abi(), but this requires a valid
+ 'iterate_over_regset_sections' gdbarch method and
+ 'collect_regset' functions for each regset. */
+
+ /* Hook into the DWARF CFI frame unwinder. */
+ alpha_dwarf2_init_abi (info, gdbarch);
+
+ /* Hook into the MDEBUG frame unwinder. */
+ alpha_mdebug_init_abi (info, gdbarch);
+
+ /* FreeBSD/alpha has SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+
+ tdep->dynamic_sigtramp_offset = alphafbsd_sigtramp_offset;
+ tdep->sigcontext_addr = alphafbsd_sigcontext_addr;
+ tdep->pc_in_sigtramp = alphafbsd_pc_in_sigtramp;
+ tdep->return_in_memory = alphafbsd_return_in_memory;
+ tdep->sc_pc_offset = 288;
+ tdep->sc_regs_offset = 24;
+ tdep->sc_fpregs_offset = 320;
+
+ tdep->jb_pc = 2;
+ tdep->jb_elt_size = 8;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_alphafbsd_tdep (void);
+
+void
+_initialize_alphafbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_FREEBSD_ELF,
+ alphafbsd_init_abi);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/alpha.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ Contributed by Wasabi Systems, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "value.h"
+
+#include "alpha-tdep.h"
+#include "alpha-bsd-tdep.h"
+#include "nbsd-tdep.h"
+#include "solib-svr4.h"
+#include "target.h"
+
+/* Core file support. */
+
+/* Even though NetBSD/alpha used ELF since day one, it used the
+ traditional a.out-style core dump format before NetBSD 1.6. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define ALPHANBSD_SIZEOF_GREGS (32 * 8)
+
+/* Sizeof `struct fpreg' in <machine/reg.h. */
+#define ALPHANBSD_SIZEOF_FPREGS ((32 * 8) + 8)
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+alphanbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) fpregs;
+ int i;
+
+ gdb_assert (len >= ALPHANBSD_SIZEOF_FPREGS);
+
+ for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + (i - ALPHA_FP0_REGNUM) * 8);
+ }
+
+ if (regnum == ALPHA_FPCR_REGNUM || regnum == -1)
+ regcache_raw_supply (regcache, ALPHA_FPCR_REGNUM, regs + 32 * 8);
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+alphanbsd_aout_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) gregs;
+ int i;
+
+ /* Table to map a GDB register number to a trapframe register index. */
+ static const int regmap[] =
+ {
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 9, 10, 11,
+ 12, 13, 14, 15,
+ 30, 31, 32, 16,
+ 17, 18, 19, 20,
+ 21, 22, 23, 24,
+ 25, 29, 26
+ };
+
+ gdb_assert (len >= ALPHANBSD_SIZEOF_GREGS);
+
+ for (i = 0; i < ARRAY_SIZE(regmap); i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + regmap[i] * 8);
+ }
+
+ if (regnum == ALPHA_PC_REGNUM || regnum == -1)
+ regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8);
+
+ if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
+ {
+ regs += ALPHANBSD_SIZEOF_GREGS;
+ len -= ALPHANBSD_SIZEOF_GREGS;
+ alphanbsd_supply_fpregset (regset, regcache, regnum, regs, len);
+ }
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+alphanbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) gregs;
+ int i;
+
+ if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
+ {
+ alphanbsd_aout_supply_gregset (regset, regcache, regnum, gregs, len);
+ return;
+ }
+
+ for (i = 0; i < ALPHA_ZERO_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + i * 8);
+ }
+
+ if (regnum == ALPHA_PC_REGNUM || regnum == -1)
+ regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8);
+}
+
+/* NetBSD/alpha register sets. */
+
+static const struct regset alphanbsd_gregset =
+{
+ NULL,
+ alphanbsd_supply_gregset,
+ NULL,
+ REGSET_VARIABLE_SIZE
+};
+
+static const struct regset alphanbsd_fpregset =
+{
+ NULL,
+ alphanbsd_supply_fpregset
+};
+
+/* Iterate over supported core file register note sections. */
+
+void
+alphanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", ALPHANBSD_SIZEOF_GREGS, &alphanbsd_gregset, NULL, cb_data);
+ cb (".reg2", ALPHANBSD_SIZEOF_FPREGS, &alphanbsd_fpregset, NULL, cb_data);
+}
+\f
+
+/* Signal trampolines. */
+
+/* Under NetBSD/alpha, signal handler invocations can be identified by the
+ designated code sequence that is used to return from a signal handler.
+ In particular, the return address of a signal handler points to the
+ following code sequence:
+
+ ldq a0, 0(sp)
+ lda sp, 16(sp)
+ lda v0, 295(zero) # __sigreturn14
+ call_pal callsys
+
+ Each instruction has a unique encoding, so we simply attempt to match
+ the instruction the PC is pointing to with any of the above instructions.
+ If there is a hit, we know the offset to the start of the designated
+ sequence and can then check whether we really are executing in the
+ signal trampoline. If not, -1 is returned, otherwise the offset from the
+ start of the return sequence is returned. */
+static const gdb_byte sigtramp_retcode[] =
+{
+ 0x00, 0x00, 0x1e, 0xa6, /* ldq a0, 0(sp) */
+ 0x10, 0x00, 0xde, 0x23, /* lda sp, 16(sp) */
+ 0x27, 0x01, 0x1f, 0x20, /* lda v0, 295(zero) */
+ 0x83, 0x00, 0x00, 0x00, /* call_pal callsys */
+};
+#define RETCODE_NWORDS 4
+#define RETCODE_SIZE (RETCODE_NWORDS * 4)
+
+static LONGEST
+alphanbsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ gdb_byte ret[RETCODE_SIZE], w[4];
+ LONGEST off;
+ int i;
+
+ if (target_read_memory (pc, w, 4) != 0)
+ return -1;
+
+ for (i = 0; i < RETCODE_NWORDS; i++)
+ {
+ if (memcmp (w, sigtramp_retcode + (i * 4), 4) == 0)
+ break;
+ }
+ if (i == RETCODE_NWORDS)
+ return (-1);
+
+ off = i * 4;
+ pc -= off;
+
+ if (target_read_memory (pc, ret, sizeof (ret)) != 0)
+ return -1;
+
+ if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0)
+ return off;
+
+ return -1;
+}
+
+static int
+alphanbsd_pc_in_sigtramp (struct gdbarch *gdbarch,
+ CORE_ADDR pc, const char *func_name)
+{
+ return (nbsd_pc_in_sigtramp (pc, func_name)
+ || alphanbsd_sigtramp_offset (gdbarch, pc) >= 0);
+}
+
+static CORE_ADDR
+alphanbsd_sigcontext_addr (struct frame_info *frame)
+{
+ /* FIXME: This is not correct for all versions of NetBSD/alpha.
+ We will probably need to disassemble the trampoline to figure
+ out which trampoline frame type we have. */
+ if (!get_next_frame (frame))
+ return 0;
+ return get_frame_base (get_next_frame (frame));
+}
+\f
+
+static void
+alphanbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Hook into the DWARF CFI frame unwinder. */
+ alpha_dwarf2_init_abi (info, gdbarch);
+
+ /* Hook into the MDEBUG frame unwinder. */
+ alpha_mdebug_init_abi (info, gdbarch);
+
+ /* NetBSD/alpha does not provide single step support via ptrace(2); we
+ must use software single-stepping. */
+ set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
+
+ /* NetBSD/alpha has SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+
+ tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
+ tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp;
+ tdep->sigcontext_addr = alphanbsd_sigcontext_addr;
+
+ tdep->jb_pc = 2;
+ tdep->jb_elt_size = 8;
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, alphanbsd_iterate_over_regset_sections);
+}
+\f
+
+static enum gdb_osabi
+alphanbsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_ELF;
+
+ return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_alphanbsd_tdep (void);
+
+void
+_initialize_alphanbsd_tdep (void)
+{
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_alpha, bfd_target_unknown_flavour,
+ alphanbsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_NETBSD_ELF,
+ alphanbsd_init_abi);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/alpha.
+
+ Copyright (C) 2006-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "osabi.h"
+
+#include "obsd-tdep.h"
+#include "alpha-tdep.h"
+#include "alpha-bsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Signal trampolines. */
+
+/* The OpenBSD kernel maps the signal trampoline at some random
+ location in user space, which means that the traditional BSD way of
+ detecting it won't work.
+
+ The signal trampoline will be mapped at an address that is page
+ aligned. We recognize the signal trampoline by looking for the
+ sigreturn system call. */
+
+static const int alphaobsd_page_size = 8192;
+
+static LONGEST
+alphaobsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ return (pc & (alphaobsd_page_size - 1));
+}
+
+static int
+alphaobsd_pc_in_sigtramp (struct gdbarch *gdbarch,
+ CORE_ADDR pc, const char *name)
+{
+ CORE_ADDR start_pc = (pc & ~(alphaobsd_page_size - 1));
+ unsigned insn;
+
+ if (name)
+ return 0;
+
+ /* Check for "". */
+ insn = alpha_read_insn (gdbarch, start_pc + 5 * ALPHA_INSN_SIZE);
+ if (insn != 0x201f0067)
+ return 0;
+
+ /* Check for "". */
+ insn = alpha_read_insn (gdbarch, start_pc + 6 * ALPHA_INSN_SIZE);
+ if (insn != 0x00000083)
+ return 0;
+
+ return 1;
+}
+
+static CORE_ADDR
+alphaobsd_sigcontext_addr (struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ CORE_ADDR pc = get_frame_pc (this_frame);
+
+ if (alphaobsd_sigtramp_offset (gdbarch, pc) < 3 * ALPHA_INSN_SIZE)
+ {
+ /* On entry, a pointer the `struct sigcontext' is passed in %a2. */
+ return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM + 2);
+ }
+ else if (alphaobsd_sigtramp_offset (gdbarch, pc) < 4 * ALPHA_INSN_SIZE)
+ {
+ /* It is stored on the stack Before calling the signal handler. */
+ CORE_ADDR sp;
+ sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
+ return get_frame_memory_unsigned (this_frame, sp, 8);
+ }
+ else
+ {
+ /* It is reloaded into %a0 for the sigreturn(2) call. */
+ return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM);
+ }
+}
+\f
+
+static void
+alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Hook into the DWARF CFI frame unwinder. */
+ alpha_dwarf2_init_abi (info, gdbarch);
+
+ /* Hook into the MDEBUG frame unwinder. */
+ alpha_mdebug_init_abi (info, gdbarch);
+
+ /* OpenBSD/alpha 3.0 and earlier does not provide single step
+ support via ptrace(2); use software single-stepping for now. */
+ set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
+
+ /* OpenBSD/alpha has SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
+
+ tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset;
+ tdep->pc_in_sigtramp = alphaobsd_pc_in_sigtramp;
+ tdep->sigcontext_addr = alphaobsd_sigcontext_addr;
+
+ tdep->jb_pc = 2;
+ tdep->jb_elt_size = 8;
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, alphanbsd_iterate_over_regset_sections);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_alphaobsd_tdep (void);
+
+void
+_initialize_alphaobsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD_ELF,
+ alphaobsd_init_abi);
+}
+++ /dev/null
-/* Native-dependent code for Alpha BSD's.
-
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#include "alpha-tdep.h"
-#include "alphabsd-tdep.h"
-#include "inf-ptrace.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#ifdef HAVE_SYS_PROCFS_H
-#include <sys/procfs.h>
-#endif
-
-#ifndef HAVE_GREGSET_T
-typedef struct reg gregset_t;
-#endif
-
-#ifndef HAVE_FPREGSET_T
-typedef struct fpreg fpregset_t;
-#endif
-
-#include "gregset.h"
-
-/* Provide *regset() wrappers around the generic Alpha BSD register
- supply/fill routines. */
-
-void
-supply_gregset (struct regcache *regcache, const gregset_t *gregsetp)
-{
- alphabsd_supply_reg (regcache, (const char *) gregsetp, -1);
-}
-
-void
-fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno)
-{
- alphabsd_fill_reg (regcache, (char *) gregsetp, regno);
-}
-
-void
-supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
-{
- alphabsd_supply_fpreg (regcache, (const char *) fpregsetp, -1);
-}
-
-void
-fill_fpregset (const struct regcache *regcache,
- fpregset_t *fpregsetp, int regno)
-{
- alphabsd_fill_fpreg (regcache, (char *) fpregsetp, regno);
-}
-\f
-/* Determine if PT_GETREGS fetches this register. */
-
-static int
-getregs_supplies (int regno)
-{
- return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM)
- || regno >= ALPHA_PC_REGNUM);
-}
-
-/* Fetch register REGNO from the inferior. If REGNO is -1, do this
- for all registers (including the floating point registers). */
-
-static void
-alphabsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- if (regno == -1 || getregs_supplies (regno))
- {
- struct reg gregs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- alphabsd_supply_reg (regcache, (char *) &gregs, regno);
- if (regno != -1)
- return;
- }
-
- if (regno == -1
- || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno);
- }
-}
-
-/* Store register REGNO back into the inferior. If REGNO is -1, do
- this for all registers (including the floating point registers). */
-
-static void
-alphabsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- if (regno == -1 || getregs_supplies (regno))
- {
- struct reg gregs;
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- alphabsd_fill_reg (regcache, (char *) &gregs, regno);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-
- if (regno != -1)
- return;
- }
-
- if (regno == -1
- || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno);
-
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't write floating point status"));
- }
-}
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/signal.h>
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- int regnum;
-
- /* The following is true for OpenBSD 3.9:
-
- The pcb contains the register state at the context switch inside
- cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_hw.apcb_ksp == 0)
- return 0;
-
- regcache_raw_supply (regcache, ALPHA_SP_REGNUM, &pcb->pcb_hw.apcb_ksp);
-
- for (regnum = ALPHA_S0_REGNUM; regnum < ALPHA_A0_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum,
- &pcb->pcb_context[regnum - ALPHA_S0_REGNUM]);
- regcache_raw_supply (regcache, ALPHA_RA_REGNUM, &pcb->pcb_context[7]);
-
- return 1;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_alphabsd_nat (void);
-
-void
-_initialize_alphabsd_nat (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
- t->to_fetch_registers = alphabsd_fetch_inferior_registers;
- t->to_store_registers = alphabsd_store_inferior_registers;
- add_target (t);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (alphabsd_supply_pcb);
-}
+++ /dev/null
-/* Common target dependent code Alpha BSD's.
-
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "regcache.h"
-
-#include "alpha-tdep.h"
-#include "alphabsd-tdep.h"
-
-/* Conviently, GDB uses the same register numbering as the
- ptrace register structure used by BSD on Alpha. */
-
-void
-alphabsd_supply_reg (struct regcache *regcache, const char *regs, int regno)
-{
- /* PC is at slot 32; UNIQUE not present. */
- alpha_supply_int_regs (regcache, regno, regs, regs + 31 * 8, NULL);
-}
-
-void
-alphabsd_fill_reg (const struct regcache *regcache, char *regs, int regno)
-{
- /* PC is at slot 32; UNIQUE not present. */
- alpha_fill_int_regs (regcache, regno, regs, regs + 31 * 8, NULL);
-}
-
-void
-alphabsd_supply_fpreg (struct regcache *regcache,
- const char *fpregs, int regno)
-{
- /* FPCR is at slot 33; slot 32 unused. */
- alpha_supply_fp_regs (regcache, regno, fpregs, fpregs + 32 * 8);
-}
-
-void
-alphabsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno)
-{
- /* FPCR is at slot 33; slot 32 unused. */
- alpha_fill_fp_regs (regcache, regno, fpregs, fpregs + 32 * 8);
-}
+++ /dev/null
-/* Common target dependent code for Alpha BSD's.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef ALPHABSD_TDEP_H
-#define ALPHABSD_TDEP_H
-
-struct regcache;
-
-void alphabsd_supply_reg (struct regcache *, const char *, int);
-void alphabsd_fill_reg (const struct regcache *, char *, int);
-
-void alphabsd_supply_fpreg (struct regcache *, const char *, int);
-void alphabsd_fill_fpreg (const struct regcache *, char *, int);
-\f
-
-/* Functions exported from alphanbsd-tdep.c. */
-
-/* Iterate over supported core file register note sections. */
-void alphanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache);
-
-#endif /* alphabsd-tdep.h */
+++ /dev/null
-/* Target-dependent code for FreeBSD/alpha.
-
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "value.h"
-#include "osabi.h"
-
-#include "alpha-tdep.h"
-#include "solib-svr4.h"
-
-static int
-alphafbsd_return_in_memory (struct type *type)
-{
- enum type_code code;
- int i;
-
- /* All aggregate types that won't fit in a register must be returned
- in memory. */
- if (TYPE_LENGTH (type) > ALPHA_REGISTER_SIZE)
- return 1;
-
- /* The only aggregate types that can be returned in a register are
- structs and unions. Arrays must be returned in memory. */
- code = TYPE_CODE (type);
- if (code != TYPE_CODE_STRUCT && code != TYPE_CODE_UNION)
- return 1;
-
- /* We need to check if this struct/union is "integer" like. For
- this to be true, the offset of each adressable subfield must be
- zero. Note that bit fields are not addressable. */
- for (i = 0; i < TYPE_NFIELDS (type); i++)
- {
- /* If the field bitsize is non-zero, it isn't adressable. */
- if (TYPE_FIELD_BITPOS (type, i) != 0
- && TYPE_FIELD_BITSIZE (type, i) == 0)
- return 1;
- }
-
- return 0;
-}
-\f
-
-/* Support for signal handlers. */
-
-/* Return whether PC is in a BSD sigtramp routine. */
-
-CORE_ADDR alphafbsd_sigtramp_start = 0x11ffff68;
-CORE_ADDR alphafbsd_sigtramp_end = 0x11ffffe0;
-
-static int
-alphafbsd_pc_in_sigtramp (struct gdbarch *gdbarch,
- CORE_ADDR pc, const char *func_name)
-{
- return (pc >= alphafbsd_sigtramp_start && pc < alphafbsd_sigtramp_end);
-}
-
-static LONGEST
-alphafbsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
-{
- return pc - alphafbsd_sigtramp_start;
-}
-
-/* Assuming THIS_FRAME is the frame of a BSD sigtramp routine,
- return the address of the associated sigcontext structure. */
-
-static CORE_ADDR
-alphafbsd_sigcontext_addr (struct frame_info *this_frame)
-{
- return get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM) + 24;
-}
-
-/* FreeBSD 5.0-RELEASE or later. */
-
-static void
-alphafbsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* FIXME: Should activate generic FreeBSD support here with
- fbsd_init_abi(), but this requires a valid
- 'iterate_over_regset_sections' gdbarch method and
- 'collect_regset' functions for each regset. */
-
- /* Hook into the DWARF CFI frame unwinder. */
- alpha_dwarf2_init_abi (info, gdbarch);
-
- /* Hook into the MDEBUG frame unwinder. */
- alpha_mdebug_init_abi (info, gdbarch);
-
- /* FreeBSD/alpha has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-
- tdep->dynamic_sigtramp_offset = alphafbsd_sigtramp_offset;
- tdep->sigcontext_addr = alphafbsd_sigcontext_addr;
- tdep->pc_in_sigtramp = alphafbsd_pc_in_sigtramp;
- tdep->return_in_memory = alphafbsd_return_in_memory;
- tdep->sc_pc_offset = 288;
- tdep->sc_regs_offset = 24;
- tdep->sc_fpregs_offset = 320;
-
- tdep->jb_pc = 2;
- tdep->jb_elt_size = 8;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_alphafbsd_tdep (void);
-
-void
-_initialize_alphafbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_FREEBSD_ELF,
- alphafbsd_init_abi);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/alpha.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- Contributed by Wasabi Systems, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "value.h"
-
-#include "alpha-tdep.h"
-#include "alphabsd-tdep.h"
-#include "nbsd-tdep.h"
-#include "solib-svr4.h"
-#include "target.h"
-
-/* Core file support. */
-
-/* Even though NetBSD/alpha used ELF since day one, it used the
- traditional a.out-style core dump format before NetBSD 1.6. */
-
-/* Sizeof `struct reg' in <machine/reg.h>. */
-#define ALPHANBSD_SIZEOF_GREGS (32 * 8)
-
-/* Sizeof `struct fpreg' in <machine/reg.h. */
-#define ALPHANBSD_SIZEOF_FPREGS ((32 * 8) + 8)
-
-/* Supply register REGNUM from the buffer specified by FPREGS and LEN
- in the floating-point register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-alphanbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) fpregs;
- int i;
-
- gdb_assert (len >= ALPHANBSD_SIZEOF_FPREGS);
-
- for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + (i - ALPHA_FP0_REGNUM) * 8);
- }
-
- if (regnum == ALPHA_FPCR_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, ALPHA_FPCR_REGNUM, regs + 32 * 8);
-}
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-alphanbsd_aout_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) gregs;
- int i;
-
- /* Table to map a GDB register number to a trapframe register index. */
- static const int regmap[] =
- {
- 0, 1, 2, 3,
- 4, 5, 6, 7,
- 8, 9, 10, 11,
- 12, 13, 14, 15,
- 30, 31, 32, 16,
- 17, 18, 19, 20,
- 21, 22, 23, 24,
- 25, 29, 26
- };
-
- gdb_assert (len >= ALPHANBSD_SIZEOF_GREGS);
-
- for (i = 0; i < ARRAY_SIZE(regmap); i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + regmap[i] * 8);
- }
-
- if (regnum == ALPHA_PC_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8);
-
- if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
- {
- regs += ALPHANBSD_SIZEOF_GREGS;
- len -= ALPHANBSD_SIZEOF_GREGS;
- alphanbsd_supply_fpregset (regset, regcache, regnum, regs, len);
- }
-}
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-alphanbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) gregs;
- int i;
-
- if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
- {
- alphanbsd_aout_supply_gregset (regset, regcache, regnum, gregs, len);
- return;
- }
-
- for (i = 0; i < ALPHA_ZERO_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + i * 8);
- }
-
- if (regnum == ALPHA_PC_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8);
-}
-
-/* NetBSD/alpha register sets. */
-
-static const struct regset alphanbsd_gregset =
-{
- NULL,
- alphanbsd_supply_gregset,
- NULL,
- REGSET_VARIABLE_SIZE
-};
-
-static const struct regset alphanbsd_fpregset =
-{
- NULL,
- alphanbsd_supply_fpregset
-};
-
-/* Iterate over supported core file register note sections. */
-
-void
-alphanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", ALPHANBSD_SIZEOF_GREGS, &alphanbsd_gregset, NULL, cb_data);
- cb (".reg2", ALPHANBSD_SIZEOF_FPREGS, &alphanbsd_fpregset, NULL, cb_data);
-}
-\f
-
-/* Signal trampolines. */
-
-/* Under NetBSD/alpha, signal handler invocations can be identified by the
- designated code sequence that is used to return from a signal handler.
- In particular, the return address of a signal handler points to the
- following code sequence:
-
- ldq a0, 0(sp)
- lda sp, 16(sp)
- lda v0, 295(zero) # __sigreturn14
- call_pal callsys
-
- Each instruction has a unique encoding, so we simply attempt to match
- the instruction the PC is pointing to with any of the above instructions.
- If there is a hit, we know the offset to the start of the designated
- sequence and can then check whether we really are executing in the
- signal trampoline. If not, -1 is returned, otherwise the offset from the
- start of the return sequence is returned. */
-static const gdb_byte sigtramp_retcode[] =
-{
- 0x00, 0x00, 0x1e, 0xa6, /* ldq a0, 0(sp) */
- 0x10, 0x00, 0xde, 0x23, /* lda sp, 16(sp) */
- 0x27, 0x01, 0x1f, 0x20, /* lda v0, 295(zero) */
- 0x83, 0x00, 0x00, 0x00, /* call_pal callsys */
-};
-#define RETCODE_NWORDS 4
-#define RETCODE_SIZE (RETCODE_NWORDS * 4)
-
-static LONGEST
-alphanbsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
-{
- gdb_byte ret[RETCODE_SIZE], w[4];
- LONGEST off;
- int i;
-
- if (target_read_memory (pc, w, 4) != 0)
- return -1;
-
- for (i = 0; i < RETCODE_NWORDS; i++)
- {
- if (memcmp (w, sigtramp_retcode + (i * 4), 4) == 0)
- break;
- }
- if (i == RETCODE_NWORDS)
- return (-1);
-
- off = i * 4;
- pc -= off;
-
- if (target_read_memory (pc, ret, sizeof (ret)) != 0)
- return -1;
-
- if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0)
- return off;
-
- return -1;
-}
-
-static int
-alphanbsd_pc_in_sigtramp (struct gdbarch *gdbarch,
- CORE_ADDR pc, const char *func_name)
-{
- return (nbsd_pc_in_sigtramp (pc, func_name)
- || alphanbsd_sigtramp_offset (gdbarch, pc) >= 0);
-}
-
-static CORE_ADDR
-alphanbsd_sigcontext_addr (struct frame_info *frame)
-{
- /* FIXME: This is not correct for all versions of NetBSD/alpha.
- We will probably need to disassemble the trampoline to figure
- out which trampoline frame type we have. */
- if (!get_next_frame (frame))
- return 0;
- return get_frame_base (get_next_frame (frame));
-}
-\f
-
-static void
-alphanbsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Hook into the DWARF CFI frame unwinder. */
- alpha_dwarf2_init_abi (info, gdbarch);
-
- /* Hook into the MDEBUG frame unwinder. */
- alpha_mdebug_init_abi (info, gdbarch);
-
- /* NetBSD/alpha does not provide single step support via ptrace(2); we
- must use software single-stepping. */
- set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
-
- /* NetBSD/alpha has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-
- tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
- tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp;
- tdep->sigcontext_addr = alphanbsd_sigcontext_addr;
-
- tdep->jb_pc = 2;
- tdep->jb_elt_size = 8;
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, alphanbsd_iterate_over_regset_sections);
-}
-\f
-
-static enum gdb_osabi
-alphanbsd_core_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
- return GDB_OSABI_NETBSD_ELF;
-
- return GDB_OSABI_UNKNOWN;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_alphanbsd_tdep (void);
-
-void
-_initialize_alphanbsd_tdep (void)
-{
- /* BFD doesn't set a flavour for NetBSD style a.out core files. */
- gdbarch_register_osabi_sniffer (bfd_arch_alpha, bfd_target_unknown_flavour,
- alphanbsd_core_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_NETBSD_ELF,
- alphanbsd_init_abi);
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/alpha.
-
- Copyright (C) 2006-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "osabi.h"
-
-#include "obsd-tdep.h"
-#include "alpha-tdep.h"
-#include "alphabsd-tdep.h"
-#include "solib-svr4.h"
-
-/* Signal trampolines. */
-
-/* The OpenBSD kernel maps the signal trampoline at some random
- location in user space, which means that the traditional BSD way of
- detecting it won't work.
-
- The signal trampoline will be mapped at an address that is page
- aligned. We recognize the signal trampoline by looking for the
- sigreturn system call. */
-
-static const int alphaobsd_page_size = 8192;
-
-static LONGEST
-alphaobsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
-{
- return (pc & (alphaobsd_page_size - 1));
-}
-
-static int
-alphaobsd_pc_in_sigtramp (struct gdbarch *gdbarch,
- CORE_ADDR pc, const char *name)
-{
- CORE_ADDR start_pc = (pc & ~(alphaobsd_page_size - 1));
- unsigned insn;
-
- if (name)
- return 0;
-
- /* Check for "". */
- insn = alpha_read_insn (gdbarch, start_pc + 5 * ALPHA_INSN_SIZE);
- if (insn != 0x201f0067)
- return 0;
-
- /* Check for "". */
- insn = alpha_read_insn (gdbarch, start_pc + 6 * ALPHA_INSN_SIZE);
- if (insn != 0x00000083)
- return 0;
-
- return 1;
-}
-
-static CORE_ADDR
-alphaobsd_sigcontext_addr (struct frame_info *this_frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- CORE_ADDR pc = get_frame_pc (this_frame);
-
- if (alphaobsd_sigtramp_offset (gdbarch, pc) < 3 * ALPHA_INSN_SIZE)
- {
- /* On entry, a pointer the `struct sigcontext' is passed in %a2. */
- return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM + 2);
- }
- else if (alphaobsd_sigtramp_offset (gdbarch, pc) < 4 * ALPHA_INSN_SIZE)
- {
- /* It is stored on the stack Before calling the signal handler. */
- CORE_ADDR sp;
- sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
- return get_frame_memory_unsigned (this_frame, sp, 8);
- }
- else
- {
- /* It is reloaded into %a0 for the sigreturn(2) call. */
- return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM);
- }
-}
-\f
-
-static void
-alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Hook into the DWARF CFI frame unwinder. */
- alpha_dwarf2_init_abi (info, gdbarch);
-
- /* Hook into the MDEBUG frame unwinder. */
- alpha_mdebug_init_abi (info, gdbarch);
-
- /* OpenBSD/alpha 3.0 and earlier does not provide single step
- support via ptrace(2); use software single-stepping for now. */
- set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
-
- /* OpenBSD/alpha has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
- set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
-
- tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset;
- tdep->pc_in_sigtramp = alphaobsd_pc_in_sigtramp;
- tdep->sigcontext_addr = alphaobsd_sigcontext_addr;
-
- tdep->jb_pc = 2;
- tdep->jb_elt_size = 8;
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, alphanbsd_iterate_over_regset_sections);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_alphaobsd_tdep (void);
-
-void
-_initialize_alphaobsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD_ELF,
- alphaobsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for AMD64 BSD's.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+/* We include <signal.h> to make sure `struct fxsave64' is defined on
+ NetBSD, since NetBSD's <machine/reg.h> needs it. */
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "amd64-tdep.h"
+#include "amd64-nat.h"
+#include "x86-bsd-nat.h"
+#include "inf-ptrace.h"
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating-point registers). */
+
+static void
+amd64bsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ amd64_supply_native_gregset (regcache, ®s, -1);
+ if (regnum != -1)
+ return;
+ }
+
+ if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
+ {
+ struct fpreg fpregs;
+#ifdef PT_GETXSTATE_INFO
+ void *xstateregs;
+
+ if (x86bsd_xsave_len != 0)
+ {
+ xstateregs = alloca (x86bsd_xsave_len);
+ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
+ perror_with_name (_("Couldn't get extended state status"));
+
+ amd64_supply_xsave (regcache, -1, xstateregs);
+ return;
+ }
+#endif
+
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ amd64_supply_fxsave (regcache, -1, &fpregs);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating-point registers). */
+
+static void
+amd64bsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ amd64_collect_native_gregset (regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+
+ if (regnum != -1)
+ return;
+ }
+
+ if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
+ {
+ struct fpreg fpregs;
+#ifdef PT_GETXSTATE_INFO
+ void *xstateregs;
+
+ if (x86bsd_xsave_len != 0)
+ {
+ xstateregs = alloca (x86bsd_xsave_len);
+ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
+ perror_with_name (_("Couldn't get extended state status"));
+
+ amd64_collect_xsave (regcache, regnum, xstateregs, 0);
+
+ if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xstateregs, x86bsd_xsave_len) == -1)
+ perror_with_name (_("Couldn't write extended state status"));
+ return;
+ }
+#endif
+
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ amd64_collect_fxsave (regcache, regnum, &fpregs);
+
+ if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+ }
+}
+
+/* Create a prototype *BSD/amd64 target. The client can override it
+ with local methods. */
+
+struct target_ops *
+amd64bsd_target (void)
+{
+ struct target_ops *t;
+
+ t = x86bsd_target ();
+ t->to_fetch_registers = amd64bsd_fetch_inferior_registers;
+ t->to_store_registers = amd64bsd_store_inferior_registers;
+ return t;
+}
--- /dev/null
+/* Native-dependent code for FreeBSD/amd64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+#include <machine/reg.h>
+
+#include "fbsd-nat.h"
+#include "amd64-tdep.h"
+#include "amd64-nat.h"
+#include "x86-bsd-nat.h"
+#include "x86-nat.h"
+\f
+
+/* Offset in `struct reg' where MEMBER is stored. */
+#define REG_OFFSET(member) offsetof (struct reg, member)
+
+/* At amd64fbsd64_r_reg_offset[REGNUM] you'll find the offset in
+ `struct reg' location where the GDB register REGNUM is stored.
+ Unsupported registers are marked with `-1'. */
+static int amd64fbsd64_r_reg_offset[] =
+{
+ REG_OFFSET (r_rax),
+ REG_OFFSET (r_rbx),
+ REG_OFFSET (r_rcx),
+ REG_OFFSET (r_rdx),
+ REG_OFFSET (r_rsi),
+ REG_OFFSET (r_rdi),
+ REG_OFFSET (r_rbp),
+ REG_OFFSET (r_rsp),
+ REG_OFFSET (r_r8),
+ REG_OFFSET (r_r9),
+ REG_OFFSET (r_r10),
+ REG_OFFSET (r_r11),
+ REG_OFFSET (r_r12),
+ REG_OFFSET (r_r13),
+ REG_OFFSET (r_r14),
+ REG_OFFSET (r_r15),
+ REG_OFFSET (r_rip),
+ REG_OFFSET (r_rflags),
+ REG_OFFSET (r_cs),
+ REG_OFFSET (r_ss),
+ -1,
+ -1,
+ -1,
+ -1
+};
+\f
+
+/* Mapping between the general-purpose registers in FreeBSD/amd64
+ `struct reg' format and GDB's register cache layout for
+ FreeBSD/i386.
+
+ Note that most FreeBSD/amd64 registers are 64-bit, while the
+ FreeBSD/i386 registers are all 32-bit, but since we're
+ little-endian we get away with that. */
+
+/* From <machine/reg.h>. */
+static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] =
+{
+ 14 * 8, 13 * 8, /* %eax, %ecx */
+ 12 * 8, 11 * 8, /* %edx, %ebx */
+ 20 * 8, 10 * 8, /* %esp, %ebp */
+ 9 * 8, 8 * 8, /* %esi, %edi */
+ 17 * 8, 19 * 8, /* %eip, %eflags */
+ 18 * 8, 21 * 8, /* %cs, %ss */
+ -1, -1, -1, -1 /* %ds, %es, %fs, %gs */
+};
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <machine/pcb.h>
+#include <osreldate.h>
+
+#include "bsd-kvm.h"
+
+static int
+amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ /* The following is true for FreeBSD 5.2:
+
+ The pcb contains %rip, %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15,
+ %ds, %es, %fs and %gs. This accounts for all callee-saved
+ registers specified by the psABI and then some. Here %esp
+ contains the stack pointer at the point just after the call to
+ cpu_switch(). From this information we reconstruct the register
+ state as it would like when we just returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_rsp == 0)
+ return 0;
+
+ pcb->pcb_rsp += 8;
+ regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &pcb->pcb_rip);
+ regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &pcb->pcb_rbx);
+ regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp);
+ regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp);
+ regcache_raw_supply (regcache, 12, &pcb->pcb_r12);
+ regcache_raw_supply (regcache, 13, &pcb->pcb_r13);
+ regcache_raw_supply (regcache, 14, &pcb->pcb_r14);
+ regcache_raw_supply (regcache, 15, &pcb->pcb_r15);
+#if (__FreeBSD_version < 800075) && (__FreeBSD_kernel_version < 800075)
+ /* struct pcb provides the pcb_ds/pcb_es/pcb_fs/pcb_gs fields only
+ up until __FreeBSD_version 800074: The removal of these fields
+ occurred on 2009-04-01 while the __FreeBSD_version number was
+ bumped to 800075 on 2009-04-06. So 800075 is the closest version
+ number where we should not try to access these fields. */
+ regcache_raw_supply (regcache, AMD64_DS_REGNUM, &pcb->pcb_ds);
+ regcache_raw_supply (regcache, AMD64_ES_REGNUM, &pcb->pcb_es);
+ regcache_raw_supply (regcache, AMD64_FS_REGNUM, &pcb->pcb_fs);
+ regcache_raw_supply (regcache, AMD64_GS_REGNUM, &pcb->pcb_gs);
+#endif
+
+ return 1;
+}
+\f
+
+/* Implement the to_read_description method. */
+
+static const struct target_desc *
+amd64fbsd_read_description (struct target_ops *ops)
+{
+#ifdef PT_GETXSTATE_INFO
+ static int xsave_probed;
+ static uint64_t xcr0;
+#endif
+ struct reg regs;
+ int is64;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+ is64 = (regs.r_cs == GSEL (GUCODE_SEL, SEL_UPL));
+#ifdef PT_GETXSTATE_INFO
+ if (!xsave_probed)
+ {
+ struct ptrace_xstate_info info;
+
+ if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
+ {
+ x86bsd_xsave_len = info.xsave_len;
+ xcr0 = info.xsave_mask;
+ }
+ xsave_probed = 1;
+ }
+
+ if (x86bsd_xsave_len != 0)
+ {
+ if (is64)
+ return amd64_target_description (xcr0);
+ else
+ return i386_target_description (xcr0);
+ }
+#endif
+ if (is64)
+ return tdesc_amd64;
+ else
+ return tdesc_i386;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_amd64fbsd_nat (void);
+
+void
+_initialize_amd64fbsd_nat (void)
+{
+ struct target_ops *t;
+ int offset;
+
+ amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset;
+ amd64_native_gregset64_reg_offset = amd64fbsd64_r_reg_offset;
+
+ /* Add some extra features to the common *BSD/i386 target. */
+ t = amd64bsd_target ();
+ t->to_read_description = amd64fbsd_read_description;
+
+ fbsd_nat_add_target (t);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (amd64fbsd_supply_pcb);
+
+ /* To support the recognition of signal handlers, i386-bsd-tdep.c
+ hardcodes some constants. Inclusion of this file means that we
+ are compiling a native debugger, which means that we can use the
+ system header files and sysctl(3) to get at the relevant
+ information. */
+
+#define SC_REG_OFFSET amd64fbsd_sc_reg_offset
+
+ /* We only check the program counter, stack pointer and frame
+ pointer since these members of `struct sigcontext' are essential
+ for providing backtraces. */
+
+#define SC_RIP_OFFSET SC_REG_OFFSET[AMD64_RIP_REGNUM]
+#define SC_RSP_OFFSET SC_REG_OFFSET[AMD64_RSP_REGNUM]
+#define SC_RBP_OFFSET SC_REG_OFFSET[AMD64_RBP_REGNUM]
+
+ /* Override the default value for the offset of the program counter
+ in the sigcontext structure. */
+ offset = offsetof (struct sigcontext, sc_rip);
+
+ if (SC_RIP_OFFSET != offset)
+ {
+ warning (_("\
+offsetof (struct sigcontext, sc_rip) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>."),
+ offset, SC_RIP_OFFSET);
+ }
+
+ SC_RIP_OFFSET = offset;
+
+ /* Likewise for the stack pointer. */
+ offset = offsetof (struct sigcontext, sc_rsp);
+
+ if (SC_RSP_OFFSET != offset)
+ {
+ warning (_("\
+offsetof (struct sigcontext, sc_rsp) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>."),
+ offset, SC_RSP_OFFSET);
+ }
+
+ SC_RSP_OFFSET = offset;
+
+ /* And the frame pointer. */
+ offset = offsetof (struct sigcontext, sc_rbp);
+
+ if (SC_RBP_OFFSET != offset)
+ {
+ warning (_("\
+offsetof (struct sigcontext, sc_rbp) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>."),
+ offset, SC_RBP_OFFSET);
+ }
+
+ SC_RBP_OFFSET = offset;
+
+#ifdef KERN_PROC_SIGTRAMP
+ /* Normally signal frames are detected via amd64fbsd_sigtramp_p.
+ However, FreeBSD 9.2 through 10.1 do not include the page holding
+ the signal code in core dumps. These releases do provide a
+ kern.proc.sigtramp.<pid> sysctl that returns the location of the
+ signal trampoline for a running process. We fetch the location
+ of the current (gdb) process and use this to identify signal
+ frames in core dumps from these releases. Note that this only
+ works for core dumps of 64-bit (FreeBSD/amd64) processes and does
+ not handle core dumps of 32-bit (FreeBSD/i386) processes. */
+ {
+ int mib[4];
+ struct kinfo_sigtramp kst;
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_SIGTRAMP;
+ mib[3] = getpid ();
+ len = sizeof (kst);
+ if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0)
+ {
+ amd64fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start;
+ amd64fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end;
+ }
+ }
+#endif
+}
--- /dev/null
+/* Target-dependent code for FreeBSD/amd64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "osabi.h"
+#include "regset.h"
+#include "i386-fbsd-tdep.h"
+#include "x86-xstate.h"
+
+#include "amd64-tdep.h"
+#include "bsd-uthread.h"
+#include "fbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Support for signal handlers. */
+
+/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp
+ routine. */
+
+static const gdb_byte amd64fbsd_sigtramp_code[] =
+{
+ 0x48, 0x8d, 0x7c, 0x24, 0x10, /* lea SIGF_UC(%rsp),%rdi */
+ 0x6a, 0x00, /* pushq $0 */
+ 0x48, 0xc7, 0xc0, 0xa1, 0x01, 0x00, 0x00,
+ /* movq $SYS_sigreturn,%rax */
+ 0x0f, 0x05 /* syscall */
+};
+
+static int
+amd64fbsd_sigtramp_p (struct frame_info *this_frame)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ gdb_byte buf[sizeof amd64fbsd_sigtramp_code];
+
+ if (!safe_frame_unwind_memory (this_frame, pc, buf, sizeof buf))
+ return 0;
+ if (memcmp (buf, amd64fbsd_sigtramp_code, sizeof amd64fbsd_sigtramp_code)
+ != 0)
+ return 0;
+
+ return 1;
+}
+
+/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
+ address of the associated sigcontext structure. */
+
+static CORE_ADDR
+amd64fbsd_sigcontext_addr (struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp;
+ gdb_byte buf[8];
+
+ /* The `struct sigcontext' (which really is an `ucontext_t' on
+ FreeBSD/amd64) lives at a fixed offset in the signal frame. See
+ <machine/sigframe.h>. */
+ get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
+ sp = extract_unsigned_integer (buf, 8, byte_order);
+ return sp + 16;
+}
+\f
+/* FreeBSD 5.1-RELEASE or later. */
+
+/* Mapping between the general-purpose registers in `struct reg'
+ format and GDB's register cache layout.
+
+ Note that some registers are 32-bit, but since we're little-endian
+ we get away with that. */
+
+/* From <machine/reg.h>. */
+static int amd64fbsd_r_reg_offset[] =
+{
+ 14 * 8, /* %rax */
+ 11 * 8, /* %rbx */
+ 13 * 8, /* %rcx */
+ 12 * 8, /* %rdx */
+ 9 * 8, /* %rsi */
+ 8 * 8, /* %rdi */
+ 10 * 8, /* %rbp */
+ 20 * 8, /* %rsp */
+ 7 * 8, /* %r8 ... */
+ 6 * 8,
+ 5 * 8,
+ 4 * 8,
+ 3 * 8,
+ 2 * 8,
+ 1 * 8,
+ 0 * 8, /* ... %r15 */
+ 17 * 8, /* %rip */
+ 19 * 8, /* %eflags */
+ 18 * 8, /* %cs */
+ 21 * 8, /* %ss */
+ -1, /* %ds */
+ -1, /* %es */
+ -1, /* %fs */
+ -1 /* %gs */
+};
+
+/* Location of the signal trampoline. */
+CORE_ADDR amd64fbsd_sigtramp_start_addr;
+CORE_ADDR amd64fbsd_sigtramp_end_addr;
+
+/* From <machine/signal.h>. */
+int amd64fbsd_sc_reg_offset[] =
+{
+ 24 + 6 * 8, /* %rax */
+ 24 + 7 * 8, /* %rbx */
+ 24 + 3 * 8, /* %rcx */
+ 24 + 2 * 8, /* %rdx */
+ 24 + 1 * 8, /* %rsi */
+ 24 + 0 * 8, /* %rdi */
+ 24 + 8 * 8, /* %rbp */
+ 24 + 22 * 8, /* %rsp */
+ 24 + 4 * 8, /* %r8 ... */
+ 24 + 5 * 8,
+ 24 + 9 * 8,
+ 24 + 10 * 8,
+ 24 + 11 * 8,
+ 24 + 12 * 8,
+ 24 + 13 * 8,
+ 24 + 14 * 8, /* ... %r15 */
+ 24 + 19 * 8, /* %rip */
+ 24 + 21 * 8, /* %eflags */
+ 24 + 20 * 8, /* %cs */
+ 24 + 23 * 8, /* %ss */
+ -1, /* %ds */
+ -1, /* %es */
+ -1, /* %fs */
+ -1 /* %gs */
+};
+
+/* From /usr/src/lib/libc/amd64/gen/_setjmp.S. */
+static int amd64fbsd_jmp_buf_reg_offset[] =
+{
+ -1, /* %rax */
+ 1 * 8, /* %rbx */
+ -1, /* %rcx */
+ -1, /* %rdx */
+ -1, /* %rsi */
+ -1, /* %rdi */
+ 3 * 8, /* %rbp */
+ 2 * 8, /* %rsp */
+ -1, /* %r8 ... */
+ -1,
+ -1,
+ -1, /* ... %r11 */
+ 4 * 8, /* %r12 ... */
+ 5 * 8,
+ 6 * 8,
+ 7 * 8, /* ... %r15 */
+ 0 * 8 /* %rip */
+};
+
+/* Implement the core_read_description gdbarch method. */
+
+static const struct target_desc *
+amd64fbsd_core_read_description (struct gdbarch *gdbarch,
+ struct target_ops *target,
+ bfd *abfd)
+{
+ return amd64_target_description (i386fbsd_core_read_xcr0 (abfd));
+}
+
+/* Similar to amd64_supply_fpregset, but use XSAVE extended state. */
+
+static void
+amd64fbsd_supply_xstateregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *xstateregs, size_t len)
+{
+ amd64_supply_xsave (regcache, regnum, xstateregs);
+}
+
+/* Similar to amd64_collect_fpregset, but use XSAVE extended state. */
+
+static void
+amd64fbsd_collect_xstateregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *xstateregs, size_t len)
+{
+ amd64_collect_xsave (regcache, regnum, xstateregs, 1);
+}
+
+static const struct regset amd64fbsd_xstateregset =
+ {
+ NULL,
+ amd64fbsd_supply_xstateregset,
+ amd64fbsd_collect_xstateregset
+ };
+
+/* Iterate over core file register note sections. */
+
+static void
+amd64fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ cb (".reg", tdep->sizeof_gregset, &i386_gregset, NULL, cb_data);
+ cb (".reg2", tdep->sizeof_fpregset, &amd64_fpregset, NULL, cb_data);
+ cb (".reg-xstate", X86_XSTATE_SIZE(tdep->xcr0),
+ &amd64fbsd_xstateregset, "XSAVE extended state", cb_data);
+}
+
+static void
+amd64fbsd_supply_uthread (struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ gdb_byte buf[8];
+ int i;
+
+ gdb_assert (regnum >= -1);
+
+ for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
+ {
+ if (amd64fbsd_jmp_buf_reg_offset[i] != -1
+ && (regnum == -1 || regnum == i))
+ {
+ read_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
+ regcache_raw_supply (regcache, i, buf);
+ }
+ }
+}
+
+static void
+amd64fbsd_collect_uthread (const struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ gdb_byte buf[8];
+ int i;
+
+ gdb_assert (regnum >= -1);
+
+ for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
+ {
+ if (amd64fbsd_jmp_buf_reg_offset[i] != -1
+ && (regnum == -1 || regnum == i))
+ {
+ regcache_raw_collect (regcache, i, buf);
+ write_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
+ }
+ }
+}
+
+static void
+amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Generic FreeBSD support. */
+ fbsd_init_abi (info, gdbarch);
+
+ /* Obviously FreeBSD is BSD-based. */
+ i386bsd_init_abi (info, gdbarch);
+
+ tdep->gregset_reg_offset = amd64fbsd_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset);
+ tdep->sizeof_gregset = 22 * 8;
+
+ amd64_init_abi (info, gdbarch);
+
+ tdep->sigtramp_p = amd64fbsd_sigtramp_p;
+ tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
+ tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr;
+ tdep->sigcontext_addr = amd64fbsd_sigcontext_addr;
+ tdep->sc_reg_offset = amd64fbsd_sc_reg_offset;
+ tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset);
+
+ tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET;
+
+ /* Iterate over core file register note sections. */
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, amd64fbsd_iterate_over_regset_sections);
+
+ set_gdbarch_core_read_description (gdbarch,
+ amd64fbsd_core_read_description);
+
+ /* FreeBSD provides a user-level threads implementation. */
+ bsd_uthread_set_supply_uthread (gdbarch, amd64fbsd_supply_uthread);
+ bsd_uthread_set_collect_uthread (gdbarch, amd64fbsd_collect_uthread);
+
+ /* FreeBSD uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_amd64fbsd_tdep (void);
+
+void
+_initialize_amd64fbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
+ GDB_OSABI_FREEBSD_ELF, amd64fbsd_init_abi);
+}
--- /dev/null
+/* Native-dependent code for NetBSD/amd64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "target.h"
+
+#include "nbsd-nat.h"
+#include "amd64-tdep.h"
+#include "amd64-nat.h"
+
+/* Mapping between the general-purpose registers in NetBSD/amd64
+ `struct reg' format and GDB's register cache layout for
+ NetBSD/i386.
+
+ Note that most (if not all) NetBSD/amd64 registers are 64-bit,
+ while the NetBSD/i386 registers are all 32-bit, but since we're
+ little-endian we get away with that. */
+
+/* From <machine/reg.h>. */
+static int amd64nbsd32_r_reg_offset[] =
+{
+ 14 * 8, /* %eax */
+ 3 * 8, /* %ecx */
+ 2 * 8, /* %edx */
+ 13 * 8, /* %ebx */
+ 24 * 8, /* %esp */
+ 12 * 8, /* %ebp */
+ 1 * 8, /* %esi */
+ 0 * 8, /* %edi */
+ 21 * 8, /* %eip */
+ 23 * 8, /* %eflags */
+ 22 * 8, /* %cs */
+ 25 * 8, /* %ss */
+ 18 * 8, /* %ds */
+ 17 * 8, /* %es */
+ 16 * 8, /* %fs */
+ 15 * 8 /* %gs */
+};
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_amd64nbsd_nat (void);
+
+void
+_initialize_amd64nbsd_nat (void)
+{
+ struct target_ops *t;
+
+ amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset;
+ amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset);
+ amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset;
+
+ /* Add some extra features to the common *BSD/amd64 target. */
+ t = amd64bsd_target ();
+ t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
+ add_target (t);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/amd64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "symtab.h"
+
+#include "amd64-tdep.h"
+#include "nbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Support for signal handlers. */
+
+/* Return whether THIS_FRAME corresponds to a NetBSD sigtramp
+ routine. */
+
+static int
+amd64nbsd_sigtramp_p (struct frame_info *this_frame)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ return nbsd_pc_in_sigtramp (pc, name);
+}
+
+/* Assuming THIS_FRAME corresponds to a NetBSD sigtramp routine,
+ return the address of the associated mcontext structure. */
+
+static CORE_ADDR
+amd64nbsd_mcontext_addr (struct frame_info *this_frame)
+{
+ CORE_ADDR addr;
+
+ /* The register %r15 points at `struct ucontext' upon entry of a
+ signal trampoline. */
+ addr = get_frame_register_unsigned (this_frame, AMD64_R15_REGNUM);
+
+ /* The mcontext structure lives as offset 56 in `struct ucontext'. */
+ return addr + 56;
+}
+\f
+/* NetBSD 2.0 or later. */
+
+/* Mapping between the general-purpose registers in `struct reg'
+ format and GDB's register cache layout. */
+
+/* From <machine/reg.h>. */
+int amd64nbsd_r_reg_offset[] =
+{
+ 14 * 8, /* %rax */
+ 13 * 8, /* %rbx */
+ 3 * 8, /* %rcx */
+ 2 * 8, /* %rdx */
+ 1 * 8, /* %rsi */
+ 0 * 8, /* %rdi */
+ 12 * 8, /* %rbp */
+ 24 * 8, /* %rsp */
+ 4 * 8, /* %r8 .. */
+ 5 * 8,
+ 6 * 8,
+ 7 * 8,
+ 8 * 8,
+ 9 * 8,
+ 10 * 8,
+ 11 * 8, /* ... %r15 */
+ 21 * 8, /* %rip */
+ 23 * 8, /* %eflags */
+ 22 * 8, /* %cs */
+ 25 * 8, /* %ss */
+ 18 * 8, /* %ds */
+ 17 * 8, /* %es */
+ 16 * 8, /* %fs */
+ 15 * 8 /* %gs */
+};
+
+static void
+amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Initialize general-purpose register set details first. */
+ tdep->gregset_reg_offset = amd64nbsd_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
+ tdep->sizeof_gregset = 26 * 8;
+
+ amd64_init_abi (info, gdbarch);
+
+ tdep->jb_pc_offset = 7 * 8;
+
+ /* NetBSD has its own convention for signal trampolines. */
+ tdep->sigtramp_p = amd64nbsd_sigtramp_p;
+ tdep->sigcontext_addr = amd64nbsd_mcontext_addr;
+ tdep->sc_reg_offset = amd64nbsd_r_reg_offset;
+ tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
+
+ /* NetBSD uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_amd64nbsd_tdep (void);
+
+void
+_initialize_amd64nbsd_tdep (void)
+{
+ /* The NetBSD/amd64 native dependent code makes this assumption. */
+ gdb_assert (ARRAY_SIZE (amd64nbsd_r_reg_offset) == AMD64_NUM_GREGS);
+
+ gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
+ GDB_OSABI_NETBSD_ELF, amd64nbsd_init_abi);
+}
--- /dev/null
+/* Native-dependent code for OpenBSD/amd64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "amd64-tdep.h"
+#include "amd64-nat.h"
+#include "obsd-nat.h"
+
+/* Mapping between the general-purpose registers in OpenBSD/amd64
+ `struct reg' format and GDB's register cache layout for
+ OpenBSD/i386.
+
+ Note that most (if not all) OpenBSD/amd64 registers are 64-bit,
+ while the OpenBSD/i386 registers are all 32-bit, but since we're
+ little-endian we get away with that. */
+
+/* From <machine/reg.h>. */
+static int amd64obsd32_r_reg_offset[] =
+{
+ 14 * 8, /* %eax */
+ 3 * 8, /* %ecx */
+ 2 * 8, /* %edx */
+ 13 * 8, /* %ebx */
+ 15 * 8, /* %esp */
+ 12 * 8, /* %ebp */
+ 1 * 8, /* %esi */
+ 0 * 8, /* %edi */
+ 16 * 8, /* %eip */
+ 17 * 8, /* %eflags */
+ 18 * 8, /* %cs */
+ 19 * 8, /* %ss */
+ 20 * 8, /* %ds */
+ 21 * 8, /* %es */
+ 22 * 8, /* %fs */
+ 23 * 8 /* %gs */
+};
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+amd64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ struct switchframe sf;
+ int regnum;
+
+ /* The following is true for OpenBSD 3.5:
+
+ The pcb contains the stack pointer at the point of the context
+ switch in cpu_switch(). At that point we have a stack frame as
+ described by `struct switchframe', which for OpenBSD 3.5 has the
+ following layout:
+
+ interrupt level
+ %r15
+ %r14
+ %r13
+ %r12
+ %rbp
+ %rbx
+ return address
+
+ Together with %rsp in the pcb, this accounts for all callee-saved
+ registers specified by the psABI. From this information we
+ reconstruct the register state as it would look when we just
+ returned from cpu_switch().
+
+ For core dumps the pcb is saved by savectx(). In that case the
+ stack frame only contains the return address, and there is no way
+ to recover the other registers. */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_rsp == 0)
+ return 0;
+
+ /* Read the stack frame, and check its validity. */
+ read_memory (pcb->pcb_rsp, (gdb_byte *) &sf, sizeof sf);
+ if (sf.sf_rbp == pcb->pcb_rbp)
+ {
+ /* Yes, we have a frame that matches cpu_switch(). */
+ pcb->pcb_rsp += sizeof (struct switchframe);
+ regcache_raw_supply (regcache, 12, &sf.sf_r12);
+ regcache_raw_supply (regcache, 13, &sf.sf_r13);
+ regcache_raw_supply (regcache, 14, &sf.sf_r14);
+ regcache_raw_supply (regcache, 15, &sf.sf_r15);
+ regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &sf.sf_rbx);
+ regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf.sf_rip);
+ }
+ else
+ {
+ /* No, the pcb must have been last updated by savectx(). */
+ pcb->pcb_rsp += 8;
+ regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf);
+ }
+
+ regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp);
+ regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_amd64obsd_nat (void);
+
+void
+_initialize_amd64obsd_nat (void)
+{
+ amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset;
+ amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset);
+ amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset;
+
+ /* Add some extra features to the common *BSD/amd64 target. */
+ obsd_add_target (amd64bsd_target ());
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (amd64obsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/amd64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "symtab.h"
+#include "objfiles.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "target.h"
+#include "trad-frame.h"
+
+#include "obsd-tdep.h"
+#include "amd64-tdep.h"
+#include "i387-tdep.h"
+#include "solib-svr4.h"
+#include "bsd-uthread.h"
+
+/* Support for core dumps. */
+
+static void
+amd64obsd_supply_regset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *regs, size_t len)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE);
+
+ i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
+ amd64_supply_fxsave (regcache, regnum,
+ ((const gdb_byte *)regs) + tdep->sizeof_gregset);
+}
+
+static const struct regset amd64obsd_combined_regset =
+ {
+ NULL, amd64obsd_supply_regset, NULL
+ };
+
+static void
+amd64obsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* OpenBSD core dumps don't use seperate register sets for the
+ general-purpose and floating-point registers. */
+
+ cb (".reg", tdep->sizeof_gregset + I387_SIZEOF_FXSAVE,
+ &amd64obsd_combined_regset, NULL, cb_data);
+}
+\f
+
+/* Support for signal handlers. */
+
+/* Default page size. */
+static const int amd64obsd_page_size = 4096;
+
+/* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp
+ routine. */
+
+static int
+amd64obsd_sigtramp_p (struct frame_info *this_frame)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1));
+ const gdb_byte osigreturn[] =
+ {
+ 0x48, 0xc7, 0xc0,
+ 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */
+ 0xcd, 0x80 /* int $0x80 */
+ };
+ const gdb_byte sigreturn[] =
+ {
+ 0x48, 0xc7, 0xc0,
+ 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */
+ 0x0f, 0x05 /* syscall */
+ };
+ size_t buflen = (sizeof sigreturn) + 1;
+ gdb_byte *buf;
+ const char *name;
+
+ /* If the function has a valid symbol name, it isn't a
+ trampoline. */
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (name != NULL)
+ return 0;
+
+ /* If the function lives in a valid section (even without a starting
+ point) it isn't a trampoline. */
+ if (find_pc_section (pc) != NULL)
+ return 0;
+
+ /* If we can't read the instructions at START_PC, return zero. */
+ buf = (gdb_byte *) alloca ((sizeof sigreturn) + 1);
+ if (!safe_frame_unwind_memory (this_frame, start_pc + 6, buf, buflen))
+ return 0;
+
+ /* Check for sigreturn(2). Depending on how the assembler encoded
+ the `movq %rsp, %rdi' instruction, the code starts at offset 6 or
+ 7. OpenBSD 5.0 and later use the `syscall' instruction. Older
+ versions use `int $0x80'. Check for both. */
+ if (memcmp (buf, sigreturn, sizeof sigreturn)
+ && memcmp (buf + 1, sigreturn, sizeof sigreturn)
+ && memcmp (buf, osigreturn, sizeof osigreturn)
+ && memcmp (buf + 1, osigreturn, sizeof osigreturn))
+ return 0;
+
+ return 1;
+}
+
+/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
+ address of the associated sigcontext structure. */
+
+static CORE_ADDR
+amd64obsd_sigcontext_addr (struct frame_info *this_frame)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ ULONGEST offset = (pc & (amd64obsd_page_size - 1));
+
+ /* The %rsp register points at `struct sigcontext' upon entry of a
+ signal trampoline. The relevant part of the trampoline is
+
+ call *%rax
+ movq %rsp, %rdi
+ pushq %rdi
+ movq $SYS_sigreturn,%rax
+ int $0x80
+
+ (see /usr/src/sys/arch/amd64/amd64/locore.S). The `pushq'
+ instruction clobbers %rsp, but its value is saved in `%rdi'. */
+
+ if (offset > 5)
+ return get_frame_register_unsigned (this_frame, AMD64_RDI_REGNUM);
+ else
+ return get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
+}
+\f
+/* OpenBSD 3.5 or later. */
+
+/* Mapping between the general-purpose registers in `struct reg'
+ format and GDB's register cache layout. */
+
+/* From <machine/reg.h>. */
+int amd64obsd_r_reg_offset[] =
+{
+ 14 * 8, /* %rax */
+ 13 * 8, /* %rbx */
+ 3 * 8, /* %rcx */
+ 2 * 8, /* %rdx */
+ 1 * 8, /* %rsi */
+ 0 * 8, /* %rdi */
+ 12 * 8, /* %rbp */
+ 15 * 8, /* %rsp */
+ 4 * 8, /* %r8 .. */
+ 5 * 8,
+ 6 * 8,
+ 7 * 8,
+ 8 * 8,
+ 9 * 8,
+ 10 * 8,
+ 11 * 8, /* ... %r15 */
+ 16 * 8, /* %rip */
+ 17 * 8, /* %eflags */
+ 18 * 8, /* %cs */
+ 19 * 8, /* %ss */
+ 20 * 8, /* %ds */
+ 21 * 8, /* %es */
+ 22 * 8, /* %fs */
+ 23 * 8 /* %gs */
+};
+
+/* From <machine/signal.h>. */
+static int amd64obsd_sc_reg_offset[] =
+{
+ 14 * 8, /* %rax */
+ 13 * 8, /* %rbx */
+ 3 * 8, /* %rcx */
+ 2 * 8, /* %rdx */
+ 1 * 8, /* %rsi */
+ 0 * 8, /* %rdi */
+ 12 * 8, /* %rbp */
+ 24 * 8, /* %rsp */
+ 4 * 8, /* %r8 ... */
+ 5 * 8,
+ 6 * 8,
+ 7 * 8,
+ 8 * 8,
+ 9 * 8,
+ 10 * 8,
+ 11 * 8, /* ... %r15 */
+ 21 * 8, /* %rip */
+ 23 * 8, /* %eflags */
+ 22 * 8, /* %cs */
+ 25 * 8, /* %ss */
+ 18 * 8, /* %ds */
+ 17 * 8, /* %es */
+ 16 * 8, /* %fs */
+ 15 * 8 /* %gs */
+};
+
+/* From /usr/src/lib/libpthread/arch/amd64/uthread_machdep.c. */
+static int amd64obsd_uthread_reg_offset[] =
+{
+ 19 * 8, /* %rax */
+ 16 * 8, /* %rbx */
+ 18 * 8, /* %rcx */
+ 17 * 8, /* %rdx */
+ 14 * 8, /* %rsi */
+ 13 * 8, /* %rdi */
+ 15 * 8, /* %rbp */
+ -1, /* %rsp */
+ 12 * 8, /* %r8 ... */
+ 11 * 8,
+ 10 * 8,
+ 9 * 8,
+ 8 * 8,
+ 7 * 8,
+ 6 * 8,
+ 5 * 8, /* ... %r15 */
+ 20 * 8, /* %rip */
+ 4 * 8, /* %eflags */
+ 21 * 8, /* %cs */
+ -1, /* %ss */
+ 3 * 8, /* %ds */
+ 2 * 8, /* %es */
+ 1 * 8, /* %fs */
+ 0 * 8 /* %gs */
+};
+
+/* Offset within the thread structure where we can find the saved
+ stack pointer (%esp). */
+#define AMD64OBSD_UTHREAD_RSP_OFFSET 400
+
+static void
+amd64obsd_supply_uthread (struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
+ CORE_ADDR sp = 0;
+ gdb_byte buf[8];
+ int i;
+
+ gdb_assert (regnum >= -1);
+
+ if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
+ {
+ int offset;
+
+ /* Fetch stack pointer from thread structure. */
+ sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
+
+ /* Adjust the stack pointer such that it looks as if we just
+ returned from _thread_machdep_switch. */
+ offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
+ store_unsigned_integer (buf, 8, byte_order, sp + offset);
+ regcache_raw_supply (regcache, AMD64_RSP_REGNUM, buf);
+ }
+
+ for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
+ {
+ if (amd64obsd_uthread_reg_offset[i] != -1
+ && (regnum == -1 || regnum == i))
+ {
+ /* Fetch stack pointer from thread structure (if we didn't
+ do so already). */
+ if (sp == 0)
+ sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
+
+ /* Read the saved register from the stack frame. */
+ read_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
+ regcache_raw_supply (regcache, i, buf);
+ }
+ }
+}
+
+static void
+amd64obsd_collect_uthread (const struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
+ CORE_ADDR sp = 0;
+ gdb_byte buf[8];
+ int i;
+
+ gdb_assert (regnum >= -1);
+
+ if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
+ {
+ int offset;
+
+ /* Calculate the stack pointer (frame pointer) that will be
+ stored into the thread structure. */
+ offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
+ regcache_raw_collect (regcache, AMD64_RSP_REGNUM, buf);
+ sp = extract_unsigned_integer (buf, 8, byte_order) - offset;
+
+ /* Store the stack pointer. */
+ write_memory_unsigned_integer (sp_addr, 8, byte_order, sp);
+
+ /* The stack pointer was (potentially) modified. Make sure we
+ build a proper stack frame. */
+ regnum = -1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
+ {
+ if (amd64obsd_uthread_reg_offset[i] != -1
+ && (regnum == -1 || regnum == i))
+ {
+ /* Fetch stack pointer from thread structure (if we didn't
+ calculate it already). */
+ if (sp == 0)
+ sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
+
+ /* Write the register into the stack frame. */
+ regcache_raw_collect (regcache, i, buf);
+ write_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
+ }
+ }
+}
+/* Kernel debugging support. */
+
+/* From <machine/frame.h>. Easy since `struct trapframe' matches
+ `struct sigcontext'. */
+#define amd64obsd_tf_reg_offset amd64obsd_sc_reg_offset
+
+static struct trad_frame_cache *
+amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ struct trad_frame_cache *cache;
+ CORE_ADDR func, sp, addr;
+ ULONGEST cs;
+ const char *name;
+ int i;
+
+ if (*this_cache)
+ return (struct trad_frame_cache *) *this_cache;
+
+ cache = trad_frame_cache_zalloc (this_frame);
+ *this_cache = cache;
+
+ func = get_frame_func (this_frame);
+ sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
+
+ find_pc_partial_function (func, &name, NULL, NULL);
+ if (name && startswith (name, "Xintr"))
+ addr = sp + 8; /* It's an interrupt frame. */
+ else
+ addr = sp;
+
+ for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++)
+ if (amd64obsd_tf_reg_offset[i] != -1)
+ trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]);
+
+ /* Read %cs from trap frame. */
+ addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM];
+ cs = read_memory_unsigned_integer (addr, 8, byte_order);
+ if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
+ {
+ /* Trap from user space; terminate backtrace. */
+ trad_frame_set_id (cache, outer_frame_id);
+ }
+ else
+ {
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (cache, frame_id_build (sp + 16, func));
+ }
+
+ return cache;
+}
+
+static void
+amd64obsd_trapframe_this_id (struct frame_info *this_frame,
+ void **this_cache, struct frame_id *this_id)
+{
+ struct trad_frame_cache *cache =
+ amd64obsd_trapframe_cache (this_frame, this_cache);
+
+ trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+amd64obsd_trapframe_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct trad_frame_cache *cache =
+ amd64obsd_trapframe_cache (this_frame, this_cache);
+
+ return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static int
+amd64obsd_trapframe_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_prologue_cache)
+{
+ ULONGEST cs;
+ const char *name;
+
+ /* Check Current Privilege Level and bail out if we're not executing
+ in kernel space. */
+ cs = get_frame_register_unsigned (this_frame, AMD64_CS_REGNUM);
+ if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
+ return 0;
+
+ find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
+ return (name && ((strcmp (name, "calltrap") == 0)
+ || (strcmp (name, "osyscall1") == 0)
+ || (strcmp (name, "Xsyscall") == 0)
+ || (startswith (name, "Xintr"))));
+}
+
+static const struct frame_unwind amd64obsd_trapframe_unwind = {
+ /* FIXME: kettenis/20051219: This really is more like an interrupt
+ frame, but SIGTRAMP_FRAME would print <signal handler called>,
+ which really is not what we want here. */
+ NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
+ amd64obsd_trapframe_this_id,
+ amd64obsd_trapframe_prev_register,
+ NULL,
+ amd64obsd_trapframe_sniffer
+};
+\f
+
+static void
+amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ amd64_init_abi (info, gdbarch);
+ obsd_init_abi (info, gdbarch);
+
+ /* Initialize general-purpose register set details. */
+ tdep->gregset_reg_offset = amd64obsd_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (amd64obsd_r_reg_offset);
+ tdep->sizeof_gregset = 24 * 8;
+
+ tdep->jb_pc_offset = 7 * 8;
+
+ tdep->sigtramp_p = amd64obsd_sigtramp_p;
+ tdep->sigcontext_addr = amd64obsd_sigcontext_addr;
+ tdep->sc_reg_offset = amd64obsd_sc_reg_offset;
+ tdep->sc_num_regs = ARRAY_SIZE (amd64obsd_sc_reg_offset);
+
+ /* OpenBSD provides a user-level threads implementation. */
+ bsd_uthread_set_supply_uthread (gdbarch, amd64obsd_supply_uthread);
+ bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread);
+
+ /* OpenBSD uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+
+ /* Unwind kernel trap frames correctly. */
+ frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind);
+}
+
+/* Traditional (a.out) NetBSD-style core dumps. */
+
+static void
+amd64obsd_core_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ amd64obsd_init_abi (info, gdbarch);
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, amd64obsd_iterate_over_regset_sections);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_amd64obsd_tdep (void);
+
+void
+_initialize_amd64obsd_tdep (void)
+{
+ /* The OpenBSD/amd64 native dependent code makes this assumption. */
+ gdb_assert (ARRAY_SIZE (amd64obsd_r_reg_offset) == AMD64_NUM_GREGS);
+
+ gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
+ GDB_OSABI_OPENBSD_ELF, amd64obsd_init_abi);
+
+ /* OpenBSD uses traditional (a.out) NetBSD-style core dumps. */
+ gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
+ GDB_OSABI_NETBSD_AOUT, amd64obsd_core_init_abi);
+}
/* Variables exported from amd64-linux-tdep.c. */
extern int amd64_linux_gregset_reg_offset[];
-/* Variables exported from amd64nbsd-tdep.c. */
+/* Variables exported from amd64-nbsd-tdep.c. */
extern int amd64nbsd_r_reg_offset[];
-/* Variables exported from amd64obsd-tdep.c. */
+/* Variables exported from amd64-obsd-tdep.c. */
extern int amd64obsd_r_reg_offset[];
-/* Variables exported from amd64fbsd-tdep.c. */
+/* Variables exported from amd64-fbsd-tdep.c. */
extern CORE_ADDR amd64fbsd_sigtramp_start_addr;
extern CORE_ADDR amd64fbsd_sigtramp_end_addr;
extern int amd64fbsd_sc_reg_offset[];
+++ /dev/null
-/* Native-dependent code for AMD64 BSD's.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-
-/* We include <signal.h> to make sure `struct fxsave64' is defined on
- NetBSD, since NetBSD's <machine/reg.h> needs it. */
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "amd64-tdep.h"
-#include "amd64-nat.h"
-#include "x86bsd-nat.h"
-#include "inf-ptrace.h"
-\f
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers (including the floating-point registers). */
-
-static void
-amd64bsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
-
- if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- amd64_supply_native_gregset (regcache, ®s, -1);
- if (regnum != -1)
- return;
- }
-
- if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
- {
- struct fpreg fpregs;
-#ifdef PT_GETXSTATE_INFO
- void *xstateregs;
-
- if (x86bsd_xsave_len != 0)
- {
- xstateregs = alloca (x86bsd_xsave_len);
- if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
- perror_with_name (_("Couldn't get extended state status"));
-
- amd64_supply_xsave (regcache, -1, xstateregs);
- return;
- }
-#endif
-
- if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- amd64_supply_fxsave (regcache, -1, &fpregs);
- }
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers (including the floating-point registers). */
-
-static void
-amd64bsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
-
- if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- amd64_collect_native_gregset (regcache, ®s, regnum);
-
- if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-
- if (regnum != -1)
- return;
- }
-
- if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
- {
- struct fpreg fpregs;
-#ifdef PT_GETXSTATE_INFO
- void *xstateregs;
-
- if (x86bsd_xsave_len != 0)
- {
- xstateregs = alloca (x86bsd_xsave_len);
- if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
- perror_with_name (_("Couldn't get extended state status"));
-
- amd64_collect_xsave (regcache, regnum, xstateregs, 0);
-
- if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) xstateregs, x86bsd_xsave_len) == -1)
- perror_with_name (_("Couldn't write extended state status"));
- return;
- }
-#endif
-
- if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- amd64_collect_fxsave (regcache, regnum, &fpregs);
-
- if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't write floating point status"));
- }
-}
-
-/* Create a prototype *BSD/amd64 target. The client can override it
- with local methods. */
-
-struct target_ops *
-amd64bsd_target (void)
-{
- struct target_ops *t;
-
- t = x86bsd_target ();
- t->to_fetch_registers = amd64bsd_fetch_inferior_registers;
- t->to_store_registers = amd64bsd_store_inferior_registers;
- return t;
-}
+++ /dev/null
-/* Native-dependent code for FreeBSD/amd64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <sys/sysctl.h>
-#include <sys/user.h>
-#include <machine/reg.h>
-
-#include "fbsd-nat.h"
-#include "amd64-tdep.h"
-#include "amd64-nat.h"
-#include "x86bsd-nat.h"
-#include "x86-nat.h"
-\f
-
-/* Offset in `struct reg' where MEMBER is stored. */
-#define REG_OFFSET(member) offsetof (struct reg, member)
-
-/* At amd64fbsd64_r_reg_offset[REGNUM] you'll find the offset in
- `struct reg' location where the GDB register REGNUM is stored.
- Unsupported registers are marked with `-1'. */
-static int amd64fbsd64_r_reg_offset[] =
-{
- REG_OFFSET (r_rax),
- REG_OFFSET (r_rbx),
- REG_OFFSET (r_rcx),
- REG_OFFSET (r_rdx),
- REG_OFFSET (r_rsi),
- REG_OFFSET (r_rdi),
- REG_OFFSET (r_rbp),
- REG_OFFSET (r_rsp),
- REG_OFFSET (r_r8),
- REG_OFFSET (r_r9),
- REG_OFFSET (r_r10),
- REG_OFFSET (r_r11),
- REG_OFFSET (r_r12),
- REG_OFFSET (r_r13),
- REG_OFFSET (r_r14),
- REG_OFFSET (r_r15),
- REG_OFFSET (r_rip),
- REG_OFFSET (r_rflags),
- REG_OFFSET (r_cs),
- REG_OFFSET (r_ss),
- -1,
- -1,
- -1,
- -1
-};
-\f
-
-/* Mapping between the general-purpose registers in FreeBSD/amd64
- `struct reg' format and GDB's register cache layout for
- FreeBSD/i386.
-
- Note that most FreeBSD/amd64 registers are 64-bit, while the
- FreeBSD/i386 registers are all 32-bit, but since we're
- little-endian we get away with that. */
-
-/* From <machine/reg.h>. */
-static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] =
-{
- 14 * 8, 13 * 8, /* %eax, %ecx */
- 12 * 8, 11 * 8, /* %edx, %ebx */
- 20 * 8, 10 * 8, /* %esp, %ebp */
- 9 * 8, 8 * 8, /* %esi, %edi */
- 17 * 8, 19 * 8, /* %eip, %eflags */
- 18 * 8, 21 * 8, /* %cs, %ss */
- -1, -1, -1, -1 /* %ds, %es, %fs, %gs */
-};
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <machine/pcb.h>
-#include <osreldate.h>
-
-#include "bsd-kvm.h"
-
-static int
-amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- /* The following is true for FreeBSD 5.2:
-
- The pcb contains %rip, %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15,
- %ds, %es, %fs and %gs. This accounts for all callee-saved
- registers specified by the psABI and then some. Here %esp
- contains the stack pointer at the point just after the call to
- cpu_switch(). From this information we reconstruct the register
- state as it would like when we just returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_rsp == 0)
- return 0;
-
- pcb->pcb_rsp += 8;
- regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &pcb->pcb_rip);
- regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &pcb->pcb_rbx);
- regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp);
- regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp);
- regcache_raw_supply (regcache, 12, &pcb->pcb_r12);
- regcache_raw_supply (regcache, 13, &pcb->pcb_r13);
- regcache_raw_supply (regcache, 14, &pcb->pcb_r14);
- regcache_raw_supply (regcache, 15, &pcb->pcb_r15);
-#if (__FreeBSD_version < 800075) && (__FreeBSD_kernel_version < 800075)
- /* struct pcb provides the pcb_ds/pcb_es/pcb_fs/pcb_gs fields only
- up until __FreeBSD_version 800074: The removal of these fields
- occurred on 2009-04-01 while the __FreeBSD_version number was
- bumped to 800075 on 2009-04-06. So 800075 is the closest version
- number where we should not try to access these fields. */
- regcache_raw_supply (regcache, AMD64_DS_REGNUM, &pcb->pcb_ds);
- regcache_raw_supply (regcache, AMD64_ES_REGNUM, &pcb->pcb_es);
- regcache_raw_supply (regcache, AMD64_FS_REGNUM, &pcb->pcb_fs);
- regcache_raw_supply (regcache, AMD64_GS_REGNUM, &pcb->pcb_gs);
-#endif
-
- return 1;
-}
-\f
-
-/* Implement the to_read_description method. */
-
-static const struct target_desc *
-amd64fbsd_read_description (struct target_ops *ops)
-{
-#ifdef PT_GETXSTATE_INFO
- static int xsave_probed;
- static uint64_t xcr0;
-#endif
- struct reg regs;
- int is64;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
- is64 = (regs.r_cs == GSEL (GUCODE_SEL, SEL_UPL));
-#ifdef PT_GETXSTATE_INFO
- if (!xsave_probed)
- {
- struct ptrace_xstate_info info;
-
- if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
- {
- x86bsd_xsave_len = info.xsave_len;
- xcr0 = info.xsave_mask;
- }
- xsave_probed = 1;
- }
-
- if (x86bsd_xsave_len != 0)
- {
- if (is64)
- return amd64_target_description (xcr0);
- else
- return i386_target_description (xcr0);
- }
-#endif
- if (is64)
- return tdesc_amd64;
- else
- return tdesc_i386;
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_amd64fbsd_nat (void);
-
-void
-_initialize_amd64fbsd_nat (void)
-{
- struct target_ops *t;
- int offset;
-
- amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset;
- amd64_native_gregset64_reg_offset = amd64fbsd64_r_reg_offset;
-
- /* Add some extra features to the common *BSD/i386 target. */
- t = amd64bsd_target ();
- t->to_read_description = amd64fbsd_read_description;
-
- fbsd_nat_add_target (t);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (amd64fbsd_supply_pcb);
-
- /* To support the recognition of signal handlers, i386bsd-tdep.c
- hardcodes some constants. Inclusion of this file means that we
- are compiling a native debugger, which means that we can use the
- system header files and sysctl(3) to get at the relevant
- information. */
-
-#define SC_REG_OFFSET amd64fbsd_sc_reg_offset
-
- /* We only check the program counter, stack pointer and frame
- pointer since these members of `struct sigcontext' are essential
- for providing backtraces. */
-
-#define SC_RIP_OFFSET SC_REG_OFFSET[AMD64_RIP_REGNUM]
-#define SC_RSP_OFFSET SC_REG_OFFSET[AMD64_RSP_REGNUM]
-#define SC_RBP_OFFSET SC_REG_OFFSET[AMD64_RBP_REGNUM]
-
- /* Override the default value for the offset of the program counter
- in the sigcontext structure. */
- offset = offsetof (struct sigcontext, sc_rip);
-
- if (SC_RIP_OFFSET != offset)
- {
- warning (_("\
-offsetof (struct sigcontext, sc_rip) yields %d instead of %d.\n\
-Please report this to <bug-gdb@gnu.org>."),
- offset, SC_RIP_OFFSET);
- }
-
- SC_RIP_OFFSET = offset;
-
- /* Likewise for the stack pointer. */
- offset = offsetof (struct sigcontext, sc_rsp);
-
- if (SC_RSP_OFFSET != offset)
- {
- warning (_("\
-offsetof (struct sigcontext, sc_rsp) yields %d instead of %d.\n\
-Please report this to <bug-gdb@gnu.org>."),
- offset, SC_RSP_OFFSET);
- }
-
- SC_RSP_OFFSET = offset;
-
- /* And the frame pointer. */
- offset = offsetof (struct sigcontext, sc_rbp);
-
- if (SC_RBP_OFFSET != offset)
- {
- warning (_("\
-offsetof (struct sigcontext, sc_rbp) yields %d instead of %d.\n\
-Please report this to <bug-gdb@gnu.org>."),
- offset, SC_RBP_OFFSET);
- }
-
- SC_RBP_OFFSET = offset;
-
-#ifdef KERN_PROC_SIGTRAMP
- /* Normally signal frames are detected via amd64fbsd_sigtramp_p.
- However, FreeBSD 9.2 through 10.1 do not include the page holding
- the signal code in core dumps. These releases do provide a
- kern.proc.sigtramp.<pid> sysctl that returns the location of the
- signal trampoline for a running process. We fetch the location
- of the current (gdb) process and use this to identify signal
- frames in core dumps from these releases. Note that this only
- works for core dumps of 64-bit (FreeBSD/amd64) processes and does
- not handle core dumps of 32-bit (FreeBSD/i386) processes. */
- {
- int mib[4];
- struct kinfo_sigtramp kst;
- size_t len;
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_SIGTRAMP;
- mib[3] = getpid ();
- len = sizeof (kst);
- if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0)
- {
- amd64fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start;
- amd64fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end;
- }
- }
-#endif
-}
+++ /dev/null
-/* Target-dependent code for FreeBSD/amd64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "osabi.h"
-#include "regset.h"
-#include "i386fbsd-tdep.h"
-#include "x86-xstate.h"
-
-#include "amd64-tdep.h"
-#include "bsd-uthread.h"
-#include "fbsd-tdep.h"
-#include "solib-svr4.h"
-
-/* Support for signal handlers. */
-
-/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp
- routine. */
-
-static const gdb_byte amd64fbsd_sigtramp_code[] =
-{
- 0x48, 0x8d, 0x7c, 0x24, 0x10, /* lea SIGF_UC(%rsp),%rdi */
- 0x6a, 0x00, /* pushq $0 */
- 0x48, 0xc7, 0xc0, 0xa1, 0x01, 0x00, 0x00,
- /* movq $SYS_sigreturn,%rax */
- 0x0f, 0x05 /* syscall */
-};
-
-static int
-amd64fbsd_sigtramp_p (struct frame_info *this_frame)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- gdb_byte buf[sizeof amd64fbsd_sigtramp_code];
-
- if (!safe_frame_unwind_memory (this_frame, pc, buf, sizeof buf))
- return 0;
- if (memcmp (buf, amd64fbsd_sigtramp_code, sizeof amd64fbsd_sigtramp_code)
- != 0)
- return 0;
-
- return 1;
-}
-
-/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
- address of the associated sigcontext structure. */
-
-static CORE_ADDR
-amd64fbsd_sigcontext_addr (struct frame_info *this_frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp;
- gdb_byte buf[8];
-
- /* The `struct sigcontext' (which really is an `ucontext_t' on
- FreeBSD/amd64) lives at a fixed offset in the signal frame. See
- <machine/sigframe.h>. */
- get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
- sp = extract_unsigned_integer (buf, 8, byte_order);
- return sp + 16;
-}
-\f
-/* FreeBSD 5.1-RELEASE or later. */
-
-/* Mapping between the general-purpose registers in `struct reg'
- format and GDB's register cache layout.
-
- Note that some registers are 32-bit, but since we're little-endian
- we get away with that. */
-
-/* From <machine/reg.h>. */
-static int amd64fbsd_r_reg_offset[] =
-{
- 14 * 8, /* %rax */
- 11 * 8, /* %rbx */
- 13 * 8, /* %rcx */
- 12 * 8, /* %rdx */
- 9 * 8, /* %rsi */
- 8 * 8, /* %rdi */
- 10 * 8, /* %rbp */
- 20 * 8, /* %rsp */
- 7 * 8, /* %r8 ... */
- 6 * 8,
- 5 * 8,
- 4 * 8,
- 3 * 8,
- 2 * 8,
- 1 * 8,
- 0 * 8, /* ... %r15 */
- 17 * 8, /* %rip */
- 19 * 8, /* %eflags */
- 18 * 8, /* %cs */
- 21 * 8, /* %ss */
- -1, /* %ds */
- -1, /* %es */
- -1, /* %fs */
- -1 /* %gs */
-};
-
-/* Location of the signal trampoline. */
-CORE_ADDR amd64fbsd_sigtramp_start_addr;
-CORE_ADDR amd64fbsd_sigtramp_end_addr;
-
-/* From <machine/signal.h>. */
-int amd64fbsd_sc_reg_offset[] =
-{
- 24 + 6 * 8, /* %rax */
- 24 + 7 * 8, /* %rbx */
- 24 + 3 * 8, /* %rcx */
- 24 + 2 * 8, /* %rdx */
- 24 + 1 * 8, /* %rsi */
- 24 + 0 * 8, /* %rdi */
- 24 + 8 * 8, /* %rbp */
- 24 + 22 * 8, /* %rsp */
- 24 + 4 * 8, /* %r8 ... */
- 24 + 5 * 8,
- 24 + 9 * 8,
- 24 + 10 * 8,
- 24 + 11 * 8,
- 24 + 12 * 8,
- 24 + 13 * 8,
- 24 + 14 * 8, /* ... %r15 */
- 24 + 19 * 8, /* %rip */
- 24 + 21 * 8, /* %eflags */
- 24 + 20 * 8, /* %cs */
- 24 + 23 * 8, /* %ss */
- -1, /* %ds */
- -1, /* %es */
- -1, /* %fs */
- -1 /* %gs */
-};
-
-/* From /usr/src/lib/libc/amd64/gen/_setjmp.S. */
-static int amd64fbsd_jmp_buf_reg_offset[] =
-{
- -1, /* %rax */
- 1 * 8, /* %rbx */
- -1, /* %rcx */
- -1, /* %rdx */
- -1, /* %rsi */
- -1, /* %rdi */
- 3 * 8, /* %rbp */
- 2 * 8, /* %rsp */
- -1, /* %r8 ... */
- -1,
- -1,
- -1, /* ... %r11 */
- 4 * 8, /* %r12 ... */
- 5 * 8,
- 6 * 8,
- 7 * 8, /* ... %r15 */
- 0 * 8 /* %rip */
-};
-
-/* Implement the core_read_description gdbarch method. */
-
-static const struct target_desc *
-amd64fbsd_core_read_description (struct gdbarch *gdbarch,
- struct target_ops *target,
- bfd *abfd)
-{
- return amd64_target_description (i386fbsd_core_read_xcr0 (abfd));
-}
-
-/* Similar to amd64_supply_fpregset, but use XSAVE extended state. */
-
-static void
-amd64fbsd_supply_xstateregset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *xstateregs, size_t len)
-{
- amd64_supply_xsave (regcache, regnum, xstateregs);
-}
-
-/* Similar to amd64_collect_fpregset, but use XSAVE extended state. */
-
-static void
-amd64fbsd_collect_xstateregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *xstateregs, size_t len)
-{
- amd64_collect_xsave (regcache, regnum, xstateregs, 1);
-}
-
-static const struct regset amd64fbsd_xstateregset =
- {
- NULL,
- amd64fbsd_supply_xstateregset,
- amd64fbsd_collect_xstateregset
- };
-
-/* Iterate over core file register note sections. */
-
-static void
-amd64fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- cb (".reg", tdep->sizeof_gregset, &i386_gregset, NULL, cb_data);
- cb (".reg2", tdep->sizeof_fpregset, &amd64_fpregset, NULL, cb_data);
- cb (".reg-xstate", X86_XSTATE_SIZE(tdep->xcr0),
- &amd64fbsd_xstateregset, "XSAVE extended state", cb_data);
-}
-
-static void
-amd64fbsd_supply_uthread (struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- gdb_byte buf[8];
- int i;
-
- gdb_assert (regnum >= -1);
-
- for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
- {
- if (amd64fbsd_jmp_buf_reg_offset[i] != -1
- && (regnum == -1 || regnum == i))
- {
- read_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
- regcache_raw_supply (regcache, i, buf);
- }
- }
-}
-
-static void
-amd64fbsd_collect_uthread (const struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- gdb_byte buf[8];
- int i;
-
- gdb_assert (regnum >= -1);
-
- for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
- {
- if (amd64fbsd_jmp_buf_reg_offset[i] != -1
- && (regnum == -1 || regnum == i))
- {
- regcache_raw_collect (regcache, i, buf);
- write_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
- }
- }
-}
-
-static void
-amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Generic FreeBSD support. */
- fbsd_init_abi (info, gdbarch);
-
- /* Obviously FreeBSD is BSD-based. */
- i386bsd_init_abi (info, gdbarch);
-
- tdep->gregset_reg_offset = amd64fbsd_r_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset);
- tdep->sizeof_gregset = 22 * 8;
-
- amd64_init_abi (info, gdbarch);
-
- tdep->sigtramp_p = amd64fbsd_sigtramp_p;
- tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
- tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr;
- tdep->sigcontext_addr = amd64fbsd_sigcontext_addr;
- tdep->sc_reg_offset = amd64fbsd_sc_reg_offset;
- tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset);
-
- tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET;
-
- /* Iterate over core file register note sections. */
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, amd64fbsd_iterate_over_regset_sections);
-
- set_gdbarch_core_read_description (gdbarch,
- amd64fbsd_core_read_description);
-
- /* FreeBSD provides a user-level threads implementation. */
- bsd_uthread_set_supply_uthread (gdbarch, amd64fbsd_supply_uthread);
- bsd_uthread_set_collect_uthread (gdbarch, amd64fbsd_collect_uthread);
-
- /* FreeBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_amd64fbsd_tdep (void);
-
-void
-_initialize_amd64fbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
- GDB_OSABI_FREEBSD_ELF, amd64fbsd_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for NetBSD/amd64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "target.h"
-
-#include "nbsd-nat.h"
-#include "amd64-tdep.h"
-#include "amd64-nat.h"
-
-/* Mapping between the general-purpose registers in NetBSD/amd64
- `struct reg' format and GDB's register cache layout for
- NetBSD/i386.
-
- Note that most (if not all) NetBSD/amd64 registers are 64-bit,
- while the NetBSD/i386 registers are all 32-bit, but since we're
- little-endian we get away with that. */
-
-/* From <machine/reg.h>. */
-static int amd64nbsd32_r_reg_offset[] =
-{
- 14 * 8, /* %eax */
- 3 * 8, /* %ecx */
- 2 * 8, /* %edx */
- 13 * 8, /* %ebx */
- 24 * 8, /* %esp */
- 12 * 8, /* %ebp */
- 1 * 8, /* %esi */
- 0 * 8, /* %edi */
- 21 * 8, /* %eip */
- 23 * 8, /* %eflags */
- 22 * 8, /* %cs */
- 25 * 8, /* %ss */
- 18 * 8, /* %ds */
- 17 * 8, /* %es */
- 16 * 8, /* %fs */
- 15 * 8 /* %gs */
-};
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_amd64nbsd_nat (void);
-
-void
-_initialize_amd64nbsd_nat (void)
-{
- struct target_ops *t;
-
- amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset;
- amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset);
- amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset;
-
- /* Add some extra features to the common *BSD/amd64 target. */
- t = amd64bsd_target ();
- t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
- add_target (t);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/amd64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "symtab.h"
-
-#include "amd64-tdep.h"
-#include "nbsd-tdep.h"
-#include "solib-svr4.h"
-
-/* Support for signal handlers. */
-
-/* Return whether THIS_FRAME corresponds to a NetBSD sigtramp
- routine. */
-
-static int
-amd64nbsd_sigtramp_p (struct frame_info *this_frame)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- return nbsd_pc_in_sigtramp (pc, name);
-}
-
-/* Assuming THIS_FRAME corresponds to a NetBSD sigtramp routine,
- return the address of the associated mcontext structure. */
-
-static CORE_ADDR
-amd64nbsd_mcontext_addr (struct frame_info *this_frame)
-{
- CORE_ADDR addr;
-
- /* The register %r15 points at `struct ucontext' upon entry of a
- signal trampoline. */
- addr = get_frame_register_unsigned (this_frame, AMD64_R15_REGNUM);
-
- /* The mcontext structure lives as offset 56 in `struct ucontext'. */
- return addr + 56;
-}
-\f
-/* NetBSD 2.0 or later. */
-
-/* Mapping between the general-purpose registers in `struct reg'
- format and GDB's register cache layout. */
-
-/* From <machine/reg.h>. */
-int amd64nbsd_r_reg_offset[] =
-{
- 14 * 8, /* %rax */
- 13 * 8, /* %rbx */
- 3 * 8, /* %rcx */
- 2 * 8, /* %rdx */
- 1 * 8, /* %rsi */
- 0 * 8, /* %rdi */
- 12 * 8, /* %rbp */
- 24 * 8, /* %rsp */
- 4 * 8, /* %r8 .. */
- 5 * 8,
- 6 * 8,
- 7 * 8,
- 8 * 8,
- 9 * 8,
- 10 * 8,
- 11 * 8, /* ... %r15 */
- 21 * 8, /* %rip */
- 23 * 8, /* %eflags */
- 22 * 8, /* %cs */
- 25 * 8, /* %ss */
- 18 * 8, /* %ds */
- 17 * 8, /* %es */
- 16 * 8, /* %fs */
- 15 * 8 /* %gs */
-};
-
-static void
-amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Initialize general-purpose register set details first. */
- tdep->gregset_reg_offset = amd64nbsd_r_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
- tdep->sizeof_gregset = 26 * 8;
-
- amd64_init_abi (info, gdbarch);
-
- tdep->jb_pc_offset = 7 * 8;
-
- /* NetBSD has its own convention for signal trampolines. */
- tdep->sigtramp_p = amd64nbsd_sigtramp_p;
- tdep->sigcontext_addr = amd64nbsd_mcontext_addr;
- tdep->sc_reg_offset = amd64nbsd_r_reg_offset;
- tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
-
- /* NetBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_amd64nbsd_tdep (void);
-
-void
-_initialize_amd64nbsd_tdep (void)
-{
- /* The NetBSD/amd64 native dependent code makes this assumption. */
- gdb_assert (ARRAY_SIZE (amd64nbsd_r_reg_offset) == AMD64_NUM_GREGS);
-
- gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
- GDB_OSABI_NETBSD_ELF, amd64nbsd_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for OpenBSD/amd64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "target.h"
-
-#include "amd64-tdep.h"
-#include "amd64-nat.h"
-#include "obsd-nat.h"
-
-/* Mapping between the general-purpose registers in OpenBSD/amd64
- `struct reg' format and GDB's register cache layout for
- OpenBSD/i386.
-
- Note that most (if not all) OpenBSD/amd64 registers are 64-bit,
- while the OpenBSD/i386 registers are all 32-bit, but since we're
- little-endian we get away with that. */
-
-/* From <machine/reg.h>. */
-static int amd64obsd32_r_reg_offset[] =
-{
- 14 * 8, /* %eax */
- 3 * 8, /* %ecx */
- 2 * 8, /* %edx */
- 13 * 8, /* %ebx */
- 15 * 8, /* %esp */
- 12 * 8, /* %ebp */
- 1 * 8, /* %esi */
- 0 * 8, /* %edi */
- 16 * 8, /* %eip */
- 17 * 8, /* %eflags */
- 18 * 8, /* %cs */
- 19 * 8, /* %ss */
- 20 * 8, /* %ds */
- 21 * 8, /* %es */
- 22 * 8, /* %fs */
- 23 * 8 /* %gs */
-};
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/types.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-amd64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- struct switchframe sf;
- int regnum;
-
- /* The following is true for OpenBSD 3.5:
-
- The pcb contains the stack pointer at the point of the context
- switch in cpu_switch(). At that point we have a stack frame as
- described by `struct switchframe', which for OpenBSD 3.5 has the
- following layout:
-
- interrupt level
- %r15
- %r14
- %r13
- %r12
- %rbp
- %rbx
- return address
-
- Together with %rsp in the pcb, this accounts for all callee-saved
- registers specified by the psABI. From this information we
- reconstruct the register state as it would look when we just
- returned from cpu_switch().
-
- For core dumps the pcb is saved by savectx(). In that case the
- stack frame only contains the return address, and there is no way
- to recover the other registers. */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_rsp == 0)
- return 0;
-
- /* Read the stack frame, and check its validity. */
- read_memory (pcb->pcb_rsp, (gdb_byte *) &sf, sizeof sf);
- if (sf.sf_rbp == pcb->pcb_rbp)
- {
- /* Yes, we have a frame that matches cpu_switch(). */
- pcb->pcb_rsp += sizeof (struct switchframe);
- regcache_raw_supply (regcache, 12, &sf.sf_r12);
- regcache_raw_supply (regcache, 13, &sf.sf_r13);
- regcache_raw_supply (regcache, 14, &sf.sf_r14);
- regcache_raw_supply (regcache, 15, &sf.sf_r15);
- regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &sf.sf_rbx);
- regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf.sf_rip);
- }
- else
- {
- /* No, the pcb must have been last updated by savectx(). */
- pcb->pcb_rsp += 8;
- regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf);
- }
-
- regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp);
- regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp);
-
- return 1;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_amd64obsd_nat (void);
-
-void
-_initialize_amd64obsd_nat (void)
-{
- amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset;
- amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset);
- amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset;
-
- /* Add some extra features to the common *BSD/amd64 target. */
- obsd_add_target (amd64bsd_target ());
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (amd64obsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/amd64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "symtab.h"
-#include "objfiles.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "target.h"
-#include "trad-frame.h"
-
-#include "obsd-tdep.h"
-#include "amd64-tdep.h"
-#include "i387-tdep.h"
-#include "solib-svr4.h"
-#include "bsd-uthread.h"
-
-/* Support for core dumps. */
-
-static void
-amd64obsd_supply_regset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *regs, size_t len)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE);
-
- i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
- amd64_supply_fxsave (regcache, regnum,
- ((const gdb_byte *)regs) + tdep->sizeof_gregset);
-}
-
-static const struct regset amd64obsd_combined_regset =
- {
- NULL, amd64obsd_supply_regset, NULL
- };
-
-static void
-amd64obsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* OpenBSD core dumps don't use seperate register sets for the
- general-purpose and floating-point registers. */
-
- cb (".reg", tdep->sizeof_gregset + I387_SIZEOF_FXSAVE,
- &amd64obsd_combined_regset, NULL, cb_data);
-}
-\f
-
-/* Support for signal handlers. */
-
-/* Default page size. */
-static const int amd64obsd_page_size = 4096;
-
-/* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp
- routine. */
-
-static int
-amd64obsd_sigtramp_p (struct frame_info *this_frame)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1));
- const gdb_byte osigreturn[] =
- {
- 0x48, 0xc7, 0xc0,
- 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */
- 0xcd, 0x80 /* int $0x80 */
- };
- const gdb_byte sigreturn[] =
- {
- 0x48, 0xc7, 0xc0,
- 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */
- 0x0f, 0x05 /* syscall */
- };
- size_t buflen = (sizeof sigreturn) + 1;
- gdb_byte *buf;
- const char *name;
-
- /* If the function has a valid symbol name, it isn't a
- trampoline. */
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (name != NULL)
- return 0;
-
- /* If the function lives in a valid section (even without a starting
- point) it isn't a trampoline. */
- if (find_pc_section (pc) != NULL)
- return 0;
-
- /* If we can't read the instructions at START_PC, return zero. */
- buf = (gdb_byte *) alloca ((sizeof sigreturn) + 1);
- if (!safe_frame_unwind_memory (this_frame, start_pc + 6, buf, buflen))
- return 0;
-
- /* Check for sigreturn(2). Depending on how the assembler encoded
- the `movq %rsp, %rdi' instruction, the code starts at offset 6 or
- 7. OpenBSD 5.0 and later use the `syscall' instruction. Older
- versions use `int $0x80'. Check for both. */
- if (memcmp (buf, sigreturn, sizeof sigreturn)
- && memcmp (buf + 1, sigreturn, sizeof sigreturn)
- && memcmp (buf, osigreturn, sizeof osigreturn)
- && memcmp (buf + 1, osigreturn, sizeof osigreturn))
- return 0;
-
- return 1;
-}
-
-/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
- address of the associated sigcontext structure. */
-
-static CORE_ADDR
-amd64obsd_sigcontext_addr (struct frame_info *this_frame)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- ULONGEST offset = (pc & (amd64obsd_page_size - 1));
-
- /* The %rsp register points at `struct sigcontext' upon entry of a
- signal trampoline. The relevant part of the trampoline is
-
- call *%rax
- movq %rsp, %rdi
- pushq %rdi
- movq $SYS_sigreturn,%rax
- int $0x80
-
- (see /usr/src/sys/arch/amd64/amd64/locore.S). The `pushq'
- instruction clobbers %rsp, but its value is saved in `%rdi'. */
-
- if (offset > 5)
- return get_frame_register_unsigned (this_frame, AMD64_RDI_REGNUM);
- else
- return get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
-}
-\f
-/* OpenBSD 3.5 or later. */
-
-/* Mapping between the general-purpose registers in `struct reg'
- format and GDB's register cache layout. */
-
-/* From <machine/reg.h>. */
-int amd64obsd_r_reg_offset[] =
-{
- 14 * 8, /* %rax */
- 13 * 8, /* %rbx */
- 3 * 8, /* %rcx */
- 2 * 8, /* %rdx */
- 1 * 8, /* %rsi */
- 0 * 8, /* %rdi */
- 12 * 8, /* %rbp */
- 15 * 8, /* %rsp */
- 4 * 8, /* %r8 .. */
- 5 * 8,
- 6 * 8,
- 7 * 8,
- 8 * 8,
- 9 * 8,
- 10 * 8,
- 11 * 8, /* ... %r15 */
- 16 * 8, /* %rip */
- 17 * 8, /* %eflags */
- 18 * 8, /* %cs */
- 19 * 8, /* %ss */
- 20 * 8, /* %ds */
- 21 * 8, /* %es */
- 22 * 8, /* %fs */
- 23 * 8 /* %gs */
-};
-
-/* From <machine/signal.h>. */
-static int amd64obsd_sc_reg_offset[] =
-{
- 14 * 8, /* %rax */
- 13 * 8, /* %rbx */
- 3 * 8, /* %rcx */
- 2 * 8, /* %rdx */
- 1 * 8, /* %rsi */
- 0 * 8, /* %rdi */
- 12 * 8, /* %rbp */
- 24 * 8, /* %rsp */
- 4 * 8, /* %r8 ... */
- 5 * 8,
- 6 * 8,
- 7 * 8,
- 8 * 8,
- 9 * 8,
- 10 * 8,
- 11 * 8, /* ... %r15 */
- 21 * 8, /* %rip */
- 23 * 8, /* %eflags */
- 22 * 8, /* %cs */
- 25 * 8, /* %ss */
- 18 * 8, /* %ds */
- 17 * 8, /* %es */
- 16 * 8, /* %fs */
- 15 * 8 /* %gs */
-};
-
-/* From /usr/src/lib/libpthread/arch/amd64/uthread_machdep.c. */
-static int amd64obsd_uthread_reg_offset[] =
-{
- 19 * 8, /* %rax */
- 16 * 8, /* %rbx */
- 18 * 8, /* %rcx */
- 17 * 8, /* %rdx */
- 14 * 8, /* %rsi */
- 13 * 8, /* %rdi */
- 15 * 8, /* %rbp */
- -1, /* %rsp */
- 12 * 8, /* %r8 ... */
- 11 * 8,
- 10 * 8,
- 9 * 8,
- 8 * 8,
- 7 * 8,
- 6 * 8,
- 5 * 8, /* ... %r15 */
- 20 * 8, /* %rip */
- 4 * 8, /* %eflags */
- 21 * 8, /* %cs */
- -1, /* %ss */
- 3 * 8, /* %ds */
- 2 * 8, /* %es */
- 1 * 8, /* %fs */
- 0 * 8 /* %gs */
-};
-
-/* Offset within the thread structure where we can find the saved
- stack pointer (%esp). */
-#define AMD64OBSD_UTHREAD_RSP_OFFSET 400
-
-static void
-amd64obsd_supply_uthread (struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
- CORE_ADDR sp = 0;
- gdb_byte buf[8];
- int i;
-
- gdb_assert (regnum >= -1);
-
- if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
- {
- int offset;
-
- /* Fetch stack pointer from thread structure. */
- sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
-
- /* Adjust the stack pointer such that it looks as if we just
- returned from _thread_machdep_switch. */
- offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
- store_unsigned_integer (buf, 8, byte_order, sp + offset);
- regcache_raw_supply (regcache, AMD64_RSP_REGNUM, buf);
- }
-
- for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
- {
- if (amd64obsd_uthread_reg_offset[i] != -1
- && (regnum == -1 || regnum == i))
- {
- /* Fetch stack pointer from thread structure (if we didn't
- do so already). */
- if (sp == 0)
- sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
-
- /* Read the saved register from the stack frame. */
- read_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
- regcache_raw_supply (regcache, i, buf);
- }
- }
-}
-
-static void
-amd64obsd_collect_uthread (const struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
- CORE_ADDR sp = 0;
- gdb_byte buf[8];
- int i;
-
- gdb_assert (regnum >= -1);
-
- if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
- {
- int offset;
-
- /* Calculate the stack pointer (frame pointer) that will be
- stored into the thread structure. */
- offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
- regcache_raw_collect (regcache, AMD64_RSP_REGNUM, buf);
- sp = extract_unsigned_integer (buf, 8, byte_order) - offset;
-
- /* Store the stack pointer. */
- write_memory_unsigned_integer (sp_addr, 8, byte_order, sp);
-
- /* The stack pointer was (potentially) modified. Make sure we
- build a proper stack frame. */
- regnum = -1;
- }
-
- for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
- {
- if (amd64obsd_uthread_reg_offset[i] != -1
- && (regnum == -1 || regnum == i))
- {
- /* Fetch stack pointer from thread structure (if we didn't
- calculate it already). */
- if (sp == 0)
- sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
-
- /* Write the register into the stack frame. */
- regcache_raw_collect (regcache, i, buf);
- write_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
- }
- }
-}
-/* Kernel debugging support. */
-
-/* From <machine/frame.h>. Easy since `struct trapframe' matches
- `struct sigcontext'. */
-#define amd64obsd_tf_reg_offset amd64obsd_sc_reg_offset
-
-static struct trad_frame_cache *
-amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct trad_frame_cache *cache;
- CORE_ADDR func, sp, addr;
- ULONGEST cs;
- const char *name;
- int i;
-
- if (*this_cache)
- return (struct trad_frame_cache *) *this_cache;
-
- cache = trad_frame_cache_zalloc (this_frame);
- *this_cache = cache;
-
- func = get_frame_func (this_frame);
- sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
-
- find_pc_partial_function (func, &name, NULL, NULL);
- if (name && startswith (name, "Xintr"))
- addr = sp + 8; /* It's an interrupt frame. */
- else
- addr = sp;
-
- for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++)
- if (amd64obsd_tf_reg_offset[i] != -1)
- trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]);
-
- /* Read %cs from trap frame. */
- addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM];
- cs = read_memory_unsigned_integer (addr, 8, byte_order);
- if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
- {
- /* Trap from user space; terminate backtrace. */
- trad_frame_set_id (cache, outer_frame_id);
- }
- else
- {
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (cache, frame_id_build (sp + 16, func));
- }
-
- return cache;
-}
-
-static void
-amd64obsd_trapframe_this_id (struct frame_info *this_frame,
- void **this_cache, struct frame_id *this_id)
-{
- struct trad_frame_cache *cache =
- amd64obsd_trapframe_cache (this_frame, this_cache);
-
- trad_frame_get_id (cache, this_id);
-}
-
-static struct value *
-amd64obsd_trapframe_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct trad_frame_cache *cache =
- amd64obsd_trapframe_cache (this_frame, this_cache);
-
- return trad_frame_get_register (cache, this_frame, regnum);
-}
-
-static int
-amd64obsd_trapframe_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_prologue_cache)
-{
- ULONGEST cs;
- const char *name;
-
- /* Check Current Privilege Level and bail out if we're not executing
- in kernel space. */
- cs = get_frame_register_unsigned (this_frame, AMD64_CS_REGNUM);
- if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
- return 0;
-
- find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
- return (name && ((strcmp (name, "calltrap") == 0)
- || (strcmp (name, "osyscall1") == 0)
- || (strcmp (name, "Xsyscall") == 0)
- || (startswith (name, "Xintr"))));
-}
-
-static const struct frame_unwind amd64obsd_trapframe_unwind = {
- /* FIXME: kettenis/20051219: This really is more like an interrupt
- frame, but SIGTRAMP_FRAME would print <signal handler called>,
- which really is not what we want here. */
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- amd64obsd_trapframe_this_id,
- amd64obsd_trapframe_prev_register,
- NULL,
- amd64obsd_trapframe_sniffer
-};
-\f
-
-static void
-amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- amd64_init_abi (info, gdbarch);
- obsd_init_abi (info, gdbarch);
-
- /* Initialize general-purpose register set details. */
- tdep->gregset_reg_offset = amd64obsd_r_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (amd64obsd_r_reg_offset);
- tdep->sizeof_gregset = 24 * 8;
-
- tdep->jb_pc_offset = 7 * 8;
-
- tdep->sigtramp_p = amd64obsd_sigtramp_p;
- tdep->sigcontext_addr = amd64obsd_sigcontext_addr;
- tdep->sc_reg_offset = amd64obsd_sc_reg_offset;
- tdep->sc_num_regs = ARRAY_SIZE (amd64obsd_sc_reg_offset);
-
- /* OpenBSD provides a user-level threads implementation. */
- bsd_uthread_set_supply_uthread (gdbarch, amd64obsd_supply_uthread);
- bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread);
-
- /* OpenBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-
- /* Unwind kernel trap frames correctly. */
- frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind);
-}
-
-/* Traditional (a.out) NetBSD-style core dumps. */
-
-static void
-amd64obsd_core_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- amd64obsd_init_abi (info, gdbarch);
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, amd64obsd_iterate_over_regset_sections);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_amd64obsd_tdep (void);
-
-void
-_initialize_amd64obsd_tdep (void)
-{
- /* The OpenBSD/amd64 native dependent code makes this assumption. */
- gdb_assert (ARRAY_SIZE (amd64obsd_r_reg_offset) == AMD64_NUM_GREGS);
-
- gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
- GDB_OSABI_OPENBSD_ELF, amd64obsd_init_abi);
-
- /* OpenBSD uses traditional (a.out) NetBSD-style core dumps. */
- gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
- GDB_OSABI_NETBSD_AOUT, amd64obsd_core_init_abi);
-}
--- /dev/null
+/* Target-dependent code for ARM BSD's.
+
+ Copyright (C) 2006-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "arm-tdep.h"
+
+/* Core file support. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define ARMBSD_SIZEOF_GREGS (17 * 4)
+
+/* Sizeof `struct fpreg' in <machine/reg.h. */
+#define ARMBSD_SIZEOF_FPREGS ((1 + (8 * 3)) * 4)
+
+static int
+armbsd_fpreg_offset (int regnum)
+{
+ if (regnum == ARM_FPS_REGNUM)
+ return 0;
+
+ return 4 + (regnum - ARM_F0_REGNUM) * 12;
+}
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+armbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) fpregs;
+ int i;
+
+ gdb_assert (len >= ARMBSD_SIZEOF_FPREGS);
+
+ for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + armbsd_fpreg_offset (i));
+ }
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+armbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) gregs;
+ int i;
+
+ gdb_assert (len >= ARMBSD_SIZEOF_GREGS);
+
+ for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + i * 4);
+ }
+
+ if (regnum == ARM_PS_REGNUM || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + 16 * 4);
+
+ if (len >= ARMBSD_SIZEOF_GREGS + ARMBSD_SIZEOF_FPREGS)
+ {
+ regs += ARMBSD_SIZEOF_GREGS;
+ len -= ARMBSD_SIZEOF_GREGS;
+ armbsd_supply_fpregset (regset, regcache, regnum, regs, len);
+ }
+}
+
+/* ARM register sets. */
+
+static const struct regset armbsd_gregset =
+{
+ NULL,
+ armbsd_supply_gregset,
+ NULL,
+ REGSET_VARIABLE_SIZE
+};
+
+static const struct regset armbsd_fpregset =
+{
+ NULL,
+ armbsd_supply_fpregset
+};
+
+/* Iterate over supported core file register note sections. */
+
+void
+armbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", ARMBSD_SIZEOF_GREGS, &armbsd_gregset, NULL, cb_data);
+ cb (".reg2", ARMBSD_SIZEOF_FPREGS, &armbsd_fpregset, NULL, cb_data);
+}
--- /dev/null
+/* Native-dependent code for BSD Unix running on ARM's, for GDB.
+
+ Copyright (C) 1988-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+
+#include "arm-tdep.h"
+#include "inf-ptrace.h"
+
+extern int arm_apcs_32;
+
+static void
+arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
+{
+ int regno;
+ CORE_ADDR r_pc;
+
+ /* Integer registers. */
+ for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
+ regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);
+
+ regcache_raw_supply (regcache, ARM_SP_REGNUM,
+ (char *) &gregset->r_sp);
+ regcache_raw_supply (regcache, ARM_LR_REGNUM,
+ (char *) &gregset->r_lr);
+ /* This is ok: we're running native... */
+ r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc);
+ regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
+
+ if (arm_apcs_32)
+ regcache_raw_supply (regcache, ARM_PS_REGNUM,
+ (char *) &gregset->r_cpsr);
+ else
+ regcache_raw_supply (regcache, ARM_PS_REGNUM,
+ (char *) &gregset->r_pc);
+}
+
+static void
+arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
+{
+ int regno;
+
+ for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+ regcache_raw_supply (regcache, regno,
+ (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
+
+ regcache_raw_supply (regcache, ARM_FPS_REGNUM,
+ (char *) &fparegset->fpr_fpsr);
+}
+
+static void
+fetch_register (struct regcache *regcache, int regno)
+{
+ struct reg inferior_registers;
+ int ret;
+
+ ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_registers, 0);
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch general register"));
+ return;
+ }
+
+ switch (regno)
+ {
+ case ARM_SP_REGNUM:
+ regcache_raw_supply (regcache, ARM_SP_REGNUM,
+ (char *) &inferior_registers.r_sp);
+ break;
+
+ case ARM_LR_REGNUM:
+ regcache_raw_supply (regcache, ARM_LR_REGNUM,
+ (char *) &inferior_registers.r_lr);
+ break;
+
+ case ARM_PC_REGNUM:
+ /* This is ok: we're running native... */
+ inferior_registers.r_pc = gdbarch_addr_bits_remove
+ (get_regcache_arch (regcache),
+ inferior_registers.r_pc);
+ regcache_raw_supply (regcache, ARM_PC_REGNUM,
+ (char *) &inferior_registers.r_pc);
+ break;
+
+ case ARM_PS_REGNUM:
+ if (arm_apcs_32)
+ regcache_raw_supply (regcache, ARM_PS_REGNUM,
+ (char *) &inferior_registers.r_cpsr);
+ else
+ regcache_raw_supply (regcache, ARM_PS_REGNUM,
+ (char *) &inferior_registers.r_pc);
+ break;
+
+ default:
+ regcache_raw_supply (regcache, regno,
+ (char *) &inferior_registers.r[regno]);
+ break;
+ }
+}
+
+static void
+fetch_regs (struct regcache *regcache)
+{
+ struct reg inferior_registers;
+ int ret;
+ int regno;
+
+ ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_registers, 0);
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch general registers"));
+ return;
+ }
+
+ arm_supply_gregset (regcache, &inferior_registers);
+}
+
+static void
+fetch_fp_register (struct regcache *regcache, int regno)
+{
+ struct fpreg inferior_fp_registers;
+ int ret;
+
+ ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch floating-point register"));
+ return;
+ }
+
+ switch (regno)
+ {
+ case ARM_FPS_REGNUM:
+ regcache_raw_supply (regcache, ARM_FPS_REGNUM,
+ (char *) &inferior_fp_registers.fpr_fpsr);
+ break;
+
+ default:
+ regcache_raw_supply (regcache, regno,
+ (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
+ break;
+ }
+}
+
+static void
+fetch_fp_regs (struct regcache *regcache)
+{
+ struct fpreg inferior_fp_registers;
+ int ret;
+ int regno;
+
+ ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch general registers"));
+ return;
+ }
+
+ arm_supply_fparegset (regcache, &inferior_fp_registers);
+}
+
+static void
+armnbsd_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ if (regno >= 0)
+ {
+ if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+ fetch_register (regcache, regno);
+ else
+ fetch_fp_register (regcache, regno);
+ }
+ else
+ {
+ fetch_regs (regcache);
+ fetch_fp_regs (regcache);
+ }
+}
+
+
+static void
+store_register (const struct regcache *regcache, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct reg inferior_registers;
+ int ret;
+
+ ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_registers, 0);
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch general registers"));
+ return;
+ }
+
+ switch (regno)
+ {
+ case ARM_SP_REGNUM:
+ regcache_raw_collect (regcache, ARM_SP_REGNUM,
+ (char *) &inferior_registers.r_sp);
+ break;
+
+ case ARM_LR_REGNUM:
+ regcache_raw_collect (regcache, ARM_LR_REGNUM,
+ (char *) &inferior_registers.r_lr);
+ break;
+
+ case ARM_PC_REGNUM:
+ if (arm_apcs_32)
+ regcache_raw_collect (regcache, ARM_PC_REGNUM,
+ (char *) &inferior_registers.r_pc);
+ else
+ {
+ unsigned pc_val;
+
+ regcache_raw_collect (regcache, ARM_PC_REGNUM,
+ (char *) &pc_val);
+
+ pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
+ inferior_registers.r_pc ^= gdbarch_addr_bits_remove
+ (gdbarch, inferior_registers.r_pc);
+ inferior_registers.r_pc |= pc_val;
+ }
+ break;
+
+ case ARM_PS_REGNUM:
+ if (arm_apcs_32)
+ regcache_raw_collect (regcache, ARM_PS_REGNUM,
+ (char *) &inferior_registers.r_cpsr);
+ else
+ {
+ unsigned psr_val;
+
+ regcache_raw_collect (regcache, ARM_PS_REGNUM,
+ (char *) &psr_val);
+
+ psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
+ inferior_registers.r_pc = gdbarch_addr_bits_remove
+ (gdbarch, inferior_registers.r_pc);
+ inferior_registers.r_pc |= psr_val;
+ }
+ break;
+
+ default:
+ regcache_raw_collect (regcache, regno,
+ (char *) &inferior_registers.r[regno]);
+ break;
+ }
+
+ ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_registers, 0);
+
+ if (ret < 0)
+ warning (_("unable to write register %d to inferior"), regno);
+}
+
+static void
+store_regs (const struct regcache *regcache)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct reg inferior_registers;
+ int ret;
+ int regno;
+
+
+ for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
+ regcache_raw_collect (regcache, regno,
+ (char *) &inferior_registers.r[regno]);
+
+ regcache_raw_collect (regcache, ARM_SP_REGNUM,
+ (char *) &inferior_registers.r_sp);
+ regcache_raw_collect (regcache, ARM_LR_REGNUM,
+ (char *) &inferior_registers.r_lr);
+
+ if (arm_apcs_32)
+ {
+ regcache_raw_collect (regcache, ARM_PC_REGNUM,
+ (char *) &inferior_registers.r_pc);
+ regcache_raw_collect (regcache, ARM_PS_REGNUM,
+ (char *) &inferior_registers.r_cpsr);
+ }
+ else
+ {
+ unsigned pc_val;
+ unsigned psr_val;
+
+ regcache_raw_collect (regcache, ARM_PC_REGNUM,
+ (char *) &pc_val);
+ regcache_raw_collect (regcache, ARM_PS_REGNUM,
+ (char *) &psr_val);
+
+ pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
+ psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
+
+ inferior_registers.r_pc = pc_val | psr_val;
+ }
+
+ ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_registers, 0);
+
+ if (ret < 0)
+ warning (_("unable to store general registers"));
+}
+
+static void
+store_fp_register (const struct regcache *regcache, int regno)
+{
+ struct fpreg inferior_fp_registers;
+ int ret;
+
+ ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch floating-point registers"));
+ return;
+ }
+
+ switch (regno)
+ {
+ case ARM_FPS_REGNUM:
+ regcache_raw_collect (regcache, ARM_FPS_REGNUM,
+ (char *) &inferior_fp_registers.fpr_fpsr);
+ break;
+
+ default:
+ regcache_raw_collect (regcache, regno,
+ (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
+ break;
+ }
+
+ ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ warning (_("unable to write register %d to inferior"), regno);
+}
+
+static void
+store_fp_regs (const struct regcache *regcache)
+{
+ struct fpreg inferior_fp_registers;
+ int ret;
+ int regno;
+
+
+ for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+ regcache_raw_collect (regcache, regno,
+ (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
+
+ regcache_raw_collect (regcache, ARM_FPS_REGNUM,
+ (char *) &inferior_fp_registers.fpr_fpsr);
+
+ ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
+
+ if (ret < 0)
+ warning (_("unable to store floating-point registers"));
+}
+
+static void
+armnbsd_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ if (regno >= 0)
+ {
+ if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+ store_register (regcache, regno);
+ else
+ store_fp_register (regcache, regno);
+ }
+ else
+ {
+ store_regs (regcache);
+ store_fp_regs (regcache);
+ }
+}
+
+struct md_core
+{
+ struct reg intreg;
+ struct fpreg freg;
+};
+
+static void
+fetch_core_registers (struct regcache *regcache,
+ char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR ignore)
+{
+ struct md_core *core_reg = (struct md_core *) core_reg_sect;
+ int regno;
+ CORE_ADDR r_pc;
+
+ arm_supply_gregset (regcache, &core_reg->intreg);
+ arm_supply_fparegset (regcache, &core_reg->freg);
+}
+
+static void
+fetch_elfcore_registers (struct regcache *regcache,
+ char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR ignore)
+{
+ struct reg gregset;
+ struct fpreg fparegset;
+
+ switch (which)
+ {
+ case 0: /* Integer registers. */
+ if (core_reg_size != sizeof (struct reg))
+ warning (_("wrong size of register set in core file"));
+ else
+ {
+ /* The memcpy may be unnecessary, but we can't really be sure
+ of the alignment of the data in the core file. */
+ memcpy (&gregset, core_reg_sect, sizeof (gregset));
+ arm_supply_gregset (regcache, &gregset);
+ }
+ break;
+
+ case 2:
+ if (core_reg_size != sizeof (struct fpreg))
+ warning (_("wrong size of FPA register set in core file"));
+ else
+ {
+ /* The memcpy may be unnecessary, but we can't really be sure
+ of the alignment of the data in the core file. */
+ memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
+ arm_supply_fparegset (regcache, &fparegset);
+ }
+ break;
+
+ default:
+ /* Don't know what kind of register request this is; just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns arm_netbsd_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flovour. */
+ default_check_format, /* check_format. */
+ default_core_sniffer, /* core_sniffer. */
+ fetch_core_registers, /* core_read_registers. */
+ NULL
+};
+
+static struct core_fns arm_netbsd_elfcore_fns =
+{
+ bfd_target_elf_flavour, /* core_flovour. */
+ default_check_format, /* check_format. */
+ default_core_sniffer, /* core_sniffer. */
+ fetch_elfcore_registers, /* core_read_registers. */
+ NULL
+};
+
+void
+_initialize_arm_netbsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = armnbsd_fetch_registers;
+ t->to_store_registers = armnbsd_store_registers;
+ add_target (t);
+
+ deprecated_add_core_fns (&arm_netbsd_core_fns);
+ deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/arm.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "osabi.h"
+
+#include "arch/arm.h"
+#include "arm-tdep.h"
+#include "solib-svr4.h"
+
+/* Description of the longjmp buffer. */
+#define ARM_NBSD_JB_PC 24
+#define ARM_NBSD_JB_ELEMENT_SIZE INT_REGISTER_SIZE
+
+/* For compatibility with previous implemenations of GDB on arm/NetBSD,
+ override the default little-endian breakpoint. */
+static const gdb_byte arm_nbsd_arm_le_breakpoint[] = {0x11, 0x00, 0x00, 0xe6};
+static const gdb_byte arm_nbsd_arm_be_breakpoint[] = {0xe6, 0x00, 0x00, 0x11};
+static const gdb_byte arm_nbsd_thumb_le_breakpoint[] = {0xfe, 0xde};
+static const gdb_byte arm_nbsd_thumb_be_breakpoint[] = {0xde, 0xfe};
+
+static void
+arm_netbsd_init_abi_common (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->lowest_pc = 0x8000;
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_LITTLE:
+ tdep->arm_breakpoint = arm_nbsd_arm_le_breakpoint;
+ tdep->thumb_breakpoint = arm_nbsd_thumb_le_breakpoint;
+ tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_le_breakpoint);
+ tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_le_breakpoint);
+ break;
+
+ case BFD_ENDIAN_BIG:
+ tdep->arm_breakpoint = arm_nbsd_arm_be_breakpoint;
+ tdep->thumb_breakpoint = arm_nbsd_thumb_be_breakpoint;
+ tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_be_breakpoint);
+ tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_be_breakpoint);
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("arm_gdbarch_init: bad byte order for float format"));
+ }
+
+ tdep->jb_pc = ARM_NBSD_JB_PC;
+ tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE;
+
+ /* Single stepping. */
+ set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
+}
+
+static void
+arm_netbsd_aout_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ arm_netbsd_init_abi_common (info, gdbarch);
+ if (tdep->fp_model == ARM_FLOAT_AUTO)
+ tdep->fp_model = ARM_FLOAT_SOFT_FPA;
+}
+
+static void
+arm_netbsd_elf_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ arm_netbsd_init_abi_common (info, gdbarch);
+ if (tdep->fp_model == ARM_FLOAT_AUTO)
+ tdep->fp_model = ARM_FLOAT_SOFT_VFP;
+
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+
+static enum gdb_osabi
+arm_netbsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-arm-netbsd") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_arm_netbsd_tdep;
+
+void
+_initialize_arm_netbsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_aout_flavour,
+ arm_netbsd_aout_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD_AOUT,
+ arm_netbsd_aout_init_abi);
+ gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD_ELF,
+ arm_netbsd_elf_init_abi);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/arm.
+
+ Copyright (C) 2006-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "osabi.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+
+#include "obsd-tdep.h"
+#include "arm-tdep.h"
+#include "solib-svr4.h"
+
+/* Signal trampolines. */
+
+static void
+armobsd_sigframe_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *cache,
+ CORE_ADDR func)
+{
+ CORE_ADDR sp, sigcontext_addr, addr;
+ int regnum;
+
+ /* We find the appropriate instance of `struct sigcontext' at a
+ fixed offset in the signal frame. */
+ sp = get_frame_register_signed (this_frame, ARM_SP_REGNUM);
+ sigcontext_addr = sp + 16;
+
+ /* PC. */
+ trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sigcontext_addr + 76);
+
+ /* GPRs. */
+ for (regnum = ARM_A1_REGNUM, addr = sigcontext_addr + 12;
+ regnum <= ARM_LR_REGNUM; regnum++, addr += 4)
+ trad_frame_set_reg_addr (cache, regnum, addr);
+
+ trad_frame_set_id (cache, frame_id_build (sp, func));
+}
+
+static const struct tramp_frame armobsd_sigframe =
+{
+ SIGTRAMP_FRAME,
+ 4,
+ {
+ { 0xe28d0010, -1 }, /* add r0, sp, #16 */
+ { 0xef000067, -1 }, /* swi SYS_sigreturn */
+ { 0xef000001, -1 }, /* swi SYS_exit */
+ { 0xeafffffc, -1 }, /* b . - 8 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ armobsd_sigframe_init
+};
+\f
+
+/* Override default thumb breakpoints. */
+static const gdb_byte arm_obsd_thumb_le_breakpoint[] = {0xfe, 0xdf};
+static const gdb_byte arm_obsd_thumb_be_breakpoint[] = {0xdf, 0xfe};
+
+static void
+armobsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (tdep->fp_model == ARM_FLOAT_AUTO)
+ tdep->fp_model = ARM_FLOAT_SOFT_VFP;
+
+ tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe);
+
+ /* OpenBSD/arm uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
+
+ tdep->jb_pc = 24;
+ tdep->jb_elt_size = 4;
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, armbsd_iterate_over_regset_sections);
+
+ /* OpenBSD/arm uses -fpcc-struct-return by default. */
+ tdep->struct_return = pcc_struct_return;
+
+ /* Single stepping. */
+ set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
+
+ /* Breakpoints. */
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_BIG:
+ tdep->thumb_breakpoint = arm_obsd_thumb_be_breakpoint;
+ tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_be_breakpoint);
+ break;
+
+ case BFD_ENDIAN_LITTLE:
+ tdep->thumb_breakpoint = arm_obsd_thumb_le_breakpoint;
+ tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_le_breakpoint);
+ break;
+ }
+}
+\f
+
+static enum gdb_osabi
+armobsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_OPENBSD_ELF;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_armobsd_tdep;
+
+void
+_initialize_armobsd_tdep (void)
+{
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_unknown_flavour,
+ armobsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_OPENBSD_ELF,
+ armobsd_init_abi);
+}
extern int arm_process_record (struct gdbarch *gdbarch,
struct regcache *regcache, CORE_ADDR addr);
-/* Functions exported from armbsd-tdep.h. */
+/* Functions exported from arm-bsd-tdep.h. */
/* Return the appropriate register set for the core section identified
by SECT_NAME and SECT_SIZE. */
+++ /dev/null
-/* Target-dependent code for ARM BSD's.
-
- Copyright (C) 2006-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-
-#include "arm-tdep.h"
-
-/* Core file support. */
-
-/* Sizeof `struct reg' in <machine/reg.h>. */
-#define ARMBSD_SIZEOF_GREGS (17 * 4)
-
-/* Sizeof `struct fpreg' in <machine/reg.h. */
-#define ARMBSD_SIZEOF_FPREGS ((1 + (8 * 3)) * 4)
-
-static int
-armbsd_fpreg_offset (int regnum)
-{
- if (regnum == ARM_FPS_REGNUM)
- return 0;
-
- return 4 + (regnum - ARM_F0_REGNUM) * 12;
-}
-
-/* Supply register REGNUM from the buffer specified by FPREGS and LEN
- in the floating-point register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-armbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) fpregs;
- int i;
-
- gdb_assert (len >= ARMBSD_SIZEOF_FPREGS);
-
- for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + armbsd_fpreg_offset (i));
- }
-}
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-armbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) gregs;
- int i;
-
- gdb_assert (len >= ARMBSD_SIZEOF_GREGS);
-
- for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + i * 4);
- }
-
- if (regnum == ARM_PS_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, i, regs + 16 * 4);
-
- if (len >= ARMBSD_SIZEOF_GREGS + ARMBSD_SIZEOF_FPREGS)
- {
- regs += ARMBSD_SIZEOF_GREGS;
- len -= ARMBSD_SIZEOF_GREGS;
- armbsd_supply_fpregset (regset, regcache, regnum, regs, len);
- }
-}
-
-/* ARM register sets. */
-
-static const struct regset armbsd_gregset =
-{
- NULL,
- armbsd_supply_gregset,
- NULL,
- REGSET_VARIABLE_SIZE
-};
-
-static const struct regset armbsd_fpregset =
-{
- NULL,
- armbsd_supply_fpregset
-};
-
-/* Iterate over supported core file register note sections. */
-
-void
-armbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", ARMBSD_SIZEOF_GREGS, &armbsd_gregset, NULL, cb_data);
- cb (".reg2", ARMBSD_SIZEOF_FPREGS, &armbsd_fpregset, NULL, cb_data);
-}
+++ /dev/null
-/* Native-dependent code for BSD Unix running on ARM's, for GDB.
-
- Copyright (C) 1988-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-#include <machine/frame.h>
-
-#include "arm-tdep.h"
-#include "inf-ptrace.h"
-
-extern int arm_apcs_32;
-
-static void
-arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
-{
- int regno;
- CORE_ADDR r_pc;
-
- /* Integer registers. */
- for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
- regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);
-
- regcache_raw_supply (regcache, ARM_SP_REGNUM,
- (char *) &gregset->r_sp);
- regcache_raw_supply (regcache, ARM_LR_REGNUM,
- (char *) &gregset->r_lr);
- /* This is ok: we're running native... */
- r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc);
- regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
-
- if (arm_apcs_32)
- regcache_raw_supply (regcache, ARM_PS_REGNUM,
- (char *) &gregset->r_cpsr);
- else
- regcache_raw_supply (regcache, ARM_PS_REGNUM,
- (char *) &gregset->r_pc);
-}
-
-static void
-arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
-{
- int regno;
-
- for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
- regcache_raw_supply (regcache, regno,
- (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
-
- regcache_raw_supply (regcache, ARM_FPS_REGNUM,
- (char *) &fparegset->fpr_fpsr);
-}
-
-static void
-fetch_register (struct regcache *regcache, int regno)
-{
- struct reg inferior_registers;
- int ret;
-
- ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_registers, 0);
-
- if (ret < 0)
- {
- warning (_("unable to fetch general register"));
- return;
- }
-
- switch (regno)
- {
- case ARM_SP_REGNUM:
- regcache_raw_supply (regcache, ARM_SP_REGNUM,
- (char *) &inferior_registers.r_sp);
- break;
-
- case ARM_LR_REGNUM:
- regcache_raw_supply (regcache, ARM_LR_REGNUM,
- (char *) &inferior_registers.r_lr);
- break;
-
- case ARM_PC_REGNUM:
- /* This is ok: we're running native... */
- inferior_registers.r_pc = gdbarch_addr_bits_remove
- (get_regcache_arch (regcache),
- inferior_registers.r_pc);
- regcache_raw_supply (regcache, ARM_PC_REGNUM,
- (char *) &inferior_registers.r_pc);
- break;
-
- case ARM_PS_REGNUM:
- if (arm_apcs_32)
- regcache_raw_supply (regcache, ARM_PS_REGNUM,
- (char *) &inferior_registers.r_cpsr);
- else
- regcache_raw_supply (regcache, ARM_PS_REGNUM,
- (char *) &inferior_registers.r_pc);
- break;
-
- default:
- regcache_raw_supply (regcache, regno,
- (char *) &inferior_registers.r[regno]);
- break;
- }
-}
-
-static void
-fetch_regs (struct regcache *regcache)
-{
- struct reg inferior_registers;
- int ret;
- int regno;
-
- ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_registers, 0);
-
- if (ret < 0)
- {
- warning (_("unable to fetch general registers"));
- return;
- }
-
- arm_supply_gregset (regcache, &inferior_registers);
-}
-
-static void
-fetch_fp_register (struct regcache *regcache, int regno)
-{
- struct fpreg inferior_fp_registers;
- int ret;
-
- ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
-
- if (ret < 0)
- {
- warning (_("unable to fetch floating-point register"));
- return;
- }
-
- switch (regno)
- {
- case ARM_FPS_REGNUM:
- regcache_raw_supply (regcache, ARM_FPS_REGNUM,
- (char *) &inferior_fp_registers.fpr_fpsr);
- break;
-
- default:
- regcache_raw_supply (regcache, regno,
- (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
- break;
- }
-}
-
-static void
-fetch_fp_regs (struct regcache *regcache)
-{
- struct fpreg inferior_fp_registers;
- int ret;
- int regno;
-
- ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
-
- if (ret < 0)
- {
- warning (_("unable to fetch general registers"));
- return;
- }
-
- arm_supply_fparegset (regcache, &inferior_fp_registers);
-}
-
-static void
-armnbsd_fetch_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- if (regno >= 0)
- {
- if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
- fetch_register (regcache, regno);
- else
- fetch_fp_register (regcache, regno);
- }
- else
- {
- fetch_regs (regcache);
- fetch_fp_regs (regcache);
- }
-}
-
-
-static void
-store_register (const struct regcache *regcache, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct reg inferior_registers;
- int ret;
-
- ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_registers, 0);
-
- if (ret < 0)
- {
- warning (_("unable to fetch general registers"));
- return;
- }
-
- switch (regno)
- {
- case ARM_SP_REGNUM:
- regcache_raw_collect (regcache, ARM_SP_REGNUM,
- (char *) &inferior_registers.r_sp);
- break;
-
- case ARM_LR_REGNUM:
- regcache_raw_collect (regcache, ARM_LR_REGNUM,
- (char *) &inferior_registers.r_lr);
- break;
-
- case ARM_PC_REGNUM:
- if (arm_apcs_32)
- regcache_raw_collect (regcache, ARM_PC_REGNUM,
- (char *) &inferior_registers.r_pc);
- else
- {
- unsigned pc_val;
-
- regcache_raw_collect (regcache, ARM_PC_REGNUM,
- (char *) &pc_val);
-
- pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
- inferior_registers.r_pc ^= gdbarch_addr_bits_remove
- (gdbarch, inferior_registers.r_pc);
- inferior_registers.r_pc |= pc_val;
- }
- break;
-
- case ARM_PS_REGNUM:
- if (arm_apcs_32)
- regcache_raw_collect (regcache, ARM_PS_REGNUM,
- (char *) &inferior_registers.r_cpsr);
- else
- {
- unsigned psr_val;
-
- regcache_raw_collect (regcache, ARM_PS_REGNUM,
- (char *) &psr_val);
-
- psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
- inferior_registers.r_pc = gdbarch_addr_bits_remove
- (gdbarch, inferior_registers.r_pc);
- inferior_registers.r_pc |= psr_val;
- }
- break;
-
- default:
- regcache_raw_collect (regcache, regno,
- (char *) &inferior_registers.r[regno]);
- break;
- }
-
- ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_registers, 0);
-
- if (ret < 0)
- warning (_("unable to write register %d to inferior"), regno);
-}
-
-static void
-store_regs (const struct regcache *regcache)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct reg inferior_registers;
- int ret;
- int regno;
-
-
- for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
- regcache_raw_collect (regcache, regno,
- (char *) &inferior_registers.r[regno]);
-
- regcache_raw_collect (regcache, ARM_SP_REGNUM,
- (char *) &inferior_registers.r_sp);
- regcache_raw_collect (regcache, ARM_LR_REGNUM,
- (char *) &inferior_registers.r_lr);
-
- if (arm_apcs_32)
- {
- regcache_raw_collect (regcache, ARM_PC_REGNUM,
- (char *) &inferior_registers.r_pc);
- regcache_raw_collect (regcache, ARM_PS_REGNUM,
- (char *) &inferior_registers.r_cpsr);
- }
- else
- {
- unsigned pc_val;
- unsigned psr_val;
-
- regcache_raw_collect (regcache, ARM_PC_REGNUM,
- (char *) &pc_val);
- regcache_raw_collect (regcache, ARM_PS_REGNUM,
- (char *) &psr_val);
-
- pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
- psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
-
- inferior_registers.r_pc = pc_val | psr_val;
- }
-
- ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_registers, 0);
-
- if (ret < 0)
- warning (_("unable to store general registers"));
-}
-
-static void
-store_fp_register (const struct regcache *regcache, int regno)
-{
- struct fpreg inferior_fp_registers;
- int ret;
-
- ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
-
- if (ret < 0)
- {
- warning (_("unable to fetch floating-point registers"));
- return;
- }
-
- switch (regno)
- {
- case ARM_FPS_REGNUM:
- regcache_raw_collect (regcache, ARM_FPS_REGNUM,
- (char *) &inferior_fp_registers.fpr_fpsr);
- break;
-
- default:
- regcache_raw_collect (regcache, regno,
- (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
- break;
- }
-
- ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
-
- if (ret < 0)
- warning (_("unable to write register %d to inferior"), regno);
-}
-
-static void
-store_fp_regs (const struct regcache *regcache)
-{
- struct fpreg inferior_fp_registers;
- int ret;
- int regno;
-
-
- for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
- regcache_raw_collect (regcache, regno,
- (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
-
- regcache_raw_collect (regcache, ARM_FPS_REGNUM,
- (char *) &inferior_fp_registers.fpr_fpsr);
-
- ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
-
- if (ret < 0)
- warning (_("unable to store floating-point registers"));
-}
-
-static void
-armnbsd_store_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- if (regno >= 0)
- {
- if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
- store_register (regcache, regno);
- else
- store_fp_register (regcache, regno);
- }
- else
- {
- store_regs (regcache);
- store_fp_regs (regcache);
- }
-}
-
-struct md_core
-{
- struct reg intreg;
- struct fpreg freg;
-};
-
-static void
-fetch_core_registers (struct regcache *regcache,
- char *core_reg_sect, unsigned core_reg_size,
- int which, CORE_ADDR ignore)
-{
- struct md_core *core_reg = (struct md_core *) core_reg_sect;
- int regno;
- CORE_ADDR r_pc;
-
- arm_supply_gregset (regcache, &core_reg->intreg);
- arm_supply_fparegset (regcache, &core_reg->freg);
-}
-
-static void
-fetch_elfcore_registers (struct regcache *regcache,
- char *core_reg_sect, unsigned core_reg_size,
- int which, CORE_ADDR ignore)
-{
- struct reg gregset;
- struct fpreg fparegset;
-
- switch (which)
- {
- case 0: /* Integer registers. */
- if (core_reg_size != sizeof (struct reg))
- warning (_("wrong size of register set in core file"));
- else
- {
- /* The memcpy may be unnecessary, but we can't really be sure
- of the alignment of the data in the core file. */
- memcpy (&gregset, core_reg_sect, sizeof (gregset));
- arm_supply_gregset (regcache, &gregset);
- }
- break;
-
- case 2:
- if (core_reg_size != sizeof (struct fpreg))
- warning (_("wrong size of FPA register set in core file"));
- else
- {
- /* The memcpy may be unnecessary, but we can't really be sure
- of the alignment of the data in the core file. */
- memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
- arm_supply_fparegset (regcache, &fparegset);
- }
- break;
-
- default:
- /* Don't know what kind of register request this is; just ignore it. */
- break;
- }
-}
-
-static struct core_fns arm_netbsd_core_fns =
-{
- bfd_target_unknown_flavour, /* core_flovour. */
- default_check_format, /* check_format. */
- default_core_sniffer, /* core_sniffer. */
- fetch_core_registers, /* core_read_registers. */
- NULL
-};
-
-static struct core_fns arm_netbsd_elfcore_fns =
-{
- bfd_target_elf_flavour, /* core_flovour. */
- default_check_format, /* check_format. */
- default_core_sniffer, /* core_sniffer. */
- fetch_elfcore_registers, /* core_read_registers. */
- NULL
-};
-
-void
-_initialize_arm_netbsd_nat (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
- t->to_fetch_registers = armnbsd_fetch_registers;
- t->to_store_registers = armnbsd_store_registers;
- add_target (t);
-
- deprecated_add_core_fns (&arm_netbsd_core_fns);
- deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/arm.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "osabi.h"
-
-#include "arch/arm.h"
-#include "arm-tdep.h"
-#include "solib-svr4.h"
-
-/* Description of the longjmp buffer. */
-#define ARM_NBSD_JB_PC 24
-#define ARM_NBSD_JB_ELEMENT_SIZE INT_REGISTER_SIZE
-
-/* For compatibility with previous implemenations of GDB on arm/NetBSD,
- override the default little-endian breakpoint. */
-static const gdb_byte arm_nbsd_arm_le_breakpoint[] = {0x11, 0x00, 0x00, 0xe6};
-static const gdb_byte arm_nbsd_arm_be_breakpoint[] = {0xe6, 0x00, 0x00, 0x11};
-static const gdb_byte arm_nbsd_thumb_le_breakpoint[] = {0xfe, 0xde};
-static const gdb_byte arm_nbsd_thumb_be_breakpoint[] = {0xde, 0xfe};
-
-static void
-arm_netbsd_init_abi_common (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- tdep->lowest_pc = 0x8000;
- switch (info.byte_order)
- {
- case BFD_ENDIAN_LITTLE:
- tdep->arm_breakpoint = arm_nbsd_arm_le_breakpoint;
- tdep->thumb_breakpoint = arm_nbsd_thumb_le_breakpoint;
- tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_le_breakpoint);
- tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_le_breakpoint);
- break;
-
- case BFD_ENDIAN_BIG:
- tdep->arm_breakpoint = arm_nbsd_arm_be_breakpoint;
- tdep->thumb_breakpoint = arm_nbsd_thumb_be_breakpoint;
- tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_be_breakpoint);
- tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_be_breakpoint);
- break;
-
- default:
- internal_error (__FILE__, __LINE__,
- _("arm_gdbarch_init: bad byte order for float format"));
- }
-
- tdep->jb_pc = ARM_NBSD_JB_PC;
- tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE;
-
- /* Single stepping. */
- set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
-}
-
-static void
-arm_netbsd_aout_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- arm_netbsd_init_abi_common (info, gdbarch);
- if (tdep->fp_model == ARM_FLOAT_AUTO)
- tdep->fp_model = ARM_FLOAT_SOFT_FPA;
-}
-
-static void
-arm_netbsd_elf_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- arm_netbsd_init_abi_common (info, gdbarch);
- if (tdep->fp_model == ARM_FLOAT_AUTO)
- tdep->fp_model = ARM_FLOAT_SOFT_VFP;
-
- /* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-
-static enum gdb_osabi
-arm_netbsd_aout_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "a.out-arm-netbsd") == 0)
- return GDB_OSABI_NETBSD_AOUT;
-
- return GDB_OSABI_UNKNOWN;
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_arm_netbsd_tdep;
-
-void
-_initialize_arm_netbsd_tdep (void)
-{
- gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_aout_flavour,
- arm_netbsd_aout_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD_AOUT,
- arm_netbsd_aout_init_abi);
- gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD_ELF,
- arm_netbsd_elf_init_abi);
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/arm.
-
- Copyright (C) 2006-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "osabi.h"
-#include "trad-frame.h"
-#include "tramp-frame.h"
-
-#include "obsd-tdep.h"
-#include "arm-tdep.h"
-#include "solib-svr4.h"
-
-/* Signal trampolines. */
-
-static void
-armobsd_sigframe_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *cache,
- CORE_ADDR func)
-{
- CORE_ADDR sp, sigcontext_addr, addr;
- int regnum;
-
- /* We find the appropriate instance of `struct sigcontext' at a
- fixed offset in the signal frame. */
- sp = get_frame_register_signed (this_frame, ARM_SP_REGNUM);
- sigcontext_addr = sp + 16;
-
- /* PC. */
- trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sigcontext_addr + 76);
-
- /* GPRs. */
- for (regnum = ARM_A1_REGNUM, addr = sigcontext_addr + 12;
- regnum <= ARM_LR_REGNUM; regnum++, addr += 4)
- trad_frame_set_reg_addr (cache, regnum, addr);
-
- trad_frame_set_id (cache, frame_id_build (sp, func));
-}
-
-static const struct tramp_frame armobsd_sigframe =
-{
- SIGTRAMP_FRAME,
- 4,
- {
- { 0xe28d0010, -1 }, /* add r0, sp, #16 */
- { 0xef000067, -1 }, /* swi SYS_sigreturn */
- { 0xef000001, -1 }, /* swi SYS_exit */
- { 0xeafffffc, -1 }, /* b . - 8 */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- armobsd_sigframe_init
-};
-\f
-
-/* Override default thumb breakpoints. */
-static const gdb_byte arm_obsd_thumb_le_breakpoint[] = {0xfe, 0xdf};
-static const gdb_byte arm_obsd_thumb_be_breakpoint[] = {0xdf, 0xfe};
-
-static void
-armobsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- if (tdep->fp_model == ARM_FLOAT_AUTO)
- tdep->fp_model = ARM_FLOAT_SOFT_VFP;
-
- tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe);
-
- /* OpenBSD/arm uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
- set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
-
- tdep->jb_pc = 24;
- tdep->jb_elt_size = 4;
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, armbsd_iterate_over_regset_sections);
-
- /* OpenBSD/arm uses -fpcc-struct-return by default. */
- tdep->struct_return = pcc_struct_return;
-
- /* Single stepping. */
- set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
-
- /* Breakpoints. */
- switch (info.byte_order)
- {
- case BFD_ENDIAN_BIG:
- tdep->thumb_breakpoint = arm_obsd_thumb_be_breakpoint;
- tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_be_breakpoint);
- break;
-
- case BFD_ENDIAN_LITTLE:
- tdep->thumb_breakpoint = arm_obsd_thumb_le_breakpoint;
- tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_le_breakpoint);
- break;
- }
-}
-\f
-
-static enum gdb_osabi
-armobsd_core_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
- return GDB_OSABI_OPENBSD_ELF;
-
- return GDB_OSABI_UNKNOWN;
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_armobsd_tdep;
-
-void
-_initialize_armobsd_tdep (void)
-{
- /* BFD doesn't set a flavour for NetBSD style a.out core files. */
- gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_unknown_flavour,
- armobsd_core_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_OPENBSD_ELF,
- armobsd_init_abi);
-}
# Host: FreeBSD/alpha
NATDEPFILES= fork-child.o inf-ptrace.o \
- fbsd-nat.o alphabsd-nat.o bsd-kvm.o \
+ fbsd-nat.o alpha-bsd-nat.o bsd-kvm.o \
core-regset.o
LOADLIBES= -lkvm
# Host: NetBSD/alpha
-NATDEPFILES= fork-child.o inf-ptrace.o alphabsd-nat.o bsd-kvm.o
+NATDEPFILES= fork-child.o inf-ptrace.o alpha-bsd-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: NetBSD/arm
-NATDEPFILES= fork-child.o inf-ptrace.o armnbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o arm-nbsd-nat.o
@V@/gdb/ada-exp.tab.c @V@/gdb/ada-exp_tab.c
@V@/gdb/amd64-windows-nat.c @V@/gdb/a64w-nat.c
@V@/gdb/amd64-windows-tdep.c @V@/gdb/a64w-tdep.c
-@V@/gdb/amd64fbsd-nat.c @V@/gdb/a64fb-nat.c
-@V@/gdb/amd64fbsd-tdep.c @V@/gdb/a64fb-tdep.c
-@V@/gdb/amd64nbsd-nat.c @V@/gdb/a64nb-nat.c
-@V@/gdb/amd64nbsd-tdep.c @V@/gdb/a64nb-tdep.c
-@V@/gdb/amd64obsd-nat.c @V@/gdb/a64ob-nat.c
-@V@/gdb/amd64obsd-tdep.c @V@/gdb/a64ob-tdep.c
-@V@/gdb/alphabsd-nat.c @V@/gdb/alphb-nat.c
-@V@/gdb/alphabsd-tdep.c @V@/gdb/alphb-tdep.c
-@V@/gdb/alphanbsd-tdep.c @V@/gdb/alphnb-tdep.c
+@V@/gdb/amd64-fbsd-nat.c @V@/gdb/a64fb-nat.c
+@V@/gdb/amd64-fbsd-tdep.c @V@/gdb/a64fb-tdep.c
+@V@/gdb/amd64-nbsd-nat.c @V@/gdb/a64nb-nat.c
+@V@/gdb/amd64-nbsd-tdep.c @V@/gdb/a64nb-tdep.c
+@V@/gdb/amd64-obsd-nat.c @V@/gdb/a64ob-nat.c
+@V@/gdb/amd64-obsd-tdep.c @V@/gdb/a64ob-tdep.c
+@V@/gdb/alpha-bsd-nat.c @V@/gdb/alphb-nat.c
+@V@/gdb/alpha-bsd-tdep.c @V@/gdb/alphb-tdep.c
+@V@/gdb/alpha-nbsd-tdep.c @V@/gdb/alphnb-tdep.c
@V@/gdb/alpha-linux-nat.c @V@/gdb/alphl-nat.c
@V@/gdb/alpha-linux-tdep.c @V@/gdb/alphl-tdep.c
@V@/gdb/arm-linux-nat.c @V@/gdb/armlin-nat.c
@V@/gdb/arm-linux-tdep.c @V@/gdb/armlin-tdep.c
-@V@/gdb/armnbsd-nat.c @V@/gdb/armnbd-nat.c
-@V@/gdb/armnbsd-tdep.c @V@/gdb/armnbd-tdep.c
+@V@/gdb/arm-nbsd-nat.c @V@/gdb/armnbd-nat.c
+@V@/gdb/arm-nbsd-tdep.c @V@/gdb/armnbd-tdep.c
@V@/gdb/c-exp.tab.c @V@/gdb/c-exp_tab.c
@V@/gdb/config/alpha/tm-alphalinux.h @V@/gdb/config/alpha/tm-alplinux.h
@V@/gdb/config/i386/nm-cygwin64.h @V@/gdb/config/i386/nm-cyg64.h
@V@/gdb/gdbtk/library/ChangeLog-2000 @V@/gdb/gdbtk/library/ChangeLog.000
@V@/gdb/gdbtk/plugins/intel-pentium/intel-pentium.tcl.in @V@/gdb/gdbtk/plugins/intel-pentium/intel-pentium.t-in
@V@/gdb/gdbtk/plugins/rhabout/rhabout.tcl.in @V@/gdb/gdbtk/plugins/rhabout/rhabout.t-in
-@V@/gdb/hppabsd-nat.c @V@/gdb/hppab-nat.c
-@V@/gdb/hppabsd-tdep.c @V@/gdb/hppab-tdep.c
-@V@/gdb/hppnbsd-nat.c @V@/gdb/hppnb-nat.c
-@V@/gdb/hppnbsd-tdep.c @V@/gdb/hppnb-tdep.c
+@V@/gdb/hppa-bsd-nat.c @V@/gdb/hppab-nat.c
+@V@/gdb/hppa-bsd-tdep.c @V@/gdb/hppab-tdep.c
+@V@/gdb/hpp-nbsd-nat.c @V@/gdb/hppnb-nat.c
+@V@/gdb/hpp-nbsd-tdep.c @V@/gdb/hppnb-tdep.c
@V@/gdb/i386-darwin-nat.c @V@/gdb/i386dw-nat.c
@V@/gdb/i386-darwin-tdep.c @V@/gdb/i386dw-tdep.c
@V@/gdb/i386-linux-tdep.c @V@/gdb/i386lx-tdep.c
@V@/gdb/i386-linux-nat.c @V@/gdb/i386lx-nat.c
-@V@/gdb/i386bsd-nat.c @V@/gdb/i3bsd-nat.c
-@V@/gdb/i386bsd-tdep.c @V@/gdb/i3bsd-tdep.c
-@V@/gdb/i386fbsd-nat.c @V@/gdb/i3fbsd-nat.c
-@V@/gdb/i386fbsd-tdep.c @V@/gdb/i3fbsd-tdep.c
-@V@/gdb/i386gnu-nat.c @V@/gdb/i3gnu-nat.c
-@V@/gdb/i386gnu-tdep.c @V@/gdb/i3gnu-tdep.c
-@V@/gdb/i386nbsd-tdep.c @V@/gdb/i3nbsd-tdep.c
-@V@/gdb/i386obsd-nat.c @V@/gdb/i3obsd-nat.c
-@V@/gdb/i386obsd-tdep.c @V@/gdb/i3obsd-tdep.c
+@V@/gdb/i386-bsd-nat.c @V@/gdb/i3bsd-nat.c
+@V@/gdb/i386-bsd-tdep.c @V@/gdb/i3bsd-tdep.c
+@V@/gdb/i386-fbsd-nat.c @V@/gdb/i3fbsd-nat.c
+@V@/gdb/i386-fbsd-tdep.c @V@/gdb/i3fbsd-tdep.c
+@V@/gdb/i386-gnu-nat.c @V@/gdb/i3gnu-nat.c
+@V@/gdb/i386-gnu-tdep.c @V@/gdb/i3gnu-tdep.c
+@V@/gdb/i386-nbsd-tdep.c @V@/gdb/i3nbsd-tdep.c
+@V@/gdb/i386-obsd-nat.c @V@/gdb/i3obsd-nat.c
+@V@/gdb/i386-obsd-tdep.c @V@/gdb/i3obsd-tdep.c
@V@/gdb/i386-sol2-nat.c @V@/gdb/i3sol2-nat.c
@V@/gdb/i386-sol2-tdep.c @V@/gdb/i3sol2-tdep.c
@V@/gdb/ia64-aix-nat.c @V@/gdb/ia64ax-nat.c
@V@/gdb/m2-exp.tab.c @V@/gdb/m2-exp_tab.c
@V@/gdb/m32r-linux-nat.c @V@/gdb/m32rlnxnat.c
@V@/gdb/m32r-linux-tdep.c @V@/gdb/m32rlnxtdep.c
-@V@/gdb/m68klinux-nat.c @V@/gdb/m68kl-nat.c
-@V@/gdb/m68klinux-tdep.c @V@/gdb/m68kl-tdep.c
-@V@/gdb/m68kbsd-nat.c @V@/gdb/m68bsd-nat.c
-@V@/gdb/m68kbsd-tdep.c @V@/gdb/m68bsd-tdep.c
-@V@/gdb/m68knbsd-nat.c @V@/gdb/m6nbsd-nat.c
-@V@/gdb/m68knbsd-tdep.c @V@/gdb/m6nbsd-tdep.c
+@V@/gdb/m68k-linux-nat.c @V@/gdb/m68kl-nat.c
+@V@/gdb/m68k-linux-tdep.c @V@/gdb/m68kl-tdep.c
+@V@/gdb/m68k-bsd-nat.c @V@/gdb/m68bsd-nat.c
+@V@/gdb/m68k-bsd-tdep.c @V@/gdb/m68bsd-tdep.c
+@V@/gdb/m68k-nbsd-nat.c @V@/gdb/m6nbsd-nat.c
+@V@/gdb/m68k-nbsd-tdep.c @V@/gdb/m6nbsd-tdep.c
@V@/gdb/microblaze-rom.c @V@/gdb/mb-rom.c
@V@/gdb/microblaze-linux-tdep.c @V@/gdb/mbl-tdep.c
@V@/gdb/microblaze-tdep.h @V@/gdb/mb-tdep.h
@V@/gdb/microblaze-tdep.c @V@/gdb/mb-tdep.c
@V@/gdb/mips-linux-nat.c @V@/gdb/mipslnxnat.c
@V@/gdb/mips-linux-tdep.c @V@/gdb/mipslnxtdep.c
-@V@/gdb/mipsnbsd-nat.c @V@/gdb/mipsnbnat.c
-@V@/gdb/mipsnbsd-tdep.c @V@/gdb/mipsnbtdep.c
-@V@/gdb/mips64obsd-nat.c @V@/gdb/mipsobnat.c
-@V@/gdb/mips64obsd-tdep.c @V@/gdb/mipsobtdep.c
+@V@/gdb/mips-nbsd-nat.c @V@/gdb/mipsnbnat.c
+@V@/gdb/mips-nbsd-tdep.c @V@/gdb/mipsnbtdep.c
+@V@/gdb/mips64-obsd-nat.c @V@/gdb/mipsobnat.c
+@V@/gdb/mips64-obsd-tdep.c @V@/gdb/mipsobtdep.c
@V@/gdb/mn10300-linux-tdep.c @V@/gdb/mn10300linux-tdep.c
-@V@/gdb/ns32knbsd-nat.c @V@/gdb/ns32nb-nat.c
-@V@/gdb/ns32knbsd-tdep.c @V@/gdb/ns32nb-tdep.c
+@V@/gdb/ns32k-nbsd-nat.c @V@/gdb/ns32nb-nat.c
+@V@/gdb/ns32k-nbsd-tdep.c @V@/gdb/ns32nb-tdep.c
@V@/gdb/objc-exp.tab.c @V@/gdb/objc-exp_tab.c
@V@/gdb/p-exp.tab.c @V@/gdb/p-exp_tab.c
@V@/gdb/ppc-linux-tdep.c @V@/gdb/ppc-lx-tdep.c
@V@/gdb/ppc-linux-nat.c @V@/gdb/ppc-lx-nat.c
-@V@/gdb/ppcnbsd-nat.c @V@/gdb/ppcnb-nat.c
-@V@/gdb/ppcnbsd-tdep.c @V@/gdb/ppcnb-tdep.c
-@V@/gdb/ppcobsd-nat.c @V@/gdb/ppcob-nat.c
-@V@/gdb/ppcobsd-tdep.c @V@/gdb/ppcob-tdep.c
+@V@/gdb/ppc-nbsd-nat.c @V@/gdb/ppcnb-nat.c
+@V@/gdb/ppc-nbsd-tdep.c @V@/gdb/ppcnb-tdep.c
+@V@/gdb/ppc-obsd-nat.c @V@/gdb/ppcob-nat.c
+@V@/gdb/ppc-obsd-tdep.c @V@/gdb/ppcob-tdep.c
@V@/gdb/regformats/arm-with-vfpv2.dat @V@/gdb/regformats/arm-wv2.dat
@V@/gdb/regformats/arm-with-vfpv3.dat @V@/gdb/regformats/arm-wv3.dat
@V@/gdb/regformats/arm-with-iwmmxt.dat @V@/gdb/regformats/arm-iwmmxt.dat
@V@/gdb/remote-vx68.c @V@/gdb/rmt-vx68.c
@V@/gdb/remote-vxmips.c @V@/gdb/rmt-vxmips.c
@V@/gdb/remote-vxsparc.c @V@/gdb/rmt-vxsparc.c
-@V@/gdb/sparc64fbsd-nat.c @V@/gdb/sp64fb-nat.c
-@V@/gdb/sparc64fbsd-tdep.c @V@/gdb/sp64fb-tdep.c
-@V@/gdb/sparc64nbsd-nat.c @V@/gdb/sp64nb-nat.c
-@V@/gdb/sparc64nbsd-tdep.c @V@/gdb/sp64nb-tdep.c
+@V@/gdb/sparc64-fbsd-nat.c @V@/gdb/sp64fb-nat.c
+@V@/gdb/sparc64-fbsd-tdep.c @V@/gdb/sp64fb-tdep.c
+@V@/gdb/sparc64-nbsd-nat.c @V@/gdb/sp64nb-nat.c
+@V@/gdb/sparc64-nbsd-tdep.c @V@/gdb/sp64nb-tdep.c
@V@/gdb/sparc64-linux-nat.c @V@/gdb/sp64lx-nat.c
@V@/gdb/sparc64-linux-tdep.c @V@/gdb/sp64lx-tdep.c
@V@/gdb/sparc64-nat.c @V@/gdb/sp64-nat.c
@V@/gdb/sparc64-tdep.c @V@/gdb/sp64-tdep.c
@V@/gdb/sparc64-sol2-tdep.c @V@/gdb/sp64s2-tdep.c
-@V@/gdb/sparcnbsd-nat.c @V@/gdb/spnb-nat.c
-@V@/gdb/sparcnbsd-tdep.c @V@/gdb/spnb-tdep.c
+@V@/gdb/sparc-nbsd-nat.c @V@/gdb/spnb-nat.c
+@V@/gdb/sparc-nbsd-tdep.c @V@/gdb/spnb-tdep.c
@V@/gdb/sparc-linux-nat.c @V@/gdb/splx-nat.c
@V@/gdb/sparc-linux-tdep.c @V@/gdb/splx-tdep.c
@V@/gdb/sparc-sol2-nat.c @V@/gdb/spsol2-nat.c
@V@/gdb/amd64-linux-nat.c @V@/gdb/amd64-lnat.c
@V@/gdb/hppa-linux-tdep.c @V@/gdb/palnxtdep.c
@V@/gdb/hppa-linux-nat.c @V@/gdb/palnxnat.c
-@V@/gdb/hppanbsd-nat.c @V@/gdb/panbsd-nat.c
-@V@/gdb/hppanbsd-tdep.c @V@/gdb/panbsd-tdep.c
+@V@/gdb/hppa-nbsd-nat.c @V@/gdb/panbsd-nat.c
+@V@/gdb/hppa-nbsd-tdep.c @V@/gdb/panbsd-tdep.c
@V@/gdb/amd64-windows-nat.c @V@/gdb/amd64-wnat.c
@V@/gdb/amd64-windows-tdep.c @V@/gdb/amd64-wtdep.c
@V@/gdb/i386-windows-nat.c @V@/gdb/i386-wnat.c
# Host: FreeBSD/i386
NATDEPFILES= fork-child.o inf-ptrace.o \
- fbsd-nat.o x86-nat.o x86-dregs.o x86bsd-nat.o i386bsd-nat.o \
- i386fbsd-nat.o bsd-kvm.o
+ fbsd-nat.o x86-nat.o x86-dregs.o x86-bsd-nat.o i386-bsd-nat.o \
+ i386-fbsd-nat.o bsd-kvm.o
NAT_FILE= nm-fbsd.h
HAVE_NATIVE_GCORE_HOST = 1
# Host: FreeBSD/amd64
NATDEPFILES= fork-child.o inf-ptrace.o \
- fbsd-nat.o amd64-nat.o amd64bsd-nat.o amd64fbsd-nat.o \
- bsd-kvm.o x86-nat.o x86-dregs.o x86bsd-nat.o
+ fbsd-nat.o amd64-nat.o amd64-bsd-nat.o amd64-fbsd-nat.o \
+ bsd-kvm.o x86-nat.o x86-dregs.o x86-bsd-nat.o
HAVE_NATIVE_GCORE_HOST = 1
LOADLIBES= -lkvm
# Host: Intel 386 running the GNU Hurd
-NATDEPFILES= i386gnu-nat.o gnu-nat.o \
+NATDEPFILES= i386-gnu-nat.o gnu-nat.o \
x86-nat.o x86-dregs.o fork-child.o \
notify_S.o process_reply_S.o msg_reply_S.o \
msg_U.o exc_request_U.o exc_request_S.o
# Host: Solaris x86
-NATDEPFILES= fork-child.o i386v4-nat.o i386-sol2-nat.o \
+NATDEPFILES= fork-child.o i386-v4-nat.o i386-sol2-nat.o \
procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
HAVE_NATIVE_GCORE_HOST = 1
# Host: NetBSD/amd64
NATDEPFILES= fork-child.o inf-ptrace.o \
- nbsd-nat.o amd64-nat.o x86bsd-nat.o amd64bsd-nat.o amd64nbsd-nat.o
+ nbsd-nat.o amd64-nat.o x86-bsd-nat.o amd64-bsd-nat.o amd64-nbsd-nat.o
# Host: NetBSD/i386 ELF
NATDEPFILES= fork-child.o inf-ptrace.o \
- nbsd-nat.o x86bsd-nat.o i386bsd-nat.o i386nbsd-nat.o bsd-kvm.o
+ nbsd-nat.o x86-bsd-nat.o i386-bsd-nat.o i386-nbsd-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: OpenBSD/i386 ELF
NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o \
- x86bsd-nat.o i386bsd-nat.o i386obsd-nat.o bsd-kvm.o
+ x86-bsd-nat.o i386-bsd-nat.o i386-obsd-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: OpenBSD/amd64
NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o \
- amd64-nat.o x86bsd-nat.o amd64bsd-nat.o amd64obsd-nat.o bsd-kvm.o
+ amd64-nat.o x86-bsd-nat.o amd64-bsd-nat.o amd64-obsd-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: Solaris x86_64
-NATDEPFILES= fork-child.o amd64-nat.o i386v4-nat.o i386-sol2-nat.o \
+NATDEPFILES= fork-child.o amd64-nat.o i386-v4-nat.o i386-sol2-nat.o \
procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
HAVE_NATIVE_GCORE_HOST = 1
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
- m68klinux-nat.o \
+ m68k-linux-nat.o \
proc-service.o linux-thread-db.o \
linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
linux-personality.o \
# Host: NetBSD/m68k ELF
-NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o inf-ptrace.o
+NATDEPFILES= m68k-bsd-nat.o bsd-kvm.o fork-child.o inf-ptrace.o
LOADLIBES= -lkvm
# Host: OpenBSD/m68k
-NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o inf-ptrace.o
+NATDEPFILES= m68k-bsd-nat.o bsd-kvm.o fork-child.o inf-ptrace.o
LOADLIBES= -lkvm
# Host: OpenBSD/m88k
-NATDEPFILES= fork-child.o inf-ptrace.o m88kbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o m88k-bsd-nat.o
# Host: NetBSD/mips
-NATDEPFILES= fork-child.o inf-ptrace.o mipsnbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o mips-nbsd-nat.o
# Host: OpenBSD/mips64
-NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o mips64obsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o mips64-obsd-nat.o
# Host: NetBSD/hppa
-NATDEPFILES= fork-child.o inf-ptrace.o nbsd-nat.o hppanbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o nbsd-nat.o hppa-nbsd-nat.o
# Host: OpenBSD/hppa
-NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o hppaobsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o hppa-obsd-nat.o
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
-NATDEPFILES= fbsd-nat.o fork-child.o inf-ptrace.o ppcfbsd-nat.o bsd-kvm.o
+NATDEPFILES= fbsd-nat.o fork-child.o inf-ptrace.o ppc-fbsd-nat.o bsd-kvm.o
HAVE_NATIVE_GCORE_HOST = 1
LOADLIBES= -lkvm
# Host: NetBSD/powerpc
-NATDEPFILES= fork-child.o inf-ptrace.o ppcnbsd-nat.o bsd-kvm.o
+NATDEPFILES= fork-child.o inf-ptrace.o ppc-nbsd-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: OpenBSD/powerpc
-NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o ppcobsd-nat.o bsd-kvm.o
+NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o ppc-obsd-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: NetBSD/sh
-NATDEPFILES= fork-child.o inf-ptrace.o shnbsd-nat.o
+NATDEPFILES= fork-child.o inf-ptrace.o sh-nbsd-nat.o
# Host: FreeBSD/sparc64
NATDEPFILES= fork-child.o inf-ptrace.o \
- fbsd-nat.o sparc-nat.o sparc64-nat.o sparc64fbsd-nat.o \
+ fbsd-nat.o sparc-nat.o sparc64-nat.o sparc64-fbsd-nat.o \
bsd-kvm.o
HAVE_NATIVE_GCORE_HOST = 1
# Host: NetBSD/sparc64
NATDEPFILES= fork-child.o inf-ptrace.o \
- sparc64nbsd-nat.o sparc-nat.o bsd-kvm.o
+ sparc64-nbsd-nat.o sparc-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: NetBSD/sparc ELF
NATDEPFILES= fork-child.o inf-ptrace.o \
- sparc-nat.o sparcnbsd-nat.o bsd-kvm.o
+ sparc-nat.o sparc-nbsd-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: OpenBSD/sparc64
NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o \
- sparc64obsd-nat.o sparc-nat.o bsd-kvm.o
+ sparc64-obsd-nat.o sparc-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: NetBSD/vax ELF
NATDEPFILES= fork-child.o inf-ptrace.o \
- vaxbsd-nat.o bsd-kvm.o
+ vax-bsd-nat.o bsd-kvm.o
LOADLIBES= -lkvm
# Host: OpenBSD/vax
NATDEPFILES= fork-child.o inf-ptrace.o \
- vaxbsd-nat.o bsd-kvm.o
+ vax-bsd-nat.o bsd-kvm.o
LOADLIBES= -lkvm
;;
alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
# Target: FreeBSD/alpha
- gdb_target_obs="alpha-tdep.o alpha-mdebug-tdep.o alphabsd-tdep.o \
- alphafbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="alpha-tdep.o alpha-mdebug-tdep.o alpha-bsd-tdep.o \
+ alpha-fbsd-tdep.o solib-svr4.o"
;;
alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu)
# Target: NetBSD/alpha
- gdb_target_obs="alpha-tdep.o alpha-mdebug-tdep.o alphabsd-tdep.o \
- alphanbsd-tdep.o nbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="alpha-tdep.o alpha-mdebug-tdep.o alpha-bsd-tdep.o \
+ alpha-nbsd-tdep.o nbsd-tdep.o solib-svr4.o"
;;
alpha*-*-openbsd*)
# Target: OpenBSD/alpha
- gdb_target_obs="alpha-tdep.o alpha-mdebug-tdep.o alphabsd-tdep.o \
- alphanbsd-tdep.o alphaobsd-tdep.o nbsd-tdep.o \
+ gdb_target_obs="alpha-tdep.o alpha-mdebug-tdep.o alpha-bsd-tdep.o \
+ alpha-nbsd-tdep.o alpha-obsd-tdep.o nbsd-tdep.o \
obsd-tdep.o solib-svr4.o"
;;
alpha*-*-*)
;;
arm*-*-netbsd* | arm*-*-knetbsd*-gnu)
# Target: NetBSD/arm
- gdb_target_obs="arm.o arm-get-next-pcs.o arm-tdep.o armnbsd-tdep.o \
+ gdb_target_obs="arm.o arm-get-next-pcs.o arm-tdep.o arm-nbsd-tdep.o \
solib-svr4.o"
;;
arm*-*-openbsd*)
# Target: OpenBSD/arm
- gdb_target_obs="arm.o arm-get-next-pcs.o arm-tdep.o armbsd-tdep.o \
- armobsd-tdep.o obsd-tdep.o solib-svr4.o"
+ gdb_target_obs="arm.o arm-get-next-pcs.o arm-tdep.o arm-bsd-tdep.o \
+ arm-obsd-tdep.o obsd-tdep.o solib-svr4.o"
;;
arm*-*-symbianelf*)
# Target: SymbianOS/arm
;;
hppa*-*-netbsd*)
# Target: NetBSD/hppa
- gdb_target_obs="hppa-tdep.o hppabsd-tdep.o hppanbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="hppa-tdep.o hppa-bsd-tdep.o hppa-nbsd-tdep.o solib-svr4.o"
;;
hppa*-*-openbsd*)
# Target: OpenBSD/hppa
- gdb_target_obs="hppa-tdep.o hppabsd-tdep.o hppaobsd-tdep.o solib-svr4.o"
+ gdb_target_obs="hppa-tdep.o hppa-bsd-tdep.o hppa-obsd-tdep.o solib-svr4.o"
;;
hppa*-*-*)
# Target: HP PA-RISC
;;
i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
# Target: FreeBSD/i386
- gdb_target_obs="i386-tdep.o i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \
+ gdb_target_obs="i386-tdep.o i387-tdep.o i386-bsd-tdep.o i386-fbsd-tdep.o \
bsd-uthread.o fbsd-tdep.o solib-svr4.o"
;;
i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
# Target: NetBSD/i386
- gdb_target_obs="i386-tdep.o i387-tdep.o i386bsd-tdep.o i386nbsd-tdep.o \
+ gdb_target_obs="i386-tdep.o i387-tdep.o i386-bsd-tdep.o i386-nbsd-tdep.o \
nbsd-tdep.o solib-svr4.o"
;;
i[34567]86-*-openbsd*)
# Target: OpenBSD/i386
- gdb_target_obs="i386-tdep.o i387-tdep.o i386bsd-tdep.o i386obsd-tdep.o \
+ gdb_target_obs="i386-tdep.o i387-tdep.o i386-bsd-tdep.o i386-obsd-tdep.o \
obsd-tdep.o bsd-uthread.o solib-svr4.o"
;;
i[34567]86-*-nto*)
;;
i[34567]86-*-gnu*)
# Target: Intel 386 running the GNU Hurd
- gdb_target_obs="i386-tdep.o i387-tdep.o i386gnu-tdep.o solib-svr4.o"
+ gdb_target_obs="i386-tdep.o i387-tdep.o i386-gnu-tdep.o solib-svr4.o"
;;
i[34567]86-*-cygwin*)
# Target: Intel 386 running win32
;;
m68*-*-linux*)
# Target: Motorola m68k with a.out and ELF
- gdb_target_obs="m68k-tdep.o m68klinux-tdep.o solib-svr4.o \
+ gdb_target_obs="m68k-tdep.o m68k-linux-tdep.o solib-svr4.o \
linux-tdep.o glibc-tdep.o symfile-mem.o"
build_gdbserver=yes
;;
m68*-*-netbsd* | m68*-*-knetbsd*-gnu)
# Target: NetBSD/m68k
- gdb_target_obs="m68k-tdep.o m68kbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="m68k-tdep.o m68k-bsd-tdep.o solib-svr4.o"
;;
m68*-*-openbsd*)
# Target: OpenBSD/m68k
- gdb_target_obs="m68k-tdep.o m68kbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="m68k-tdep.o m68k-bsd-tdep.o solib-svr4.o"
;;
m88*-*-openbsd*)
;;
mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
# Target: MIPS running NetBSD
- gdb_target_obs="mips-tdep.o mipsnbsd-tdep.o solib-svr4.o nbsd-tdep.o"
+ gdb_target_obs="mips-tdep.o mips-nbsd-tdep.o solib-svr4.o nbsd-tdep.o"
gdb_sim=../sim/mips/libsim.a
;;
mips64*-*-openbsd*)
# Target: OpenBSD/mips64
- gdb_target_obs="mips-tdep.o mips64obsd-tdep.o obsd-tdep.o solib-svr4.o"
+ gdb_target_obs="mips-tdep.o mips64-obsd-tdep.o obsd-tdep.o solib-svr4.o"
;;
mips*-sde*-elf*)
# Target: MIPS SDE
powerpc*-*-freebsd*)
# Target: FreeBSD/powerpc
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
- ppcfbsd-tdep.o fbsd-tdep.o solib-svr4.o \
+ ppc-fbsd-tdep.o fbsd-tdep.o solib-svr4.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
# Target: NetBSD/powerpc
- gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o \
+ gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc-nbsd-tdep.o \
solib-svr4.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
gdb_sim=../sim/ppc/libsim.a
;;
powerpc-*-openbsd*)
# Target: OpenBSD/powerpc
- gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppcobsd-tdep.o \
+ gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc-obsd-tdep.o \
solib-svr4.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
;;
sh*-*-netbsdelf* | sh*-*-knetbsd*-gnu)
# Target: NetBSD/sh
- gdb_target_obs="sh-tdep.o shnbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="sh-tdep.o sh-nbsd-tdep.o solib-svr4.o"
gdb_sim=../sim/sh/libsim.a
;;
sh*-*-openbsd*)
# Target: OpenBSD/sh
- gdb_target_obs="sh-tdep.o sh64-tdep.o shnbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="sh-tdep.o sh64-tdep.o sh-nbsd-tdep.o solib-svr4.o"
;;
sh64-*-elf*)
# Target: Renesas/Super-H 64 bit with simulator
;;
sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
# Target: FreeBSD/sparc64
- gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64fbsd-tdep.o \
+ gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64-fbsd-tdep.o \
fbsd-tdep.o solib-svr4.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
# Target: NetBSD/sparc
- gdb_target_obs="sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o \
+ gdb_target_obs="sparc-tdep.o sparc-nbsd-tdep.o nbsd-tdep.o \
solib-svr4.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu)
# Target: NetBSD/sparc64
- gdb_target_obs="sparc64-tdep.o sparc64nbsd-tdep.o sparc-tdep.o \
- sparcnbsd-tdep.o nbsd-tdep.o solib-svr4.o \
+ gdb_target_obs="sparc64-tdep.o sparc64-nbsd-tdep.o sparc-tdep.o \
+ sparc-nbsd-tdep.o nbsd-tdep.o solib-svr4.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-openbsd*)
# Target: OpenBSD/sparc
- gdb_target_obs="sparc-tdep.o sparcnbsd-tdep.o sparcobsd-tdep.o \
+ gdb_target_obs="sparc-tdep.o sparc-nbsd-tdep.o sparc-obsd-tdep.o \
nbsd-tdep.o obsd-tdep.o bsd-uthread.o solib-svr4.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc64-*-openbsd*)
# Target: OpenBSD/sparc64
- gdb_target_obs="sparc64-tdep.o sparc64nbsd-tdep.o sparc64obsd-tdep.o \
- sparc-tdep.o sparcnbsd-tdep.o sparcobsd-tdep.o \
+ gdb_target_obs="sparc64-tdep.o sparc64-nbsd-tdep.o sparc64-obsd-tdep.o \
+ sparc-tdep.o sparc-nbsd-tdep.o sparc-obsd-tdep.o \
nbsd-tdep.o obsd-tdep.o bsd-uthread.o solib-svr4.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
vax-*-netbsd* | vax-*-knetbsd*-gnu)
# Target: NetBSD/vax
- gdb_target_obs="vax-tdep.o vaxnbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="vax-tdep.o vax-nbsd-tdep.o solib-svr4.o"
;;
vax-*-openbsd*)
# Target: OpenBSD/vax
- gdb_target_obs="vax-tdep.o vaxobsd-tdep.o"
+ gdb_target_obs="vax-tdep.o vax-obsd-tdep.o"
;;
vax-*-*)
# Target: VAX
;;
x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
# Target: FreeBSD/amd64
- gdb_target_obs="amd64-tdep.o amd64fbsd-tdep.o i386-tdep.o \
- i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \
+ gdb_target_obs="amd64-tdep.o amd64-fbsd-tdep.o i386-tdep.o \
+ i387-tdep.o i386-bsd-tdep.o i386-fbsd-tdep.o \
bsd-uthread.o fbsd-tdep.o solib-svr4.o"
;;
x86_64-*-mingw* | x86_64-*-cygwin*)
;;
x86_64-*-netbsd* | x86_64-*-knetbsd*-gnu)
# Target: NetBSD/amd64
- gdb_target_obs="amd64-tdep.o amd64nbsd-tdep.o i386-tdep.o i387-tdep.o \
+ gdb_target_obs="amd64-tdep.o amd64-nbsd-tdep.o i386-tdep.o i387-tdep.o \
nbsd-tdep.o solib-svr4.o"
;;
x86_64-*-openbsd*)
# Target: OpenBSD/amd64
- gdb_target_obs="amd64-tdep.o amd64obsd-tdep.o i386-tdep.o \
- i387-tdep.o i386bsd-tdep.o i386obsd-tdep.o \
+ gdb_target_obs="amd64-tdep.o amd64-obsd-tdep.o i386-tdep.o \
+ i387-tdep.o i386-bsd-tdep.o i386-obsd-tdep.o \
obsd-tdep.o bsd-uthread.o solib-svr4.o"
;;
x86_64-*-rtems*)
- gdb_target_obs="amd64-tdep.o i386-tdep.o i387-tdep.o i386bsd-tdep.o"
+ gdb_target_obs="amd64-tdep.o i386-tdep.o i387-tdep.o i386-bsd-tdep.o"
;;
xtensa*-*-linux*) gdb_target=linux
# Target: GNU/Linux Xtensa
--- /dev/null
+/* Target-dependent code for HP PA-RISC BSD's.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "objfiles.h"
+#include "target.h"
+#include "value.h"
+
+#include "elf/common.h"
+
+#include "hppa-tdep.h"
+#include "hppa-bsd-tdep.h"
+#include "dwarf2-frame.h"
+#include "solib-svr4.h"
+
+static CORE_ADDR
+hppabsd_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
+{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR faddr = value_as_address (function);
+ struct obj_section *faddr_sec;
+ gdb_byte buf[4];
+
+ /* Is this a plabel? If so, dereference it to get the Global Pointer
+ value. */
+ if (faddr & 2)
+ {
+ if (target_read_memory ((faddr & ~3) + 4, buf, sizeof buf) == 0)
+ return extract_unsigned_integer (buf, sizeof buf, byte_order);
+ }
+
+ /* If the address is in the .plt section, then the real function
+ hasn't yet been fixed up by the linker so we cannot determine the
+ Global Pointer for that function. */
+ if (in_plt_section (faddr))
+ return 0;
+
+ faddr_sec = find_pc_section (faddr);
+ if (faddr_sec != NULL)
+ {
+ struct obj_section *sec;
+
+ ALL_OBJFILE_OSECTIONS (faddr_sec->objfile, sec)
+ {
+ if (strcmp (sec->the_bfd_section->name, ".dynamic") == 0)
+ break;
+ }
+
+ if (sec < faddr_sec->objfile->sections_end)
+ {
+ CORE_ADDR addr = obj_section_addr (sec);
+ CORE_ADDR endaddr = obj_section_endaddr (sec);
+
+ while (addr < endaddr)
+ {
+ gdb_byte buf[4];
+ LONGEST tag;
+
+ if (target_read_memory (addr, buf, sizeof buf) != 0)
+ break;
+
+ tag = extract_signed_integer (buf, sizeof buf, byte_order);
+ if (tag == DT_PLTGOT)
+ {
+ CORE_ADDR pltgot;
+
+ if (target_read_memory (addr + 4, buf, sizeof buf) != 0)
+ break;
+
+ /* The NetBSD/OpenBSD ld.so doesn't relocate DT_PLTGOT, so
+ we have to do it ourselves. */
+ pltgot = extract_unsigned_integer (buf, sizeof buf,
+ byte_order);
+ pltgot += ANOFFSET (sec->objfile->section_offsets,
+ SECT_OFF_TEXT (sec->objfile));
+
+ return pltgot;
+ }
+
+ if (tag == DT_NULL)
+ break;
+
+ addr += 8;
+ }
+ }
+ }
+
+ return 0;
+}
+\f
+
+static void
+hppabsd_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
+ struct dwarf2_frame_state_reg *reg,
+ struct frame_info *this_frame)
+{
+ if (regnum == HPPA_PCOQ_HEAD_REGNUM)
+ reg->how = DWARF2_FRAME_REG_RA;
+ else if (regnum == HPPA_SP_REGNUM)
+ reg->how = DWARF2_FRAME_REG_CFA;
+}
+
+void
+hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* OpenBSD and NetBSD have a 64-bit 'long double'. */
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+
+ /* OpenBSD and NetBSD use ELF. */
+ tdep->is_elf = 1;
+ tdep->find_global_pointer = hppabsd_find_global_pointer;
+ tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
+ set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
+
+ /* OpenBSD and NetBSD use SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ /* Hook in the DWARF CFI frame unwinder. */
+ dwarf2_frame_set_init_reg (gdbarch, hppabsd_dwarf2_frame_init_reg);
+ dwarf2_append_unwinders (gdbarch);
+}
--- /dev/null
+/* Target-dependent code for HP PA-RISC BSD's.
+
+ Copyright (C) 2009-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef HPPA_BSD_TDEP_H
+#define HPPA_BSD_TDEP_H
+
+extern void hppabsd_init_abi (struct gdbarch_info, struct gdbarch *);
+
+#endif /* hppa-bsd-tdep.h */
--- /dev/null
+/* Native-dependent code for NetBSD/hppa.
+
+ Copyright (C) 2008-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "hppa-tdep.h"
+#include "inf-ptrace.h"
+
+#include "nbsd-nat.h"
+
+static int
+hppanbsd_gregset_supplies_p (int regnum)
+{
+ return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) ||
+ (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) ||
+ regnum == HPPA_IPSW_REGNUM ||
+ (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5));
+}
+
+static int
+hppanbsd_fpregset_supplies_p (int regnum)
+{
+ return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ const int *r = gregs;
+ int regnum;
+
+ for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+
+ regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
+ regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
+ regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
+ regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
+ regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
+ regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
+ regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
+ regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 1, regs + 37 * 4);
+ regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 2, regs + 38 * 4);
+ regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 3, regs + 39 * 4);
+ regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 4, regs + 40 * 4);
+}
+
+/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
+
+static void
+hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
+{
+ const char *regs = fpregs;
+ int regnum;
+
+ for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
+ regnum += 2, regs += 8)
+ {
+ regcache_raw_supply (regcache, regnum, regs);
+ regcache_raw_supply (regcache, regnum + 1, regs + 4);
+ }
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+hppanbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int *r = gregs;
+ int i;
+
+ for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 4);
+ }
+
+ if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
+ regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
+
+ if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
+ if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
+ if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
+ if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
+ regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1)
+ regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 1, regs + 37 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2)
+ regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 2, regs + 38 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3)
+ regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 3, regs + 39 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4)
+ regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 4, regs + 40 * 4);
+}
+
+/* Collect the floating-point registers from REGCACHE and store them
+ in FPREGS. */
+
+static void
+hppanbsd_collect_fpregset (struct regcache *regcache,
+ void *fpregs, int regnum)
+{
+ char *regs = fpregs;
+ int i;
+
+ for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
+ {
+ if (regnum == -1 || regnum == i || regnum == i + 1)
+ {
+ regcache_raw_collect (regcache, i, regs);
+ regcache_raw_collect (regcache, i + 1, regs + 4);
+ }
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating-point registers). */
+
+static void
+hppanbsd_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+
+{
+ if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ hppanbsd_supply_gregset (regcache, ®s);
+ }
+
+ if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ hppanbsd_supply_fpregset (regcache, &fpregs);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating-point registers). */
+
+static void
+hppanbsd_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ hppanbsd_collect_gregset (regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+ }
+
+ if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
+
+ if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+ }
+}
+
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_hppanbsd_nat (void);
+
+void
+_initialize_hppanbsd_nat (void)
+{
+ struct target_ops *t;
+
+ /* Add some extra features to the ptrace target. */
+ t = inf_ptrace_target ();
+
+ t->to_fetch_registers = hppanbsd_fetch_registers;
+ t->to_store_registers = hppanbsd_store_registers;
+
+ t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
+
+ add_target (t);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/hppa
+
+ Copyright (C) 2008-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "trad-frame.h"
+#include "tramp-frame.h"
+
+#include "hppa-tdep.h"
+#include "hppa-bsd-tdep.h"
+
+/* From <machine/mcontext.h>. */
+static int hppanbsd_mc_reg_offset[] =
+{
+ /* r0 ... r31 */
+ -1, 1 * 4, 2 * 4, 3 * 4,
+ 4 * 4, 5 * 4, 6 * 4, 7 * 4,
+ 8 * 4, 9 * 4, 10 * 4, 11 * 4,
+ 12 * 4, 13 * 4, 14 * 4, 15 * 4,
+ 16 * 4, 17 * 4, 18 * 4, 19 * 4,
+ 20 * 4, 21 * 4, 22 * 4, 23 * 4,
+ 24 * 4, 25 * 4, 26 * 4, 27 * 4,
+ 28 * 4, 29 * 4, 30 * 4, 31 * 4,
+
+ 32 * 4, /* HPPA_SAR_REGNUM */
+ 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */
+ 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */
+ 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */
+ 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */
+ -1, /* HPPA_EIEM_REGNUM */
+ -1, /* HPPA_IIR_REGNUM */
+ -1, /* HPPA_ISR_REGNUM */
+ -1, /* HPPA_IOR_REGNUM */
+ 0 * 4, /* HPPA_IPSW_REGNUM */
+ -1, /* spare? */
+ 41 * 4, /* HPPA_SR4_REGNUM */
+ 37 * 4, /* sr0 */
+ 38 * 4, /* sr1 */
+ 39 * 4, /* sr2 */
+ 40 * 4, /* sr3 */
+
+ /* more tbd */
+};
+
+static void hppanbsd_sigtramp_cache_init (const struct tramp_frame *,
+ struct frame_info *,
+ struct trad_frame_cache *,
+ CORE_ADDR);
+
+static const struct tramp_frame hppanbsd_sigtramp_si4 =
+{
+ SIGTRAMP_FRAME,
+ 4,
+ {
+ { 0xc7d7c012, -1 }, /* bb,>=,n %arg3, 30, 1f */
+ { 0xd6e01c1e, -1 }, /* depwi 0,31,2,%arg3 */
+ { 0x0ee81093, -1 }, /* ldw 4(%arg3), %r19 */
+ { 0x0ee01097, -1 }, /* ldw 0(%arg3), %arg3 */
+ /* 1: */
+ { 0xe8404000, -1 }, /* blr %r0, %rp */
+ { 0xeae0c002, -1 }, /* bv,n %r0(%arg3) */
+ { 0x08000240, -1 }, /* nop */
+
+ { 0x0803025a, -1 }, /* copy %r3, %arg0 */
+ { 0x20200801, -1 }, /* ldil -40000000, %r1 */
+ { 0xe420e008, -1 }, /* be,l 4(%sr7, %r1), %sr0, %r31 */
+ { 0x34160268, -1 }, /* ldi 134, %t1 ; SYS_setcontext */
+
+ { 0x081c025a, -1 }, /* copy ret0, %arg0 */
+ { 0x20200801, -1 }, /* ldil -40000000, %r1 */
+ { 0xe420e008, -1 }, /* be,l 4(%sr7, %r1), %sr0, %r31 */
+ { 0x34160002, -1 }, /* ldi 1, %t1 ; SYS_exit */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ hppanbsd_sigtramp_cache_init
+};
+
+
+static void
+hppanbsd_sigtramp_cache_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ CORE_ADDR sp = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM);
+ CORE_ADDR base;
+ int *reg_offset;
+ int num_regs;
+ int i;
+
+ reg_offset = hppanbsd_mc_reg_offset;
+ num_regs = ARRAY_SIZE (hppanbsd_mc_reg_offset);
+
+ /* frame pointer */
+ base = sp - 0x280;
+ /* offsetof(struct sigframe_siginfo, sf_uc) = 128 */
+ base += 128;
+ /* offsetof(ucontext_t, uc_mcontext) == 40 */
+ base += 40;
+
+ for (i = 0; i < num_regs; i++)
+ if (reg_offset[i] != -1)
+ trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+
+/* Core file support. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define HPPANBSD_SIZEOF_GREGS (44 * 4)
+
+static int hppanbsd_reg_offset[] =
+{
+ /* r0 ... r31 */
+ -1, 1 * 4, 2 * 4, 3 * 4,
+ 4 * 4, 5 * 4, 6 * 4, 7 * 4,
+ 8 * 4, 9 * 4, 10 * 4, 11 * 4,
+ 12 * 4, 13 * 4, 14 * 4, 15 * 4,
+ 16 * 4, 17 * 4, 18 * 4, 19 * 4,
+ 20 * 4, 21 * 4, 22 * 4, 23 * 4,
+ 24 * 4, 25 * 4, 26 * 4, 27 * 4,
+ 28 * 4, 29 * 4, 30 * 4, 31 * 4,
+
+ 32 * 4, /* HPPA_SAR_REGNUM */
+ 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */
+ 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */
+ 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */
+ 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */
+ -1, /* HPPA_EIEM_REGNUM */
+ -1, /* HPPA_IIR_REGNUM */
+ -1, /* HPPA_ISR_REGNUM */
+ -1, /* HPPA_IOR_REGNUM */
+ 0 * 4, /* HPPA_IPSW_REGNUM */
+};
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+hppanbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) gregs;
+ int i;
+
+ gdb_assert (len >= HPPANBSD_SIZEOF_GREGS);
+
+ for (i = 0; i < ARRAY_SIZE (hppanbsd_reg_offset); i++)
+ if (hppanbsd_reg_offset[i] != -1)
+ if (regnum == -1 || regnum == i)
+ regcache_raw_supply (regcache, i, regs + hppanbsd_reg_offset[i]);
+}
+
+/* NetBSD/hppa register set. */
+
+static const struct regset hppanbsd_gregset =
+{
+ NULL,
+ hppanbsd_supply_gregset
+};
+
+/* Iterate over supported core file register note sections. */
+
+static void
+hppanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", HPPANBSD_SIZEOF_GREGS, &hppanbsd_gregset, NULL, cb_data);
+}
+\f
+static void
+hppanbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* Obviously NetBSD is BSD-based. */
+ hppabsd_init_abi (info, gdbarch);
+
+ /* Core file support. */
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, hppanbsd_iterate_over_regset_sections);
+
+ tramp_frame_prepend_unwinder (gdbarch, &hppanbsd_sigtramp_si4);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_hppanbsd_tdep;
+
+void
+_initialize_hppanbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD_ELF,
+ hppanbsd_init_abi);
+}
--- /dev/null
+/* Native-dependent code for OpenBSD/hppa.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "hppa-tdep.h"
+#include "inf-ptrace.h"
+
+#include "obsd-nat.h"
+
+static int
+hppaobsd_gregset_supplies_p (int regnum)
+{
+ return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_CR27_REGNUM);
+}
+
+static int
+hppaobsd_fpregset_supplies_p (int regnum)
+{
+ return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+hppaobsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ gdb_byte zero[4] = { 0 };
+ const char *regs = gregs;
+ int regnum;
+
+ regcache_raw_supply (regcache, HPPA_R0_REGNUM, &zero);
+ for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+
+ if (sizeof(struct reg) >= 46 * 4)
+ {
+ regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
+ regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
+ regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
+ regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
+ regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
+ regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
+ regcache_raw_supply (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
+ regcache_raw_supply (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
+ regcache_raw_supply (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
+ regcache_raw_supply (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
+ regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
+ regcache_raw_supply (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
+ regcache_raw_supply (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
+ regcache_raw_supply (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
+ regcache_raw_supply (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
+ regcache_raw_supply (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
+ }
+ else
+ {
+ regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
+ regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+ regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+ }
+}
+
+/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
+
+static void
+hppaobsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
+{
+ const char *regs = fpregs;
+ int regnum;
+
+ for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
+ regnum += 2, regs += 8)
+ {
+ regcache_raw_supply (regcache, regnum, regs);
+ regcache_raw_supply (regcache, regnum + 1, regs + 4);
+ }
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+hppaobsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 4);
+ }
+
+ if (sizeof(struct reg) >= 46 * 4)
+ {
+ if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
+ regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
+ if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
+ if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
+ if (regnum == -1 || regnum == HPPA_SR0_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
+ if (regnum == -1 || regnum == HPPA_SR1_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
+ if (regnum == -1 || regnum == HPPA_SR2_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
+ if (regnum == -1 || regnum == HPPA_SR3_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
+ if (regnum == -1 || regnum == HPPA_SR5_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
+ if (regnum == -1 || regnum == HPPA_SR6_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
+ if (regnum == -1 || regnum == HPPA_SR7_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
+ if (regnum == -1 || regnum == HPPA_CR26_REGNUM)
+ regcache_raw_collect (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
+ if (regnum == -1 || regnum == HPPA_CR27_REGNUM)
+ regcache_raw_collect (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
+ }
+ else
+ {
+ if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+ }
+}
+
+/* Collect the floating-point registers from REGCACHE and store them
+ in FPREGS. */
+
+static void
+hppaobsd_collect_fpregset (struct regcache *regcache,
+ void *fpregs, int regnum)
+{
+ char *regs = fpregs;
+ int i;
+
+ for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
+ {
+ if (regnum == -1 || regnum == i || regnum == i + 1)
+ {
+ regcache_raw_collect (regcache, i, regs);
+ regcache_raw_collect (regcache, i + 1, regs + 4);
+ }
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating-point registers). */
+
+static void
+hppaobsd_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ hppaobsd_supply_gregset (regcache, ®s);
+ }
+
+ if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ hppaobsd_supply_fpregset (regcache, &fpregs);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating-point registers). */
+
+static void
+hppaobsd_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ hppaobsd_collect_gregset (regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+ }
+
+ if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ hppaobsd_collect_fpregset (regcache, &fpregs, regnum);
+
+ if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+ }
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_hppaobsd_nat (void);
+
+void
+_initialize_hppaobsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = hppaobsd_fetch_registers;
+ t->to_store_registers = hppaobsd_store_registers;
+ obsd_add_target (t);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/hppa
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "hppa-tdep.h"
+#include "hppa-bsd-tdep.h"
+
+/* Core file support. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define HPPAOBSD_SIZEOF_GREGS (34 * 4) /* OpenBSD 5.1 and earlier. */
+#define HPPANBSD_SIZEOF_GREGS (46 * 4) /* NetBSD and OpenBSD 5.2 and later. */
+
+/* Sizeof `struct fpreg' in <machine/reg.h>. */
+#define HPPAOBSD_SIZEOF_FPREGS (32 * 8)
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+hppaobsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ gdb_byte zero[4] = { 0 };
+ const gdb_byte *regs = (const gdb_byte *) gregs;
+ size_t offset;
+ int i;
+
+ gdb_assert (len >= HPPAOBSD_SIZEOF_GREGS);
+
+ if (regnum == -1 || regnum == HPPA_R0_REGNUM)
+ regcache_raw_supply (regcache, HPPA_R0_REGNUM, &zero);
+ for (i = HPPA_R1_REGNUM, offset = 4; i <= HPPA_R31_REGNUM; i++, offset += 4)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_supply (regcache, i, regs + offset);
+ }
+
+ if (len >= HPPANBSD_SIZEOF_GREGS)
+ {
+ if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
+ regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
+ if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
+ regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
+ if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
+ regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
+ if (regnum == -1 || regnum == HPPA_SR0_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
+ if (regnum == -1 || regnum == HPPA_SR1_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
+ if (regnum == -1 || regnum == HPPA_SR2_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
+ if (regnum == -1 || regnum == HPPA_SR3_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
+ if (regnum == -1 || regnum == HPPA_SR5_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
+ if (regnum == -1 || regnum == HPPA_SR6_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
+ if (regnum == -1 || regnum == HPPA_SR7_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
+ if (regnum == -1 || regnum == HPPA_CR26_REGNUM)
+ regcache_raw_supply (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
+ if (regnum == -1 || regnum == HPPA_CR27_REGNUM)
+ regcache_raw_supply (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
+ }
+ else
+ {
+ if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+ }
+}
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+hppaobsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) fpregs;
+ int i;
+
+ gdb_assert (len >= HPPAOBSD_SIZEOF_FPREGS);
+
+ for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + (i - HPPA_FP0_REGNUM) * 4);
+ }
+}
+
+/* OpenBSD/hppa register sets. */
+
+static const struct regset hppaobsd_gregset =
+{
+ NULL,
+ hppaobsd_supply_gregset,
+ NULL,
+ REGSET_VARIABLE_SIZE
+};
+
+static const struct regset hppaobsd_fpregset =
+{
+ NULL,
+ hppaobsd_supply_fpregset
+};
+
+/* Iterate over supported core file register note sections. */
+
+static void
+hppaobsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", HPPAOBSD_SIZEOF_GREGS, &hppaobsd_gregset, NULL, cb_data);
+ cb (".reg2", HPPAOBSD_SIZEOF_FPREGS, &hppaobsd_fpregset, NULL, cb_data);
+}
+\f
+
+static void
+hppaobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* Obviously OpenBSD is BSD-based. */
+ hppabsd_init_abi (info, gdbarch);
+
+ /* Core file support. */
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, hppaobsd_iterate_over_regset_sections);
+}
+\f
+
+/* OpenBSD uses uses the traditional NetBSD core file format, even for
+ ports that use ELF. */
+#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
+
+static enum gdb_osabi
+hppaobsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_CORE;
+
+ return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_hppabsd_tdep (void);
+
+void
+_initialize_hppabsd_tdep (void)
+{
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_hppa, bfd_target_unknown_flavour,
+ hppaobsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_OPENBSD_ELF,
+ hppaobsd_init_abi);
+}
+++ /dev/null
-/* Target-dependent code for HP PA-RISC BSD's.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "objfiles.h"
-#include "target.h"
-#include "value.h"
-
-#include "elf/common.h"
-
-#include "hppa-tdep.h"
-#include "hppabsd-tdep.h"
-#include "dwarf2-frame.h"
-#include "solib-svr4.h"
-
-static CORE_ADDR
-hppabsd_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR faddr = value_as_address (function);
- struct obj_section *faddr_sec;
- gdb_byte buf[4];
-
- /* Is this a plabel? If so, dereference it to get the Global Pointer
- value. */
- if (faddr & 2)
- {
- if (target_read_memory ((faddr & ~3) + 4, buf, sizeof buf) == 0)
- return extract_unsigned_integer (buf, sizeof buf, byte_order);
- }
-
- /* If the address is in the .plt section, then the real function
- hasn't yet been fixed up by the linker so we cannot determine the
- Global Pointer for that function. */
- if (in_plt_section (faddr))
- return 0;
-
- faddr_sec = find_pc_section (faddr);
- if (faddr_sec != NULL)
- {
- struct obj_section *sec;
-
- ALL_OBJFILE_OSECTIONS (faddr_sec->objfile, sec)
- {
- if (strcmp (sec->the_bfd_section->name, ".dynamic") == 0)
- break;
- }
-
- if (sec < faddr_sec->objfile->sections_end)
- {
- CORE_ADDR addr = obj_section_addr (sec);
- CORE_ADDR endaddr = obj_section_endaddr (sec);
-
- while (addr < endaddr)
- {
- gdb_byte buf[4];
- LONGEST tag;
-
- if (target_read_memory (addr, buf, sizeof buf) != 0)
- break;
-
- tag = extract_signed_integer (buf, sizeof buf, byte_order);
- if (tag == DT_PLTGOT)
- {
- CORE_ADDR pltgot;
-
- if (target_read_memory (addr + 4, buf, sizeof buf) != 0)
- break;
-
- /* The NetBSD/OpenBSD ld.so doesn't relocate DT_PLTGOT, so
- we have to do it ourselves. */
- pltgot = extract_unsigned_integer (buf, sizeof buf,
- byte_order);
- pltgot += ANOFFSET (sec->objfile->section_offsets,
- SECT_OFF_TEXT (sec->objfile));
-
- return pltgot;
- }
-
- if (tag == DT_NULL)
- break;
-
- addr += 8;
- }
- }
- }
-
- return 0;
-}
-\f
-
-static void
-hppabsd_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
- struct dwarf2_frame_state_reg *reg,
- struct frame_info *this_frame)
-{
- if (regnum == HPPA_PCOQ_HEAD_REGNUM)
- reg->how = DWARF2_FRAME_REG_RA;
- else if (regnum == HPPA_SP_REGNUM)
- reg->how = DWARF2_FRAME_REG_CFA;
-}
-
-void
-hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* OpenBSD and NetBSD have a 64-bit 'long double'. */
- set_gdbarch_long_double_bit (gdbarch, 64);
- set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
-
- /* OpenBSD and NetBSD use ELF. */
- tdep->is_elf = 1;
- tdep->find_global_pointer = hppabsd_find_global_pointer;
- tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
- set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
-
- /* OpenBSD and NetBSD use SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
- /* Hook in the DWARF CFI frame unwinder. */
- dwarf2_frame_set_init_reg (gdbarch, hppabsd_dwarf2_frame_init_reg);
- dwarf2_append_unwinders (gdbarch);
-}
+++ /dev/null
-/* Target-dependent code for HP PA-RISC BSD's.
-
- Copyright (C) 2009-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef HPPABSD_TDEP_H
-#define HPPABSD_TDEP_H
-
-extern void hppabsd_init_abi (struct gdbarch_info, struct gdbarch *);
-
-#endif /* hppabsd-tdep.h */
+++ /dev/null
-/* Native-dependent code for NetBSD/hppa.
-
- Copyright (C) 2008-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "hppa-tdep.h"
-#include "inf-ptrace.h"
-
-#include "nbsd-nat.h"
-
-static int
-hppanbsd_gregset_supplies_p (int regnum)
-{
- return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) ||
- (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) ||
- regnum == HPPA_IPSW_REGNUM ||
- (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5));
-}
-
-static int
-hppanbsd_fpregset_supplies_p (int regnum)
-{
- return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
-}
-
-/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
-
-static void
-hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
-{
- const char *regs = gregs;
- const int *r = gregs;
- int regnum;
-
- for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum, regs + regnum * 4);
-
- regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
- regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
- regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
- regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
- regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
- regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
- regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
- regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 1, regs + 37 * 4);
- regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 2, regs + 38 * 4);
- regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 3, regs + 39 * 4);
- regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 4, regs + 40 * 4);
-}
-
-/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
-
-static void
-hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
-{
- const char *regs = fpregs;
- int regnum;
-
- for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
- regnum += 2, regs += 8)
- {
- regcache_raw_supply (regcache, regnum, regs);
- regcache_raw_supply (regcache, regnum + 1, regs + 4);
- }
-}
-
-/* Collect the general-purpose registers from REGCACHE and store them
- in GREGS. */
-
-static void
-hppanbsd_collect_gregset (const struct regcache *regcache,
- void *gregs, int regnum)
-{
- char *regs = gregs;
- int *r = gregs;
- int i;
-
- for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
- {
- if (regnum == -1 || regnum == i)
- regcache_raw_collect (regcache, i, regs + i * 4);
- }
-
- if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
- regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
- if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
-
- if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
- regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
- if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
- if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
- if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
- regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
- regcache_raw_collect (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1)
- regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 1, regs + 37 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2)
- regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 2, regs + 38 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3)
- regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 3, regs + 39 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4)
- regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 4, regs + 40 * 4);
-}
-
-/* Collect the floating-point registers from REGCACHE and store them
- in FPREGS. */
-
-static void
-hppanbsd_collect_fpregset (struct regcache *regcache,
- void *fpregs, int regnum)
-{
- char *regs = fpregs;
- int i;
-
- for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
- {
- if (regnum == -1 || regnum == i || regnum == i + 1)
- {
- regcache_raw_collect (regcache, i, regs);
- regcache_raw_collect (regcache, i + 1, regs + 4);
- }
- }
-}
-\f
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers (including the floating-point registers). */
-
-static void
-hppanbsd_fetch_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-
-{
- if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- hppanbsd_supply_gregset (regcache, ®s);
- }
-
- if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- hppanbsd_supply_fpregset (regcache, &fpregs);
- }
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers (including the floating-point registers). */
-
-static void
-hppanbsd_store_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- hppanbsd_collect_gregset (regcache, ®s, regnum);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
- }
-
- if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
-
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't write floating point status"));
- }
-}
-
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_hppanbsd_nat (void);
-
-void
-_initialize_hppanbsd_nat (void)
-{
- struct target_ops *t;
-
- /* Add some extra features to the ptrace target. */
- t = inf_ptrace_target ();
-
- t->to_fetch_registers = hppanbsd_fetch_registers;
- t->to_store_registers = hppanbsd_store_registers;
-
- t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
-
- add_target (t);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/hppa
-
- Copyright (C) 2008-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-
-#include "trad-frame.h"
-#include "tramp-frame.h"
-
-#include "hppa-tdep.h"
-#include "hppabsd-tdep.h"
-
-/* From <machine/mcontext.h>. */
-static int hppanbsd_mc_reg_offset[] =
-{
- /* r0 ... r31 */
- -1, 1 * 4, 2 * 4, 3 * 4,
- 4 * 4, 5 * 4, 6 * 4, 7 * 4,
- 8 * 4, 9 * 4, 10 * 4, 11 * 4,
- 12 * 4, 13 * 4, 14 * 4, 15 * 4,
- 16 * 4, 17 * 4, 18 * 4, 19 * 4,
- 20 * 4, 21 * 4, 22 * 4, 23 * 4,
- 24 * 4, 25 * 4, 26 * 4, 27 * 4,
- 28 * 4, 29 * 4, 30 * 4, 31 * 4,
-
- 32 * 4, /* HPPA_SAR_REGNUM */
- 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */
- 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */
- 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */
- 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */
- -1, /* HPPA_EIEM_REGNUM */
- -1, /* HPPA_IIR_REGNUM */
- -1, /* HPPA_ISR_REGNUM */
- -1, /* HPPA_IOR_REGNUM */
- 0 * 4, /* HPPA_IPSW_REGNUM */
- -1, /* spare? */
- 41 * 4, /* HPPA_SR4_REGNUM */
- 37 * 4, /* sr0 */
- 38 * 4, /* sr1 */
- 39 * 4, /* sr2 */
- 40 * 4, /* sr3 */
-
- /* more tbd */
-};
-
-static void hppanbsd_sigtramp_cache_init (const struct tramp_frame *,
- struct frame_info *,
- struct trad_frame_cache *,
- CORE_ADDR);
-
-static const struct tramp_frame hppanbsd_sigtramp_si4 =
-{
- SIGTRAMP_FRAME,
- 4,
- {
- { 0xc7d7c012, -1 }, /* bb,>=,n %arg3, 30, 1f */
- { 0xd6e01c1e, -1 }, /* depwi 0,31,2,%arg3 */
- { 0x0ee81093, -1 }, /* ldw 4(%arg3), %r19 */
- { 0x0ee01097, -1 }, /* ldw 0(%arg3), %arg3 */
- /* 1: */
- { 0xe8404000, -1 }, /* blr %r0, %rp */
- { 0xeae0c002, -1 }, /* bv,n %r0(%arg3) */
- { 0x08000240, -1 }, /* nop */
-
- { 0x0803025a, -1 }, /* copy %r3, %arg0 */
- { 0x20200801, -1 }, /* ldil -40000000, %r1 */
- { 0xe420e008, -1 }, /* be,l 4(%sr7, %r1), %sr0, %r31 */
- { 0x34160268, -1 }, /* ldi 134, %t1 ; SYS_setcontext */
-
- { 0x081c025a, -1 }, /* copy ret0, %arg0 */
- { 0x20200801, -1 }, /* ldil -40000000, %r1 */
- { 0xe420e008, -1 }, /* be,l 4(%sr7, %r1), %sr0, %r31 */
- { 0x34160002, -1 }, /* ldi 1, %t1 ; SYS_exit */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- hppanbsd_sigtramp_cache_init
-};
-
-
-static void
-hppanbsd_sigtramp_cache_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func)
-{
- CORE_ADDR sp = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM);
- CORE_ADDR base;
- int *reg_offset;
- int num_regs;
- int i;
-
- reg_offset = hppanbsd_mc_reg_offset;
- num_regs = ARRAY_SIZE (hppanbsd_mc_reg_offset);
-
- /* frame pointer */
- base = sp - 0x280;
- /* offsetof(struct sigframe_siginfo, sf_uc) = 128 */
- base += 128;
- /* offsetof(ucontext_t, uc_mcontext) == 40 */
- base += 40;
-
- for (i = 0; i < num_regs; i++)
- if (reg_offset[i] != -1)
- trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (this_cache, frame_id_build (sp, func));
-}
-
-/* Core file support. */
-
-/* Sizeof `struct reg' in <machine/reg.h>. */
-#define HPPANBSD_SIZEOF_GREGS (44 * 4)
-
-static int hppanbsd_reg_offset[] =
-{
- /* r0 ... r31 */
- -1, 1 * 4, 2 * 4, 3 * 4,
- 4 * 4, 5 * 4, 6 * 4, 7 * 4,
- 8 * 4, 9 * 4, 10 * 4, 11 * 4,
- 12 * 4, 13 * 4, 14 * 4, 15 * 4,
- 16 * 4, 17 * 4, 18 * 4, 19 * 4,
- 20 * 4, 21 * 4, 22 * 4, 23 * 4,
- 24 * 4, 25 * 4, 26 * 4, 27 * 4,
- 28 * 4, 29 * 4, 30 * 4, 31 * 4,
-
- 32 * 4, /* HPPA_SAR_REGNUM */
- 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */
- 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */
- 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */
- 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */
- -1, /* HPPA_EIEM_REGNUM */
- -1, /* HPPA_IIR_REGNUM */
- -1, /* HPPA_ISR_REGNUM */
- -1, /* HPPA_IOR_REGNUM */
- 0 * 4, /* HPPA_IPSW_REGNUM */
-};
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-hppanbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) gregs;
- int i;
-
- gdb_assert (len >= HPPANBSD_SIZEOF_GREGS);
-
- for (i = 0; i < ARRAY_SIZE (hppanbsd_reg_offset); i++)
- if (hppanbsd_reg_offset[i] != -1)
- if (regnum == -1 || regnum == i)
- regcache_raw_supply (regcache, i, regs + hppanbsd_reg_offset[i]);
-}
-
-/* NetBSD/hppa register set. */
-
-static const struct regset hppanbsd_gregset =
-{
- NULL,
- hppanbsd_supply_gregset
-};
-
-/* Iterate over supported core file register note sections. */
-
-static void
-hppanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", HPPANBSD_SIZEOF_GREGS, &hppanbsd_gregset, NULL, cb_data);
-}
-\f
-static void
-hppanbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- /* Obviously NetBSD is BSD-based. */
- hppabsd_init_abi (info, gdbarch);
-
- /* Core file support. */
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, hppanbsd_iterate_over_regset_sections);
-
- tramp_frame_prepend_unwinder (gdbarch, &hppanbsd_sigtramp_si4);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_hppanbsd_tdep;
-
-void
-_initialize_hppanbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD_ELF,
- hppanbsd_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for OpenBSD/hppa.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "hppa-tdep.h"
-#include "inf-ptrace.h"
-
-#include "obsd-nat.h"
-
-static int
-hppaobsd_gregset_supplies_p (int regnum)
-{
- return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_CR27_REGNUM);
-}
-
-static int
-hppaobsd_fpregset_supplies_p (int regnum)
-{
- return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
-}
-
-/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
-
-static void
-hppaobsd_supply_gregset (struct regcache *regcache, const void *gregs)
-{
- gdb_byte zero[4] = { 0 };
- const char *regs = gregs;
- int regnum;
-
- regcache_raw_supply (regcache, HPPA_R0_REGNUM, &zero);
- for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum, regs + regnum * 4);
-
- if (sizeof(struct reg) >= 46 * 4)
- {
- regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
- regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
- regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
- regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
- regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
- regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
- regcache_raw_supply (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
- regcache_raw_supply (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
- regcache_raw_supply (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
- regcache_raw_supply (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
- regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
- regcache_raw_supply (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
- regcache_raw_supply (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
- regcache_raw_supply (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
- regcache_raw_supply (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
- regcache_raw_supply (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
- }
- else
- {
- regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
- regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
- regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
- }
-}
-
-/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
-
-static void
-hppaobsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
-{
- const char *regs = fpregs;
- int regnum;
-
- for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
- regnum += 2, regs += 8)
- {
- regcache_raw_supply (regcache, regnum, regs);
- regcache_raw_supply (regcache, regnum + 1, regs + 4);
- }
-}
-
-/* Collect the general-purpose registers from REGCACHE and store them
- in GREGS. */
-
-static void
-hppaobsd_collect_gregset (const struct regcache *regcache,
- void *gregs, int regnum)
-{
- char *regs = gregs;
- int i;
-
- for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
- {
- if (regnum == -1 || regnum == i)
- regcache_raw_collect (regcache, i, regs + i * 4);
- }
-
- if (sizeof(struct reg) >= 46 * 4)
- {
- if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
- regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
- if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
- regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
- if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
- if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
- if (regnum == -1 || regnum == HPPA_SR0_REGNUM)
- regcache_raw_collect (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
- if (regnum == -1 || regnum == HPPA_SR1_REGNUM)
- regcache_raw_collect (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
- if (regnum == -1 || regnum == HPPA_SR2_REGNUM)
- regcache_raw_collect (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
- if (regnum == -1 || regnum == HPPA_SR3_REGNUM)
- regcache_raw_collect (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
- regcache_raw_collect (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
- if (regnum == -1 || regnum == HPPA_SR5_REGNUM)
- regcache_raw_collect (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
- if (regnum == -1 || regnum == HPPA_SR6_REGNUM)
- regcache_raw_collect (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
- if (regnum == -1 || regnum == HPPA_SR7_REGNUM)
- regcache_raw_collect (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
- if (regnum == -1 || regnum == HPPA_CR26_REGNUM)
- regcache_raw_collect (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
- if (regnum == -1 || regnum == HPPA_CR27_REGNUM)
- regcache_raw_collect (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
- }
- else
- {
- if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
- regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs);
- if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
- regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
- }
-}
-
-/* Collect the floating-point registers from REGCACHE and store them
- in FPREGS. */
-
-static void
-hppaobsd_collect_fpregset (struct regcache *regcache,
- void *fpregs, int regnum)
-{
- char *regs = fpregs;
- int i;
-
- for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
- {
- if (regnum == -1 || regnum == i || regnum == i + 1)
- {
- regcache_raw_collect (regcache, i, regs);
- regcache_raw_collect (regcache, i + 1, regs + 4);
- }
- }
-}
-\f
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers (including the floating-point registers). */
-
-static void
-hppaobsd_fetch_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- hppaobsd_supply_gregset (regcache, ®s);
- }
-
- if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- hppaobsd_supply_fpregset (regcache, &fpregs);
- }
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers (including the floating-point registers). */
-
-static void
-hppaobsd_store_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- hppaobsd_collect_gregset (regcache, ®s, regnum);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
- }
-
- if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- hppaobsd_collect_fpregset (regcache, &fpregs, regnum);
-
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't write floating point status"));
- }
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_hppaobsd_nat (void);
-
-void
-_initialize_hppaobsd_nat (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
- t->to_fetch_registers = hppaobsd_fetch_registers;
- t->to_store_registers = hppaobsd_store_registers;
- obsd_add_target (t);
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/hppa
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-
-#include "hppa-tdep.h"
-#include "hppabsd-tdep.h"
-
-/* Core file support. */
-
-/* Sizeof `struct reg' in <machine/reg.h>. */
-#define HPPAOBSD_SIZEOF_GREGS (34 * 4) /* OpenBSD 5.1 and earlier. */
-#define HPPANBSD_SIZEOF_GREGS (46 * 4) /* NetBSD and OpenBSD 5.2 and later. */
-
-/* Sizeof `struct fpreg' in <machine/reg.h>. */
-#define HPPAOBSD_SIZEOF_FPREGS (32 * 8)
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-hppaobsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- gdb_byte zero[4] = { 0 };
- const gdb_byte *regs = (const gdb_byte *) gregs;
- size_t offset;
- int i;
-
- gdb_assert (len >= HPPAOBSD_SIZEOF_GREGS);
-
- if (regnum == -1 || regnum == HPPA_R0_REGNUM)
- regcache_raw_supply (regcache, HPPA_R0_REGNUM, &zero);
- for (i = HPPA_R1_REGNUM, offset = 4; i <= HPPA_R31_REGNUM; i++, offset += 4)
- {
- if (regnum == -1 || regnum == i)
- regcache_raw_supply (regcache, i, regs + offset);
- }
-
- if (len >= HPPANBSD_SIZEOF_GREGS)
- {
- if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
- regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
- if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
- regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
- if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
- regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
- if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
- regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
- regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
- regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
- if (regnum == -1 || regnum == HPPA_SR0_REGNUM)
- regcache_raw_supply (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
- if (regnum == -1 || regnum == HPPA_SR1_REGNUM)
- regcache_raw_supply (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
- if (regnum == -1 || regnum == HPPA_SR2_REGNUM)
- regcache_raw_supply (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
- if (regnum == -1 || regnum == HPPA_SR3_REGNUM)
- regcache_raw_supply (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
- regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
- if (regnum == -1 || regnum == HPPA_SR5_REGNUM)
- regcache_raw_supply (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
- if (regnum == -1 || regnum == HPPA_SR6_REGNUM)
- regcache_raw_supply (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
- if (regnum == -1 || regnum == HPPA_SR7_REGNUM)
- regcache_raw_supply (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
- if (regnum == -1 || regnum == HPPA_CR26_REGNUM)
- regcache_raw_supply (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
- if (regnum == -1 || regnum == HPPA_CR27_REGNUM)
- regcache_raw_supply (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
- }
- else
- {
- if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
- regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
- if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
- regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
- regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
- }
-}
-
-/* Supply register REGNUM from the buffer specified by FPREGS and LEN
- in the floating-point register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-hppaobsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) fpregs;
- int i;
-
- gdb_assert (len >= HPPAOBSD_SIZEOF_FPREGS);
-
- for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + (i - HPPA_FP0_REGNUM) * 4);
- }
-}
-
-/* OpenBSD/hppa register sets. */
-
-static const struct regset hppaobsd_gregset =
-{
- NULL,
- hppaobsd_supply_gregset,
- NULL,
- REGSET_VARIABLE_SIZE
-};
-
-static const struct regset hppaobsd_fpregset =
-{
- NULL,
- hppaobsd_supply_fpregset
-};
-
-/* Iterate over supported core file register note sections. */
-
-static void
-hppaobsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", HPPAOBSD_SIZEOF_GREGS, &hppaobsd_gregset, NULL, cb_data);
- cb (".reg2", HPPAOBSD_SIZEOF_FPREGS, &hppaobsd_fpregset, NULL, cb_data);
-}
-\f
-
-static void
-hppaobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- /* Obviously OpenBSD is BSD-based. */
- hppabsd_init_abi (info, gdbarch);
-
- /* Core file support. */
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, hppaobsd_iterate_over_regset_sections);
-}
-\f
-
-/* OpenBSD uses uses the traditional NetBSD core file format, even for
- ports that use ELF. */
-#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
-
-static enum gdb_osabi
-hppaobsd_core_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
- return GDB_OSABI_NETBSD_CORE;
-
- return GDB_OSABI_UNKNOWN;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_hppabsd_tdep (void);
-
-void
-_initialize_hppabsd_tdep (void)
-{
- /* BFD doesn't set a flavour for NetBSD style a.out core files. */
- gdbarch_register_osabi_sniffer (bfd_arch_hppa, bfd_target_unknown_flavour,
- hppaobsd_core_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_OPENBSD_ELF,
- hppaobsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for modern i386 BSD's.
+
+ Copyright (C) 2000-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+
+#include "i386-tdep.h"
+#include "i387-tdep.h"
+#include "x86-bsd-nat.h"
+#include "i386-bsd-nat.h"
+#include "inf-ptrace.h"
+\f
+
+/* In older BSD versions we cannot get at some of the segment
+ registers. FreeBSD for example didn't support the %fs and %gs
+ registers until the 3.0 release. We have autoconf checks for their
+ presence, and deal gracefully with their absence. */
+
+/* Offset in `struct reg' where MEMBER is stored. */
+#define REG_OFFSET(member) offsetof (struct reg, member)
+
+/* At i386bsd_reg_offset[REGNUM] you'll find the offset in `struct
+ reg' where the GDB register REGNUM is stored. Unsupported
+ registers are marked with `-1'. */
+static int i386bsd_r_reg_offset[] =
+{
+ REG_OFFSET (r_eax),
+ REG_OFFSET (r_ecx),
+ REG_OFFSET (r_edx),
+ REG_OFFSET (r_ebx),
+ REG_OFFSET (r_esp),
+ REG_OFFSET (r_ebp),
+ REG_OFFSET (r_esi),
+ REG_OFFSET (r_edi),
+ REG_OFFSET (r_eip),
+ REG_OFFSET (r_eflags),
+ REG_OFFSET (r_cs),
+ REG_OFFSET (r_ss),
+ REG_OFFSET (r_ds),
+ REG_OFFSET (r_es),
+#ifdef HAVE_STRUCT_REG_R_FS
+ REG_OFFSET (r_fs),
+#else
+ -1,
+#endif
+#ifdef HAVE_STRUCT_REG_R_GS
+ REG_OFFSET (r_gs)
+#else
+ -1
+#endif
+};
+
+/* Macro to determine if a register is fetched with PT_GETREGS. */
+#define GETREGS_SUPPLIES(regnum) \
+ ((0 <= (regnum) && (regnum) <= 15))
+
+#ifdef HAVE_PT_GETXMMREGS
+/* Set to 1 if the kernel supports PT_GETXMMREGS. Initialized to -1
+ so that we try PT_GETXMMREGS the first time around. */
+static int have_ptrace_xmmregs = -1;
+#endif
+\f
+
+/* Supply the general-purpose registers in GREGS, to REGCACHE. */
+
+static void
+i386bsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = (const char *) gregs;
+ int regnum;
+
+ for (regnum = 0; regnum < ARRAY_SIZE (i386bsd_r_reg_offset); regnum++)
+ {
+ int offset = i386bsd_r_reg_offset[regnum];
+
+ if (offset != -1)
+ regcache_raw_supply (regcache, regnum, regs + offset);
+ }
+}
+
+/* Collect register REGNUM from REGCACHE and store its contents in
+ GREGS. If REGNUM is -1, collect and store all appropriate
+ registers. */
+
+static void
+i386bsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = (char *) gregs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE (i386bsd_r_reg_offset); i++)
+ {
+ if (regnum == -1 || regnum == i)
+ {
+ int offset = i386bsd_r_reg_offset[i];
+
+ if (offset != -1)
+ regcache_raw_collect (regcache, i, regs + offset);
+ }
+ }
+}
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating point registers). */
+
+static void
+i386bsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ if (regnum == -1 || GETREGS_SUPPLIES (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ i386bsd_supply_gregset (regcache, ®s);
+ if (regnum != -1)
+ return;
+ }
+
+ if (regnum == -1 || regnum >= I386_ST0_REGNUM)
+ {
+ struct fpreg fpregs;
+#ifdef HAVE_PT_GETXMMREGS
+ char xmmregs[512];
+#endif
+
+#ifdef PT_GETXSTATE_INFO
+ if (x86bsd_xsave_len != 0)
+ {
+ void *xstateregs;
+
+ xstateregs = alloca (x86bsd_xsave_len);
+ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
+ perror_with_name (_("Couldn't get extended state status"));
+
+ i387_supply_xsave (regcache, -1, xstateregs);
+ return;
+ }
+#endif
+
+#ifdef HAVE_PT_GETXMMREGS
+ if (have_ptrace_xmmregs != 0
+ && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
+ {
+ have_ptrace_xmmregs = 1;
+ i387_supply_fxsave (regcache, -1, xmmregs);
+ }
+ else
+ {
+ have_ptrace_xmmregs = 0;
+#endif
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ i387_supply_fsave (regcache, -1, &fpregs);
+#ifdef HAVE_PT_GETXMMREGS
+ }
+#endif
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating point registers). */
+
+static void
+i386bsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ if (regnum == -1 || GETREGS_SUPPLIES (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ i386bsd_collect_gregset (regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+
+ if (regnum != -1)
+ return;
+ }
+
+ if (regnum == -1 || regnum >= I386_ST0_REGNUM)
+ {
+ struct fpreg fpregs;
+#ifdef HAVE_PT_GETXMMREGS
+ char xmmregs[512];
+#endif
+
+#ifdef PT_GETXSTATE_INFO
+ if (x86bsd_xsave_len != 0)
+ {
+ void *xstateregs;
+
+ xstateregs = alloca (x86bsd_xsave_len);
+ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
+ perror_with_name (_("Couldn't get extended state status"));
+
+ i387_collect_xsave (regcache, -1, xstateregs, 0);
+
+ if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xstateregs, x86bsd_xsave_len) == -1)
+ perror_with_name (_("Couldn't write extended state status"));
+ return;
+ }
+#endif
+
+#ifdef HAVE_PT_GETXMMREGS
+ if (have_ptrace_xmmregs != 0
+ && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
+ {
+ have_ptrace_xmmregs = 1;
+
+ i387_collect_fxsave (regcache, regnum, xmmregs);
+
+ if (ptrace (PT_SETXMMREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xmmregs, 0) == -1)
+ perror_with_name (_("Couldn't write XMM registers"));
+ }
+ else
+ {
+ have_ptrace_xmmregs = 0;
+#endif
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ i387_collect_fsave (regcache, regnum, &fpregs);
+
+ if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+#ifdef HAVE_PT_GETXMMREGS
+ }
+#endif
+ }
+}
+
+/* Create a prototype *BSD/i386 target. The client can override it
+ with local methods. */
+
+struct target_ops *
+i386bsd_target (void)
+{
+ struct target_ops *t;
+
+ t = x86bsd_target ();
+ t->to_fetch_registers = i386bsd_fetch_inferior_registers;
+ t->to_store_registers = i386bsd_store_inferior_registers;
+ return t;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_i386bsd_nat (void);
+
+void
+_initialize_i386bsd_nat (void)
+{
+ int offset;
+
+ /* To support the recognition of signal handlers, i386-bsd-tdep.c
+ hardcodes some constants. Inclusion of this file means that we
+ are compiling a native debugger, which means that we can use the
+ system header files and sysctl(3) to get at the relevant
+ information. */
+
+#if defined (__FreeBSD_version) && __FreeBSD_version >= 400011
+#define SC_REG_OFFSET i386fbsd4_sc_reg_offset
+#elif defined (__FreeBSD_version) && __FreeBSD_version >= 300005
+#define SC_REG_OFFSET i386fbsd_sc_reg_offset
+#elif defined (NetBSD) || defined (__NetBSD_Version__)
+#define SC_REG_OFFSET i386nbsd_sc_reg_offset
+#elif defined (OpenBSD)
+#define SC_REG_OFFSET i386obsd_sc_reg_offset
+#endif
+
+#ifdef SC_REG_OFFSET
+
+ /* We only check the program counter, stack pointer and frame
+ pointer since these members of `struct sigcontext' are essential
+ for providing backtraces. More checks could be added, but would
+ involve adding configure checks for the appropriate structure
+ members, since older BSD's don't provide all of them. */
+
+#define SC_PC_OFFSET SC_REG_OFFSET[I386_EIP_REGNUM]
+#define SC_SP_OFFSET SC_REG_OFFSET[I386_ESP_REGNUM]
+#define SC_FP_OFFSET SC_REG_OFFSET[I386_EBP_REGNUM]
+
+ /* Override the default value for the offset of the program counter
+ in the sigcontext structure. */
+ offset = offsetof (struct sigcontext, sc_pc);
+
+ if (SC_PC_OFFSET != offset)
+ {
+ warning (_("\
+offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>."),
+ offset, SC_PC_OFFSET);
+ }
+
+ SC_PC_OFFSET = offset;
+
+ /* Likewise for the stack pointer. */
+ offset = offsetof (struct sigcontext, sc_sp);
+
+ if (SC_SP_OFFSET != offset)
+ {
+ warning (_("\
+offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>."),
+ offset, SC_SP_OFFSET);
+ }
+
+ SC_SP_OFFSET = offset;
+
+ /* And the frame pointer. */
+ offset = offsetof (struct sigcontext, sc_fp);
+
+ if (SC_FP_OFFSET != offset)
+ {
+ warning (_("\
+offsetof (struct sigcontext, sc_fp) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>."),
+ offset, SC_FP_OFFSET);
+ }
+
+ SC_FP_OFFSET = offset;
+
+#endif /* SC_REG_OFFSET */
+}
--- /dev/null
+/* Native-dependent code for modern i386 BSD's.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef I386_BSD_NAT_H
+#define I386_BSD_NAT_H
+
+/* Create a prototype *BSD/i386 target. The client can override it
+ with local methods. */
+
+extern struct target_ops *i386bsd_target (void);
+
+#endif /* i386-bsd-nat.h */
--- /dev/null
+/* Target-dependent code for i386 BSD's.
+
+ Copyright (C) 2001-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "osabi.h"
+
+#include "i386-tdep.h"
+
+/* Support for signal handlers. */
+
+/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
+ address of the associated sigcontext structure. */
+
+static CORE_ADDR
+i386bsd_sigcontext_addr (struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ gdb_byte buf[4];
+ CORE_ADDR sp;
+
+ get_frame_register (this_frame, I386_ESP_REGNUM, buf);
+ sp = extract_unsigned_integer (buf, 4, byte_order);
+
+ return read_memory_unsigned_integer (sp + 8, 4, byte_order);
+}
+\f
+
+/* Support for shared libraries. */
+
+/* Traditional BSD (4.3 BSD, still used for BSDI and 386BSD). */
+
+/* From <machine/signal.h>. */
+int i386bsd_sc_reg_offset[] =
+{
+ -1, /* %eax */
+ -1, /* %ecx */
+ -1, /* %edx */
+ -1, /* %ebx */
+ 8 + 0 * 4, /* %esp */
+ 8 + 1 * 4, /* %ebp */
+ -1, /* %esi */
+ -1, /* %edi */
+ 8 + 3 * 4, /* %eip */
+ 8 + 4 * 4, /* %eflags */
+ -1, /* %cs */
+ -1, /* %ss */
+ -1, /* %ds */
+ -1, /* %es */
+ -1, /* %fs */
+ -1 /* %gs */
+};
+
+void
+i386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->jb_pc_offset = 0;
+
+ tdep->sigtramp_start = 0xfdbfdfc0;
+ tdep->sigtramp_end = 0xfdbfe000;
+ tdep->sigcontext_addr = i386bsd_sigcontext_addr;
+ tdep->sc_reg_offset = i386bsd_sc_reg_offset;
+ tdep->sc_num_regs = ARRAY_SIZE (i386bsd_sc_reg_offset);
+}
+
+\f
+static enum gdb_osabi
+i386bsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-i386-netbsd") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ if (strcmp (bfd_get_target (abfd), "a.out-i386-freebsd") == 0)
+ return GDB_OSABI_FREEBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+static enum gdb_osabi
+i386bsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+\f
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_i386bsd_tdep (void);
+
+void
+_initialize_i386bsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_aout_flavour,
+ i386bsd_aout_osabi_sniffer);
+
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_unknown_flavour,
+ i386bsd_core_osabi_sniffer);
+}
--- /dev/null
+/* Native-dependent code for FreeBSD/i386.
+
+ Copyright (C) 2001-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+
+#include "fbsd-nat.h"
+#include "i386-tdep.h"
+#include "x86-nat.h"
+#include "x86-bsd-nat.h"
+#include "i386-bsd-nat.h"
+
+/* Resume execution of the inferior process. If STEP is nonzero,
+ single-step it. If SIGNAL is nonzero, give it that signal. */
+
+static void
+i386fbsd_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum gdb_signal signal)
+{
+ pid_t pid = ptid_get_pid (ptid);
+ int request = PT_STEP;
+
+ if (pid == -1)
+ /* Resume all threads. This only gets used in the non-threaded
+ case, where "resume all threads" and "resume inferior_ptid" are
+ the same. */
+ pid = ptid_get_pid (inferior_ptid);
+
+ if (!step)
+ {
+ struct regcache *regcache = get_current_regcache ();
+ ULONGEST eflags;
+
+ /* Workaround for a bug in FreeBSD. Make sure that the trace
+ flag is off when doing a continue. There is a code path
+ through the kernel which leaves the flag set when it should
+ have been cleared. If a process has a signal pending (such
+ as SIGALRM) and we do a PT_STEP, the process never really has
+ a chance to run because the kernel needs to notify the
+ debugger that a signal is being sent. Therefore, the process
+ never goes through the kernel's trap() function which would
+ normally clear it. */
+
+ regcache_cooked_read_unsigned (regcache, I386_EFLAGS_REGNUM,
+ &eflags);
+ if (eflags & 0x0100)
+ regcache_cooked_write_unsigned (regcache, I386_EFLAGS_REGNUM,
+ eflags & ~0x0100);
+
+ request = PT_CONTINUE;
+ }
+
+ /* An addres of (caddr_t) 1 tells ptrace to continue from where it
+ was. (If GDB wanted it to start some other way, we have already
+ written a new PC value to the child.) */
+ if (ptrace (request, pid, (caddr_t) 1,
+ gdb_signal_to_host (signal)) == -1)
+ perror_with_name (("ptrace"));
+}
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ /* The following is true for FreeBSD 4.7:
+
+ The pcb contains %eip, %ebx, %esp, %ebp, %esi, %edi and %gs.
+ This accounts for all callee-saved registers specified by the
+ psABI and then some. Here %esp contains the stack pointer at the
+ point just after the call to cpu_switch(). From this information
+ we reconstruct the register state as it would look when we just
+ returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_esp == 0)
+ return 0;
+
+ pcb->pcb_esp += 4;
+ regcache_raw_supply (regcache, I386_EDI_REGNUM, &pcb->pcb_edi);
+ regcache_raw_supply (regcache, I386_ESI_REGNUM, &pcb->pcb_esi);
+ regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
+ regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
+ regcache_raw_supply (regcache, I386_EBX_REGNUM, &pcb->pcb_ebx);
+ regcache_raw_supply (regcache, I386_EIP_REGNUM, &pcb->pcb_eip);
+ regcache_raw_supply (regcache, I386_GS_REGNUM, &pcb->pcb_gs);
+
+ return 1;
+}
+\f
+
+#ifdef PT_GETXSTATE_INFO
+/* Implement the to_read_description method. */
+
+static const struct target_desc *
+i386fbsd_read_description (struct target_ops *ops)
+{
+ static int xsave_probed;
+ static uint64_t xcr0;
+
+ if (!xsave_probed)
+ {
+ struct ptrace_xstate_info info;
+
+ if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
+ {
+ x86bsd_xsave_len = info.xsave_len;
+ xcr0 = info.xsave_mask;
+ }
+ xsave_probed = 1;
+ }
+
+ if (x86bsd_xsave_len != 0)
+ {
+ return i386_target_description (xcr0);
+ }
+ else
+ return tdesc_i386;
+}
+#endif
+
+/* Prevent warning from -Wmissing-prototypes. */
+void _initialize_i386fbsd_nat (void);
+
+void
+_initialize_i386fbsd_nat (void)
+{
+ struct target_ops *t;
+
+ /* Add some extra features to the common *BSD/i386 target. */
+ t = i386bsd_target ();
+
+#ifdef PT_GETXSTATE_INFO
+ t->to_read_description = i386fbsd_read_description;
+#endif
+
+ t->to_resume = i386fbsd_resume;
+ fbsd_nat_add_target (t);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (i386fbsd_supply_pcb);
+
+#ifdef KERN_PROC_SIGTRAMP
+ /* Normally signal frames are detected via i386fbsd_sigtramp_p.
+ However, FreeBSD 9.2 through 10.1 do not include the page holding
+ the signal code in core dumps. These releases do provide a
+ kern.proc.sigtramp.<pid> sysctl that returns the location of the
+ signal trampoline for a running process. We fetch the location
+ of the current (gdb) process and use this to identify signal
+ frames in core dumps from these releases. */
+ {
+ int mib[4];
+ struct kinfo_sigtramp kst;
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_SIGTRAMP;
+ mib[3] = getpid ();
+ len = sizeof (kst);
+ if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0)
+ {
+ i386fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start;
+ i386fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end;
+ }
+ }
+#endif
+}
--- /dev/null
+/* Target-dependent code for FreeBSD/i386.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "i386-fbsd-tdep.h"
+#include "x86-xstate.h"
+
+#include "i386-tdep.h"
+#include "i387-tdep.h"
+#include "bsd-uthread.h"
+#include "fbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Support for signal handlers. */
+
+/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp
+ routine. */
+
+/* FreeBSD/i386 supports three different signal trampolines, one for
+ versions before 4.0, a second for 4.x, and a third for 5.0 and
+ later. To complicate matters, FreeBSD/i386 binaries running under
+ an amd64 kernel use a different set of trampolines. These
+ trampolines differ from the i386 kernel trampolines in that they
+ omit a middle section that conditionally restores %gs. */
+
+static const gdb_byte i386fbsd_sigtramp_start[] =
+{
+ 0x8d, 0x44, 0x24, 0x20, /* lea SIGF_UC(%esp),%eax */
+ 0x50 /* pushl %eax */
+};
+
+static const gdb_byte i386fbsd_sigtramp_middle[] =
+{
+ 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x00,
+ /* testl $PSL_VM,UC_EFLAGS(%eax) */
+ 0x75, 0x03, /* jne +3 */
+ 0x8e, 0x68, 0x14 /* mov UC_GS(%eax),%gs */
+};
+
+static const gdb_byte i386fbsd_sigtramp_end[] =
+{
+ 0xb8, 0xa1, 0x01, 0x00, 0x00, /* movl $SYS_sigreturn,%eax */
+ 0x50, /* pushl %eax */
+ 0xcd, 0x80 /* int $0x80 */
+};
+
+static const gdb_byte i386fbsd_freebsd4_sigtramp_start[] =
+{
+ 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_UC4(%esp),%eax */
+ 0x50 /* pushl %eax */
+};
+
+static const gdb_byte i386fbsd_freebsd4_sigtramp_middle[] =
+{
+ 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x00,
+ /* testl $PSL_VM,UC4_EFLAGS(%eax) */
+ 0x75, 0x03, /* jne +3 */
+ 0x8e, 0x68, 0x14 /* mov UC4_GS(%eax),%gs */
+};
+
+static const gdb_byte i386fbsd_freebsd4_sigtramp_end[] =
+{
+ 0xb8, 0x58, 0x01, 0x00, 0x00, /* movl $344,%eax */
+ 0x50, /* pushl %eax */
+ 0xcd, 0x80 /* int $0x80 */
+};
+
+static const gdb_byte i386fbsd_osigtramp_start[] =
+{
+ 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_SC(%esp),%eax */
+ 0x50 /* pushl %eax */
+};
+
+static const gdb_byte i386fbsd_osigtramp_middle[] =
+{
+ 0xf7, 0x40, 0x18, 0x00, 0x00, 0x02, 0x00,
+ /* testl $PSL_VM,SC_PS(%eax) */
+ 0x75, 0x03, /* jne +3 */
+ 0x8e, 0x68, 0x44 /* mov SC_GS(%eax),%gs */
+};
+
+static const gdb_byte i386fbsd_osigtramp_end[] =
+{
+ 0xb8, 0x67, 0x00, 0x00, 0x00, /* movl $103,%eax */
+ 0x50, /* pushl %eax */
+ 0xcd, 0x80 /* int $0x80 */
+};
+
+/* The three different trampolines are all the same size. */
+gdb_static_assert (sizeof i386fbsd_sigtramp_start
+ == sizeof i386fbsd_freebsd4_sigtramp_start);
+gdb_static_assert (sizeof i386fbsd_sigtramp_start
+ == sizeof i386fbsd_osigtramp_start);
+gdb_static_assert (sizeof i386fbsd_sigtramp_middle
+ == sizeof i386fbsd_freebsd4_sigtramp_middle);
+gdb_static_assert (sizeof i386fbsd_sigtramp_middle
+ == sizeof i386fbsd_osigtramp_middle);
+gdb_static_assert (sizeof i386fbsd_sigtramp_end
+ == sizeof i386fbsd_freebsd4_sigtramp_end);
+gdb_static_assert (sizeof i386fbsd_sigtramp_end
+ == sizeof i386fbsd_osigtramp_end);
+
+/* We assume that the middle is the largest chunk below. */
+gdb_static_assert (sizeof i386fbsd_sigtramp_middle
+ > sizeof i386fbsd_sigtramp_start);
+gdb_static_assert (sizeof i386fbsd_sigtramp_middle
+ > sizeof i386fbsd_sigtramp_end);
+
+static int
+i386fbsd_sigtramp_p (struct frame_info *this_frame)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ gdb_byte buf[sizeof i386fbsd_sigtramp_middle];
+ const gdb_byte *middle, *end;
+
+ /* Look for a matching start. */
+ if (!safe_frame_unwind_memory (this_frame, pc, buf,
+ sizeof i386fbsd_sigtramp_start))
+ return 0;
+ if (memcmp (buf, i386fbsd_sigtramp_start, sizeof i386fbsd_sigtramp_start)
+ == 0)
+ {
+ middle = i386fbsd_sigtramp_middle;
+ end = i386fbsd_sigtramp_end;
+ }
+ else if (memcmp (buf, i386fbsd_freebsd4_sigtramp_start,
+ sizeof i386fbsd_freebsd4_sigtramp_start) == 0)
+ {
+ middle = i386fbsd_freebsd4_sigtramp_middle;
+ end = i386fbsd_freebsd4_sigtramp_end;
+ }
+ else if (memcmp (buf, i386fbsd_osigtramp_start,
+ sizeof i386fbsd_osigtramp_start) == 0)
+ {
+ middle = i386fbsd_osigtramp_middle;
+ end = i386fbsd_osigtramp_end;
+ }
+ else
+ return 0;
+
+ /* Since the end is shorter than the middle, check for a matching end
+ next. */
+ pc += sizeof i386fbsd_sigtramp_start;
+ if (!safe_frame_unwind_memory (this_frame, pc, buf,
+ sizeof i386fbsd_sigtramp_end))
+ return 0;
+ if (memcmp (buf, end, sizeof i386fbsd_sigtramp_end) == 0)
+ return 1;
+
+ /* If the end didn't match, check for a matching middle. */
+ if (!safe_frame_unwind_memory (this_frame, pc, buf,
+ sizeof i386fbsd_sigtramp_middle))
+ return 0;
+ if (memcmp (buf, middle, sizeof i386fbsd_sigtramp_middle) != 0)
+ return 0;
+
+ /* The middle matched, check for a matching end. */
+ pc += sizeof i386fbsd_sigtramp_middle;
+ if (!safe_frame_unwind_memory (this_frame, pc, buf,
+ sizeof i386fbsd_sigtramp_end))
+ return 0;
+ if (memcmp (buf, end, sizeof i386fbsd_sigtramp_end) != 0)
+ return 0;
+
+ return 1;
+}
+
+/* FreeBSD 3.0-RELEASE or later. */
+
+/* From <machine/reg.h>. */
+static int i386fbsd_r_reg_offset[] =
+{
+ 9 * 4, 8 * 4, 7 * 4, 6 * 4, /* %eax, %ecx, %edx, %ebx */
+ 15 * 4, 4 * 4, /* %esp, %ebp */
+ 3 * 4, 2 * 4, /* %esi, %edi */
+ 12 * 4, 14 * 4, /* %eip, %eflags */
+ 13 * 4, 16 * 4, /* %cs, %ss */
+ 1 * 4, 0 * 4, -1, -1 /* %ds, %es, %fs, %gs */
+};
+
+/* Sigtramp routine location. */
+CORE_ADDR i386fbsd_sigtramp_start_addr;
+CORE_ADDR i386fbsd_sigtramp_end_addr;
+
+/* From <machine/signal.h>. */
+int i386fbsd_sc_reg_offset[] =
+{
+ 8 + 14 * 4, /* %eax */
+ 8 + 13 * 4, /* %ecx */
+ 8 + 12 * 4, /* %edx */
+ 8 + 11 * 4, /* %ebx */
+ 8 + 0 * 4, /* %esp */
+ 8 + 1 * 4, /* %ebp */
+ 8 + 10 * 4, /* %esi */
+ 8 + 9 * 4, /* %edi */
+ 8 + 3 * 4, /* %eip */
+ 8 + 4 * 4, /* %eflags */
+ 8 + 7 * 4, /* %cs */
+ 8 + 8 * 4, /* %ss */
+ 8 + 6 * 4, /* %ds */
+ 8 + 5 * 4, /* %es */
+ 8 + 15 * 4, /* %fs */
+ 8 + 16 * 4 /* %gs */
+};
+
+/* From /usr/src/lib/libc/i386/gen/_setjmp.S. */
+static int i386fbsd_jmp_buf_reg_offset[] =
+{
+ -1, /* %eax */
+ -1, /* %ecx */
+ -1, /* %edx */
+ 1 * 4, /* %ebx */
+ 2 * 4, /* %esp */
+ 3 * 4, /* %ebp */
+ 4 * 4, /* %esi */
+ 5 * 4, /* %edi */
+ 0 * 4 /* %eip */
+};
+
+/* Get XSAVE extended state xcr0 from core dump. */
+
+uint64_t
+i386fbsd_core_read_xcr0 (bfd *abfd)
+{
+ asection *xstate = bfd_get_section_by_name (abfd, ".reg-xstate");
+ uint64_t xcr0;
+
+ if (xstate)
+ {
+ size_t size = bfd_section_size (abfd, xstate);
+
+ /* Check extended state size. */
+ if (size < X86_XSTATE_AVX_SIZE)
+ xcr0 = X86_XSTATE_SSE_MASK;
+ else
+ {
+ char contents[8];
+
+ if (! bfd_get_section_contents (abfd, xstate, contents,
+ I386_FBSD_XSAVE_XCR0_OFFSET,
+ 8))
+ {
+ warning (_("Couldn't read `xcr0' bytes from "
+ "`.reg-xstate' section in core file."));
+ return 0;
+ }
+
+ xcr0 = bfd_get_64 (abfd, contents);
+ }
+ }
+ else
+ xcr0 = 0;
+
+ return xcr0;
+}
+
+/* Implement the core_read_description gdbarch method. */
+
+static const struct target_desc *
+i386fbsd_core_read_description (struct gdbarch *gdbarch,
+ struct target_ops *target,
+ bfd *abfd)
+{
+ return i386_target_description (i386fbsd_core_read_xcr0 (abfd));
+}
+
+/* Similar to i386_supply_fpregset, but use XSAVE extended state. */
+
+static void
+i386fbsd_supply_xstateregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *xstateregs, size_t len)
+{
+ i387_supply_xsave (regcache, regnum, xstateregs);
+}
+
+/* Similar to i386_collect_fpregset, but use XSAVE extended state. */
+
+static void
+i386fbsd_collect_xstateregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *xstateregs, size_t len)
+{
+ i387_collect_xsave (regcache, regnum, xstateregs, 1);
+}
+
+/* Register set definitions. */
+
+static const struct regset i386fbsd_xstateregset =
+ {
+ NULL,
+ i386fbsd_supply_xstateregset,
+ i386fbsd_collect_xstateregset
+ };
+
+/* Iterate over core file register note sections. */
+
+static void
+i386fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ cb (".reg", tdep->sizeof_gregset, &i386_gregset, NULL, cb_data);
+ cb (".reg2", tdep->sizeof_fpregset, &i386_fpregset, NULL, cb_data);
+
+ if (tdep->xcr0 & X86_XSTATE_AVX)
+ cb (".reg-xstate", X86_XSTATE_SIZE(tdep->xcr0),
+ &i386fbsd_xstateregset, "XSAVE extended state", cb_data);
+}
+
+static void
+i386fbsd_supply_uthread (struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ gdb_byte buf[4];
+ int i;
+
+ gdb_assert (regnum >= -1);
+
+ for (i = 0; i < ARRAY_SIZE (i386fbsd_jmp_buf_reg_offset); i++)
+ {
+ if (i386fbsd_jmp_buf_reg_offset[i] != -1
+ && (regnum == -1 || regnum == i))
+ {
+ read_memory (addr + i386fbsd_jmp_buf_reg_offset[i], buf, 4);
+ regcache_raw_supply (regcache, i, buf);
+ }
+ }
+}
+
+static void
+i386fbsd_collect_uthread (const struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ gdb_byte buf[4];
+ int i;
+
+ gdb_assert (regnum >= -1);
+
+ for (i = 0; i < ARRAY_SIZE (i386fbsd_jmp_buf_reg_offset); i++)
+ {
+ if (i386fbsd_jmp_buf_reg_offset[i] != -1
+ && (regnum == -1 || regnum == i))
+ {
+ regcache_raw_collect (regcache, i, buf);
+ write_memory (addr + i386fbsd_jmp_buf_reg_offset[i], buf, 4);
+ }
+ }
+}
+
+static void
+i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Obviously FreeBSD is BSD-based. */
+ i386bsd_init_abi (info, gdbarch);
+
+ /* FreeBSD has a different `struct reg', and reserves some space for
+ its FPU emulator in `struct fpreg'. */
+ tdep->gregset_reg_offset = i386fbsd_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd_r_reg_offset);
+ tdep->sizeof_gregset = 18 * 4;
+ tdep->sizeof_fpregset = 176;
+
+ /* FreeBSD uses -freg-struct-return by default. */
+ tdep->struct_return = reg_struct_return;
+
+ tdep->sigtramp_p = i386fbsd_sigtramp_p;
+
+ /* FreeBSD uses a different memory layout. */
+ tdep->sigtramp_start = i386fbsd_sigtramp_start_addr;
+ tdep->sigtramp_end = i386fbsd_sigtramp_end_addr;
+
+ /* FreeBSD has a more complete `struct sigcontext'. */
+ tdep->sc_reg_offset = i386fbsd_sc_reg_offset;
+ tdep->sc_num_regs = ARRAY_SIZE (i386fbsd_sc_reg_offset);
+
+ /* FreeBSD provides a user-level threads implementation. */
+ bsd_uthread_set_supply_uthread (gdbarch, i386fbsd_supply_uthread);
+ bsd_uthread_set_collect_uthread (gdbarch, i386fbsd_collect_uthread);
+}
+
+static void
+i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* It's almost identical to FreeBSD a.out. */
+ i386fbsdaout_init_abi (info, gdbarch);
+
+ /* Except that it uses ELF. */
+ i386_elf_init_abi (info, gdbarch);
+
+ /* FreeBSD ELF uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+
+/* FreeBSD 4.0-RELEASE or later. */
+
+/* From <machine/reg.h>. */
+static int i386fbsd4_r_reg_offset[] =
+{
+ 10 * 4, 9 * 4, 8 * 4, 7 * 4, /* %eax, %ecx, %edx, %ebx */
+ 16 * 4, 5 * 4, /* %esp, %ebp */
+ 4 * 4, 3 * 4, /* %esi, %edi */
+ 13 * 4, 15 * 4, /* %eip, %eflags */
+ 14 * 4, 17 * 4, /* %cs, %ss */
+ 2 * 4, 1 * 4, 0 * 4, 18 * 4 /* %ds, %es, %fs, %gs */
+};
+
+/* From <machine/signal.h>. */
+int i386fbsd4_sc_reg_offset[] =
+{
+ 20 + 11 * 4, /* %eax */
+ 20 + 10 * 4, /* %ecx */
+ 20 + 9 * 4, /* %edx */
+ 20 + 8 * 4, /* %ebx */
+ 20 + 17 * 4, /* %esp */
+ 20 + 6 * 4, /* %ebp */
+ 20 + 5 * 4, /* %esi */
+ 20 + 4 * 4, /* %edi */
+ 20 + 14 * 4, /* %eip */
+ 20 + 16 * 4, /* %eflags */
+ 20 + 15 * 4, /* %cs */
+ 20 + 18 * 4, /* %ss */
+ 20 + 3 * 4, /* %ds */
+ 20 + 2 * 4, /* %es */
+ 20 + 1 * 4, /* %fs */
+ 20 + 0 * 4 /* %gs */
+};
+
+static void
+i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Generic FreeBSD support. */
+ fbsd_init_abi (info, gdbarch);
+
+ /* Inherit stuff from older releases. We assume that FreeBSD
+ 4.0-RELEASE always uses ELF. */
+ i386fbsd_init_abi (info, gdbarch);
+
+ /* FreeBSD 4.0 introduced a new `struct reg'. */
+ tdep->gregset_reg_offset = i386fbsd4_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd4_r_reg_offset);
+ tdep->sizeof_gregset = 19 * 4;
+
+ /* FreeBSD 4.0 introduced a new `struct sigcontext'. */
+ tdep->sc_reg_offset = i386fbsd4_sc_reg_offset;
+ tdep->sc_num_regs = ARRAY_SIZE (i386fbsd4_sc_reg_offset);
+
+ tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET;
+
+ /* Iterate over core file register note sections. */
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, i386fbsd_iterate_over_regset_sections);
+
+ set_gdbarch_core_read_description (gdbarch,
+ i386fbsd_core_read_description);
+}
+
+\f
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_i386fbsd_tdep (void);
+
+void
+_initialize_i386fbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_AOUT,
+ i386fbsdaout_init_abi);
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_ELF,
+ i386fbsd4_init_abi);
+}
--- /dev/null
+/* Target-dependent code for FreeBSD x86.
+
+ Copyright (C) 2015-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef I386_FBSD_TDEP_H
+#define I386_FBSD_TDEP_H
+
+/* Get XSAVE extended state xcr0 from core dump. */
+extern uint64_t i386fbsd_core_read_xcr0 (bfd *abfd);
+
+/* The format of the XSAVE extended area is determined by hardware.
+ Cores store the XSAVE extended area in a NT_X86_XSTATE note that
+ matches the layout on Linux. */
+#define I386_FBSD_XSAVE_XCR0_OFFSET 464
+
+#endif /* i386-fbsd-tdep.h */
--- /dev/null
+/* Low level interface to i386 running the GNU Hurd.
+
+ Copyright (C) 1992-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "x86-nat.h"
+#include "inferior.h"
+#include "floatformat.h"
+#include "regcache.h"
+
+#include <mach.h>
+#include <mach_error.h>
+#include <mach/message.h>
+#include <mach/exception.h>
+
+#include "i386-tdep.h"
+
+#include "gnu-nat.h"
+#include "inf-child.h"
+#include "i387-tdep.h"
+
+/* Offset to the thread_state_t location where REG is stored. */
+#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
+
+/* At REG_OFFSET[N] is the offset to the thread_state_t location where
+ the GDB register N is stored. */
+static int reg_offset[] =
+{
+ REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
+ REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
+ REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
+ REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
+};
+
+#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
+
+\f
+/* Get the whole floating-point state of THREAD and record the values
+ of the corresponding (pseudo) registers. */
+
+static void
+fetch_fpregs (struct regcache *regcache, struct proc *thread)
+{
+ mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
+ struct i386_float_state state;
+ error_t err;
+
+ err = thread_get_state (thread->port, i386_FLOAT_STATE,
+ (thread_state_t) &state, &count);
+ if (err)
+ {
+ warning (_("Couldn't fetch floating-point state from %s"),
+ proc_string (thread));
+ return;
+ }
+
+ if (!state.initialized)
+ {
+ /* The floating-point state isn't initialized. */
+ i387_supply_fsave (regcache, -1, NULL);
+ }
+ else
+ {
+ /* Supply the floating-point registers. */
+ i387_supply_fsave (regcache, -1, state.hw_state);
+ }
+}
+
+/* Fetch register REGNO, or all regs if REGNO is -1. */
+static void
+gnu_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ struct proc *thread;
+
+ /* Make sure we know about new threads. */
+ inf_update_procs (gnu_current_inf);
+
+ thread = inf_tid_to_thread (gnu_current_inf,
+ ptid_get_lwp (inferior_ptid));
+ if (!thread)
+ error (_("Can't fetch registers from thread %s: No such thread"),
+ target_pid_to_str (inferior_ptid));
+
+ if (regno < I386_NUM_GREGS || regno == -1)
+ {
+ thread_state_t state;
+
+ /* This does the dirty work for us. */
+ state = proc_get_state (thread, 0);
+ if (!state)
+ {
+ warning (_("Couldn't fetch registers from %s"),
+ proc_string (thread));
+ return;
+ }
+
+ if (regno == -1)
+ {
+ int i;
+
+ proc_debug (thread, "fetching all register");
+
+ for (i = 0; i < I386_NUM_GREGS; i++)
+ regcache_raw_supply (regcache, i, REG_ADDR (state, i));
+ thread->fetched_regs = ~0;
+ }
+ else
+ {
+ proc_debug (thread, "fetching register %s",
+ gdbarch_register_name (get_regcache_arch (regcache),
+ regno));
+
+ regcache_raw_supply (regcache, regno,
+ REG_ADDR (state, regno));
+ thread->fetched_regs |= (1 << regno);
+ }
+ }
+
+ if (regno >= I386_NUM_GREGS || regno == -1)
+ {
+ proc_debug (thread, "fetching floating-point registers");
+
+ fetch_fpregs (regcache, thread);
+ }
+}
+\f
+
+/* Store the whole floating-point state into THREAD using information
+ from the corresponding (pseudo) registers. */
+static void
+store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
+{
+ mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
+ struct i386_float_state state;
+ error_t err;
+
+ err = thread_get_state (thread->port, i386_FLOAT_STATE,
+ (thread_state_t) &state, &count);
+ if (err)
+ {
+ warning (_("Couldn't fetch floating-point state from %s"),
+ proc_string (thread));
+ return;
+ }
+
+ /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
+ take into account DEPRECATED_REGISTER_VALID like the old code did? */
+ i387_collect_fsave (regcache, regno, state.hw_state);
+
+ err = thread_set_state (thread->port, i386_FLOAT_STATE,
+ (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
+ if (err)
+ {
+ warning (_("Couldn't store floating-point state into %s"),
+ proc_string (thread));
+ return;
+ }
+}
+
+/* Store at least register REGNO, or all regs if REGNO == -1. */
+static void
+gnu_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ struct proc *thread;
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ /* Make sure we know about new threads. */
+ inf_update_procs (gnu_current_inf);
+
+ thread = inf_tid_to_thread (gnu_current_inf,
+ ptid_get_lwp (inferior_ptid));
+ if (!thread)
+ error (_("Couldn't store registers into thread %s: No such thread"),
+ target_pid_to_str (inferior_ptid));
+
+ if (regno < I386_NUM_GREGS || regno == -1)
+ {
+ thread_state_t state;
+ thread_state_data_t old_state;
+ int was_aborted = thread->aborted;
+ int was_valid = thread->state_valid;
+ int trace;
+
+ if (!was_aborted && was_valid)
+ memcpy (&old_state, &thread->state, sizeof (old_state));
+
+ state = proc_get_state (thread, 1);
+ if (!state)
+ {
+ warning (_("Couldn't store registers into %s"),
+ proc_string (thread));
+ return;
+ }
+
+ /* Save the T bit. We might try to restore the %eflags register
+ below, but changing the T bit would seriously confuse GDB. */
+ trace = ((struct i386_thread_state *)state)->efl & 0x100;
+
+ if (!was_aborted && was_valid)
+ /* See which registers have changed after aborting the thread. */
+ {
+ int check_regno;
+
+ for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
+ if ((thread->fetched_regs & (1 << check_regno))
+ && memcpy (REG_ADDR (&old_state, check_regno),
+ REG_ADDR (state, check_regno),
+ register_size (gdbarch, check_regno)))
+ /* Register CHECK_REGNO has changed! Ack! */
+ {
+ warning (_("Register %s changed after the thread was aborted"),
+ gdbarch_register_name (gdbarch, check_regno));
+ if (regno >= 0 && regno != check_regno)
+ /* Update GDB's copy of the register. */
+ regcache_raw_supply (regcache, check_regno,
+ REG_ADDR (state, check_regno));
+ else
+ warning (_("... also writing this register! "
+ "Suspicious..."));
+ }
+ }
+
+ if (regno == -1)
+ {
+ int i;
+
+ proc_debug (thread, "storing all registers");
+
+ for (i = 0; i < I386_NUM_GREGS; i++)
+ if (REG_VALID == regcache_register_status (regcache, i))
+ regcache_raw_collect (regcache, i, REG_ADDR (state, i));
+ }
+ else
+ {
+ proc_debug (thread, "storing register %s",
+ gdbarch_register_name (gdbarch, regno));
+
+ gdb_assert (REG_VALID == regcache_register_status (regcache, regno));
+ regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
+ }
+
+ /* Restore the T bit. */
+ ((struct i386_thread_state *)state)->efl &= ~0x100;
+ ((struct i386_thread_state *)state)->efl |= trace;
+ }
+
+ if (regno >= I386_NUM_GREGS || regno == -1)
+ {
+ proc_debug (thread, "storing floating-point registers");
+
+ store_fpregs (regcache, thread, regno);
+ }
+}
+
+\f
+/* Support for debug registers. */
+
+#ifdef i386_DEBUG_STATE
+/* Get debug registers for thread THREAD. */
+
+static void
+i386_gnu_dr_get (struct i386_debug_state *regs, struct proc *thread)
+{
+ mach_msg_type_number_t count = i386_DEBUG_STATE_COUNT;
+ error_t err;
+
+ err = thread_get_state (thread->port, i386_DEBUG_STATE,
+ (thread_state_t) regs, &count);
+ if (err != 0 || count != i386_DEBUG_STATE_COUNT)
+ warning (_("Couldn't fetch debug state from %s"),
+ proc_string (thread));
+}
+
+/* Set debug registers for thread THREAD. */
+
+static void
+i386_gnu_dr_set (const struct i386_debug_state *regs, struct proc *thread)
+{
+ error_t err;
+
+ err = thread_set_state (thread->port, i386_DEBUG_STATE,
+ (thread_state_t) regs, i386_DEBUG_STATE_COUNT);
+ if (err != 0)
+ warning (_("Couldn't store debug state into %s"),
+ proc_string (thread));
+}
+
+/* Set DR_CONTROL in THREAD. */
+
+static void
+i386_gnu_dr_set_control_one (struct proc *thread, void *arg)
+{
+ unsigned long *control = arg;
+ struct i386_debug_state regs;
+
+ i386_gnu_dr_get (®s, thread);
+ regs.dr[DR_CONTROL] = *control;
+ i386_gnu_dr_set (®s, thread);
+}
+
+/* Set DR_CONTROL to CONTROL in all threads. */
+
+static void
+i386_gnu_dr_set_control (unsigned long control)
+{
+ inf_update_procs (gnu_current_inf);
+ inf_threads (gnu_current_inf, i386_gnu_dr_set_control_one, &control);
+}
+
+/* Parameters to set a debugging address. */
+
+struct reg_addr
+{
+ int regnum; /* Register number (zero based). */
+ CORE_ADDR addr; /* Address. */
+};
+
+/* Set address REGNUM (zero based) to ADDR in THREAD. */
+
+static void
+i386_gnu_dr_set_addr_one (struct proc *thread, void *arg)
+{
+ struct reg_addr *reg_addr = arg;
+ struct i386_debug_state regs;
+
+ i386_gnu_dr_get (®s, thread);
+ regs.dr[reg_addr->regnum] = reg_addr->addr;
+ i386_gnu_dr_set (®s, thread);
+}
+
+/* Set address REGNUM (zero based) to ADDR in all threads. */
+
+static void
+i386_gnu_dr_set_addr (int regnum, CORE_ADDR addr)
+{
+ struct reg_addr reg_addr;
+
+ gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
+
+ reg_addr.regnum = regnum;
+ reg_addr.addr = addr;
+
+ inf_update_procs (gnu_current_inf);
+ inf_threads (gnu_current_inf, i386_gnu_dr_set_addr_one, ®_addr);
+}
+
+/* Get debug register REGNUM value from only the one LWP of PTID. */
+
+static unsigned long
+i386_gnu_dr_get_reg (ptid_t ptid, int regnum)
+{
+ struct i386_debug_state regs;
+ struct proc *thread;
+
+ /* Make sure we know about new threads. */
+ inf_update_procs (gnu_current_inf);
+
+ thread = inf_tid_to_thread (gnu_current_inf, ptid_get_lwp (ptid));
+ i386_gnu_dr_get (®s, thread);
+
+ return regs.dr[regnum];
+}
+
+/* Return the inferior's debug register REGNUM. */
+
+static CORE_ADDR
+i386_gnu_dr_get_addr (int regnum)
+{
+ gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
+
+ return i386_gnu_dr_get_reg (inferior_ptid, regnum);
+}
+
+/* Get DR_STATUS from only the one thread of INFERIOR_PTID. */
+
+static unsigned long
+i386_gnu_dr_get_status (void)
+{
+ return i386_gnu_dr_get_reg (inferior_ptid, DR_STATUS);
+}
+
+/* Return the inferior's DR7 debug control register. */
+
+static unsigned long
+i386_gnu_dr_get_control (void)
+{
+ return i386_gnu_dr_get_reg (inferior_ptid, DR_CONTROL);
+}
+#endif /* i386_DEBUG_STATE */
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_i386gnu_nat;
+
+void
+_initialize_i386gnu_nat (void)
+{
+ struct target_ops *t;
+
+ /* Fill in the generic GNU/Hurd methods. */
+ t = gnu_target ();
+
+#ifdef i386_DEBUG_STATE
+ x86_use_watchpoints (t);
+
+ x86_dr_low.set_control = i386_gnu_dr_set_control;
+ gdb_assert (DR_FIRSTADDR == 0 && DR_LASTADDR < i386_DEBUG_STATE_COUNT);
+ x86_dr_low.set_addr = i386_gnu_dr_set_addr;
+ x86_dr_low.get_addr = i386_gnu_dr_get_addr;
+ x86_dr_low.get_status = i386_gnu_dr_get_status;
+ x86_dr_low.get_control = i386_gnu_dr_get_control;
+ x86_set_debug_register_length (4);
+#endif /* i386_DEBUG_STATE */
+
+ t->to_fetch_registers = gnu_fetch_registers;
+ t->to_store_registers = gnu_store_registers;
+
+ /* Register the target. */
+ add_target (t);
+}
--- /dev/null
+/* Target-dependent code for the GNU Hurd.
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "osabi.h"
+#include "solib-svr4.h"
+
+#include "i386-tdep.h"
+
+/* From <sys/ucontext.h>. */
+static int i386gnu_gregset_reg_offset[] =
+{
+ 11 * 4, /* %eax */
+ 10 * 4, /* %ecx */
+ 9 * 4, /* %edx */
+ 8 * 4, /* %ebx */
+ 17 * 4, /* %uesp */
+ 6 * 4, /* %ebp */
+ 5 * 4, /* %esi */
+ 4 * 4, /* %edi */
+ 14 * 4, /* %eip */
+ 16 * 4, /* %efl */
+ 15 * 4, /* %cs */
+ 18 * 4, /* %ss */
+ 3 * 4, /* %ds */
+ 2 * 4, /* %es */
+ 1 * 4, /* %fs */
+ 0 * 4, /* %gs */
+};
+
+static void
+i386gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* GNU uses ELF. */
+ i386_elf_init_abi (info, gdbarch);
+
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ tdep->gregset_reg_offset = i386gnu_gregset_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (i386gnu_gregset_reg_offset);
+ tdep->sizeof_gregset = 19 * 4;
+
+ tdep->jb_pc_offset = 20; /* From <bits/setjmp.h>. */
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern void _initialize_i386gnu_tdep (void);
+
+void
+_initialize_i386gnu_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_HURD, i386gnu_init_abi);
+}
--- /dev/null
+/* Native-dependent code for NetBSD/i386.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "i386-tdep.h"
+#include "i386-bsd-nat.h"
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "nbsd-nat.h"
+#include "bsd-kvm.h"
+
+static int
+i386nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ struct switchframe sf;
+
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %esp and %ebp at the point of the context switch
+ in cpu_switch(). At that point we have a stack frame as
+ described by `struct switchframe', which for NetBSD 1.6.2 has the
+ following layout:
+
+ interrupt level
+ %edi
+ %esi
+ %ebx
+ %eip
+
+ we reconstruct the register state as it would look when we just
+ returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_esp == 0)
+ return 0;
+
+ read_memory (pcb->pcb_esp, (gdb_byte *)&sf, sizeof sf);
+ pcb->pcb_esp += sizeof (struct switchframe);
+ regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi);
+ regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi);
+ regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
+ regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
+ regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx);
+ regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_i386nbsd_nat (void);
+
+void
+_initialize_i386nbsd_nat (void)
+{
+ struct target_ops *t;
+
+ /* Add some extra features to the common *BSD/i386 target. */
+ t = i386bsd_target ();
+ t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
+ add_target (t);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (i386nbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/i386.
+
+ Copyright (C) 1988-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "regset.h"
+#include "osabi.h"
+#include "symtab.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+
+#include "i386-tdep.h"
+#include "i387-tdep.h"
+#include "nbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* From <machine/reg.h>. */
+static int i386nbsd_r_reg_offset[] =
+{
+ 0 * 4, /* %eax */
+ 1 * 4, /* %ecx */
+ 2 * 4, /* %edx */
+ 3 * 4, /* %ebx */
+ 4 * 4, /* %esp */
+ 5 * 4, /* %ebp */
+ 6 * 4, /* %esi */
+ 7 * 4, /* %edi */
+ 8 * 4, /* %eip */
+ 9 * 4, /* %eflags */
+ 10 * 4, /* %cs */
+ 11 * 4, /* %ss */
+ 12 * 4, /* %ds */
+ 13 * 4, /* %es */
+ 14 * 4, /* %fs */
+ 15 * 4 /* %gs */
+};
+
+/* From <machine/signal.h>. */
+int i386nbsd_sc_reg_offset[] =
+{
+ 10 * 4, /* %eax */
+ 9 * 4, /* %ecx */
+ 8 * 4, /* %edx */
+ 7 * 4, /* %ebx */
+ 14 * 4, /* %esp */
+ 6 * 4, /* %ebp */
+ 5 * 4, /* %esi */
+ 4 * 4, /* %edi */
+ 11 * 4, /* %eip */
+ 13 * 4, /* %eflags */
+ 12 * 4, /* %cs */
+ 15 * 4, /* %ss */
+ 3 * 4, /* %ds */
+ 2 * 4, /* %es */
+ 1 * 4, /* %fs */
+ 0 * 4 /* %gs */
+};
+
+/* From <machine/mcontext.h>. */
+int i386nbsd_mc_reg_offset[] =
+{
+ 11 * 4, /* %eax */
+ 10 * 4, /* %ecx */
+ 9 * 4, /* %edx */
+ 8 * 4, /* %ebx */
+ 7 * 4, /* %esp */
+ 6 * 4, /* %ebp */
+ 5 * 4, /* %esi */
+ 4 * 4, /* %edi */
+ 14 * 4, /* %eip */
+ 16 * 4, /* %eflags */
+ 15 * 4, /* %cs */
+ 18 * 4, /* %ss */
+ 3 * 4, /* %ds */
+ 2 * 4, /* %es */
+ 1 * 4, /* %fs */
+ 0 * 4 /* %gs */
+};
+
+static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *,
+ struct frame_info *,
+ struct trad_frame_cache *,
+ CORE_ADDR);
+
+static const struct tramp_frame i386nbsd_sigtramp_sc16 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x10, -1 },
+ /* leal 0x10(%esp), %eax */
+ { 0x50, -1 }, /* pushl %eax */
+ { 0x50, -1 }, /* pushl %eax */
+ { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x127, %eax # __sigreturn14 */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x1, %eax # exit */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_sc2 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x0c, -1 },
+ /* leal 0x0c(%esp), %eax */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x127, %eax # __sigreturn14 */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x1, %eax */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si2 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8b, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x08, -1 },
+ /* movl 8(%esp),%eax */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* movl $0x134, %eax # setcontext */
+ { 0xcd, -1 }, { 0x80, -1 },
+ /* int $0x80 */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* movl $0x1, %eax */
+ { 0xcd, -1 }, { 0x80, -1 },
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si31 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
+ { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* leal 0x8c(%esp), %eax */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* movl $0x134, %eax # setcontext */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x1, %eax */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si4 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
+ { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* leal 0x8c(%esp), %eax */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* movl $0x134, %eax # setcontext */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { 0xc7, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 },
+ /* movl $0xffffffff,0x4(%esp) */
+ { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x1, %eax */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static void
+i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
+ CORE_ADDR base;
+ int *reg_offset;
+ int num_regs;
+ int i;
+
+ if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2)
+ {
+ reg_offset = i386nbsd_sc_reg_offset;
+ num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
+
+ /* Read in the sigcontext address. */
+ base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
+ }
+ else
+ {
+ reg_offset = i386nbsd_mc_reg_offset;
+ num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset);
+
+ /* Read in the ucontext address. */
+ base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
+ /* offsetof(ucontext_t, uc_mcontext) == 36 */
+ base += 36;
+ }
+
+ for (i = 0; i < num_regs; i++)
+ if (reg_offset[i] != -1)
+ trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+\f
+
+static void
+i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Obviously NetBSD is BSD-based. */
+ i386bsd_init_abi (info, gdbarch);
+
+ /* NetBSD has a different `struct reg'. */
+ tdep->gregset_reg_offset = i386nbsd_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (i386nbsd_r_reg_offset);
+ tdep->sizeof_gregset = 16 * 4;
+
+ /* NetBSD uses -freg-struct-return by default. */
+ tdep->struct_return = reg_struct_return;
+
+ /* NetBSD uses tramp_frame sniffers for signal trampolines. */
+ tdep->sigcontext_addr= 0;
+ tdep->sigtramp_start = 0;
+ tdep->sigtramp_end = 0;
+ tdep->sigtramp_p = 0;
+ tdep->sc_reg_offset = 0;
+ tdep->sc_num_regs = 0;
+
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc16);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc2);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si2);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si31);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si4);
+}
+
+/* NetBSD ELF. */
+
+static void
+i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* It's still NetBSD. */
+ i386nbsd_init_abi (info, gdbarch);
+
+ /* But ELF-based. */
+ i386_elf_init_abi (info, gdbarch);
+
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ /* NetBSD ELF uses -fpcc-struct-return by default. */
+ tdep->struct_return = pcc_struct_return;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_i386nbsd_tdep;
+
+void
+_initialize_i386nbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD_ELF,
+ i386nbsdelf_init_abi);
+}
--- /dev/null
+/* Native-dependent code for OpenBSD/i386.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <sys/sysctl.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "i386-tdep.h"
+#include "i386-bsd-nat.h"
+#include "obsd-nat.h"
+#include "bsd-kvm.h"
+
+static int
+i386obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ struct switchframe sf;
+
+ /* The following is true for OpenBSD 3.6:
+
+ The pcb contains %esp and %ebp at the point of the context switch
+ in cpu_switch(). At that point we have a stack frame as
+ described by `struct switchframe', which for OpenBSD 3.6 has the
+ following layout:
+
+ interrupt level
+ %edi
+ %esi
+ %ebx
+ %eip
+
+ we reconstruct the register state as it would look when we just
+ returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_esp == 0)
+ return 0;
+
+ /* Read the stack frame, and check its validity. We do this by
+ checking if the saved interrupt priority level in the stack frame
+ looks reasonable.. */
+#ifdef PCB_SAVECTX
+ if ((pcb->pcb_flags & PCB_SAVECTX) == 0)
+ {
+ /* Yes, we have a frame that matches cpu_switch(). */
+ read_memory (pcb->pcb_esp, (gdb_byte *) &sf, sizeof sf);
+ pcb->pcb_esp += sizeof (struct switchframe);
+ regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi);
+ regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi);
+ regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx);
+ regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip);
+ }
+ else
+#endif
+ {
+ /* No, the pcb must have been last updated by savectx(). */
+ pcb->pcb_esp = pcb->pcb_ebp;
+ pcb->pcb_ebp = read_memory_integer(pcb->pcb_esp, 4, byte_order);
+ sf.sf_eip = read_memory_integer(pcb->pcb_esp + 4, 4, byte_order);
+ regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip);
+ }
+
+ regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
+ regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
+
+ return 1;
+}
+\f
+
+/* Prevent warning from -Wmissing-prototypes. */
+void _initialize_i386obsd_nat (void);
+
+void
+_initialize_i386obsd_nat (void)
+{
+ /* Add some extra features to the common *BSD/i386 target. */
+ obsd_add_target (i386bsd_target ());
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (i386obsd_supply_pcb);
+
+ /* OpenBSD provides a vm.psstrings sysctl that we can use to locate
+ the sigtramp. That way we can still recognize a sigtramp if its
+ location is changed in a new kernel. This is especially
+ important for OpenBSD, since it uses a different memory layout
+ than NetBSD, yet we cannot distinguish between the two.
+
+ Of course this is still based on the assumption that the sigtramp
+ is placed directly under the location where the program arguments
+ and environment can be found. */
+#ifdef VM_PSSTRINGS
+ {
+ struct _ps_strings _ps;
+ int mib[2];
+ size_t len;
+
+ mib[0] = CTL_VM;
+ mib[1] = VM_PSSTRINGS;
+ len = sizeof (_ps);
+ if (sysctl (mib, 2, &_ps, &len, NULL, 0) == 0)
+ {
+ i386obsd_sigtramp_start_addr = (u_long) _ps.val - 128;
+ i386obsd_sigtramp_end_addr = (u_long) _ps.val;
+ }
+ }
+#endif
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/i386.
+
+ Copyright (C) 1988-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "regset.h"
+#include "symtab.h"
+#include "objfiles.h"
+#include "osabi.h"
+#include "target.h"
+#include "trad-frame.h"
+
+#include "obsd-tdep.h"
+#include "i386-tdep.h"
+#include "i387-tdep.h"
+#include "solib-svr4.h"
+#include "bsd-uthread.h"
+
+/* Support for signal handlers. */
+
+/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
+ in virtual memory. The randomness makes it somewhat tricky to
+ detect it, but fortunately we can rely on the fact that the start
+ of the sigtramp routine is page-aligned. We recognize the
+ trampoline by looking for the code that invokes the sigreturn
+ system call. The offset where we can find that code varies from
+ release to release.
+
+ By the way, the mapping mentioned above is read-only, so you cannot
+ place a breakpoint in the signal trampoline. */
+
+/* Default page size. */
+static const int i386obsd_page_size = 4096;
+
+/* Offset for sigreturn(2). */
+static const int i386obsd_sigreturn_offset[] = {
+ 0x0a, /* OpenBSD 3.2 */
+ 0x14, /* OpenBSD 3.6 */
+ 0x3a, /* OpenBSD 3.8 */
+ -1
+};
+
+/* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp
+ routine. */
+
+static int
+i386obsd_sigtramp_p (struct frame_info *this_frame)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
+ /* The call sequence invoking sigreturn(2). */
+ const gdb_byte sigreturn[] =
+ {
+ 0xb8,
+ 0x67, 0x00, 0x00, 0x00, /* movl $SYS_sigreturn, %eax */
+ 0xcd, 0x80 /* int $0x80 */
+ };
+ size_t buflen = sizeof sigreturn;
+ const int *offset;
+ gdb_byte *buf;
+ const char *name;
+
+ /* If the function has a valid symbol name, it isn't a
+ trampoline. */
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (name != NULL)
+ return 0;
+
+ /* If the function lives in a valid section (even without a starting
+ point) it isn't a trampoline. */
+ if (find_pc_section (pc) != NULL)
+ return 0;
+
+ /* Allocate buffer. */
+ buf = (gdb_byte *) alloca (buflen);
+
+ /* Loop over all offsets. */
+ for (offset = i386obsd_sigreturn_offset; *offset != -1; offset++)
+ {
+ /* If we can't read the instructions, return zero. */
+ if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
+ buf, buflen))
+ return 0;
+
+ /* Check for sigreturn(2). */
+ if (memcmp (buf, sigreturn, buflen) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+\f
+/* Mapping between the general-purpose registers in `struct reg'
+ format and GDB's register cache layout. */
+
+/* From <machine/reg.h>. */
+static int i386obsd_r_reg_offset[] =
+{
+ 0 * 4, /* %eax */
+ 1 * 4, /* %ecx */
+ 2 * 4, /* %edx */
+ 3 * 4, /* %ebx */
+ 4 * 4, /* %esp */
+ 5 * 4, /* %ebp */
+ 6 * 4, /* %esi */
+ 7 * 4, /* %edi */
+ 8 * 4, /* %eip */
+ 9 * 4, /* %eflags */
+ 10 * 4, /* %cs */
+ 11 * 4, /* %ss */
+ 12 * 4, /* %ds */
+ 13 * 4, /* %es */
+ 14 * 4, /* %fs */
+ 15 * 4 /* %gs */
+};
+
+static void
+i386obsd_aout_supply_regset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *regs, size_t len)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const gdb_byte *gregs = (const gdb_byte *) regs;
+
+ gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE);
+
+ i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
+ i387_supply_fsave (regcache, regnum, gregs + tdep->sizeof_gregset);
+}
+
+static const struct regset i386obsd_aout_gregset =
+ {
+ NULL, i386obsd_aout_supply_regset, NULL
+ };
+
+static void
+i386obsd_aout_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* OpenBSD a.out core dumps don't use seperate register sets for the
+ general-purpose and floating-point registers. */
+
+ cb (".reg", tdep->sizeof_gregset + I387_SIZEOF_FSAVE,
+ &i386obsd_aout_gregset, NULL, cb_data);
+}
+\f
+
+/* Sigtramp routine location for OpenBSD 3.1 and earlier releases. */
+CORE_ADDR i386obsd_sigtramp_start_addr = 0xbfbfdf20;
+CORE_ADDR i386obsd_sigtramp_end_addr = 0xbfbfdff0;
+
+/* From <machine/signal.h>. */
+int i386obsd_sc_reg_offset[I386_NUM_GREGS] =
+{
+ 10 * 4, /* %eax */
+ 9 * 4, /* %ecx */
+ 8 * 4, /* %edx */
+ 7 * 4, /* %ebx */
+ 14 * 4, /* %esp */
+ 6 * 4, /* %ebp */
+ 5 * 4, /* %esi */
+ 4 * 4, /* %edi */
+ 11 * 4, /* %eip */
+ 13 * 4, /* %eflags */
+ 12 * 4, /* %cs */
+ 15 * 4, /* %ss */
+ 3 * 4, /* %ds */
+ 2 * 4, /* %es */
+ 1 * 4, /* %fs */
+ 0 * 4 /* %gs */
+};
+
+/* From /usr/src/lib/libpthread/arch/i386/uthread_machdep.c. */
+static int i386obsd_uthread_reg_offset[] =
+{
+ 11 * 4, /* %eax */
+ 10 * 4, /* %ecx */
+ 9 * 4, /* %edx */
+ 8 * 4, /* %ebx */
+ -1, /* %esp */
+ 6 * 4, /* %ebp */
+ 5 * 4, /* %esi */
+ 4 * 4, /* %edi */
+ 12 * 4, /* %eip */
+ -1, /* %eflags */
+ 13 * 4, /* %cs */
+ -1, /* %ss */
+ 3 * 4, /* %ds */
+ 2 * 4, /* %es */
+ 1 * 4, /* %fs */
+ 0 * 4 /* %gs */
+};
+
+/* Offset within the thread structure where we can find the saved
+ stack pointer (%esp). */
+#define I386OBSD_UTHREAD_ESP_OFFSET 176
+
+static void
+i386obsd_supply_uthread (struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
+ CORE_ADDR sp = 0;
+ gdb_byte buf[4];
+ int i;
+
+ gdb_assert (regnum >= -1);
+
+ if (regnum == -1 || regnum == I386_ESP_REGNUM)
+ {
+ int offset;
+
+ /* Fetch stack pointer from thread structure. */
+ sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
+
+ /* Adjust the stack pointer such that it looks as if we just
+ returned from _thread_machdep_switch. */
+ offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4;
+ store_unsigned_integer (buf, 4, byte_order, sp + offset);
+ regcache_raw_supply (regcache, I386_ESP_REGNUM, buf);
+ }
+
+ for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
+ {
+ if (i386obsd_uthread_reg_offset[i] != -1
+ && (regnum == -1 || regnum == i))
+ {
+ /* Fetch stack pointer from thread structure (if we didn't
+ do so already). */
+ if (sp == 0)
+ sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
+
+ /* Read the saved register from the stack frame. */
+ read_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
+ regcache_raw_supply (regcache, i, buf);
+ }
+ }
+}
+
+static void
+i386obsd_collect_uthread (const struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
+ CORE_ADDR sp = 0;
+ gdb_byte buf[4];
+ int i;
+
+ gdb_assert (regnum >= -1);
+
+ if (regnum == -1 || regnum == I386_ESP_REGNUM)
+ {
+ int offset;
+
+ /* Calculate the stack pointer (frame pointer) that will be
+ stored into the thread structure. */
+ offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4;
+ regcache_raw_collect (regcache, I386_ESP_REGNUM, buf);
+ sp = extract_unsigned_integer (buf, 4, byte_order) - offset;
+
+ /* Store the stack pointer. */
+ write_memory_unsigned_integer (sp_addr, 4, byte_order, sp);
+
+ /* The stack pointer was (potentially) modified. Make sure we
+ build a proper stack frame. */
+ regnum = -1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
+ {
+ if (i386obsd_uthread_reg_offset[i] != -1
+ && (regnum == -1 || regnum == i))
+ {
+ /* Fetch stack pointer from thread structure (if we didn't
+ calculate it already). */
+ if (sp == 0)
+ sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
+
+ /* Write the register into the stack frame. */
+ regcache_raw_collect (regcache, i, buf);
+ write_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
+ }
+ }
+}
+\f
+/* Kernel debugging support. */
+
+/* From <machine/frame.h>. Note that %esp and %ess are only saved in
+ a trap frame when entering the kernel from user space. */
+static int i386obsd_tf_reg_offset[] =
+{
+ 10 * 4, /* %eax */
+ 9 * 4, /* %ecx */
+ 8 * 4, /* %edx */
+ 7 * 4, /* %ebx */
+ -1, /* %esp */
+ 6 * 4, /* %ebp */
+ 5 * 4, /* %esi */
+ 4 * 4, /* %edi */
+ 13 * 4, /* %eip */
+ 15 * 4, /* %eflags */
+ 14 * 4, /* %cs */
+ -1, /* %ss */
+ 3 * 4, /* %ds */
+ 2 * 4, /* %es */
+ 0 * 4, /* %fs */
+ 1 * 4 /* %gs */
+};
+
+static struct trad_frame_cache *
+i386obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ struct trad_frame_cache *cache;
+ CORE_ADDR func, sp, addr;
+ ULONGEST cs;
+ const char *name;
+ int i;
+
+ if (*this_cache)
+ return (struct trad_frame_cache *) *this_cache;
+
+ cache = trad_frame_cache_zalloc (this_frame);
+ *this_cache = cache;
+
+ func = get_frame_func (this_frame);
+ sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
+
+ find_pc_partial_function (func, &name, NULL, NULL);
+ if (name && startswith (name, "Xintr"))
+ addr = sp + 8; /* It's an interrupt frame. */
+ else
+ addr = sp;
+
+ for (i = 0; i < ARRAY_SIZE (i386obsd_tf_reg_offset); i++)
+ if (i386obsd_tf_reg_offset[i] != -1)
+ trad_frame_set_reg_addr (cache, i, addr + i386obsd_tf_reg_offset[i]);
+
+ /* Read %cs from trap frame. */
+ addr += i386obsd_tf_reg_offset[I386_CS_REGNUM];
+ cs = read_memory_unsigned_integer (addr, 4, byte_order);
+ if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
+ {
+ /* Trap from user space; terminate backtrace. */
+ trad_frame_set_id (cache, outer_frame_id);
+ }
+ else
+ {
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (cache, frame_id_build (sp + 8, func));
+ }
+
+ return cache;
+}
+
+static void
+i386obsd_trapframe_this_id (struct frame_info *this_frame,
+ void **this_cache, struct frame_id *this_id)
+{
+ struct trad_frame_cache *cache =
+ i386obsd_trapframe_cache (this_frame, this_cache);
+
+ trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+i386obsd_trapframe_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct trad_frame_cache *cache =
+ i386obsd_trapframe_cache (this_frame, this_cache);
+
+ return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static int
+i386obsd_trapframe_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_prologue_cache)
+{
+ ULONGEST cs;
+ const char *name;
+
+ /* Check Current Privilege Level and bail out if we're not executing
+ in kernel space. */
+ cs = get_frame_register_unsigned (this_frame, I386_CS_REGNUM);
+ if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
+ return 0;
+
+ find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
+ return (name && (strcmp (name, "calltrap") == 0
+ || strcmp (name, "syscall1") == 0
+ || startswith (name, "Xintr")
+ || startswith (name, "Xsoft")));
+}
+
+static const struct frame_unwind i386obsd_trapframe_unwind = {
+ /* FIXME: kettenis/20051219: This really is more like an interrupt
+ frame, but SIGTRAMP_FRAME would print <signal handler called>,
+ which really is not what we want here. */
+ NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
+ i386obsd_trapframe_this_id,
+ i386obsd_trapframe_prev_register,
+ NULL,
+ i386obsd_trapframe_sniffer
+};
+\f
+
+static void
+i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Obviously OpenBSD is BSD-based. */
+ i386bsd_init_abi (info, gdbarch);
+ obsd_init_abi (info, gdbarch);
+
+ /* OpenBSD has a different `struct reg'. */
+ tdep->gregset_reg_offset = i386obsd_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset);
+ tdep->sizeof_gregset = 16 * 4;
+
+ /* OpenBSD uses -freg-struct-return by default. */
+ tdep->struct_return = reg_struct_return;
+
+ /* OpenBSD uses a different memory layout. */
+ tdep->sigtramp_start = i386obsd_sigtramp_start_addr;
+ tdep->sigtramp_end = i386obsd_sigtramp_end_addr;
+ tdep->sigtramp_p = i386obsd_sigtramp_p;
+
+ /* OpenBSD has a `struct sigcontext' that's different from the
+ original 4.3 BSD. */
+ tdep->sc_reg_offset = i386obsd_sc_reg_offset;
+ tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset);
+
+ /* OpenBSD provides a user-level threads implementation. */
+ bsd_uthread_set_supply_uthread (gdbarch, i386obsd_supply_uthread);
+ bsd_uthread_set_collect_uthread (gdbarch, i386obsd_collect_uthread);
+
+ /* Unwind kernel trap frames correctly. */
+ frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind);
+}
+
+/* OpenBSD a.out. */
+
+static void
+i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ i386obsd_init_abi (info, gdbarch);
+
+ /* OpenBSD a.out has a single register set. */
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, i386obsd_aout_iterate_over_regset_sections);
+}
+
+/* OpenBSD ELF. */
+
+static void
+i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* It's still OpenBSD. */
+ i386obsd_init_abi (info, gdbarch);
+
+ /* But ELF-based. */
+ i386_elf_init_abi (info, gdbarch);
+
+ /* OpenBSD ELF uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_i386obsd_tdep (void);
+
+void
+_initialize_i386obsd_tdep (void)
+{
+ /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are
+ indistingushable from NetBSD/i386 a.out binaries, building a GDB
+ that should support both these targets will probably not work as
+ expected. */
+#define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT
+
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT,
+ i386obsd_aout_init_abi);
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF,
+ i386obsd_elf_init_abi);
+}
extern int i386_mpx_enabled (void);
\f
-/* Functions and variables exported from i386bsd-tdep.c. */
+/* Functions and variables exported from i386-bsd-tdep.c. */
extern void i386bsd_init_abi (struct gdbarch_info, struct gdbarch *);
extern CORE_ADDR i386fbsd_sigtramp_start_addr;
--- /dev/null
+/* Native-dependent code for Unix SVR4 running on i386's.
+
+ Copyright (C) 1988-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "value.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#include "i386-tdep.h"
+#include "i387-tdep.h"
+
+#ifdef HAVE_SYS_PROCFS_H
+
+#include <sys/procfs.h>
+
+/* We must not compile this code for 64-bit Solaris x86. */
+#if !defined (PR_MODEL_NATIVE) || (PR_MODEL_NATIVE == PR_MODEL_ILP32)
+
+#include "gregset.h"
+
+/* The `/proc' interface divides the target machine's register set up
+ into two different sets, the general purpose register set (gregset)
+ and the floating-point register set (fpregset). For each set,
+ there is an ioctl to get the current register set and another ioctl
+ to set the current values.
+
+ The actual structure passed through the ioctl interface is, of
+ course, naturally machine dependent, and is different for each set
+ of registers. For the i386 for example, the general-purpose
+ register set is typically defined by:
+
+ typedef int gregset_t[19]; (in <sys/regset.h>)
+
+ #define GS 0 (in <sys/reg.h>)
+ #define FS 1
+ ...
+ #define UESP 17
+ #define SS 18
+
+ and the floating-point set by:
+
+ typedef struct fpregset {
+ union {
+ struct fpchip_state // fp extension state //
+ {
+ int state[27]; // 287/387 saved state //
+ int status; // status word saved at //
+ // exception //
+ } fpchip_state;
+ struct fp_emul_space // for emulators //
+ {
+ char fp_emul[246];
+ char fp_epad[2];
+ } fp_emul_space;
+ int f_fpregs[62]; // union of the above //
+ } fp_reg_set;
+ long f_wregs[33]; // saved weitek state //
+ } fpregset_t;
+
+ Incidentally fpchip_state contains the FPU state in the same format
+ as used by the "fsave" instruction, and that's the only thing we
+ support here. I don't know how the emulator stores it state. The
+ Weitek stuff definitely isn't supported.
+
+ The routines defined here, provide the packing and unpacking of
+ gregset_t and fpregset_t formatted data. */
+
+#ifdef HAVE_GREGSET_T
+
+/* Mapping between the general-purpose registers in `/proc'
+ format and GDB's register array layout. */
+static int regmap[] =
+{
+ EAX, ECX, EDX, EBX,
+ UESP, EBP, ESI, EDI,
+ EIP, EFL, CS, SS,
+ DS, ES, FS, GS
+};
+
+/* Fill GDB's register array with the general-purpose register values
+ in *GREGSETP. */
+
+void
+supply_gregset (struct regcache *regcache, const gregset_t *gregsetp)
+{
+ const greg_t *regp = (const greg_t *) gregsetp;
+ int regnum;
+
+ for (regnum = 0; regnum < I386_NUM_GREGS; regnum++)
+ regcache_raw_supply (regcache, regnum, regp + regmap[regnum]);
+}
+
+/* Fill register REGNUM (if it is a general-purpose register) in
+ *GREGSETPS with the value in GDB's register array. If REGNUM is -1,
+ do this for all registers. */
+
+void
+fill_gregset (const struct regcache *regcache,
+ gregset_t *gregsetp, int regnum)
+{
+ greg_t *regp = (greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < I386_NUM_GREGS; i++)
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regp + regmap[i]);
+}
+
+#endif /* HAVE_GREGSET_T */
+
+#ifdef HAVE_FPREGSET_T
+
+/* Fill GDB's register array with the floating-point register values in
+ *FPREGSETP. */
+
+void
+supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
+{
+ if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) == 0)
+ return;
+
+ i387_supply_fsave (regcache, -1, fpregsetp);
+}
+
+/* Fill register REGNO (if it is a floating-point register) in
+ *FPREGSETP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_fpregset (const struct regcache *regcache,
+ fpregset_t *fpregsetp, int regno)
+{
+ if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) == 0)
+ return;
+
+ i387_collect_fsave (regcache, regno, fpregsetp);
+}
+
+#endif /* HAVE_FPREGSET_T */
+
+#endif /* not 64-bit. */
+
+#endif /* HAVE_SYS_PROCFS_H */
+++ /dev/null
-/* Native-dependent code for modern i386 BSD's.
-
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-#include <machine/frame.h>
-
-#include "i386-tdep.h"
-#include "i387-tdep.h"
-#include "x86bsd-nat.h"
-#include "i386bsd-nat.h"
-#include "inf-ptrace.h"
-\f
-
-/* In older BSD versions we cannot get at some of the segment
- registers. FreeBSD for example didn't support the %fs and %gs
- registers until the 3.0 release. We have autoconf checks for their
- presence, and deal gracefully with their absence. */
-
-/* Offset in `struct reg' where MEMBER is stored. */
-#define REG_OFFSET(member) offsetof (struct reg, member)
-
-/* At i386bsd_reg_offset[REGNUM] you'll find the offset in `struct
- reg' where the GDB register REGNUM is stored. Unsupported
- registers are marked with `-1'. */
-static int i386bsd_r_reg_offset[] =
-{
- REG_OFFSET (r_eax),
- REG_OFFSET (r_ecx),
- REG_OFFSET (r_edx),
- REG_OFFSET (r_ebx),
- REG_OFFSET (r_esp),
- REG_OFFSET (r_ebp),
- REG_OFFSET (r_esi),
- REG_OFFSET (r_edi),
- REG_OFFSET (r_eip),
- REG_OFFSET (r_eflags),
- REG_OFFSET (r_cs),
- REG_OFFSET (r_ss),
- REG_OFFSET (r_ds),
- REG_OFFSET (r_es),
-#ifdef HAVE_STRUCT_REG_R_FS
- REG_OFFSET (r_fs),
-#else
- -1,
-#endif
-#ifdef HAVE_STRUCT_REG_R_GS
- REG_OFFSET (r_gs)
-#else
- -1
-#endif
-};
-
-/* Macro to determine if a register is fetched with PT_GETREGS. */
-#define GETREGS_SUPPLIES(regnum) \
- ((0 <= (regnum) && (regnum) <= 15))
-
-#ifdef HAVE_PT_GETXMMREGS
-/* Set to 1 if the kernel supports PT_GETXMMREGS. Initialized to -1
- so that we try PT_GETXMMREGS the first time around. */
-static int have_ptrace_xmmregs = -1;
-#endif
-\f
-
-/* Supply the general-purpose registers in GREGS, to REGCACHE. */
-
-static void
-i386bsd_supply_gregset (struct regcache *regcache, const void *gregs)
-{
- const char *regs = (const char *) gregs;
- int regnum;
-
- for (regnum = 0; regnum < ARRAY_SIZE (i386bsd_r_reg_offset); regnum++)
- {
- int offset = i386bsd_r_reg_offset[regnum];
-
- if (offset != -1)
- regcache_raw_supply (regcache, regnum, regs + offset);
- }
-}
-
-/* Collect register REGNUM from REGCACHE and store its contents in
- GREGS. If REGNUM is -1, collect and store all appropriate
- registers. */
-
-static void
-i386bsd_collect_gregset (const struct regcache *regcache,
- void *gregs, int regnum)
-{
- char *regs = (char *) gregs;
- int i;
-
- for (i = 0; i < ARRAY_SIZE (i386bsd_r_reg_offset); i++)
- {
- if (regnum == -1 || regnum == i)
- {
- int offset = i386bsd_r_reg_offset[i];
-
- if (offset != -1)
- regcache_raw_collect (regcache, i, regs + offset);
- }
- }
-}
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers (including the floating point registers). */
-
-static void
-i386bsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- if (regnum == -1 || GETREGS_SUPPLIES (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- i386bsd_supply_gregset (regcache, ®s);
- if (regnum != -1)
- return;
- }
-
- if (regnum == -1 || regnum >= I386_ST0_REGNUM)
- {
- struct fpreg fpregs;
-#ifdef HAVE_PT_GETXMMREGS
- char xmmregs[512];
-#endif
-
-#ifdef PT_GETXSTATE_INFO
- if (x86bsd_xsave_len != 0)
- {
- void *xstateregs;
-
- xstateregs = alloca (x86bsd_xsave_len);
- if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
- perror_with_name (_("Couldn't get extended state status"));
-
- i387_supply_xsave (regcache, -1, xstateregs);
- return;
- }
-#endif
-
-#ifdef HAVE_PT_GETXMMREGS
- if (have_ptrace_xmmregs != 0
- && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
- {
- have_ptrace_xmmregs = 1;
- i387_supply_fxsave (regcache, -1, xmmregs);
- }
- else
- {
- have_ptrace_xmmregs = 0;
-#endif
- if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- i387_supply_fsave (regcache, -1, &fpregs);
-#ifdef HAVE_PT_GETXMMREGS
- }
-#endif
- }
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers (including the floating point registers). */
-
-static void
-i386bsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- if (regnum == -1 || GETREGS_SUPPLIES (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- i386bsd_collect_gregset (regcache, ®s, regnum);
-
- if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-
- if (regnum != -1)
- return;
- }
-
- if (regnum == -1 || regnum >= I386_ST0_REGNUM)
- {
- struct fpreg fpregs;
-#ifdef HAVE_PT_GETXMMREGS
- char xmmregs[512];
-#endif
-
-#ifdef PT_GETXSTATE_INFO
- if (x86bsd_xsave_len != 0)
- {
- void *xstateregs;
-
- xstateregs = alloca (x86bsd_xsave_len);
- if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
- perror_with_name (_("Couldn't get extended state status"));
-
- i387_collect_xsave (regcache, -1, xstateregs, 0);
-
- if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) xstateregs, x86bsd_xsave_len) == -1)
- perror_with_name (_("Couldn't write extended state status"));
- return;
- }
-#endif
-
-#ifdef HAVE_PT_GETXMMREGS
- if (have_ptrace_xmmregs != 0
- && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
- {
- have_ptrace_xmmregs = 1;
-
- i387_collect_fxsave (regcache, regnum, xmmregs);
-
- if (ptrace (PT_SETXMMREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) xmmregs, 0) == -1)
- perror_with_name (_("Couldn't write XMM registers"));
- }
- else
- {
- have_ptrace_xmmregs = 0;
-#endif
- if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- i387_collect_fsave (regcache, regnum, &fpregs);
-
- if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't write floating point status"));
-#ifdef HAVE_PT_GETXMMREGS
- }
-#endif
- }
-}
-
-/* Create a prototype *BSD/i386 target. The client can override it
- with local methods. */
-
-struct target_ops *
-i386bsd_target (void)
-{
- struct target_ops *t;
-
- t = x86bsd_target ();
- t->to_fetch_registers = i386bsd_fetch_inferior_registers;
- t->to_store_registers = i386bsd_store_inferior_registers;
- return t;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_i386bsd_nat (void);
-
-void
-_initialize_i386bsd_nat (void)
-{
- int offset;
-
- /* To support the recognition of signal handlers, i386bsd-tdep.c
- hardcodes some constants. Inclusion of this file means that we
- are compiling a native debugger, which means that we can use the
- system header files and sysctl(3) to get at the relevant
- information. */
-
-#if defined (__FreeBSD_version) && __FreeBSD_version >= 400011
-#define SC_REG_OFFSET i386fbsd4_sc_reg_offset
-#elif defined (__FreeBSD_version) && __FreeBSD_version >= 300005
-#define SC_REG_OFFSET i386fbsd_sc_reg_offset
-#elif defined (NetBSD) || defined (__NetBSD_Version__)
-#define SC_REG_OFFSET i386nbsd_sc_reg_offset
-#elif defined (OpenBSD)
-#define SC_REG_OFFSET i386obsd_sc_reg_offset
-#endif
-
-#ifdef SC_REG_OFFSET
-
- /* We only check the program counter, stack pointer and frame
- pointer since these members of `struct sigcontext' are essential
- for providing backtraces. More checks could be added, but would
- involve adding configure checks for the appropriate structure
- members, since older BSD's don't provide all of them. */
-
-#define SC_PC_OFFSET SC_REG_OFFSET[I386_EIP_REGNUM]
-#define SC_SP_OFFSET SC_REG_OFFSET[I386_ESP_REGNUM]
-#define SC_FP_OFFSET SC_REG_OFFSET[I386_EBP_REGNUM]
-
- /* Override the default value for the offset of the program counter
- in the sigcontext structure. */
- offset = offsetof (struct sigcontext, sc_pc);
-
- if (SC_PC_OFFSET != offset)
- {
- warning (_("\
-offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\
-Please report this to <bug-gdb@gnu.org>."),
- offset, SC_PC_OFFSET);
- }
-
- SC_PC_OFFSET = offset;
-
- /* Likewise for the stack pointer. */
- offset = offsetof (struct sigcontext, sc_sp);
-
- if (SC_SP_OFFSET != offset)
- {
- warning (_("\
-offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\
-Please report this to <bug-gdb@gnu.org>."),
- offset, SC_SP_OFFSET);
- }
-
- SC_SP_OFFSET = offset;
-
- /* And the frame pointer. */
- offset = offsetof (struct sigcontext, sc_fp);
-
- if (SC_FP_OFFSET != offset)
- {
- warning (_("\
-offsetof (struct sigcontext, sc_fp) yields %d instead of %d.\n\
-Please report this to <bug-gdb@gnu.org>."),
- offset, SC_FP_OFFSET);
- }
-
- SC_FP_OFFSET = offset;
-
-#endif /* SC_REG_OFFSET */
-}
+++ /dev/null
-/* Native-dependent code for modern i386 BSD's.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef I386BSD_NAT_H
-#define I386BSD_NAT_H
-
-/* Create a prototype *BSD/i386 target. The client can override it
- with local methods. */
-
-extern struct target_ops *i386bsd_target (void);
-
-#endif /* i386bsd-nat.h */
+++ /dev/null
-/* Target-dependent code for i386 BSD's.
-
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "osabi.h"
-
-#include "i386-tdep.h"
-
-/* Support for signal handlers. */
-
-/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
- address of the associated sigcontext structure. */
-
-static CORE_ADDR
-i386bsd_sigcontext_addr (struct frame_info *this_frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[4];
- CORE_ADDR sp;
-
- get_frame_register (this_frame, I386_ESP_REGNUM, buf);
- sp = extract_unsigned_integer (buf, 4, byte_order);
-
- return read_memory_unsigned_integer (sp + 8, 4, byte_order);
-}
-\f
-
-/* Support for shared libraries. */
-
-/* Traditional BSD (4.3 BSD, still used for BSDI and 386BSD). */
-
-/* From <machine/signal.h>. */
-int i386bsd_sc_reg_offset[] =
-{
- -1, /* %eax */
- -1, /* %ecx */
- -1, /* %edx */
- -1, /* %ebx */
- 8 + 0 * 4, /* %esp */
- 8 + 1 * 4, /* %ebp */
- -1, /* %esi */
- -1, /* %edi */
- 8 + 3 * 4, /* %eip */
- 8 + 4 * 4, /* %eflags */
- -1, /* %cs */
- -1, /* %ss */
- -1, /* %ds */
- -1, /* %es */
- -1, /* %fs */
- -1 /* %gs */
-};
-
-void
-i386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- tdep->jb_pc_offset = 0;
-
- tdep->sigtramp_start = 0xfdbfdfc0;
- tdep->sigtramp_end = 0xfdbfe000;
- tdep->sigcontext_addr = i386bsd_sigcontext_addr;
- tdep->sc_reg_offset = i386bsd_sc_reg_offset;
- tdep->sc_num_regs = ARRAY_SIZE (i386bsd_sc_reg_offset);
-}
-
-\f
-static enum gdb_osabi
-i386bsd_aout_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "a.out-i386-netbsd") == 0)
- return GDB_OSABI_NETBSD_AOUT;
-
- if (strcmp (bfd_get_target (abfd), "a.out-i386-freebsd") == 0)
- return GDB_OSABI_FREEBSD_AOUT;
-
- return GDB_OSABI_UNKNOWN;
-}
-
-static enum gdb_osabi
-i386bsd_core_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
- return GDB_OSABI_NETBSD_AOUT;
-
- return GDB_OSABI_UNKNOWN;
-}
-
-\f
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_i386bsd_tdep (void);
-
-void
-_initialize_i386bsd_tdep (void)
-{
- gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_aout_flavour,
- i386bsd_aout_osabi_sniffer);
-
- /* BFD doesn't set a flavour for NetBSD style a.out core files. */
- gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_unknown_flavour,
- i386bsd_core_osabi_sniffer);
-}
+++ /dev/null
-/* Native-dependent code for FreeBSD/i386.
-
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <sys/sysctl.h>
-#include <sys/user.h>
-
-#include "fbsd-nat.h"
-#include "i386-tdep.h"
-#include "x86-nat.h"
-#include "x86bsd-nat.h"
-#include "i386bsd-nat.h"
-
-/* Resume execution of the inferior process. If STEP is nonzero,
- single-step it. If SIGNAL is nonzero, give it that signal. */
-
-static void
-i386fbsd_resume (struct target_ops *ops,
- ptid_t ptid, int step, enum gdb_signal signal)
-{
- pid_t pid = ptid_get_pid (ptid);
- int request = PT_STEP;
-
- if (pid == -1)
- /* Resume all threads. This only gets used in the non-threaded
- case, where "resume all threads" and "resume inferior_ptid" are
- the same. */
- pid = ptid_get_pid (inferior_ptid);
-
- if (!step)
- {
- struct regcache *regcache = get_current_regcache ();
- ULONGEST eflags;
-
- /* Workaround for a bug in FreeBSD. Make sure that the trace
- flag is off when doing a continue. There is a code path
- through the kernel which leaves the flag set when it should
- have been cleared. If a process has a signal pending (such
- as SIGALRM) and we do a PT_STEP, the process never really has
- a chance to run because the kernel needs to notify the
- debugger that a signal is being sent. Therefore, the process
- never goes through the kernel's trap() function which would
- normally clear it. */
-
- regcache_cooked_read_unsigned (regcache, I386_EFLAGS_REGNUM,
- &eflags);
- if (eflags & 0x0100)
- regcache_cooked_write_unsigned (regcache, I386_EFLAGS_REGNUM,
- eflags & ~0x0100);
-
- request = PT_CONTINUE;
- }
-
- /* An addres of (caddr_t) 1 tells ptrace to continue from where it
- was. (If GDB wanted it to start some other way, we have already
- written a new PC value to the child.) */
- if (ptrace (request, pid, (caddr_t) 1,
- gdb_signal_to_host (signal)) == -1)
- perror_with_name (("ptrace"));
-}
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- /* The following is true for FreeBSD 4.7:
-
- The pcb contains %eip, %ebx, %esp, %ebp, %esi, %edi and %gs.
- This accounts for all callee-saved registers specified by the
- psABI and then some. Here %esp contains the stack pointer at the
- point just after the call to cpu_switch(). From this information
- we reconstruct the register state as it would look when we just
- returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_esp == 0)
- return 0;
-
- pcb->pcb_esp += 4;
- regcache_raw_supply (regcache, I386_EDI_REGNUM, &pcb->pcb_edi);
- regcache_raw_supply (regcache, I386_ESI_REGNUM, &pcb->pcb_esi);
- regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
- regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
- regcache_raw_supply (regcache, I386_EBX_REGNUM, &pcb->pcb_ebx);
- regcache_raw_supply (regcache, I386_EIP_REGNUM, &pcb->pcb_eip);
- regcache_raw_supply (regcache, I386_GS_REGNUM, &pcb->pcb_gs);
-
- return 1;
-}
-\f
-
-#ifdef PT_GETXSTATE_INFO
-/* Implement the to_read_description method. */
-
-static const struct target_desc *
-i386fbsd_read_description (struct target_ops *ops)
-{
- static int xsave_probed;
- static uint64_t xcr0;
-
- if (!xsave_probed)
- {
- struct ptrace_xstate_info info;
-
- if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
- {
- x86bsd_xsave_len = info.xsave_len;
- xcr0 = info.xsave_mask;
- }
- xsave_probed = 1;
- }
-
- if (x86bsd_xsave_len != 0)
- {
- return i386_target_description (xcr0);
- }
- else
- return tdesc_i386;
-}
-#endif
-
-/* Prevent warning from -Wmissing-prototypes. */
-void _initialize_i386fbsd_nat (void);
-
-void
-_initialize_i386fbsd_nat (void)
-{
- struct target_ops *t;
-
- /* Add some extra features to the common *BSD/i386 target. */
- t = i386bsd_target ();
-
-#ifdef PT_GETXSTATE_INFO
- t->to_read_description = i386fbsd_read_description;
-#endif
-
- t->to_resume = i386fbsd_resume;
- fbsd_nat_add_target (t);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (i386fbsd_supply_pcb);
-
-#ifdef KERN_PROC_SIGTRAMP
- /* Normally signal frames are detected via i386fbsd_sigtramp_p.
- However, FreeBSD 9.2 through 10.1 do not include the page holding
- the signal code in core dumps. These releases do provide a
- kern.proc.sigtramp.<pid> sysctl that returns the location of the
- signal trampoline for a running process. We fetch the location
- of the current (gdb) process and use this to identify signal
- frames in core dumps from these releases. */
- {
- int mib[4];
- struct kinfo_sigtramp kst;
- size_t len;
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_SIGTRAMP;
- mib[3] = getpid ();
- len = sizeof (kst);
- if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0)
- {
- i386fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start;
- i386fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end;
- }
- }
-#endif
-}
+++ /dev/null
-/* Target-dependent code for FreeBSD/i386.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "i386fbsd-tdep.h"
-#include "x86-xstate.h"
-
-#include "i386-tdep.h"
-#include "i387-tdep.h"
-#include "bsd-uthread.h"
-#include "fbsd-tdep.h"
-#include "solib-svr4.h"
-
-/* Support for signal handlers. */
-
-/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp
- routine. */
-
-/* FreeBSD/i386 supports three different signal trampolines, one for
- versions before 4.0, a second for 4.x, and a third for 5.0 and
- later. To complicate matters, FreeBSD/i386 binaries running under
- an amd64 kernel use a different set of trampolines. These
- trampolines differ from the i386 kernel trampolines in that they
- omit a middle section that conditionally restores %gs. */
-
-static const gdb_byte i386fbsd_sigtramp_start[] =
-{
- 0x8d, 0x44, 0x24, 0x20, /* lea SIGF_UC(%esp),%eax */
- 0x50 /* pushl %eax */
-};
-
-static const gdb_byte i386fbsd_sigtramp_middle[] =
-{
- 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x00,
- /* testl $PSL_VM,UC_EFLAGS(%eax) */
- 0x75, 0x03, /* jne +3 */
- 0x8e, 0x68, 0x14 /* mov UC_GS(%eax),%gs */
-};
-
-static const gdb_byte i386fbsd_sigtramp_end[] =
-{
- 0xb8, 0xa1, 0x01, 0x00, 0x00, /* movl $SYS_sigreturn,%eax */
- 0x50, /* pushl %eax */
- 0xcd, 0x80 /* int $0x80 */
-};
-
-static const gdb_byte i386fbsd_freebsd4_sigtramp_start[] =
-{
- 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_UC4(%esp),%eax */
- 0x50 /* pushl %eax */
-};
-
-static const gdb_byte i386fbsd_freebsd4_sigtramp_middle[] =
-{
- 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x00,
- /* testl $PSL_VM,UC4_EFLAGS(%eax) */
- 0x75, 0x03, /* jne +3 */
- 0x8e, 0x68, 0x14 /* mov UC4_GS(%eax),%gs */
-};
-
-static const gdb_byte i386fbsd_freebsd4_sigtramp_end[] =
-{
- 0xb8, 0x58, 0x01, 0x00, 0x00, /* movl $344,%eax */
- 0x50, /* pushl %eax */
- 0xcd, 0x80 /* int $0x80 */
-};
-
-static const gdb_byte i386fbsd_osigtramp_start[] =
-{
- 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_SC(%esp),%eax */
- 0x50 /* pushl %eax */
-};
-
-static const gdb_byte i386fbsd_osigtramp_middle[] =
-{
- 0xf7, 0x40, 0x18, 0x00, 0x00, 0x02, 0x00,
- /* testl $PSL_VM,SC_PS(%eax) */
- 0x75, 0x03, /* jne +3 */
- 0x8e, 0x68, 0x44 /* mov SC_GS(%eax),%gs */
-};
-
-static const gdb_byte i386fbsd_osigtramp_end[] =
-{
- 0xb8, 0x67, 0x00, 0x00, 0x00, /* movl $103,%eax */
- 0x50, /* pushl %eax */
- 0xcd, 0x80 /* int $0x80 */
-};
-
-/* The three different trampolines are all the same size. */
-gdb_static_assert (sizeof i386fbsd_sigtramp_start
- == sizeof i386fbsd_freebsd4_sigtramp_start);
-gdb_static_assert (sizeof i386fbsd_sigtramp_start
- == sizeof i386fbsd_osigtramp_start);
-gdb_static_assert (sizeof i386fbsd_sigtramp_middle
- == sizeof i386fbsd_freebsd4_sigtramp_middle);
-gdb_static_assert (sizeof i386fbsd_sigtramp_middle
- == sizeof i386fbsd_osigtramp_middle);
-gdb_static_assert (sizeof i386fbsd_sigtramp_end
- == sizeof i386fbsd_freebsd4_sigtramp_end);
-gdb_static_assert (sizeof i386fbsd_sigtramp_end
- == sizeof i386fbsd_osigtramp_end);
-
-/* We assume that the middle is the largest chunk below. */
-gdb_static_assert (sizeof i386fbsd_sigtramp_middle
- > sizeof i386fbsd_sigtramp_start);
-gdb_static_assert (sizeof i386fbsd_sigtramp_middle
- > sizeof i386fbsd_sigtramp_end);
-
-static int
-i386fbsd_sigtramp_p (struct frame_info *this_frame)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- gdb_byte buf[sizeof i386fbsd_sigtramp_middle];
- const gdb_byte *middle, *end;
-
- /* Look for a matching start. */
- if (!safe_frame_unwind_memory (this_frame, pc, buf,
- sizeof i386fbsd_sigtramp_start))
- return 0;
- if (memcmp (buf, i386fbsd_sigtramp_start, sizeof i386fbsd_sigtramp_start)
- == 0)
- {
- middle = i386fbsd_sigtramp_middle;
- end = i386fbsd_sigtramp_end;
- }
- else if (memcmp (buf, i386fbsd_freebsd4_sigtramp_start,
- sizeof i386fbsd_freebsd4_sigtramp_start) == 0)
- {
- middle = i386fbsd_freebsd4_sigtramp_middle;
- end = i386fbsd_freebsd4_sigtramp_end;
- }
- else if (memcmp (buf, i386fbsd_osigtramp_start,
- sizeof i386fbsd_osigtramp_start) == 0)
- {
- middle = i386fbsd_osigtramp_middle;
- end = i386fbsd_osigtramp_end;
- }
- else
- return 0;
-
- /* Since the end is shorter than the middle, check for a matching end
- next. */
- pc += sizeof i386fbsd_sigtramp_start;
- if (!safe_frame_unwind_memory (this_frame, pc, buf,
- sizeof i386fbsd_sigtramp_end))
- return 0;
- if (memcmp (buf, end, sizeof i386fbsd_sigtramp_end) == 0)
- return 1;
-
- /* If the end didn't match, check for a matching middle. */
- if (!safe_frame_unwind_memory (this_frame, pc, buf,
- sizeof i386fbsd_sigtramp_middle))
- return 0;
- if (memcmp (buf, middle, sizeof i386fbsd_sigtramp_middle) != 0)
- return 0;
-
- /* The middle matched, check for a matching end. */
- pc += sizeof i386fbsd_sigtramp_middle;
- if (!safe_frame_unwind_memory (this_frame, pc, buf,
- sizeof i386fbsd_sigtramp_end))
- return 0;
- if (memcmp (buf, end, sizeof i386fbsd_sigtramp_end) != 0)
- return 0;
-
- return 1;
-}
-
-/* FreeBSD 3.0-RELEASE or later. */
-
-/* From <machine/reg.h>. */
-static int i386fbsd_r_reg_offset[] =
-{
- 9 * 4, 8 * 4, 7 * 4, 6 * 4, /* %eax, %ecx, %edx, %ebx */
- 15 * 4, 4 * 4, /* %esp, %ebp */
- 3 * 4, 2 * 4, /* %esi, %edi */
- 12 * 4, 14 * 4, /* %eip, %eflags */
- 13 * 4, 16 * 4, /* %cs, %ss */
- 1 * 4, 0 * 4, -1, -1 /* %ds, %es, %fs, %gs */
-};
-
-/* Sigtramp routine location. */
-CORE_ADDR i386fbsd_sigtramp_start_addr;
-CORE_ADDR i386fbsd_sigtramp_end_addr;
-
-/* From <machine/signal.h>. */
-int i386fbsd_sc_reg_offset[] =
-{
- 8 + 14 * 4, /* %eax */
- 8 + 13 * 4, /* %ecx */
- 8 + 12 * 4, /* %edx */
- 8 + 11 * 4, /* %ebx */
- 8 + 0 * 4, /* %esp */
- 8 + 1 * 4, /* %ebp */
- 8 + 10 * 4, /* %esi */
- 8 + 9 * 4, /* %edi */
- 8 + 3 * 4, /* %eip */
- 8 + 4 * 4, /* %eflags */
- 8 + 7 * 4, /* %cs */
- 8 + 8 * 4, /* %ss */
- 8 + 6 * 4, /* %ds */
- 8 + 5 * 4, /* %es */
- 8 + 15 * 4, /* %fs */
- 8 + 16 * 4 /* %gs */
-};
-
-/* From /usr/src/lib/libc/i386/gen/_setjmp.S. */
-static int i386fbsd_jmp_buf_reg_offset[] =
-{
- -1, /* %eax */
- -1, /* %ecx */
- -1, /* %edx */
- 1 * 4, /* %ebx */
- 2 * 4, /* %esp */
- 3 * 4, /* %ebp */
- 4 * 4, /* %esi */
- 5 * 4, /* %edi */
- 0 * 4 /* %eip */
-};
-
-/* Get XSAVE extended state xcr0 from core dump. */
-
-uint64_t
-i386fbsd_core_read_xcr0 (bfd *abfd)
-{
- asection *xstate = bfd_get_section_by_name (abfd, ".reg-xstate");
- uint64_t xcr0;
-
- if (xstate)
- {
- size_t size = bfd_section_size (abfd, xstate);
-
- /* Check extended state size. */
- if (size < X86_XSTATE_AVX_SIZE)
- xcr0 = X86_XSTATE_SSE_MASK;
- else
- {
- char contents[8];
-
- if (! bfd_get_section_contents (abfd, xstate, contents,
- I386_FBSD_XSAVE_XCR0_OFFSET,
- 8))
- {
- warning (_("Couldn't read `xcr0' bytes from "
- "`.reg-xstate' section in core file."));
- return 0;
- }
-
- xcr0 = bfd_get_64 (abfd, contents);
- }
- }
- else
- xcr0 = 0;
-
- return xcr0;
-}
-
-/* Implement the core_read_description gdbarch method. */
-
-static const struct target_desc *
-i386fbsd_core_read_description (struct gdbarch *gdbarch,
- struct target_ops *target,
- bfd *abfd)
-{
- return i386_target_description (i386fbsd_core_read_xcr0 (abfd));
-}
-
-/* Similar to i386_supply_fpregset, but use XSAVE extended state. */
-
-static void
-i386fbsd_supply_xstateregset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *xstateregs, size_t len)
-{
- i387_supply_xsave (regcache, regnum, xstateregs);
-}
-
-/* Similar to i386_collect_fpregset, but use XSAVE extended state. */
-
-static void
-i386fbsd_collect_xstateregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *xstateregs, size_t len)
-{
- i387_collect_xsave (regcache, regnum, xstateregs, 1);
-}
-
-/* Register set definitions. */
-
-static const struct regset i386fbsd_xstateregset =
- {
- NULL,
- i386fbsd_supply_xstateregset,
- i386fbsd_collect_xstateregset
- };
-
-/* Iterate over core file register note sections. */
-
-static void
-i386fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- cb (".reg", tdep->sizeof_gregset, &i386_gregset, NULL, cb_data);
- cb (".reg2", tdep->sizeof_fpregset, &i386_fpregset, NULL, cb_data);
-
- if (tdep->xcr0 & X86_XSTATE_AVX)
- cb (".reg-xstate", X86_XSTATE_SIZE(tdep->xcr0),
- &i386fbsd_xstateregset, "XSAVE extended state", cb_data);
-}
-
-static void
-i386fbsd_supply_uthread (struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- gdb_byte buf[4];
- int i;
-
- gdb_assert (regnum >= -1);
-
- for (i = 0; i < ARRAY_SIZE (i386fbsd_jmp_buf_reg_offset); i++)
- {
- if (i386fbsd_jmp_buf_reg_offset[i] != -1
- && (regnum == -1 || regnum == i))
- {
- read_memory (addr + i386fbsd_jmp_buf_reg_offset[i], buf, 4);
- regcache_raw_supply (regcache, i, buf);
- }
- }
-}
-
-static void
-i386fbsd_collect_uthread (const struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- gdb_byte buf[4];
- int i;
-
- gdb_assert (regnum >= -1);
-
- for (i = 0; i < ARRAY_SIZE (i386fbsd_jmp_buf_reg_offset); i++)
- {
- if (i386fbsd_jmp_buf_reg_offset[i] != -1
- && (regnum == -1 || regnum == i))
- {
- regcache_raw_collect (regcache, i, buf);
- write_memory (addr + i386fbsd_jmp_buf_reg_offset[i], buf, 4);
- }
- }
-}
-
-static void
-i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Obviously FreeBSD is BSD-based. */
- i386bsd_init_abi (info, gdbarch);
-
- /* FreeBSD has a different `struct reg', and reserves some space for
- its FPU emulator in `struct fpreg'. */
- tdep->gregset_reg_offset = i386fbsd_r_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd_r_reg_offset);
- tdep->sizeof_gregset = 18 * 4;
- tdep->sizeof_fpregset = 176;
-
- /* FreeBSD uses -freg-struct-return by default. */
- tdep->struct_return = reg_struct_return;
-
- tdep->sigtramp_p = i386fbsd_sigtramp_p;
-
- /* FreeBSD uses a different memory layout. */
- tdep->sigtramp_start = i386fbsd_sigtramp_start_addr;
- tdep->sigtramp_end = i386fbsd_sigtramp_end_addr;
-
- /* FreeBSD has a more complete `struct sigcontext'. */
- tdep->sc_reg_offset = i386fbsd_sc_reg_offset;
- tdep->sc_num_regs = ARRAY_SIZE (i386fbsd_sc_reg_offset);
-
- /* FreeBSD provides a user-level threads implementation. */
- bsd_uthread_set_supply_uthread (gdbarch, i386fbsd_supply_uthread);
- bsd_uthread_set_collect_uthread (gdbarch, i386fbsd_collect_uthread);
-}
-
-static void
-i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- /* It's almost identical to FreeBSD a.out. */
- i386fbsdaout_init_abi (info, gdbarch);
-
- /* Except that it uses ELF. */
- i386_elf_init_abi (info, gdbarch);
-
- /* FreeBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-
-/* FreeBSD 4.0-RELEASE or later. */
-
-/* From <machine/reg.h>. */
-static int i386fbsd4_r_reg_offset[] =
-{
- 10 * 4, 9 * 4, 8 * 4, 7 * 4, /* %eax, %ecx, %edx, %ebx */
- 16 * 4, 5 * 4, /* %esp, %ebp */
- 4 * 4, 3 * 4, /* %esi, %edi */
- 13 * 4, 15 * 4, /* %eip, %eflags */
- 14 * 4, 17 * 4, /* %cs, %ss */
- 2 * 4, 1 * 4, 0 * 4, 18 * 4 /* %ds, %es, %fs, %gs */
-};
-
-/* From <machine/signal.h>. */
-int i386fbsd4_sc_reg_offset[] =
-{
- 20 + 11 * 4, /* %eax */
- 20 + 10 * 4, /* %ecx */
- 20 + 9 * 4, /* %edx */
- 20 + 8 * 4, /* %ebx */
- 20 + 17 * 4, /* %esp */
- 20 + 6 * 4, /* %ebp */
- 20 + 5 * 4, /* %esi */
- 20 + 4 * 4, /* %edi */
- 20 + 14 * 4, /* %eip */
- 20 + 16 * 4, /* %eflags */
- 20 + 15 * 4, /* %cs */
- 20 + 18 * 4, /* %ss */
- 20 + 3 * 4, /* %ds */
- 20 + 2 * 4, /* %es */
- 20 + 1 * 4, /* %fs */
- 20 + 0 * 4 /* %gs */
-};
-
-static void
-i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Generic FreeBSD support. */
- fbsd_init_abi (info, gdbarch);
-
- /* Inherit stuff from older releases. We assume that FreeBSD
- 4.0-RELEASE always uses ELF. */
- i386fbsd_init_abi (info, gdbarch);
-
- /* FreeBSD 4.0 introduced a new `struct reg'. */
- tdep->gregset_reg_offset = i386fbsd4_r_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (i386fbsd4_r_reg_offset);
- tdep->sizeof_gregset = 19 * 4;
-
- /* FreeBSD 4.0 introduced a new `struct sigcontext'. */
- tdep->sc_reg_offset = i386fbsd4_sc_reg_offset;
- tdep->sc_num_regs = ARRAY_SIZE (i386fbsd4_sc_reg_offset);
-
- tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET;
-
- /* Iterate over core file register note sections. */
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, i386fbsd_iterate_over_regset_sections);
-
- set_gdbarch_core_read_description (gdbarch,
- i386fbsd_core_read_description);
-}
-
-\f
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_i386fbsd_tdep (void);
-
-void
-_initialize_i386fbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_AOUT,
- i386fbsdaout_init_abi);
- gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_ELF,
- i386fbsd4_init_abi);
-}
+++ /dev/null
-/* Target-dependent code for FreeBSD x86.
-
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef I386FBSD_TDEP_H
-#define I386FBSD_TDEP_H
-
-/* Get XSAVE extended state xcr0 from core dump. */
-extern uint64_t i386fbsd_core_read_xcr0 (bfd *abfd);
-
-/* The format of the XSAVE extended area is determined by hardware.
- Cores store the XSAVE extended area in a NT_X86_XSTATE note that
- matches the layout on Linux. */
-#define I386_FBSD_XSAVE_XCR0_OFFSET 464
-
-#endif /* i386fbsd-tdep.h */
+++ /dev/null
-/* Low level interface to i386 running the GNU Hurd.
-
- Copyright (C) 1992-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "x86-nat.h"
-#include "inferior.h"
-#include "floatformat.h"
-#include "regcache.h"
-
-#include <mach.h>
-#include <mach_error.h>
-#include <mach/message.h>
-#include <mach/exception.h>
-
-#include "i386-tdep.h"
-
-#include "gnu-nat.h"
-#include "inf-child.h"
-#include "i387-tdep.h"
-
-/* Offset to the thread_state_t location where REG is stored. */
-#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
-
-/* At REG_OFFSET[N] is the offset to the thread_state_t location where
- the GDB register N is stored. */
-static int reg_offset[] =
-{
- REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
- REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
- REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
- REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
-};
-
-#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
-
-\f
-/* Get the whole floating-point state of THREAD and record the values
- of the corresponding (pseudo) registers. */
-
-static void
-fetch_fpregs (struct regcache *regcache, struct proc *thread)
-{
- mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
- struct i386_float_state state;
- error_t err;
-
- err = thread_get_state (thread->port, i386_FLOAT_STATE,
- (thread_state_t) &state, &count);
- if (err)
- {
- warning (_("Couldn't fetch floating-point state from %s"),
- proc_string (thread));
- return;
- }
-
- if (!state.initialized)
- {
- /* The floating-point state isn't initialized. */
- i387_supply_fsave (regcache, -1, NULL);
- }
- else
- {
- /* Supply the floating-point registers. */
- i387_supply_fsave (regcache, -1, state.hw_state);
- }
-}
-
-/* Fetch register REGNO, or all regs if REGNO is -1. */
-static void
-gnu_fetch_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- struct proc *thread;
-
- /* Make sure we know about new threads. */
- inf_update_procs (gnu_current_inf);
-
- thread = inf_tid_to_thread (gnu_current_inf,
- ptid_get_lwp (inferior_ptid));
- if (!thread)
- error (_("Can't fetch registers from thread %s: No such thread"),
- target_pid_to_str (inferior_ptid));
-
- if (regno < I386_NUM_GREGS || regno == -1)
- {
- thread_state_t state;
-
- /* This does the dirty work for us. */
- state = proc_get_state (thread, 0);
- if (!state)
- {
- warning (_("Couldn't fetch registers from %s"),
- proc_string (thread));
- return;
- }
-
- if (regno == -1)
- {
- int i;
-
- proc_debug (thread, "fetching all register");
-
- for (i = 0; i < I386_NUM_GREGS; i++)
- regcache_raw_supply (regcache, i, REG_ADDR (state, i));
- thread->fetched_regs = ~0;
- }
- else
- {
- proc_debug (thread, "fetching register %s",
- gdbarch_register_name (get_regcache_arch (regcache),
- regno));
-
- regcache_raw_supply (regcache, regno,
- REG_ADDR (state, regno));
- thread->fetched_regs |= (1 << regno);
- }
- }
-
- if (regno >= I386_NUM_GREGS || regno == -1)
- {
- proc_debug (thread, "fetching floating-point registers");
-
- fetch_fpregs (regcache, thread);
- }
-}
-\f
-
-/* Store the whole floating-point state into THREAD using information
- from the corresponding (pseudo) registers. */
-static void
-store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
-{
- mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
- struct i386_float_state state;
- error_t err;
-
- err = thread_get_state (thread->port, i386_FLOAT_STATE,
- (thread_state_t) &state, &count);
- if (err)
- {
- warning (_("Couldn't fetch floating-point state from %s"),
- proc_string (thread));
- return;
- }
-
- /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
- take into account DEPRECATED_REGISTER_VALID like the old code did? */
- i387_collect_fsave (regcache, regno, state.hw_state);
-
- err = thread_set_state (thread->port, i386_FLOAT_STATE,
- (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
- if (err)
- {
- warning (_("Couldn't store floating-point state into %s"),
- proc_string (thread));
- return;
- }
-}
-
-/* Store at least register REGNO, or all regs if REGNO == -1. */
-static void
-gnu_store_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- struct proc *thread;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
-
- /* Make sure we know about new threads. */
- inf_update_procs (gnu_current_inf);
-
- thread = inf_tid_to_thread (gnu_current_inf,
- ptid_get_lwp (inferior_ptid));
- if (!thread)
- error (_("Couldn't store registers into thread %s: No such thread"),
- target_pid_to_str (inferior_ptid));
-
- if (regno < I386_NUM_GREGS || regno == -1)
- {
- thread_state_t state;
- thread_state_data_t old_state;
- int was_aborted = thread->aborted;
- int was_valid = thread->state_valid;
- int trace;
-
- if (!was_aborted && was_valid)
- memcpy (&old_state, &thread->state, sizeof (old_state));
-
- state = proc_get_state (thread, 1);
- if (!state)
- {
- warning (_("Couldn't store registers into %s"),
- proc_string (thread));
- return;
- }
-
- /* Save the T bit. We might try to restore the %eflags register
- below, but changing the T bit would seriously confuse GDB. */
- trace = ((struct i386_thread_state *)state)->efl & 0x100;
-
- if (!was_aborted && was_valid)
- /* See which registers have changed after aborting the thread. */
- {
- int check_regno;
-
- for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
- if ((thread->fetched_regs & (1 << check_regno))
- && memcpy (REG_ADDR (&old_state, check_regno),
- REG_ADDR (state, check_regno),
- register_size (gdbarch, check_regno)))
- /* Register CHECK_REGNO has changed! Ack! */
- {
- warning (_("Register %s changed after the thread was aborted"),
- gdbarch_register_name (gdbarch, check_regno));
- if (regno >= 0 && regno != check_regno)
- /* Update GDB's copy of the register. */
- regcache_raw_supply (regcache, check_regno,
- REG_ADDR (state, check_regno));
- else
- warning (_("... also writing this register! "
- "Suspicious..."));
- }
- }
-
- if (regno == -1)
- {
- int i;
-
- proc_debug (thread, "storing all registers");
-
- for (i = 0; i < I386_NUM_GREGS; i++)
- if (REG_VALID == regcache_register_status (regcache, i))
- regcache_raw_collect (regcache, i, REG_ADDR (state, i));
- }
- else
- {
- proc_debug (thread, "storing register %s",
- gdbarch_register_name (gdbarch, regno));
-
- gdb_assert (REG_VALID == regcache_register_status (regcache, regno));
- regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
- }
-
- /* Restore the T bit. */
- ((struct i386_thread_state *)state)->efl &= ~0x100;
- ((struct i386_thread_state *)state)->efl |= trace;
- }
-
- if (regno >= I386_NUM_GREGS || regno == -1)
- {
- proc_debug (thread, "storing floating-point registers");
-
- store_fpregs (regcache, thread, regno);
- }
-}
-
-\f
-/* Support for debug registers. */
-
-#ifdef i386_DEBUG_STATE
-/* Get debug registers for thread THREAD. */
-
-static void
-i386_gnu_dr_get (struct i386_debug_state *regs, struct proc *thread)
-{
- mach_msg_type_number_t count = i386_DEBUG_STATE_COUNT;
- error_t err;
-
- err = thread_get_state (thread->port, i386_DEBUG_STATE,
- (thread_state_t) regs, &count);
- if (err != 0 || count != i386_DEBUG_STATE_COUNT)
- warning (_("Couldn't fetch debug state from %s"),
- proc_string (thread));
-}
-
-/* Set debug registers for thread THREAD. */
-
-static void
-i386_gnu_dr_set (const struct i386_debug_state *regs, struct proc *thread)
-{
- error_t err;
-
- err = thread_set_state (thread->port, i386_DEBUG_STATE,
- (thread_state_t) regs, i386_DEBUG_STATE_COUNT);
- if (err != 0)
- warning (_("Couldn't store debug state into %s"),
- proc_string (thread));
-}
-
-/* Set DR_CONTROL in THREAD. */
-
-static void
-i386_gnu_dr_set_control_one (struct proc *thread, void *arg)
-{
- unsigned long *control = arg;
- struct i386_debug_state regs;
-
- i386_gnu_dr_get (®s, thread);
- regs.dr[DR_CONTROL] = *control;
- i386_gnu_dr_set (®s, thread);
-}
-
-/* Set DR_CONTROL to CONTROL in all threads. */
-
-static void
-i386_gnu_dr_set_control (unsigned long control)
-{
- inf_update_procs (gnu_current_inf);
- inf_threads (gnu_current_inf, i386_gnu_dr_set_control_one, &control);
-}
-
-/* Parameters to set a debugging address. */
-
-struct reg_addr
-{
- int regnum; /* Register number (zero based). */
- CORE_ADDR addr; /* Address. */
-};
-
-/* Set address REGNUM (zero based) to ADDR in THREAD. */
-
-static void
-i386_gnu_dr_set_addr_one (struct proc *thread, void *arg)
-{
- struct reg_addr *reg_addr = arg;
- struct i386_debug_state regs;
-
- i386_gnu_dr_get (®s, thread);
- regs.dr[reg_addr->regnum] = reg_addr->addr;
- i386_gnu_dr_set (®s, thread);
-}
-
-/* Set address REGNUM (zero based) to ADDR in all threads. */
-
-static void
-i386_gnu_dr_set_addr (int regnum, CORE_ADDR addr)
-{
- struct reg_addr reg_addr;
-
- gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
-
- reg_addr.regnum = regnum;
- reg_addr.addr = addr;
-
- inf_update_procs (gnu_current_inf);
- inf_threads (gnu_current_inf, i386_gnu_dr_set_addr_one, ®_addr);
-}
-
-/* Get debug register REGNUM value from only the one LWP of PTID. */
-
-static unsigned long
-i386_gnu_dr_get_reg (ptid_t ptid, int regnum)
-{
- struct i386_debug_state regs;
- struct proc *thread;
-
- /* Make sure we know about new threads. */
- inf_update_procs (gnu_current_inf);
-
- thread = inf_tid_to_thread (gnu_current_inf, ptid_get_lwp (ptid));
- i386_gnu_dr_get (®s, thread);
-
- return regs.dr[regnum];
-}
-
-/* Return the inferior's debug register REGNUM. */
-
-static CORE_ADDR
-i386_gnu_dr_get_addr (int regnum)
-{
- gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
-
- return i386_gnu_dr_get_reg (inferior_ptid, regnum);
-}
-
-/* Get DR_STATUS from only the one thread of INFERIOR_PTID. */
-
-static unsigned long
-i386_gnu_dr_get_status (void)
-{
- return i386_gnu_dr_get_reg (inferior_ptid, DR_STATUS);
-}
-
-/* Return the inferior's DR7 debug control register. */
-
-static unsigned long
-i386_gnu_dr_get_control (void)
-{
- return i386_gnu_dr_get_reg (inferior_ptid, DR_CONTROL);
-}
-#endif /* i386_DEBUG_STATE */
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_i386gnu_nat;
-
-void
-_initialize_i386gnu_nat (void)
-{
- struct target_ops *t;
-
- /* Fill in the generic GNU/Hurd methods. */
- t = gnu_target ();
-
-#ifdef i386_DEBUG_STATE
- x86_use_watchpoints (t);
-
- x86_dr_low.set_control = i386_gnu_dr_set_control;
- gdb_assert (DR_FIRSTADDR == 0 && DR_LASTADDR < i386_DEBUG_STATE_COUNT);
- x86_dr_low.set_addr = i386_gnu_dr_set_addr;
- x86_dr_low.get_addr = i386_gnu_dr_get_addr;
- x86_dr_low.get_status = i386_gnu_dr_get_status;
- x86_dr_low.get_control = i386_gnu_dr_get_control;
- x86_set_debug_register_length (4);
-#endif /* i386_DEBUG_STATE */
-
- t->to_fetch_registers = gnu_fetch_registers;
- t->to_store_registers = gnu_store_registers;
-
- /* Register the target. */
- add_target (t);
-}
+++ /dev/null
-/* Target-dependent code for the GNU Hurd.
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "osabi.h"
-#include "solib-svr4.h"
-
-#include "i386-tdep.h"
-
-/* From <sys/ucontext.h>. */
-static int i386gnu_gregset_reg_offset[] =
-{
- 11 * 4, /* %eax */
- 10 * 4, /* %ecx */
- 9 * 4, /* %edx */
- 8 * 4, /* %ebx */
- 17 * 4, /* %uesp */
- 6 * 4, /* %ebp */
- 5 * 4, /* %esi */
- 4 * 4, /* %edi */
- 14 * 4, /* %eip */
- 16 * 4, /* %efl */
- 15 * 4, /* %cs */
- 18 * 4, /* %ss */
- 3 * 4, /* %ds */
- 2 * 4, /* %es */
- 1 * 4, /* %fs */
- 0 * 4, /* %gs */
-};
-
-static void
-i386gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* GNU uses ELF. */
- i386_elf_init_abi (info, gdbarch);
-
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
- tdep->gregset_reg_offset = i386gnu_gregset_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (i386gnu_gregset_reg_offset);
- tdep->sizeof_gregset = 19 * 4;
-
- tdep->jb_pc_offset = 20; /* From <bits/setjmp.h>. */
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern void _initialize_i386gnu_tdep (void);
-
-void
-_initialize_i386gnu_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_HURD, i386gnu_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for NetBSD/i386.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "target.h"
-
-#include "i386-tdep.h"
-#include "i386bsd-nat.h"
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/types.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-
-#include "nbsd-nat.h"
-#include "bsd-kvm.h"
-
-static int
-i386nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- struct switchframe sf;
-
- /* The following is true for NetBSD 1.6.2:
-
- The pcb contains %esp and %ebp at the point of the context switch
- in cpu_switch(). At that point we have a stack frame as
- described by `struct switchframe', which for NetBSD 1.6.2 has the
- following layout:
-
- interrupt level
- %edi
- %esi
- %ebx
- %eip
-
- we reconstruct the register state as it would look when we just
- returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_esp == 0)
- return 0;
-
- read_memory (pcb->pcb_esp, (gdb_byte *)&sf, sizeof sf);
- pcb->pcb_esp += sizeof (struct switchframe);
- regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi);
- regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi);
- regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
- regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
- regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx);
- regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip);
-
- return 1;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_i386nbsd_nat (void);
-
-void
-_initialize_i386nbsd_nat (void)
-{
- struct target_ops *t;
-
- /* Add some extra features to the common *BSD/i386 target. */
- t = i386bsd_target ();
- t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
- add_target (t);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (i386nbsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/i386.
-
- Copyright (C) 1988-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "regset.h"
-#include "osabi.h"
-#include "symtab.h"
-#include "trad-frame.h"
-#include "tramp-frame.h"
-
-#include "i386-tdep.h"
-#include "i387-tdep.h"
-#include "nbsd-tdep.h"
-#include "solib-svr4.h"
-
-/* From <machine/reg.h>. */
-static int i386nbsd_r_reg_offset[] =
-{
- 0 * 4, /* %eax */
- 1 * 4, /* %ecx */
- 2 * 4, /* %edx */
- 3 * 4, /* %ebx */
- 4 * 4, /* %esp */
- 5 * 4, /* %ebp */
- 6 * 4, /* %esi */
- 7 * 4, /* %edi */
- 8 * 4, /* %eip */
- 9 * 4, /* %eflags */
- 10 * 4, /* %cs */
- 11 * 4, /* %ss */
- 12 * 4, /* %ds */
- 13 * 4, /* %es */
- 14 * 4, /* %fs */
- 15 * 4 /* %gs */
-};
-
-/* From <machine/signal.h>. */
-int i386nbsd_sc_reg_offset[] =
-{
- 10 * 4, /* %eax */
- 9 * 4, /* %ecx */
- 8 * 4, /* %edx */
- 7 * 4, /* %ebx */
- 14 * 4, /* %esp */
- 6 * 4, /* %ebp */
- 5 * 4, /* %esi */
- 4 * 4, /* %edi */
- 11 * 4, /* %eip */
- 13 * 4, /* %eflags */
- 12 * 4, /* %cs */
- 15 * 4, /* %ss */
- 3 * 4, /* %ds */
- 2 * 4, /* %es */
- 1 * 4, /* %fs */
- 0 * 4 /* %gs */
-};
-
-/* From <machine/mcontext.h>. */
-int i386nbsd_mc_reg_offset[] =
-{
- 11 * 4, /* %eax */
- 10 * 4, /* %ecx */
- 9 * 4, /* %edx */
- 8 * 4, /* %ebx */
- 7 * 4, /* %esp */
- 6 * 4, /* %ebp */
- 5 * 4, /* %esi */
- 4 * 4, /* %edi */
- 14 * 4, /* %eip */
- 16 * 4, /* %eflags */
- 15 * 4, /* %cs */
- 18 * 4, /* %ss */
- 3 * 4, /* %ds */
- 2 * 4, /* %es */
- 1 * 4, /* %fs */
- 0 * 4 /* %gs */
-};
-
-static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *,
- struct frame_info *,
- struct trad_frame_cache *,
- CORE_ADDR);
-
-static const struct tramp_frame i386nbsd_sigtramp_sc16 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x10, -1 },
- /* leal 0x10(%esp), %eax */
- { 0x50, -1 }, /* pushl %eax */
- { 0x50, -1 }, /* pushl %eax */
- { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
- /* movl $0x127, %eax # __sigreturn14 */
- { 0xcd, -1 }, { 0x80, -1},
- /* int $0x80 */
- { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
- /* movl $0x1, %eax # exit */
- { 0xcd, -1 }, { 0x80, -1},
- /* int $0x80 */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static const struct tramp_frame i386nbsd_sigtramp_sc2 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x0c, -1 },
- /* leal 0x0c(%esp), %eax */
- { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
- /* movl %eax, 0x4(%esp) */
- { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
- /* movl $0x127, %eax # __sigreturn14 */
- { 0xcd, -1 }, { 0x80, -1},
- /* int $0x80 */
- { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
- /* movl %eax, 0x4(%esp) */
- { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
- /* movl $0x1, %eax */
- { 0xcd, -1 }, { 0x80, -1},
- /* int $0x80 */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static const struct tramp_frame i386nbsd_sigtramp_si2 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- { 0x8b, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x08, -1 },
- /* movl 8(%esp),%eax */
- { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
- /* movl %eax, 0x4(%esp) */
- { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
- /* movl $0x134, %eax # setcontext */
- { 0xcd, -1 }, { 0x80, -1 },
- /* int $0x80 */
- { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
- /* movl %eax, 0x4(%esp) */
- { 0xb8, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
- /* movl $0x1, %eax */
- { 0xcd, -1 }, { 0x80, -1 },
- /* int $0x80 */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static const struct tramp_frame i386nbsd_sigtramp_si31 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
- { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
- /* leal 0x8c(%esp), %eax */
- { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
- /* movl %eax, 0x4(%esp) */
- { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
- /* movl $0x134, %eax # setcontext */
- { 0xcd, -1 }, { 0x80, -1},
- /* int $0x80 */
- { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
- /* movl %eax, 0x4(%esp) */
- { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
- /* movl $0x1, %eax */
- { 0xcd, -1 }, { 0x80, -1},
- /* int $0x80 */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static const struct tramp_frame i386nbsd_sigtramp_si4 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
- { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
- /* leal 0x8c(%esp), %eax */
- { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
- /* movl %eax, 0x4(%esp) */
- { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
- /* movl $0x134, %eax # setcontext */
- { 0xcd, -1 }, { 0x80, -1},
- /* int $0x80 */
- { 0xc7, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
- { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 },
- /* movl $0xffffffff,0x4(%esp) */
- { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
- /* movl $0x1, %eax */
- { 0xcd, -1 }, { 0x80, -1},
- /* int $0x80 */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static void
-i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
- CORE_ADDR base;
- int *reg_offset;
- int num_regs;
- int i;
-
- if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2)
- {
- reg_offset = i386nbsd_sc_reg_offset;
- num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
-
- /* Read in the sigcontext address. */
- base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
- }
- else
- {
- reg_offset = i386nbsd_mc_reg_offset;
- num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset);
-
- /* Read in the ucontext address. */
- base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
- /* offsetof(ucontext_t, uc_mcontext) == 36 */
- base += 36;
- }
-
- for (i = 0; i < num_regs; i++)
- if (reg_offset[i] != -1)
- trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (this_cache, frame_id_build (sp, func));
-}
-\f
-
-static void
-i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Obviously NetBSD is BSD-based. */
- i386bsd_init_abi (info, gdbarch);
-
- /* NetBSD has a different `struct reg'. */
- tdep->gregset_reg_offset = i386nbsd_r_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (i386nbsd_r_reg_offset);
- tdep->sizeof_gregset = 16 * 4;
-
- /* NetBSD uses -freg-struct-return by default. */
- tdep->struct_return = reg_struct_return;
-
- /* NetBSD uses tramp_frame sniffers for signal trampolines. */
- tdep->sigcontext_addr= 0;
- tdep->sigtramp_start = 0;
- tdep->sigtramp_end = 0;
- tdep->sigtramp_p = 0;
- tdep->sc_reg_offset = 0;
- tdep->sc_num_regs = 0;
-
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc16);
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc2);
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si2);
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si31);
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si4);
-}
-
-/* NetBSD ELF. */
-
-static void
-i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* It's still NetBSD. */
- i386nbsd_init_abi (info, gdbarch);
-
- /* But ELF-based. */
- i386_elf_init_abi (info, gdbarch);
-
- /* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
- /* NetBSD ELF uses -fpcc-struct-return by default. */
- tdep->struct_return = pcc_struct_return;
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_i386nbsd_tdep;
-
-void
-_initialize_i386nbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD_ELF,
- i386nbsdelf_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for OpenBSD/i386.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "target.h"
-
-#include <sys/sysctl.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-
-#include "i386-tdep.h"
-#include "i386bsd-nat.h"
-#include "obsd-nat.h"
-#include "bsd-kvm.h"
-
-static int
-i386obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct switchframe sf;
-
- /* The following is true for OpenBSD 3.6:
-
- The pcb contains %esp and %ebp at the point of the context switch
- in cpu_switch(). At that point we have a stack frame as
- described by `struct switchframe', which for OpenBSD 3.6 has the
- following layout:
-
- interrupt level
- %edi
- %esi
- %ebx
- %eip
-
- we reconstruct the register state as it would look when we just
- returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_esp == 0)
- return 0;
-
- /* Read the stack frame, and check its validity. We do this by
- checking if the saved interrupt priority level in the stack frame
- looks reasonable.. */
-#ifdef PCB_SAVECTX
- if ((pcb->pcb_flags & PCB_SAVECTX) == 0)
- {
- /* Yes, we have a frame that matches cpu_switch(). */
- read_memory (pcb->pcb_esp, (gdb_byte *) &sf, sizeof sf);
- pcb->pcb_esp += sizeof (struct switchframe);
- regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi);
- regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi);
- regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx);
- regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip);
- }
- else
-#endif
- {
- /* No, the pcb must have been last updated by savectx(). */
- pcb->pcb_esp = pcb->pcb_ebp;
- pcb->pcb_ebp = read_memory_integer(pcb->pcb_esp, 4, byte_order);
- sf.sf_eip = read_memory_integer(pcb->pcb_esp + 4, 4, byte_order);
- regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip);
- }
-
- regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
- regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
-
- return 1;
-}
-\f
-
-/* Prevent warning from -Wmissing-prototypes. */
-void _initialize_i386obsd_nat (void);
-
-void
-_initialize_i386obsd_nat (void)
-{
- /* Add some extra features to the common *BSD/i386 target. */
- obsd_add_target (i386bsd_target ());
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (i386obsd_supply_pcb);
-
- /* OpenBSD provides a vm.psstrings sysctl that we can use to locate
- the sigtramp. That way we can still recognize a sigtramp if its
- location is changed in a new kernel. This is especially
- important for OpenBSD, since it uses a different memory layout
- than NetBSD, yet we cannot distinguish between the two.
-
- Of course this is still based on the assumption that the sigtramp
- is placed directly under the location where the program arguments
- and environment can be found. */
-#ifdef VM_PSSTRINGS
- {
- struct _ps_strings _ps;
- int mib[2];
- size_t len;
-
- mib[0] = CTL_VM;
- mib[1] = VM_PSSTRINGS;
- len = sizeof (_ps);
- if (sysctl (mib, 2, &_ps, &len, NULL, 0) == 0)
- {
- i386obsd_sigtramp_start_addr = (u_long) _ps.val - 128;
- i386obsd_sigtramp_end_addr = (u_long) _ps.val;
- }
- }
-#endif
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/i386.
-
- Copyright (C) 1988-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "regset.h"
-#include "symtab.h"
-#include "objfiles.h"
-#include "osabi.h"
-#include "target.h"
-#include "trad-frame.h"
-
-#include "obsd-tdep.h"
-#include "i386-tdep.h"
-#include "i387-tdep.h"
-#include "solib-svr4.h"
-#include "bsd-uthread.h"
-
-/* Support for signal handlers. */
-
-/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
- in virtual memory. The randomness makes it somewhat tricky to
- detect it, but fortunately we can rely on the fact that the start
- of the sigtramp routine is page-aligned. We recognize the
- trampoline by looking for the code that invokes the sigreturn
- system call. The offset where we can find that code varies from
- release to release.
-
- By the way, the mapping mentioned above is read-only, so you cannot
- place a breakpoint in the signal trampoline. */
-
-/* Default page size. */
-static const int i386obsd_page_size = 4096;
-
-/* Offset for sigreturn(2). */
-static const int i386obsd_sigreturn_offset[] = {
- 0x0a, /* OpenBSD 3.2 */
- 0x14, /* OpenBSD 3.6 */
- 0x3a, /* OpenBSD 3.8 */
- -1
-};
-
-/* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp
- routine. */
-
-static int
-i386obsd_sigtramp_p (struct frame_info *this_frame)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
- /* The call sequence invoking sigreturn(2). */
- const gdb_byte sigreturn[] =
- {
- 0xb8,
- 0x67, 0x00, 0x00, 0x00, /* movl $SYS_sigreturn, %eax */
- 0xcd, 0x80 /* int $0x80 */
- };
- size_t buflen = sizeof sigreturn;
- const int *offset;
- gdb_byte *buf;
- const char *name;
-
- /* If the function has a valid symbol name, it isn't a
- trampoline. */
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (name != NULL)
- return 0;
-
- /* If the function lives in a valid section (even without a starting
- point) it isn't a trampoline. */
- if (find_pc_section (pc) != NULL)
- return 0;
-
- /* Allocate buffer. */
- buf = (gdb_byte *) alloca (buflen);
-
- /* Loop over all offsets. */
- for (offset = i386obsd_sigreturn_offset; *offset != -1; offset++)
- {
- /* If we can't read the instructions, return zero. */
- if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
- buf, buflen))
- return 0;
-
- /* Check for sigreturn(2). */
- if (memcmp (buf, sigreturn, buflen) == 0)
- return 1;
- }
-
- return 0;
-}
-\f
-/* Mapping between the general-purpose registers in `struct reg'
- format and GDB's register cache layout. */
-
-/* From <machine/reg.h>. */
-static int i386obsd_r_reg_offset[] =
-{
- 0 * 4, /* %eax */
- 1 * 4, /* %ecx */
- 2 * 4, /* %edx */
- 3 * 4, /* %ebx */
- 4 * 4, /* %esp */
- 5 * 4, /* %ebp */
- 6 * 4, /* %esi */
- 7 * 4, /* %edi */
- 8 * 4, /* %eip */
- 9 * 4, /* %eflags */
- 10 * 4, /* %cs */
- 11 * 4, /* %ss */
- 12 * 4, /* %ds */
- 13 * 4, /* %es */
- 14 * 4, /* %fs */
- 15 * 4 /* %gs */
-};
-
-static void
-i386obsd_aout_supply_regset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *regs, size_t len)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- const gdb_byte *gregs = (const gdb_byte *) regs;
-
- gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE);
-
- i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
- i387_supply_fsave (regcache, regnum, gregs + tdep->sizeof_gregset);
-}
-
-static const struct regset i386obsd_aout_gregset =
- {
- NULL, i386obsd_aout_supply_regset, NULL
- };
-
-static void
-i386obsd_aout_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* OpenBSD a.out core dumps don't use seperate register sets for the
- general-purpose and floating-point registers. */
-
- cb (".reg", tdep->sizeof_gregset + I387_SIZEOF_FSAVE,
- &i386obsd_aout_gregset, NULL, cb_data);
-}
-\f
-
-/* Sigtramp routine location for OpenBSD 3.1 and earlier releases. */
-CORE_ADDR i386obsd_sigtramp_start_addr = 0xbfbfdf20;
-CORE_ADDR i386obsd_sigtramp_end_addr = 0xbfbfdff0;
-
-/* From <machine/signal.h>. */
-int i386obsd_sc_reg_offset[I386_NUM_GREGS] =
-{
- 10 * 4, /* %eax */
- 9 * 4, /* %ecx */
- 8 * 4, /* %edx */
- 7 * 4, /* %ebx */
- 14 * 4, /* %esp */
- 6 * 4, /* %ebp */
- 5 * 4, /* %esi */
- 4 * 4, /* %edi */
- 11 * 4, /* %eip */
- 13 * 4, /* %eflags */
- 12 * 4, /* %cs */
- 15 * 4, /* %ss */
- 3 * 4, /* %ds */
- 2 * 4, /* %es */
- 1 * 4, /* %fs */
- 0 * 4 /* %gs */
-};
-
-/* From /usr/src/lib/libpthread/arch/i386/uthread_machdep.c. */
-static int i386obsd_uthread_reg_offset[] =
-{
- 11 * 4, /* %eax */
- 10 * 4, /* %ecx */
- 9 * 4, /* %edx */
- 8 * 4, /* %ebx */
- -1, /* %esp */
- 6 * 4, /* %ebp */
- 5 * 4, /* %esi */
- 4 * 4, /* %edi */
- 12 * 4, /* %eip */
- -1, /* %eflags */
- 13 * 4, /* %cs */
- -1, /* %ss */
- 3 * 4, /* %ds */
- 2 * 4, /* %es */
- 1 * 4, /* %fs */
- 0 * 4 /* %gs */
-};
-
-/* Offset within the thread structure where we can find the saved
- stack pointer (%esp). */
-#define I386OBSD_UTHREAD_ESP_OFFSET 176
-
-static void
-i386obsd_supply_uthread (struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
- CORE_ADDR sp = 0;
- gdb_byte buf[4];
- int i;
-
- gdb_assert (regnum >= -1);
-
- if (regnum == -1 || regnum == I386_ESP_REGNUM)
- {
- int offset;
-
- /* Fetch stack pointer from thread structure. */
- sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
-
- /* Adjust the stack pointer such that it looks as if we just
- returned from _thread_machdep_switch. */
- offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4;
- store_unsigned_integer (buf, 4, byte_order, sp + offset);
- regcache_raw_supply (regcache, I386_ESP_REGNUM, buf);
- }
-
- for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
- {
- if (i386obsd_uthread_reg_offset[i] != -1
- && (regnum == -1 || regnum == i))
- {
- /* Fetch stack pointer from thread structure (if we didn't
- do so already). */
- if (sp == 0)
- sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
-
- /* Read the saved register from the stack frame. */
- read_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
- regcache_raw_supply (regcache, i, buf);
- }
- }
-}
-
-static void
-i386obsd_collect_uthread (const struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
- CORE_ADDR sp = 0;
- gdb_byte buf[4];
- int i;
-
- gdb_assert (regnum >= -1);
-
- if (regnum == -1 || regnum == I386_ESP_REGNUM)
- {
- int offset;
-
- /* Calculate the stack pointer (frame pointer) that will be
- stored into the thread structure. */
- offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4;
- regcache_raw_collect (regcache, I386_ESP_REGNUM, buf);
- sp = extract_unsigned_integer (buf, 4, byte_order) - offset;
-
- /* Store the stack pointer. */
- write_memory_unsigned_integer (sp_addr, 4, byte_order, sp);
-
- /* The stack pointer was (potentially) modified. Make sure we
- build a proper stack frame. */
- regnum = -1;
- }
-
- for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
- {
- if (i386obsd_uthread_reg_offset[i] != -1
- && (regnum == -1 || regnum == i))
- {
- /* Fetch stack pointer from thread structure (if we didn't
- calculate it already). */
- if (sp == 0)
- sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
-
- /* Write the register into the stack frame. */
- regcache_raw_collect (regcache, i, buf);
- write_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
- }
- }
-}
-\f
-/* Kernel debugging support. */
-
-/* From <machine/frame.h>. Note that %esp and %ess are only saved in
- a trap frame when entering the kernel from user space. */
-static int i386obsd_tf_reg_offset[] =
-{
- 10 * 4, /* %eax */
- 9 * 4, /* %ecx */
- 8 * 4, /* %edx */
- 7 * 4, /* %ebx */
- -1, /* %esp */
- 6 * 4, /* %ebp */
- 5 * 4, /* %esi */
- 4 * 4, /* %edi */
- 13 * 4, /* %eip */
- 15 * 4, /* %eflags */
- 14 * 4, /* %cs */
- -1, /* %ss */
- 3 * 4, /* %ds */
- 2 * 4, /* %es */
- 0 * 4, /* %fs */
- 1 * 4 /* %gs */
-};
-
-static struct trad_frame_cache *
-i386obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct trad_frame_cache *cache;
- CORE_ADDR func, sp, addr;
- ULONGEST cs;
- const char *name;
- int i;
-
- if (*this_cache)
- return (struct trad_frame_cache *) *this_cache;
-
- cache = trad_frame_cache_zalloc (this_frame);
- *this_cache = cache;
-
- func = get_frame_func (this_frame);
- sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
-
- find_pc_partial_function (func, &name, NULL, NULL);
- if (name && startswith (name, "Xintr"))
- addr = sp + 8; /* It's an interrupt frame. */
- else
- addr = sp;
-
- for (i = 0; i < ARRAY_SIZE (i386obsd_tf_reg_offset); i++)
- if (i386obsd_tf_reg_offset[i] != -1)
- trad_frame_set_reg_addr (cache, i, addr + i386obsd_tf_reg_offset[i]);
-
- /* Read %cs from trap frame. */
- addr += i386obsd_tf_reg_offset[I386_CS_REGNUM];
- cs = read_memory_unsigned_integer (addr, 4, byte_order);
- if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
- {
- /* Trap from user space; terminate backtrace. */
- trad_frame_set_id (cache, outer_frame_id);
- }
- else
- {
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (cache, frame_id_build (sp + 8, func));
- }
-
- return cache;
-}
-
-static void
-i386obsd_trapframe_this_id (struct frame_info *this_frame,
- void **this_cache, struct frame_id *this_id)
-{
- struct trad_frame_cache *cache =
- i386obsd_trapframe_cache (this_frame, this_cache);
-
- trad_frame_get_id (cache, this_id);
-}
-
-static struct value *
-i386obsd_trapframe_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct trad_frame_cache *cache =
- i386obsd_trapframe_cache (this_frame, this_cache);
-
- return trad_frame_get_register (cache, this_frame, regnum);
-}
-
-static int
-i386obsd_trapframe_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_prologue_cache)
-{
- ULONGEST cs;
- const char *name;
-
- /* Check Current Privilege Level and bail out if we're not executing
- in kernel space. */
- cs = get_frame_register_unsigned (this_frame, I386_CS_REGNUM);
- if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
- return 0;
-
- find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
- return (name && (strcmp (name, "calltrap") == 0
- || strcmp (name, "syscall1") == 0
- || startswith (name, "Xintr")
- || startswith (name, "Xsoft")));
-}
-
-static const struct frame_unwind i386obsd_trapframe_unwind = {
- /* FIXME: kettenis/20051219: This really is more like an interrupt
- frame, but SIGTRAMP_FRAME would print <signal handler called>,
- which really is not what we want here. */
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- i386obsd_trapframe_this_id,
- i386obsd_trapframe_prev_register,
- NULL,
- i386obsd_trapframe_sniffer
-};
-\f
-
-static void
-i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Obviously OpenBSD is BSD-based. */
- i386bsd_init_abi (info, gdbarch);
- obsd_init_abi (info, gdbarch);
-
- /* OpenBSD has a different `struct reg'. */
- tdep->gregset_reg_offset = i386obsd_r_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset);
- tdep->sizeof_gregset = 16 * 4;
-
- /* OpenBSD uses -freg-struct-return by default. */
- tdep->struct_return = reg_struct_return;
-
- /* OpenBSD uses a different memory layout. */
- tdep->sigtramp_start = i386obsd_sigtramp_start_addr;
- tdep->sigtramp_end = i386obsd_sigtramp_end_addr;
- tdep->sigtramp_p = i386obsd_sigtramp_p;
-
- /* OpenBSD has a `struct sigcontext' that's different from the
- original 4.3 BSD. */
- tdep->sc_reg_offset = i386obsd_sc_reg_offset;
- tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset);
-
- /* OpenBSD provides a user-level threads implementation. */
- bsd_uthread_set_supply_uthread (gdbarch, i386obsd_supply_uthread);
- bsd_uthread_set_collect_uthread (gdbarch, i386obsd_collect_uthread);
-
- /* Unwind kernel trap frames correctly. */
- frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind);
-}
-
-/* OpenBSD a.out. */
-
-static void
-i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- i386obsd_init_abi (info, gdbarch);
-
- /* OpenBSD a.out has a single register set. */
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, i386obsd_aout_iterate_over_regset_sections);
-}
-
-/* OpenBSD ELF. */
-
-static void
-i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- /* It's still OpenBSD. */
- i386obsd_init_abi (info, gdbarch);
-
- /* But ELF-based. */
- i386_elf_init_abi (info, gdbarch);
-
- /* OpenBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_i386obsd_tdep (void);
-
-void
-_initialize_i386obsd_tdep (void)
-{
- /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are
- indistingushable from NetBSD/i386 a.out binaries, building a GDB
- that should support both these targets will probably not work as
- expected. */
-#define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT
-
- gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT,
- i386obsd_aout_init_abi);
- gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF,
- i386obsd_elf_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for Unix SVR4 running on i386's.
-
- Copyright (C) 1988-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "value.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#ifdef HAVE_SYS_REG_H
-#include <sys/reg.h>
-#endif
-
-#include "i386-tdep.h"
-#include "i387-tdep.h"
-
-#ifdef HAVE_SYS_PROCFS_H
-
-#include <sys/procfs.h>
-
-/* We must not compile this code for 64-bit Solaris x86. */
-#if !defined (PR_MODEL_NATIVE) || (PR_MODEL_NATIVE == PR_MODEL_ILP32)
-
-#include "gregset.h"
-
-/* The `/proc' interface divides the target machine's register set up
- into two different sets, the general purpose register set (gregset)
- and the floating-point register set (fpregset). For each set,
- there is an ioctl to get the current register set and another ioctl
- to set the current values.
-
- The actual structure passed through the ioctl interface is, of
- course, naturally machine dependent, and is different for each set
- of registers. For the i386 for example, the general-purpose
- register set is typically defined by:
-
- typedef int gregset_t[19]; (in <sys/regset.h>)
-
- #define GS 0 (in <sys/reg.h>)
- #define FS 1
- ...
- #define UESP 17
- #define SS 18
-
- and the floating-point set by:
-
- typedef struct fpregset {
- union {
- struct fpchip_state // fp extension state //
- {
- int state[27]; // 287/387 saved state //
- int status; // status word saved at //
- // exception //
- } fpchip_state;
- struct fp_emul_space // for emulators //
- {
- char fp_emul[246];
- char fp_epad[2];
- } fp_emul_space;
- int f_fpregs[62]; // union of the above //
- } fp_reg_set;
- long f_wregs[33]; // saved weitek state //
- } fpregset_t;
-
- Incidentally fpchip_state contains the FPU state in the same format
- as used by the "fsave" instruction, and that's the only thing we
- support here. I don't know how the emulator stores it state. The
- Weitek stuff definitely isn't supported.
-
- The routines defined here, provide the packing and unpacking of
- gregset_t and fpregset_t formatted data. */
-
-#ifdef HAVE_GREGSET_T
-
-/* Mapping between the general-purpose registers in `/proc'
- format and GDB's register array layout. */
-static int regmap[] =
-{
- EAX, ECX, EDX, EBX,
- UESP, EBP, ESI, EDI,
- EIP, EFL, CS, SS,
- DS, ES, FS, GS
-};
-
-/* Fill GDB's register array with the general-purpose register values
- in *GREGSETP. */
-
-void
-supply_gregset (struct regcache *regcache, const gregset_t *gregsetp)
-{
- const greg_t *regp = (const greg_t *) gregsetp;
- int regnum;
-
- for (regnum = 0; regnum < I386_NUM_GREGS; regnum++)
- regcache_raw_supply (regcache, regnum, regp + regmap[regnum]);
-}
-
-/* Fill register REGNUM (if it is a general-purpose register) in
- *GREGSETPS with the value in GDB's register array. If REGNUM is -1,
- do this for all registers. */
-
-void
-fill_gregset (const struct regcache *regcache,
- gregset_t *gregsetp, int regnum)
-{
- greg_t *regp = (greg_t *) gregsetp;
- int i;
-
- for (i = 0; i < I386_NUM_GREGS; i++)
- if (regnum == -1 || regnum == i)
- regcache_raw_collect (regcache, i, regp + regmap[i]);
-}
-
-#endif /* HAVE_GREGSET_T */
-
-#ifdef HAVE_FPREGSET_T
-
-/* Fill GDB's register array with the floating-point register values in
- *FPREGSETP. */
-
-void
-supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
-{
- if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) == 0)
- return;
-
- i387_supply_fsave (regcache, -1, fpregsetp);
-}
-
-/* Fill register REGNO (if it is a floating-point register) in
- *FPREGSETP with the value in GDB's register array. If REGNO is -1,
- do this for all registers. */
-
-void
-fill_fpregset (const struct regcache *regcache,
- fpregset_t *fpregsetp, int regno)
-{
- if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) == 0)
- return;
-
- i387_collect_fsave (regcache, regno, fpregsetp);
-}
-
-#endif /* HAVE_FPREGSET_T */
-
-#endif /* not 64-bit. */
-
-#endif /* HAVE_SYS_PROCFS_H */
--- /dev/null
+/* Native-dependent code for Motorola 68000 BSD's.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "m68k-tdep.h"
+#include "inf-ptrace.h"
+
+static int
+m68kbsd_gregset_supplies_p (int regnum)
+{
+ return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM);
+}
+
+static int
+m68kbsd_fpregset_supplies_p (int regnum)
+{
+ return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ int regnum;
+
+ for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
+
+static void
+m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ const char *regs = fpregs;
+ int regnum;
+
+ for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum,
+ regs + m68kbsd_fpreg_offset (gdbarch, regnum));
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+m68kbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 4);
+ }
+}
+
+/* Collect the floating-point registers from REGCACHE and store them
+ in FPREGS. */
+
+static void
+m68kbsd_collect_fpregset (struct regcache *regcache,
+ void *fpregs, int regnum)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ char *regs = fpregs;
+ int i;
+
+ for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i,
+ regs + m68kbsd_fpreg_offset (gdbarch, i));
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating-point registers). */
+
+static void
+m68kbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ m68kbsd_supply_gregset (regcache, ®s);
+ }
+
+ if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ m68kbsd_supply_fpregset (regcache, &fpregs);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating-point registers). */
+
+static void
+m68kbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ m68kbsd_collect_gregset (regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+ }
+
+ if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ m68kbsd_collect_fpregset (regcache, &fpregs, regnum);
+
+ if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+ }
+}
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+/* OpenBSD doesn't have these. */
+#ifndef PCB_REGS_FP
+#define PCB_REGS_FP 10
+#endif
+#ifndef PCB_REGS_SP
+#define PCB_REGS_SP 11
+#endif
+
+static int
+m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ int regnum, tmp;
+ int i = 0;
+
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for
+ all callee-saved registers. From this information we reconstruct
+ the register state as it would look when we just returned from
+ cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_regs[PCB_REGS_SP] == 0)
+ return 0;
+
+ for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
+ for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
+
+ tmp = pcb->pcb_ps & 0xffff;
+ regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp);
+
+ read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp);
+ regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_m68kbsd_nat (void);
+
+void
+_initialize_m68kbsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = m68kbsd_fetch_inferior_registers;
+ t->to_store_registers = m68kbsd_store_inferior_registers;
+ add_target (t);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (m68kbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for Motorola 68000 BSD's.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+#include "gdbtypes.h"
+
+#include "m68k-tdep.h"
+#include "solib-svr4.h"
+
+/* Core file support. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define M68KBSD_SIZEOF_GREGS (18 * 4)
+
+/* Sizeof `struct fpreg' in <machine/reg.h. */
+#define M68KBSD_SIZEOF_FPREGS (((8 * 3) + 3) * 4)
+
+int
+m68kbsd_fpreg_offset (struct gdbarch *gdbarch, int regnum)
+{
+ int fp_len = TYPE_LENGTH (gdbarch_register_type (gdbarch, regnum));
+
+ if (regnum >= M68K_FPC_REGNUM)
+ return 8 * fp_len + (regnum - M68K_FPC_REGNUM) * 4;
+
+ return (regnum - M68K_FP0_REGNUM) * fp_len;
+}
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+m68kbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ const gdb_byte *regs = (const gdb_byte *) fpregs;
+ int i;
+
+ gdb_assert (len >= M68KBSD_SIZEOF_FPREGS);
+
+ for (i = M68K_FP0_REGNUM; i <= M68K_PC_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i,
+ regs + m68kbsd_fpreg_offset (gdbarch, i));
+ }
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+m68kbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) gregs;
+ int i;
+
+ gdb_assert (len >= M68KBSD_SIZEOF_GREGS);
+
+ for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + i * 4);
+ }
+
+ if (len >= M68KBSD_SIZEOF_GREGS + M68KBSD_SIZEOF_FPREGS)
+ {
+ regs += M68KBSD_SIZEOF_GREGS;
+ len -= M68KBSD_SIZEOF_GREGS;
+ m68kbsd_supply_fpregset (regset, regcache, regnum, regs, len);
+ }
+}
+
+/* Motorola 68000 register sets. */
+
+static const struct regset m68kbsd_gregset =
+{
+ NULL,
+ m68kbsd_supply_gregset,
+ NULL,
+ REGSET_VARIABLE_SIZE
+};
+
+static const struct regset m68kbsd_fpregset =
+{
+ NULL,
+ m68kbsd_supply_fpregset
+};
+
+/* Iterate over core file register note sections. */
+
+static void
+m68kbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", M68KBSD_SIZEOF_GREGS, &m68kbsd_gregset, NULL, cb_data);
+ cb (".reg2", M68KBSD_SIZEOF_FPREGS, &m68kbsd_fpregset, NULL, cb_data);
+}
+\f
+
+/* Signal trampolines. */
+
+static void
+m68kobsd_sigtramp_cache_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ CORE_ADDR addr, base, pc;
+ int regnum;
+
+ base = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM);
+
+ /* The 'addql #4,%sp' instruction at offset 8 adjusts the stack
+ pointer. Adjust the frame base accordingly. */
+ pc = get_frame_register_unsigned (this_frame, M68K_PC_REGNUM);
+ if ((pc - func) > 8)
+ base -= 4;
+
+ /* Get frame pointer, stack pointer, program counter and processor
+ state from `struct sigcontext'. */
+ addr = get_frame_memory_unsigned (this_frame, base + 8, 4);
+ trad_frame_set_reg_addr (this_cache, M68K_FP_REGNUM, addr + 8);
+ trad_frame_set_reg_addr (this_cache, M68K_SP_REGNUM, addr + 12);
+ trad_frame_set_reg_addr (this_cache, M68K_PC_REGNUM, addr + 20);
+ trad_frame_set_reg_addr (this_cache, M68K_PS_REGNUM, addr + 24);
+
+ /* The sc_ap member of `struct sigcontext' points to additional
+ hardware state. Here we find the missing registers. */
+ addr = get_frame_memory_unsigned (this_frame, addr + 16, 4) + 4;
+ for (regnum = M68K_D0_REGNUM; regnum < M68K_FP_REGNUM; regnum++, addr += 4)
+ trad_frame_set_reg_addr (this_cache, regnum, addr);
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (this_cache, frame_id_build (base, func));
+}
+
+static const struct tramp_frame m68kobsd_sigtramp = {
+ SIGTRAMP_FRAME,
+ 2,
+ {
+ { 0x206f, -1 }, { 0x000c, -1}, /* moveal %sp@(12),%a0 */
+ { 0x4e90, -1 }, /* jsr %a0@ */
+ { 0x588f, -1 }, /* addql #4,%sp */
+ { 0x4e41, -1 }, /* trap #1 */
+ { 0x2f40, -1 }, { 0x0004, -1 }, /* moveal %d0,%sp@(4) */
+ { 0x7001, -1 }, /* moveq #SYS_exit,%d0 */
+ { 0x4e40, -1 }, /* trap #0 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ m68kobsd_sigtramp_cache_init
+};
+\f
+
+static void
+m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->jb_pc = 5;
+ tdep->jb_elt_size = 4;
+
+ set_gdbarch_decr_pc_after_break (gdbarch, 2);
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, m68kbsd_iterate_over_regset_sections);
+}
+
+/* OpenBSD and NetBSD a.out. */
+
+static void
+m68kbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ m68kbsd_init_abi (info, gdbarch);
+
+ tdep->struct_return = reg_struct_return;
+
+ tramp_frame_prepend_unwinder (gdbarch, &m68kobsd_sigtramp);
+}
+
+/* NetBSD ELF. */
+
+static void
+m68kbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ m68kbsd_init_abi (info, gdbarch);
+
+ /* NetBSD ELF uses the SVR4 ABI. */
+ m68k_svr4_init_abi (info, gdbarch);
+ tdep->struct_return = pcc_struct_return;
+
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+static enum gdb_osabi
+m68kbsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-m68k-netbsd") == 0
+ || strcmp (bfd_get_target (abfd), "a.out-m68k4k-netbsd") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+static enum gdb_osabi
+m68kbsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_m68kbsd_tdep (void);
+
+void
+_initialize_m68kbsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_aout_flavour,
+ m68kbsd_aout_osabi_sniffer);
+
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_unknown_flavour,
+ m68kbsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_AOUT,
+ m68kbsd_aout_init_abi);
+ gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_ELF,
+ m68kbsd_elf_init_abi);
+}
--- /dev/null
+/* Motorola m68k native support for GNU/Linux.
+
+ Copyright (C) 1996-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "language.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+#include "linux-nat.h"
+
+#include "m68k-tdep.h"
+
+#include <sys/dir.h>
+#include <signal.h>
+#include "nat/gdb_ptrace.h"
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/procfs.h>
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include "floatformat.h"
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* Defines ps_err_e, struct ps_prochandle. */
+#include "gdb_proc_service.h"
+
+#ifndef PTRACE_GET_THREAD_AREA
+#define PTRACE_GET_THREAD_AREA 25
+#endif
+\f
+/* This table must line up with gdbarch_register_name in "m68k-tdep.c". */
+static const int regmap[] =
+{
+ PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
+ PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
+ PT_SR, PT_PC,
+ /* PT_FP0, ..., PT_FP7 */
+ 21, 24, 27, 30, 33, 36, 39, 42,
+ /* PT_FPCR, PT_FPSR, PT_FPIAR */
+ 45, 46, 47
+};
+
+/* Which ptrace request retrieves which registers?
+ These apply to the corresponding SET requests as well. */
+#define NUM_GREGS (18)
+#define MAX_NUM_REGS (NUM_GREGS + 11)
+
+static int
+getregs_supplies (int regno)
+{
+ return 0 <= regno && regno < NUM_GREGS;
+}
+
+static int
+getfpregs_supplies (int regno)
+{
+ return M68K_FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM;
+}
+
+/* Does the current host support the GETREGS request? */
+static int have_ptrace_getregs =
+#ifdef HAVE_PTRACE_GETREGS
+ 1
+#else
+ 0
+#endif
+;
+
+\f
+
+/* Fetching registers directly from the U area, one at a time. */
+
+/* Fetch one register. */
+
+static void
+fetch_register (struct regcache *regcache, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ long regaddr, val;
+ int i;
+ gdb_byte buf[MAX_REGISTER_SIZE];
+ int tid;
+
+ /* Overload thread id onto process id. */
+ tid = ptid_get_lwp (inferior_ptid);
+ if (tid == 0)
+ tid = ptid_get_pid (inferior_ptid); /* no thread id, just use
+ process id. */
+
+ regaddr = 4 * regmap[regno];
+ for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
+ {
+ errno = 0;
+ val = ptrace (PTRACE_PEEKUSER, tid, regaddr, 0);
+ memcpy (&buf[i], &val, sizeof (long));
+ regaddr += sizeof (long);
+ if (errno != 0)
+ error (_("Couldn't read register %s (#%d): %s."),
+ gdbarch_register_name (gdbarch, regno),
+ regno, safe_strerror (errno));
+ }
+ regcache_raw_supply (regcache, regno, buf);
+}
+
+/* Fetch register values from the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+static void
+old_fetch_inferior_registers (struct regcache *regcache, int regno)
+{
+ if (regno >= 0)
+ {
+ fetch_register (regcache, regno);
+ }
+ else
+ {
+ for (regno = 0;
+ regno < gdbarch_num_regs (get_regcache_arch (regcache));
+ regno++)
+ {
+ fetch_register (regcache, regno);
+ }
+ }
+}
+
+/* Store one register. */
+
+static void
+store_register (const struct regcache *regcache, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ long regaddr, val;
+ int i;
+ int tid;
+ gdb_byte buf[MAX_REGISTER_SIZE];
+
+ /* Overload thread id onto process id. */
+ tid = ptid_get_lwp (inferior_ptid);
+ if (tid == 0)
+ tid = ptid_get_pid (inferior_ptid); /* no thread id, just use
+ process id. */
+
+ regaddr = 4 * regmap[regno];
+
+ /* Put the contents of regno into a local buffer. */
+ regcache_raw_collect (regcache, regno, buf);
+
+ /* Store the local buffer into the inferior a chunk at the time. */
+ for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
+ {
+ errno = 0;
+ memcpy (&val, &buf[i], sizeof (long));
+ ptrace (PTRACE_POKEUSER, tid, regaddr, val);
+ regaddr += sizeof (long);
+ if (errno != 0)
+ error (_("Couldn't write register %s (#%d): %s."),
+ gdbarch_register_name (gdbarch, regno),
+ regno, safe_strerror (errno));
+ }
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+static void
+old_store_inferior_registers (const struct regcache *regcache, int regno)
+{
+ if (regno >= 0)
+ {
+ store_register (regcache, regno);
+ }
+ else
+ {
+ for (regno = 0;
+ regno < gdbarch_num_regs (get_regcache_arch (regcache));
+ regno++)
+ {
+ store_register (regcache, regno);
+ }
+ }
+}
+\f
+/* Given a pointer to a general register set in /proc format
+ (elf_gregset_t *), unpack the register contents and supply
+ them as gdb's idea of the current register values. */
+
+void
+supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
+ int regi;
+
+ for (regi = M68K_D0_REGNUM;
+ regi <= gdbarch_sp_regnum (gdbarch);
+ regi++)
+ regcache_raw_supply (regcache, regi, ®p[regmap[regi]]);
+ regcache_raw_supply (regcache, gdbarch_ps_regnum (gdbarch),
+ ®p[PT_SR]);
+ regcache_raw_supply (regcache,
+ gdbarch_pc_regnum (gdbarch), ®p[PT_PC]);
+}
+
+/* Fill register REGNO (if it is a general-purpose register) in
+ *GREGSETPS with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+void
+fill_gregset (const struct regcache *regcache,
+ elf_gregset_t *gregsetp, int regno)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < NUM_GREGS; i++)
+ if (regno == -1 || regno == i)
+ regcache_raw_collect (regcache, i, regp + regmap[i]);
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all general-purpose registers from process/thread TID and
+ store their values in GDB's register array. */
+
+static void
+fetch_regs (struct regcache *regcache, int tid)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
+ {
+ if (errno == EIO)
+ {
+ /* The kernel we're running on doesn't support the GETREGS
+ request. Reset `have_ptrace_getregs'. */
+ have_ptrace_getregs = 0;
+ return;
+ }
+
+ perror_with_name (_("Couldn't get registers"));
+ }
+
+ supply_gregset (regcache, (const elf_gregset_t *) ®s);
+}
+
+/* Store all valid general-purpose registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_regs (const struct regcache *regcache, int tid, int regno)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
+ perror_with_name (_("Couldn't get registers"));
+
+ fill_gregset (regcache, ®s, regno);
+
+ if (ptrace (PTRACE_SETREGS, tid, 0, (int) ®s) < 0)
+ perror_with_name (_("Couldn't write registers"));
+}
+
+#else
+
+static void fetch_regs (struct regcache *regcache, int tid)
+{
+}
+
+static void store_regs (const struct regcache *regcache, int tid, int regno)
+{
+}
+
+#endif
+
+\f
+/* Transfering floating-point registers between GDB, inferiors and cores. */
+
+/* What is the address of fpN within the floating-point register set F? */
+#define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3])
+
+/* Fill GDB's register array with the floating-point register values in
+ *FPREGSETP. */
+
+void
+supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ int regi;
+
+ for (regi = gdbarch_fp0_regnum (gdbarch);
+ regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
+ regcache_raw_supply (regcache, regi,
+ FPREG_ADDR (fpregsetp,
+ regi - gdbarch_fp0_regnum (gdbarch)));
+ regcache_raw_supply (regcache, M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
+ regcache_raw_supply (regcache, M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
+ regcache_raw_supply (regcache, M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
+}
+
+/* Fill register REGNO (if it is a floating-point register) in
+ *FPREGSETP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_fpregset (const struct regcache *regcache,
+ elf_fpregset_t *fpregsetp, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ int i;
+
+ /* Fill in the floating-point registers. */
+ for (i = gdbarch_fp0_regnum (gdbarch);
+ i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
+ if (regno == -1 || regno == i)
+ regcache_raw_collect (regcache, i,
+ FPREG_ADDR (fpregsetp,
+ i - gdbarch_fp0_regnum (gdbarch)));
+
+ /* Fill in the floating-point control registers. */
+ for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
+ if (regno == -1 || regno == i)
+ regcache_raw_collect (regcache, i,
+ &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all floating-point registers from process/thread TID and store
+ thier values in GDB's register array. */
+
+static void
+fetch_fpregs (struct regcache *regcache, int tid)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
+}
+
+/* Store all valid floating-point registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_fpregs (const struct regcache *regcache, int tid, int regno)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ fill_fpregset (regcache, &fpregs, regno);
+
+ if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name (_("Couldn't write floating point status"));
+}
+
+#else
+
+static void fetch_fpregs (struct regcache *regcache, int tid)
+{
+}
+
+static void store_fpregs (const struct regcache *regcache, int tid, int regno)
+{
+}
+
+#endif
+\f
+/* Transferring arbitrary registers between GDB and inferior. */
+
+/* Fetch register REGNO from the child process. If REGNO is -1, do
+ this for all registers (including the floating point and SSE
+ registers). */
+
+static void
+m68k_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ int tid;
+
+ /* Use the old method of peeking around in `struct user' if the
+ GETREGS request isn't available. */
+ if (! have_ptrace_getregs)
+ {
+ old_fetch_inferior_registers (regcache, regno);
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = ptid_get_lwp (inferior_ptid);
+ if (tid == 0)
+ tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
+
+ /* Use the PTRACE_GETFPXREGS request whenever possible, since it
+ transfers more registers in one system call, and we'll cache the
+ results. But remember that fetch_fpxregs can fail, and return
+ zero. */
+ if (regno == -1)
+ {
+ fetch_regs (regcache, tid);
+
+ /* The call above might reset `have_ptrace_getregs'. */
+ if (! have_ptrace_getregs)
+ {
+ old_fetch_inferior_registers (regcache, -1);
+ return;
+ }
+
+ fetch_fpregs (regcache, tid);
+ return;
+ }
+
+ if (getregs_supplies (regno))
+ {
+ fetch_regs (regcache, tid);
+ return;
+ }
+
+ if (getfpregs_supplies (regno))
+ {
+ fetch_fpregs (regcache, tid);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ _("Got request for bad register number %d."), regno);
+}
+
+/* Store register REGNO back into the child process. If REGNO is -1,
+ do this for all registers (including the floating point and SSE
+ registers). */
+static void
+m68k_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ int tid;
+
+ /* Use the old method of poking around in `struct user' if the
+ SETREGS request isn't available. */
+ if (! have_ptrace_getregs)
+ {
+ old_store_inferior_registers (regcache, regno);
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = ptid_get_lwp (inferior_ptid);
+ if (tid == 0)
+ tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
+
+ /* Use the PTRACE_SETFPREGS requests whenever possible, since it
+ transfers more registers in one system call. But remember that
+ store_fpregs can fail, and return zero. */
+ if (regno == -1)
+ {
+ store_regs (regcache, tid, regno);
+ store_fpregs (regcache, tid, regno);
+ return;
+ }
+
+ if (getregs_supplies (regno))
+ {
+ store_regs (regcache, tid, regno);
+ return;
+ }
+
+ if (getfpregs_supplies (regno))
+ {
+ store_fpregs (regcache, tid, regno);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ _("Got request to store bad register number %d."), regno);
+}
+\f
+
+/* Fetch the thread-local storage pointer for libthread_db. */
+
+ps_err_e
+ps_get_thread_area (struct ps_prochandle *ph,
+ lwpid_t lwpid, int idx, void **base)
+{
+ if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) < 0)
+ return PS_ERR;
+
+ /* IDX is the bias from the thread pointer to the beginning of the
+ thread descriptor. It has to be subtracted due to implementation
+ quirks in libthread_db. */
+ *base = (char *) *base - idx;
+
+ return PS_OK;
+}
+\f
+
+void _initialize_m68k_linux_nat (void);
+
+void
+_initialize_m68k_linux_nat (void)
+{
+ struct target_ops *t;
+
+ /* Fill in the generic GNU/Linux methods. */
+ t = linux_target ();
+
+ /* Add our register access methods. */
+ t->to_fetch_registers = m68k_linux_fetch_inferior_registers;
+ t->to_store_registers = m68k_linux_store_inferior_registers;
+
+ /* Register the target. */
+ linux_nat_add_target (t);
+}
--- /dev/null
+/* Motorola m68k target-dependent support for GNU/Linux.
+
+ Copyright (C) 1996-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "doublest.h"
+#include "floatformat.h"
+#include "frame.h"
+#include "target.h"
+#include "gdbtypes.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "objfiles.h"
+#include "symtab.h"
+#include "m68k-tdep.h"
+#include "trad-frame.h"
+#include "frame-unwind.h"
+#include "glibc-tdep.h"
+#include "solib-svr4.h"
+#include "auxv.h"
+#include "observer.h"
+#include "elf/common.h"
+#include "linux-tdep.h"
+#include "regset.h"
+\f
+/* Offsets (in target ints) into jmp_buf. */
+
+#define M68K_LINUX_JB_ELEMENT_SIZE 4
+#define M68K_LINUX_JB_PC 7
+
+/* Check whether insn1 and insn2 are parts of a signal trampoline. */
+
+#define IS_SIGTRAMP(insn1, insn2) \
+ (/* addaw #20,sp; moveq #119,d0; trap #0 */ \
+ (insn1 == 0xdefc0014 && insn2 == 0x70774e40) \
+ /* moveq #119,d0; trap #0 */ \
+ || insn1 == 0x70774e40)
+
+#define IS_RT_SIGTRAMP(insn1, insn2) \
+ (/* movel #173,d0; trap #0 */ \
+ (insn1 == 0x203c0000 && insn2 == 0x00ad4e40) \
+ /* moveq #82,d0; notb d0; trap #0 */ \
+ || (insn1 == 0x70524600 && (insn2 >> 16) == 0x4e40))
+
+/* Return non-zero if THIS_FRAME corresponds to a signal trampoline. For
+ the sake of m68k_linux_get_sigtramp_info we also distinguish between
+ non-RT and RT signal trampolines. */
+
+static int
+m68k_linux_pc_in_sigtramp (struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ gdb_byte buf[12];
+ unsigned long insn0, insn1, insn2;
+ CORE_ADDR pc = get_frame_pc (this_frame);
+
+ if (!safe_frame_unwind_memory (this_frame, pc - 4, buf, sizeof (buf)))
+ return 0;
+ insn1 = extract_unsigned_integer (buf + 4, 4, byte_order);
+ insn2 = extract_unsigned_integer (buf + 8, 4, byte_order);
+ if (IS_SIGTRAMP (insn1, insn2))
+ return 1;
+ if (IS_RT_SIGTRAMP (insn1, insn2))
+ return 2;
+
+ insn0 = extract_unsigned_integer (buf, 4, byte_order);
+ if (IS_SIGTRAMP (insn0, insn1))
+ return 1;
+ if (IS_RT_SIGTRAMP (insn0, insn1))
+ return 2;
+
+ insn0 = ((insn0 << 16) & 0xffffffff) | (insn1 >> 16);
+ insn1 = ((insn1 << 16) & 0xffffffff) | (insn2 >> 16);
+ if (IS_SIGTRAMP (insn0, insn1))
+ return 1;
+ if (IS_RT_SIGTRAMP (insn0, insn1))
+ return 2;
+
+ return 0;
+}
+
+/* From <asm/sigcontext.h>. */
+static int m68k_linux_sigcontext_reg_offset[M68K_NUM_REGS] =
+{
+ 2 * 4, /* %d0 */
+ 3 * 4, /* %d1 */
+ -1, /* %d2 */
+ -1, /* %d3 */
+ -1, /* %d4 */
+ -1, /* %d5 */
+ -1, /* %d6 */
+ -1, /* %d7 */
+ 4 * 4, /* %a0 */
+ 5 * 4, /* %a1 */
+ -1, /* %a2 */
+ -1, /* %a3 */
+ -1, /* %a4 */
+ -1, /* %a5 */
+ -1, /* %fp */
+ 1 * 4, /* %sp */
+ 6 * 4, /* %sr */
+ 6 * 4 + 2, /* %pc */
+ 8 * 4, /* %fp0 */
+ 11 * 4, /* %fp1 */
+ -1, /* %fp2 */
+ -1, /* %fp3 */
+ -1, /* %fp4 */
+ -1, /* %fp5 */
+ -1, /* %fp6 */
+ -1, /* %fp7 */
+ 14 * 4, /* %fpcr */
+ 15 * 4, /* %fpsr */
+ 16 * 4 /* %fpiaddr */
+};
+
+static int m68k_uclinux_sigcontext_reg_offset[M68K_NUM_REGS] =
+{
+ 2 * 4, /* %d0 */
+ 3 * 4, /* %d1 */
+ -1, /* %d2 */
+ -1, /* %d3 */
+ -1, /* %d4 */
+ -1, /* %d5 */
+ -1, /* %d6 */
+ -1, /* %d7 */
+ 4 * 4, /* %a0 */
+ 5 * 4, /* %a1 */
+ -1, /* %a2 */
+ -1, /* %a3 */
+ -1, /* %a4 */
+ 6 * 4, /* %a5 */
+ -1, /* %fp */
+ 1 * 4, /* %sp */
+ 7 * 4, /* %sr */
+ 7 * 4 + 2, /* %pc */
+ -1, /* %fp0 */
+ -1, /* %fp1 */
+ -1, /* %fp2 */
+ -1, /* %fp3 */
+ -1, /* %fp4 */
+ -1, /* %fp5 */
+ -1, /* %fp6 */
+ -1, /* %fp7 */
+ -1, /* %fpcr */
+ -1, /* %fpsr */
+ -1 /* %fpiaddr */
+};
+
+/* From <asm/ucontext.h>. */
+static int m68k_linux_ucontext_reg_offset[M68K_NUM_REGS] =
+{
+ 6 * 4, /* %d0 */
+ 7 * 4, /* %d1 */
+ 8 * 4, /* %d2 */
+ 9 * 4, /* %d3 */
+ 10 * 4, /* %d4 */
+ 11 * 4, /* %d5 */
+ 12 * 4, /* %d6 */
+ 13 * 4, /* %d7 */
+ 14 * 4, /* %a0 */
+ 15 * 4, /* %a1 */
+ 16 * 4, /* %a2 */
+ 17 * 4, /* %a3 */
+ 18 * 4, /* %a4 */
+ 19 * 4, /* %a5 */
+ 20 * 4, /* %fp */
+ 21 * 4, /* %sp */
+ 23 * 4, /* %sr */
+ 22 * 4, /* %pc */
+ 27 * 4, /* %fp0 */
+ 30 * 4, /* %fp1 */
+ 33 * 4, /* %fp2 */
+ 36 * 4, /* %fp3 */
+ 39 * 4, /* %fp4 */
+ 42 * 4, /* %fp5 */
+ 45 * 4, /* %fp6 */
+ 48 * 4, /* %fp7 */
+ 24 * 4, /* %fpcr */
+ 25 * 4, /* %fpsr */
+ 26 * 4 /* %fpiaddr */
+};
+
+
+/* Get info about saved registers in sigtramp. */
+
+struct m68k_linux_sigtramp_info
+{
+ /* Address of sigcontext. */
+ CORE_ADDR sigcontext_addr;
+
+ /* Offset of registers in `struct sigcontext'. */
+ int *sc_reg_offset;
+};
+
+/* Nonzero if running on uClinux. */
+static int target_is_uclinux;
+
+static void
+m68k_linux_inferior_created (struct target_ops *objfile, int from_tty)
+{
+ /* Record that we will need to re-evaluate whether we are running on a
+ uClinux or normal GNU/Linux target (see m68k_linux_get_sigtramp_info). */
+ target_is_uclinux = -1;
+}
+
+static struct m68k_linux_sigtramp_info
+m68k_linux_get_sigtramp_info (struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp;
+ struct m68k_linux_sigtramp_info info;
+
+ /* Determine whether we are running on a uClinux or normal GNU/Linux
+ target so we can use the correct sigcontext layouts. */
+ if (target_is_uclinux == -1)
+ target_is_uclinux = linux_is_uclinux ();
+
+ sp = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM);
+
+ /* Get sigcontext address, it is the third parameter on the stack. */
+ info.sigcontext_addr = read_memory_unsigned_integer (sp + 8, 4, byte_order);
+
+ if (m68k_linux_pc_in_sigtramp (this_frame) == 2)
+ info.sc_reg_offset = m68k_linux_ucontext_reg_offset;
+ else
+ info.sc_reg_offset = (target_is_uclinux
+ ? m68k_uclinux_sigcontext_reg_offset
+ : m68k_linux_sigcontext_reg_offset);
+ return info;
+}
+
+/* Signal trampolines. */
+
+static struct trad_frame_cache *
+m68k_linux_sigtramp_frame_cache (struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct frame_id this_id;
+ struct trad_frame_cache *cache;
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ struct m68k_linux_sigtramp_info info;
+ gdb_byte buf[4];
+ int i;
+
+ if (*this_cache)
+ return (struct trad_frame_cache *) *this_cache;
+
+ cache = trad_frame_cache_zalloc (this_frame);
+
+ /* FIXME: cagney/2004-05-01: This is is long standing broken code.
+ The frame ID's code address should be the start-address of the
+ signal trampoline and not the current PC within that
+ trampoline. */
+ get_frame_register (this_frame, M68K_SP_REGNUM, buf);
+ /* See the end of m68k_push_dummy_call. */
+ this_id = frame_id_build (extract_unsigned_integer (buf, 4, byte_order)
+ - 4 + 8, get_frame_pc (this_frame));
+ trad_frame_set_id (cache, this_id);
+
+ info = m68k_linux_get_sigtramp_info (this_frame);
+
+ for (i = 0; i < M68K_NUM_REGS; i++)
+ if (info.sc_reg_offset[i] != -1)
+ trad_frame_set_reg_addr (cache, i,
+ info.sigcontext_addr + info.sc_reg_offset[i]);
+
+ *this_cache = cache;
+ return cache;
+}
+
+static void
+m68k_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct trad_frame_cache *cache =
+ m68k_linux_sigtramp_frame_cache (this_frame, this_cache);
+ trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+m68k_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache,
+ int regnum)
+{
+ /* Make sure we've initialized the cache. */
+ struct trad_frame_cache *cache =
+ m68k_linux_sigtramp_frame_cache (this_frame, this_cache);
+ return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static int
+m68k_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_prologue_cache)
+{
+ return m68k_linux_pc_in_sigtramp (this_frame);
+}
+
+static const struct frame_unwind m68k_linux_sigtramp_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ m68k_linux_sigtramp_frame_this_id,
+ m68k_linux_sigtramp_frame_prev_register,
+ NULL,
+ m68k_linux_sigtramp_frame_sniffer
+};
+
+/* Register maps for supply/collect regset functions. */
+
+static const struct regcache_map_entry m68k_linux_gregmap[] =
+ {
+ { 7, M68K_D1_REGNUM, 4 }, /* d1 ... d7 */
+ { 7, M68K_A0_REGNUM, 4 }, /* a0 ... a6 */
+ { 1, M68K_D0_REGNUM, 4 },
+ { 1, M68K_SP_REGNUM, 4 },
+ { 1, REGCACHE_MAP_SKIP, 4 }, /* orig_d0 (skip) */
+ { 1, M68K_PS_REGNUM, 4 },
+ { 1, M68K_PC_REGNUM, 4 },
+ /* Ignore 16-bit fields 'fmtvec' and '__fill'. */
+ { 0 }
+ };
+
+#define M68K_LINUX_GREGS_SIZE (20 * 4)
+
+static const struct regcache_map_entry m68k_linux_fpregmap[] =
+ {
+ { 8, M68K_FP0_REGNUM, 12 }, /* fp0 ... fp7 */
+ { 1, M68K_FPC_REGNUM, 4 },
+ { 1, M68K_FPS_REGNUM, 4 },
+ { 1, M68K_FPI_REGNUM, 4 },
+ { 0 }
+ };
+
+#define M68K_LINUX_FPREGS_SIZE (27 * 4)
+
+/* Register sets. */
+
+static const struct regset m68k_linux_gregset =
+ {
+ m68k_linux_gregmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+static const struct regset m68k_linux_fpregset =
+ {
+ m68k_linux_fpregmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+/* Iterate over core file register note sections. */
+
+static void
+m68k_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", M68K_LINUX_GREGS_SIZE, &m68k_linux_gregset, NULL, cb_data);
+ cb (".reg2", M68K_LINUX_FPREGS_SIZE, &m68k_linux_fpregset, NULL, cb_data);
+}
+
+static void
+m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ linux_init_abi (info, gdbarch);
+
+ tdep->jb_pc = M68K_LINUX_JB_PC;
+ tdep->jb_elt_size = M68K_LINUX_JB_ELEMENT_SIZE;
+
+ /* GNU/Linux uses a calling convention that's similar to SVR4. It
+ returns integer values in %d0/%d1, pointer values in %a0 and
+ floating values in %fp0, just like SVR4, but uses %a1 to pass the
+ address to store a structure value. It also returns small
+ structures in registers instead of memory. */
+ m68k_svr4_init_abi (info, gdbarch);
+ tdep->struct_value_regnum = M68K_A1_REGNUM;
+ tdep->struct_return = reg_struct_return;
+
+ set_gdbarch_decr_pc_after_break (gdbarch, 2);
+
+ frame_unwind_append_unwinder (gdbarch, &m68k_linux_sigtramp_frame_unwind);
+
+ /* Shared library handling. */
+
+ /* GNU/Linux uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ svr4_ilp32_fetch_link_map_offsets);
+
+ /* GNU/Linux uses the dynamic linker included in the GNU C Library. */
+ set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
+
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+
+ /* Core file support. */
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, m68k_linux_iterate_over_regset_sections);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_m68k_linux_tdep;
+
+void
+_initialize_m68k_linux_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_LINUX,
+ m68k_linux_init_abi);
+ observer_attach_inferior_created (m68k_linux_inferior_created);
+}
extern void m68k_svr4_init_abi (struct gdbarch_info, struct gdbarch *);
\f
-/* Functions exported from m68kbsd-tdep.c. */
+/* Functions exported from m68k-bsd-tdep.c. */
extern int m68kbsd_fpreg_offset (struct gdbarch *gdbarch, int regnum);
+++ /dev/null
-/* Native-dependent code for Motorola 68000 BSD's.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "m68k-tdep.h"
-#include "inf-ptrace.h"
-
-static int
-m68kbsd_gregset_supplies_p (int regnum)
-{
- return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM);
-}
-
-static int
-m68kbsd_fpregset_supplies_p (int regnum)
-{
- return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM);
-}
-
-/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
-
-static void
-m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
-{
- const char *regs = gregs;
- int regnum;
-
- for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum, regs + regnum * 4);
-}
-
-/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
-
-static void
-m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- const char *regs = fpregs;
- int regnum;
-
- for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum,
- regs + m68kbsd_fpreg_offset (gdbarch, regnum));
-}
-
-/* Collect the general-purpose registers from REGCACHE and store them
- in GREGS. */
-
-static void
-m68kbsd_collect_gregset (const struct regcache *regcache,
- void *gregs, int regnum)
-{
- char *regs = gregs;
- int i;
-
- for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
- {
- if (regnum == -1 || regnum == i)
- regcache_raw_collect (regcache, i, regs + i * 4);
- }
-}
-
-/* Collect the floating-point registers from REGCACHE and store them
- in FPREGS. */
-
-static void
-m68kbsd_collect_fpregset (struct regcache *regcache,
- void *fpregs, int regnum)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- char *regs = fpregs;
- int i;
-
- for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
- {
- if (regnum == -1 || regnum == i)
- regcache_raw_collect (regcache, i,
- regs + m68kbsd_fpreg_offset (gdbarch, i));
- }
-}
-\f
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers (including the floating-point registers). */
-
-static void
-m68kbsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- m68kbsd_supply_gregset (regcache, ®s);
- }
-
- if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- m68kbsd_supply_fpregset (regcache, &fpregs);
- }
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers (including the floating-point registers). */
-
-static void
-m68kbsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- m68kbsd_collect_gregset (regcache, ®s, regnum);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
- }
-
- if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- m68kbsd_collect_fpregset (regcache, &fpregs, regnum);
-
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't write floating point status"));
- }
-}
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-/* OpenBSD doesn't have these. */
-#ifndef PCB_REGS_FP
-#define PCB_REGS_FP 10
-#endif
-#ifndef PCB_REGS_SP
-#define PCB_REGS_SP 11
-#endif
-
-static int
-m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- int regnum, tmp;
- int i = 0;
-
- /* The following is true for NetBSD 1.6.2:
-
- The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for
- all callee-saved registers. From this information we reconstruct
- the register state as it would look when we just returned from
- cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_regs[PCB_REGS_SP] == 0)
- return 0;
-
- for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
- for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
-
- tmp = pcb->pcb_ps & 0xffff;
- regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp);
-
- read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp);
- regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp);
-
- return 1;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_m68kbsd_nat (void);
-
-void
-_initialize_m68kbsd_nat (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
- t->to_fetch_registers = m68kbsd_fetch_inferior_registers;
- t->to_store_registers = m68kbsd_store_inferior_registers;
- add_target (t);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (m68kbsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for Motorola 68000 BSD's.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "trad-frame.h"
-#include "tramp-frame.h"
-#include "gdbtypes.h"
-
-#include "m68k-tdep.h"
-#include "solib-svr4.h"
-
-/* Core file support. */
-
-/* Sizeof `struct reg' in <machine/reg.h>. */
-#define M68KBSD_SIZEOF_GREGS (18 * 4)
-
-/* Sizeof `struct fpreg' in <machine/reg.h. */
-#define M68KBSD_SIZEOF_FPREGS (((8 * 3) + 3) * 4)
-
-int
-m68kbsd_fpreg_offset (struct gdbarch *gdbarch, int regnum)
-{
- int fp_len = TYPE_LENGTH (gdbarch_register_type (gdbarch, regnum));
-
- if (regnum >= M68K_FPC_REGNUM)
- return 8 * fp_len + (regnum - M68K_FPC_REGNUM) * 4;
-
- return (regnum - M68K_FP0_REGNUM) * fp_len;
-}
-
-/* Supply register REGNUM from the buffer specified by FPREGS and LEN
- in the floating-point register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-m68kbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- const gdb_byte *regs = (const gdb_byte *) fpregs;
- int i;
-
- gdb_assert (len >= M68KBSD_SIZEOF_FPREGS);
-
- for (i = M68K_FP0_REGNUM; i <= M68K_PC_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i,
- regs + m68kbsd_fpreg_offset (gdbarch, i));
- }
-}
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-m68kbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) gregs;
- int i;
-
- gdb_assert (len >= M68KBSD_SIZEOF_GREGS);
-
- for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + i * 4);
- }
-
- if (len >= M68KBSD_SIZEOF_GREGS + M68KBSD_SIZEOF_FPREGS)
- {
- regs += M68KBSD_SIZEOF_GREGS;
- len -= M68KBSD_SIZEOF_GREGS;
- m68kbsd_supply_fpregset (regset, regcache, regnum, regs, len);
- }
-}
-
-/* Motorola 68000 register sets. */
-
-static const struct regset m68kbsd_gregset =
-{
- NULL,
- m68kbsd_supply_gregset,
- NULL,
- REGSET_VARIABLE_SIZE
-};
-
-static const struct regset m68kbsd_fpregset =
-{
- NULL,
- m68kbsd_supply_fpregset
-};
-
-/* Iterate over core file register note sections. */
-
-static void
-m68kbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", M68KBSD_SIZEOF_GREGS, &m68kbsd_gregset, NULL, cb_data);
- cb (".reg2", M68KBSD_SIZEOF_FPREGS, &m68kbsd_fpregset, NULL, cb_data);
-}
-\f
-
-/* Signal trampolines. */
-
-static void
-m68kobsd_sigtramp_cache_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func)
-{
- CORE_ADDR addr, base, pc;
- int regnum;
-
- base = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM);
-
- /* The 'addql #4,%sp' instruction at offset 8 adjusts the stack
- pointer. Adjust the frame base accordingly. */
- pc = get_frame_register_unsigned (this_frame, M68K_PC_REGNUM);
- if ((pc - func) > 8)
- base -= 4;
-
- /* Get frame pointer, stack pointer, program counter and processor
- state from `struct sigcontext'. */
- addr = get_frame_memory_unsigned (this_frame, base + 8, 4);
- trad_frame_set_reg_addr (this_cache, M68K_FP_REGNUM, addr + 8);
- trad_frame_set_reg_addr (this_cache, M68K_SP_REGNUM, addr + 12);
- trad_frame_set_reg_addr (this_cache, M68K_PC_REGNUM, addr + 20);
- trad_frame_set_reg_addr (this_cache, M68K_PS_REGNUM, addr + 24);
-
- /* The sc_ap member of `struct sigcontext' points to additional
- hardware state. Here we find the missing registers. */
- addr = get_frame_memory_unsigned (this_frame, addr + 16, 4) + 4;
- for (regnum = M68K_D0_REGNUM; regnum < M68K_FP_REGNUM; regnum++, addr += 4)
- trad_frame_set_reg_addr (this_cache, regnum, addr);
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (this_cache, frame_id_build (base, func));
-}
-
-static const struct tramp_frame m68kobsd_sigtramp = {
- SIGTRAMP_FRAME,
- 2,
- {
- { 0x206f, -1 }, { 0x000c, -1}, /* moveal %sp@(12),%a0 */
- { 0x4e90, -1 }, /* jsr %a0@ */
- { 0x588f, -1 }, /* addql #4,%sp */
- { 0x4e41, -1 }, /* trap #1 */
- { 0x2f40, -1 }, { 0x0004, -1 }, /* moveal %d0,%sp@(4) */
- { 0x7001, -1 }, /* moveq #SYS_exit,%d0 */
- { 0x4e40, -1 }, /* trap #0 */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- m68kobsd_sigtramp_cache_init
-};
-\f
-
-static void
-m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- tdep->jb_pc = 5;
- tdep->jb_elt_size = 4;
-
- set_gdbarch_decr_pc_after_break (gdbarch, 2);
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, m68kbsd_iterate_over_regset_sections);
-}
-
-/* OpenBSD and NetBSD a.out. */
-
-static void
-m68kbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- m68kbsd_init_abi (info, gdbarch);
-
- tdep->struct_return = reg_struct_return;
-
- tramp_frame_prepend_unwinder (gdbarch, &m68kobsd_sigtramp);
-}
-
-/* NetBSD ELF. */
-
-static void
-m68kbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- m68kbsd_init_abi (info, gdbarch);
-
- /* NetBSD ELF uses the SVR4 ABI. */
- m68k_svr4_init_abi (info, gdbarch);
- tdep->struct_return = pcc_struct_return;
-
- /* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-\f
-
-static enum gdb_osabi
-m68kbsd_aout_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "a.out-m68k-netbsd") == 0
- || strcmp (bfd_get_target (abfd), "a.out-m68k4k-netbsd") == 0)
- return GDB_OSABI_NETBSD_AOUT;
-
- return GDB_OSABI_UNKNOWN;
-}
-
-static enum gdb_osabi
-m68kbsd_core_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
- return GDB_OSABI_NETBSD_AOUT;
-
- return GDB_OSABI_UNKNOWN;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_m68kbsd_tdep (void);
-
-void
-_initialize_m68kbsd_tdep (void)
-{
- gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_aout_flavour,
- m68kbsd_aout_osabi_sniffer);
-
- /* BFD doesn't set a flavour for NetBSD style a.out core files. */
- gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_unknown_flavour,
- m68kbsd_core_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_AOUT,
- m68kbsd_aout_init_abi);
- gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_ELF,
- m68kbsd_elf_init_abi);
-}
+++ /dev/null
-/* Motorola m68k native support for GNU/Linux.
-
- Copyright (C) 1996-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "inferior.h"
-#include "language.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "target.h"
-#include "linux-nat.h"
-
-#include "m68k-tdep.h"
-
-#include <sys/dir.h>
-#include <signal.h>
-#include "nat/gdb_ptrace.h"
-#include <sys/user.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <sys/procfs.h>
-
-#ifdef HAVE_SYS_REG_H
-#include <sys/reg.h>
-#endif
-
-#include <sys/file.h>
-#include <sys/stat.h>
-
-#include "floatformat.h"
-
-/* Prototypes for supply_gregset etc. */
-#include "gregset.h"
-
-/* Defines ps_err_e, struct ps_prochandle. */
-#include "gdb_proc_service.h"
-
-#ifndef PTRACE_GET_THREAD_AREA
-#define PTRACE_GET_THREAD_AREA 25
-#endif
-\f
-/* This table must line up with gdbarch_register_name in "m68k-tdep.c". */
-static const int regmap[] =
-{
- PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
- PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
- PT_SR, PT_PC,
- /* PT_FP0, ..., PT_FP7 */
- 21, 24, 27, 30, 33, 36, 39, 42,
- /* PT_FPCR, PT_FPSR, PT_FPIAR */
- 45, 46, 47
-};
-
-/* Which ptrace request retrieves which registers?
- These apply to the corresponding SET requests as well. */
-#define NUM_GREGS (18)
-#define MAX_NUM_REGS (NUM_GREGS + 11)
-
-static int
-getregs_supplies (int regno)
-{
- return 0 <= regno && regno < NUM_GREGS;
-}
-
-static int
-getfpregs_supplies (int regno)
-{
- return M68K_FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM;
-}
-
-/* Does the current host support the GETREGS request? */
-static int have_ptrace_getregs =
-#ifdef HAVE_PTRACE_GETREGS
- 1
-#else
- 0
-#endif
-;
-
-\f
-
-/* Fetching registers directly from the U area, one at a time. */
-
-/* Fetch one register. */
-
-static void
-fetch_register (struct regcache *regcache, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- long regaddr, val;
- int i;
- gdb_byte buf[MAX_REGISTER_SIZE];
- int tid;
-
- /* Overload thread id onto process id. */
- tid = ptid_get_lwp (inferior_ptid);
- if (tid == 0)
- tid = ptid_get_pid (inferior_ptid); /* no thread id, just use
- process id. */
-
- regaddr = 4 * regmap[regno];
- for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
- {
- errno = 0;
- val = ptrace (PTRACE_PEEKUSER, tid, regaddr, 0);
- memcpy (&buf[i], &val, sizeof (long));
- regaddr += sizeof (long);
- if (errno != 0)
- error (_("Couldn't read register %s (#%d): %s."),
- gdbarch_register_name (gdbarch, regno),
- regno, safe_strerror (errno));
- }
- regcache_raw_supply (regcache, regno, buf);
-}
-
-/* Fetch register values from the inferior.
- If REGNO is negative, do this for all registers.
- Otherwise, REGNO specifies which register (so we can save time). */
-
-static void
-old_fetch_inferior_registers (struct regcache *regcache, int regno)
-{
- if (regno >= 0)
- {
- fetch_register (regcache, regno);
- }
- else
- {
- for (regno = 0;
- regno < gdbarch_num_regs (get_regcache_arch (regcache));
- regno++)
- {
- fetch_register (regcache, regno);
- }
- }
-}
-
-/* Store one register. */
-
-static void
-store_register (const struct regcache *regcache, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- long regaddr, val;
- int i;
- int tid;
- gdb_byte buf[MAX_REGISTER_SIZE];
-
- /* Overload thread id onto process id. */
- tid = ptid_get_lwp (inferior_ptid);
- if (tid == 0)
- tid = ptid_get_pid (inferior_ptid); /* no thread id, just use
- process id. */
-
- regaddr = 4 * regmap[regno];
-
- /* Put the contents of regno into a local buffer. */
- regcache_raw_collect (regcache, regno, buf);
-
- /* Store the local buffer into the inferior a chunk at the time. */
- for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
- {
- errno = 0;
- memcpy (&val, &buf[i], sizeof (long));
- ptrace (PTRACE_POKEUSER, tid, regaddr, val);
- regaddr += sizeof (long);
- if (errno != 0)
- error (_("Couldn't write register %s (#%d): %s."),
- gdbarch_register_name (gdbarch, regno),
- regno, safe_strerror (errno));
- }
-}
-
-/* Store our register values back into the inferior.
- If REGNO is negative, do this for all registers.
- Otherwise, REGNO specifies which register (so we can save time). */
-
-static void
-old_store_inferior_registers (const struct regcache *regcache, int regno)
-{
- if (regno >= 0)
- {
- store_register (regcache, regno);
- }
- else
- {
- for (regno = 0;
- regno < gdbarch_num_regs (get_regcache_arch (regcache));
- regno++)
- {
- store_register (regcache, regno);
- }
- }
-}
-\f
-/* Given a pointer to a general register set in /proc format
- (elf_gregset_t *), unpack the register contents and supply
- them as gdb's idea of the current register values. */
-
-void
-supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
- int regi;
-
- for (regi = M68K_D0_REGNUM;
- regi <= gdbarch_sp_regnum (gdbarch);
- regi++)
- regcache_raw_supply (regcache, regi, ®p[regmap[regi]]);
- regcache_raw_supply (regcache, gdbarch_ps_regnum (gdbarch),
- ®p[PT_SR]);
- regcache_raw_supply (regcache,
- gdbarch_pc_regnum (gdbarch), ®p[PT_PC]);
-}
-
-/* Fill register REGNO (if it is a general-purpose register) in
- *GREGSETPS with the value in GDB's register array. If REGNO is -1,
- do this for all registers. */
-void
-fill_gregset (const struct regcache *regcache,
- elf_gregset_t *gregsetp, int regno)
-{
- elf_greg_t *regp = (elf_greg_t *) gregsetp;
- int i;
-
- for (i = 0; i < NUM_GREGS; i++)
- if (regno == -1 || regno == i)
- regcache_raw_collect (regcache, i, regp + regmap[i]);
-}
-
-#ifdef HAVE_PTRACE_GETREGS
-
-/* Fetch all general-purpose registers from process/thread TID and
- store their values in GDB's register array. */
-
-static void
-fetch_regs (struct regcache *regcache, int tid)
-{
- elf_gregset_t regs;
-
- if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
- {
- if (errno == EIO)
- {
- /* The kernel we're running on doesn't support the GETREGS
- request. Reset `have_ptrace_getregs'. */
- have_ptrace_getregs = 0;
- return;
- }
-
- perror_with_name (_("Couldn't get registers"));
- }
-
- supply_gregset (regcache, (const elf_gregset_t *) ®s);
-}
-
-/* Store all valid general-purpose registers in GDB's register array
- into the process/thread specified by TID. */
-
-static void
-store_regs (const struct regcache *regcache, int tid, int regno)
-{
- elf_gregset_t regs;
-
- if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
- perror_with_name (_("Couldn't get registers"));
-
- fill_gregset (regcache, ®s, regno);
-
- if (ptrace (PTRACE_SETREGS, tid, 0, (int) ®s) < 0)
- perror_with_name (_("Couldn't write registers"));
-}
-
-#else
-
-static void fetch_regs (struct regcache *regcache, int tid)
-{
-}
-
-static void store_regs (const struct regcache *regcache, int tid, int regno)
-{
-}
-
-#endif
-
-\f
-/* Transfering floating-point registers between GDB, inferiors and cores. */
-
-/* What is the address of fpN within the floating-point register set F? */
-#define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3])
-
-/* Fill GDB's register array with the floating-point register values in
- *FPREGSETP. */
-
-void
-supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- int regi;
-
- for (regi = gdbarch_fp0_regnum (gdbarch);
- regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
- regcache_raw_supply (regcache, regi,
- FPREG_ADDR (fpregsetp,
- regi - gdbarch_fp0_regnum (gdbarch)));
- regcache_raw_supply (regcache, M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
- regcache_raw_supply (regcache, M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
- regcache_raw_supply (regcache, M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
-}
-
-/* Fill register REGNO (if it is a floating-point register) in
- *FPREGSETP with the value in GDB's register array. If REGNO is -1,
- do this for all registers. */
-
-void
-fill_fpregset (const struct regcache *regcache,
- elf_fpregset_t *fpregsetp, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- int i;
-
- /* Fill in the floating-point registers. */
- for (i = gdbarch_fp0_regnum (gdbarch);
- i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
- if (regno == -1 || regno == i)
- regcache_raw_collect (regcache, i,
- FPREG_ADDR (fpregsetp,
- i - gdbarch_fp0_regnum (gdbarch)));
-
- /* Fill in the floating-point control registers. */
- for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
- if (regno == -1 || regno == i)
- regcache_raw_collect (regcache, i,
- &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
-}
-
-#ifdef HAVE_PTRACE_GETREGS
-
-/* Fetch all floating-point registers from process/thread TID and store
- thier values in GDB's register array. */
-
-static void
-fetch_fpregs (struct regcache *regcache, int tid)
-{
- elf_fpregset_t fpregs;
-
- if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
- perror_with_name (_("Couldn't get floating point status"));
-
- supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
-}
-
-/* Store all valid floating-point registers in GDB's register array
- into the process/thread specified by TID. */
-
-static void
-store_fpregs (const struct regcache *regcache, int tid, int regno)
-{
- elf_fpregset_t fpregs;
-
- if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
- perror_with_name (_("Couldn't get floating point status"));
-
- fill_fpregset (regcache, &fpregs, regno);
-
- if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
- perror_with_name (_("Couldn't write floating point status"));
-}
-
-#else
-
-static void fetch_fpregs (struct regcache *regcache, int tid)
-{
-}
-
-static void store_fpregs (const struct regcache *regcache, int tid, int regno)
-{
-}
-
-#endif
-\f
-/* Transferring arbitrary registers between GDB and inferior. */
-
-/* Fetch register REGNO from the child process. If REGNO is -1, do
- this for all registers (including the floating point and SSE
- registers). */
-
-static void
-m68k_linux_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- int tid;
-
- /* Use the old method of peeking around in `struct user' if the
- GETREGS request isn't available. */
- if (! have_ptrace_getregs)
- {
- old_fetch_inferior_registers (regcache, regno);
- return;
- }
-
- /* GNU/Linux LWP ID's are process ID's. */
- tid = ptid_get_lwp (inferior_ptid);
- if (tid == 0)
- tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
-
- /* Use the PTRACE_GETFPXREGS request whenever possible, since it
- transfers more registers in one system call, and we'll cache the
- results. But remember that fetch_fpxregs can fail, and return
- zero. */
- if (regno == -1)
- {
- fetch_regs (regcache, tid);
-
- /* The call above might reset `have_ptrace_getregs'. */
- if (! have_ptrace_getregs)
- {
- old_fetch_inferior_registers (regcache, -1);
- return;
- }
-
- fetch_fpregs (regcache, tid);
- return;
- }
-
- if (getregs_supplies (regno))
- {
- fetch_regs (regcache, tid);
- return;
- }
-
- if (getfpregs_supplies (regno))
- {
- fetch_fpregs (regcache, tid);
- return;
- }
-
- internal_error (__FILE__, __LINE__,
- _("Got request for bad register number %d."), regno);
-}
-
-/* Store register REGNO back into the child process. If REGNO is -1,
- do this for all registers (including the floating point and SSE
- registers). */
-static void
-m68k_linux_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- int tid;
-
- /* Use the old method of poking around in `struct user' if the
- SETREGS request isn't available. */
- if (! have_ptrace_getregs)
- {
- old_store_inferior_registers (regcache, regno);
- return;
- }
-
- /* GNU/Linux LWP ID's are process ID's. */
- tid = ptid_get_lwp (inferior_ptid);
- if (tid == 0)
- tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
-
- /* Use the PTRACE_SETFPREGS requests whenever possible, since it
- transfers more registers in one system call. But remember that
- store_fpregs can fail, and return zero. */
- if (regno == -1)
- {
- store_regs (regcache, tid, regno);
- store_fpregs (regcache, tid, regno);
- return;
- }
-
- if (getregs_supplies (regno))
- {
- store_regs (regcache, tid, regno);
- return;
- }
-
- if (getfpregs_supplies (regno))
- {
- store_fpregs (regcache, tid, regno);
- return;
- }
-
- internal_error (__FILE__, __LINE__,
- _("Got request to store bad register number %d."), regno);
-}
-\f
-
-/* Fetch the thread-local storage pointer for libthread_db. */
-
-ps_err_e
-ps_get_thread_area (struct ps_prochandle *ph,
- lwpid_t lwpid, int idx, void **base)
-{
- if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) < 0)
- return PS_ERR;
-
- /* IDX is the bias from the thread pointer to the beginning of the
- thread descriptor. It has to be subtracted due to implementation
- quirks in libthread_db. */
- *base = (char *) *base - idx;
-
- return PS_OK;
-}
-\f
-
-void _initialize_m68k_linux_nat (void);
-
-void
-_initialize_m68k_linux_nat (void)
-{
- struct target_ops *t;
-
- /* Fill in the generic GNU/Linux methods. */
- t = linux_target ();
-
- /* Add our register access methods. */
- t->to_fetch_registers = m68k_linux_fetch_inferior_registers;
- t->to_store_registers = m68k_linux_store_inferior_registers;
-
- /* Register the target. */
- linux_nat_add_target (t);
-}
+++ /dev/null
-/* Motorola m68k target-dependent support for GNU/Linux.
-
- Copyright (C) 1996-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "doublest.h"
-#include "floatformat.h"
-#include "frame.h"
-#include "target.h"
-#include "gdbtypes.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "objfiles.h"
-#include "symtab.h"
-#include "m68k-tdep.h"
-#include "trad-frame.h"
-#include "frame-unwind.h"
-#include "glibc-tdep.h"
-#include "solib-svr4.h"
-#include "auxv.h"
-#include "observer.h"
-#include "elf/common.h"
-#include "linux-tdep.h"
-#include "regset.h"
-\f
-/* Offsets (in target ints) into jmp_buf. */
-
-#define M68K_LINUX_JB_ELEMENT_SIZE 4
-#define M68K_LINUX_JB_PC 7
-
-/* Check whether insn1 and insn2 are parts of a signal trampoline. */
-
-#define IS_SIGTRAMP(insn1, insn2) \
- (/* addaw #20,sp; moveq #119,d0; trap #0 */ \
- (insn1 == 0xdefc0014 && insn2 == 0x70774e40) \
- /* moveq #119,d0; trap #0 */ \
- || insn1 == 0x70774e40)
-
-#define IS_RT_SIGTRAMP(insn1, insn2) \
- (/* movel #173,d0; trap #0 */ \
- (insn1 == 0x203c0000 && insn2 == 0x00ad4e40) \
- /* moveq #82,d0; notb d0; trap #0 */ \
- || (insn1 == 0x70524600 && (insn2 >> 16) == 0x4e40))
-
-/* Return non-zero if THIS_FRAME corresponds to a signal trampoline. For
- the sake of m68k_linux_get_sigtramp_info we also distinguish between
- non-RT and RT signal trampolines. */
-
-static int
-m68k_linux_pc_in_sigtramp (struct frame_info *this_frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[12];
- unsigned long insn0, insn1, insn2;
- CORE_ADDR pc = get_frame_pc (this_frame);
-
- if (!safe_frame_unwind_memory (this_frame, pc - 4, buf, sizeof (buf)))
- return 0;
- insn1 = extract_unsigned_integer (buf + 4, 4, byte_order);
- insn2 = extract_unsigned_integer (buf + 8, 4, byte_order);
- if (IS_SIGTRAMP (insn1, insn2))
- return 1;
- if (IS_RT_SIGTRAMP (insn1, insn2))
- return 2;
-
- insn0 = extract_unsigned_integer (buf, 4, byte_order);
- if (IS_SIGTRAMP (insn0, insn1))
- return 1;
- if (IS_RT_SIGTRAMP (insn0, insn1))
- return 2;
-
- insn0 = ((insn0 << 16) & 0xffffffff) | (insn1 >> 16);
- insn1 = ((insn1 << 16) & 0xffffffff) | (insn2 >> 16);
- if (IS_SIGTRAMP (insn0, insn1))
- return 1;
- if (IS_RT_SIGTRAMP (insn0, insn1))
- return 2;
-
- return 0;
-}
-
-/* From <asm/sigcontext.h>. */
-static int m68k_linux_sigcontext_reg_offset[M68K_NUM_REGS] =
-{
- 2 * 4, /* %d0 */
- 3 * 4, /* %d1 */
- -1, /* %d2 */
- -1, /* %d3 */
- -1, /* %d4 */
- -1, /* %d5 */
- -1, /* %d6 */
- -1, /* %d7 */
- 4 * 4, /* %a0 */
- 5 * 4, /* %a1 */
- -1, /* %a2 */
- -1, /* %a3 */
- -1, /* %a4 */
- -1, /* %a5 */
- -1, /* %fp */
- 1 * 4, /* %sp */
- 6 * 4, /* %sr */
- 6 * 4 + 2, /* %pc */
- 8 * 4, /* %fp0 */
- 11 * 4, /* %fp1 */
- -1, /* %fp2 */
- -1, /* %fp3 */
- -1, /* %fp4 */
- -1, /* %fp5 */
- -1, /* %fp6 */
- -1, /* %fp7 */
- 14 * 4, /* %fpcr */
- 15 * 4, /* %fpsr */
- 16 * 4 /* %fpiaddr */
-};
-
-static int m68k_uclinux_sigcontext_reg_offset[M68K_NUM_REGS] =
-{
- 2 * 4, /* %d0 */
- 3 * 4, /* %d1 */
- -1, /* %d2 */
- -1, /* %d3 */
- -1, /* %d4 */
- -1, /* %d5 */
- -1, /* %d6 */
- -1, /* %d7 */
- 4 * 4, /* %a0 */
- 5 * 4, /* %a1 */
- -1, /* %a2 */
- -1, /* %a3 */
- -1, /* %a4 */
- 6 * 4, /* %a5 */
- -1, /* %fp */
- 1 * 4, /* %sp */
- 7 * 4, /* %sr */
- 7 * 4 + 2, /* %pc */
- -1, /* %fp0 */
- -1, /* %fp1 */
- -1, /* %fp2 */
- -1, /* %fp3 */
- -1, /* %fp4 */
- -1, /* %fp5 */
- -1, /* %fp6 */
- -1, /* %fp7 */
- -1, /* %fpcr */
- -1, /* %fpsr */
- -1 /* %fpiaddr */
-};
-
-/* From <asm/ucontext.h>. */
-static int m68k_linux_ucontext_reg_offset[M68K_NUM_REGS] =
-{
- 6 * 4, /* %d0 */
- 7 * 4, /* %d1 */
- 8 * 4, /* %d2 */
- 9 * 4, /* %d3 */
- 10 * 4, /* %d4 */
- 11 * 4, /* %d5 */
- 12 * 4, /* %d6 */
- 13 * 4, /* %d7 */
- 14 * 4, /* %a0 */
- 15 * 4, /* %a1 */
- 16 * 4, /* %a2 */
- 17 * 4, /* %a3 */
- 18 * 4, /* %a4 */
- 19 * 4, /* %a5 */
- 20 * 4, /* %fp */
- 21 * 4, /* %sp */
- 23 * 4, /* %sr */
- 22 * 4, /* %pc */
- 27 * 4, /* %fp0 */
- 30 * 4, /* %fp1 */
- 33 * 4, /* %fp2 */
- 36 * 4, /* %fp3 */
- 39 * 4, /* %fp4 */
- 42 * 4, /* %fp5 */
- 45 * 4, /* %fp6 */
- 48 * 4, /* %fp7 */
- 24 * 4, /* %fpcr */
- 25 * 4, /* %fpsr */
- 26 * 4 /* %fpiaddr */
-};
-
-
-/* Get info about saved registers in sigtramp. */
-
-struct m68k_linux_sigtramp_info
-{
- /* Address of sigcontext. */
- CORE_ADDR sigcontext_addr;
-
- /* Offset of registers in `struct sigcontext'. */
- int *sc_reg_offset;
-};
-
-/* Nonzero if running on uClinux. */
-static int target_is_uclinux;
-
-static void
-m68k_linux_inferior_created (struct target_ops *objfile, int from_tty)
-{
- /* Record that we will need to re-evaluate whether we are running on a
- uClinux or normal GNU/Linux target (see m68k_linux_get_sigtramp_info). */
- target_is_uclinux = -1;
-}
-
-static struct m68k_linux_sigtramp_info
-m68k_linux_get_sigtramp_info (struct frame_info *this_frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp;
- struct m68k_linux_sigtramp_info info;
-
- /* Determine whether we are running on a uClinux or normal GNU/Linux
- target so we can use the correct sigcontext layouts. */
- if (target_is_uclinux == -1)
- target_is_uclinux = linux_is_uclinux ();
-
- sp = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM);
-
- /* Get sigcontext address, it is the third parameter on the stack. */
- info.sigcontext_addr = read_memory_unsigned_integer (sp + 8, 4, byte_order);
-
- if (m68k_linux_pc_in_sigtramp (this_frame) == 2)
- info.sc_reg_offset = m68k_linux_ucontext_reg_offset;
- else
- info.sc_reg_offset = (target_is_uclinux
- ? m68k_uclinux_sigcontext_reg_offset
- : m68k_linux_sigcontext_reg_offset);
- return info;
-}
-
-/* Signal trampolines. */
-
-static struct trad_frame_cache *
-m68k_linux_sigtramp_frame_cache (struct frame_info *this_frame,
- void **this_cache)
-{
- struct frame_id this_id;
- struct trad_frame_cache *cache;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct m68k_linux_sigtramp_info info;
- gdb_byte buf[4];
- int i;
-
- if (*this_cache)
- return (struct trad_frame_cache *) *this_cache;
-
- cache = trad_frame_cache_zalloc (this_frame);
-
- /* FIXME: cagney/2004-05-01: This is is long standing broken code.
- The frame ID's code address should be the start-address of the
- signal trampoline and not the current PC within that
- trampoline. */
- get_frame_register (this_frame, M68K_SP_REGNUM, buf);
- /* See the end of m68k_push_dummy_call. */
- this_id = frame_id_build (extract_unsigned_integer (buf, 4, byte_order)
- - 4 + 8, get_frame_pc (this_frame));
- trad_frame_set_id (cache, this_id);
-
- info = m68k_linux_get_sigtramp_info (this_frame);
-
- for (i = 0; i < M68K_NUM_REGS; i++)
- if (info.sc_reg_offset[i] != -1)
- trad_frame_set_reg_addr (cache, i,
- info.sigcontext_addr + info.sc_reg_offset[i]);
-
- *this_cache = cache;
- return cache;
-}
-
-static void
-m68k_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
- void **this_cache,
- struct frame_id *this_id)
-{
- struct trad_frame_cache *cache =
- m68k_linux_sigtramp_frame_cache (this_frame, this_cache);
- trad_frame_get_id (cache, this_id);
-}
-
-static struct value *
-m68k_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
- void **this_cache,
- int regnum)
-{
- /* Make sure we've initialized the cache. */
- struct trad_frame_cache *cache =
- m68k_linux_sigtramp_frame_cache (this_frame, this_cache);
- return trad_frame_get_register (cache, this_frame, regnum);
-}
-
-static int
-m68k_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_prologue_cache)
-{
- return m68k_linux_pc_in_sigtramp (this_frame);
-}
-
-static const struct frame_unwind m68k_linux_sigtramp_frame_unwind =
-{
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- m68k_linux_sigtramp_frame_this_id,
- m68k_linux_sigtramp_frame_prev_register,
- NULL,
- m68k_linux_sigtramp_frame_sniffer
-};
-
-/* Register maps for supply/collect regset functions. */
-
-static const struct regcache_map_entry m68k_linux_gregmap[] =
- {
- { 7, M68K_D1_REGNUM, 4 }, /* d1 ... d7 */
- { 7, M68K_A0_REGNUM, 4 }, /* a0 ... a6 */
- { 1, M68K_D0_REGNUM, 4 },
- { 1, M68K_SP_REGNUM, 4 },
- { 1, REGCACHE_MAP_SKIP, 4 }, /* orig_d0 (skip) */
- { 1, M68K_PS_REGNUM, 4 },
- { 1, M68K_PC_REGNUM, 4 },
- /* Ignore 16-bit fields 'fmtvec' and '__fill'. */
- { 0 }
- };
-
-#define M68K_LINUX_GREGS_SIZE (20 * 4)
-
-static const struct regcache_map_entry m68k_linux_fpregmap[] =
- {
- { 8, M68K_FP0_REGNUM, 12 }, /* fp0 ... fp7 */
- { 1, M68K_FPC_REGNUM, 4 },
- { 1, M68K_FPS_REGNUM, 4 },
- { 1, M68K_FPI_REGNUM, 4 },
- { 0 }
- };
-
-#define M68K_LINUX_FPREGS_SIZE (27 * 4)
-
-/* Register sets. */
-
-static const struct regset m68k_linux_gregset =
- {
- m68k_linux_gregmap,
- regcache_supply_regset, regcache_collect_regset
- };
-
-static const struct regset m68k_linux_fpregset =
- {
- m68k_linux_fpregmap,
- regcache_supply_regset, regcache_collect_regset
- };
-
-/* Iterate over core file register note sections. */
-
-static void
-m68k_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", M68K_LINUX_GREGS_SIZE, &m68k_linux_gregset, NULL, cb_data);
- cb (".reg2", M68K_LINUX_FPREGS_SIZE, &m68k_linux_fpregset, NULL, cb_data);
-}
-
-static void
-m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- linux_init_abi (info, gdbarch);
-
- tdep->jb_pc = M68K_LINUX_JB_PC;
- tdep->jb_elt_size = M68K_LINUX_JB_ELEMENT_SIZE;
-
- /* GNU/Linux uses a calling convention that's similar to SVR4. It
- returns integer values in %d0/%d1, pointer values in %a0 and
- floating values in %fp0, just like SVR4, but uses %a1 to pass the
- address to store a structure value. It also returns small
- structures in registers instead of memory. */
- m68k_svr4_init_abi (info, gdbarch);
- tdep->struct_value_regnum = M68K_A1_REGNUM;
- tdep->struct_return = reg_struct_return;
-
- set_gdbarch_decr_pc_after_break (gdbarch, 2);
-
- frame_unwind_append_unwinder (gdbarch, &m68k_linux_sigtramp_frame_unwind);
-
- /* Shared library handling. */
-
- /* GNU/Linux uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_ilp32_fetch_link_map_offsets);
-
- /* GNU/Linux uses the dynamic linker included in the GNU C Library. */
- set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
-
- set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-
- /* Core file support. */
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, m68k_linux_iterate_over_regset_sections);
-
- /* Enable TLS support. */
- set_gdbarch_fetch_tls_load_module_address (gdbarch,
- svr4_fetch_objfile_link_map);
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_m68k_linux_tdep;
-
-void
-_initialize_m68k_linux_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_LINUX,
- m68k_linux_init_abi);
- observer_attach_inferior_created (m68k_linux_inferior_created);
-}
--- /dev/null
+/* Native-dependent code for Motorola 88000 BSD's.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "m88k-tdep.h"
+#include "inf-ptrace.h"
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+m88kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ int regnum;
+
+ for (regnum = 0; regnum < M88K_NUM_REGS; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+m88kbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = 0; i < M88K_NUM_REGS; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 4);
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+static void
+m88kbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ m88kbsd_supply_gregset (regcache, ®s);
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers. */
+
+static void
+m88kbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ m88kbsd_collect_gregset (regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_m88kbsd_nat (void);
+
+void
+_initialize_m88kbsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = m88kbsd_fetch_inferior_registers;
+ t->to_store_registers = m88kbsd_store_inferior_registers;
+ add_target (t);
+}
+++ /dev/null
-/* Native-dependent code for Motorola 88000 BSD's.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "m88k-tdep.h"
-#include "inf-ptrace.h"
-
-/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
-
-static void
-m88kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
-{
- const char *regs = gregs;
- int regnum;
-
- for (regnum = 0; regnum < M88K_NUM_REGS; regnum++)
- regcache_raw_supply (regcache, regnum, regs + regnum * 4);
-}
-
-/* Collect the general-purpose registers from REGCACHE and store them
- in GREGS. */
-
-static void
-m88kbsd_collect_gregset (const struct regcache *regcache,
- void *gregs, int regnum)
-{
- char *regs = gregs;
- int i;
-
- for (i = 0; i < M88K_NUM_REGS; i++)
- {
- if (regnum == -1 || regnum == i)
- regcache_raw_collect (regcache, i, regs + i * 4);
- }
-}
-\f
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers. */
-
-static void
-m88kbsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- m88kbsd_supply_gregset (regcache, ®s);
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers. */
-
-static void
-m88kbsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- m88kbsd_collect_gregset (regcache, ®s, regnum);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_m88kbsd_nat (void);
-
-void
-_initialize_m88kbsd_nat (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
- t->to_fetch_registers = m88kbsd_fetch_inferior_registers;
- t->to_store_registers = m88kbsd_store_inferior_registers;
- add_target (t);
-}
--- /dev/null
+/* Native-dependent code for MIPS systems running NetBSD.
+
+ Copyright (C) 2000-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "mips-tdep.h"
+#include "mips-nbsd-tdep.h"
+#include "inf-ptrace.h"
+
+/* Determine if PT_GETREGS fetches this register. */
+static int
+getregs_supplies (struct gdbarch *gdbarch, int regno)
+{
+ return ((regno) >= MIPS_ZERO_REGNUM
+ && (regno) <= gdbarch_pc_regnum (gdbarch));
+}
+
+static void
+mipsnbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ if (regno == -1 || getregs_supplies (gdbarch, regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ mipsnbsd_supply_reg (regcache, (char *) ®s, regno);
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1
+ || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ mipsnbsd_supply_fpreg (regcache, (char *) &fpregs, regno);
+ }
+}
+
+static void
+mipsnbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ if (regno == -1 || getregs_supplies (gdbarch, regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ mipsnbsd_fill_reg (regcache, (char *) ®s, regno);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1
+ || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ mipsnbsd_fill_fpreg (regcache, (char *) &fpregs, regno);
+
+ if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+ }
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_mipsnbsd_nat (void);
+
+void
+_initialize_mipsnbsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = mipsnbsd_fetch_inferior_registers;
+ t->to_store_registers = mipsnbsd_store_inferior_registers;
+ add_target (t);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/mips.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ Contributed by Wasabi Systems, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "regset.h"
+#include "target.h"
+#include "value.h"
+#include "osabi.h"
+
+#include "nbsd-tdep.h"
+#include "mips-nbsd-tdep.h"
+#include "mips-tdep.h"
+
+#include "solib-svr4.h"
+
+/* Shorthand for some register numbers used below. */
+#define MIPS_PC_REGNUM MIPS_EMBED_PC_REGNUM
+#define MIPS_FP0_REGNUM MIPS_EMBED_FP0_REGNUM
+#define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32
+
+/* Core file support. */
+
+/* Number of registers in `struct reg' from <machine/reg.h>. */
+#define MIPSNBSD_NUM_GREGS 38
+
+/* Number of registers in `struct fpreg' from <machine/reg.h>. */
+#define MIPSNBSD_NUM_FPREGS 33
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+mipsnbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ size_t regsize = mips_isa_regsize (get_regcache_arch (regcache));
+ const char *regs = (const char *) fpregs;
+ int i;
+
+ gdb_assert (len >= MIPSNBSD_NUM_FPREGS * regsize);
+
+ for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i,
+ regs + (i - MIPS_FP0_REGNUM) * regsize);
+ }
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+mipsnbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *gregs, size_t len)
+{
+ size_t regsize = mips_isa_regsize (get_regcache_arch (regcache));
+ const char *regs = (const char *) gregs;
+ int i;
+
+ gdb_assert (len >= MIPSNBSD_NUM_GREGS * regsize);
+
+ for (i = 0; i <= MIPS_PC_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + i * regsize);
+ }
+
+ if (len >= (MIPSNBSD_NUM_GREGS + MIPSNBSD_NUM_FPREGS) * regsize)
+ {
+ regs += MIPSNBSD_NUM_GREGS * regsize;
+ len -= MIPSNBSD_NUM_GREGS * regsize;
+ mipsnbsd_supply_fpregset (regset, regcache, regnum, regs, len);
+ }
+}
+
+/* NetBSD/mips register sets. */
+
+static const struct regset mipsnbsd_gregset =
+{
+ NULL,
+ mipsnbsd_supply_gregset,
+ NULL,
+ REGSET_VARIABLE_SIZE
+};
+
+static const struct regset mipsnbsd_fpregset =
+{
+ NULL,
+ mipsnbsd_supply_fpregset
+};
+
+/* Iterate over core file register note sections. */
+
+static void
+mipsnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ size_t regsize = mips_isa_regsize (gdbarch);
+
+ cb (".reg", MIPSNBSD_NUM_GREGS * regsize, &mipsnbsd_gregset,
+ NULL, cb_data);
+ cb (".reg2", MIPSNBSD_NUM_FPREGS * regsize, &mipsnbsd_fpregset,
+ NULL, cb_data);
+}
+\f
+
+/* Conveniently, GDB uses the same register numbering as the
+ ptrace register structure used by NetBSD/mips. */
+
+void
+mipsnbsd_supply_reg (struct regcache *regcache, const char *regs, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ int i;
+
+ for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
+ {
+ if (regno == i || regno == -1)
+ {
+ if (gdbarch_cannot_fetch_register (gdbarch, i))
+ regcache_raw_supply (regcache, i, NULL);
+ else
+ regcache_raw_supply (regcache, i,
+ regs + (i * mips_isa_regsize (gdbarch)));
+ }
+ }
+}
+
+void
+mipsnbsd_fill_reg (const struct regcache *regcache, char *regs, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ int i;
+
+ for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
+ if ((regno == i || regno == -1)
+ && ! gdbarch_cannot_store_register (gdbarch, i))
+ regcache_raw_collect (regcache, i,
+ regs + (i * mips_isa_regsize (gdbarch)));
+}
+
+void
+mipsnbsd_supply_fpreg (struct regcache *regcache,
+ const char *fpregs, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ int i;
+
+ for (i = gdbarch_fp0_regnum (gdbarch);
+ i <= mips_regnum (gdbarch)->fp_implementation_revision;
+ i++)
+ {
+ if (regno == i || regno == -1)
+ {
+ if (gdbarch_cannot_fetch_register (gdbarch, i))
+ regcache_raw_supply (regcache, i, NULL);
+ else
+ regcache_raw_supply (regcache, i,
+ fpregs
+ + ((i - gdbarch_fp0_regnum (gdbarch))
+ * mips_isa_regsize (gdbarch)));
+ }
+ }
+}
+
+void
+mipsnbsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ int i;
+
+ for (i = gdbarch_fp0_regnum (gdbarch);
+ i <= mips_regnum (gdbarch)->fp_control_status;
+ i++)
+ if ((regno == i || regno == -1)
+ && ! gdbarch_cannot_store_register (gdbarch, i))
+ regcache_raw_collect (regcache, i,
+ fpregs + ((i - gdbarch_fp0_regnum (gdbarch))
+ * mips_isa_regsize (gdbarch)));
+}
+
+#if 0
+
+/* Under NetBSD/mips, signal handler invocations can be identified by the
+ designated code sequence that is used to return from a signal handler.
+ In particular, the return address of a signal handler points to the
+ following code sequence:
+
+ addu a0, sp, 16
+ li v0, 295 # __sigreturn14
+ syscall
+
+ Each instruction has a unique encoding, so we simply attempt to match
+ the instruction the PC is pointing to with any of the above instructions.
+ If there is a hit, we know the offset to the start of the designated
+ sequence and can then check whether we really are executing in the
+ signal trampoline. If not, -1 is returned, otherwise the offset from the
+ start of the return sequence is returned. */
+
+#define RETCODE_NWORDS 3
+#define RETCODE_SIZE (RETCODE_NWORDS * 4)
+
+static const unsigned char sigtramp_retcode_mipsel[RETCODE_SIZE] =
+{
+ 0x10, 0x00, 0xa4, 0x27, /* addu a0, sp, 16 */
+ 0x27, 0x01, 0x02, 0x24, /* li v0, 295 */
+ 0x0c, 0x00, 0x00, 0x00, /* syscall */
+};
+
+static const unsigned char sigtramp_retcode_mipseb[RETCODE_SIZE] =
+{
+ 0x27, 0xa4, 0x00, 0x10, /* addu a0, sp, 16 */
+ 0x24, 0x02, 0x01, 0x27, /* li v0, 295 */
+ 0x00, 0x00, 0x00, 0x0c, /* syscall */
+};
+
+#endif
+
+/* Figure out where the longjmp will land. We expect that we have
+ just entered longjmp and haven't yet setup the stack frame, so the
+ args are still in the argument regs. MIPS_A0_REGNUM points at the
+ jmp_buf structure from which we extract the PC that we will land
+ at. The PC is copied into *pc. This routine returns true on
+ success. */
+
+#define NBSD_MIPS_JB_PC (2 * 4)
+#define NBSD_MIPS_JB_ELEMENT_SIZE(gdbarch) mips_isa_regsize (gdbarch)
+#define NBSD_MIPS_JB_OFFSET(gdbarch) (NBSD_MIPS_JB_PC * \
+ NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch))
+
+static int
+mipsnbsd_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR jb_addr;
+ gdb_byte *buf;
+
+ buf = (gdb_byte *) alloca (NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch));
+
+ jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
+
+ if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET (gdbarch), buf,
+ NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch)))
+ return 0;
+
+ *pc = extract_unsigned_integer (buf, NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch),
+ byte_order);
+ return 1;
+}
+
+static int
+mipsnbsd_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
+{
+ return (regno == MIPS_ZERO_REGNUM
+ || regno == mips_regnum (gdbarch)->fp_implementation_revision);
+}
+
+static int
+mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno)
+{
+ return (regno == MIPS_ZERO_REGNUM
+ || regno == mips_regnum (gdbarch)->fp_implementation_revision);
+}
+
+/* Shared library support. */
+
+/* NetBSD/mips uses a slightly different `struct link_map' than the
+ other NetBSD platforms. */
+
+static struct link_map_offsets *
+mipsnbsd_ilp32_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 4;
+ lmo.r_brk_offset = 8;
+ lmo.r_ldsomap_offset = -1;
+
+ /* Everything we need is in the first 24 bytes. */
+ lmo.link_map_size = 24;
+ lmo.l_addr_offset = 4;
+ lmo.l_name_offset = 8;
+ lmo.l_ld_offset = 12;
+ lmo.l_next_offset = 16;
+ lmo.l_prev_offset = 20;
+ }
+
+ return lmp;
+}
+
+static struct link_map_offsets *
+mipsnbsd_lp64_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 8;
+ lmo.r_brk_offset = 16;
+ lmo.r_ldsomap_offset = -1;
+
+ /* Everything we need is in the first 40 bytes. */
+ lmo.link_map_size = 48;
+ lmo.l_addr_offset = 0;
+ lmo.l_name_offset = 16;
+ lmo.l_ld_offset = 24;
+ lmo.l_next_offset = 32;
+ lmo.l_prev_offset = 40;
+ }
+
+ return lmp;
+}
+\f
+
+static void
+mipsnbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, mipsnbsd_iterate_over_regset_sections);
+
+ set_gdbarch_get_longjmp_target (gdbarch, mipsnbsd_get_longjmp_target);
+
+ set_gdbarch_cannot_fetch_register (gdbarch, mipsnbsd_cannot_fetch_register);
+ set_gdbarch_cannot_store_register (gdbarch, mipsnbsd_cannot_store_register);
+
+ set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
+
+ /* NetBSD/mips has SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
+ mipsnbsd_ilp32_fetch_link_map_offsets :
+ mipsnbsd_lp64_fetch_link_map_offsets));
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_mipsnbsd_tdep;
+
+void
+_initialize_mipsnbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_NETBSD_ELF,
+ mipsnbsd_init_abi);
+}
--- /dev/null
+/* Common target dependent code for GDB on MIPS systems running NetBSD.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef MIPS_NBSD_TDEP_H
+#define MIPS_NBSD_TDEP_H
+
+void mipsnbsd_supply_reg (struct regcache *, const char *, int);
+void mipsnbsd_fill_reg (const struct regcache *, char *, int);
+
+void mipsnbsd_supply_fpreg (struct regcache *, const char *, int);
+void mipsnbsd_fill_fpreg (const struct regcache *, char *, int);
+
+#endif /* MIPS_NBSD_TDEP_H */
--- /dev/null
+/* Native-dependent code for OpenBSD/mips64.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "mips-tdep.h"
+#include "inf-ptrace.h"
+#include "obsd-nat.h"
+
+/* Shorthand for some register numbers used below. */
+#define MIPS_PC_REGNUM MIPS_EMBED_PC_REGNUM
+#define MIPS_FP0_REGNUM MIPS_EMBED_FP0_REGNUM
+#define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+mips64obsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ int regnum;
+
+ for (regnum = MIPS_ZERO_REGNUM; regnum <= MIPS_PC_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 8);
+
+ for (regnum = MIPS_FP0_REGNUM; regnum <= MIPS_FSR_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + (regnum + 2) * 8);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+mips64obsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = MIPS_ZERO_REGNUM; i <= MIPS_PC_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 8);
+ }
+
+ for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + (i + 2) * 8);
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+static void
+mips64obsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ mips64obsd_supply_gregset (regcache, ®s);
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers. */
+
+static void
+mips64obsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ mips64obsd_collect_gregset (regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_mips64obsd_nat (void);
+
+void
+_initialize_mips64obsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = mips64obsd_fetch_inferior_registers;
+ t->to_store_registers = mips64obsd_store_inferior_registers;
+ obsd_add_target (t);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/mips64.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbtypes.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+
+#include "obsd-tdep.h"
+#include "mips-tdep.h"
+#include "solib-svr4.h"
+
+/* The MIPS64 Floating-Point Quad-Precision format is similar to
+ big-endian IA-64 Quad-Precision format. */
+#define floatformats_mips64_quad floatformats_ia64_quad
+
+#define MIPS64OBSD_NUM_REGS 73
+
+/* Core file support. */
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+mips64obsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *gregs, size_t len)
+{
+ const char *regs = (const char *) gregs;
+ int i;
+
+ for (i = 0; i < MIPS64OBSD_NUM_REGS; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + i * 8);
+ }
+}
+
+/* OpenBSD/mips64 register set. */
+
+static const struct regset mips64obsd_gregset =
+{
+ NULL,
+ mips64obsd_supply_gregset
+};
+
+/* Iterate over core file register note sections. */
+
+static void
+mips64obsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", MIPS64OBSD_NUM_REGS * 8, &mips64obsd_gregset, NULL, cb_data);
+}
+\f
+
+/* Signal trampolines. */
+
+static void
+mips64obsd_sigframe_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *cache,
+ CORE_ADDR func)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ CORE_ADDR sp, sigcontext_addr, addr;
+ int regnum;
+
+ /* We find the appropriate instance of `struct sigcontext' at a
+ fixed offset in the signal frame. */
+ sp = get_frame_register_signed (this_frame,
+ MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch));
+ sigcontext_addr = sp + 32;
+
+ /* PC. */
+ regnum = mips_regnum (gdbarch)->pc;
+ trad_frame_set_reg_addr (cache,
+ regnum + gdbarch_num_regs (gdbarch),
+ sigcontext_addr + 16);
+
+ /* GPRs. */
+ for (regnum = MIPS_AT_REGNUM, addr = sigcontext_addr + 32;
+ regnum <= MIPS_RA_REGNUM; regnum++, addr += 8)
+ trad_frame_set_reg_addr (cache,
+ regnum + gdbarch_num_regs (gdbarch),
+ addr);
+
+ /* HI and LO. */
+ regnum = mips_regnum (gdbarch)->lo;
+ trad_frame_set_reg_addr (cache,
+ regnum + gdbarch_num_regs (gdbarch),
+ sigcontext_addr + 280);
+ regnum = mips_regnum (gdbarch)->hi;
+ trad_frame_set_reg_addr (cache,
+ regnum + gdbarch_num_regs (gdbarch),
+ sigcontext_addr + 288);
+
+ /* TODO: Handle the floating-point registers. */
+
+ trad_frame_set_id (cache, frame_id_build (sp, func));
+}
+
+static const struct tramp_frame mips64obsd_sigframe =
+{
+ SIGTRAMP_FRAME,
+ MIPS_INSN32_SIZE,
+ {
+ { 0x67a40020, -1 }, /* daddiu a0,sp,32 */
+ { 0x24020067, -1 }, /* li v0,103 */
+ { 0x0000000c, -1 }, /* syscall */
+ { 0x0000000d, -1 }, /* break */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ mips64obsd_sigframe_init
+};
+
+\f
+static void
+mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* OpenBSD/mips64 only supports the n64 ABI, but the braindamaged
+ way GDB works, forces us to pretend we can handle them all. */
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, mips64obsd_iterate_over_regset_sections);
+
+ tramp_frame_prepend_unwinder (gdbarch, &mips64obsd_sigframe);
+
+ set_gdbarch_long_double_bit (gdbarch, 128);
+ set_gdbarch_long_double_format (gdbarch, floatformats_mips64_quad);
+
+ obsd_init_abi(info, gdbarch);
+
+ /* OpenBSD/mips64 has SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+}
+
+\f
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_mips64obsd_tdep (void);
+
+void
+_initialize_mips64obsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_OPENBSD_ELF,
+ mips64obsd_init_abi);
+}
+++ /dev/null
-/* Native-dependent code for OpenBSD/mips64.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "mips-tdep.h"
-#include "inf-ptrace.h"
-#include "obsd-nat.h"
-
-/* Shorthand for some register numbers used below. */
-#define MIPS_PC_REGNUM MIPS_EMBED_PC_REGNUM
-#define MIPS_FP0_REGNUM MIPS_EMBED_FP0_REGNUM
-#define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32
-
-/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
-
-static void
-mips64obsd_supply_gregset (struct regcache *regcache, const void *gregs)
-{
- const char *regs = gregs;
- int regnum;
-
- for (regnum = MIPS_ZERO_REGNUM; regnum <= MIPS_PC_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum, regs + regnum * 8);
-
- for (regnum = MIPS_FP0_REGNUM; regnum <= MIPS_FSR_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum, regs + (regnum + 2) * 8);
-}
-
-/* Collect the general-purpose registers from REGCACHE and store them
- in GREGS. */
-
-static void
-mips64obsd_collect_gregset (const struct regcache *regcache,
- void *gregs, int regnum)
-{
- char *regs = gregs;
- int i;
-
- for (i = MIPS_ZERO_REGNUM; i <= MIPS_PC_REGNUM; i++)
- {
- if (regnum == -1 || regnum == i)
- regcache_raw_collect (regcache, i, regs + i * 8);
- }
-
- for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++)
- {
- if (regnum == -1 || regnum == i)
- regcache_raw_collect (regcache, i, regs + (i + 2) * 8);
- }
-}
-\f
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers. */
-
-static void
-mips64obsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- mips64obsd_supply_gregset (regcache, ®s);
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers. */
-
-static void
-mips64obsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- mips64obsd_collect_gregset (regcache, ®s, regnum);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_mips64obsd_nat (void);
-
-void
-_initialize_mips64obsd_nat (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
- t->to_fetch_registers = mips64obsd_fetch_inferior_registers;
- t->to_store_registers = mips64obsd_store_inferior_registers;
- obsd_add_target (t);
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/mips64.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbtypes.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "trad-frame.h"
-#include "tramp-frame.h"
-
-#include "obsd-tdep.h"
-#include "mips-tdep.h"
-#include "solib-svr4.h"
-
-/* The MIPS64 Floating-Point Quad-Precision format is similar to
- big-endian IA-64 Quad-Precision format. */
-#define floatformats_mips64_quad floatformats_ia64_quad
-
-#define MIPS64OBSD_NUM_REGS 73
-
-/* Core file support. */
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-mips64obsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *gregs, size_t len)
-{
- const char *regs = (const char *) gregs;
- int i;
-
- for (i = 0; i < MIPS64OBSD_NUM_REGS; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + i * 8);
- }
-}
-
-/* OpenBSD/mips64 register set. */
-
-static const struct regset mips64obsd_gregset =
-{
- NULL,
- mips64obsd_supply_gregset
-};
-
-/* Iterate over core file register note sections. */
-
-static void
-mips64obsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", MIPS64OBSD_NUM_REGS * 8, &mips64obsd_gregset, NULL, cb_data);
-}
-\f
-
-/* Signal trampolines. */
-
-static void
-mips64obsd_sigframe_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *cache,
- CORE_ADDR func)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- CORE_ADDR sp, sigcontext_addr, addr;
- int regnum;
-
- /* We find the appropriate instance of `struct sigcontext' at a
- fixed offset in the signal frame. */
- sp = get_frame_register_signed (this_frame,
- MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch));
- sigcontext_addr = sp + 32;
-
- /* PC. */
- regnum = mips_regnum (gdbarch)->pc;
- trad_frame_set_reg_addr (cache,
- regnum + gdbarch_num_regs (gdbarch),
- sigcontext_addr + 16);
-
- /* GPRs. */
- for (regnum = MIPS_AT_REGNUM, addr = sigcontext_addr + 32;
- regnum <= MIPS_RA_REGNUM; regnum++, addr += 8)
- trad_frame_set_reg_addr (cache,
- regnum + gdbarch_num_regs (gdbarch),
- addr);
-
- /* HI and LO. */
- regnum = mips_regnum (gdbarch)->lo;
- trad_frame_set_reg_addr (cache,
- regnum + gdbarch_num_regs (gdbarch),
- sigcontext_addr + 280);
- regnum = mips_regnum (gdbarch)->hi;
- trad_frame_set_reg_addr (cache,
- regnum + gdbarch_num_regs (gdbarch),
- sigcontext_addr + 288);
-
- /* TODO: Handle the floating-point registers. */
-
- trad_frame_set_id (cache, frame_id_build (sp, func));
-}
-
-static const struct tramp_frame mips64obsd_sigframe =
-{
- SIGTRAMP_FRAME,
- MIPS_INSN32_SIZE,
- {
- { 0x67a40020, -1 }, /* daddiu a0,sp,32 */
- { 0x24020067, -1 }, /* li v0,103 */
- { 0x0000000c, -1 }, /* syscall */
- { 0x0000000d, -1 }, /* break */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- mips64obsd_sigframe_init
-};
-
-\f
-static void
-mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- /* OpenBSD/mips64 only supports the n64 ABI, but the braindamaged
- way GDB works, forces us to pretend we can handle them all. */
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, mips64obsd_iterate_over_regset_sections);
-
- tramp_frame_prepend_unwinder (gdbarch, &mips64obsd_sigframe);
-
- set_gdbarch_long_double_bit (gdbarch, 128);
- set_gdbarch_long_double_format (gdbarch, floatformats_mips64_quad);
-
- obsd_init_abi(info, gdbarch);
-
- /* OpenBSD/mips64 has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-}
-
-\f
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_mips64obsd_tdep (void);
-
-void
-_initialize_mips64obsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_OPENBSD_ELF,
- mips64obsd_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for MIPS systems running NetBSD.
-
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "mips-tdep.h"
-#include "mipsnbsd-tdep.h"
-#include "inf-ptrace.h"
-
-/* Determine if PT_GETREGS fetches this register. */
-static int
-getregs_supplies (struct gdbarch *gdbarch, int regno)
-{
- return ((regno) >= MIPS_ZERO_REGNUM
- && (regno) <= gdbarch_pc_regnum (gdbarch));
-}
-
-static void
-mipsnbsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- if (regno == -1 || getregs_supplies (gdbarch, regno))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- mipsnbsd_supply_reg (regcache, (char *) ®s, regno);
- if (regno != -1)
- return;
- }
-
- if (regno == -1
- || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- mipsnbsd_supply_fpreg (regcache, (char *) &fpregs, regno);
- }
-}
-
-static void
-mipsnbsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- if (regno == -1 || getregs_supplies (gdbarch, regno))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- mipsnbsd_fill_reg (regcache, (char *) ®s, regno);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-
- if (regno != -1)
- return;
- }
-
- if (regno == -1
- || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- mipsnbsd_fill_fpreg (regcache, (char *) &fpregs, regno);
-
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't write floating point status"));
- }
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_mipsnbsd_nat (void);
-
-void
-_initialize_mipsnbsd_nat (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
- t->to_fetch_registers = mipsnbsd_fetch_inferior_registers;
- t->to_store_registers = mipsnbsd_store_inferior_registers;
- add_target (t);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/mips.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- Contributed by Wasabi Systems, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "regset.h"
-#include "target.h"
-#include "value.h"
-#include "osabi.h"
-
-#include "nbsd-tdep.h"
-#include "mipsnbsd-tdep.h"
-#include "mips-tdep.h"
-
-#include "solib-svr4.h"
-
-/* Shorthand for some register numbers used below. */
-#define MIPS_PC_REGNUM MIPS_EMBED_PC_REGNUM
-#define MIPS_FP0_REGNUM MIPS_EMBED_FP0_REGNUM
-#define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32
-
-/* Core file support. */
-
-/* Number of registers in `struct reg' from <machine/reg.h>. */
-#define MIPSNBSD_NUM_GREGS 38
-
-/* Number of registers in `struct fpreg' from <machine/reg.h>. */
-#define MIPSNBSD_NUM_FPREGS 33
-
-/* Supply register REGNUM from the buffer specified by FPREGS and LEN
- in the floating-point register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-mipsnbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- size_t regsize = mips_isa_regsize (get_regcache_arch (regcache));
- const char *regs = (const char *) fpregs;
- int i;
-
- gdb_assert (len >= MIPSNBSD_NUM_FPREGS * regsize);
-
- for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i,
- regs + (i - MIPS_FP0_REGNUM) * regsize);
- }
-}
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-mipsnbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *gregs, size_t len)
-{
- size_t regsize = mips_isa_regsize (get_regcache_arch (regcache));
- const char *regs = (const char *) gregs;
- int i;
-
- gdb_assert (len >= MIPSNBSD_NUM_GREGS * regsize);
-
- for (i = 0; i <= MIPS_PC_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + i * regsize);
- }
-
- if (len >= (MIPSNBSD_NUM_GREGS + MIPSNBSD_NUM_FPREGS) * regsize)
- {
- regs += MIPSNBSD_NUM_GREGS * regsize;
- len -= MIPSNBSD_NUM_GREGS * regsize;
- mipsnbsd_supply_fpregset (regset, regcache, regnum, regs, len);
- }
-}
-
-/* NetBSD/mips register sets. */
-
-static const struct regset mipsnbsd_gregset =
-{
- NULL,
- mipsnbsd_supply_gregset,
- NULL,
- REGSET_VARIABLE_SIZE
-};
-
-static const struct regset mipsnbsd_fpregset =
-{
- NULL,
- mipsnbsd_supply_fpregset
-};
-
-/* Iterate over core file register note sections. */
-
-static void
-mipsnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- size_t regsize = mips_isa_regsize (gdbarch);
-
- cb (".reg", MIPSNBSD_NUM_GREGS * regsize, &mipsnbsd_gregset,
- NULL, cb_data);
- cb (".reg2", MIPSNBSD_NUM_FPREGS * regsize, &mipsnbsd_fpregset,
- NULL, cb_data);
-}
-\f
-
-/* Conveniently, GDB uses the same register numbering as the
- ptrace register structure used by NetBSD/mips. */
-
-void
-mipsnbsd_supply_reg (struct regcache *regcache, const char *regs, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- int i;
-
- for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
- {
- if (regno == i || regno == -1)
- {
- if (gdbarch_cannot_fetch_register (gdbarch, i))
- regcache_raw_supply (regcache, i, NULL);
- else
- regcache_raw_supply (regcache, i,
- regs + (i * mips_isa_regsize (gdbarch)));
- }
- }
-}
-
-void
-mipsnbsd_fill_reg (const struct regcache *regcache, char *regs, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- int i;
-
- for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
- if ((regno == i || regno == -1)
- && ! gdbarch_cannot_store_register (gdbarch, i))
- regcache_raw_collect (regcache, i,
- regs + (i * mips_isa_regsize (gdbarch)));
-}
-
-void
-mipsnbsd_supply_fpreg (struct regcache *regcache,
- const char *fpregs, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- int i;
-
- for (i = gdbarch_fp0_regnum (gdbarch);
- i <= mips_regnum (gdbarch)->fp_implementation_revision;
- i++)
- {
- if (regno == i || regno == -1)
- {
- if (gdbarch_cannot_fetch_register (gdbarch, i))
- regcache_raw_supply (regcache, i, NULL);
- else
- regcache_raw_supply (regcache, i,
- fpregs
- + ((i - gdbarch_fp0_regnum (gdbarch))
- * mips_isa_regsize (gdbarch)));
- }
- }
-}
-
-void
-mipsnbsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- int i;
-
- for (i = gdbarch_fp0_regnum (gdbarch);
- i <= mips_regnum (gdbarch)->fp_control_status;
- i++)
- if ((regno == i || regno == -1)
- && ! gdbarch_cannot_store_register (gdbarch, i))
- regcache_raw_collect (regcache, i,
- fpregs + ((i - gdbarch_fp0_regnum (gdbarch))
- * mips_isa_regsize (gdbarch)));
-}
-
-#if 0
-
-/* Under NetBSD/mips, signal handler invocations can be identified by the
- designated code sequence that is used to return from a signal handler.
- In particular, the return address of a signal handler points to the
- following code sequence:
-
- addu a0, sp, 16
- li v0, 295 # __sigreturn14
- syscall
-
- Each instruction has a unique encoding, so we simply attempt to match
- the instruction the PC is pointing to with any of the above instructions.
- If there is a hit, we know the offset to the start of the designated
- sequence and can then check whether we really are executing in the
- signal trampoline. If not, -1 is returned, otherwise the offset from the
- start of the return sequence is returned. */
-
-#define RETCODE_NWORDS 3
-#define RETCODE_SIZE (RETCODE_NWORDS * 4)
-
-static const unsigned char sigtramp_retcode_mipsel[RETCODE_SIZE] =
-{
- 0x10, 0x00, 0xa4, 0x27, /* addu a0, sp, 16 */
- 0x27, 0x01, 0x02, 0x24, /* li v0, 295 */
- 0x0c, 0x00, 0x00, 0x00, /* syscall */
-};
-
-static const unsigned char sigtramp_retcode_mipseb[RETCODE_SIZE] =
-{
- 0x27, 0xa4, 0x00, 0x10, /* addu a0, sp, 16 */
- 0x24, 0x02, 0x01, 0x27, /* li v0, 295 */
- 0x00, 0x00, 0x00, 0x0c, /* syscall */
-};
-
-#endif
-
-/* Figure out where the longjmp will land. We expect that we have
- just entered longjmp and haven't yet setup the stack frame, so the
- args are still in the argument regs. MIPS_A0_REGNUM points at the
- jmp_buf structure from which we extract the PC that we will land
- at. The PC is copied into *pc. This routine returns true on
- success. */
-
-#define NBSD_MIPS_JB_PC (2 * 4)
-#define NBSD_MIPS_JB_ELEMENT_SIZE(gdbarch) mips_isa_regsize (gdbarch)
-#define NBSD_MIPS_JB_OFFSET(gdbarch) (NBSD_MIPS_JB_PC * \
- NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch))
-
-static int
-mipsnbsd_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
-{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR jb_addr;
- gdb_byte *buf;
-
- buf = (gdb_byte *) alloca (NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch));
-
- jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
-
- if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET (gdbarch), buf,
- NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch)))
- return 0;
-
- *pc = extract_unsigned_integer (buf, NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch),
- byte_order);
- return 1;
-}
-
-static int
-mipsnbsd_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
-{
- return (regno == MIPS_ZERO_REGNUM
- || regno == mips_regnum (gdbarch)->fp_implementation_revision);
-}
-
-static int
-mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno)
-{
- return (regno == MIPS_ZERO_REGNUM
- || regno == mips_regnum (gdbarch)->fp_implementation_revision);
-}
-
-/* Shared library support. */
-
-/* NetBSD/mips uses a slightly different `struct link_map' than the
- other NetBSD platforms. */
-
-static struct link_map_offsets *
-mipsnbsd_ilp32_fetch_link_map_offsets (void)
-{
- static struct link_map_offsets lmo;
- static struct link_map_offsets *lmp = NULL;
-
- if (lmp == NULL)
- {
- lmp = &lmo;
-
- lmo.r_version_offset = 0;
- lmo.r_version_size = 4;
- lmo.r_map_offset = 4;
- lmo.r_brk_offset = 8;
- lmo.r_ldsomap_offset = -1;
-
- /* Everything we need is in the first 24 bytes. */
- lmo.link_map_size = 24;
- lmo.l_addr_offset = 4;
- lmo.l_name_offset = 8;
- lmo.l_ld_offset = 12;
- lmo.l_next_offset = 16;
- lmo.l_prev_offset = 20;
- }
-
- return lmp;
-}
-
-static struct link_map_offsets *
-mipsnbsd_lp64_fetch_link_map_offsets (void)
-{
- static struct link_map_offsets lmo;
- static struct link_map_offsets *lmp = NULL;
-
- if (lmp == NULL)
- {
- lmp = &lmo;
-
- lmo.r_version_offset = 0;
- lmo.r_version_size = 4;
- lmo.r_map_offset = 8;
- lmo.r_brk_offset = 16;
- lmo.r_ldsomap_offset = -1;
-
- /* Everything we need is in the first 40 bytes. */
- lmo.link_map_size = 48;
- lmo.l_addr_offset = 0;
- lmo.l_name_offset = 16;
- lmo.l_ld_offset = 24;
- lmo.l_next_offset = 32;
- lmo.l_prev_offset = 40;
- }
-
- return lmp;
-}
-\f
-
-static void
-mipsnbsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, mipsnbsd_iterate_over_regset_sections);
-
- set_gdbarch_get_longjmp_target (gdbarch, mipsnbsd_get_longjmp_target);
-
- set_gdbarch_cannot_fetch_register (gdbarch, mipsnbsd_cannot_fetch_register);
- set_gdbarch_cannot_store_register (gdbarch, mipsnbsd_cannot_store_register);
-
- set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
-
- /* NetBSD/mips has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
- mipsnbsd_ilp32_fetch_link_map_offsets :
- mipsnbsd_lp64_fetch_link_map_offsets));
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_mipsnbsd_tdep;
-
-void
-_initialize_mipsnbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_NETBSD_ELF,
- mipsnbsd_init_abi);
-}
+++ /dev/null
-/* Common target dependent code for GDB on MIPS systems running NetBSD.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef MIPSNBSD_TDEP_H
-#define MIPSNBSD_TDEP_H
-
-void mipsnbsd_supply_reg (struct regcache *, const char *, int);
-void mipsnbsd_fill_reg (const struct regcache *, char *, int);
-
-void mipsnbsd_supply_fpreg (struct regcache *, const char *, int);
-void mipsnbsd_fill_fpreg (const struct regcache *, char *, int);
-
-#endif /* MIPSNBSD_TDEP_H */
--- /dev/null
+/* Native-dependent code for PowerPC's running FreeBSD, for GDB.
+
+ Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+#include <sys/signal.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/reg.h>
+
+#include "fbsd-nat.h"
+#include "gregset.h"
+#include "ppc-tdep.h"
+#include "ppc-fbsd-tdep.h"
+#include "inf-ptrace.h"
+#include "bsd-kvm.h"
+
+/* Fill GDB's register array with the general-purpose register values
+ in *GREGSETP. */
+
+void
+supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
+{
+ const struct regset *regset = ppc_fbsd_gregset (sizeof (long));
+
+ ppc_supply_gregset (regset, regcache, -1, gregsetp, sizeof (*gregsetp));
+}
+
+/* Fill register REGNO (if a gpr) in *GREGSETP with the value in GDB's
+ register array. If REGNO is -1 do it for all registers. */
+
+void
+fill_gregset (const struct regcache *regcache,
+ gdb_gregset_t *gregsetp, int regno)
+{
+ const struct regset *regset = ppc_fbsd_gregset (sizeof (long));
+
+ if (regno == -1)
+ memset (gregsetp, 0, sizeof (*gregsetp));
+ ppc_collect_gregset (regset, regcache, regno, gregsetp, sizeof (*gregsetp));
+}
+
+/* Fill GDB's register array with the floating-point register values
+ in *FPREGSETP. */
+
+void
+supply_fpregset (struct regcache *regcache, const gdb_fpregset_t * fpregsetp)
+{
+ const struct regset *regset = ppc_fbsd_fpregset ();
+
+ ppc_supply_fpregset (regset, regcache, -1,
+ fpregsetp, sizeof (*fpregsetp));
+}
+
+/* Fill register REGNO in *FGREGSETP with the value in GDB's
+ register array. If REGNO is -1 do it for all registers. */
+
+void
+fill_fpregset (const struct regcache *regcache,
+ gdb_fpregset_t *fpregsetp, int regno)
+{
+ const struct regset *regset = ppc_fbsd_fpregset ();
+
+ ppc_collect_fpregset (regset, regcache, regno,
+ fpregsetp, sizeof (*fpregsetp));
+}
+
+/* Returns true if PT_GETFPREGS fetches this register. */
+
+static int
+getfpregs_supplies (struct gdbarch *gdbarch, int regno)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
+ point registers. Traditionally, GDB's register set has still
+ listed the floating point registers for such machines, so this
+ code is harmless. However, the new E500 port actually omits the
+ floating point registers entirely from the register set --- they
+ don't even have register numbers assigned to them.
+
+ It's not clear to me how best to update this code, so this assert
+ will alert the first person to encounter the NetBSD/E500
+ combination to the problem. */
+
+ gdb_assert (ppc_floating_point_unit_p (gdbarch));
+
+ return ((regno >= tdep->ppc_fp0_regnum
+ && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
+ || regno == tdep->ppc_fpscr_regnum);
+}
+
+/* Fetch register REGNO from the child process. If REGNO is -1, do it
+ for all registers. */
+
+static void
+ppcfbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ gdb_gregset_t regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_lwp (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ supply_gregset (regcache, ®s);
+
+ if (regno == -1 || getfpregs_supplies (get_regcache_arch (regcache), regno))
+ {
+ const struct regset *fpregset = ppc_fbsd_fpregset ();
+ gdb_fpregset_t fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_lwp (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get FP registers"));
+
+ ppc_supply_fpregset (fpregset, regcache, regno, &fpregs, sizeof fpregs);
+ }
+}
+
+/* Store register REGNO back into the child process. If REGNO is -1,
+ do this for all registers. */
+
+static void
+ppcfbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ gdb_gregset_t regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_lwp (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ fill_gregset (regcache, ®s, regno);
+
+ if (ptrace (PT_SETREGS, ptid_get_lwp (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+
+ if (regno == -1 || getfpregs_supplies (get_regcache_arch (regcache), regno))
+ {
+ gdb_fpregset_t fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_lwp (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get FP registers"));
+
+ fill_fpregset (regcache, &fpregs, regno);
+
+ if (ptrace (PT_SETFPREGS, ptid_get_lwp (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't set FP registers"));
+ }
+}
+
+/* Architecture specific function that reconstructs the
+ register state from PCB (Process Control Block) and supplies it
+ to REGCACHE. */
+
+static int
+ppcfbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int i, regnum;
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ regcache_raw_supply (regcache, gdbarch_sp_regnum (gdbarch), &pcb->pcb_sp);
+ regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &pcb->pcb_cr);
+ regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &pcb->pcb_lr);
+ for (i = 0, regnum = tdep->ppc_gp0_regnum + 14; i < 20; i++, regnum++)
+ regcache_raw_supply (regcache, regnum, &pcb->pcb_context[i]);
+
+ return 1;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+
+void _initialize_ppcfbsd_nat (void);
+
+void
+_initialize_ppcfbsd_nat (void)
+{
+ struct target_ops *t;
+
+ /* Add in local overrides. */
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = ppcfbsd_fetch_inferior_registers;
+ t->to_store_registers = ppcfbsd_store_inferior_registers;
+ fbsd_nat_add_target (t);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (ppcfbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for PowerPC systems running FreeBSD.
+
+ Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "frame-unwind.h"
+#include "gdbtypes.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "symtab.h"
+#include "target.h"
+#include "trad-frame.h"
+
+#include "ppc-tdep.h"
+#include "ppc64-tdep.h"
+#include "ppc-fbsd-tdep.h"
+#include "fbsd-tdep.h"
+#include "solib-svr4.h"
+
+
+/* 32-bit regset descriptions. */
+
+static const struct ppc_reg_offsets ppc32_fbsd_reg_offsets =
+ {
+ /* General-purpose registers. */
+ /* .r0_offset = */ 0,
+ /* .gpr_size = */ 4,
+ /* .xr_size = */ 4,
+ /* .pc_offset = */ 144,
+ /* .ps_offset = */ -1,
+ /* .cr_offset = */ 132,
+ /* .lr_offset = */ 128,
+ /* .ctr_offset = */ 140,
+ /* .xer_offset = */ 136,
+ /* .mq_offset = */ -1,
+
+ /* Floating-point registers. */
+ /* .f0_offset = */ 0,
+ /* .fpscr_offset = */ 256,
+ /* .fpscr_size = */ 8,
+#ifdef NOTYET
+ /* AltiVec registers. */
+ /* .vr0_offset = */ 0,
+ /* .vscr_offset = */ 512 + 12,
+ /* .vrsave_offset = */ 512
+#endif
+ };
+
+/* 64-bit regset descriptions. */
+
+static const struct ppc_reg_offsets ppc64_fbsd_reg_offsets =
+ {
+ /* General-purpose registers. */
+ /* .r0_offset = */ 0,
+ /* .gpr_size = */ 8,
+ /* .xr_size = */ 8,
+ /* .pc_offset = */ 288,
+ /* .ps_offset = */ -1,
+ /* .cr_offset = */ 264,
+ /* .lr_offset = */ 256,
+ /* .ctr_offset = */ 280,
+ /* .xer_offset = */ 272,
+ /* .mq_offset = */ -1,
+
+ /* Floating-point registers. */
+ /* .f0_offset = */ 0,
+ /* .fpscr_offset = */ 256,
+ /* .fpscr_size = */ 8,
+#ifdef NOYET
+ /* AltiVec registers. */
+ /* .vr0_offset = */ 0,
+ /* .vscr_offset = */ 512 + 12,
+ /* .vrsave_offset = */ 528
+#endif
+ };
+
+/* 32-bit general-purpose register set. */
+
+static const struct regset ppc32_fbsd_gregset = {
+ &ppc32_fbsd_reg_offsets,
+ ppc_supply_gregset,
+ ppc_collect_gregset
+};
+
+/* 64-bit general-purpose register set. */
+
+static const struct regset ppc64_fbsd_gregset = {
+ &ppc64_fbsd_reg_offsets,
+ ppc_supply_gregset,
+ ppc_collect_gregset
+};
+
+/* 32-/64-bit floating-point register set. */
+
+static const struct regset ppc32_fbsd_fpregset = {
+ &ppc32_fbsd_reg_offsets,
+ ppc_supply_fpregset,
+ ppc_collect_fpregset
+};
+
+const struct regset *
+ppc_fbsd_gregset (int wordsize)
+{
+ return wordsize == 8 ? &ppc64_fbsd_gregset : &ppc32_fbsd_gregset;
+}
+
+const struct regset *
+ppc_fbsd_fpregset (void)
+{
+ return &ppc32_fbsd_fpregset;
+}
+
+/* Iterate over core file register note sections. */
+
+static void
+ppcfbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (tdep->wordsize == 4)
+ cb (".reg", 148, &ppc32_fbsd_gregset, NULL, cb_data);
+ else
+ cb (".reg", 296, &ppc64_fbsd_gregset, NULL, cb_data);
+ cb (".reg2", 264, &ppc32_fbsd_fpregset, NULL, cb_data);
+}
+
+/* Default page size. */
+
+static const int ppcfbsd_page_size = 4096;
+
+/* Offset for sigreturn(2). */
+
+static const int ppcfbsd_sigreturn_offset[] = {
+ 0xc, /* FreeBSD 32-bit */
+ -1
+};
+
+/* Signal trampolines. */
+
+static int
+ppcfbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ CORE_ADDR start_pc = (pc & ~(ppcfbsd_page_size - 1));
+ const int *offset;
+ const char *name;
+
+ /* A stack trampoline is detected if no name is associated
+ to the current pc and if it points inside a trampoline
+ sequence. */
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+
+ /* If we have a name, we have no trampoline, return. */
+ if (name)
+ return 0;
+
+ for (offset = ppcfbsd_sigreturn_offset; *offset != -1; offset++)
+ {
+ gdb_byte buf[2 * PPC_INSN_SIZE];
+ unsigned long insn;
+
+ if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
+ buf, sizeof buf))
+ continue;
+
+ /* Check for "li r0,SYS_sigreturn". */
+ insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
+ if (insn != 0x380001a1)
+ continue;
+
+ /* Check for "sc". */
+ insn = extract_unsigned_integer (buf + PPC_INSN_SIZE,
+ PPC_INSN_SIZE, byte_order);
+ if (insn != 0x44000002)
+ continue;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static struct trad_frame_cache *
+ppcfbsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ struct trad_frame_cache *cache;
+ CORE_ADDR addr, base, func;
+ gdb_byte buf[PPC_INSN_SIZE];
+ int i;
+
+ if (*this_cache)
+ return (struct trad_frame_cache *) *this_cache;
+
+ cache = trad_frame_cache_zalloc (this_frame);
+ *this_cache = cache;
+
+ func = get_frame_pc (this_frame);
+ func &= ~(ppcfbsd_page_size - 1);
+ if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf))
+ return cache;
+
+ base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
+ addr = base + 0x10 + 2 * tdep->wordsize;
+ for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
+ {
+ int regnum = i + tdep->ppc_gp0_regnum;
+ trad_frame_set_reg_addr (cache, regnum, addr);
+ }
+ trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr);
+ /* SRR0? */
+ addr += tdep->wordsize;
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (cache, frame_id_build (base, func));
+
+ return cache;
+}
+
+static void
+ppcfbsd_sigtramp_frame_this_id (struct frame_info *this_frame,
+ void **this_cache, struct frame_id *this_id)
+{
+ struct trad_frame_cache *cache =
+ ppcfbsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+ppcfbsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct trad_frame_cache *cache =
+ ppcfbsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static const struct frame_unwind ppcfbsd_sigtramp_frame_unwind = {
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ ppcfbsd_sigtramp_frame_this_id,
+ ppcfbsd_sigtramp_frame_prev_register,
+ NULL,
+ ppcfbsd_sigtramp_frame_sniffer
+};
+
+static enum return_value_convention
+ppcfbsd_return_value (struct gdbarch *gdbarch, struct value *function,
+ struct type *valtype, struct regcache *regcache,
+ gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+ return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
+ regcache, readbuf, writebuf);
+}
+
+
+static void
+ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Generic FreeBSD support. */
+ fbsd_init_abi (info, gdbarch);
+
+ /* FreeBSD doesn't support the 128-bit `long double' from the psABI. */
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+
+ if (tdep->wordsize == 4)
+ {
+ set_gdbarch_return_value (gdbarch, ppcfbsd_return_value);
+
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ svr4_ilp32_fetch_link_map_offsets);
+
+ frame_unwind_append_unwinder (gdbarch, &ppcfbsd_sigtramp_frame_unwind);
+ set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
+ }
+
+ if (tdep->wordsize == 8)
+ {
+ set_gdbarch_convert_from_func_ptr_addr
+ (gdbarch, ppc64_convert_from_func_ptr_addr);
+ set_gdbarch_elf_make_msymbol_special (gdbarch,
+ ppc64_elf_make_msymbol_special);
+
+ set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ svr4_lp64_fetch_link_map_offsets);
+ set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
+ }
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, ppcfbsd_iterate_over_regset_sections);
+
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+
+void _initialize_ppcfbsd_tdep (void);
+
+void
+_initialize_ppcfbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc, GDB_OSABI_FREEBSD_ELF,
+ ppcfbsd_init_abi);
+ gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc64,
+ GDB_OSABI_FREEBSD_ELF,
+ ppcfbsd_init_abi);
+ gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_FREEBSD_ELF,
+ ppcfbsd_init_abi);
+}
--- /dev/null
+/* Target-dependent code for GDB on PowerPC systems running FreeBSD.
+
+ Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef PPC_FBSD_TDEP_H
+#define PPC_FBSD_TDEP_H
+
+struct regset;
+
+/* From ppc-fbsd-tdep.c ... */
+const struct regset *ppc_fbsd_gregset (int);
+const struct regset *ppc_fbsd_fpregset (void);
+
+#endif /* PPC_FBSD_TDEP_H */
--- /dev/null
+/* Native-dependent code for NetBSD/powerpc.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ Contributed by Wasabi Systems, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "ppc-tdep.h"
+#include "ppc-nbsd-tdep.h"
+#include "bsd-kvm.h"
+#include "inf-ptrace.h"
+
+/* Returns true if PT_GETREGS fetches this register. */
+
+static int
+getregs_supplies (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ return ((regnum >= tdep->ppc_gp0_regnum
+ && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
+ || regnum == tdep->ppc_lr_regnum
+ || regnum == tdep->ppc_cr_regnum
+ || regnum == tdep->ppc_xer_regnum
+ || regnum == tdep->ppc_ctr_regnum
+ || regnum == gdbarch_pc_regnum (gdbarch));
+}
+
+/* Like above, but for PT_GETFPREGS. */
+
+static int
+getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
+ point registers. Traditionally, GDB's register set has still
+ listed the floating point registers for such machines, so this
+ code is harmless. However, the new E500 port actually omits the
+ floating point registers entirely from the register set --- they
+ don't even have register numbers assigned to them.
+
+ It's not clear to me how best to update this code, so this assert
+ will alert the first person to encounter the NetBSD/E500
+ combination to the problem. */
+ gdb_assert (ppc_floating_point_unit_p (gdbarch));
+
+ return ((regnum >= tdep->ppc_fp0_regnum
+ && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
+ || regnum == tdep->ppc_fpscr_regnum);
+}
+
+static void
+ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ if (regnum == -1 || getregs_supplies (gdbarch, regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ ppc_supply_gregset (&ppcnbsd_gregset, regcache,
+ regnum, ®s, sizeof regs);
+ }
+
+ if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get FP registers"));
+
+ ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
+ regnum, &fpregs, sizeof fpregs);
+ }
+}
+
+static void
+ppcnbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ if (regnum == -1 || getregs_supplies (gdbarch, regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ ppc_collect_gregset (&ppcnbsd_gregset, regcache,
+ regnum, ®s, sizeof regs);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+ }
+
+ if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get FP registers"));
+
+ ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
+ regnum, &fpregs, sizeof fpregs);
+
+ if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't set FP registers"));
+ }
+}
+
+static int
+ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ struct switchframe sf;
+ struct callframe cf;
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int i;
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
+ regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
+ regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
+ for (i = 0 ; i < 19 ; i++)
+ regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i,
+ &sf.fixreg[i]);
+
+ read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
+ regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
+ regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
+ regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp);
+
+ read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
+ regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr);
+ regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
+
+ return 1;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_ppcnbsd_nat (void);
+
+void
+_initialize_ppcnbsd_nat (void)
+{
+ struct target_ops *t;
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (ppcnbsd_supply_pcb);
+
+ /* Add in local overrides. */
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = ppcnbsd_fetch_inferior_registers;
+ t->to_store_registers = ppcnbsd_store_inferior_registers;
+ add_target (t);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/powerpc.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ Contributed by Wasabi Systems, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbtypes.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+
+#include "ppc-tdep.h"
+#include "ppc-nbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Register offsets from <machine/reg.h>. */
+struct ppc_reg_offsets ppcnbsd_reg_offsets;
+\f
+
+/* Core file support. */
+
+/* NetBSD/powerpc register sets. */
+
+const struct regset ppcnbsd_gregset =
+{
+ &ppcnbsd_reg_offsets,
+ ppc_supply_gregset
+};
+
+const struct regset ppcnbsd_fpregset =
+{
+ &ppcnbsd_reg_offsets,
+ ppc_supply_fpregset
+};
+
+/* Iterate over core file register note sections. */
+
+static void
+ppcnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", 148, &ppcnbsd_gregset, NULL, cb_data);
+ cb (".reg2", 264, &ppcnbsd_fpregset, NULL, cb_data);
+}
+\f
+
+/* NetBSD is confused. It appears that 1.5 was using the correct SVR4
+ convention but, 1.6 switched to the below broken convention. For
+ the moment use the broken convention. Ulgh! */
+
+static enum return_value_convention
+ppcnbsd_return_value (struct gdbarch *gdbarch, struct value *function,
+ struct type *valtype, struct regcache *regcache,
+ gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+#if 0
+ if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+ || TYPE_CODE (valtype) == TYPE_CODE_UNION)
+ && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8)
+ && TYPE_VECTOR (valtype))
+ && !(TYPE_LENGTH (valtype) == 1
+ || TYPE_LENGTH (valtype) == 2
+ || TYPE_LENGTH (valtype) == 4
+ || TYPE_LENGTH (valtype) == 8))
+ return RETURN_VALUE_STRUCT_CONVENTION;
+ else
+#endif
+ return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
+ regcache, readbuf, writebuf);
+}
+\f
+
+/* Signal trampolines. */
+
+extern const struct tramp_frame ppcnbsd2_sigtramp;
+
+static void
+ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ CORE_ADDR addr, base;
+ int i;
+
+ base = get_frame_register_unsigned (this_frame,
+ gdbarch_sp_regnum (gdbarch));
+ if (self == &ppcnbsd2_sigtramp)
+ addr = base + 0x10 + 2 * tdep->wordsize;
+ else
+ addr = base + 0x18 + 2 * tdep->wordsize;
+ for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
+ {
+ int regnum = i + tdep->ppc_gp0_regnum;
+ trad_frame_set_reg_addr (this_cache, regnum, addr);
+ }
+ trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (this_cache, gdbarch_pc_regnum (gdbarch),
+ addr); /* SRR0? */
+ addr += tdep->wordsize;
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (this_cache, frame_id_build (base, func));
+}
+
+static const struct tramp_frame ppcnbsd_sigtramp =
+{
+ SIGTRAMP_FRAME,
+ 4,
+ {
+ { 0x3821fff0, -1 }, /* add r1,r1,-16 */
+ { 0x4e800021, -1 }, /* blrl */
+ { 0x38610018, -1 }, /* addi r3,r1,24 */
+ { 0x38000127, -1 }, /* li r0,295 */
+ { 0x44000002, -1 }, /* sc */
+ { 0x38000001, -1 }, /* li r0,1 */
+ { 0x44000002, -1 }, /* sc */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ ppcnbsd_sigtramp_cache_init
+};
+
+/* NetBSD 2.0 introduced a slightly different signal trampoline. */
+
+const struct tramp_frame ppcnbsd2_sigtramp =
+{
+ SIGTRAMP_FRAME,
+ 4,
+ {
+ { 0x3821fff0, -1 }, /* add r1,r1,-16 */
+ { 0x4e800021, -1 }, /* blrl */
+ { 0x38610010, -1 }, /* addi r3,r1,16 */
+ { 0x38000127, -1 }, /* li r0,295 */
+ { 0x44000002, -1 }, /* sc */
+ { 0x38000001, -1 }, /* li r0,1 */
+ { 0x44000002, -1 }, /* sc */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ ppcnbsd_sigtramp_cache_init
+};
+\f
+
+static void
+ppcnbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ /* For NetBSD, this is an on again, off again thing. Some systems
+ do use the broken struct convention, and some don't. */
+ set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
+
+ /* NetBSD uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, ppcnbsd_iterate_over_regset_sections);
+
+ tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp);
+ tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_ppcnbsd_tdep (void);
+
+void
+_initialize_ppcnbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD_ELF,
+ ppcnbsd_init_abi);
+
+ /* Avoid initializing the register offsets again if they were
+ already initialized by ppcnbsd-nat.c. */
+ if (ppcnbsd_reg_offsets.pc_offset == 0)
+ {
+ /* General-purpose registers. */
+ ppcnbsd_reg_offsets.r0_offset = 0;
+ ppcnbsd_reg_offsets.gpr_size = 4;
+ ppcnbsd_reg_offsets.xr_size = 4;
+ ppcnbsd_reg_offsets.lr_offset = 128;
+ ppcnbsd_reg_offsets.cr_offset = 132;
+ ppcnbsd_reg_offsets.xer_offset = 136;
+ ppcnbsd_reg_offsets.ctr_offset = 140;
+ ppcnbsd_reg_offsets.pc_offset = 144;
+ ppcnbsd_reg_offsets.ps_offset = -1;
+ ppcnbsd_reg_offsets.mq_offset = -1;
+
+ /* Floating-point registers. */
+ ppcnbsd_reg_offsets.f0_offset = 0;
+ ppcnbsd_reg_offsets.fpscr_offset = 256;
+ ppcnbsd_reg_offsets.fpscr_size = 4;
+
+ /* AltiVec registers. */
+ ppcnbsd_reg_offsets.vr0_offset = 0;
+ ppcnbsd_reg_offsets.vrsave_offset = 512;
+ ppcnbsd_reg_offsets.vscr_offset = 524;
+ }
+}
--- /dev/null
+/* Target-dependent code for NetBSD/powerpc.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef PPC_NBSD_TDEP_H
+#define PPC_NBSD_TDEP_H
+
+struct regset;
+
+/* Register offsets for NetBSD/powerpc. */
+extern struct ppc_reg_offsets ppcnbsd_reg_offsets;
+
+/* Register sets for NetBSD/powerpc. */
+extern const struct regset ppcnbsd_gregset;
+extern const struct regset ppcnbsd_fpregset;
+
+#endif /* ppc-nbsd-tdep.h */
--- /dev/null
+/* Native-dependent code for OpenBSD/powerpc.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/signal.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/reg.h>
+
+#include "ppc-tdep.h"
+#include "ppc-obsd-tdep.h"
+#include "inf-ptrace.h"
+#include "obsd-nat.h"
+#include "bsd-kvm.h"
+
+/* OpenBSD/powerpc didn't have PT_GETFPREGS/PT_SETFPREGS until release
+ 4.0. On older releases the floating-point registers are handled by
+ PT_GETREGS/PT_SETREGS, but fpscr wasn't available.. */
+
+#ifdef PT_GETFPREGS
+
+/* Returns true if PT_GETFPREGS fetches this register. */
+
+static int
+getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
+ point registers. Traditionally, GDB's register set has still
+ listed the floating point registers for such machines, so this
+ code is harmless. However, the new E500 port actually omits the
+ floating point registers entirely from the register set --- they
+ don't even have register numbers assigned to them.
+
+ It's not clear to me how best to update this code, so this assert
+ will alert the first person to encounter the NetBSD/E500
+ combination to the problem. */
+ gdb_assert (ppc_floating_point_unit_p (gdbarch));
+
+ return ((regnum >= tdep->ppc_fp0_regnum
+ && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
+ || regnum == tdep->ppc_fpscr_regnum);
+}
+
+#endif /* PT_GETFPREGS */
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+static void
+ppcobsd_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ ppc_supply_gregset (&ppcobsd_gregset, regcache, -1,
+ ®s, sizeof regs);
+#ifndef PT_GETFPREGS
+ ppc_supply_fpregset (&ppcobsd_gregset, regcache, -1,
+ ®s, sizeof regs);
+#endif
+
+#ifdef PT_GETFPREGS
+ if (regnum == -1
+ || getfpregs_supplies (get_regcache_arch (regcache), regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ ppc_supply_fpregset (&ppcobsd_fpregset, regcache, -1,
+ &fpregs, sizeof fpregs);
+ }
+#endif
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers. */
+
+static void
+ppcobsd_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ ppc_collect_gregset (&ppcobsd_gregset, regcache,
+ regnum, ®s, sizeof regs);
+#ifndef PT_GETFPREGS
+ ppc_collect_fpregset (&ppcobsd_gregset, regcache,
+ regnum, ®s, sizeof regs);
+#endif
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+
+#ifdef PT_GETFPREGS
+ if (regnum == -1
+ || getfpregs_supplies (get_regcache_arch (regcache), regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ ppc_collect_fpregset (&ppcobsd_fpregset, regcache,
+ regnum, &fpregs, sizeof fpregs);
+
+ if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+ }
+#endif
+}
+\f
+
+static int
+ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ struct switchframe sf;
+ struct callframe cf;
+ int i, regnum;
+
+ /* The following is true for OpenBSD 3.7:
+
+ The pcb contains %r1 (the stack pointer) at the point of the
+ context switch in cpu_switch(). At that point we have a stack
+ frame as described by `struct switchframe', and below that a call
+ frame as described by `struct callframe'. From this information
+ we reconstruct the register state as it would look when we are in
+ cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
+ regcache_raw_supply (regcache, gdbarch_sp_regnum (gdbarch), &sf.sp);
+ regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
+ regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
+ for (i = 0, regnum = tdep->ppc_gp0_regnum + 13; i < 19; i++, regnum++)
+ regcache_raw_supply (regcache, regnum, &sf.fixreg[i]);
+
+ read_memory (sf.sp, (gdb_byte *)&cf, sizeof cf);
+ regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
+ regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
+ regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_ppcobsd_nat (void);
+
+void
+_initialize_ppcobsd_nat (void)
+{
+ struct target_ops *t;
+
+ /* Add in local overrides. */
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = ppcobsd_fetch_registers;
+ t->to_store_registers = ppcobsd_store_registers;
+ obsd_add_target (t);
+
+ /* General-purpose registers. */
+ ppcobsd_reg_offsets.r0_offset = offsetof (struct reg, gpr);
+ ppcobsd_reg_offsets.gpr_size = 4;
+ ppcobsd_reg_offsets.xr_size = 4;
+ ppcobsd_reg_offsets.pc_offset = offsetof (struct reg, pc);
+ ppcobsd_reg_offsets.ps_offset = offsetof (struct reg, ps);
+ ppcobsd_reg_offsets.cr_offset = offsetof (struct reg, cnd);
+ ppcobsd_reg_offsets.lr_offset = offsetof (struct reg, lr);
+ ppcobsd_reg_offsets.ctr_offset = offsetof (struct reg, cnt);
+ ppcobsd_reg_offsets.xer_offset = offsetof (struct reg, xer);
+ ppcobsd_reg_offsets.mq_offset = offsetof (struct reg, mq);
+
+ /* Floating-point registers. */
+ ppcobsd_reg_offsets.f0_offset = offsetof (struct reg, fpr);
+ ppcobsd_reg_offsets.fpscr_offset = -1;
+#ifdef PT_GETFPREGS
+ ppcobsd_fpreg_offsets.f0_offset = offsetof (struct fpreg, fpr);
+ ppcobsd_fpreg_offsets.fpscr_offset = offsetof (struct fpreg, fpscr);
+ ppcobsd_fpreg_offsets.fpscr_size = 4;
+#endif
+
+ /* AltiVec registers. */
+ ppcobsd_reg_offsets.vr0_offset = offsetof (struct vreg, vreg);
+ ppcobsd_reg_offsets.vscr_offset = offsetof (struct vreg, vscr);
+ ppcobsd_reg_offsets.vrsave_offset = offsetof (struct vreg, vrsave);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (ppcobsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/powerpc.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbtypes.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "symtab.h"
+#include "trad-frame.h"
+
+#include "ppc-tdep.h"
+#include "ppc-obsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Register offsets from <machine/reg.h>. */
+struct ppc_reg_offsets ppcobsd_reg_offsets;
+struct ppc_reg_offsets ppcobsd_fpreg_offsets;
+\f
+
+/* Core file support. */
+
+/* Supply register REGNUM in the general-purpose register set REGSET
+ from the buffer specified by GREGS and LEN to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+void
+ppcobsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *gregs, size_t len)
+{
+ ppc_supply_gregset (regset, regcache, regnum, gregs, len);
+ ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+/* Collect register REGNUM in the general-purpose register set
+ REGSET, from register cache REGCACHE into the buffer specified by
+ GREGS and LEN. If REGNUM is -1, do this for all registers in
+ REGSET. */
+
+void
+ppcobsd_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache, int regnum,
+ void *gregs, size_t len)
+{
+ ppc_collect_gregset (regset, regcache, regnum, gregs, len);
+ ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+/* OpenBSD/powerpc register set. */
+
+const struct regset ppcobsd_gregset =
+{
+ &ppcobsd_reg_offsets,
+ ppcobsd_supply_gregset
+};
+
+const struct regset ppcobsd_fpregset =
+{
+ &ppcobsd_fpreg_offsets,
+ ppc_supply_fpregset
+};
+
+/* Iterate over core file register note sections. */
+
+static void
+ppcobsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", 412, &ppcobsd_gregset, NULL, cb_data);
+}
+\f
+
+/* Signal trampolines. */
+
+/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
+ in virtual memory. The randomness makes it somewhat tricky to
+ detect it, but fortunately we can rely on the fact that the start
+ of the sigtramp routine is page-aligned. We recognize the
+ trampoline by looking for the code that invokes the sigreturn
+ system call. The offset where we can find that code varies from
+ release to release.
+
+ By the way, the mapping mentioned above is read-only, so you cannot
+ place a breakpoint in the signal trampoline. */
+
+/* Default page size. */
+static const int ppcobsd_page_size = 4096;
+
+/* Offset for sigreturn(2). */
+static const int ppcobsd_sigreturn_offset[] = {
+ 0x98, /* OpenBSD 3.8 */
+ 0x0c, /* OpenBSD 3.2 */
+ -1
+};
+
+static int
+ppcobsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ CORE_ADDR start_pc = (pc & ~(ppcobsd_page_size - 1));
+ const int *offset;
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (name)
+ return 0;
+
+ for (offset = ppcobsd_sigreturn_offset; *offset != -1; offset++)
+ {
+ gdb_byte buf[2 * PPC_INSN_SIZE];
+ unsigned long insn;
+
+ if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
+ buf, sizeof buf))
+ continue;
+
+ /* Check for "li r0,SYS_sigreturn". */
+ insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
+ if (insn != 0x38000067)
+ continue;
+
+ /* Check for "sc". */
+ insn = extract_unsigned_integer (buf + PPC_INSN_SIZE,
+ PPC_INSN_SIZE, byte_order);
+ if (insn != 0x44000002)
+ continue;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static struct trad_frame_cache *
+ppcobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ struct trad_frame_cache *cache;
+ CORE_ADDR addr, base, func;
+ gdb_byte buf[PPC_INSN_SIZE];
+ unsigned long insn, sigcontext_offset;
+ int i;
+
+ if (*this_cache)
+ return (struct trad_frame_cache *) *this_cache;
+
+ cache = trad_frame_cache_zalloc (this_frame);
+ *this_cache = cache;
+
+ func = get_frame_pc (this_frame);
+ func &= ~(ppcobsd_page_size - 1);
+ if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf))
+ return cache;
+
+ /* Calculate the offset where we can find `struct sigcontext'. We
+ base our calculation on the amount of stack space reserved by the
+ first instruction of the signal trampoline. */
+ insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
+ sigcontext_offset = (0x10000 - (insn & 0x0000ffff)) + 8;
+
+ base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
+ addr = base + sigcontext_offset + 2 * tdep->wordsize;
+ for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
+ {
+ int regnum = i + tdep->ppc_gp0_regnum;
+ trad_frame_set_reg_addr (cache, regnum, addr);
+ }
+ trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr);
+ /* SRR0? */
+ addr += tdep->wordsize;
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (cache, frame_id_build (base, func));
+
+ return cache;
+}
+
+static void
+ppcobsd_sigtramp_frame_this_id (struct frame_info *this_frame,
+ void **this_cache, struct frame_id *this_id)
+{
+ struct trad_frame_cache *cache =
+ ppcobsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+ppcobsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct trad_frame_cache *cache =
+ ppcobsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static const struct frame_unwind ppcobsd_sigtramp_frame_unwind = {
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ ppcobsd_sigtramp_frame_this_id,
+ ppcobsd_sigtramp_frame_prev_register,
+ NULL,
+ ppcobsd_sigtramp_frame_sniffer
+};
+\f
+
+static void
+ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* OpenBSD doesn't support the 128-bit `long double' from the psABI. */
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+
+ /* OpenBSD currently uses a broken GCC. */
+ set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value);
+
+ /* OpenBSD uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, ppcobsd_iterate_over_regset_sections);
+
+ frame_unwind_append_unwinder (gdbarch, &ppcobsd_sigtramp_frame_unwind);
+}
+\f
+
+/* OpenBSD uses uses the traditional NetBSD core file format, even for
+ ports that use ELF. */
+#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
+
+static enum gdb_osabi
+ppcobsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_CORE;
+
+ return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_ppcobsd_tdep (void);
+
+void
+_initialize_ppcobsd_tdep (void)
+{
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_powerpc, bfd_target_unknown_flavour,
+ ppcobsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_OPENBSD_ELF,
+ ppcobsd_init_abi);
+ gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_OPENBSD_ELF,
+ ppcobsd_init_abi);
+
+ /* Avoid initializing the register offsets again if they were
+ already initialized by ppcobsd-nat.c. */
+ if (ppcobsd_reg_offsets.pc_offset == 0)
+ {
+ /* General-purpose registers. */
+ ppcobsd_reg_offsets.r0_offset = 0;
+ ppcobsd_reg_offsets.gpr_size = 4;
+ ppcobsd_reg_offsets.xr_size = 4;
+ ppcobsd_reg_offsets.pc_offset = 384;
+ ppcobsd_reg_offsets.ps_offset = 388;
+ ppcobsd_reg_offsets.cr_offset = 392;
+ ppcobsd_reg_offsets.lr_offset = 396;
+ ppcobsd_reg_offsets.ctr_offset = 400;
+ ppcobsd_reg_offsets.xer_offset = 404;
+ ppcobsd_reg_offsets.mq_offset = 408;
+
+ /* Floating-point registers. */
+ ppcobsd_reg_offsets.f0_offset = 128;
+ ppcobsd_reg_offsets.fpscr_offset = -1;
+
+ /* AltiVec registers. */
+ ppcobsd_reg_offsets.vr0_offset = 0;
+ ppcobsd_reg_offsets.vscr_offset = 512;
+ ppcobsd_reg_offsets.vrsave_offset = 520;
+ }
+
+ if (ppcobsd_fpreg_offsets.fpscr_offset == 0)
+ {
+ /* Floating-point registers. */
+ ppcobsd_reg_offsets.f0_offset = 0;
+ ppcobsd_reg_offsets.fpscr_offset = 256;
+ ppcobsd_reg_offsets.fpscr_size = 4;
+ }
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/powerpc.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef PPC_OBSD_TDEP_H
+#define PPC_OBSD_TDEP_H
+
+struct regset;
+struct regcache;
+
+/* Register offsets for OpenBSD/powerpc. */
+extern struct ppc_reg_offsets ppcobsd_reg_offsets;
+extern struct ppc_reg_offsets ppcobsd_fpreg_offsets;
+
+/* Register sets for OpenBSD/powerpc. */
+extern const struct regset ppcobsd_gregset;
+extern const struct regset ppcobsd_fpregset;
+\f
+
+/* Supply register REGNUM in the general-purpose register set REGSET
+ from the buffer specified by GREGS and LEN to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+extern void ppcobsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *gregs, size_t len);
+
+/* Collect register REGNUM in the general-purpose register set
+ REGSET, from register cache REGCACHE into the buffer specified by
+ GREGS and LEN. If REGNUM is -1, do this for all registers in
+ REGSET. */
+
+extern void ppcobsd_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *gregs, size_t len);
+
+#endif /* ppc-obsd-tdep.h */
+++ /dev/null
-/* Native-dependent code for PowerPC's running FreeBSD, for GDB.
-
- Copyright (C) 2013-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#include <sys/types.h>
-#include <sys/procfs.h>
-#include <sys/ptrace.h>
-#include <sys/signal.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-#include <machine/reg.h>
-
-#include "fbsd-nat.h"
-#include "gregset.h"
-#include "ppc-tdep.h"
-#include "ppcfbsd-tdep.h"
-#include "inf-ptrace.h"
-#include "bsd-kvm.h"
-
-/* Fill GDB's register array with the general-purpose register values
- in *GREGSETP. */
-
-void
-supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
-{
- const struct regset *regset = ppc_fbsd_gregset (sizeof (long));
-
- ppc_supply_gregset (regset, regcache, -1, gregsetp, sizeof (*gregsetp));
-}
-
-/* Fill register REGNO (if a gpr) in *GREGSETP with the value in GDB's
- register array. If REGNO is -1 do it for all registers. */
-
-void
-fill_gregset (const struct regcache *regcache,
- gdb_gregset_t *gregsetp, int regno)
-{
- const struct regset *regset = ppc_fbsd_gregset (sizeof (long));
-
- if (regno == -1)
- memset (gregsetp, 0, sizeof (*gregsetp));
- ppc_collect_gregset (regset, regcache, regno, gregsetp, sizeof (*gregsetp));
-}
-
-/* Fill GDB's register array with the floating-point register values
- in *FPREGSETP. */
-
-void
-supply_fpregset (struct regcache *regcache, const gdb_fpregset_t * fpregsetp)
-{
- const struct regset *regset = ppc_fbsd_fpregset ();
-
- ppc_supply_fpregset (regset, regcache, -1,
- fpregsetp, sizeof (*fpregsetp));
-}
-
-/* Fill register REGNO in *FGREGSETP with the value in GDB's
- register array. If REGNO is -1 do it for all registers. */
-
-void
-fill_fpregset (const struct regcache *regcache,
- gdb_fpregset_t *fpregsetp, int regno)
-{
- const struct regset *regset = ppc_fbsd_fpregset ();
-
- ppc_collect_fpregset (regset, regcache, regno,
- fpregsetp, sizeof (*fpregsetp));
-}
-
-/* Returns true if PT_GETFPREGS fetches this register. */
-
-static int
-getfpregs_supplies (struct gdbarch *gdbarch, int regno)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
- point registers. Traditionally, GDB's register set has still
- listed the floating point registers for such machines, so this
- code is harmless. However, the new E500 port actually omits the
- floating point registers entirely from the register set --- they
- don't even have register numbers assigned to them.
-
- It's not clear to me how best to update this code, so this assert
- will alert the first person to encounter the NetBSD/E500
- combination to the problem. */
-
- gdb_assert (ppc_floating_point_unit_p (gdbarch));
-
- return ((regno >= tdep->ppc_fp0_regnum
- && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
- || regno == tdep->ppc_fpscr_regnum);
-}
-
-/* Fetch register REGNO from the child process. If REGNO is -1, do it
- for all registers. */
-
-static void
-ppcfbsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- gdb_gregset_t regs;
-
- if (ptrace (PT_GETREGS, ptid_get_lwp (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- supply_gregset (regcache, ®s);
-
- if (regno == -1 || getfpregs_supplies (get_regcache_arch (regcache), regno))
- {
- const struct regset *fpregset = ppc_fbsd_fpregset ();
- gdb_fpregset_t fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_lwp (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get FP registers"));
-
- ppc_supply_fpregset (fpregset, regcache, regno, &fpregs, sizeof fpregs);
- }
-}
-
-/* Store register REGNO back into the child process. If REGNO is -1,
- do this for all registers. */
-
-static void
-ppcfbsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- gdb_gregset_t regs;
-
- if (ptrace (PT_GETREGS, ptid_get_lwp (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- fill_gregset (regcache, ®s, regno);
-
- if (ptrace (PT_SETREGS, ptid_get_lwp (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-
- if (regno == -1 || getfpregs_supplies (get_regcache_arch (regcache), regno))
- {
- gdb_fpregset_t fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_lwp (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get FP registers"));
-
- fill_fpregset (regcache, &fpregs, regno);
-
- if (ptrace (PT_SETFPREGS, ptid_get_lwp (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't set FP registers"));
- }
-}
-
-/* Architecture specific function that reconstructs the
- register state from PCB (Process Control Block) and supplies it
- to REGCACHE. */
-
-static int
-ppcfbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int i, regnum;
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- regcache_raw_supply (regcache, gdbarch_sp_regnum (gdbarch), &pcb->pcb_sp);
- regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &pcb->pcb_cr);
- regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &pcb->pcb_lr);
- for (i = 0, regnum = tdep->ppc_gp0_regnum + 14; i < 20; i++, regnum++)
- regcache_raw_supply (regcache, regnum, &pcb->pcb_context[i]);
-
- return 1;
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-
-void _initialize_ppcfbsd_nat (void);
-
-void
-_initialize_ppcfbsd_nat (void)
-{
- struct target_ops *t;
-
- /* Add in local overrides. */
- t = inf_ptrace_target ();
- t->to_fetch_registers = ppcfbsd_fetch_inferior_registers;
- t->to_store_registers = ppcfbsd_store_inferior_registers;
- fbsd_nat_add_target (t);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (ppcfbsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for PowerPC systems running FreeBSD.
-
- Copyright (C) 2013-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "frame-unwind.h"
-#include "gdbtypes.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "symtab.h"
-#include "target.h"
-#include "trad-frame.h"
-
-#include "ppc-tdep.h"
-#include "ppc64-tdep.h"
-#include "ppcfbsd-tdep.h"
-#include "fbsd-tdep.h"
-#include "solib-svr4.h"
-
-
-/* 32-bit regset descriptions. */
-
-static const struct ppc_reg_offsets ppc32_fbsd_reg_offsets =
- {
- /* General-purpose registers. */
- /* .r0_offset = */ 0,
- /* .gpr_size = */ 4,
- /* .xr_size = */ 4,
- /* .pc_offset = */ 144,
- /* .ps_offset = */ -1,
- /* .cr_offset = */ 132,
- /* .lr_offset = */ 128,
- /* .ctr_offset = */ 140,
- /* .xer_offset = */ 136,
- /* .mq_offset = */ -1,
-
- /* Floating-point registers. */
- /* .f0_offset = */ 0,
- /* .fpscr_offset = */ 256,
- /* .fpscr_size = */ 8,
-#ifdef NOTYET
- /* AltiVec registers. */
- /* .vr0_offset = */ 0,
- /* .vscr_offset = */ 512 + 12,
- /* .vrsave_offset = */ 512
-#endif
- };
-
-/* 64-bit regset descriptions. */
-
-static const struct ppc_reg_offsets ppc64_fbsd_reg_offsets =
- {
- /* General-purpose registers. */
- /* .r0_offset = */ 0,
- /* .gpr_size = */ 8,
- /* .xr_size = */ 8,
- /* .pc_offset = */ 288,
- /* .ps_offset = */ -1,
- /* .cr_offset = */ 264,
- /* .lr_offset = */ 256,
- /* .ctr_offset = */ 280,
- /* .xer_offset = */ 272,
- /* .mq_offset = */ -1,
-
- /* Floating-point registers. */
- /* .f0_offset = */ 0,
- /* .fpscr_offset = */ 256,
- /* .fpscr_size = */ 8,
-#ifdef NOYET
- /* AltiVec registers. */
- /* .vr0_offset = */ 0,
- /* .vscr_offset = */ 512 + 12,
- /* .vrsave_offset = */ 528
-#endif
- };
-
-/* 32-bit general-purpose register set. */
-
-static const struct regset ppc32_fbsd_gregset = {
- &ppc32_fbsd_reg_offsets,
- ppc_supply_gregset,
- ppc_collect_gregset
-};
-
-/* 64-bit general-purpose register set. */
-
-static const struct regset ppc64_fbsd_gregset = {
- &ppc64_fbsd_reg_offsets,
- ppc_supply_gregset,
- ppc_collect_gregset
-};
-
-/* 32-/64-bit floating-point register set. */
-
-static const struct regset ppc32_fbsd_fpregset = {
- &ppc32_fbsd_reg_offsets,
- ppc_supply_fpregset,
- ppc_collect_fpregset
-};
-
-const struct regset *
-ppc_fbsd_gregset (int wordsize)
-{
- return wordsize == 8 ? &ppc64_fbsd_gregset : &ppc32_fbsd_gregset;
-}
-
-const struct regset *
-ppc_fbsd_fpregset (void)
-{
- return &ppc32_fbsd_fpregset;
-}
-
-/* Iterate over core file register note sections. */
-
-static void
-ppcfbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- if (tdep->wordsize == 4)
- cb (".reg", 148, &ppc32_fbsd_gregset, NULL, cb_data);
- else
- cb (".reg", 296, &ppc64_fbsd_gregset, NULL, cb_data);
- cb (".reg2", 264, &ppc32_fbsd_fpregset, NULL, cb_data);
-}
-
-/* Default page size. */
-
-static const int ppcfbsd_page_size = 4096;
-
-/* Offset for sigreturn(2). */
-
-static const int ppcfbsd_sigreturn_offset[] = {
- 0xc, /* FreeBSD 32-bit */
- -1
-};
-
-/* Signal trampolines. */
-
-static int
-ppcfbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR pc = get_frame_pc (this_frame);
- CORE_ADDR start_pc = (pc & ~(ppcfbsd_page_size - 1));
- const int *offset;
- const char *name;
-
- /* A stack trampoline is detected if no name is associated
- to the current pc and if it points inside a trampoline
- sequence. */
-
- find_pc_partial_function (pc, &name, NULL, NULL);
-
- /* If we have a name, we have no trampoline, return. */
- if (name)
- return 0;
-
- for (offset = ppcfbsd_sigreturn_offset; *offset != -1; offset++)
- {
- gdb_byte buf[2 * PPC_INSN_SIZE];
- unsigned long insn;
-
- if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
- buf, sizeof buf))
- continue;
-
- /* Check for "li r0,SYS_sigreturn". */
- insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
- if (insn != 0x380001a1)
- continue;
-
- /* Check for "sc". */
- insn = extract_unsigned_integer (buf + PPC_INSN_SIZE,
- PPC_INSN_SIZE, byte_order);
- if (insn != 0x44000002)
- continue;
-
- return 1;
- }
-
- return 0;
-}
-
-static struct trad_frame_cache *
-ppcfbsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- struct trad_frame_cache *cache;
- CORE_ADDR addr, base, func;
- gdb_byte buf[PPC_INSN_SIZE];
- int i;
-
- if (*this_cache)
- return (struct trad_frame_cache *) *this_cache;
-
- cache = trad_frame_cache_zalloc (this_frame);
- *this_cache = cache;
-
- func = get_frame_pc (this_frame);
- func &= ~(ppcfbsd_page_size - 1);
- if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf))
- return cache;
-
- base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
- addr = base + 0x10 + 2 * tdep->wordsize;
- for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
- {
- int regnum = i + tdep->ppc_gp0_regnum;
- trad_frame_set_reg_addr (cache, regnum, addr);
- }
- trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr);
- /* SRR0? */
- addr += tdep->wordsize;
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (cache, frame_id_build (base, func));
-
- return cache;
-}
-
-static void
-ppcfbsd_sigtramp_frame_this_id (struct frame_info *this_frame,
- void **this_cache, struct frame_id *this_id)
-{
- struct trad_frame_cache *cache =
- ppcfbsd_sigtramp_frame_cache (this_frame, this_cache);
-
- trad_frame_get_id (cache, this_id);
-}
-
-static struct value *
-ppcfbsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct trad_frame_cache *cache =
- ppcfbsd_sigtramp_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_register (cache, this_frame, regnum);
-}
-
-static const struct frame_unwind ppcfbsd_sigtramp_frame_unwind = {
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- ppcfbsd_sigtramp_frame_this_id,
- ppcfbsd_sigtramp_frame_prev_register,
- NULL,
- ppcfbsd_sigtramp_frame_sniffer
-};
-
-static enum return_value_convention
-ppcfbsd_return_value (struct gdbarch *gdbarch, struct value *function,
- struct type *valtype, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
-{
- return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
- regcache, readbuf, writebuf);
-}
-
-
-static void
-ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Generic FreeBSD support. */
- fbsd_init_abi (info, gdbarch);
-
- /* FreeBSD doesn't support the 128-bit `long double' from the psABI. */
- set_gdbarch_long_double_bit (gdbarch, 64);
- set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
-
- if (tdep->wordsize == 4)
- {
- set_gdbarch_return_value (gdbarch, ppcfbsd_return_value);
-
- set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_ilp32_fetch_link_map_offsets);
-
- frame_unwind_append_unwinder (gdbarch, &ppcfbsd_sigtramp_frame_unwind);
- set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
- }
-
- if (tdep->wordsize == 8)
- {
- set_gdbarch_convert_from_func_ptr_addr
- (gdbarch, ppc64_convert_from_func_ptr_addr);
- set_gdbarch_elf_make_msymbol_special (gdbarch,
- ppc64_elf_make_msymbol_special);
-
- set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_lp64_fetch_link_map_offsets);
- set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
- }
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, ppcfbsd_iterate_over_regset_sections);
-
- set_gdbarch_fetch_tls_load_module_address (gdbarch,
- svr4_fetch_objfile_link_map);
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-
-void _initialize_ppcfbsd_tdep (void);
-
-void
-_initialize_ppcfbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc, GDB_OSABI_FREEBSD_ELF,
- ppcfbsd_init_abi);
- gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc64,
- GDB_OSABI_FREEBSD_ELF,
- ppcfbsd_init_abi);
- gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_FREEBSD_ELF,
- ppcfbsd_init_abi);
-}
+++ /dev/null
-/* Target-dependent code for GDB on PowerPC systems running FreeBSD.
-
- Copyright (C) 2013-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef PPCFBSD_TDEP_H
-#define PPCFBSD_TDEP_H
-
-struct regset;
-
-/* From ppcfbsd-tdep.c ... */
-const struct regset *ppc_fbsd_gregset (int);
-const struct regset *ppc_fbsd_fpregset (void);
-
-#endif /* PPCFBSD_TDEP_H */
+++ /dev/null
-/* Native-dependent code for NetBSD/powerpc.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- Contributed by Wasabi Systems, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-
-#include "gdbcore.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#include "ppc-tdep.h"
-#include "ppcnbsd-tdep.h"
-#include "bsd-kvm.h"
-#include "inf-ptrace.h"
-
-/* Returns true if PT_GETREGS fetches this register. */
-
-static int
-getregs_supplies (struct gdbarch *gdbarch, int regnum)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- return ((regnum >= tdep->ppc_gp0_regnum
- && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
- || regnum == tdep->ppc_lr_regnum
- || regnum == tdep->ppc_cr_regnum
- || regnum == tdep->ppc_xer_regnum
- || regnum == tdep->ppc_ctr_regnum
- || regnum == gdbarch_pc_regnum (gdbarch));
-}
-
-/* Like above, but for PT_GETFPREGS. */
-
-static int
-getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
- point registers. Traditionally, GDB's register set has still
- listed the floating point registers for such machines, so this
- code is harmless. However, the new E500 port actually omits the
- floating point registers entirely from the register set --- they
- don't even have register numbers assigned to them.
-
- It's not clear to me how best to update this code, so this assert
- will alert the first person to encounter the NetBSD/E500
- combination to the problem. */
- gdb_assert (ppc_floating_point_unit_p (gdbarch));
-
- return ((regnum >= tdep->ppc_fp0_regnum
- && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
- || regnum == tdep->ppc_fpscr_regnum);
-}
-
-static void
-ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
-
- if (regnum == -1 || getregs_supplies (gdbarch, regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- ppc_supply_gregset (&ppcnbsd_gregset, regcache,
- regnum, ®s, sizeof regs);
- }
-
- if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get FP registers"));
-
- ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
- regnum, &fpregs, sizeof fpregs);
- }
-}
-
-static void
-ppcnbsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
-
- if (regnum == -1 || getregs_supplies (gdbarch, regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- ppc_collect_gregset (&ppcnbsd_gregset, regcache,
- regnum, ®s, sizeof regs);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
- }
-
- if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get FP registers"));
-
- ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
- regnum, &fpregs, sizeof fpregs);
-
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't set FP registers"));
- }
-}
-
-static int
-ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- struct switchframe sf;
- struct callframe cf;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int i;
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
- regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
- regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
- for (i = 0 ; i < 19 ; i++)
- regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i,
- &sf.fixreg[i]);
-
- read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
- regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
- regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
- regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp);
-
- read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
- regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr);
- regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
-
- return 1;
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_ppcnbsd_nat (void);
-
-void
-_initialize_ppcnbsd_nat (void)
-{
- struct target_ops *t;
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (ppcnbsd_supply_pcb);
-
- /* Add in local overrides. */
- t = inf_ptrace_target ();
- t->to_fetch_registers = ppcnbsd_fetch_inferior_registers;
- t->to_store_registers = ppcnbsd_store_inferior_registers;
- add_target (t);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/powerpc.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- Contributed by Wasabi Systems, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbtypes.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "trad-frame.h"
-#include "tramp-frame.h"
-
-#include "ppc-tdep.h"
-#include "ppcnbsd-tdep.h"
-#include "solib-svr4.h"
-
-/* Register offsets from <machine/reg.h>. */
-struct ppc_reg_offsets ppcnbsd_reg_offsets;
-\f
-
-/* Core file support. */
-
-/* NetBSD/powerpc register sets. */
-
-const struct regset ppcnbsd_gregset =
-{
- &ppcnbsd_reg_offsets,
- ppc_supply_gregset
-};
-
-const struct regset ppcnbsd_fpregset =
-{
- &ppcnbsd_reg_offsets,
- ppc_supply_fpregset
-};
-
-/* Iterate over core file register note sections. */
-
-static void
-ppcnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", 148, &ppcnbsd_gregset, NULL, cb_data);
- cb (".reg2", 264, &ppcnbsd_fpregset, NULL, cb_data);
-}
-\f
-
-/* NetBSD is confused. It appears that 1.5 was using the correct SVR4
- convention but, 1.6 switched to the below broken convention. For
- the moment use the broken convention. Ulgh! */
-
-static enum return_value_convention
-ppcnbsd_return_value (struct gdbarch *gdbarch, struct value *function,
- struct type *valtype, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
-{
-#if 0
- if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
- || TYPE_CODE (valtype) == TYPE_CODE_UNION)
- && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8)
- && TYPE_VECTOR (valtype))
- && !(TYPE_LENGTH (valtype) == 1
- || TYPE_LENGTH (valtype) == 2
- || TYPE_LENGTH (valtype) == 4
- || TYPE_LENGTH (valtype) == 8))
- return RETURN_VALUE_STRUCT_CONVENTION;
- else
-#endif
- return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
- regcache, readbuf, writebuf);
-}
-\f
-
-/* Signal trampolines. */
-
-extern const struct tramp_frame ppcnbsd2_sigtramp;
-
-static void
-ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- CORE_ADDR addr, base;
- int i;
-
- base = get_frame_register_unsigned (this_frame,
- gdbarch_sp_regnum (gdbarch));
- if (self == &ppcnbsd2_sigtramp)
- addr = base + 0x10 + 2 * tdep->wordsize;
- else
- addr = base + 0x18 + 2 * tdep->wordsize;
- for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
- {
- int regnum = i + tdep->ppc_gp0_regnum;
- trad_frame_set_reg_addr (this_cache, regnum, addr);
- }
- trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (this_cache, gdbarch_pc_regnum (gdbarch),
- addr); /* SRR0? */
- addr += tdep->wordsize;
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (this_cache, frame_id_build (base, func));
-}
-
-static const struct tramp_frame ppcnbsd_sigtramp =
-{
- SIGTRAMP_FRAME,
- 4,
- {
- { 0x3821fff0, -1 }, /* add r1,r1,-16 */
- { 0x4e800021, -1 }, /* blrl */
- { 0x38610018, -1 }, /* addi r3,r1,24 */
- { 0x38000127, -1 }, /* li r0,295 */
- { 0x44000002, -1 }, /* sc */
- { 0x38000001, -1 }, /* li r0,1 */
- { 0x44000002, -1 }, /* sc */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- ppcnbsd_sigtramp_cache_init
-};
-
-/* NetBSD 2.0 introduced a slightly different signal trampoline. */
-
-const struct tramp_frame ppcnbsd2_sigtramp =
-{
- SIGTRAMP_FRAME,
- 4,
- {
- { 0x3821fff0, -1 }, /* add r1,r1,-16 */
- { 0x4e800021, -1 }, /* blrl */
- { 0x38610010, -1 }, /* addi r3,r1,16 */
- { 0x38000127, -1 }, /* li r0,295 */
- { 0x44000002, -1 }, /* sc */
- { 0x38000001, -1 }, /* li r0,1 */
- { 0x44000002, -1 }, /* sc */
- { TRAMP_SENTINEL_INSN, -1 }
- },
- ppcnbsd_sigtramp_cache_init
-};
-\f
-
-static void
-ppcnbsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- /* For NetBSD, this is an on again, off again thing. Some systems
- do use the broken struct convention, and some don't. */
- set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
-
- /* NetBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, ppcnbsd_iterate_over_regset_sections);
-
- tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp);
- tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_ppcnbsd_tdep (void);
-
-void
-_initialize_ppcnbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD_ELF,
- ppcnbsd_init_abi);
-
- /* Avoid initializing the register offsets again if they were
- already initialized by ppcnbsd-nat.c. */
- if (ppcnbsd_reg_offsets.pc_offset == 0)
- {
- /* General-purpose registers. */
- ppcnbsd_reg_offsets.r0_offset = 0;
- ppcnbsd_reg_offsets.gpr_size = 4;
- ppcnbsd_reg_offsets.xr_size = 4;
- ppcnbsd_reg_offsets.lr_offset = 128;
- ppcnbsd_reg_offsets.cr_offset = 132;
- ppcnbsd_reg_offsets.xer_offset = 136;
- ppcnbsd_reg_offsets.ctr_offset = 140;
- ppcnbsd_reg_offsets.pc_offset = 144;
- ppcnbsd_reg_offsets.ps_offset = -1;
- ppcnbsd_reg_offsets.mq_offset = -1;
-
- /* Floating-point registers. */
- ppcnbsd_reg_offsets.f0_offset = 0;
- ppcnbsd_reg_offsets.fpscr_offset = 256;
- ppcnbsd_reg_offsets.fpscr_size = 4;
-
- /* AltiVec registers. */
- ppcnbsd_reg_offsets.vr0_offset = 0;
- ppcnbsd_reg_offsets.vrsave_offset = 512;
- ppcnbsd_reg_offsets.vscr_offset = 524;
- }
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/powerpc.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef PPCNBSD_TDEP_H
-#define PPCNBSD_TDEP_H
-
-struct regset;
-
-/* Register offsets for NetBSD/powerpc. */
-extern struct ppc_reg_offsets ppcnbsd_reg_offsets;
-
-/* Register sets for NetBSD/powerpc. */
-extern const struct regset ppcnbsd_gregset;
-extern const struct regset ppcnbsd_fpregset;
-
-#endif /* ppcnbsd-tdep.h */
+++ /dev/null
-/* Native-dependent code for OpenBSD/powerpc.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <sys/signal.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-#include <machine/reg.h>
-
-#include "ppc-tdep.h"
-#include "ppcobsd-tdep.h"
-#include "inf-ptrace.h"
-#include "obsd-nat.h"
-#include "bsd-kvm.h"
-
-/* OpenBSD/powerpc didn't have PT_GETFPREGS/PT_SETFPREGS until release
- 4.0. On older releases the floating-point registers are handled by
- PT_GETREGS/PT_SETREGS, but fpscr wasn't available.. */
-
-#ifdef PT_GETFPREGS
-
-/* Returns true if PT_GETFPREGS fetches this register. */
-
-static int
-getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
- point registers. Traditionally, GDB's register set has still
- listed the floating point registers for such machines, so this
- code is harmless. However, the new E500 port actually omits the
- floating point registers entirely from the register set --- they
- don't even have register numbers assigned to them.
-
- It's not clear to me how best to update this code, so this assert
- will alert the first person to encounter the NetBSD/E500
- combination to the problem. */
- gdb_assert (ppc_floating_point_unit_p (gdbarch));
-
- return ((regnum >= tdep->ppc_fp0_regnum
- && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
- || regnum == tdep->ppc_fpscr_regnum);
-}
-
-#endif /* PT_GETFPREGS */
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers. */
-
-static void
-ppcobsd_fetch_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- ppc_supply_gregset (&ppcobsd_gregset, regcache, -1,
- ®s, sizeof regs);
-#ifndef PT_GETFPREGS
- ppc_supply_fpregset (&ppcobsd_gregset, regcache, -1,
- ®s, sizeof regs);
-#endif
-
-#ifdef PT_GETFPREGS
- if (regnum == -1
- || getfpregs_supplies (get_regcache_arch (regcache), regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- ppc_supply_fpregset (&ppcobsd_fpregset, regcache, -1,
- &fpregs, sizeof fpregs);
- }
-#endif
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers. */
-
-static void
-ppcobsd_store_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- ppc_collect_gregset (&ppcobsd_gregset, regcache,
- regnum, ®s, sizeof regs);
-#ifndef PT_GETFPREGS
- ppc_collect_fpregset (&ppcobsd_gregset, regcache,
- regnum, ®s, sizeof regs);
-#endif
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-
-#ifdef PT_GETFPREGS
- if (regnum == -1
- || getfpregs_supplies (get_regcache_arch (regcache), regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- ppc_collect_fpregset (&ppcobsd_fpregset, regcache,
- regnum, &fpregs, sizeof fpregs);
-
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't write floating point status"));
- }
-#endif
-}
-\f
-
-static int
-ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- struct switchframe sf;
- struct callframe cf;
- int i, regnum;
-
- /* The following is true for OpenBSD 3.7:
-
- The pcb contains %r1 (the stack pointer) at the point of the
- context switch in cpu_switch(). At that point we have a stack
- frame as described by `struct switchframe', and below that a call
- frame as described by `struct callframe'. From this information
- we reconstruct the register state as it would look when we are in
- cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
- regcache_raw_supply (regcache, gdbarch_sp_regnum (gdbarch), &sf.sp);
- regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
- regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
- for (i = 0, regnum = tdep->ppc_gp0_regnum + 13; i < 19; i++, regnum++)
- regcache_raw_supply (regcache, regnum, &sf.fixreg[i]);
-
- read_memory (sf.sp, (gdb_byte *)&cf, sizeof cf);
- regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
- regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
- regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
-
- return 1;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_ppcobsd_nat (void);
-
-void
-_initialize_ppcobsd_nat (void)
-{
- struct target_ops *t;
-
- /* Add in local overrides. */
- t = inf_ptrace_target ();
- t->to_fetch_registers = ppcobsd_fetch_registers;
- t->to_store_registers = ppcobsd_store_registers;
- obsd_add_target (t);
-
- /* General-purpose registers. */
- ppcobsd_reg_offsets.r0_offset = offsetof (struct reg, gpr);
- ppcobsd_reg_offsets.gpr_size = 4;
- ppcobsd_reg_offsets.xr_size = 4;
- ppcobsd_reg_offsets.pc_offset = offsetof (struct reg, pc);
- ppcobsd_reg_offsets.ps_offset = offsetof (struct reg, ps);
- ppcobsd_reg_offsets.cr_offset = offsetof (struct reg, cnd);
- ppcobsd_reg_offsets.lr_offset = offsetof (struct reg, lr);
- ppcobsd_reg_offsets.ctr_offset = offsetof (struct reg, cnt);
- ppcobsd_reg_offsets.xer_offset = offsetof (struct reg, xer);
- ppcobsd_reg_offsets.mq_offset = offsetof (struct reg, mq);
-
- /* Floating-point registers. */
- ppcobsd_reg_offsets.f0_offset = offsetof (struct reg, fpr);
- ppcobsd_reg_offsets.fpscr_offset = -1;
-#ifdef PT_GETFPREGS
- ppcobsd_fpreg_offsets.f0_offset = offsetof (struct fpreg, fpr);
- ppcobsd_fpreg_offsets.fpscr_offset = offsetof (struct fpreg, fpscr);
- ppcobsd_fpreg_offsets.fpscr_size = 4;
-#endif
-
- /* AltiVec registers. */
- ppcobsd_reg_offsets.vr0_offset = offsetof (struct vreg, vreg);
- ppcobsd_reg_offsets.vscr_offset = offsetof (struct vreg, vscr);
- ppcobsd_reg_offsets.vrsave_offset = offsetof (struct vreg, vrsave);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (ppcobsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/powerpc.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbtypes.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "symtab.h"
-#include "trad-frame.h"
-
-#include "ppc-tdep.h"
-#include "ppcobsd-tdep.h"
-#include "solib-svr4.h"
-
-/* Register offsets from <machine/reg.h>. */
-struct ppc_reg_offsets ppcobsd_reg_offsets;
-struct ppc_reg_offsets ppcobsd_fpreg_offsets;
-\f
-
-/* Core file support. */
-
-/* Supply register REGNUM in the general-purpose register set REGSET
- from the buffer specified by GREGS and LEN to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-void
-ppcobsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *gregs, size_t len)
-{
- ppc_supply_gregset (regset, regcache, regnum, gregs, len);
- ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
-}
-
-/* Collect register REGNUM in the general-purpose register set
- REGSET, from register cache REGCACHE into the buffer specified by
- GREGS and LEN. If REGNUM is -1, do this for all registers in
- REGSET. */
-
-void
-ppcobsd_collect_gregset (const struct regset *regset,
- const struct regcache *regcache, int regnum,
- void *gregs, size_t len)
-{
- ppc_collect_gregset (regset, regcache, regnum, gregs, len);
- ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
-}
-
-/* OpenBSD/powerpc register set. */
-
-const struct regset ppcobsd_gregset =
-{
- &ppcobsd_reg_offsets,
- ppcobsd_supply_gregset
-};
-
-const struct regset ppcobsd_fpregset =
-{
- &ppcobsd_fpreg_offsets,
- ppc_supply_fpregset
-};
-
-/* Iterate over core file register note sections. */
-
-static void
-ppcobsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", 412, &ppcobsd_gregset, NULL, cb_data);
-}
-\f
-
-/* Signal trampolines. */
-
-/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
- in virtual memory. The randomness makes it somewhat tricky to
- detect it, but fortunately we can rely on the fact that the start
- of the sigtramp routine is page-aligned. We recognize the
- trampoline by looking for the code that invokes the sigreturn
- system call. The offset where we can find that code varies from
- release to release.
-
- By the way, the mapping mentioned above is read-only, so you cannot
- place a breakpoint in the signal trampoline. */
-
-/* Default page size. */
-static const int ppcobsd_page_size = 4096;
-
-/* Offset for sigreturn(2). */
-static const int ppcobsd_sigreturn_offset[] = {
- 0x98, /* OpenBSD 3.8 */
- 0x0c, /* OpenBSD 3.2 */
- -1
-};
-
-static int
-ppcobsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR pc = get_frame_pc (this_frame);
- CORE_ADDR start_pc = (pc & ~(ppcobsd_page_size - 1));
- const int *offset;
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (name)
- return 0;
-
- for (offset = ppcobsd_sigreturn_offset; *offset != -1; offset++)
- {
- gdb_byte buf[2 * PPC_INSN_SIZE];
- unsigned long insn;
-
- if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
- buf, sizeof buf))
- continue;
-
- /* Check for "li r0,SYS_sigreturn". */
- insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
- if (insn != 0x38000067)
- continue;
-
- /* Check for "sc". */
- insn = extract_unsigned_integer (buf + PPC_INSN_SIZE,
- PPC_INSN_SIZE, byte_order);
- if (insn != 0x44000002)
- continue;
-
- return 1;
- }
-
- return 0;
-}
-
-static struct trad_frame_cache *
-ppcobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct trad_frame_cache *cache;
- CORE_ADDR addr, base, func;
- gdb_byte buf[PPC_INSN_SIZE];
- unsigned long insn, sigcontext_offset;
- int i;
-
- if (*this_cache)
- return (struct trad_frame_cache *) *this_cache;
-
- cache = trad_frame_cache_zalloc (this_frame);
- *this_cache = cache;
-
- func = get_frame_pc (this_frame);
- func &= ~(ppcobsd_page_size - 1);
- if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf))
- return cache;
-
- /* Calculate the offset where we can find `struct sigcontext'. We
- base our calculation on the amount of stack space reserved by the
- first instruction of the signal trampoline. */
- insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
- sigcontext_offset = (0x10000 - (insn & 0x0000ffff)) + 8;
-
- base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
- addr = base + sigcontext_offset + 2 * tdep->wordsize;
- for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
- {
- int regnum = i + tdep->ppc_gp0_regnum;
- trad_frame_set_reg_addr (cache, regnum, addr);
- }
- trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr);
- /* SRR0? */
- addr += tdep->wordsize;
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (cache, frame_id_build (base, func));
-
- return cache;
-}
-
-static void
-ppcobsd_sigtramp_frame_this_id (struct frame_info *this_frame,
- void **this_cache, struct frame_id *this_id)
-{
- struct trad_frame_cache *cache =
- ppcobsd_sigtramp_frame_cache (this_frame, this_cache);
-
- trad_frame_get_id (cache, this_id);
-}
-
-static struct value *
-ppcobsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct trad_frame_cache *cache =
- ppcobsd_sigtramp_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_register (cache, this_frame, regnum);
-}
-
-static const struct frame_unwind ppcobsd_sigtramp_frame_unwind = {
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- ppcobsd_sigtramp_frame_this_id,
- ppcobsd_sigtramp_frame_prev_register,
- NULL,
- ppcobsd_sigtramp_frame_sniffer
-};
-\f
-
-static void
-ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- /* OpenBSD doesn't support the 128-bit `long double' from the psABI. */
- set_gdbarch_long_double_bit (gdbarch, 64);
- set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
-
- /* OpenBSD currently uses a broken GCC. */
- set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value);
-
- /* OpenBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, ppcobsd_iterate_over_regset_sections);
-
- frame_unwind_append_unwinder (gdbarch, &ppcobsd_sigtramp_frame_unwind);
-}
-\f
-
-/* OpenBSD uses uses the traditional NetBSD core file format, even for
- ports that use ELF. */
-#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
-
-static enum gdb_osabi
-ppcobsd_core_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
- return GDB_OSABI_NETBSD_CORE;
-
- return GDB_OSABI_UNKNOWN;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_ppcobsd_tdep (void);
-
-void
-_initialize_ppcobsd_tdep (void)
-{
- /* BFD doesn't set a flavour for NetBSD style a.out core files. */
- gdbarch_register_osabi_sniffer (bfd_arch_powerpc, bfd_target_unknown_flavour,
- ppcobsd_core_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_OPENBSD_ELF,
- ppcobsd_init_abi);
- gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_OPENBSD_ELF,
- ppcobsd_init_abi);
-
- /* Avoid initializing the register offsets again if they were
- already initialized by ppcobsd-nat.c. */
- if (ppcobsd_reg_offsets.pc_offset == 0)
- {
- /* General-purpose registers. */
- ppcobsd_reg_offsets.r0_offset = 0;
- ppcobsd_reg_offsets.gpr_size = 4;
- ppcobsd_reg_offsets.xr_size = 4;
- ppcobsd_reg_offsets.pc_offset = 384;
- ppcobsd_reg_offsets.ps_offset = 388;
- ppcobsd_reg_offsets.cr_offset = 392;
- ppcobsd_reg_offsets.lr_offset = 396;
- ppcobsd_reg_offsets.ctr_offset = 400;
- ppcobsd_reg_offsets.xer_offset = 404;
- ppcobsd_reg_offsets.mq_offset = 408;
-
- /* Floating-point registers. */
- ppcobsd_reg_offsets.f0_offset = 128;
- ppcobsd_reg_offsets.fpscr_offset = -1;
-
- /* AltiVec registers. */
- ppcobsd_reg_offsets.vr0_offset = 0;
- ppcobsd_reg_offsets.vscr_offset = 512;
- ppcobsd_reg_offsets.vrsave_offset = 520;
- }
-
- if (ppcobsd_fpreg_offsets.fpscr_offset == 0)
- {
- /* Floating-point registers. */
- ppcobsd_reg_offsets.f0_offset = 0;
- ppcobsd_reg_offsets.fpscr_offset = 256;
- ppcobsd_reg_offsets.fpscr_size = 4;
- }
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/powerpc.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef PPCOBSD_TDEP_H
-#define PPCOBSD_TDEP_H
-
-struct regset;
-struct regcache;
-
-/* Register offsets for OpenBSD/powerpc. */
-extern struct ppc_reg_offsets ppcobsd_reg_offsets;
-extern struct ppc_reg_offsets ppcobsd_fpreg_offsets;
-
-/* Register sets for OpenBSD/powerpc. */
-extern const struct regset ppcobsd_gregset;
-extern const struct regset ppcobsd_fpregset;
-\f
-
-/* Supply register REGNUM in the general-purpose register set REGSET
- from the buffer specified by GREGS and LEN to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-extern void ppcobsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *gregs, size_t len);
-
-/* Collect register REGNUM in the general-purpose register set
- REGSET, from register cache REGCACHE into the buffer specified by
- GREGS and LEN. If REGNUM is -1, do this for all registers in
- REGSET. */
-
-extern void ppcobsd_collect_gregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *gregs, size_t len);
-
-#endif /* ppcobsd-tdep.h */
--- /dev/null
+/* Native-dependent code for NetBSD/sh.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ Contributed by Wasabi Systems, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "sh-tdep.h"
+#include "inf-ptrace.h"
+#include "regcache.h"
+
+
+/* Determine if PT_GETREGS fetches this register. */
+#define GETREGS_SUPPLIES(gdbarch, regno) \
+ (((regno) >= R0_REGNUM && (regno) <= (R0_REGNUM + 15)) \
+|| (regno) == gdbarch_pc_regnum (gdbarch) || (regno) == PR_REGNUM \
+|| (regno) == MACH_REGNUM || (regno) == MACL_REGNUM \
+|| (regno) == SR_REGNUM)
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define SHNBSD_SIZEOF_GREGS (21 * 4)
+
+static void
+shnbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
+ {
+ struct reg inferior_registers;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ sh_corefile_supply_regset (&sh_corefile_gregset, regcache, regno,
+ (char *) &inferior_registers,
+ SHNBSD_SIZEOF_GREGS);
+
+ if (regno != -1)
+ return;
+ }
+}
+
+static void
+shnbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
+{
+ if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
+ {
+ struct reg inferior_registers;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ sh_corefile_collect_regset (&sh_corefile_gregset, regcache, regno,
+ (char *) &inferior_registers,
+ SHNBSD_SIZEOF_GREGS);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
+ perror_with_name (_("Couldn't set registers"));
+
+ if (regno != -1)
+ return;
+ }
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_shnbsd_nat (void);
+
+void
+_initialize_shnbsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = shnbsd_fetch_inferior_registers;
+ t->to_store_registers = shnbsd_store_inferior_registers;
+ add_target (t);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/sh.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ Contributed by Wasabi Systems, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regset.h"
+#include "value.h"
+#include "osabi.h"
+
+#include "sh-tdep.h"
+#include "solib-svr4.h"
+
+/* Convert a register number into an offset into a ptrace
+ register structure. */
+static const struct sh_corefile_regmap regmap[] =
+{
+ {R0_REGNUM, 20 * 4},
+ {R0_REGNUM + 1, 19 * 4},
+ {R0_REGNUM + 2, 18 * 4},
+ {R0_REGNUM + 3, 17 * 4},
+ {R0_REGNUM + 4, 16 * 4},
+ {R0_REGNUM + 5, 15 * 4},
+ {R0_REGNUM + 6, 14 * 4},
+ {R0_REGNUM + 7, 13 * 4},
+ {R0_REGNUM + 8, 12 * 4},
+ {R0_REGNUM + 9, 11 * 4},
+ {R0_REGNUM + 10, 10 * 4},
+ {R0_REGNUM + 11, 9 * 4},
+ {R0_REGNUM + 12, 8 * 4},
+ {R0_REGNUM + 13, 7 * 4},
+ {R0_REGNUM + 14, 6 * 4},
+ {R0_REGNUM + 15, 5 * 4},
+ {PC_REGNUM, 0 * 4},
+ {SR_REGNUM, 1 * 4},
+ {PR_REGNUM, 2 * 4},
+ {MACH_REGNUM, 3 * 4},
+ {MACL_REGNUM, 4 * 4},
+ {-1 /* Terminator. */, 0}
+};
+\f
+
+static void
+shnbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
+ tdep->sizeof_gregset = 84;
+
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+/* OpenBSD uses uses the traditional NetBSD core file format, even for
+ ports that use ELF. */
+#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
+
+static enum gdb_osabi
+shnbsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_CORE;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_shnbsd_tdep;
+
+void
+_initialize_shnbsd_tdep (void)
+{
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_sh, bfd_target_unknown_flavour,
+ shnbsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD_ELF,
+ shnbsd_init_abi);
+ gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD_ELF,
+ shnbsd_init_abi);
+}
+++ /dev/null
-/* Native-dependent code for NetBSD/sh.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- Contributed by Wasabi Systems, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "sh-tdep.h"
-#include "inf-ptrace.h"
-#include "regcache.h"
-
-
-/* Determine if PT_GETREGS fetches this register. */
-#define GETREGS_SUPPLIES(gdbarch, regno) \
- (((regno) >= R0_REGNUM && (regno) <= (R0_REGNUM + 15)) \
-|| (regno) == gdbarch_pc_regnum (gdbarch) || (regno) == PR_REGNUM \
-|| (regno) == MACH_REGNUM || (regno) == MACL_REGNUM \
-|| (regno) == SR_REGNUM)
-
-/* Sizeof `struct reg' in <machine/reg.h>. */
-#define SHNBSD_SIZEOF_GREGS (21 * 4)
-
-static void
-shnbsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
- {
- struct reg inferior_registers;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- sh_corefile_supply_regset (&sh_corefile_gregset, regcache, regno,
- (char *) &inferior_registers,
- SHNBSD_SIZEOF_GREGS);
-
- if (regno != -1)
- return;
- }
-}
-
-static void
-shnbsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
-{
- if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
- {
- struct reg inferior_registers;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- sh_corefile_collect_regset (&sh_corefile_gregset, regcache, regno,
- (char *) &inferior_registers,
- SHNBSD_SIZEOF_GREGS);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
- perror_with_name (_("Couldn't set registers"));
-
- if (regno != -1)
- return;
- }
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_shnbsd_nat (void);
-
-void
-_initialize_shnbsd_nat (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
- t->to_fetch_registers = shnbsd_fetch_inferior_registers;
- t->to_store_registers = shnbsd_store_inferior_registers;
- add_target (t);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/sh.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- Contributed by Wasabi Systems, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regset.h"
-#include "value.h"
-#include "osabi.h"
-
-#include "sh-tdep.h"
-#include "solib-svr4.h"
-
-/* Convert a register number into an offset into a ptrace
- register structure. */
-static const struct sh_corefile_regmap regmap[] =
-{
- {R0_REGNUM, 20 * 4},
- {R0_REGNUM + 1, 19 * 4},
- {R0_REGNUM + 2, 18 * 4},
- {R0_REGNUM + 3, 17 * 4},
- {R0_REGNUM + 4, 16 * 4},
- {R0_REGNUM + 5, 15 * 4},
- {R0_REGNUM + 6, 14 * 4},
- {R0_REGNUM + 7, 13 * 4},
- {R0_REGNUM + 8, 12 * 4},
- {R0_REGNUM + 9, 11 * 4},
- {R0_REGNUM + 10, 10 * 4},
- {R0_REGNUM + 11, 9 * 4},
- {R0_REGNUM + 12, 8 * 4},
- {R0_REGNUM + 13, 7 * 4},
- {R0_REGNUM + 14, 6 * 4},
- {R0_REGNUM + 15, 5 * 4},
- {PC_REGNUM, 0 * 4},
- {SR_REGNUM, 1 * 4},
- {PR_REGNUM, 2 * 4},
- {MACH_REGNUM, 3 * 4},
- {MACL_REGNUM, 4 * 4},
- {-1 /* Terminator. */, 0}
-};
-\f
-
-static void
-shnbsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
- tdep->sizeof_gregset = 84;
-
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-\f
-
-/* OpenBSD uses uses the traditional NetBSD core file format, even for
- ports that use ELF. */
-#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
-
-static enum gdb_osabi
-shnbsd_core_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
- return GDB_OSABI_NETBSD_CORE;
-
- return GDB_OSABI_UNKNOWN;
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_shnbsd_tdep;
-
-void
-_initialize_shnbsd_tdep (void)
-{
- /* BFD doesn't set a flavour for NetBSD style a.out core files. */
- gdbarch_register_osabi_sniffer (bfd_arch_sh, bfd_target_unknown_flavour,
- shnbsd_core_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD_ELF,
- shnbsd_init_abi);
- gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD_ELF,
- shnbsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for NetBSD/sparc.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "sparc-tdep.h"
+#include "sparc-nat.h"
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+sparc32nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %sp, %pc, %psr and %wim. From this information
+ we reconstruct the register state as it would look when we just
+ returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp);
+ regcache_raw_supply (regcache, SPARC_O7_REGNUM, &pcb->pcb_pc);
+ regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, &pcb->pcb_psr);
+ regcache_raw_supply (regcache, SPARC32_WIM_REGNUM, &pcb->pcb_wim);
+ regcache_raw_supply (regcache, SPARC32_PC_REGNUM, &pcb->pcb_pc);
+
+ sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_sparcnbsd_nat (void);
+
+void
+_initialize_sparcnbsd_nat (void)
+{
+ sparc_gregmap = &sparc32nbsd_gregmap;
+ sparc_fpregmap = &sparc32_bsd_fpregmap;
+
+ /* We've got nothing to add to the generic SPARC target. */
+ add_target (sparc_target ());
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (sparc32nbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/sparc.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+ Contributed by Wasabi Systems, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "gdbtypes.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "solib-svr4.h"
+#include "symtab.h"
+#include "trad-frame.h"
+
+#include "sparc-tdep.h"
+#include "nbsd-tdep.h"
+
+/* Macros to extract fields from SPARC instructions. */
+#define X_RS1(i) (((i) >> 14) & 0x1f)
+#define X_RS2(i) ((i) & 0x1f)
+#define X_I(i) (((i) >> 13) & 1)
+
+const struct sparc_gregmap sparc32nbsd_gregmap =
+{
+ 0 * 4, /* %psr */
+ 1 * 4, /* %pc */
+ 2 * 4, /* %npc */
+ 3 * 4, /* %y */
+ -1, /* %wim */
+ -1, /* %tbr */
+ 5 * 4, /* %g1 */
+ -1 /* %l0 */
+};
+
+static void
+sparc32nbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
+
+ /* Traditional NetBSD core files don't use multiple register sets.
+ Instead, the general-purpose and floating-point registers are
+ lumped together in a single section. */
+ if (len >= 212)
+ sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum,
+ (const char *) gregs + 80);
+}
+
+static void
+sparc32nbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
+}
+
+\f
+/* Signal trampolines. */
+
+/* The following variables describe the location of an on-stack signal
+ trampoline. The current values correspond to the memory layout for
+ NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
+ up, since NetBSD uses signal trampolines provided by libc now. */
+
+static const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0;
+static const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0;
+
+static int
+sparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+ if (pc >= sparc32nbsd_sigtramp_start && pc < sparc32nbsd_sigtramp_end)
+ return 1;
+
+ return nbsd_pc_in_sigtramp (pc, name);
+}
+
+struct trad_frame_saved_reg *
+sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct trad_frame_saved_reg *saved_regs;
+ CORE_ADDR addr, sigcontext_addr;
+ int regnum, delta;
+ ULONGEST psr;
+
+ saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+ /* We find the appropriate instance of `struct sigcontext' at a
+ fixed offset in the signal frame. */
+ addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
+ sigcontext_addr = addr + 64 + 16;
+
+ /* The registers are saved in bits and pieces scattered all over the
+ place. The code below records their location on the assumption
+ that the part of the signal trampoline that saves the state has
+ been executed. */
+
+ saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
+ saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
+ saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
+ saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
+ saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
+ saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;
+
+ /* The remaining `global' registers and %y are saved in the `local'
+ registers. */
+ delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
+ for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
+ saved_regs[regnum].realreg = regnum + delta;
+ saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM;
+
+ /* The remaining `out' registers can be found in the current frame's
+ `in' registers. */
+ delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
+ for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
+ saved_regs[regnum].realreg = regnum + delta;
+ saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
+
+ /* The `local' and `in' registers have been saved in the register
+ save area. */
+ addr = saved_regs[SPARC_SP_REGNUM].addr;
+ addr = get_frame_memory_unsigned (this_frame, addr, 4);
+ for (regnum = SPARC_L0_REGNUM;
+ regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
+ saved_regs[regnum].addr = addr;
+
+ /* Handle StackGhost. */
+ {
+ ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
+
+ if (wcookie != 0)
+ {
+ ULONGEST i7;
+
+ addr = saved_regs[SPARC_I7_REGNUM].addr;
+ i7 = get_frame_memory_unsigned (this_frame, addr, 4);
+ trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
+ }
+ }
+
+ /* The floating-point registers are only saved if the EF bit in %prs
+ has been set. */
+
+#define PSR_EF 0x00001000
+
+ addr = saved_regs[SPARC32_PSR_REGNUM].addr;
+ psr = get_frame_memory_unsigned (this_frame, addr, 4);
+ if (psr & PSR_EF)
+ {
+ CORE_ADDR sp;
+
+ sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
+ saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
+ for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
+ regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
+ saved_regs[regnum].addr = addr;
+ }
+
+ return saved_regs;
+}
+
+static struct sparc_frame_cache *
+sparc32nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct sparc_frame_cache *cache;
+ CORE_ADDR addr;
+
+ if (*this_cache)
+ return (struct sparc_frame_cache *) *this_cache;
+
+ cache = sparc_frame_cache (this_frame, this_cache);
+ gdb_assert (cache == *this_cache);
+
+ /* If we couldn't find the frame's function, we're probably dealing
+ with an on-stack signal trampoline. */
+ if (cache->pc == 0)
+ {
+ cache->pc = sparc32nbsd_sigtramp_start;
+
+ /* Since we couldn't find the frame's function, the cache was
+ initialized under the assumption that we're frameless. */
+ sparc_record_save_insn (cache);
+ addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
+ cache->base = addr;
+ }
+
+ cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
+
+ return cache;
+}
+
+static void
+sparc32nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct sparc_frame_cache *cache =
+ sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static struct value *
+sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct sparc_frame_cache *cache =
+ sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
+}
+
+static int
+sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (sparc32nbsd_pc_in_sigtramp (pc, name))
+ {
+ if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
+ return 1;
+ }
+
+ return 0;
+}
+
+static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ sparc32nbsd_sigcontext_frame_this_id,
+ sparc32nbsd_sigcontext_frame_prev_register,
+ NULL,
+ sparc32nbsd_sigcontext_frame_sniffer
+};
+\f
+/* Return the address of a system call's alternative return
+ address. */
+
+CORE_ADDR
+sparcnbsd_step_trap (struct frame_info *frame, unsigned long insn)
+{
+ if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
+ || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
+ {
+ /* "New" system call. */
+ ULONGEST number = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);
+
+ if (number & 0x400)
+ return get_frame_register_unsigned (frame, SPARC_G2_REGNUM);
+ if (number & 0x800)
+ return get_frame_register_unsigned (frame, SPARC_G7_REGNUM);
+ }
+
+ return 0;
+}
+\f
+
+static const struct regset sparc32nbsd_gregset =
+ {
+ NULL, sparc32nbsd_supply_gregset, NULL
+ };
+
+static const struct regset sparc32nbsd_fpregset =
+ {
+ NULL, sparc32nbsd_supply_fpregset, NULL
+ };
+
+static void
+sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* NetBSD doesn't support the 128-bit `long double' from the psABI. */
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+
+ tdep->gregset = &sparc32nbsd_gregset;
+ tdep->sizeof_gregset = 20 * 4;
+
+ tdep->fpregset = &sparc32nbsd_fpregset;
+ tdep->sizeof_fpregset = 33 * 4;
+
+ /* Make sure we can single-step "new" syscalls. */
+ tdep->step_trap = sparcnbsd_step_trap;
+
+ frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
+}
+
+static void
+sparc32nbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ sparc32nbsd_init_abi (info, gdbarch);
+}
+
+void
+sparc32nbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ sparc32nbsd_init_abi (info, gdbarch);
+
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+
+static enum gdb_osabi
+sparcnbsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-sparc-netbsd") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+/* OpenBSD uses the traditional NetBSD core file format, even for
+ ports that use ELF. Therefore, if the default OS ABI is OpenBSD
+ ELF, we return that instead of NetBSD a.out. This is mainly for
+ the benfit of OpenBSD/sparc64, which inherits the sniffer below
+ since we include this file for an OpenBSD/sparc64 target. For
+ OpenBSD/sparc, the NetBSD a.out OS ABI is probably similar enough
+ to both the OpenBSD a.out and the OpenBSD ELF OS ABI. */
+#if defined (GDB_OSABI_DEFAULT) && (GDB_OSABI_DEFAULT == GDB_OSABI_OPENBSD_ELF)
+#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
+#else
+#define GDB_OSABI_NETBSD_CORE GDB_OSABI_NETBSD_AOUT
+#endif
+
+static enum gdb_osabi
+sparcnbsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_CORE;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+\f
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_sparcnbsd_tdep (void);
+
+void
+_initialize_sparcnbsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_aout_flavour,
+ sparcnbsd_aout_osabi_sniffer);
+
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_unknown_flavour,
+ sparcnbsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_AOUT,
+ sparc32nbsd_aout_init_abi);
+ gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_ELF,
+ sparc32nbsd_elf_init_abi);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/sparc.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "floatformat.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "symtab.h"
+#include "trad-frame.h"
+
+#include "obsd-tdep.h"
+#include "sparc-tdep.h"
+#include "solib-svr4.h"
+#include "bsd-uthread.h"
+
+/* Signal trampolines. */
+
+/* The OpenBSD kernel maps the signal trampoline at some random
+ location in user space, which means that the traditional BSD way of
+ detecting it won't work.
+
+ The signal trampoline will be mapped at an address that is page
+ aligned. We recognize the signal trampoline by looking for the
+ sigreturn system call. */
+
+static const int sparc32obsd_page_size = 4096;
+
+static int
+sparc32obsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+ CORE_ADDR start_pc = (pc & ~(sparc32obsd_page_size - 1));
+ unsigned long insn;
+
+ if (name)
+ return 0;
+
+ /* Check for "restore %g0, SYS_sigreturn, %g1". */
+ insn = sparc_fetch_instruction (start_pc + 0xec);
+ if (insn != 0x83e82067)
+ return 0;
+
+ /* Check for "t ST_SYSCALL". */
+ insn = sparc_fetch_instruction (start_pc + 0xf4);
+ if (insn != 0x91d02000)
+ return 0;
+
+ return 1;
+}
+
+static struct sparc_frame_cache *
+sparc32obsd_sigtramp_frame_cache (struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct sparc_frame_cache *cache;
+ CORE_ADDR addr;
+
+ if (*this_cache)
+ return (struct sparc_frame_cache *) *this_cache;
+
+ cache = sparc_frame_cache (this_frame, this_cache);
+ gdb_assert (cache == *this_cache);
+
+ /* If we couldn't find the frame's function, we're probably dealing
+ with an on-stack signal trampoline. */
+ if (cache->pc == 0)
+ {
+ cache->pc = get_frame_pc (this_frame);
+ cache->pc &= ~(sparc32obsd_page_size - 1);
+
+ /* Since we couldn't find the frame's function, the cache was
+ initialized under the assumption that we're frameless. */
+ sparc_record_save_insn (cache);
+ addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
+ cache->base = addr;
+ }
+
+ cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
+
+ return cache;
+}
+
+static void
+sparc32obsd_sigtramp_frame_this_id (struct frame_info *this_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct sparc_frame_cache *cache =
+ sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static struct value *
+sparc32obsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct sparc_frame_cache *cache =
+ sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
+}
+
+static int
+sparc32obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (sparc32obsd_pc_in_sigtramp (pc, name))
+ return 1;
+
+ return 0;
+}
+static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ sparc32obsd_sigtramp_frame_this_id,
+ sparc32obsd_sigtramp_frame_prev_register,
+ NULL,
+ sparc32obsd_sigtramp_frame_sniffer
+};
+
+\f
+
+/* Offset wthin the thread structure where we can find %fp and %i7. */
+#define SPARC32OBSD_UTHREAD_FP_OFFSET 128
+#define SPARC32OBSD_UTHREAD_PC_OFFSET 132
+
+static void
+sparc32obsd_supply_uthread (struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR fp, fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
+ gdb_byte buf[4];
+
+ gdb_assert (regnum >= -1);
+
+ fp = read_memory_unsigned_integer (fp_addr, 4, byte_order);
+ if (regnum == SPARC_SP_REGNUM || regnum == -1)
+ {
+ store_unsigned_integer (buf, 4, byte_order, fp);
+ regcache_raw_supply (regcache, SPARC_SP_REGNUM, buf);
+
+ if (regnum == SPARC_SP_REGNUM)
+ return;
+ }
+
+ if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM
+ || regnum == -1)
+ {
+ CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
+
+ i7 = read_memory_unsigned_integer (i7_addr, 4, byte_order);
+ if (regnum == SPARC32_PC_REGNUM || regnum == -1)
+ {
+ store_unsigned_integer (buf, 4, byte_order, i7 + 8);
+ regcache_raw_supply (regcache, SPARC32_PC_REGNUM, buf);
+ }
+ if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
+ {
+ store_unsigned_integer (buf, 4, byte_order, i7 + 12);
+ regcache_raw_supply (regcache, SPARC32_NPC_REGNUM, buf);
+ }
+
+ if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
+ return;
+ }
+
+ sparc_supply_rwindow (regcache, fp, regnum);
+}
+
+static void
+sparc32obsd_collect_uthread(const struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp;
+ gdb_byte buf[4];
+
+ gdb_assert (regnum >= -1);
+
+ if (regnum == SPARC_SP_REGNUM || regnum == -1)
+ {
+ CORE_ADDR fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
+
+ regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
+ write_memory (fp_addr,buf, 4);
+ }
+
+ if (regnum == SPARC32_PC_REGNUM || regnum == -1)
+ {
+ CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
+
+ regcache_raw_collect (regcache, SPARC32_PC_REGNUM, buf);
+ i7 = extract_unsigned_integer (buf, 4, byte_order) - 8;
+ write_memory_unsigned_integer (i7_addr, 4, byte_order, i7);
+
+ if (regnum == SPARC32_PC_REGNUM)
+ return;
+ }
+
+ regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
+ sp = extract_unsigned_integer (buf, 4, byte_order);
+ sparc_collect_rwindow (regcache, sp, regnum);
+}
+\f
+
+static void
+sparc32obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* OpenBSD/sparc is very similar to NetBSD/sparc ELF. */
+ sparc32nbsd_elf_init_abi (info, gdbarch);
+
+ set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
+
+ frame_unwind_append_unwinder (gdbarch, &sparc32obsd_sigtramp_frame_unwind);
+
+ /* OpenBSD provides a user-level threads implementation. */
+ bsd_uthread_set_supply_uthread (gdbarch, sparc32obsd_supply_uthread);
+ bsd_uthread_set_collect_uthread (gdbarch, sparc32obsd_collect_uthread);
+}
+
+\f
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_sparc32obsd_tdep (void);
+
+void
+_initialize_sparc32obsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD_ELF,
+ sparc32obsd_init_abi);
+}
--- /dev/null
+/* Native-dependent code for FreeBSD/sparc64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "fbsd-nat.h"
+#include "sparc64-tdep.h"
+#include "sparc-nat.h"
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+sparc64fbsd_kvm_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ /* The following is true for FreeBSD 5.4:
+
+ The pcb contains %sp and %pc. Since the register windows are
+ explicitly flushed, we can find the `local' and `in' registers on
+ the stack. */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp);
+ regcache_raw_supply (regcache, SPARC64_PC_REGNUM, &pcb->pcb_pc);
+
+ /* Synthesize %npc. */
+ pcb->pcb_pc += 4;
+ regcache_raw_supply (regcache, SPARC64_NPC_REGNUM, &pcb->pcb_pc);
+
+ /* Read `local' and `in' registers from the stack. */
+ sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_sparc64fbsd_nat (void);
+
+void
+_initialize_sparc64fbsd_nat (void)
+{
+ struct target_ops *t;
+
+ /* Add some extra features to the generic SPARC target. */
+ t = sparc_target ();
+ fbsd_nat_add_target (t);
+
+ sparc_gregmap = &sparc64fbsd_gregmap;
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (sparc64fbsd_kvm_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for FreeBSD/sparc64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "target.h"
+#include "trad-frame.h"
+
+#include "sparc64-tdep.h"
+#include "fbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* From <machine/reg.h>. */
+const struct sparc_gregmap sparc64fbsd_gregmap =
+{
+ 26 * 8, /* "tstate" */
+ 25 * 8, /* %pc */
+ 24 * 8, /* %npc */
+ 28 * 8, /* %y */
+ 16 * 8, /* %fprs */
+ -1,
+ 1 * 8, /* %g1 */
+ -1, /* %l0 */
+ 8 /* sizeof (%y) */
+};
+\f
+
+static void
+sparc64fbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ sparc64_supply_gregset (&sparc64fbsd_gregmap, regcache, regnum, gregs);
+}
+
+static void
+sparc64fbsd_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *gregs, size_t len)
+{
+ sparc64_collect_gregset (&sparc64fbsd_gregmap, regcache, regnum, gregs);
+}
+
+static void
+sparc64fbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+
+static void
+sparc64fbsd_collect_fpregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *fpregs, size_t len)
+{
+ sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+\f
+
+/* Signal trampolines. */
+
+static int
+sparc64fbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+ return (name && strcmp (name, "__sigtramp") == 0);
+}
+
+static struct sparc_frame_cache *
+sparc64fbsd_sigtramp_frame_cache (struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct sparc_frame_cache *cache;
+ CORE_ADDR addr, mcontext_addr, sp;
+ LONGEST fprs;
+ int regnum;
+
+ if (*this_cache)
+ return (struct sparc_frame_cache *) *this_cache;
+
+ cache = sparc_frame_cache (this_frame, this_cache);
+ gdb_assert (cache == *this_cache);
+
+ cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+ /* The third argument is a pointer to an instance of `ucontext_t',
+ which has a member `uc_mcontext' that contains the saved
+ registers. */
+ addr = get_frame_register_unsigned (this_frame, SPARC_O2_REGNUM);
+ mcontext_addr = addr + 64;
+
+ /* The following registers travel in the `mc_local' slots of
+ `mcontext_t'. */
+ addr = mcontext_addr + 16 * 8;
+ cache->saved_regs[SPARC64_FPRS_REGNUM].addr = addr + 0 * 8;
+ cache->saved_regs[SPARC64_FSR_REGNUM].addr = addr + 1 * 8;
+
+ /* The following registers travel in the `mc_in' slots of
+ `mcontext_t'. */
+ addr = mcontext_addr + 24 * 8;
+ cache->saved_regs[SPARC64_NPC_REGNUM].addr = addr + 0 * 8;
+ cache->saved_regs[SPARC64_PC_REGNUM].addr = addr + 1 * 8;
+ cache->saved_regs[SPARC64_STATE_REGNUM].addr = addr + 2 * 8;
+ cache->saved_regs[SPARC64_Y_REGNUM].addr = addr + 4 * 8;
+
+ /* The `global' and `out' registers travel in the `mc_global' and
+ `mc_out' slots of `mcontext_t', except for %g0. Since %g0 is
+ always zero, keep the identity encoding. */
+ for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 8;
+ regnum <= SPARC_O7_REGNUM; regnum++, addr += 8)
+ cache->saved_regs[regnum].addr = addr;
+
+ /* The `local' and `in' registers have been saved in the register
+ save area. */
+ addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
+ sp = get_frame_memory_unsigned (this_frame, addr, 8);
+ for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
+ regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
+ cache->saved_regs[regnum].addr = addr;
+
+ /* The floating-point registers are only saved if the FEF bit in
+ %fprs has been set. */
+
+#define FPRS_FEF (1 << 2)
+
+ addr = cache->saved_regs[SPARC64_FPRS_REGNUM].addr;
+ fprs = get_frame_memory_unsigned (this_frame, addr, 8);
+ if (fprs & FPRS_FEF)
+ {
+ for (regnum = SPARC_F0_REGNUM, addr = mcontext_addr + 32 * 8;
+ regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
+ cache->saved_regs[regnum].addr = addr;
+
+ for (regnum = SPARC64_F32_REGNUM;
+ regnum <= SPARC64_F62_REGNUM; regnum++, addr += 8)
+ cache->saved_regs[regnum].addr = addr;
+ }
+
+ return cache;
+}
+
+static void
+sparc64fbsd_sigtramp_frame_this_id (struct frame_info *this_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct sparc_frame_cache *cache =
+ sparc64fbsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static struct value *
+sparc64fbsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct sparc_frame_cache *cache =
+ sparc64fbsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
+}
+
+static int
+sparc64fbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (sparc64fbsd_pc_in_sigtramp (pc, name))
+ return 1;
+
+ return 0;
+}
+
+static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ sparc64fbsd_sigtramp_frame_this_id,
+ sparc64fbsd_sigtramp_frame_prev_register,
+ NULL,
+ sparc64fbsd_sigtramp_frame_sniffer
+};
+\f
+
+static const struct regset sparc64fbsd_gregset =
+ {
+ NULL, sparc64fbsd_supply_gregset, sparc64fbsd_collect_gregset
+ };
+
+static const struct regset sparc64fbsd_fpregset =
+ {
+ NULL, sparc64fbsd_supply_fpregset, sparc64fbsd_collect_fpregset
+ };
+
+static void
+sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Generic FreeBSD support. */
+ fbsd_init_abi (info, gdbarch);
+
+ tdep->gregset = &sparc64fbsd_gregset;
+ tdep->sizeof_gregset = 256;
+
+ tdep->fpregset = &sparc64fbsd_fpregset;
+ tdep->sizeof_fpregset = 272;
+
+ frame_unwind_append_unwinder (gdbarch, &sparc64fbsd_sigtramp_frame_unwind);
+
+ sparc64_init_abi (info, gdbarch);
+
+ /* FreeBSD/sparc64 has SVR4-style shared libraries. */
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_sparc64fbsd_tdep (void);
+
+void
+_initialize_sparc64fbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
+ GDB_OSABI_FREEBSD_ELF, sparc64fbsd_init_abi);
+}
--- /dev/null
+/* Native-dependent code for NetBSD/sparc64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "sparc64-tdep.h"
+#include "sparc-nat.h"
+
+/* NetBSD is different from the other OSes that support both SPARC and
+ UltraSPARC in that the result of ptrace(2) depends on whether the
+ traced process is 32-bit or 64-bit. */
+
+static void
+sparc64nbsd_supply_gregset (const struct sparc_gregmap *gregmap,
+ struct regcache *regcache,
+ int regnum, const void *gregs)
+{
+ int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
+
+ if (sparc32)
+ sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
+ else
+ sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
+}
+
+static void
+sparc64nbsd_collect_gregset (const struct sparc_gregmap *gregmap,
+ const struct regcache *regcache,
+ int regnum, void *gregs)
+{
+ int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
+
+ if (sparc32)
+ sparc32_collect_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
+ else
+ sparc64_collect_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
+}
+
+static void
+sparc64nbsd_supply_fpregset (const struct sparc_fpregmap *fpregmap,
+ struct regcache *regcache,
+ int regnum, const void *fpregs)
+{
+ int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
+
+ if (sparc32)
+ sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
+ else
+ sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+
+static void
+sparc64nbsd_collect_fpregset (const struct sparc_fpregmap *fpregmap,
+ const struct regcache *regcache,
+ int regnum, void *fpregs)
+{
+ int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
+
+ if (sparc32)
+ sparc32_collect_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
+ else
+ sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+
+/* Determine whether `gregset_t' contains register REGNUM. */
+
+static int
+sparc64nbsd_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
+{
+ if (gdbarch_ptr_bit (gdbarch) == 32)
+ return sparc32_gregset_supplies_p (gdbarch, regnum);
+
+ /* Integer registers. */
+ if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
+ || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
+ || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
+ || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM))
+ return 1;
+
+ /* Control registers. */
+ if (regnum == SPARC64_PC_REGNUM
+ || regnum == SPARC64_NPC_REGNUM
+ || regnum == SPARC64_STATE_REGNUM
+ || regnum == SPARC64_Y_REGNUM)
+ return 1;
+
+ return 0;
+}
+
+/* Determine whether `fpregset_t' contains register REGNUM. */
+
+static int
+sparc64nbsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
+{
+ if (gdbarch_ptr_bit (gdbarch) == 32)
+ return sparc32_fpregset_supplies_p (gdbarch, regnum);
+
+ /* Floating-point registers. */
+ if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
+ || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM))
+ return 1;
+
+ /* Control registers. */
+ if (regnum == SPARC64_FSR_REGNUM)
+ return 1;
+
+ return 0;
+}
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+sparc64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ u_int64_t state;
+ int regnum;
+
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %sp and %pc, %pstate and %cwp. From this
+ information we reconstruct the register state as it would look
+ when we just returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ /* If the program counter is zero, this is probably a core dump, and
+ we can get %pc from the stack. */
+ if (pcb->pcb_pc == 0)
+ read_memory(pcb->pcb_sp + BIAS - 176 + (11 * 8),
+ (gdb_byte *)&pcb->pcb_pc, sizeof pcb->pcb_pc);
+
+ regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp);
+ regcache_raw_supply (regcache, SPARC64_PC_REGNUM, &pcb->pcb_pc);
+
+ state = pcb->pcb_pstate << 8 | pcb->pcb_cwp;
+ regcache_raw_supply (regcache, SPARC64_STATE_REGNUM, &state);
+
+ sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
+
+ return 1;
+}
+
+\f
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_sparc64nbsd_nat (void);
+
+void
+_initialize_sparc64nbsd_nat (void)
+{
+ sparc_supply_gregset = sparc64nbsd_supply_gregset;
+ sparc_collect_gregset = sparc64nbsd_collect_gregset;
+ sparc_supply_fpregset = sparc64nbsd_supply_fpregset;
+ sparc_collect_fpregset = sparc64nbsd_collect_fpregset;
+ sparc_gregset_supplies_p = sparc64nbsd_gregset_supplies_p;
+ sparc_fpregset_supplies_p = sparc64nbsd_fpregset_supplies_p;
+
+ /* We've got nothing to add to the generic SPARC target. */
+ add_target (sparc_target ());
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (sparc64nbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/sparc64.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+ Based on code contributed by Wasabi Systems, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "symtab.h"
+#include "objfiles.h"
+#include "solib-svr4.h"
+#include "trad-frame.h"
+
+#include "sparc64-tdep.h"
+#include "nbsd-tdep.h"
+
+/* From <machine/reg.h>. */
+const struct sparc_gregmap sparc64nbsd_gregmap =
+{
+ 0 * 8, /* "tstate" */
+ 1 * 8, /* %pc */
+ 2 * 8, /* %npc */
+ 3 * 8, /* %y */
+ -1, /* %fprs */
+ -1,
+ 5 * 8, /* %g1 */
+ -1, /* %l0 */
+ 4 /* sizeof (%y) */
+};
+\f
+
+static void
+sparc64nbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
+}
+
+static void
+sparc64nbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+\f
+
+/* Signal trampolines. */
+
+/* The following variables describe the location of an on-stack signal
+ trampoline. The current values correspond to the memory layout for
+ NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
+ up, since NetBSD uses signal trampolines provided by libc now. */
+
+static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL;
+static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL;
+
+static int
+sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+ if (pc >= sparc64nbsd_sigtramp_start && pc < sparc64nbsd_sigtramp_end)
+ return 1;
+
+ return nbsd_pc_in_sigtramp (pc, name);
+}
+
+struct trad_frame_saved_reg *
+sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
+ struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct trad_frame_saved_reg *saved_regs;
+ CORE_ADDR addr, sp;
+ int regnum, delta;
+
+ saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+ /* The registers are saved in bits and pieces scattered all over the
+ place. The code below records their location on the assumption
+ that the part of the signal trampoline that saves the state has
+ been executed. */
+
+ saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
+ saved_regs[SPARC64_PC_REGNUM].addr = sigcontext_addr + 16;
+ saved_regs[SPARC64_NPC_REGNUM].addr = sigcontext_addr + 24;
+ saved_regs[SPARC64_STATE_REGNUM].addr = sigcontext_addr + 32;
+ saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 40;
+ saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 48;
+
+ /* The remaining `global' registers and %y are saved in the `local'
+ registers. */
+ delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
+ for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
+ saved_regs[regnum].realreg = regnum + delta;
+ saved_regs[SPARC64_Y_REGNUM].realreg = SPARC_L1_REGNUM;
+
+ /* The remaining `out' registers can be found in the current frame's
+ `in' registers. */
+ delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
+ for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
+ saved_regs[regnum].realreg = regnum + delta;
+ saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
+
+ /* The `local' and `in' registers have been saved in the register
+ save area. */
+ addr = saved_regs[SPARC_SP_REGNUM].addr;
+ sp = get_frame_memory_unsigned (this_frame, addr, 8);
+ for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
+ regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
+ saved_regs[regnum].addr = addr;
+
+ /* Handle StackGhost. */
+ {
+ ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
+
+ if (wcookie != 0)
+ {
+ ULONGEST i7;
+
+ addr = saved_regs[SPARC_I7_REGNUM].addr;
+ i7 = get_frame_memory_unsigned (this_frame, addr, 8);
+ trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
+ }
+ }
+
+ /* TODO: Handle the floating-point registers. */
+
+ return saved_regs;
+}
+
+static struct sparc_frame_cache *
+sparc64nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct sparc_frame_cache *cache;
+ CORE_ADDR addr;
+
+ if (*this_cache)
+ return (struct sparc_frame_cache *) *this_cache;
+
+ cache = sparc_frame_cache (this_frame, this_cache);
+ gdb_assert (cache == *this_cache);
+
+ /* If we couldn't find the frame's function, we're probably dealing
+ with an on-stack signal trampoline. */
+ if (cache->pc == 0)
+ {
+ cache->pc = sparc64nbsd_sigtramp_start;
+
+ /* Since we couldn't find the frame's function, the cache was
+ initialized under the assumption that we're frameless. */
+ sparc_record_save_insn (cache);
+ addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
+ if (addr & 1)
+ addr += BIAS;
+ cache->base = addr;
+ }
+
+ /* We find the appropriate instance of `struct sigcontext' at a
+ fixed offset in the signal frame. */
+ addr = cache->base + 128 + 8;
+ cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
+
+ return cache;
+}
+
+static void
+sparc64nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct sparc_frame_cache *cache =
+ sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static struct value *
+sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct sparc_frame_cache *cache =
+ sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
+}
+
+static int
+sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (sparc64nbsd_pc_in_sigtramp (pc, name))
+ {
+ if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
+ return 1;
+ }
+
+ return 0;
+}
+
+static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ sparc64nbsd_sigcontext_frame_this_id,
+ sparc64nbsd_sigcontext_frame_prev_register,
+ NULL,
+ sparc64nbsd_sigtramp_frame_sniffer
+};
+\f
+
+static const struct regset sparc64nbsd_gregset =
+ {
+ NULL, sparc64nbsd_supply_gregset, NULL
+ };
+
+static const struct regset sparc64nbsd_fpregset =
+ {
+ NULL, sparc64nbsd_supply_fpregset, NULL
+ };
+
+static void
+sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->gregset = &sparc64nbsd_gregset;
+ tdep->sizeof_gregset = 160;
+
+ tdep->fpregset = &sparc64nbsd_fpregset;
+ tdep->sizeof_fpregset = 272;
+
+ /* Make sure we can single-step "new" syscalls. */
+ tdep->step_trap = sparcnbsd_step_trap;
+
+ frame_unwind_append_unwinder (gdbarch, &sparc64nbsd_sigcontext_frame_unwind);
+
+ sparc64_init_abi (info, gdbarch);
+
+ /* NetBSD/sparc64 has SVR4-style shared libraries. */
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_sparc64nbsd_tdep (void);
+
+void
+_initialize_sparc64nbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
+ GDB_OSABI_NETBSD_ELF, sparc64nbsd_init_abi);
+}
--- /dev/null
+/* Native-dependent code for OpenBSD/sparc64.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "sparc64-tdep.h"
+#include "sparc-nat.h"
+#include "obsd-nat.h"
+
+/* Determine whether `gregset_t' contains register REGNUM. */
+
+static int
+sparc64obsd_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
+{
+ /* Integer registers. */
+ if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
+ || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
+ || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
+ || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM))
+ return 1;
+
+ /* Control registers. */
+ if (regnum == SPARC64_PC_REGNUM
+ || regnum == SPARC64_NPC_REGNUM
+ || regnum == SPARC64_STATE_REGNUM
+ || regnum == SPARC64_Y_REGNUM)
+ return 1;
+
+ return 0;
+}
+
+/* Determine whether `fpregset_t' contains register REGNUM. */
+
+static int
+sparc64obsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
+{
+ /* Floating-point registers. */
+ if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
+ || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM))
+ return 1;
+
+ /* Control registers. */
+ if (regnum == SPARC64_FSR_REGNUM)
+ return 1;
+
+ return 0;
+}
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+sparc64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ u_int64_t state;
+ int regnum;
+
+ /* The following is true for OpenBSD 3.0:
+
+ The pcb contains %sp and %pc, %pstate and %cwp. From this
+ information we reconstruct the register state as it would look
+ when we just returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ /* If the program counter is zero, this is probably a core dump, and
+ we can get %pc from the stack. */
+ if (pcb->pcb_pc == 0)
+ read_memory(pcb->pcb_sp + BIAS - 176 + (11 * 8),
+ (gdb_byte *)&pcb->pcb_pc, sizeof pcb->pcb_pc);
+
+ regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp);
+ regcache_raw_supply (regcache, SPARC64_PC_REGNUM, &pcb->pcb_pc);
+
+ state = pcb->pcb_pstate << 8 | pcb->pcb_cwp;
+ regcache_raw_supply (regcache, SPARC64_STATE_REGNUM, &state);
+
+ sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
+
+ return 1;
+}
+
+\f
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_sparc64obsd_nat (void);
+
+void
+_initialize_sparc64obsd_nat (void)
+{
+ sparc_supply_gregset = sparc64_supply_gregset;
+ sparc_collect_gregset = sparc64_collect_gregset;
+ sparc_supply_fpregset = sparc64_supply_fpregset;
+ sparc_collect_fpregset = sparc64_collect_fpregset;
+ sparc_gregset_supplies_p = sparc64obsd_gregset_supplies_p;
+ sparc_fpregset_supplies_p = sparc64obsd_fpregset_supplies_p;
+
+ sparc_gregmap = &sparc64nbsd_gregmap;
+ sparc_fpregmap = &sparc64_bsd_fpregmap;
+
+ /* Add some extra features to the generic SPARC target. */
+ obsd_add_target (sparc_target ());
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (sparc64obsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/sparc64.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "symtab.h"
+#include "objfiles.h"
+#include "trad-frame.h"
+
+#include "obsd-tdep.h"
+#include "sparc64-tdep.h"
+#include "solib-svr4.h"
+#include "bsd-uthread.h"
+
+/* Older OpenBSD versions used the traditional NetBSD core file
+ format, even for ports that use ELF. These core files don't use
+ multiple register sets. Instead, the general-purpose and
+ floating-point registers are lumped together in a single section.
+ Unlike on NetBSD, OpenBSD uses a different layout for its
+ general-purpose registers than the layout used for ptrace(2).
+
+ Newer OpenBSD versions use ELF core files. Here the register sets
+ match the ptrace(2) layout. */
+
+/* From <machine/reg.h>. */
+const struct sparc_gregmap sparc64obsd_gregmap =
+{
+ 0 * 8, /* "tstate" */
+ 1 * 8, /* %pc */
+ 2 * 8, /* %npc */
+ 3 * 8, /* %y */
+ -1, /* %fprs */
+ -1,
+ 5 * 8, /* %g1 */
+ 20 * 8, /* %l0 */
+ 4 /* sizeof (%y) */
+};
+
+const struct sparc_gregmap sparc64obsd_core_gregmap =
+{
+ 0 * 8, /* "tstate" */
+ 1 * 8, /* %pc */
+ 2 * 8, /* %npc */
+ 3 * 8, /* %y */
+ -1, /* %fprs */
+ -1,
+ 7 * 8, /* %g1 */
+ 22 * 8, /* %l0 */
+ 4 /* sizeof (%y) */
+};
+
+static void
+sparc64obsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const void *fpregs = (char *)gregs + 288;
+
+ if (len < 832)
+ {
+ sparc64_supply_gregset (&sparc64obsd_gregmap, regcache, regnum, gregs);
+ return;
+ }
+
+ sparc64_supply_gregset (&sparc64obsd_core_gregmap, regcache, regnum, gregs);
+ sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+
+static void
+sparc64obsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+\f
+
+/* Signal trampolines. */
+
+/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
+ in virtual memory. The randomness makes it somewhat tricky to
+ detect it, but fortunately we can rely on the fact that the start
+ of the sigtramp routine is page-aligned. We recognize the
+ trampoline by looking for the code that invokes the sigreturn
+ system call. The offset where we can find that code varies from
+ release to release.
+
+ By the way, the mapping mentioned above is read-only, so you cannot
+ place a breakpoint in the signal trampoline. */
+
+/* Default page size. */
+static const int sparc64obsd_page_size = 8192;
+
+/* Offset for sigreturn(2). */
+static const int sparc64obsd_sigreturn_offset[] = {
+ 0xf0, /* OpenBSD 3.8 */
+ 0xec, /* OpenBSD 3.6 */
+ 0xe8, /* OpenBSD 3.2 */
+ -1
+};
+
+static int
+sparc64obsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+ CORE_ADDR start_pc = (pc & ~(sparc64obsd_page_size - 1));
+ unsigned long insn;
+ const int *offset;
+
+ if (name)
+ return 0;
+
+ for (offset = sparc64obsd_sigreturn_offset; *offset != -1; offset++)
+ {
+ /* Check for "restore %g0, SYS_sigreturn, %g1". */
+ insn = sparc_fetch_instruction (start_pc + *offset);
+ if (insn != 0x83e82067)
+ continue;
+
+ /* Check for "t ST_SYSCALL". */
+ insn = sparc_fetch_instruction (start_pc + *offset + 8);
+ if (insn != 0x91d02000)
+ continue;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static struct sparc_frame_cache *
+sparc64obsd_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+ struct sparc_frame_cache *cache;
+ CORE_ADDR addr;
+
+ if (*this_cache)
+ return (struct sparc_frame_cache *) *this_cache;
+
+ cache = sparc_frame_cache (this_frame, this_cache);
+ gdb_assert (cache == *this_cache);
+
+ /* If we couldn't find the frame's function, we're probably dealing
+ with an on-stack signal trampoline. */
+ if (cache->pc == 0)
+ {
+ cache->pc = get_frame_pc (this_frame);
+ cache->pc &= ~(sparc64obsd_page_size - 1);
+
+ /* Since we couldn't find the frame's function, the cache was
+ initialized under the assumption that we're frameless. */
+ sparc_record_save_insn (cache);
+ addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
+ if (addr & 1)
+ addr += BIAS;
+ cache->base = addr;
+ }
+
+ /* We find the appropriate instance of `struct sigcontext' at a
+ fixed offset in the signal frame. */
+ addr = cache->base + 128 + 16;
+ cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
+
+ return cache;
+}
+
+static void
+sparc64obsd_frame_this_id (struct frame_info *this_frame, void **this_cache,
+ struct frame_id *this_id)
+{
+ struct sparc_frame_cache *cache =
+ sparc64obsd_frame_cache (this_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static struct value *
+sparc64obsd_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct sparc_frame_cache *cache =
+ sparc64obsd_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
+}
+
+static int
+sparc64obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (sparc64obsd_pc_in_sigtramp (pc, name))
+ return 1;
+
+ return 0;
+}
+
+static const struct frame_unwind sparc64obsd_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ sparc64obsd_frame_this_id,
+ sparc64obsd_frame_prev_register,
+ NULL,
+ sparc64obsd_sigtramp_frame_sniffer
+};
+\f
+/* Kernel debugging support. */
+
+static struct sparc_frame_cache *
+sparc64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
+{
+ struct sparc_frame_cache *cache;
+ CORE_ADDR sp, trapframe_addr;
+ int regnum;
+
+ if (*this_cache)
+ return (struct sparc_frame_cache *) *this_cache;
+
+ cache = sparc_frame_cache (this_frame, this_cache);
+ gdb_assert (cache == *this_cache);
+
+ sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
+ trapframe_addr = sp + BIAS + 176;
+
+ cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+ cache->saved_regs[SPARC64_STATE_REGNUM].addr = trapframe_addr;
+ cache->saved_regs[SPARC64_PC_REGNUM].addr = trapframe_addr + 8;
+ cache->saved_regs[SPARC64_NPC_REGNUM].addr = trapframe_addr + 16;
+
+ for (regnum = SPARC_G0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
+ cache->saved_regs[regnum].addr =
+ trapframe_addr + 48 + (regnum - SPARC_G0_REGNUM) * 8;
+
+ return cache;
+}
+
+static void
+sparc64obsd_trapframe_this_id (struct frame_info *this_frame,
+ void **this_cache, struct frame_id *this_id)
+{
+ struct sparc_frame_cache *cache =
+ sparc64obsd_trapframe_cache (this_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static struct value *
+sparc64obsd_trapframe_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct sparc_frame_cache *cache =
+ sparc64obsd_trapframe_cache (this_frame, this_cache);
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
+}
+
+static int
+sparc64obsd_trapframe_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc;
+ ULONGEST pstate;
+ const char *name;
+
+ /* Check whether we are in privileged mode, and bail out if we're not. */
+ pstate = get_frame_register_unsigned (this_frame, SPARC64_PSTATE_REGNUM);
+ if ((pstate & SPARC64_PSTATE_PRIV) == 0)
+ return 0;
+
+ pc = get_frame_address_in_block (this_frame);
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (name && strcmp (name, "Lslowtrap_reenter") == 0)
+ return 1;
+
+ return 0;
+}
+
+static const struct frame_unwind sparc64obsd_trapframe_unwind =
+{
+ NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
+ sparc64obsd_trapframe_this_id,
+ sparc64obsd_trapframe_prev_register,
+ NULL,
+ sparc64obsd_trapframe_sniffer
+};
+\f
+
+/* Threads support. */
+
+/* Offset wthin the thread structure where we can find %fp and %i7. */
+#define SPARC64OBSD_UTHREAD_FP_OFFSET 232
+#define SPARC64OBSD_UTHREAD_PC_OFFSET 240
+
+static void
+sparc64obsd_supply_uthread (struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR fp, fp_addr = addr + SPARC64OBSD_UTHREAD_FP_OFFSET;
+ gdb_byte buf[8];
+
+ gdb_assert (regnum >= -1);
+
+ fp = read_memory_unsigned_integer (fp_addr, 8, byte_order);
+ if (regnum == SPARC_SP_REGNUM || regnum == -1)
+ {
+ store_unsigned_integer (buf, 8, byte_order, fp);
+ regcache_raw_supply (regcache, SPARC_SP_REGNUM, buf);
+
+ if (regnum == SPARC_SP_REGNUM)
+ return;
+ }
+
+ if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM
+ || regnum == -1)
+ {
+ CORE_ADDR i7, i7_addr = addr + SPARC64OBSD_UTHREAD_PC_OFFSET;
+
+ i7 = read_memory_unsigned_integer (i7_addr, 8, byte_order);
+ if (regnum == SPARC64_PC_REGNUM || regnum == -1)
+ {
+ store_unsigned_integer (buf, 8, byte_order, i7 + 8);
+ regcache_raw_supply (regcache, SPARC64_PC_REGNUM, buf);
+ }
+ if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
+ {
+ store_unsigned_integer (buf, 8, byte_order, i7 + 12);
+ regcache_raw_supply (regcache, SPARC64_NPC_REGNUM, buf);
+ }
+
+ if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM)
+ return;
+ }
+
+ sparc_supply_rwindow (regcache, fp, regnum);
+}
+
+static void
+sparc64obsd_collect_uthread(const struct regcache *regcache,
+ int regnum, CORE_ADDR addr)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp;
+ gdb_byte buf[8];
+
+ gdb_assert (regnum >= -1);
+
+ if (regnum == SPARC_SP_REGNUM || regnum == -1)
+ {
+ CORE_ADDR fp_addr = addr + SPARC64OBSD_UTHREAD_FP_OFFSET;
+
+ regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
+ write_memory (fp_addr,buf, 8);
+ }
+
+ if (regnum == SPARC64_PC_REGNUM || regnum == -1)
+ {
+ CORE_ADDR i7, i7_addr = addr + SPARC64OBSD_UTHREAD_PC_OFFSET;
+
+ regcache_raw_collect (regcache, SPARC64_PC_REGNUM, buf);
+ i7 = extract_unsigned_integer (buf, 8, byte_order) - 8;
+ write_memory_unsigned_integer (i7_addr, 8, byte_order, i7);
+
+ if (regnum == SPARC64_PC_REGNUM)
+ return;
+ }
+
+ regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
+ sp = extract_unsigned_integer (buf, 8, byte_order);
+ sparc_collect_rwindow (regcache, sp, regnum);
+}
+\f
+
+static const struct regset sparc64obsd_gregset =
+ {
+ NULL, sparc64obsd_supply_gregset, NULL
+ };
+
+static const struct regset sparc64obsd_fpregset =
+ {
+ NULL, sparc64obsd_supply_fpregset, NULL
+ };
+
+static void
+sparc64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->gregset = &sparc64obsd_gregset;
+ tdep->sizeof_gregset = 288;
+ tdep->fpregset = &sparc64obsd_fpregset;
+ tdep->sizeof_fpregset = 272;
+
+ /* Make sure we can single-step "new" syscalls. */
+ tdep->step_trap = sparcnbsd_step_trap;
+
+ frame_unwind_append_unwinder (gdbarch, &sparc64obsd_frame_unwind);
+ frame_unwind_append_unwinder (gdbarch, &sparc64obsd_trapframe_unwind);
+
+ sparc64_init_abi (info, gdbarch);
+ obsd_init_abi (info, gdbarch);
+
+ /* OpenBSD/sparc64 has SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
+
+ /* OpenBSD provides a user-level threads implementation. */
+ bsd_uthread_set_supply_uthread (gdbarch, sparc64obsd_supply_uthread);
+ bsd_uthread_set_collect_uthread (gdbarch, sparc64obsd_collect_uthread);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_sparc64obsd_tdep (void);
+
+void
+_initialize_sparc64obsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
+ GDB_OSABI_OPENBSD_ELF, sparc64obsd_init_abi);
+}
extern void sparc64_sol2_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch);
-/* Variables exported from sparc64fbsd-tdep.c. */
+/* Variables exported from sparc64-fbsd-tdep.c. */
/* Register offsets for FreeBSD/sparc64. */
extern const struct sparc_gregmap sparc64fbsd_gregmap;
-/* Functions and variables exported from sparc64nbsd-tdep.c. */
+/* Functions and variables exported from sparc64-nbsd-tdep.c. */
/* Register offsets for NetBSD/sparc64. */
extern const struct sparc_gregmap sparc64nbsd_gregmap;
+++ /dev/null
-/* Native-dependent code for FreeBSD/sparc64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "regcache.h"
-#include "target.h"
-
-#include "fbsd-nat.h"
-#include "sparc64-tdep.h"
-#include "sparc-nat.h"
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/types.h>
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-sparc64fbsd_kvm_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- /* The following is true for FreeBSD 5.4:
-
- The pcb contains %sp and %pc. Since the register windows are
- explicitly flushed, we can find the `local' and `in' registers on
- the stack. */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp);
- regcache_raw_supply (regcache, SPARC64_PC_REGNUM, &pcb->pcb_pc);
-
- /* Synthesize %npc. */
- pcb->pcb_pc += 4;
- regcache_raw_supply (regcache, SPARC64_NPC_REGNUM, &pcb->pcb_pc);
-
- /* Read `local' and `in' registers from the stack. */
- sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
-
- return 1;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_sparc64fbsd_nat (void);
-
-void
-_initialize_sparc64fbsd_nat (void)
-{
- struct target_ops *t;
-
- /* Add some extra features to the generic SPARC target. */
- t = sparc_target ();
- fbsd_nat_add_target (t);
-
- sparc_gregmap = &sparc64fbsd_gregmap;
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (sparc64fbsd_kvm_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for FreeBSD/sparc64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "target.h"
-#include "trad-frame.h"
-
-#include "sparc64-tdep.h"
-#include "fbsd-tdep.h"
-#include "solib-svr4.h"
-
-/* From <machine/reg.h>. */
-const struct sparc_gregmap sparc64fbsd_gregmap =
-{
- 26 * 8, /* "tstate" */
- 25 * 8, /* %pc */
- 24 * 8, /* %npc */
- 28 * 8, /* %y */
- 16 * 8, /* %fprs */
- -1,
- 1 * 8, /* %g1 */
- -1, /* %l0 */
- 8 /* sizeof (%y) */
-};
-\f
-
-static void
-sparc64fbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- sparc64_supply_gregset (&sparc64fbsd_gregmap, regcache, regnum, gregs);
-}
-
-static void
-sparc64fbsd_collect_gregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *gregs, size_t len)
-{
- sparc64_collect_gregset (&sparc64fbsd_gregmap, regcache, regnum, gregs);
-}
-
-static void
-sparc64fbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-
-static void
-sparc64fbsd_collect_fpregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *fpregs, size_t len)
-{
- sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-\f
-
-/* Signal trampolines. */
-
-static int
-sparc64fbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
-{
- return (name && strcmp (name, "__sigtramp") == 0);
-}
-
-static struct sparc_frame_cache *
-sparc64fbsd_sigtramp_frame_cache (struct frame_info *this_frame,
- void **this_cache)
-{
- struct sparc_frame_cache *cache;
- CORE_ADDR addr, mcontext_addr, sp;
- LONGEST fprs;
- int regnum;
-
- if (*this_cache)
- return (struct sparc_frame_cache *) *this_cache;
-
- cache = sparc_frame_cache (this_frame, this_cache);
- gdb_assert (cache == *this_cache);
-
- cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
-
- /* The third argument is a pointer to an instance of `ucontext_t',
- which has a member `uc_mcontext' that contains the saved
- registers. */
- addr = get_frame_register_unsigned (this_frame, SPARC_O2_REGNUM);
- mcontext_addr = addr + 64;
-
- /* The following registers travel in the `mc_local' slots of
- `mcontext_t'. */
- addr = mcontext_addr + 16 * 8;
- cache->saved_regs[SPARC64_FPRS_REGNUM].addr = addr + 0 * 8;
- cache->saved_regs[SPARC64_FSR_REGNUM].addr = addr + 1 * 8;
-
- /* The following registers travel in the `mc_in' slots of
- `mcontext_t'. */
- addr = mcontext_addr + 24 * 8;
- cache->saved_regs[SPARC64_NPC_REGNUM].addr = addr + 0 * 8;
- cache->saved_regs[SPARC64_PC_REGNUM].addr = addr + 1 * 8;
- cache->saved_regs[SPARC64_STATE_REGNUM].addr = addr + 2 * 8;
- cache->saved_regs[SPARC64_Y_REGNUM].addr = addr + 4 * 8;
-
- /* The `global' and `out' registers travel in the `mc_global' and
- `mc_out' slots of `mcontext_t', except for %g0. Since %g0 is
- always zero, keep the identity encoding. */
- for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 8;
- regnum <= SPARC_O7_REGNUM; regnum++, addr += 8)
- cache->saved_regs[regnum].addr = addr;
-
- /* The `local' and `in' registers have been saved in the register
- save area. */
- addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
- sp = get_frame_memory_unsigned (this_frame, addr, 8);
- for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
- regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
- cache->saved_regs[regnum].addr = addr;
-
- /* The floating-point registers are only saved if the FEF bit in
- %fprs has been set. */
-
-#define FPRS_FEF (1 << 2)
-
- addr = cache->saved_regs[SPARC64_FPRS_REGNUM].addr;
- fprs = get_frame_memory_unsigned (this_frame, addr, 8);
- if (fprs & FPRS_FEF)
- {
- for (regnum = SPARC_F0_REGNUM, addr = mcontext_addr + 32 * 8;
- regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
- cache->saved_regs[regnum].addr = addr;
-
- for (regnum = SPARC64_F32_REGNUM;
- regnum <= SPARC64_F62_REGNUM; regnum++, addr += 8)
- cache->saved_regs[regnum].addr = addr;
- }
-
- return cache;
-}
-
-static void
-sparc64fbsd_sigtramp_frame_this_id (struct frame_info *this_frame,
- void **this_cache,
- struct frame_id *this_id)
-{
- struct sparc_frame_cache *cache =
- sparc64fbsd_sigtramp_frame_cache (this_frame, this_cache);
-
- (*this_id) = frame_id_build (cache->base, cache->pc);
-}
-
-static struct value *
-sparc64fbsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct sparc_frame_cache *cache =
- sparc64fbsd_sigtramp_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
-}
-
-static int
-sparc64fbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (sparc64fbsd_pc_in_sigtramp (pc, name))
- return 1;
-
- return 0;
-}
-
-static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind =
-{
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- sparc64fbsd_sigtramp_frame_this_id,
- sparc64fbsd_sigtramp_frame_prev_register,
- NULL,
- sparc64fbsd_sigtramp_frame_sniffer
-};
-\f
-
-static const struct regset sparc64fbsd_gregset =
- {
- NULL, sparc64fbsd_supply_gregset, sparc64fbsd_collect_gregset
- };
-
-static const struct regset sparc64fbsd_fpregset =
- {
- NULL, sparc64fbsd_supply_fpregset, sparc64fbsd_collect_fpregset
- };
-
-static void
-sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Generic FreeBSD support. */
- fbsd_init_abi (info, gdbarch);
-
- tdep->gregset = &sparc64fbsd_gregset;
- tdep->sizeof_gregset = 256;
-
- tdep->fpregset = &sparc64fbsd_fpregset;
- tdep->sizeof_fpregset = 272;
-
- frame_unwind_append_unwinder (gdbarch, &sparc64fbsd_sigtramp_frame_unwind);
-
- sparc64_init_abi (info, gdbarch);
-
- /* FreeBSD/sparc64 has SVR4-style shared libraries. */
- set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-}
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_sparc64fbsd_tdep (void);
-
-void
-_initialize_sparc64fbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
- GDB_OSABI_FREEBSD_ELF, sparc64fbsd_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for NetBSD/sparc64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "target.h"
-
-#include "sparc64-tdep.h"
-#include "sparc-nat.h"
-
-/* NetBSD is different from the other OSes that support both SPARC and
- UltraSPARC in that the result of ptrace(2) depends on whether the
- traced process is 32-bit or 64-bit. */
-
-static void
-sparc64nbsd_supply_gregset (const struct sparc_gregmap *gregmap,
- struct regcache *regcache,
- int regnum, const void *gregs)
-{
- int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
-
- if (sparc32)
- sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
- else
- sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
-}
-
-static void
-sparc64nbsd_collect_gregset (const struct sparc_gregmap *gregmap,
- const struct regcache *regcache,
- int regnum, void *gregs)
-{
- int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
-
- if (sparc32)
- sparc32_collect_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
- else
- sparc64_collect_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
-}
-
-static void
-sparc64nbsd_supply_fpregset (const struct sparc_fpregmap *fpregmap,
- struct regcache *regcache,
- int regnum, const void *fpregs)
-{
- int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
-
- if (sparc32)
- sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
- else
- sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-
-static void
-sparc64nbsd_collect_fpregset (const struct sparc_fpregmap *fpregmap,
- const struct regcache *regcache,
- int regnum, void *fpregs)
-{
- int sparc32 = (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32);
-
- if (sparc32)
- sparc32_collect_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
- else
- sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-
-/* Determine whether `gregset_t' contains register REGNUM. */
-
-static int
-sparc64nbsd_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
-{
- if (gdbarch_ptr_bit (gdbarch) == 32)
- return sparc32_gregset_supplies_p (gdbarch, regnum);
-
- /* Integer registers. */
- if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
- || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
- || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
- || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM))
- return 1;
-
- /* Control registers. */
- if (regnum == SPARC64_PC_REGNUM
- || regnum == SPARC64_NPC_REGNUM
- || regnum == SPARC64_STATE_REGNUM
- || regnum == SPARC64_Y_REGNUM)
- return 1;
-
- return 0;
-}
-
-/* Determine whether `fpregset_t' contains register REGNUM. */
-
-static int
-sparc64nbsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
-{
- if (gdbarch_ptr_bit (gdbarch) == 32)
- return sparc32_fpregset_supplies_p (gdbarch, regnum);
-
- /* Floating-point registers. */
- if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
- || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM))
- return 1;
-
- /* Control registers. */
- if (regnum == SPARC64_FSR_REGNUM)
- return 1;
-
- return 0;
-}
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/types.h>
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-sparc64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- u_int64_t state;
- int regnum;
-
- /* The following is true for NetBSD 1.6.2:
-
- The pcb contains %sp and %pc, %pstate and %cwp. From this
- information we reconstruct the register state as it would look
- when we just returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- /* If the program counter is zero, this is probably a core dump, and
- we can get %pc from the stack. */
- if (pcb->pcb_pc == 0)
- read_memory(pcb->pcb_sp + BIAS - 176 + (11 * 8),
- (gdb_byte *)&pcb->pcb_pc, sizeof pcb->pcb_pc);
-
- regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp);
- regcache_raw_supply (regcache, SPARC64_PC_REGNUM, &pcb->pcb_pc);
-
- state = pcb->pcb_pstate << 8 | pcb->pcb_cwp;
- regcache_raw_supply (regcache, SPARC64_STATE_REGNUM, &state);
-
- sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
-
- return 1;
-}
-
-\f
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_sparc64nbsd_nat (void);
-
-void
-_initialize_sparc64nbsd_nat (void)
-{
- sparc_supply_gregset = sparc64nbsd_supply_gregset;
- sparc_collect_gregset = sparc64nbsd_collect_gregset;
- sparc_supply_fpregset = sparc64nbsd_supply_fpregset;
- sparc_collect_fpregset = sparc64nbsd_collect_fpregset;
- sparc_gregset_supplies_p = sparc64nbsd_gregset_supplies_p;
- sparc_fpregset_supplies_p = sparc64nbsd_fpregset_supplies_p;
-
- /* We've got nothing to add to the generic SPARC target. */
- add_target (sparc_target ());
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (sparc64nbsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/sparc64.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
- Based on code contributed by Wasabi Systems, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "symtab.h"
-#include "objfiles.h"
-#include "solib-svr4.h"
-#include "trad-frame.h"
-
-#include "sparc64-tdep.h"
-#include "nbsd-tdep.h"
-
-/* From <machine/reg.h>. */
-const struct sparc_gregmap sparc64nbsd_gregmap =
-{
- 0 * 8, /* "tstate" */
- 1 * 8, /* %pc */
- 2 * 8, /* %npc */
- 3 * 8, /* %y */
- -1, /* %fprs */
- -1,
- 5 * 8, /* %g1 */
- -1, /* %l0 */
- 4 /* sizeof (%y) */
-};
-\f
-
-static void
-sparc64nbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
-}
-
-static void
-sparc64nbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-\f
-
-/* Signal trampolines. */
-
-/* The following variables describe the location of an on-stack signal
- trampoline. The current values correspond to the memory layout for
- NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
- up, since NetBSD uses signal trampolines provided by libc now. */
-
-static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL;
-static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL;
-
-static int
-sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
-{
- if (pc >= sparc64nbsd_sigtramp_start && pc < sparc64nbsd_sigtramp_end)
- return 1;
-
- return nbsd_pc_in_sigtramp (pc, name);
-}
-
-struct trad_frame_saved_reg *
-sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
- struct frame_info *this_frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct trad_frame_saved_reg *saved_regs;
- CORE_ADDR addr, sp;
- int regnum, delta;
-
- saved_regs = trad_frame_alloc_saved_regs (this_frame);
-
- /* The registers are saved in bits and pieces scattered all over the
- place. The code below records their location on the assumption
- that the part of the signal trampoline that saves the state has
- been executed. */
-
- saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
- saved_regs[SPARC64_PC_REGNUM].addr = sigcontext_addr + 16;
- saved_regs[SPARC64_NPC_REGNUM].addr = sigcontext_addr + 24;
- saved_regs[SPARC64_STATE_REGNUM].addr = sigcontext_addr + 32;
- saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 40;
- saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 48;
-
- /* The remaining `global' registers and %y are saved in the `local'
- registers. */
- delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
- for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
- saved_regs[regnum].realreg = regnum + delta;
- saved_regs[SPARC64_Y_REGNUM].realreg = SPARC_L1_REGNUM;
-
- /* The remaining `out' registers can be found in the current frame's
- `in' registers. */
- delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
- for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
- saved_regs[regnum].realreg = regnum + delta;
- saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
-
- /* The `local' and `in' registers have been saved in the register
- save area. */
- addr = saved_regs[SPARC_SP_REGNUM].addr;
- sp = get_frame_memory_unsigned (this_frame, addr, 8);
- for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
- regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
- saved_regs[regnum].addr = addr;
-
- /* Handle StackGhost. */
- {
- ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
-
- if (wcookie != 0)
- {
- ULONGEST i7;
-
- addr = saved_regs[SPARC_I7_REGNUM].addr;
- i7 = get_frame_memory_unsigned (this_frame, addr, 8);
- trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
- }
- }
-
- /* TODO: Handle the floating-point registers. */
-
- return saved_regs;
-}
-
-static struct sparc_frame_cache *
-sparc64nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
- void **this_cache)
-{
- struct sparc_frame_cache *cache;
- CORE_ADDR addr;
-
- if (*this_cache)
- return (struct sparc_frame_cache *) *this_cache;
-
- cache = sparc_frame_cache (this_frame, this_cache);
- gdb_assert (cache == *this_cache);
-
- /* If we couldn't find the frame's function, we're probably dealing
- with an on-stack signal trampoline. */
- if (cache->pc == 0)
- {
- cache->pc = sparc64nbsd_sigtramp_start;
-
- /* Since we couldn't find the frame's function, the cache was
- initialized under the assumption that we're frameless. */
- sparc_record_save_insn (cache);
- addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
- if (addr & 1)
- addr += BIAS;
- cache->base = addr;
- }
-
- /* We find the appropriate instance of `struct sigcontext' at a
- fixed offset in the signal frame. */
- addr = cache->base + 128 + 8;
- cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
-
- return cache;
-}
-
-static void
-sparc64nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
- void **this_cache,
- struct frame_id *this_id)
-{
- struct sparc_frame_cache *cache =
- sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
-
- (*this_id) = frame_id_build (cache->base, cache->pc);
-}
-
-static struct value *
-sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct sparc_frame_cache *cache =
- sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
-}
-
-static int
-sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (sparc64nbsd_pc_in_sigtramp (pc, name))
- {
- if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
- return 1;
- }
-
- return 0;
-}
-
-static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
-{
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- sparc64nbsd_sigcontext_frame_this_id,
- sparc64nbsd_sigcontext_frame_prev_register,
- NULL,
- sparc64nbsd_sigtramp_frame_sniffer
-};
-\f
-
-static const struct regset sparc64nbsd_gregset =
- {
- NULL, sparc64nbsd_supply_gregset, NULL
- };
-
-static const struct regset sparc64nbsd_fpregset =
- {
- NULL, sparc64nbsd_supply_fpregset, NULL
- };
-
-static void
-sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- tdep->gregset = &sparc64nbsd_gregset;
- tdep->sizeof_gregset = 160;
-
- tdep->fpregset = &sparc64nbsd_fpregset;
- tdep->sizeof_fpregset = 272;
-
- /* Make sure we can single-step "new" syscalls. */
- tdep->step_trap = sparcnbsd_step_trap;
-
- frame_unwind_append_unwinder (gdbarch, &sparc64nbsd_sigcontext_frame_unwind);
-
- sparc64_init_abi (info, gdbarch);
-
- /* NetBSD/sparc64 has SVR4-style shared libraries. */
- set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_sparc64nbsd_tdep (void);
-
-void
-_initialize_sparc64nbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
- GDB_OSABI_NETBSD_ELF, sparc64nbsd_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for OpenBSD/sparc64.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "target.h"
-
-#include "sparc64-tdep.h"
-#include "sparc-nat.h"
-#include "obsd-nat.h"
-
-/* Determine whether `gregset_t' contains register REGNUM. */
-
-static int
-sparc64obsd_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
-{
- /* Integer registers. */
- if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
- || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
- || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
- || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM))
- return 1;
-
- /* Control registers. */
- if (regnum == SPARC64_PC_REGNUM
- || regnum == SPARC64_NPC_REGNUM
- || regnum == SPARC64_STATE_REGNUM
- || regnum == SPARC64_Y_REGNUM)
- return 1;
-
- return 0;
-}
-
-/* Determine whether `fpregset_t' contains register REGNUM. */
-
-static int
-sparc64obsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
-{
- /* Floating-point registers. */
- if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
- || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM))
- return 1;
-
- /* Control registers. */
- if (regnum == SPARC64_FSR_REGNUM)
- return 1;
-
- return 0;
-}
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/types.h>
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-sparc64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- u_int64_t state;
- int regnum;
-
- /* The following is true for OpenBSD 3.0:
-
- The pcb contains %sp and %pc, %pstate and %cwp. From this
- information we reconstruct the register state as it would look
- when we just returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- /* If the program counter is zero, this is probably a core dump, and
- we can get %pc from the stack. */
- if (pcb->pcb_pc == 0)
- read_memory(pcb->pcb_sp + BIAS - 176 + (11 * 8),
- (gdb_byte *)&pcb->pcb_pc, sizeof pcb->pcb_pc);
-
- regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp);
- regcache_raw_supply (regcache, SPARC64_PC_REGNUM, &pcb->pcb_pc);
-
- state = pcb->pcb_pstate << 8 | pcb->pcb_cwp;
- regcache_raw_supply (regcache, SPARC64_STATE_REGNUM, &state);
-
- sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
-
- return 1;
-}
-
-\f
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_sparc64obsd_nat (void);
-
-void
-_initialize_sparc64obsd_nat (void)
-{
- sparc_supply_gregset = sparc64_supply_gregset;
- sparc_collect_gregset = sparc64_collect_gregset;
- sparc_supply_fpregset = sparc64_supply_fpregset;
- sparc_collect_fpregset = sparc64_collect_fpregset;
- sparc_gregset_supplies_p = sparc64obsd_gregset_supplies_p;
- sparc_fpregset_supplies_p = sparc64obsd_fpregset_supplies_p;
-
- sparc_gregmap = &sparc64nbsd_gregmap;
- sparc_fpregmap = &sparc64_bsd_fpregmap;
-
- /* Add some extra features to the generic SPARC target. */
- obsd_add_target (sparc_target ());
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (sparc64obsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/sparc64.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "symtab.h"
-#include "objfiles.h"
-#include "trad-frame.h"
-
-#include "obsd-tdep.h"
-#include "sparc64-tdep.h"
-#include "solib-svr4.h"
-#include "bsd-uthread.h"
-
-/* Older OpenBSD versions used the traditional NetBSD core file
- format, even for ports that use ELF. These core files don't use
- multiple register sets. Instead, the general-purpose and
- floating-point registers are lumped together in a single section.
- Unlike on NetBSD, OpenBSD uses a different layout for its
- general-purpose registers than the layout used for ptrace(2).
-
- Newer OpenBSD versions use ELF core files. Here the register sets
- match the ptrace(2) layout. */
-
-/* From <machine/reg.h>. */
-const struct sparc_gregmap sparc64obsd_gregmap =
-{
- 0 * 8, /* "tstate" */
- 1 * 8, /* %pc */
- 2 * 8, /* %npc */
- 3 * 8, /* %y */
- -1, /* %fprs */
- -1,
- 5 * 8, /* %g1 */
- 20 * 8, /* %l0 */
- 4 /* sizeof (%y) */
-};
-
-const struct sparc_gregmap sparc64obsd_core_gregmap =
-{
- 0 * 8, /* "tstate" */
- 1 * 8, /* %pc */
- 2 * 8, /* %npc */
- 3 * 8, /* %y */
- -1, /* %fprs */
- -1,
- 7 * 8, /* %g1 */
- 22 * 8, /* %l0 */
- 4 /* sizeof (%y) */
-};
-
-static void
-sparc64obsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const void *fpregs = (char *)gregs + 288;
-
- if (len < 832)
- {
- sparc64_supply_gregset (&sparc64obsd_gregmap, regcache, regnum, gregs);
- return;
- }
-
- sparc64_supply_gregset (&sparc64obsd_core_gregmap, regcache, regnum, gregs);
- sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-
-static void
-sparc64obsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-\f
-
-/* Signal trampolines. */
-
-/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
- in virtual memory. The randomness makes it somewhat tricky to
- detect it, but fortunately we can rely on the fact that the start
- of the sigtramp routine is page-aligned. We recognize the
- trampoline by looking for the code that invokes the sigreturn
- system call. The offset where we can find that code varies from
- release to release.
-
- By the way, the mapping mentioned above is read-only, so you cannot
- place a breakpoint in the signal trampoline. */
-
-/* Default page size. */
-static const int sparc64obsd_page_size = 8192;
-
-/* Offset for sigreturn(2). */
-static const int sparc64obsd_sigreturn_offset[] = {
- 0xf0, /* OpenBSD 3.8 */
- 0xec, /* OpenBSD 3.6 */
- 0xe8, /* OpenBSD 3.2 */
- -1
-};
-
-static int
-sparc64obsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
-{
- CORE_ADDR start_pc = (pc & ~(sparc64obsd_page_size - 1));
- unsigned long insn;
- const int *offset;
-
- if (name)
- return 0;
-
- for (offset = sparc64obsd_sigreturn_offset; *offset != -1; offset++)
- {
- /* Check for "restore %g0, SYS_sigreturn, %g1". */
- insn = sparc_fetch_instruction (start_pc + *offset);
- if (insn != 0x83e82067)
- continue;
-
- /* Check for "t ST_SYSCALL". */
- insn = sparc_fetch_instruction (start_pc + *offset + 8);
- if (insn != 0x91d02000)
- continue;
-
- return 1;
- }
-
- return 0;
-}
-
-static struct sparc_frame_cache *
-sparc64obsd_frame_cache (struct frame_info *this_frame, void **this_cache)
-{
- struct sparc_frame_cache *cache;
- CORE_ADDR addr;
-
- if (*this_cache)
- return (struct sparc_frame_cache *) *this_cache;
-
- cache = sparc_frame_cache (this_frame, this_cache);
- gdb_assert (cache == *this_cache);
-
- /* If we couldn't find the frame's function, we're probably dealing
- with an on-stack signal trampoline. */
- if (cache->pc == 0)
- {
- cache->pc = get_frame_pc (this_frame);
- cache->pc &= ~(sparc64obsd_page_size - 1);
-
- /* Since we couldn't find the frame's function, the cache was
- initialized under the assumption that we're frameless. */
- sparc_record_save_insn (cache);
- addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
- if (addr & 1)
- addr += BIAS;
- cache->base = addr;
- }
-
- /* We find the appropriate instance of `struct sigcontext' at a
- fixed offset in the signal frame. */
- addr = cache->base + 128 + 16;
- cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
-
- return cache;
-}
-
-static void
-sparc64obsd_frame_this_id (struct frame_info *this_frame, void **this_cache,
- struct frame_id *this_id)
-{
- struct sparc_frame_cache *cache =
- sparc64obsd_frame_cache (this_frame, this_cache);
-
- (*this_id) = frame_id_build (cache->base, cache->pc);
-}
-
-static struct value *
-sparc64obsd_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct sparc_frame_cache *cache =
- sparc64obsd_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
-}
-
-static int
-sparc64obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (sparc64obsd_pc_in_sigtramp (pc, name))
- return 1;
-
- return 0;
-}
-
-static const struct frame_unwind sparc64obsd_frame_unwind =
-{
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- sparc64obsd_frame_this_id,
- sparc64obsd_frame_prev_register,
- NULL,
- sparc64obsd_sigtramp_frame_sniffer
-};
-\f
-/* Kernel debugging support. */
-
-static struct sparc_frame_cache *
-sparc64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
-{
- struct sparc_frame_cache *cache;
- CORE_ADDR sp, trapframe_addr;
- int regnum;
-
- if (*this_cache)
- return (struct sparc_frame_cache *) *this_cache;
-
- cache = sparc_frame_cache (this_frame, this_cache);
- gdb_assert (cache == *this_cache);
-
- sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
- trapframe_addr = sp + BIAS + 176;
-
- cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
-
- cache->saved_regs[SPARC64_STATE_REGNUM].addr = trapframe_addr;
- cache->saved_regs[SPARC64_PC_REGNUM].addr = trapframe_addr + 8;
- cache->saved_regs[SPARC64_NPC_REGNUM].addr = trapframe_addr + 16;
-
- for (regnum = SPARC_G0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
- cache->saved_regs[regnum].addr =
- trapframe_addr + 48 + (regnum - SPARC_G0_REGNUM) * 8;
-
- return cache;
-}
-
-static void
-sparc64obsd_trapframe_this_id (struct frame_info *this_frame,
- void **this_cache, struct frame_id *this_id)
-{
- struct sparc_frame_cache *cache =
- sparc64obsd_trapframe_cache (this_frame, this_cache);
-
- (*this_id) = frame_id_build (cache->base, cache->pc);
-}
-
-static struct value *
-sparc64obsd_trapframe_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct sparc_frame_cache *cache =
- sparc64obsd_trapframe_cache (this_frame, this_cache);
-
- return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
-}
-
-static int
-sparc64obsd_trapframe_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- CORE_ADDR pc;
- ULONGEST pstate;
- const char *name;
-
- /* Check whether we are in privileged mode, and bail out if we're not. */
- pstate = get_frame_register_unsigned (this_frame, SPARC64_PSTATE_REGNUM);
- if ((pstate & SPARC64_PSTATE_PRIV) == 0)
- return 0;
-
- pc = get_frame_address_in_block (this_frame);
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (name && strcmp (name, "Lslowtrap_reenter") == 0)
- return 1;
-
- return 0;
-}
-
-static const struct frame_unwind sparc64obsd_trapframe_unwind =
-{
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- sparc64obsd_trapframe_this_id,
- sparc64obsd_trapframe_prev_register,
- NULL,
- sparc64obsd_trapframe_sniffer
-};
-\f
-
-/* Threads support. */
-
-/* Offset wthin the thread structure where we can find %fp and %i7. */
-#define SPARC64OBSD_UTHREAD_FP_OFFSET 232
-#define SPARC64OBSD_UTHREAD_PC_OFFSET 240
-
-static void
-sparc64obsd_supply_uthread (struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR fp, fp_addr = addr + SPARC64OBSD_UTHREAD_FP_OFFSET;
- gdb_byte buf[8];
-
- gdb_assert (regnum >= -1);
-
- fp = read_memory_unsigned_integer (fp_addr, 8, byte_order);
- if (regnum == SPARC_SP_REGNUM || regnum == -1)
- {
- store_unsigned_integer (buf, 8, byte_order, fp);
- regcache_raw_supply (regcache, SPARC_SP_REGNUM, buf);
-
- if (regnum == SPARC_SP_REGNUM)
- return;
- }
-
- if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM
- || regnum == -1)
- {
- CORE_ADDR i7, i7_addr = addr + SPARC64OBSD_UTHREAD_PC_OFFSET;
-
- i7 = read_memory_unsigned_integer (i7_addr, 8, byte_order);
- if (regnum == SPARC64_PC_REGNUM || regnum == -1)
- {
- store_unsigned_integer (buf, 8, byte_order, i7 + 8);
- regcache_raw_supply (regcache, SPARC64_PC_REGNUM, buf);
- }
- if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
- {
- store_unsigned_integer (buf, 8, byte_order, i7 + 12);
- regcache_raw_supply (regcache, SPARC64_NPC_REGNUM, buf);
- }
-
- if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM)
- return;
- }
-
- sparc_supply_rwindow (regcache, fp, regnum);
-}
-
-static void
-sparc64obsd_collect_uthread(const struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp;
- gdb_byte buf[8];
-
- gdb_assert (regnum >= -1);
-
- if (regnum == SPARC_SP_REGNUM || regnum == -1)
- {
- CORE_ADDR fp_addr = addr + SPARC64OBSD_UTHREAD_FP_OFFSET;
-
- regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
- write_memory (fp_addr,buf, 8);
- }
-
- if (regnum == SPARC64_PC_REGNUM || regnum == -1)
- {
- CORE_ADDR i7, i7_addr = addr + SPARC64OBSD_UTHREAD_PC_OFFSET;
-
- regcache_raw_collect (regcache, SPARC64_PC_REGNUM, buf);
- i7 = extract_unsigned_integer (buf, 8, byte_order) - 8;
- write_memory_unsigned_integer (i7_addr, 8, byte_order, i7);
-
- if (regnum == SPARC64_PC_REGNUM)
- return;
- }
-
- regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
- sp = extract_unsigned_integer (buf, 8, byte_order);
- sparc_collect_rwindow (regcache, sp, regnum);
-}
-\f
-
-static const struct regset sparc64obsd_gregset =
- {
- NULL, sparc64obsd_supply_gregset, NULL
- };
-
-static const struct regset sparc64obsd_fpregset =
- {
- NULL, sparc64obsd_supply_fpregset, NULL
- };
-
-static void
-sparc64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- tdep->gregset = &sparc64obsd_gregset;
- tdep->sizeof_gregset = 288;
- tdep->fpregset = &sparc64obsd_fpregset;
- tdep->sizeof_fpregset = 272;
-
- /* Make sure we can single-step "new" syscalls. */
- tdep->step_trap = sparcnbsd_step_trap;
-
- frame_unwind_append_unwinder (gdbarch, &sparc64obsd_frame_unwind);
- frame_unwind_append_unwinder (gdbarch, &sparc64obsd_trapframe_unwind);
-
- sparc64_init_abi (info, gdbarch);
- obsd_init_abi (info, gdbarch);
-
- /* OpenBSD/sparc64 has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
- set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
-
- /* OpenBSD provides a user-level threads implementation. */
- bsd_uthread_set_supply_uthread (gdbarch, sparc64obsd_supply_uthread);
- bsd_uthread_set_collect_uthread (gdbarch, sparc64obsd_collect_uthread);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_sparc64obsd_tdep (void);
-
-void
-_initialize_sparc64obsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
- GDB_OSABI_OPENBSD_ELF, sparc64obsd_init_abi);
-}
+++ /dev/null
-/* Native-dependent code for NetBSD/sparc.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "regcache.h"
-#include "target.h"
-
-#include "sparc-tdep.h"
-#include "sparc-nat.h"
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/types.h>
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-sparc32nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- /* The following is true for NetBSD 1.6.2:
-
- The pcb contains %sp, %pc, %psr and %wim. From this information
- we reconstruct the register state as it would look when we just
- returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp);
- regcache_raw_supply (regcache, SPARC_O7_REGNUM, &pcb->pcb_pc);
- regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, &pcb->pcb_psr);
- regcache_raw_supply (regcache, SPARC32_WIM_REGNUM, &pcb->pcb_wim);
- regcache_raw_supply (regcache, SPARC32_PC_REGNUM, &pcb->pcb_pc);
-
- sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
-
- return 1;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_sparcnbsd_nat (void);
-
-void
-_initialize_sparcnbsd_nat (void)
-{
- sparc_gregmap = &sparc32nbsd_gregmap;
- sparc_fpregmap = &sparc32_bsd_fpregmap;
-
- /* We've got nothing to add to the generic SPARC target. */
- add_target (sparc_target ());
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (sparc32nbsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/sparc.
-
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
- Contributed by Wasabi Systems, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "gdbtypes.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "solib-svr4.h"
-#include "symtab.h"
-#include "trad-frame.h"
-
-#include "sparc-tdep.h"
-#include "nbsd-tdep.h"
-
-/* Macros to extract fields from SPARC instructions. */
-#define X_RS1(i) (((i) >> 14) & 0x1f)
-#define X_RS2(i) ((i) & 0x1f)
-#define X_I(i) (((i) >> 13) & 1)
-
-const struct sparc_gregmap sparc32nbsd_gregmap =
-{
- 0 * 4, /* %psr */
- 1 * 4, /* %pc */
- 2 * 4, /* %npc */
- 3 * 4, /* %y */
- -1, /* %wim */
- -1, /* %tbr */
- 5 * 4, /* %g1 */
- -1 /* %l0 */
-};
-
-static void
-sparc32nbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
-
- /* Traditional NetBSD core files don't use multiple register sets.
- Instead, the general-purpose and floating-point registers are
- lumped together in a single section. */
- if (len >= 212)
- sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum,
- (const char *) gregs + 80);
-}
-
-static void
-sparc32nbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
-}
-
-\f
-/* Signal trampolines. */
-
-/* The following variables describe the location of an on-stack signal
- trampoline. The current values correspond to the memory layout for
- NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
- up, since NetBSD uses signal trampolines provided by libc now. */
-
-static const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0;
-static const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0;
-
-static int
-sparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
-{
- if (pc >= sparc32nbsd_sigtramp_start && pc < sparc32nbsd_sigtramp_end)
- return 1;
-
- return nbsd_pc_in_sigtramp (pc, name);
-}
-
-struct trad_frame_saved_reg *
-sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct trad_frame_saved_reg *saved_regs;
- CORE_ADDR addr, sigcontext_addr;
- int regnum, delta;
- ULONGEST psr;
-
- saved_regs = trad_frame_alloc_saved_regs (this_frame);
-
- /* We find the appropriate instance of `struct sigcontext' at a
- fixed offset in the signal frame. */
- addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
- sigcontext_addr = addr + 64 + 16;
-
- /* The registers are saved in bits and pieces scattered all over the
- place. The code below records their location on the assumption
- that the part of the signal trampoline that saves the state has
- been executed. */
-
- saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
- saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
- saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
- saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
- saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
- saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;
-
- /* The remaining `global' registers and %y are saved in the `local'
- registers. */
- delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
- for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
- saved_regs[regnum].realreg = regnum + delta;
- saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM;
-
- /* The remaining `out' registers can be found in the current frame's
- `in' registers. */
- delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
- for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
- saved_regs[regnum].realreg = regnum + delta;
- saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
-
- /* The `local' and `in' registers have been saved in the register
- save area. */
- addr = saved_regs[SPARC_SP_REGNUM].addr;
- addr = get_frame_memory_unsigned (this_frame, addr, 4);
- for (regnum = SPARC_L0_REGNUM;
- regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
- saved_regs[regnum].addr = addr;
-
- /* Handle StackGhost. */
- {
- ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
-
- if (wcookie != 0)
- {
- ULONGEST i7;
-
- addr = saved_regs[SPARC_I7_REGNUM].addr;
- i7 = get_frame_memory_unsigned (this_frame, addr, 4);
- trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
- }
- }
-
- /* The floating-point registers are only saved if the EF bit in %prs
- has been set. */
-
-#define PSR_EF 0x00001000
-
- addr = saved_regs[SPARC32_PSR_REGNUM].addr;
- psr = get_frame_memory_unsigned (this_frame, addr, 4);
- if (psr & PSR_EF)
- {
- CORE_ADDR sp;
-
- sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
- saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
- for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
- regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
- saved_regs[regnum].addr = addr;
- }
-
- return saved_regs;
-}
-
-static struct sparc_frame_cache *
-sparc32nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
- void **this_cache)
-{
- struct sparc_frame_cache *cache;
- CORE_ADDR addr;
-
- if (*this_cache)
- return (struct sparc_frame_cache *) *this_cache;
-
- cache = sparc_frame_cache (this_frame, this_cache);
- gdb_assert (cache == *this_cache);
-
- /* If we couldn't find the frame's function, we're probably dealing
- with an on-stack signal trampoline. */
- if (cache->pc == 0)
- {
- cache->pc = sparc32nbsd_sigtramp_start;
-
- /* Since we couldn't find the frame's function, the cache was
- initialized under the assumption that we're frameless. */
- sparc_record_save_insn (cache);
- addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
- cache->base = addr;
- }
-
- cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
-
- return cache;
-}
-
-static void
-sparc32nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
- void **this_cache,
- struct frame_id *this_id)
-{
- struct sparc_frame_cache *cache =
- sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
-
- (*this_id) = frame_id_build (cache->base, cache->pc);
-}
-
-static struct value *
-sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct sparc_frame_cache *cache =
- sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
-}
-
-static int
-sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (sparc32nbsd_pc_in_sigtramp (pc, name))
- {
- if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
- return 1;
- }
-
- return 0;
-}
-
-static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
-{
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- sparc32nbsd_sigcontext_frame_this_id,
- sparc32nbsd_sigcontext_frame_prev_register,
- NULL,
- sparc32nbsd_sigcontext_frame_sniffer
-};
-\f
-/* Return the address of a system call's alternative return
- address. */
-
-CORE_ADDR
-sparcnbsd_step_trap (struct frame_info *frame, unsigned long insn)
-{
- if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
- || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
- {
- /* "New" system call. */
- ULONGEST number = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);
-
- if (number & 0x400)
- return get_frame_register_unsigned (frame, SPARC_G2_REGNUM);
- if (number & 0x800)
- return get_frame_register_unsigned (frame, SPARC_G7_REGNUM);
- }
-
- return 0;
-}
-\f
-
-static const struct regset sparc32nbsd_gregset =
- {
- NULL, sparc32nbsd_supply_gregset, NULL
- };
-
-static const struct regset sparc32nbsd_fpregset =
- {
- NULL, sparc32nbsd_supply_fpregset, NULL
- };
-
-static void
-sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* NetBSD doesn't support the 128-bit `long double' from the psABI. */
- set_gdbarch_long_double_bit (gdbarch, 64);
- set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
-
- tdep->gregset = &sparc32nbsd_gregset;
- tdep->sizeof_gregset = 20 * 4;
-
- tdep->fpregset = &sparc32nbsd_fpregset;
- tdep->sizeof_fpregset = 33 * 4;
-
- /* Make sure we can single-step "new" syscalls. */
- tdep->step_trap = sparcnbsd_step_trap;
-
- frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
-}
-
-static void
-sparc32nbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- sparc32nbsd_init_abi (info, gdbarch);
-}
-
-void
-sparc32nbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- sparc32nbsd_init_abi (info, gdbarch);
-
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-
-static enum gdb_osabi
-sparcnbsd_aout_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "a.out-sparc-netbsd") == 0)
- return GDB_OSABI_NETBSD_AOUT;
-
- return GDB_OSABI_UNKNOWN;
-}
-
-/* OpenBSD uses the traditional NetBSD core file format, even for
- ports that use ELF. Therefore, if the default OS ABI is OpenBSD
- ELF, we return that instead of NetBSD a.out. This is mainly for
- the benfit of OpenBSD/sparc64, which inherits the sniffer below
- since we include this file for an OpenBSD/sparc64 target. For
- OpenBSD/sparc, the NetBSD a.out OS ABI is probably similar enough
- to both the OpenBSD a.out and the OpenBSD ELF OS ABI. */
-#if defined (GDB_OSABI_DEFAULT) && (GDB_OSABI_DEFAULT == GDB_OSABI_OPENBSD_ELF)
-#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
-#else
-#define GDB_OSABI_NETBSD_CORE GDB_OSABI_NETBSD_AOUT
-#endif
-
-static enum gdb_osabi
-sparcnbsd_core_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
- return GDB_OSABI_NETBSD_CORE;
-
- return GDB_OSABI_UNKNOWN;
-}
-
-\f
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_sparcnbsd_tdep (void);
-
-void
-_initialize_sparcnbsd_tdep (void)
-{
- gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_aout_flavour,
- sparcnbsd_aout_osabi_sniffer);
-
- /* BFD doesn't set a flavour for NetBSD style a.out core files. */
- gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_unknown_flavour,
- sparcnbsd_core_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_AOUT,
- sparc32nbsd_aout_init_abi);
- gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_ELF,
- sparc32nbsd_elf_init_abi);
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/sparc.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "floatformat.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "symtab.h"
-#include "trad-frame.h"
-
-#include "obsd-tdep.h"
-#include "sparc-tdep.h"
-#include "solib-svr4.h"
-#include "bsd-uthread.h"
-
-/* Signal trampolines. */
-
-/* The OpenBSD kernel maps the signal trampoline at some random
- location in user space, which means that the traditional BSD way of
- detecting it won't work.
-
- The signal trampoline will be mapped at an address that is page
- aligned. We recognize the signal trampoline by looking for the
- sigreturn system call. */
-
-static const int sparc32obsd_page_size = 4096;
-
-static int
-sparc32obsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
-{
- CORE_ADDR start_pc = (pc & ~(sparc32obsd_page_size - 1));
- unsigned long insn;
-
- if (name)
- return 0;
-
- /* Check for "restore %g0, SYS_sigreturn, %g1". */
- insn = sparc_fetch_instruction (start_pc + 0xec);
- if (insn != 0x83e82067)
- return 0;
-
- /* Check for "t ST_SYSCALL". */
- insn = sparc_fetch_instruction (start_pc + 0xf4);
- if (insn != 0x91d02000)
- return 0;
-
- return 1;
-}
-
-static struct sparc_frame_cache *
-sparc32obsd_sigtramp_frame_cache (struct frame_info *this_frame,
- void **this_cache)
-{
- struct sparc_frame_cache *cache;
- CORE_ADDR addr;
-
- if (*this_cache)
- return (struct sparc_frame_cache *) *this_cache;
-
- cache = sparc_frame_cache (this_frame, this_cache);
- gdb_assert (cache == *this_cache);
-
- /* If we couldn't find the frame's function, we're probably dealing
- with an on-stack signal trampoline. */
- if (cache->pc == 0)
- {
- cache->pc = get_frame_pc (this_frame);
- cache->pc &= ~(sparc32obsd_page_size - 1);
-
- /* Since we couldn't find the frame's function, the cache was
- initialized under the assumption that we're frameless. */
- sparc_record_save_insn (cache);
- addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
- cache->base = addr;
- }
-
- cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
-
- return cache;
-}
-
-static void
-sparc32obsd_sigtramp_frame_this_id (struct frame_info *this_frame,
- void **this_cache,
- struct frame_id *this_id)
-{
- struct sparc_frame_cache *cache =
- sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);
-
- (*this_id) = frame_id_build (cache->base, cache->pc);
-}
-
-static struct value *
-sparc32obsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct sparc_frame_cache *cache =
- sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
-}
-
-static int
-sparc32obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (sparc32obsd_pc_in_sigtramp (pc, name))
- return 1;
-
- return 0;
-}
-static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind =
-{
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- sparc32obsd_sigtramp_frame_this_id,
- sparc32obsd_sigtramp_frame_prev_register,
- NULL,
- sparc32obsd_sigtramp_frame_sniffer
-};
-
-\f
-
-/* Offset wthin the thread structure where we can find %fp and %i7. */
-#define SPARC32OBSD_UTHREAD_FP_OFFSET 128
-#define SPARC32OBSD_UTHREAD_PC_OFFSET 132
-
-static void
-sparc32obsd_supply_uthread (struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR fp, fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
- gdb_byte buf[4];
-
- gdb_assert (regnum >= -1);
-
- fp = read_memory_unsigned_integer (fp_addr, 4, byte_order);
- if (regnum == SPARC_SP_REGNUM || regnum == -1)
- {
- store_unsigned_integer (buf, 4, byte_order, fp);
- regcache_raw_supply (regcache, SPARC_SP_REGNUM, buf);
-
- if (regnum == SPARC_SP_REGNUM)
- return;
- }
-
- if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM
- || regnum == -1)
- {
- CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
-
- i7 = read_memory_unsigned_integer (i7_addr, 4, byte_order);
- if (regnum == SPARC32_PC_REGNUM || regnum == -1)
- {
- store_unsigned_integer (buf, 4, byte_order, i7 + 8);
- regcache_raw_supply (regcache, SPARC32_PC_REGNUM, buf);
- }
- if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
- {
- store_unsigned_integer (buf, 4, byte_order, i7 + 12);
- regcache_raw_supply (regcache, SPARC32_NPC_REGNUM, buf);
- }
-
- if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
- return;
- }
-
- sparc_supply_rwindow (regcache, fp, regnum);
-}
-
-static void
-sparc32obsd_collect_uthread(const struct regcache *regcache,
- int regnum, CORE_ADDR addr)
-{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp;
- gdb_byte buf[4];
-
- gdb_assert (regnum >= -1);
-
- if (regnum == SPARC_SP_REGNUM || regnum == -1)
- {
- CORE_ADDR fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
-
- regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
- write_memory (fp_addr,buf, 4);
- }
-
- if (regnum == SPARC32_PC_REGNUM || regnum == -1)
- {
- CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
-
- regcache_raw_collect (regcache, SPARC32_PC_REGNUM, buf);
- i7 = extract_unsigned_integer (buf, 4, byte_order) - 8;
- write_memory_unsigned_integer (i7_addr, 4, byte_order, i7);
-
- if (regnum == SPARC32_PC_REGNUM)
- return;
- }
-
- regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
- sp = extract_unsigned_integer (buf, 4, byte_order);
- sparc_collect_rwindow (regcache, sp, regnum);
-}
-\f
-
-static void
-sparc32obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- /* OpenBSD/sparc is very similar to NetBSD/sparc ELF. */
- sparc32nbsd_elf_init_abi (info, gdbarch);
-
- set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
-
- frame_unwind_append_unwinder (gdbarch, &sparc32obsd_sigtramp_frame_unwind);
-
- /* OpenBSD provides a user-level threads implementation. */
- bsd_uthread_set_supply_uthread (gdbarch, sparc32obsd_supply_uthread);
- bsd_uthread_set_collect_uthread (gdbarch, sparc32obsd_collect_uthread);
-}
-
-\f
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_sparc32obsd_tdep (void);
-
-void
-_initialize_sparc32obsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD_ELF,
- sparc32obsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for modern VAX BSD's.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "vax-tdep.h"
+#include "inf-ptrace.h"
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+vaxbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const gdb_byte *regs = gregs;
+ int regnum;
+
+ for (regnum = 0; regnum < VAX_NUM_REGS; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+vaxbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ gdb_byte *regs = gregs;
+ int i;
+
+ for (i = 0; i <= VAX_NUM_REGS; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 4);
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+static void
+vaxbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ vaxbsd_supply_gregset (regcache, ®s);
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers. */
+
+static void
+vaxbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ vaxbsd_collect_gregset (regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+}
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+vaxbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ int regnum;
+
+ /* The following is true for OpenBSD 3.5:
+
+ The pcb contains the register state at the context switch inside
+ cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->KSP == 0)
+ return 0;
+
+ for (regnum = VAX_R0_REGNUM; regnum < VAX_AP_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, &pcb->R[regnum - VAX_R0_REGNUM]);
+ regcache_raw_supply (regcache, VAX_AP_REGNUM, &pcb->AP);
+ regcache_raw_supply (regcache, VAX_FP_REGNUM, &pcb->FP);
+ regcache_raw_supply (regcache, VAX_SP_REGNUM, &pcb->KSP);
+ regcache_raw_supply (regcache, VAX_PC_REGNUM, &pcb->PC);
+ regcache_raw_supply (regcache, VAX_PS_REGNUM, &pcb->PSL);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_vaxbsd_nat (void);
+
+void
+_initialize_vaxbsd_nat (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = vaxbsd_fetch_inferior_registers;
+ t->to_store_registers = vaxbsd_store_inferior_registers;
+ add_target (t);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (vaxbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/vax.
+
+ Copyright (C) 2004-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+
+#include "vax-tdep.h"
+#include "solib-svr4.h"
+
+/* NetBSD ELF. */
+
+static void
+vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_vaxnbsd_tdep (void);
+
+void
+_initialize_vaxnbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD_ELF,
+ vaxnbsd_elf_init_abi);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/vax.
+
+ Copyright (C) 2005-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "osabi.h"
+#include "symtab.h"
+#include "trad-frame.h"
+
+#include "vax-tdep.h"
+
+/* Signal trampolines. */
+
+/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
+ in virtual memory. The randomness makes it somewhat tricky to
+ detect it, but fortunately we can rely on the fact that the start
+ of the sigtramp routine is page-aligned. We recognize the
+ trampoline by looking for the code that invokes the sigreturn
+ system call. The offset where we can find that code varies from
+ release to release.
+
+ By the way, the mapping mentioned above is read-only, so you cannot
+ place a breakpoint in the signal trampoline. */
+
+/* Default page size. */
+static const int vaxobsd_page_size = 4096;
+
+/* Offset for sigreturn(2). */
+static const int vaxobsd_sigreturn_offset = 0x11;
+
+/* Instruction sequence for sigreturn(2). VAX doesn't have
+ fixed-length instructions so we include the ensuing exit(2) to
+ reduce the chance of spurious matches. */
+static const gdb_byte vaxobsd_sigreturn[] = {
+ 0xbc, 0x8f, 0x67, 0x00, /* chmk $SYS_sigreturn */
+ 0xbc, 0x01 /* chmk $SYS_exit */
+};
+
+static int
+vaxobsd_sigtramp_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ CORE_ADDR start_pc = (pc & ~(vaxobsd_page_size - 1));
+ CORE_ADDR sigreturn_addr = start_pc + vaxobsd_sigreturn_offset;
+ gdb_byte *buf;
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (name)
+ return 0;
+
+ buf = (gdb_byte *) alloca (sizeof vaxobsd_sigreturn);
+ if (!safe_frame_unwind_memory (this_frame, sigreturn_addr,
+ buf, sizeof vaxobsd_sigreturn))
+ return 0;
+
+ if (memcmp(buf, vaxobsd_sigreturn, sizeof vaxobsd_sigreturn) == 0)
+ return 1;
+
+ return 0;
+}
+
+static struct trad_frame_cache *
+vaxobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+ struct trad_frame_cache *cache;
+ CORE_ADDR addr, base, func;
+
+ if (*this_cache)
+ return (struct trad_frame_cache *) *this_cache;
+
+ cache = trad_frame_cache_zalloc (this_frame);
+ *this_cache = cache;
+
+ func = get_frame_pc (this_frame);
+ func &= ~(vaxobsd_page_size - 1);
+
+ base = get_frame_register_unsigned (this_frame, VAX_SP_REGNUM);
+ addr = get_frame_memory_unsigned (this_frame, base - 4, 4);
+
+ trad_frame_set_reg_addr (cache, VAX_SP_REGNUM, addr + 8);
+ trad_frame_set_reg_addr (cache, VAX_FP_REGNUM, addr + 12);
+ trad_frame_set_reg_addr (cache, VAX_AP_REGNUM, addr + 16);
+ trad_frame_set_reg_addr (cache, VAX_PC_REGNUM, addr + 20);
+ trad_frame_set_reg_addr (cache, VAX_PS_REGNUM, addr + 24);
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (cache, frame_id_build (base, func));
+
+ return cache;
+}
+
+static void
+vaxobsd_sigtramp_frame_this_id (struct frame_info *this_frame,
+ void **this_cache, struct frame_id *this_id)
+{
+ struct trad_frame_cache *cache =
+ vaxobsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+vaxobsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct trad_frame_cache *cache =
+ vaxobsd_sigtramp_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static const struct frame_unwind vaxobsd_sigtramp_frame_unwind = {
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ vaxobsd_sigtramp_frame_this_id,
+ vaxobsd_sigtramp_frame_prev_register,
+ NULL,
+ vaxobsd_sigtramp_sniffer
+};
+\f
+
+/* OpenBSD a.out. */
+
+static void
+vaxobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ frame_unwind_append_unwinder (gdbarch, &vaxobsd_sigtramp_frame_unwind);
+}
+
+/* FIXME: kettenis/20050821: Since OpenBSD/vax binaries are
+ indistingushable from NetBSD/vax a.out binaries, building a GDB
+ that should support both these targets will probably not work as
+ expected. */
+#define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT
+
+static enum gdb_osabi
+vaxobsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-vax-netbsd") == 0)
+ return GDB_OSABI_OPENBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_vaxobsd_tdep (void);
+
+void
+_initialize_vaxobsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_vax, bfd_target_aout_flavour,
+ vaxobsd_aout_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_OPENBSD_AOUT,
+ vaxobsd_init_abi);
+}
+++ /dev/null
-/* Native-dependent code for modern VAX BSD's.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "vax-tdep.h"
-#include "inf-ptrace.h"
-
-/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
-
-static void
-vaxbsd_supply_gregset (struct regcache *regcache, const void *gregs)
-{
- const gdb_byte *regs = gregs;
- int regnum;
-
- for (regnum = 0; regnum < VAX_NUM_REGS; regnum++)
- regcache_raw_supply (regcache, regnum, regs + regnum * 4);
-}
-
-/* Collect the general-purpose registers from REGCACHE and store them
- in GREGS. */
-
-static void
-vaxbsd_collect_gregset (const struct regcache *regcache,
- void *gregs, int regnum)
-{
- gdb_byte *regs = gregs;
- int i;
-
- for (i = 0; i <= VAX_NUM_REGS; i++)
- {
- if (regnum == -1 || regnum == i)
- regcache_raw_collect (regcache, i, regs + i * 4);
- }
-}
-\f
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers. */
-
-static void
-vaxbsd_fetch_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- vaxbsd_supply_gregset (regcache, ®s);
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers. */
-
-static void
-vaxbsd_store_inferior_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
-{
- struct reg regs;
-
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- vaxbsd_collect_gregset (regcache, ®s, regnum);
-
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-}
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-vaxbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- int regnum;
-
- /* The following is true for OpenBSD 3.5:
-
- The pcb contains the register state at the context switch inside
- cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->KSP == 0)
- return 0;
-
- for (regnum = VAX_R0_REGNUM; regnum < VAX_AP_REGNUM; regnum++)
- regcache_raw_supply (regcache, regnum, &pcb->R[regnum - VAX_R0_REGNUM]);
- regcache_raw_supply (regcache, VAX_AP_REGNUM, &pcb->AP);
- regcache_raw_supply (regcache, VAX_FP_REGNUM, &pcb->FP);
- regcache_raw_supply (regcache, VAX_SP_REGNUM, &pcb->KSP);
- regcache_raw_supply (regcache, VAX_PC_REGNUM, &pcb->PC);
- regcache_raw_supply (regcache, VAX_PS_REGNUM, &pcb->PSL);
-
- return 1;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_vaxbsd_nat (void);
-
-void
-_initialize_vaxbsd_nat (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
- t->to_fetch_registers = vaxbsd_fetch_inferior_registers;
- t->to_store_registers = vaxbsd_store_inferior_registers;
- add_target (t);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (vaxbsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/vax.
-
- Copyright (C) 2004-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "osabi.h"
-
-#include "vax-tdep.h"
-#include "solib-svr4.h"
-
-/* NetBSD ELF. */
-
-static void
-vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- /* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_vaxnbsd_tdep (void);
-
-void
-_initialize_vaxnbsd_tdep (void)
-{
- gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD_ELF,
- vaxnbsd_elf_init_abi);
-}
+++ /dev/null
-/* Target-dependent code for OpenBSD/vax.
-
- Copyright (C) 2005-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "osabi.h"
-#include "symtab.h"
-#include "trad-frame.h"
-
-#include "vax-tdep.h"
-
-/* Signal trampolines. */
-
-/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
- in virtual memory. The randomness makes it somewhat tricky to
- detect it, but fortunately we can rely on the fact that the start
- of the sigtramp routine is page-aligned. We recognize the
- trampoline by looking for the code that invokes the sigreturn
- system call. The offset where we can find that code varies from
- release to release.
-
- By the way, the mapping mentioned above is read-only, so you cannot
- place a breakpoint in the signal trampoline. */
-
-/* Default page size. */
-static const int vaxobsd_page_size = 4096;
-
-/* Offset for sigreturn(2). */
-static const int vaxobsd_sigreturn_offset = 0x11;
-
-/* Instruction sequence for sigreturn(2). VAX doesn't have
- fixed-length instructions so we include the ensuing exit(2) to
- reduce the chance of spurious matches. */
-static const gdb_byte vaxobsd_sigreturn[] = {
- 0xbc, 0x8f, 0x67, 0x00, /* chmk $SYS_sigreturn */
- 0xbc, 0x01 /* chmk $SYS_exit */
-};
-
-static int
-vaxobsd_sigtramp_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- CORE_ADDR start_pc = (pc & ~(vaxobsd_page_size - 1));
- CORE_ADDR sigreturn_addr = start_pc + vaxobsd_sigreturn_offset;
- gdb_byte *buf;
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (name)
- return 0;
-
- buf = (gdb_byte *) alloca (sizeof vaxobsd_sigreturn);
- if (!safe_frame_unwind_memory (this_frame, sigreturn_addr,
- buf, sizeof vaxobsd_sigreturn))
- return 0;
-
- if (memcmp(buf, vaxobsd_sigreturn, sizeof vaxobsd_sigreturn) == 0)
- return 1;
-
- return 0;
-}
-
-static struct trad_frame_cache *
-vaxobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
-{
- struct trad_frame_cache *cache;
- CORE_ADDR addr, base, func;
-
- if (*this_cache)
- return (struct trad_frame_cache *) *this_cache;
-
- cache = trad_frame_cache_zalloc (this_frame);
- *this_cache = cache;
-
- func = get_frame_pc (this_frame);
- func &= ~(vaxobsd_page_size - 1);
-
- base = get_frame_register_unsigned (this_frame, VAX_SP_REGNUM);
- addr = get_frame_memory_unsigned (this_frame, base - 4, 4);
-
- trad_frame_set_reg_addr (cache, VAX_SP_REGNUM, addr + 8);
- trad_frame_set_reg_addr (cache, VAX_FP_REGNUM, addr + 12);
- trad_frame_set_reg_addr (cache, VAX_AP_REGNUM, addr + 16);
- trad_frame_set_reg_addr (cache, VAX_PC_REGNUM, addr + 20);
- trad_frame_set_reg_addr (cache, VAX_PS_REGNUM, addr + 24);
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (cache, frame_id_build (base, func));
-
- return cache;
-}
-
-static void
-vaxobsd_sigtramp_frame_this_id (struct frame_info *this_frame,
- void **this_cache, struct frame_id *this_id)
-{
- struct trad_frame_cache *cache =
- vaxobsd_sigtramp_frame_cache (this_frame, this_cache);
-
- trad_frame_get_id (cache, this_id);
-}
-
-static struct value *
-vaxobsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct trad_frame_cache *cache =
- vaxobsd_sigtramp_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_register (cache, this_frame, regnum);
-}
-
-static const struct frame_unwind vaxobsd_sigtramp_frame_unwind = {
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- vaxobsd_sigtramp_frame_this_id,
- vaxobsd_sigtramp_frame_prev_register,
- NULL,
- vaxobsd_sigtramp_sniffer
-};
-\f
-
-/* OpenBSD a.out. */
-
-static void
-vaxobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- frame_unwind_append_unwinder (gdbarch, &vaxobsd_sigtramp_frame_unwind);
-}
-
-/* FIXME: kettenis/20050821: Since OpenBSD/vax binaries are
- indistingushable from NetBSD/vax a.out binaries, building a GDB
- that should support both these targets will probably not work as
- expected. */
-#define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT
-
-static enum gdb_osabi
-vaxobsd_aout_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "a.out-vax-netbsd") == 0)
- return GDB_OSABI_OPENBSD_AOUT;
-
- return GDB_OSABI_UNKNOWN;
-}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_vaxobsd_tdep (void);
-
-void
-_initialize_vaxobsd_tdep (void)
-{
- gdbarch_register_osabi_sniffer (bfd_arch_vax, bfd_target_aout_flavour,
- vaxobsd_aout_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_OPENBSD_AOUT,
- vaxobsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for X86 BSD's.
+
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "gdbthread.h"
+
+/* We include <signal.h> to make sure `struct fxsave64' is defined on
+ NetBSD, since NetBSD's <machine/reg.h> needs it. */
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "x86-nat.h"
+#include "x86-bsd-nat.h"
+#include "inf-ptrace.h"
+\f
+
+#ifdef PT_GETXSTATE_INFO
+size_t x86bsd_xsave_len;
+#endif
+
+/* Support for debug registers. */
+
+#ifdef HAVE_PT_GETDBREGS
+static void (*super_mourn_inferior) (struct target_ops *ops);
+
+/* Implement the "to_mourn_inferior" target_ops method. */
+
+static void
+x86bsd_mourn_inferior (struct target_ops *ops)
+{
+ x86_cleanup_dregs ();
+ super_mourn_inferior (ops);
+}
+
+/* Not all versions of FreeBSD/i386 that support the debug registers
+ have this macro. */
+#ifndef DBREG_DRX
+#define DBREG_DRX(d, x) ((&d->dr0)[x])
+#endif
+
+static unsigned long
+x86bsd_dr_get (ptid_t ptid, int regnum)
+{
+ struct dbreg dbregs;
+
+ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
+ perror_with_name (_("Couldn't read debug registers"));
+
+ return DBREG_DRX ((&dbregs), regnum);
+}
+
+static void
+x86bsd_dr_set (int regnum, unsigned long value)
+{
+ struct thread_info *thread;
+ struct dbreg dbregs;
+
+ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
+ perror_with_name (_("Couldn't get debug registers"));
+
+ /* For some mysterious reason, some of the reserved bits in the
+ debug control register get set. Mask these off, otherwise the
+ ptrace call below will fail. */
+ DBREG_DRX ((&dbregs), 7) &= ~(0xffffffff0000fc00);
+
+ DBREG_DRX ((&dbregs), regnum) = value;
+
+ ALL_NON_EXITED_THREADS (thread)
+ if (thread->inf == current_inferior ())
+ {
+ if (ptrace (PT_SETDBREGS, get_ptrace_pid (thread->ptid),
+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
+ perror_with_name (_("Couldn't write debug registers"));
+ }
+}
+
+static void
+x86bsd_dr_set_control (unsigned long control)
+{
+ x86bsd_dr_set (7, control);
+}
+
+static void
+x86bsd_dr_set_addr (int regnum, CORE_ADDR addr)
+{
+ gdb_assert (regnum >= 0 && regnum <= 4);
+
+ x86bsd_dr_set (regnum, addr);
+}
+
+static CORE_ADDR
+x86bsd_dr_get_addr (int regnum)
+{
+ return x86bsd_dr_get (inferior_ptid, regnum);
+}
+
+static unsigned long
+x86bsd_dr_get_status (void)
+{
+ return x86bsd_dr_get (inferior_ptid, 6);
+}
+
+static unsigned long
+x86bsd_dr_get_control (void)
+{
+ return x86bsd_dr_get (inferior_ptid, 7);
+}
+
+#endif /* PT_GETDBREGS */
+
+/* Create a prototype *BSD/x86 target. The client can override it
+ with local methods. */
+
+struct target_ops *
+x86bsd_target (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+
+#ifdef HAVE_PT_GETDBREGS
+ x86_use_watchpoints (t);
+
+ x86_dr_low.set_control = x86bsd_dr_set_control;
+ x86_dr_low.set_addr = x86bsd_dr_set_addr;
+ x86_dr_low.get_addr = x86bsd_dr_get_addr;
+ x86_dr_low.get_status = x86bsd_dr_get_status;
+ x86_dr_low.get_control = x86bsd_dr_get_control;
+ x86_set_debug_register_length (sizeof (void *));
+ super_mourn_inferior = t->to_mourn_inferior;
+ t->to_mourn_inferior = x86bsd_mourn_inferior;
+#endif /* HAVE_PT_GETDBREGS */
+
+ return t;
+}
--- /dev/null
+/* Native-dependent code for x86 BSD's.
+
+ Copyright (C) 2011-2016 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef X86_BSD_NAT_H
+#define X86_BSD_NAT_H
+
+/* Low level x86 XSAVE info. */
+extern size_t x86bsd_xsave_len;
+
+/* Create a prototype *BSD/x86 target. The client can override it
+ with local methods. */
+
+extern struct target_ops *x86bsd_target (void);
+
+#endif /* x86-bsd-nat.h */
+++ /dev/null
-/* Native-dependent code for X86 BSD's.
-
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "gdbthread.h"
-
-/* We include <signal.h> to make sure `struct fxsave64' is defined on
- NetBSD, since NetBSD's <machine/reg.h> needs it. */
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "x86-nat.h"
-#include "x86bsd-nat.h"
-#include "inf-ptrace.h"
-\f
-
-#ifdef PT_GETXSTATE_INFO
-size_t x86bsd_xsave_len;
-#endif
-
-/* Support for debug registers. */
-
-#ifdef HAVE_PT_GETDBREGS
-static void (*super_mourn_inferior) (struct target_ops *ops);
-
-/* Implement the "to_mourn_inferior" target_ops method. */
-
-static void
-x86bsd_mourn_inferior (struct target_ops *ops)
-{
- x86_cleanup_dregs ();
- super_mourn_inferior (ops);
-}
-
-/* Not all versions of FreeBSD/i386 that support the debug registers
- have this macro. */
-#ifndef DBREG_DRX
-#define DBREG_DRX(d, x) ((&d->dr0)[x])
-#endif
-
-static unsigned long
-x86bsd_dr_get (ptid_t ptid, int regnum)
-{
- struct dbreg dbregs;
-
- if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
- perror_with_name (_("Couldn't read debug registers"));
-
- return DBREG_DRX ((&dbregs), regnum);
-}
-
-static void
-x86bsd_dr_set (int regnum, unsigned long value)
-{
- struct thread_info *thread;
- struct dbreg dbregs;
-
- if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
- (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
- perror_with_name (_("Couldn't get debug registers"));
-
- /* For some mysterious reason, some of the reserved bits in the
- debug control register get set. Mask these off, otherwise the
- ptrace call below will fail. */
- DBREG_DRX ((&dbregs), 7) &= ~(0xffffffff0000fc00);
-
- DBREG_DRX ((&dbregs), regnum) = value;
-
- ALL_NON_EXITED_THREADS (thread)
- if (thread->inf == current_inferior ())
- {
- if (ptrace (PT_SETDBREGS, get_ptrace_pid (thread->ptid),
- (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
- perror_with_name (_("Couldn't write debug registers"));
- }
-}
-
-static void
-x86bsd_dr_set_control (unsigned long control)
-{
- x86bsd_dr_set (7, control);
-}
-
-static void
-x86bsd_dr_set_addr (int regnum, CORE_ADDR addr)
-{
- gdb_assert (regnum >= 0 && regnum <= 4);
-
- x86bsd_dr_set (regnum, addr);
-}
-
-static CORE_ADDR
-x86bsd_dr_get_addr (int regnum)
-{
- return x86bsd_dr_get (inferior_ptid, regnum);
-}
-
-static unsigned long
-x86bsd_dr_get_status (void)
-{
- return x86bsd_dr_get (inferior_ptid, 6);
-}
-
-static unsigned long
-x86bsd_dr_get_control (void)
-{
- return x86bsd_dr_get (inferior_ptid, 7);
-}
-
-#endif /* PT_GETDBREGS */
-
-/* Create a prototype *BSD/x86 target. The client can override it
- with local methods. */
-
-struct target_ops *
-x86bsd_target (void)
-{
- struct target_ops *t;
-
- t = inf_ptrace_target ();
-
-#ifdef HAVE_PT_GETDBREGS
- x86_use_watchpoints (t);
-
- x86_dr_low.set_control = x86bsd_dr_set_control;
- x86_dr_low.set_addr = x86bsd_dr_set_addr;
- x86_dr_low.get_addr = x86bsd_dr_get_addr;
- x86_dr_low.get_status = x86bsd_dr_get_status;
- x86_dr_low.get_control = x86bsd_dr_get_control;
- x86_set_debug_register_length (sizeof (void *));
- super_mourn_inferior = t->to_mourn_inferior;
- t->to_mourn_inferior = x86bsd_mourn_inferior;
-#endif /* HAVE_PT_GETDBREGS */
-
- return t;
-}
+++ /dev/null
-/* Native-dependent code for x86 BSD's.
-
- Copyright (C) 2011-2016 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef X86BSD_NAT_H
-#define X86BSD_NAT_H
-
-/* Low level x86 XSAVE info. */
-extern size_t x86bsd_xsave_len;
-
-/* Create a prototype *BSD/x86 target. The client can override it
- with local methods. */
-
-extern struct target_ops *x86bsd_target (void);
-
-#endif /* x86bsd-nat.h */