@@ -348,9 +348,6 @@ the native maintainer when resolving ABI issues.
i386 --target=i386-elf
Felix Willgerodt felix.willgerodt@intel.com
- ia64 --target=ia64-linux-gnu
- (--target=ia64-elf broken)
-
lm32 --target=lm32-elf
loongarch --target=loongarch32-elf
@@ -517,12 +514,10 @@ to do so!
ARM Richard Earnshaw rearnsha@arm.com
Blackfin Mike Frysinger vapier@gentoo.org
CRIS Hans-Peter Nilsson hp@axis.com
-IA64 Jeff Johnston jjohnstn@redhat.com
PowerPC Kevin Buettner kevinb@redhat.com
S390 Ulrich Weigand uweigand@de.ibm.com
djgpp DJ Delorie dj@delorie.com
[Please use this address to contact DJ about DJGPP]
-ia64 Kevin Buettner kevinb@redhat.com
AIX Kevin Buettner kevinb@redhat.com
GNU/Linux PPC native Kevin Buettner kevinb@redhat.com
Pascal support Pierre Muller muller@sourceware.org
@@ -751,9 +751,6 @@ ALL_64_TARGET_OBS = \
arch/amd64.o \
arch/riscv.o \
bpf-tdep.o \
- ia64-linux-tdep.o \
- ia64-tdep.o \
- ia64-vms-tdep.o \
loongarch-linux-tdep.o \
loongarch-tdep.o \
mips-fbsd-tdep.o \
@@ -1401,8 +1398,6 @@ HFILES_NO_SRCDIR = \
i386-linux-tdep.h \
i386-tdep.h \
i387-tdep.h \
- ia64-libunwind-tdep.h \
- ia64-tdep.h \
inf-child.h \
inf-loop.h \
inf-ptrace.h \
@@ -1756,11 +1751,6 @@ ALLDEPFILES = \
i386-tdep.c \
i386-windows-tdep.c \
i387-tdep.c \
- ia64-libunwind-tdep.c \
- ia64-linux-nat.c \
- ia64-linux-tdep.c \
- ia64-tdep.c \
- ia64-vms-tdep.c \
inf-ptrace.c \
linux-fork.c \
linux-record.c \
@@ -16,6 +16,8 @@
the background, resulting in faster startup. This can be controlled
using "maint set dwarf synchronous".
+* Remove Itanium (IA-64) architecture.
+
* Changed commands
disassemble
@@ -441,11 +441,6 @@ more obscure GDB `configure' options are not listed here.
with version 0.178. You can get the latest version from
'https://sourceware.org/elfutils/'.
-`--with-libunwind-ia64'
- Use the libunwind library for unwinding function call stack on ia64
- target platforms.
- See http://www.nongnu.org/libunwind/index.html for details.
-
`--with-system-readline'
Use the readline library installed on the host, rather than the
library supplied as part of GDB. Readline 7 or newer is required;
@@ -280,9 +280,6 @@
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
-/* Define to 1 if you have the <libunwind-ia64.h> header file. */
-#undef HAVE_LIBUNWIND_IA64_H
-
/* Define if you have the xxhash library. */
#undef HAVE_LIBXXHASH
@@ -17,16 +17,9 @@
@V@/bfd/coff-tic80.c @V@/bfd/cofftic80.c
@V@/bfd/cpu-cr16.c @V@/bfd/cpucr16.c
@V@/bfd/cpu-cr16c.c @V@/bfd/cpucr16c.c
-@V@/bfd/cpu-ia64-opc.c @V@/bfd/cpuia64-opc.c
@V@/bfd/cpu-microblaze.c @V@/bfd/cpumb.c
@V@/bfd/cpu-m68hc11.c @V@/bfd/cm68hc11.c
@V@/bfd/cpu-m68hc12.c @V@/bfd/cm68hc12.c
-@V@/bfd/efi-app-ia32.c @V@/bfd/efiia32app.c
-@V@/bfd/efi-app-ia64.c @V@/bfd/efiia64app.c
-@V@/bfd/efi-bsdrv-ia32.c @V@/bfd/efiia32bsdrv.c
-@V@/bfd/efi-bsdrv-ia64.c @V@/bfd/efiia64bsdrv.c
-@V@/bfd/efi-rtdrv-ia32.c @V@/bfd/efiia32rtdrv.c
-@V@/bfd/efi-rtdrv-ia64.c @V@/bfd/efiia64rtdrv.c
@V@/bfd/elf32-arc.c @V@/bfd/elf32arc.c
@V@/bfd/elf32-crx.c @V@/bfd/elf32crx.c
@V@/bfd/elf32-cris.c @V@/bfd/elf32cris.c
@@ -297,10 +290,6 @@
@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/ia64-aix-tdep.c @V@/gdb/ia64ax-tdep.c
-@V@/gdb/ia64-linux-nat.c @V@/gdb/ia64lx-nat.c
-@V@/gdb/ia64-linux-tdep.c @V@/gdb/ia64lx-tdep.c
@V@/gdb/jv-exp.tab.c @V@/gdb/jv-exp_tab.c
@V@/gdb/m2-exp.tab.c @V@/gdb/m2-exp_tab.c
@V@/gdb/m32r-linux-nat.c @V@/gdb/m32rlnxnat.c
@@ -551,14 +540,6 @@
@V@/opcodes/ChangeLog-2006 @V@/opcodes/ChangeLog.006
@V@/opcodes/ChangeLog-2007 @V@/opcodes/ChangeLog.007
@V@/opcodes/ChangeLog-2008 @V@/opcodes/ChangeLog.008
-@V@/opcodes/ia64-opc-a.c @V@/opcodes/ia64opca.c
-@V@/opcodes/ia64-opc-b.c @V@/opcodes/ia64opcb.c
-@V@/opcodes/ia64-opc-d.c @V@/opcodes/ia64opcd.c
-@V@/opcodes/ia64-opc-f.c @V@/opcodes/ia64opcf.c
-@V@/opcodes/ia64-opc-i.c @V@/opcodes/ia64opci.c
-@V@/opcodes/ia64-opc-m.c @V@/opcodes/ia64opcm.c
-@V@/opcodes/ia64-opc-x.c @V@/opcodes/ia64opcx.c
-@V@/opcodes/ia64-opc.c @V@/opcodes/ia64-opc.c
@V@/opcodes/iq2000-desc.c @V@/opcodes/iq2000desc.c
@V@/opcodes/iq2000-dis.c @V@/opcodes/iq2000dis.c
@V@/opcodes/microblaze-opc.h @V@/opcodes/mb-opc.h
@@ -938,7 +938,6 @@ with_amd_dbgapi
enable_tui
enable_gdbtk
with_debuginfod
-with_libunwind_ia64
with_curses
enable_profiling
enable_codesign
@@ -1706,7 +1705,6 @@ Optional Packages:
--with-amd-dbgapi support for the amd-dbgapi target (yes / no / auto)
--with-debuginfod Enable debuginfo lookups with debuginfod
(auto/yes/no)
- --with-libunwind-ia64 use libunwind frame unwinding for ia64 targets
--with-curses use the curses library instead of the termcap
library
--with-pkgversion=PKG Use PKG in the version string in place of "GDB"
@@ -6341,10 +6339,6 @@ haiku*)
hpux10.20* | hpux11*)
lt_cv_file_magic_cmd=/usr/bin/file
case $host_cpu in
- ia64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
- lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
- ;;
hppa*64*)
lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
@@ -6945,11 +6939,6 @@ aix*)
cygwin* | mingw* | pw32* | cegcc*)
symcode='[ABCDGISTW]'
;;
-hpux*)
- if test "$host_cpu" = ia64; then
- symcode='[ABCDEGRST]'
- fi
- ;;
irix* | nonstopux*)
symcode='[BCDEGRST]'
;;
@@ -6980,7 +6969,7 @@ case `$NM -V 2>&1` in
esac
# Transform an extracted symbol line into a proper C declaration.
-# Some systems (esp. on ia64) link data and code symbols differently,
+# Some systems link data and code symbols differently,
# so use this general approach.
lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
@@ -7180,25 +7169,6 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case $host in
-ia64-*-hpux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.$ac_objext` in
- *ELF-32*)
- HPUX_IA64_MODE="32"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line '$LINENO' "configure"' > conftest.$ac_ext
@@ -8534,10 +8504,6 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
case $host_os in
aix*)
# All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- fi
lt_prog_compiler_pic='-fPIC'
;;
@@ -8634,12 +8600,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
case $host_os in
aix*)
lt_prog_compiler_wl='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- else
- lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
- fi
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
;;
mingw* | cygwin* | pw32* | os2* | cegcc*)
@@ -8653,7 +8614,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
case $host_cpu in
- hppa*64*|ia64*)
+ hppa*64*)
# +Z the default
;;
*)
@@ -9178,7 +9139,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
case $host_os in
aix[3-9]*)
# On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
ld_shlibs=no
cat <<_LT_EOF 1>&2
@@ -9190,7 +9150,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
*** You will then need to restart the configuration process.
_LT_EOF
- fi
;;
amigaos*)
@@ -9286,10 +9245,6 @@ _LT_EOF
# Portland Group f77 and f90 compilers
whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
ifc* | ifort*) # Intel Fortran compiler
tmp_addflag=' -nofor_main' ;;
lf95*) # Lahey Fortran 8.1
@@ -9443,13 +9398,6 @@ _LT_EOF
;;
aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
# If we're using GNU nm, then we don't want the "-C" option.
# -C means demangle to AIX nm, but means don't demangle with GNU nm
# Also, AIX nm treats weak defined symbols like other global
@@ -9476,7 +9424,6 @@ _LT_EOF
exp_sym_flag='-bexport'
no_entry_flag='-bnoentry'
- fi
# When large executables or shared objects are built, AIX ld can
# have problems creating the table of contents. If linking a library
@@ -9519,17 +9466,11 @@ _LT_EOF
fi
else
# not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
if test "$aix_use_runtimelinking" = yes; then
shared_flag='${wl}-G'
else
shared_flag='${wl}-bM:SRE'
fi
- fi
fi
export_dynamic_flag_spec='${wl}-bexpall'
@@ -9575,11 +9516,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag="-z nodefs"
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
# Determine the default libpath from the value encoded in an
# empty executable.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -9627,7 +9563,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
archive_cmds_need_lc=yes
# This is similar to how AIX traditionally builds its shared libraries.
archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
fi
;;
@@ -9776,9 +9711,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hppa*64*)
archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
- ia64*)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
@@ -9788,9 +9720,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hppa*64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
- ia64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
*)
# Older versions of the 11.00 compiler do not understand -b yet
@@ -9840,7 +9769,7 @@ fi
hardcode_libdir_separator=:
case $host_cpu in
- hppa*64*|ia64*)
+ hppa*64*)
hardcode_direct=no
hardcode_shlibpath_var=no
;;
@@ -10477,11 +10406,6 @@ aix[4-9]*)
need_lib_prefix=no
need_version=no
hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
# With GCC up to 2.95.x, collect2 would create an import file
# for dependence libraries. The import file would start with
# the line `#! .'. This would cause the generated library to
@@ -10513,7 +10437,6 @@ aix[4-9]*)
soname_spec='${libname}${release}${shared_ext}$major'
fi
shlibpath_var=LIBPATH
- fi
;;
amigaos*)
@@ -10690,21 +10613,6 @@ hpux9* | hpux10* | hpux11*)
need_lib_prefix=no
need_version=no
case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
hppa*64*)
shrext_cmds='.sl'
hardcode_into_libs=yes
@@ -11795,7 +11703,7 @@ $as_echo_n "checking whether to build shared libraries... " >&6; }
;;
aix[4-9]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ if test "$aix_use_runtimelinking" = no ; then
test "$enable_shared" = yes && enable_static=no
fi
;;
@@ -12251,13 +12159,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
ld_shlibs_CXX=no
;;
aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
@@ -12277,7 +12178,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
exp_sym_flag='-bexport'
no_entry_flag='-bnoentry'
- fi
# When large executables or shared objects are built, AIX ld can
# have problems creating the table of contents. If linking a library
@@ -12319,17 +12219,11 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
fi
else
# not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
if test "$aix_use_runtimelinking" = yes; then
shared_flag='${wl}-G'
else
shared_flag='${wl}-bM:SRE'
fi
- fi
fi
export_dynamic_flag_spec_CXX='${wl}-bexpall'
@@ -12377,11 +12271,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag_CXX="-z nodefs"
- archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
# Determine the default libpath from the value encoded in an
# empty executable.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -12430,7 +12319,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# This is similar to how AIX traditionally builds its shared
# libraries.
archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
fi
;;
@@ -12598,7 +12486,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_separator_CXX=:
case $host_cpu in
- hppa*64*|ia64*)
+ hppa*64*)
;;
*)
export_dynamic_flag_spec_CXX='${wl}-E'
@@ -12606,7 +12494,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
esac
fi
case $host_cpu in
- hppa*64*|ia64*)
+ hppa*64*)
hardcode_direct_CXX=no
hardcode_shlibpath_var_CXX=no
;;
@@ -12629,9 +12517,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hppa*64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
- ia64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
@@ -12653,9 +12538,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hppa*64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
- ia64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
@@ -12751,9 +12633,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
*) # Version 8.0 or newer
tmp_idyn=
- case $host_cpu in
- ia64*) tmp_idyn=' -i_dynamic';;
- esac
archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
;;
@@ -13399,10 +13278,6 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
case $host_os in
aix*)
# All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_CXX='-Bstatic'
- fi
lt_prog_compiler_pic_CXX='-fPIC'
;;
@@ -13479,12 +13354,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
case $host_os in
aix[4-9]*)
# All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_CXX='-Bstatic'
- else
- lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
- fi
+ lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
;;
chorus*)
case $cc_basename in
@@ -13515,15 +13385,13 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
CC*)
lt_prog_compiler_wl_CXX='-Wl,'
lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
- if test "$host_cpu" != ia64; then
- lt_prog_compiler_pic_CXX='+Z'
- fi
+ lt_prog_compiler_pic_CXX='+Z'
;;
aCC*)
lt_prog_compiler_wl_CXX='-Wl,'
lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
case $host_cpu in
- hppa*64*|ia64*)
+ hppa*64*)
# +Z the default
;;
*)
@@ -14154,11 +14022,6 @@ aix[4-9]*)
need_lib_prefix=no
need_version=no
hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
# With GCC up to 2.95.x, collect2 would create an import file
# for dependence libraries. The import file would start with
# the line `#! .'. This would cause the generated library to
@@ -14190,7 +14053,6 @@ aix[4-9]*)
soname_spec='${libname}${release}${shared_ext}$major'
fi
shlibpath_var=LIBPATH
- fi
;;
amigaos*)
@@ -14365,21 +14227,6 @@ hpux9* | hpux10* | hpux11*)
need_lib_prefix=no
need_version=no
case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
hppa*64*)
shrext_cmds='.sl'
hardcode_into_libs=yes
@@ -25411,71 +25258,6 @@ else
$as_echo "$as_me: WARNING: debuginfod support disabled; some features may be unavailable." >&2;}
fi
-
-# Libunwind support for ia64.
-
-# Check whether --with-libunwind-ia64 was given.
-if test "${with_libunwind_ia64+set}" = set; then :
- withval=$with_libunwind_ia64;
-else
- with_libunwind_ia64=auto
-fi
-
-
-# Backward compatibility option.
-if test "${with_libunwind+set}" = set; then
- if test x"$with_libunwind_ia64" != xauto; then
- as_fn_error $? "option --with-libunwind is deprecated, use --with-libunwind-ia64" "$LINENO" 5
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: option --with-libunwind is deprecated, use --with-libunwind-ia64" >&5
-$as_echo "$as_me: WARNING: option --with-libunwind is deprecated, use --with-libunwind-ia64" >&2;}
- with_libunwind_ia64="$with_libunwind"
-fi
-
-case "$with_libunwind_ia64" in
- yes | no)
- ;;
- auto)
- for ac_header in libunwind-ia64.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "libunwind-ia64.h" "ac_cv_header_libunwind_ia64_h" "$ac_includes_default"
-if test "x$ac_cv_header_libunwind_ia64_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBUNWIND_IA64_H 1
-_ACEOF
-
-fi
-
-done
-
- with_libunwind_ia64=$ac_cv_header_libunwind_ia64_h
- ;;
- *)
- as_fn_error $? "bad value $with_libunwind_ia64 for GDB --with-libunwind-ia64 option" "$LINENO" 5
- ;;
-esac
-
-if test x"$with_libunwind_ia64" = xyes; then
- for ac_header in libunwind-ia64.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "libunwind-ia64.h" "ac_cv_header_libunwind_ia64_h" "$ac_includes_default"
-if test "x$ac_cv_header_libunwind_ia64_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBUNWIND_IA64_H 1
-_ACEOF
-
-fi
-
-done
-
- if test x"$ac_cv_header_libunwind_ia64_h" != xyes; then
- as_fn_error $? "GDB option --with-libunwind-ia64 requires libunwind-ia64.h" "$LINENO" 5
- fi
- CONFIG_OBS="$CONFIG_OBS ia64-libunwind-tdep.o"
- CONFIG_DEPS="$CONFIG_DEPS ia64-libunwind-tdep.o"
- CONFIG_SRCS="$CONFIG_SRCS ia64-libunwind-tdep.c"
-fi
-
opt_curses=no
# Check whether --with-curses was given.
@@ -354,45 +354,6 @@ esac
# Handle optional debuginfod support
AC_DEBUGINFOD
-# Libunwind support for ia64.
-AC_ARG_WITH(libunwind-ia64,
-AS_HELP_STRING([--with-libunwind-ia64],
- [use libunwind frame unwinding for ia64 targets]),,
- [with_libunwind_ia64=auto])
-
-# Backward compatibility option.
-if test "${with_libunwind+set}" = set; then
- if test x"$with_libunwind_ia64" != xauto; then
- AC_MSG_ERROR(
- [option --with-libunwind is deprecated, use --with-libunwind-ia64])
- fi
- AC_MSG_WARN([option --with-libunwind is deprecated, use --with-libunwind-ia64])
- with_libunwind_ia64="$with_libunwind"
-fi
-
-case "$with_libunwind_ia64" in
- yes | no)
- ;;
- auto)
- AC_CHECK_HEADERS(libunwind-ia64.h)
- with_libunwind_ia64=$ac_cv_header_libunwind_ia64_h
- ;;
- *)
- AC_MSG_ERROR(
- [bad value $with_libunwind_ia64 for GDB --with-libunwind-ia64 option])
- ;;
-esac
-
-if test x"$with_libunwind_ia64" = xyes; then
- AC_CHECK_HEADERS(libunwind-ia64.h)
- if test x"$ac_cv_header_libunwind_ia64_h" != xyes; then
- AC_MSG_ERROR([GDB option --with-libunwind-ia64 requires libunwind-ia64.h])
- fi
- CONFIG_OBS="$CONFIG_OBS ia64-libunwind-tdep.o"
- CONFIG_DEPS="$CONFIG_DEPS ia64-libunwind-tdep.o"
- CONFIG_SRCS="$CONFIG_SRCS ia64-libunwind-tdep.c"
-fi
-
opt_curses=no
AC_ARG_WITH(curses, AS_HELP_STRING([--with-curses], [use the curses library instead of the termcap library]), opt_curses=$withval)
@@ -42,7 +42,6 @@ case $host in
vax-*-netbsdaout* | \
vax-*-ultrix* | \
hppa*-*-hpux* | \
- ia64-*-hpux* | \
null)
echo "*** Configuration $host is obsolete." >&2
echo "*** Support has been REMOVED." >&2
@@ -116,8 +115,6 @@ i[34567]86-*-solaris2* | x86_64-*-solaris2*)
gdb_host=sol2 ;;
i[34567]86-*-cygwin*) gdb_host=cygwin ;;
-ia64-*-linux*) gdb_host=linux ;;
-
loongarch*-linux*) gdb_host=linux ;;
m68*-*-linux*) gdb_host=linux ;;
@@ -258,10 +258,6 @@ case ${gdb_host} in
i386-linux-nat.o x86-linux-nat.o nat/linux-btrace.o \
nat/x86-linux.o nat/x86-linux-dregs.o"
;;
- ia64)
- # Host: Intel IA-64 running GNU/Linux
- NATDEPFILES="${NATDEPFILES} ia64-linux-nat.o"
- ;;
loongarch)
# Host: LoongArch, running GNU/Linux.
NATDEPFILES="${NATDEPFILES} loongarch-linux-nat.o linux-nat-trad.o"
@@ -36,7 +36,6 @@ case $targ in
score-*-* | \
sh*-*-pe | \
hppa*-*-hpux* | \
- ia64-*-hpux* | \
*-*-vxworks* | \
mt-*-* | \
null)
@@ -94,11 +93,6 @@ ia16*-*-*)
cpu_obs="${i386_tobjs}"
;;
-ia64*-*-*)
- # Target: Intel IA-64
- cpu_obs="ia64-tdep.o"
- ;;
-
loongarch*-*-*)
# Target: LoongArch baremetal
cpu_obs="loongarch-tdep.o arch/loongarch.o"
@@ -343,16 +337,6 @@ i[34567]86-*-go32* | i[34567]86-*-msdosdjgpp*)
gdb_target_obs="i386-go32-tdep.o"
;;
-ia64-*-linux*)
- # Target: Intel IA-64 running GNU/Linux
- gdb_target_obs="ia64-linux-tdep.o linux-tdep.o \
- solib-svr4.o symfile-mem.o"
- ;;
-ia64-*-*vms*)
- # Target: Intel IA-64 running OpenVMS
- gdb_target_obs="ia64-vms-tdep.o"
- ;;
-
iq2000-*-*)
gdb_target_obs="iq2000-tdep.o"
;;
@@ -54,11 +54,6 @@ get_test_insn (struct gdbarch *gdbarch, size_t *len)
insn = arm_insn;
*len = sizeof (arm_insn);
break;
- case bfd_arch_ia64:
- /* We get:
- internal-error: gdbarch_sw_breakpoint_from_kind:
- Assertion `gdbarch->sw_breakpoint_from_kind != NULL' failed. */
- return insn;
case bfd_arch_mep:
/* Disassembles as '*unknown*' insn, then len self-check fails. */
return insn;
@@ -41183,11 +41183,6 @@ files. Enabled by default if @file{libdebuginfod} is installed and found
at configure time. For more information regarding @code{debuginfod} see
@ref{Debuginfod}.
-@item --with-libunwind-ia64
-Use the libunwind library for unwinding function call stack on ia64
-target platforms. See @url{http://www.nongnu.org/libunwind/index.html} for
-details.
-
@item --with-system-readline
Use the readline library installed on the host, rather than the
library supplied as part of @value{GDBN}. Readline 7 or newer is
@@ -45450,7 +45445,7 @@ by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}).
@anchor{qXfer unwind info block}
Return the unwind information block for @var{pc}. This packet is used
-on OpenVMS/ia64 to ask the kernel unwind information.
+on OpenVMS to ask the kernel unwind information.
This packet is not probed by default.
@@ -2152,7 +2152,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
if (got)
unit->dbase = got->vma;
- /* GCC emits the DW_EH_PE_textrel encoding type on sh and ia64
+ /* GCC emits the DW_EH_PE_textrel encoding type on sh
so far. */
txt = bfd_get_section_by_name (unit->abfd, ".text");
if (txt)
@@ -110,10 +110,6 @@ const struct floatformat *floatformats_arm_ext[BFD_ENDIAN_UNKNOWN] = {
&floatformat_arm_ext_big,
&floatformat_arm_ext_littlebyte_bigword
};
-const struct floatformat *floatformats_ia64_spill[BFD_ENDIAN_UNKNOWN] = {
- &floatformat_ia64_spill_big,
- &floatformat_ia64_spill_little
-};
const struct floatformat *floatformats_vax_f[BFD_ENDIAN_UNKNOWN] = {
&floatformat_vax_f,
&floatformat_vax_f
@@ -2198,7 +2198,6 @@ extern const struct floatformat *floatformats_ieee_double_littlebyte_bigword[BFD
extern const struct floatformat *floatformats_i387_ext[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_m68881_ext[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_arm_ext[BFD_ENDIAN_UNKNOWN];
-extern const struct floatformat *floatformats_ia64_spill[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_vax_f[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_vax_d[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN];
deleted file mode 100644
@@ -1,582 +0,0 @@
-/* Frame unwinder for ia64 frames using the libunwind library.
-
- Copyright (C) 2003-2024 Free Software Foundation, Inc.
-
- Written by Jeff Johnston, contributed by Red Hat 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 "inferior.h"
-#include "frame.h"
-#include "frame-base.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "gdbtypes.h"
-#include "symtab.h"
-#include "objfiles.h"
-#include "regcache.h"
-
-#include <dlfcn.h>
-
-#include "ia64-libunwind-tdep.h"
-
-#include "gdbsupport/preprocessor.h"
-
-/* IA-64 is the only target that currently uses ia64-libunwind-tdep.
- Note how UNW_TARGET, UNW_OBJ, etc. are compile time constants below.
- Those come from libunwind's headers, and are target dependent.
- Also, some of libunwind's typedefs are target dependent, as e.g.,
- unw_word_t. If some other target wants to use this, we will need
- to do some abstracting in order to make it possible to select which
- libunwind we're talking to at runtime (and have one per arch). */
-
-/* The following two macros are normally defined in <endian.h>.
- But systems such as ia64-hpux do not provide such header, so
- we just define them here if not already defined. */
-#ifndef __LITTLE_ENDIAN
-#define __LITTLE_ENDIAN 1234
-#endif
-#ifndef __BIG_ENDIAN
-#define __BIG_ENDIAN 4321
-#endif
-
-static int libunwind_initialized;
-static const registry<gdbarch>::key<libunwind_descr> libunwind_descr_handle;
-
-/* Required function pointers from libunwind. */
-typedef int (unw_get_reg_p_ftype) (unw_cursor_t *, unw_regnum_t, unw_word_t *);
-static unw_get_reg_p_ftype *unw_get_reg_p;
-typedef int (unw_get_fpreg_p_ftype) (unw_cursor_t *, unw_regnum_t,
- unw_fpreg_t *);
-static unw_get_fpreg_p_ftype *unw_get_fpreg_p;
-typedef int (unw_get_saveloc_p_ftype) (unw_cursor_t *, unw_regnum_t,
- unw_save_loc_t *);
-static unw_get_saveloc_p_ftype *unw_get_saveloc_p;
-typedef int (unw_is_signal_frame_p_ftype) (unw_cursor_t *);
-static unw_is_signal_frame_p_ftype *unw_is_signal_frame_p;
-typedef int (unw_step_p_ftype) (unw_cursor_t *);
-static unw_step_p_ftype *unw_step_p;
-typedef int (unw_init_remote_p_ftype) (unw_cursor_t *, unw_addr_space_t,
- void *);
-static unw_init_remote_p_ftype *unw_init_remote_p;
-typedef unw_addr_space_t (unw_create_addr_space_p_ftype) (unw_accessors_t *,
- int);
-static unw_create_addr_space_p_ftype *unw_create_addr_space_p;
-typedef void (unw_destroy_addr_space_p_ftype) (unw_addr_space_t);
-static unw_destroy_addr_space_p_ftype *unw_destroy_addr_space_p;
-typedef int (unw_search_unwind_table_p_ftype) (unw_addr_space_t, unw_word_t,
- unw_dyn_info_t *,
- unw_proc_info_t *, int, void *);
-static unw_search_unwind_table_p_ftype *unw_search_unwind_table_p;
-typedef unw_word_t (unw_find_dyn_list_p_ftype) (unw_addr_space_t,
- unw_dyn_info_t *, void *);
-static unw_find_dyn_list_p_ftype *unw_find_dyn_list_p;
-
-
-struct libunwind_frame_cache
-{
- CORE_ADDR base;
- CORE_ADDR func_addr;
- unw_cursor_t cursor;
- unw_addr_space_t as;
-};
-
-/* We need to qualify the function names with a platform-specific prefix
- to match the names used by the libunwind library. The UNW_OBJ macro is
- provided by the libunwind.h header file. */
-
-#ifndef LIBUNWIND_SO
-/* Use the stable ABI major version number. `libunwind-ia64.so' is a link time
- only library, not a runtime one. */
-#define LIBUNWIND_SO "libunwind-" STRINGIFY(UNW_TARGET) ".so.8"
-
-/* Provide also compatibility with older .so. The two APIs are compatible, .8
- is only extended a bit, GDB does not use the extended API at all. */
-#define LIBUNWIND_SO_7 "libunwind-" STRINGIFY(UNW_TARGET) ".so.7"
-#endif
-
-static const char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg));
-static const char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg));
-static const char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_save_loc));
-static const char *is_signal_frame_name = STRINGIFY(UNW_OBJ(is_signal_frame));
-static const char *step_name = STRINGIFY(UNW_OBJ(step));
-static const char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote));
-static const char *create_addr_space_name
- = STRINGIFY(UNW_OBJ(create_addr_space));
-static const char *destroy_addr_space_name
- = STRINGIFY(UNW_OBJ(destroy_addr_space));
-static const char *search_unwind_table_name
- = STRINGIFY(UNW_OBJ(search_unwind_table));
-static const char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));
-
-static struct libunwind_descr *
-libunwind_descr (struct gdbarch *gdbarch)
-{
- struct libunwind_descr *result = libunwind_descr_handle.get (gdbarch);
- if (result == nullptr)
- result = libunwind_descr_handle.emplace (gdbarch);
- return result;
-}
-
-void
-libunwind_frame_set_descr (struct gdbarch *gdbarch,
- struct libunwind_descr *descr)
-{
- struct libunwind_descr *arch_descr;
-
- gdb_assert (gdbarch != NULL);
-
- arch_descr = libunwind_descr (gdbarch);
- gdb_assert (arch_descr != NULL);
-
- /* Copy new descriptor info into arch descriptor. */
- arch_descr->gdb2uw = descr->gdb2uw;
- arch_descr->uw2gdb = descr->uw2gdb;
- arch_descr->is_fpreg = descr->is_fpreg;
- arch_descr->accessors = descr->accessors;
- arch_descr->special_accessors = descr->special_accessors;
-}
-
-static struct libunwind_frame_cache *
-libunwind_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
-{
- unw_accessors_t *acc;
- unw_addr_space_t as;
- unw_word_t fp;
- unw_regnum_t uw_sp_regnum;
- struct libunwind_frame_cache *cache;
- struct libunwind_descr *descr;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- int ret;
-
- if (*this_cache)
- return (struct libunwind_frame_cache *) *this_cache;
-
- /* Allocate a new cache. */
- cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache);
-
- cache->func_addr = get_frame_func (this_frame);
- if (cache->func_addr == 0)
- /* This can happen when the frame corresponds to a function for which
- there is no debugging information nor any entry in the symbol table.
- This is probably a static function for which an entry in the symbol
- table was not created when the objfile got linked (observed in
- libpthread.so on ia64-hpux).
-
- The best we can do, in that case, is use the frame PC as the function
- address. We don't need to give up since we still have the unwind
- record to help us perform the unwinding. There is also another
- compelling to continue, because abandoning now means stopping
- the backtrace, which can never be helpful for the user. */
- cache->func_addr = get_frame_pc (this_frame);
-
- /* Get a libunwind cursor to the previous frame.
-
- We do this by initializing a cursor. Libunwind treats a new cursor
- as the top of stack and will get the current register set via the
- libunwind register accessor. Now, we provide the platform-specific
- accessors and we set up the register accessor to use the frame
- register unwinding interfaces so that we properly get the registers
- for the current frame rather than the top. We then use the unw_step
- function to move the libunwind cursor back one frame. We can later
- use this cursor to find previous registers via the unw_get_reg
- interface which will invoke libunwind's special logic. */
- descr = libunwind_descr (gdbarch);
- acc = (unw_accessors_t *) descr->accessors;
- as = unw_create_addr_space_p (acc,
- gdbarch_byte_order (gdbarch)
- == BFD_ENDIAN_BIG
- ? __BIG_ENDIAN
- : __LITTLE_ENDIAN);
-
- unw_init_remote_p (&cache->cursor, as, this_frame);
- if (unw_step_p (&cache->cursor) < 0)
- {
- unw_destroy_addr_space_p (as);
- return NULL;
- }
-
- /* To get base address, get sp from previous frame. */
- uw_sp_regnum = descr->gdb2uw (gdbarch_sp_regnum (gdbarch));
- ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
- if (ret < 0)
- {
- unw_destroy_addr_space_p (as);
- error (_("Can't get libunwind sp register."));
- }
-
- cache->base = (CORE_ADDR)fp;
- cache->as = as;
-
- *this_cache = cache;
- return cache;
-}
-
-void
-libunwind_frame_dealloc_cache (frame_info_ptr self, void *this_cache)
-{
- struct libunwind_frame_cache *cache
- = (struct libunwind_frame_cache *) this_cache;
-
- if (cache->as)
- unw_destroy_addr_space_p (cache->as);
-}
-
-unw_word_t
-libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
-{
- return unw_find_dyn_list_p (as, di, arg);
-}
-
-/* Verify if there is sufficient libunwind information for the frame to use
- libunwind frame unwinding. */
-int
-libunwind_frame_sniffer (const struct frame_unwind *self,
- const frame_info_ptr &this_frame, void **this_cache)
-{
- unw_cursor_t cursor;
- unw_accessors_t *acc;
- unw_addr_space_t as;
- struct libunwind_descr *descr;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- int ret;
-
- /* To test for libunwind unwind support, initialize a cursor to
- the current frame and try to back up. We use this same method
- when setting up the frame cache (see libunwind_frame_cache()).
- If libunwind returns success for this operation, it means that
- it has found sufficient libunwind unwinding information to do so. */
-
- descr = libunwind_descr (gdbarch);
- acc = (unw_accessors_t *) descr->accessors;
- as = unw_create_addr_space_p (acc,
- gdbarch_byte_order (gdbarch)
- == BFD_ENDIAN_BIG
- ? __BIG_ENDIAN
- : __LITTLE_ENDIAN);
-
- ret = unw_init_remote_p (&cursor, as, this_frame);
-
- if (ret < 0)
- {
- unw_destroy_addr_space_p (as);
- return 0;
- }
-
-
- /* Check to see if we have libunwind info by checking if we are in a
- signal frame. If it doesn't return an error, we have libunwind info
- and can use libunwind. */
- ret = unw_is_signal_frame_p (&cursor);
- unw_destroy_addr_space_p (as);
-
- if (ret < 0)
- return 0;
-
- return 1;
-}
-
-void
-libunwind_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
- struct frame_id *this_id)
-{
- struct libunwind_frame_cache *cache =
- libunwind_frame_cache (this_frame, this_cache);
-
- if (cache != NULL)
- (*this_id) = frame_id_build (cache->base, cache->func_addr);
-}
-
-struct value *
-libunwind_frame_prev_register (const frame_info_ptr &this_frame,
- void **this_cache, int regnum)
-{
- struct libunwind_frame_cache *cache =
- libunwind_frame_cache (this_frame, this_cache);
-
- unw_save_loc_t sl;
- int ret;
- unw_word_t intval;
- unw_fpreg_t fpval;
- unw_regnum_t uw_regnum;
- struct libunwind_descr *descr;
- struct value *val = NULL;
-
- if (cache == NULL)
- return frame_unwind_got_constant (this_frame, regnum, 0);
-
- /* Convert from gdb register number to libunwind register number. */
- descr = libunwind_descr (get_frame_arch (this_frame));
- uw_regnum = descr->gdb2uw (regnum);
-
- gdb_assert (regnum >= 0);
-
- if (!target_has_registers ())
- error (_("No registers."));
-
- if (uw_regnum < 0)
- return frame_unwind_got_constant (this_frame, regnum, 0);
-
- if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
- return frame_unwind_got_constant (this_frame, regnum, 0);
-
- switch (sl.type)
- {
- case UNW_SLT_MEMORY:
- val = frame_unwind_got_memory (this_frame, regnum, sl.u.addr);
- break;
-
- case UNW_SLT_REG:
- val = frame_unwind_got_register (this_frame, regnum,
- descr->uw2gdb (sl.u.regnum));
- break;
- case UNW_SLT_NONE:
- {
- /* The register is not stored at a specific memory address nor
- inside another register. So use libunwind to fetch the register
- value for us, and create a constant value with the result. */
- if (descr->is_fpreg (uw_regnum))
- {
- ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
- if (ret < 0)
- return frame_unwind_got_constant (this_frame, regnum, 0);
- val = frame_unwind_got_bytes (this_frame, regnum,
- (gdb_byte *) &fpval);
- }
- else
- {
- ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
- if (ret < 0)
- return frame_unwind_got_constant (this_frame, regnum, 0);
- val = frame_unwind_got_constant (this_frame, regnum, intval);
- }
- break;
- }
- }
-
- return val;
-}
-
-/* The following is a glue routine to call the libunwind unwind table
- search function to get unwind information for a specified ip address. */
-int
-libunwind_search_unwind_table (void *as, long ip, void *di,
- void *pi, int need_unwind_info, void *args)
-{
- return unw_search_unwind_table_p (*(unw_addr_space_t *) as, (unw_word_t) ip,
- (unw_dyn_info_t *) di,
- (unw_proc_info_t *) pi, need_unwind_info,
- args);
-}
-
-/* Verify if we are in a sigtramp frame and we can use libunwind to unwind. */
-int
-libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
- const frame_info_ptr &this_frame,
- void **this_cache)
-{
- unw_cursor_t cursor;
- unw_accessors_t *acc;
- unw_addr_space_t as;
- struct libunwind_descr *descr;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- int ret;
-
- /* To test for libunwind unwind support, initialize a cursor to the
- current frame and try to back up. We use this same method when
- setting up the frame cache (see libunwind_frame_cache()). If
- libunwind returns success for this operation, it means that it
- has found sufficient libunwind unwinding information to do
- so. */
-
- descr = libunwind_descr (gdbarch);
- acc = (unw_accessors_t *) descr->accessors;
- as = unw_create_addr_space_p (acc,
- gdbarch_byte_order (gdbarch)
- == BFD_ENDIAN_BIG
- ? __BIG_ENDIAN
- : __LITTLE_ENDIAN);
-
- ret = unw_init_remote_p (&cursor, as, this_frame);
-
- if (ret < 0)
- {
- unw_destroy_addr_space_p (as);
- return 0;
- }
-
- /* Check to see if we are in a signal frame. */
- ret = unw_is_signal_frame_p (&cursor);
- unw_destroy_addr_space_p (as);
- if (ret > 0)
- return 1;
-
- return 0;
-}
-
-/* The following routine is for accessing special registers of the top frame.
- A special set of accessors must be given that work without frame info.
- This is used by ia64 to access the rse registers r32-r127. While they
- are usually located at BOF, this is not always true and only the libunwind
- info can decipher where they actually are. */
-int
-libunwind_get_reg_special (struct gdbarch *gdbarch, readable_regcache *regcache,
- int regnum, void *buf)
-{
- unw_cursor_t cursor;
- unw_accessors_t *acc;
- unw_addr_space_t as;
- struct libunwind_descr *descr;
- int ret;
- unw_regnum_t uw_regnum;
- unw_word_t intval;
- unw_fpreg_t fpval;
- void *ptr;
-
-
- descr = libunwind_descr (gdbarch);
- acc = (unw_accessors_t *) descr->special_accessors;
- as = unw_create_addr_space_p (acc,
- gdbarch_byte_order (gdbarch)
- == BFD_ENDIAN_BIG
- ? __BIG_ENDIAN
- : __LITTLE_ENDIAN);
-
- ret = unw_init_remote_p (&cursor, as, regcache);
- if (ret < 0)
- {
- unw_destroy_addr_space_p (as);
- return -1;
- }
-
- uw_regnum = descr->gdb2uw (regnum);
-
- if (descr->is_fpreg (uw_regnum))
- {
- ret = unw_get_fpreg_p (&cursor, uw_regnum, &fpval);
- ptr = &fpval;
- }
- else
- {
- ret = unw_get_reg_p (&cursor, uw_regnum, &intval);
- ptr = &intval;
- }
-
- unw_destroy_addr_space_p (as);
-
- if (ret < 0)
- return -1;
-
- if (buf)
- memcpy (buf, ptr, register_size (gdbarch, regnum));
-
- return 0;
-}
-
-static int
-libunwind_load (void)
-{
- void *handle;
- char *so_error = NULL;
-
- handle = dlopen (LIBUNWIND_SO, RTLD_NOW);
- if (handle == NULL)
- {
- so_error = xstrdup (dlerror ());
-#ifdef LIBUNWIND_SO_7
- handle = dlopen (LIBUNWIND_SO_7, RTLD_NOW);
-#endif /* LIBUNWIND_SO_7 */
- }
- if (handle == NULL)
- {
- gdb_printf (gdb_stderr, _("[GDB failed to load %s: %s]\n"),
- LIBUNWIND_SO, so_error);
-#ifdef LIBUNWIND_SO_7
- gdb_printf (gdb_stderr, _("[GDB failed to load %s: %s]\n"),
- LIBUNWIND_SO_7, dlerror ());
-#endif /* LIBUNWIND_SO_7 */
- }
- xfree (so_error);
- if (handle == NULL)
- return 0;
-
- /* Initialize pointers to the dynamic library functions we will use. */
-
- unw_get_reg_p = (unw_get_reg_p_ftype *) dlsym (handle, get_reg_name);
- if (unw_get_reg_p == NULL)
- return 0;
-
- unw_get_fpreg_p = (unw_get_fpreg_p_ftype *) dlsym (handle, get_fpreg_name);
- if (unw_get_fpreg_p == NULL)
- return 0;
-
- unw_get_saveloc_p
- = (unw_get_saveloc_p_ftype *) dlsym (handle, get_saveloc_name);
- if (unw_get_saveloc_p == NULL)
- return 0;
-
- unw_is_signal_frame_p
- = (unw_is_signal_frame_p_ftype *) dlsym (handle, is_signal_frame_name);
- if (unw_is_signal_frame_p == NULL)
- return 0;
-
- unw_step_p = (unw_step_p_ftype *) dlsym (handle, step_name);
- if (unw_step_p == NULL)
- return 0;
-
- unw_init_remote_p
- = (unw_init_remote_p_ftype *) dlsym (handle, init_remote_name);
- if (unw_init_remote_p == NULL)
- return 0;
-
- unw_create_addr_space_p
- = (unw_create_addr_space_p_ftype *) dlsym (handle, create_addr_space_name);
- if (unw_create_addr_space_p == NULL)
- return 0;
-
- unw_destroy_addr_space_p
- = (unw_destroy_addr_space_p_ftype *) dlsym (handle,
- destroy_addr_space_name);
- if (unw_destroy_addr_space_p == NULL)
- return 0;
-
- unw_search_unwind_table_p
- = (unw_search_unwind_table_p_ftype *) dlsym (handle,
- search_unwind_table_name);
- if (unw_search_unwind_table_p == NULL)
- return 0;
-
- unw_find_dyn_list_p
- = (unw_find_dyn_list_p_ftype *) dlsym (handle, find_dyn_list_name);
- if (unw_find_dyn_list_p == NULL)
- return 0;
-
- return 1;
-}
-
-int
-libunwind_is_initialized (void)
-{
- return libunwind_initialized;
-}
-
-void _initialize_libunwind_frame ();
-void
-_initialize_libunwind_frame ()
-{
- libunwind_initialized = libunwind_load ();
-}
deleted file mode 100644
@@ -1,79 +0,0 @@
-/* Frame unwinder for ia64 frames with libunwind frame information.
-
- Copyright (C) 2003-2024 Free Software Foundation, Inc.
-
- Contributed by Jeff Johnston.
-
- 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 IA64_LIBUNWIND_TDEP_H
-#define IA64_LIBUNWIND_TDEP_H 1
-
-class frame_info_ptr;
-struct frame_id;
-struct regcache;
-struct gdbarch;
-struct frame_unwind;
-
-/* IA-64 is the only target that currently uses libunwind. If some
- other target wants to use it, we will need to do some abstracting
- in order to make it possible to have more than one
- ia64-libunwind-tdep instance. Including "libunwind.h" is wrong as
- that ends up including the libunwind-$(arch).h for the host gdb is
- running on. */
-#include "libunwind-ia64.h"
-
-#include "gdbarch.h"
-
-struct libunwind_descr
-{
- int (*gdb2uw) (int) = nullptr;
- int (*uw2gdb) (int) = nullptr;
- int (*is_fpreg) (int) = nullptr;
- void *accessors = nullptr;
- void *special_accessors = nullptr;
-};
-
-int libunwind_frame_sniffer (const struct frame_unwind *self,
- const frame_info_ptr &this_frame,
- void **this_cache);
-
-int libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
- const frame_info_ptr &this_frame,
- void **this_cache);
-
-void libunwind_frame_set_descr (struct gdbarch *arch,
- struct libunwind_descr *descr);
-
-void libunwind_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
- struct frame_id *this_id);
-struct value *libunwind_frame_prev_register (const frame_info_ptr &this_frame,
- void **this_cache, int regnum);
-void libunwind_frame_dealloc_cache (frame_info_ptr self, void *cache);
-
-int libunwind_is_initialized (void);
-
-int libunwind_search_unwind_table (void *as, long ip, void *di,
- void *pi, int need_unwind_info, void *args);
-
-unw_word_t libunwind_find_dyn_list (unw_addr_space_t, unw_dyn_info_t *,
- void *);
-
-int libunwind_get_reg_special (struct gdbarch *gdbarch,
- readable_regcache *regcache,
- int regnum, void *buf);
-
-#endif /* IA64_LIBUNWIND_TDEP_H */
deleted file mode 100644
@@ -1,931 +0,0 @@
-/* Functions specific to running gdb native on IA-64 running
- GNU/Linux.
-
- Copyright (C) 1999-2024 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 "inferior.h"
-#include "target.h"
-#include "gdbarch.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "ia64-tdep.h"
-#include "linux-nat.h"
-
-#include <signal.h>
-#include "nat/gdb_ptrace.h"
-#include "gdbsupport/gdb_wait.h"
-#ifdef HAVE_SYS_REG_H
-#include <sys/reg.h>
-#endif
-#include <sys/syscall.h>
-#include <sys/user.h>
-
-#include <asm/ptrace_offsets.h>
-#include <sys/procfs.h>
-
-/* Prototypes for supply_gregset etc. */
-#include "gregset.h"
-
-#include "inf-ptrace.h"
-
-class ia64_linux_nat_target final : public linux_nat_target
-{
-public:
- /* Add our register access methods. */
- void fetch_registers (struct regcache *, int) override;
- void store_registers (struct regcache *, int) override;
-
- enum target_xfer_status xfer_partial (enum target_object object,
- const char *annex,
- gdb_byte *readbuf,
- const gdb_byte *writebuf,
- ULONGEST offset, ULONGEST len,
- ULONGEST *xfered_len) override;
-
- /* Override watchpoint routines. */
-
- /* The IA-64 architecture can step over a watch point (without
- triggering it again) if the "dd" (data debug fault disable) bit
- in the processor status word is set.
-
- This PSR bit is set in
- ia64_linux_nat_target::stopped_by_watchpoint when the code there
- has determined that a hardware watchpoint has indeed been hit.
- The CPU will then be able to execute one instruction without
- triggering a watchpoint. */
- bool have_steppable_watchpoint () override { return true; }
-
- int can_use_hw_breakpoint (enum bptype, int, int) override;
- bool stopped_by_watchpoint () override;
- bool stopped_data_address (CORE_ADDR *) override;
- int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
- struct expression *) override;
- int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
- struct expression *) override;
- /* Override linux_nat_target low methods. */
- void low_new_thread (struct lwp_info *lp) override;
- bool low_status_is_event (int status) override;
-
- void enable_watchpoints_in_psr (ptid_t ptid);
-};
-
-static ia64_linux_nat_target the_ia64_linux_nat_target;
-
-/* These must match the order of the register names.
-
- Some sort of lookup table is needed because the offsets associated
- with the registers are all over the board. */
-
-static int u_offsets[] =
- {
- /* general registers */
- -1, /* gr0 not available; i.e, it's always zero. */
- PT_R1,
- PT_R2,
- PT_R3,
- PT_R4,
- PT_R5,
- PT_R6,
- PT_R7,
- PT_R8,
- PT_R9,
- PT_R10,
- PT_R11,
- PT_R12,
- PT_R13,
- PT_R14,
- PT_R15,
- PT_R16,
- PT_R17,
- PT_R18,
- PT_R19,
- PT_R20,
- PT_R21,
- PT_R22,
- PT_R23,
- PT_R24,
- PT_R25,
- PT_R26,
- PT_R27,
- PT_R28,
- PT_R29,
- PT_R30,
- PT_R31,
- /* gr32 through gr127 not directly available via the ptrace interface. */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- /* Floating point registers */
- -1, -1, /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0). */
- PT_F2,
- PT_F3,
- PT_F4,
- PT_F5,
- PT_F6,
- PT_F7,
- PT_F8,
- PT_F9,
- PT_F10,
- PT_F11,
- PT_F12,
- PT_F13,
- PT_F14,
- PT_F15,
- PT_F16,
- PT_F17,
- PT_F18,
- PT_F19,
- PT_F20,
- PT_F21,
- PT_F22,
- PT_F23,
- PT_F24,
- PT_F25,
- PT_F26,
- PT_F27,
- PT_F28,
- PT_F29,
- PT_F30,
- PT_F31,
- PT_F32,
- PT_F33,
- PT_F34,
- PT_F35,
- PT_F36,
- PT_F37,
- PT_F38,
- PT_F39,
- PT_F40,
- PT_F41,
- PT_F42,
- PT_F43,
- PT_F44,
- PT_F45,
- PT_F46,
- PT_F47,
- PT_F48,
- PT_F49,
- PT_F50,
- PT_F51,
- PT_F52,
- PT_F53,
- PT_F54,
- PT_F55,
- PT_F56,
- PT_F57,
- PT_F58,
- PT_F59,
- PT_F60,
- PT_F61,
- PT_F62,
- PT_F63,
- PT_F64,
- PT_F65,
- PT_F66,
- PT_F67,
- PT_F68,
- PT_F69,
- PT_F70,
- PT_F71,
- PT_F72,
- PT_F73,
- PT_F74,
- PT_F75,
- PT_F76,
- PT_F77,
- PT_F78,
- PT_F79,
- PT_F80,
- PT_F81,
- PT_F82,
- PT_F83,
- PT_F84,
- PT_F85,
- PT_F86,
- PT_F87,
- PT_F88,
- PT_F89,
- PT_F90,
- PT_F91,
- PT_F92,
- PT_F93,
- PT_F94,
- PT_F95,
- PT_F96,
- PT_F97,
- PT_F98,
- PT_F99,
- PT_F100,
- PT_F101,
- PT_F102,
- PT_F103,
- PT_F104,
- PT_F105,
- PT_F106,
- PT_F107,
- PT_F108,
- PT_F109,
- PT_F110,
- PT_F111,
- PT_F112,
- PT_F113,
- PT_F114,
- PT_F115,
- PT_F116,
- PT_F117,
- PT_F118,
- PT_F119,
- PT_F120,
- PT_F121,
- PT_F122,
- PT_F123,
- PT_F124,
- PT_F125,
- PT_F126,
- PT_F127,
- /* Predicate registers - we don't fetch these individually. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* branch registers */
- PT_B0,
- PT_B1,
- PT_B2,
- PT_B3,
- PT_B4,
- PT_B5,
- PT_B6,
- PT_B7,
- /* Virtual frame pointer and virtual return address pointer. */
- -1, -1,
- /* other registers */
- PT_PR,
- PT_CR_IIP, /* ip */
- PT_CR_IPSR, /* psr */
- PT_CFM, /* cfm */
- /* kernel registers not visible via ptrace interface (?) */
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* hole */
- -1, -1, -1, -1, -1, -1, -1, -1,
- PT_AR_RSC,
- PT_AR_BSP,
- PT_AR_BSPSTORE,
- PT_AR_RNAT,
- -1,
- -1, /* Not available: FCR, IA32 floating control register. */
- -1, -1,
- -1, /* Not available: EFLAG */
- -1, /* Not available: CSD */
- -1, /* Not available: SSD */
- -1, /* Not available: CFLG */
- -1, /* Not available: FSR */
- -1, /* Not available: FIR */
- -1, /* Not available: FDR */
- -1,
- PT_AR_CCV,
- -1, -1, -1,
- PT_AR_UNAT,
- -1, -1, -1,
- PT_AR_FPSR,
- -1, -1, -1,
- -1, /* Not available: ITC */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1,
- PT_AR_PFS,
- PT_AR_LC,
- PT_AR_EC,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1,
- /* nat bits - not fetched directly; instead we obtain these bits from
- either rnat or unat or from memory. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- };
-
-static CORE_ADDR
-ia64_register_addr (struct gdbarch *gdbarch, int regno)
-{
- CORE_ADDR addr;
-
- if (regno < 0 || regno >= gdbarch_num_regs (gdbarch))
- error (_("Invalid register number %d."), regno);
-
- if (u_offsets[regno] == -1)
- addr = 0;
- else
- addr = (CORE_ADDR) u_offsets[regno];
-
- return addr;
-}
-
-static int
-ia64_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
-{
- return regno < 0
- || regno >= gdbarch_num_regs (gdbarch)
- || u_offsets[regno] == -1;
-}
-
-static int
-ia64_cannot_store_register (struct gdbarch *gdbarch, int regno)
-{
- /* Rationale behind not permitting stores to bspstore...
-
- The IA-64 architecture provides bspstore and bsp which refer
- memory locations in the RSE's backing store. bspstore is the
- next location which will be written when the RSE needs to write
- to memory. bsp is the address at which r32 in the current frame
- would be found if it were written to the backing store.
-
- The IA-64 architecture provides read-only access to bsp and
- read/write access to bspstore (but only when the RSE is in
- the enforced lazy mode). It should be noted that stores
- to bspstore also affect the value of bsp. Changing bspstore
- does not affect the number of dirty entries between bspstore
- and bsp, so changing bspstore by N words will also cause bsp
- to be changed by (roughly) N as well. (It could be N-1 or N+1
- depending upon where the NaT collection bits fall.)
-
- OTOH, the Linux kernel provides read/write access to bsp (and
- currently read/write access to bspstore as well). But it
- is definitely the case that if you change one, the other
- will change at the same time. It is more useful to gdb to
- be able to change bsp. So in order to prevent strange and
- undesirable things from happening when a dummy stack frame
- is popped (after calling an inferior function), we allow
- bspstore to be read, but not written. (Note that popping
- a (generic) dummy stack frame causes all registers that
- were previously read from the inferior process to be written
- back.) */
-
- return regno < 0
- || regno >= gdbarch_num_regs (gdbarch)
- || u_offsets[regno] == -1
- || regno == IA64_BSPSTORE_REGNUM;
-}
-
-void
-supply_gregset (struct regcache *regcache, const gregset_t *gregsetp)
-{
- int regi;
- const greg_t *regp = (const greg_t *) gregsetp;
-
- for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
- {
- regcache->raw_supply (regi, regp + (regi - IA64_GR0_REGNUM));
- }
-
- /* FIXME: NAT collection bits are at index 32; gotta deal with these
- somehow... */
-
- regcache->raw_supply (IA64_PR_REGNUM, regp + 33);
-
- for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
- {
- regcache->raw_supply (regi, regp + 34 + (regi - IA64_BR0_REGNUM));
- }
-
- regcache->raw_supply (IA64_IP_REGNUM, regp + 42);
- regcache->raw_supply (IA64_CFM_REGNUM, regp + 43);
- regcache->raw_supply (IA64_PSR_REGNUM, regp + 44);
- regcache->raw_supply (IA64_RSC_REGNUM, regp + 45);
- regcache->raw_supply (IA64_BSP_REGNUM, regp + 46);
- regcache->raw_supply (IA64_BSPSTORE_REGNUM, regp + 47);
- regcache->raw_supply (IA64_RNAT_REGNUM, regp + 48);
- regcache->raw_supply (IA64_CCV_REGNUM, regp + 49);
- regcache->raw_supply (IA64_UNAT_REGNUM, regp + 50);
- regcache->raw_supply (IA64_FPSR_REGNUM, regp + 51);
- regcache->raw_supply (IA64_PFS_REGNUM, regp + 52);
- regcache->raw_supply (IA64_LC_REGNUM, regp + 53);
- regcache->raw_supply (IA64_EC_REGNUM, regp + 54);
-}
-
-void
-fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno)
-{
- int regi;
- greg_t *regp = (greg_t *) gregsetp;
-
-#define COPY_REG(_idx_,_regi_) \
- if ((regno == -1) || regno == _regi_) \
- regcache->raw_collect (_regi_, regp + _idx_)
-
- for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
- {
- COPY_REG (regi - IA64_GR0_REGNUM, regi);
- }
-
- /* FIXME: NAT collection bits at index 32? */
-
- COPY_REG (33, IA64_PR_REGNUM);
-
- for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
- {
- COPY_REG (34 + (regi - IA64_BR0_REGNUM), regi);
- }
-
- COPY_REG (42, IA64_IP_REGNUM);
- COPY_REG (43, IA64_CFM_REGNUM);
- COPY_REG (44, IA64_PSR_REGNUM);
- COPY_REG (45, IA64_RSC_REGNUM);
- COPY_REG (46, IA64_BSP_REGNUM);
- COPY_REG (47, IA64_BSPSTORE_REGNUM);
- COPY_REG (48, IA64_RNAT_REGNUM);
- COPY_REG (49, IA64_CCV_REGNUM);
- COPY_REG (50, IA64_UNAT_REGNUM);
- COPY_REG (51, IA64_FPSR_REGNUM);
- COPY_REG (52, IA64_PFS_REGNUM);
- COPY_REG (53, IA64_LC_REGNUM);
- COPY_REG (54, IA64_EC_REGNUM);
-}
-
-/* Given a pointer to a floating point register set in /proc format
- (fpregset_t *), unpack the register contents and supply them as gdb's
- idea of the current floating point register values. */
-
-void
-supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
-{
- int regi;
- const char *from;
- const gdb_byte f_zero[16] = { 0 };
- const gdb_byte f_one[16] =
- { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 };
-
- /* Kernel generated cores have fr1==0 instead of 1.0. Older GDBs
- did the same. So ignore whatever might be recorded in fpregset_t
- for fr0/fr1 and always supply their expected values. */
-
- /* fr0 is always read as zero. */
- regcache->raw_supply (IA64_FR0_REGNUM, f_zero);
- /* fr1 is always read as one (1.0). */
- regcache->raw_supply (IA64_FR1_REGNUM, f_one);
-
- for (regi = IA64_FR2_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
- {
- from = (const char *) &((*fpregsetp)[regi - IA64_FR0_REGNUM]);
- regcache->raw_supply (regi, from);
- }
-}
-
-/* Given a pointer to a floating point register set in /proc format
- (fpregset_t *), update the register specified by REGNO from gdb's idea
- of the current floating point register set. If REGNO is -1, update
- them all. */
-
-void
-fill_fpregset (const struct regcache *regcache,
- fpregset_t *fpregsetp, int regno)
-{
- int regi;
-
- for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
- {
- if ((regno == -1) || (regno == regi))
- regcache->raw_collect (regi, &((*fpregsetp)[regi - IA64_FR0_REGNUM]));
- }
-}
-
-#define IA64_PSR_DB (1UL << 24)
-#define IA64_PSR_DD (1UL << 39)
-
-void
-ia64_linux_nat_target::enable_watchpoints_in_psr (ptid_t ptid)
-{
- struct regcache *regcache = get_thread_regcache (this, ptid);
- ULONGEST psr;
-
- regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr);
- if (!(psr & IA64_PSR_DB))
- {
- psr |= IA64_PSR_DB; /* Set the db bit - this enables hardware
- watchpoints and breakpoints. */
- regcache_cooked_write_unsigned (regcache, IA64_PSR_REGNUM, psr);
- }
-}
-
-static long debug_registers[8];
-
-static void
-store_debug_register (ptid_t ptid, int idx, long val)
-{
- int tid;
-
- tid = ptid.lwp ();
- if (tid == 0)
- tid = ptid.pid ();
-
- (void) ptrace (PT_WRITE_U, tid, (PTRACE_TYPE_ARG3) (PT_DBR + 8 * idx), val);
-}
-
-static void
-store_debug_register_pair (ptid_t ptid, int idx, long *dbr_addr,
- long *dbr_mask)
-{
- if (dbr_addr)
- store_debug_register (ptid, 2 * idx, *dbr_addr);
- if (dbr_mask)
- store_debug_register (ptid, 2 * idx + 1, *dbr_mask);
-}
-
-static int
-is_power_of_2 (int val)
-{
- int i, onecount;
-
- onecount = 0;
- for (i = 0; i < 8 * sizeof (val); i++)
- if (val & (1 << i))
- onecount++;
-
- return onecount <= 1;
-}
-
-int
-ia64_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
- enum target_hw_bp_type type,
- struct expression *cond)
-{
- int idx;
- long dbr_addr, dbr_mask;
- int max_watchpoints = 4;
-
- if (len <= 0 || !is_power_of_2 (len))
- return -1;
-
- for (idx = 0; idx < max_watchpoints; idx++)
- {
- dbr_mask = debug_registers[idx * 2 + 1];
- if ((dbr_mask & (0x3UL << 62)) == 0)
- {
- /* Exit loop if both r and w bits clear. */
- break;
- }
- }
-
- if (idx == max_watchpoints)
- return -1;
-
- dbr_addr = (long) addr;
- dbr_mask = (~(len - 1) & 0x00ffffffffffffffL); /* construct mask to match */
- dbr_mask |= 0x0800000000000000L; /* Only match privilege level 3 */
- switch (type)
- {
- case hw_write:
- dbr_mask |= (1L << 62); /* Set w bit */
- break;
- case hw_read:
- dbr_mask |= (1L << 63); /* Set r bit */
- break;
- case hw_access:
- dbr_mask |= (3L << 62); /* Set both r and w bits */
- break;
- default:
- return -1;
- }
-
- debug_registers[2 * idx] = dbr_addr;
- debug_registers[2 * idx + 1] = dbr_mask;
-
- for (const lwp_info *lp : all_lwps ())
- {
- store_debug_register_pair (lp->ptid, idx, &dbr_addr, &dbr_mask);
- enable_watchpoints_in_psr (lp->ptid);
- }
-
- return 0;
-}
-
-int
-ia64_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
- enum target_hw_bp_type type,
- struct expression *cond)
-{
- int idx;
- long dbr_addr, dbr_mask;
- int max_watchpoints = 4;
-
- if (len <= 0 || !is_power_of_2 (len))
- return -1;
-
- for (idx = 0; idx < max_watchpoints; idx++)
- {
- dbr_addr = debug_registers[2 * idx];
- dbr_mask = debug_registers[2 * idx + 1];
- if ((dbr_mask & (0x3UL << 62)) && addr == (CORE_ADDR) dbr_addr)
- {
- debug_registers[2 * idx] = 0;
- debug_registers[2 * idx + 1] = 0;
- dbr_addr = 0;
- dbr_mask = 0;
-
- for (const lwp_info *lp : all_lwps ())
- store_debug_register_pair (lp->ptid, idx, &dbr_addr, &dbr_mask);
-
- return 0;
- }
- }
- return -1;
-}
-
-void
-ia64_linux_nat_target::low_new_thread (struct lwp_info *lp)
-{
- int i, any;
-
- any = 0;
- for (i = 0; i < 8; i++)
- {
- if (debug_registers[i] != 0)
- any = 1;
- store_debug_register (lp->ptid, i, debug_registers[i]);
- }
-
- if (any)
- enable_watchpoints_in_psr (lp->ptid);
-}
-
-bool
-ia64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
-{
- CORE_ADDR psr;
- siginfo_t siginfo;
- regcache *regcache = get_thread_regcache (inferior_thread ());
-
- if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
- return false;
-
- if (siginfo.si_signo != SIGTRAP
- || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
- return false;
-
- regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr);
- psr |= IA64_PSR_DD; /* Set the dd bit - this will disable the watchpoint
- for the next instruction. */
- regcache_cooked_write_unsigned (regcache, IA64_PSR_REGNUM, psr);
-
- *addr_p = (CORE_ADDR) siginfo.si_addr;
- return true;
-}
-
-bool
-ia64_linux_nat_target::stopped_by_watchpoint ()
-{
- CORE_ADDR addr;
- return stopped_data_address (&addr);
-}
-
-int
-ia64_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
- int cnt, int othertype)
-{
- return 1;
-}
-
-
-/* Fetch register REGNUM from the inferior. */
-
-static void
-ia64_linux_fetch_register (struct regcache *regcache, int regnum)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- CORE_ADDR addr;
- size_t size;
- PTRACE_TYPE_RET *buf;
- pid_t pid;
- int i;
-
- /* r0 cannot be fetched but is always zero. */
- if (regnum == IA64_GR0_REGNUM)
- {
- const gdb_byte zero[8] = { 0 };
-
- gdb_assert (sizeof (zero) == register_size (gdbarch, regnum));
- regcache->raw_supply (regnum, zero);
- return;
- }
-
- /* fr0 cannot be fetched but is always zero. */
- if (regnum == IA64_FR0_REGNUM)
- {
- const gdb_byte f_zero[16] = { 0 };
-
- gdb_assert (sizeof (f_zero) == register_size (gdbarch, regnum));
- regcache->raw_supply (regnum, f_zero);
- return;
- }
-
- /* fr1 cannot be fetched but is always one (1.0). */
- if (regnum == IA64_FR1_REGNUM)
- {
- const gdb_byte f_one[16] =
- { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 };
-
- gdb_assert (sizeof (f_one) == register_size (gdbarch, regnum));
- regcache->raw_supply (regnum, f_one);
- return;
- }
-
- if (ia64_cannot_fetch_register (gdbarch, regnum))
- {
- regcache->raw_supply (regnum, NULL);
- return;
- }
-
- pid = get_ptrace_pid (regcache->ptid ());
-
- /* This isn't really an address, but ptrace thinks of it as one. */
- addr = ia64_register_addr (gdbarch, regnum);
- size = register_size (gdbarch, regnum);
-
- gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
- buf = (PTRACE_TYPE_RET *) alloca (size);
-
- /* Read the register contents from the inferior a chunk at a time. */
- for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
- {
- errno = 0;
- buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)addr, 0);
- if (errno != 0)
- error (_("Couldn't read register %s (#%d): %s."),
- gdbarch_register_name (gdbarch, regnum),
- regnum, safe_strerror (errno));
-
- addr += sizeof (PTRACE_TYPE_RET);
- }
- regcache->raw_supply (regnum, buf);
-}
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers. */
-
-void
-ia64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
-{
- if (regnum == -1)
- for (regnum = 0;
- regnum < gdbarch_num_regs (regcache->arch ());
- regnum++)
- ia64_linux_fetch_register (regcache, regnum);
- else
- ia64_linux_fetch_register (regcache, regnum);
-}
-
-/* Store register REGNUM into the inferior. */
-
-static void
-ia64_linux_store_register (const struct regcache *regcache, int regnum)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- CORE_ADDR addr;
- size_t size;
- PTRACE_TYPE_RET *buf;
- pid_t pid;
- int i;
-
- if (ia64_cannot_store_register (gdbarch, regnum))
- return;
-
- pid = get_ptrace_pid (regcache->ptid ());
-
- /* This isn't really an address, but ptrace thinks of it as one. */
- addr = ia64_register_addr (gdbarch, regnum);
- size = register_size (gdbarch, regnum);
-
- gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
- buf = (PTRACE_TYPE_RET *) alloca (size);
-
- /* Write the register contents into the inferior a chunk at a time. */
- regcache->raw_collect (regnum, buf);
- for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
- {
- errno = 0;
- ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)addr, buf[i]);
- if (errno != 0)
- error (_("Couldn't write register %s (#%d): %s."),
- gdbarch_register_name (gdbarch, regnum),
- regnum, safe_strerror (errno));
-
- addr += sizeof (PTRACE_TYPE_RET);
- }
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers. */
-
-void
-ia64_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
-{
- if (regnum == -1)
- for (regnum = 0;
- regnum < gdbarch_num_regs (regcache->arch ());
- regnum++)
- ia64_linux_store_register (regcache, regnum);
- else
- ia64_linux_store_register (regcache, regnum);
-}
-
-/* Implement the xfer_partial target_ops method. */
-
-enum target_xfer_status
-ia64_linux_nat_target::xfer_partial (enum target_object object,
- const char *annex,
- gdb_byte *readbuf, const gdb_byte *writebuf,
- ULONGEST offset, ULONGEST len,
- ULONGEST *xfered_len)
-{
- if (object == TARGET_OBJECT_UNWIND_TABLE && readbuf != NULL)
- {
- static long gate_table_size;
- gdb_byte *tmp_buf;
- long res;
-
- /* Probe for the table size once. */
- if (gate_table_size == 0)
- gate_table_size = syscall (__NR_getunwind, NULL, 0);
- if (gate_table_size < 0)
- return TARGET_XFER_E_IO;
-
- if (offset >= gate_table_size)
- return TARGET_XFER_EOF;
-
- tmp_buf = (gdb_byte *) alloca (gate_table_size);
- res = syscall (__NR_getunwind, tmp_buf, gate_table_size);
- if (res < 0)
- return TARGET_XFER_E_IO;
- gdb_assert (res == gate_table_size);
-
- if (offset + len > gate_table_size)
- len = gate_table_size - offset;
-
- memcpy (readbuf, tmp_buf + offset, len);
- *xfered_len = len;
- return TARGET_XFER_OK;
- }
-
- return linux_nat_target::xfer_partial (object, annex, readbuf, writebuf,
- offset, len, xfered_len);
-}
-
-/* For break.b instruction ia64 CPU forgets the immediate value and generates
- SIGILL with ILL_ILLOPC instead of more common SIGTRAP with TRAP_BRKPT.
- ia64 does not use gdbarch_decr_pc_after_break so we do not have to make any
- difference for the signals here. */
-
-bool
-ia64_linux_nat_target::low_status_is_event (int status)
-{
- return WIFSTOPPED (status) && (WSTOPSIG (status) == SIGTRAP
- || WSTOPSIG (status) == SIGILL);
-}
-
-void _initialize_ia64_linux_nat ();
-void
-_initialize_ia64_linux_nat ()
-{
- /* Register the target. */
- linux_target = &the_ia64_linux_nat_target;
- add_inf_child_target (&the_ia64_linux_nat_target);
-}
deleted file mode 100644
@@ -1,267 +0,0 @@
-/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
-
- Copyright (C) 2000-2024 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 "extract-store-integer.h"
-#include "ia64-tdep.h"
-#include "arch-utils.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "osabi.h"
-#include "solib-svr4.h"
-#include "symtab.h"
-#include "linux-tdep.h"
-#include "regset.h"
-
-#include <ctype.h>
-
-/* The sigtramp code is in a non-readable (executable-only) region
- of memory called the ``gate page''. The addresses in question
- were determined by examining the system headers. They are
- overly generous to allow for different pages sizes. */
-
-#define GATE_AREA_START 0xa000000000000100LL
-#define GATE_AREA_END 0xa000000000020000LL
-
-/* Offset to sigcontext structure from frame of handler. */
-#define IA64_LINUX_SIGCONTEXT_OFFSET 192
-
-static int
-ia64_linux_pc_in_sigtramp (CORE_ADDR pc)
-{
- return (pc >= (CORE_ADDR) GATE_AREA_START && pc < (CORE_ADDR) GATE_AREA_END);
-}
-
-/* IA-64 GNU/Linux specific function which, given a frame address and
- a register number, returns the address at which that register may be
- found. 0 is returned for registers which aren't stored in the
- sigcontext structure. */
-
-static CORE_ADDR
-ia64_linux_sigcontext_register_address (struct gdbarch *gdbarch,
- CORE_ADDR sp, int regno)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[8];
- CORE_ADDR sigcontext_addr = 0;
-
- /* The address of the sigcontext area is found at offset 16 in the
- sigframe. */
- read_memory (sp + 16, buf, 8);
- sigcontext_addr = extract_unsigned_integer (buf, 8, byte_order);
-
- if (IA64_GR0_REGNUM <= regno && regno <= IA64_GR31_REGNUM)
- return sigcontext_addr + 200 + 8 * (regno - IA64_GR0_REGNUM);
- else if (IA64_BR0_REGNUM <= regno && regno <= IA64_BR7_REGNUM)
- return sigcontext_addr + 136 + 8 * (regno - IA64_BR0_REGNUM);
- else if (IA64_FR0_REGNUM <= regno && regno <= IA64_FR127_REGNUM)
- return sigcontext_addr + 464 + 16 * (regno - IA64_FR0_REGNUM);
- else
- switch (regno)
- {
- case IA64_IP_REGNUM :
- return sigcontext_addr + 40;
- case IA64_CFM_REGNUM :
- return sigcontext_addr + 48;
- case IA64_PSR_REGNUM :
- return sigcontext_addr + 56; /* user mask only */
- /* sc_ar_rsc is provided, from which we could compute bspstore, but
- I don't think it's worth it. Anyway, if we want it, it's at offset
- 64. */
- case IA64_BSP_REGNUM :
- return sigcontext_addr + 72;
- case IA64_RNAT_REGNUM :
- return sigcontext_addr + 80;
- case IA64_CCV_REGNUM :
- return sigcontext_addr + 88;
- case IA64_UNAT_REGNUM :
- return sigcontext_addr + 96;
- case IA64_FPSR_REGNUM :
- return sigcontext_addr + 104;
- case IA64_PFS_REGNUM :
- return sigcontext_addr + 112;
- case IA64_LC_REGNUM :
- return sigcontext_addr + 120;
- case IA64_PR_REGNUM :
- return sigcontext_addr + 128;
- default :
- return 0;
- }
-}
-
-static void
-ia64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
-{
- ia64_write_pc (regcache, pc);
-
- /* We must be careful with modifying the instruction-pointer: if we
- just interrupt a system call, the kernel would ordinarily try to
- restart it when we resume the inferior, which typically results
- in SIGSEGV or SIGILL. We prevent this by clearing r10, which
- will tell the kernel that r8 does NOT contain a valid error code
- and hence it will skip system-call restart.
-
- The clearing of r10 is safe as long as ia64_write_pc() is only
- called as part of setting up an inferior call. */
- regcache_cooked_write_unsigned (regcache, IA64_GR10_REGNUM, 0);
-}
-
-/* Implementation of `gdbarch_stap_is_single_operand', as defined in
- gdbarch.h. */
-
-static int
-ia64_linux_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
-{
- return ((isdigit (*s) && s[1] == '[' && s[2] == 'r') /* Displacement. */
- || *s == 'r' /* Register value. */
- || isdigit (*s)); /* Literal number. */
-}
-
-/* Core file support. */
-
-static const struct regcache_map_entry ia64_linux_gregmap[] =
- {
- { 32, IA64_GR0_REGNUM, 8 }, /* r0 ... r31 */
- { 1, REGCACHE_MAP_SKIP, 8 }, /* FIXME: NAT collection bits? */
- { 1, IA64_PR_REGNUM, 8 },
- { 8, IA64_BR0_REGNUM, 8 }, /* b0 ... b7 */
- { 1, IA64_IP_REGNUM, 8 },
- { 1, IA64_CFM_REGNUM, 8 },
- { 1, IA64_PSR_REGNUM, 8 },
- { 1, IA64_RSC_REGNUM, 8 },
- { 1, IA64_BSP_REGNUM, 8 },
- { 1, IA64_BSPSTORE_REGNUM, 8 },
- { 1, IA64_RNAT_REGNUM, 8 },
- { 1, IA64_CCV_REGNUM, 8 },
- { 1, IA64_UNAT_REGNUM, 8 },
- { 1, IA64_FPSR_REGNUM, 8 },
- { 1, IA64_PFS_REGNUM, 8 },
- { 1, IA64_LC_REGNUM, 8 },
- { 1, IA64_EC_REGNUM, 8 },
- { 0 }
- };
-
-/* Size of 'gregset_t', as defined by the Linux kernel. Note that
- this is more than actually mapped in the regmap above. */
-
-#define IA64_LINUX_GREGS_SIZE (128 * 8)
-
-static const struct regcache_map_entry ia64_linux_fpregmap[] =
- {
- { 128, IA64_FR0_REGNUM, 16 }, /* f0 ... f127 */
- { 0 }
- };
-
-#define IA64_LINUX_FPREGS_SIZE (128 * 16)
-
-static void
-ia64_linux_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *regs, size_t len)
-{
- const gdb_byte f_zero[16] = { 0 };
- const gdb_byte f_one[16] =
- { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 };
-
- regcache_supply_regset (regset, regcache, regnum, regs, len);
-
- /* Kernel generated cores have fr1==0 instead of 1.0. Older GDBs
- did the same. So ignore whatever might be recorded in fpregset_t
- for fr0/fr1 and always supply their expected values. */
- if (regnum == -1 || regnum == IA64_FR0_REGNUM)
- regcache->raw_supply (IA64_FR0_REGNUM, f_zero);
- if (regnum == -1 || regnum == IA64_FR1_REGNUM)
- regcache->raw_supply (IA64_FR1_REGNUM, f_one);
-}
-
-static const struct regset ia64_linux_gregset =
- {
- ia64_linux_gregmap,
- regcache_supply_regset, regcache_collect_regset
- };
-
-static const struct regset ia64_linux_fpregset =
- {
- ia64_linux_fpregmap,
- ia64_linux_supply_fpregset, regcache_collect_regset
- };
-
-static void
-ia64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", IA64_LINUX_GREGS_SIZE, IA64_LINUX_GREGS_SIZE, &ia64_linux_gregset,
- NULL, cb_data);
- cb (".reg2", IA64_LINUX_FPREGS_SIZE, IA64_LINUX_FPREGS_SIZE,
- &ia64_linux_fpregset, NULL, cb_data);
-}
-
-static void
-ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
- static const char *const stap_register_prefixes[] = { "r", NULL };
- static const char *const stap_register_indirection_prefixes[] = { "[",
- NULL };
- static const char *const stap_register_indirection_suffixes[] = { "]",
- NULL };
-
- linux_init_abi (info, gdbarch, 0);
-
- /* Set the method of obtaining the sigcontext addresses at which
- registers are saved. */
- tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address;
-
- /* Set the pc_in_sigtramp method. */
- tdep->pc_in_sigtramp = ia64_linux_pc_in_sigtramp;
-
- set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc);
-
- set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
-
- /* Enable TLS support. */
- set_gdbarch_fetch_tls_load_module_address (gdbarch,
- svr4_fetch_objfile_link_map);
-
- /* Core file support. */
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, ia64_linux_iterate_over_regset_sections);
-
- /* SystemTap related. */
- set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
- set_gdbarch_stap_register_indirection_prefixes (gdbarch,
- stap_register_indirection_prefixes);
- set_gdbarch_stap_register_indirection_suffixes (gdbarch,
- stap_register_indirection_suffixes);
- set_gdbarch_stap_gdb_register_prefix (gdbarch, "r");
- set_gdbarch_stap_is_single_operand (gdbarch,
- ia64_linux_stap_is_single_operand);
-}
-
-void _initialize_ia64_linux_tdep ();
-void
-_initialize_ia64_linux_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_LINUX,
- ia64_linux_init_abi);
-}
deleted file mode 100644
@@ -1,4024 +0,0 @@
-/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
-
- Copyright (C) 1999-2024 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 "extract-store-integer.h"
-#include "inferior.h"
-#include "gdbcore.h"
-#include "arch-utils.h"
-#include "floatformat.h"
-#include "gdbtypes.h"
-#include "regcache.h"
-#include "reggroups.h"
-#include "frame.h"
-#include "frame-base.h"
-#include "frame-unwind.h"
-#include "target-float.h"
-#include "value.h"
-#include "objfiles.h"
-#include "elf/common.h"
-#include "elf-bfd.h"
-#include "dis-asm.h"
-#include "infcall.h"
-#include "osabi.h"
-#include "ia64-tdep.h"
-#include "cp-abi.h"
-
-#ifdef HAVE_LIBUNWIND_IA64_H
-#include "elf/ia64.h"
-#include "ia64-libunwind-tdep.h"
-
-/* Note: KERNEL_START is supposed to be an address which is not going
- to ever contain any valid unwind info. For ia64 linux, the choice
- of 0xc000000000000000 is fairly safe since that's uncached space.
-
- We use KERNEL_START as follows: after obtaining the kernel's
- unwind table via getunwind(), we project its unwind data into
- address-range KERNEL_START-(KERNEL_START+ktab_size) and then
- when ia64_access_mem() sees a memory access to this
- address-range, we redirect it to ktab instead.
-
- None of this hackery is needed with a modern kernel/libcs
- which uses the kernel virtual DSO to provide access to the
- kernel's unwind info. In that case, ktab_size remains 0 and
- hence the value of KERNEL_START doesn't matter. */
-
-#define KERNEL_START 0xc000000000000000ULL
-
-static size_t ktab_size = 0;
-struct ia64_table_entry
- {
- uint64_t start_offset;
- uint64_t end_offset;
- uint64_t info_offset;
- };
-
-static struct ia64_table_entry *ktab = NULL;
-static std::optional<gdb::byte_vector> ktab_buf;
-
-#endif
-
-/* An enumeration of the different IA-64 instruction types. */
-
-enum ia64_instruction_type
-{
- A, /* Integer ALU ; I-unit or M-unit */
- I, /* Non-ALU integer; I-unit */
- M, /* Memory ; M-unit */
- F, /* Floating-point ; F-unit */
- B, /* Branch ; B-unit */
- L, /* Extended (L+X) ; I-unit */
- X, /* Extended (L+X) ; I-unit */
- undefined /* undefined or reserved */
-};
-
-/* We represent IA-64 PC addresses as the value of the instruction
- pointer or'd with some bit combination in the low nibble which
- represents the slot number in the bundle addressed by the
- instruction pointer. The problem is that the Linux kernel
- multiplies its slot numbers (for exceptions) by one while the
- disassembler multiplies its slot numbers by 6. In addition, I've
- heard it said that the simulator uses 1 as the multiplier.
-
- I've fixed the disassembler so that the bytes_per_line field will
- be the slot multiplier. If bytes_per_line comes in as zero, it
- is set to six (which is how it was set up initially). -- objdump
- displays pretty disassembly dumps with this value. For our purposes,
- we'll set bytes_per_line to SLOT_MULTIPLIER. This is okay since we
- never want to also display the raw bytes the way objdump does. */
-
-#define SLOT_MULTIPLIER 1
-
-/* Length in bytes of an instruction bundle. */
-
-#define BUNDLE_LEN 16
-
-/* See the saved memory layout comment for ia64_memory_insert_breakpoint. */
-
-#if BREAKPOINT_MAX < BUNDLE_LEN - 2
-# error "BREAKPOINT_MAX < BUNDLE_LEN - 2"
-#endif
-
-static gdbarch_init_ftype ia64_gdbarch_init;
-
-static gdbarch_register_name_ftype ia64_register_name;
-static gdbarch_register_type_ftype ia64_register_type;
-static gdbarch_breakpoint_from_pc_ftype ia64_breakpoint_from_pc;
-static gdbarch_skip_prologue_ftype ia64_skip_prologue;
-static struct type *is_float_or_hfa_type (struct type *t);
-static CORE_ADDR ia64_find_global_pointer (struct gdbarch *gdbarch,
- CORE_ADDR faddr);
-
-#define NUM_IA64_RAW_REGS 462
-
-/* Big enough to hold a FP register in bytes. */
-#define IA64_FP_REGISTER_SIZE 16
-
-static int sp_regnum = IA64_GR12_REGNUM;
-
-/* NOTE: we treat the register stack registers r32-r127 as
- pseudo-registers because they may not be accessible via the ptrace
- register get/set interfaces. */
-
-enum pseudo_regs { FIRST_PSEUDO_REGNUM = NUM_IA64_RAW_REGS,
- VBOF_REGNUM = IA64_NAT127_REGNUM + 1, V32_REGNUM,
- V127_REGNUM = V32_REGNUM + 95,
- VP0_REGNUM, VP16_REGNUM = VP0_REGNUM + 16,
- VP63_REGNUM = VP0_REGNUM + 63, LAST_PSEUDO_REGNUM };
-
-/* Array of register names; There should be ia64_num_regs strings in
- the initializer. */
-
-static const char * const ia64_register_names[] =
-{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
-
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
- "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
- "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
- "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
- "f64", "f65", "f66", "f67", "f68", "f69", "f70", "f71",
- "f72", "f73", "f74", "f75", "f76", "f77", "f78", "f79",
- "f80", "f81", "f82", "f83", "f84", "f85", "f86", "f87",
- "f88", "f89", "f90", "f91", "f92", "f93", "f94", "f95",
- "f96", "f97", "f98", "f99", "f100", "f101", "f102", "f103",
- "f104", "f105", "f106", "f107", "f108", "f109", "f110", "f111",
- "f112", "f113", "f114", "f115", "f116", "f117", "f118", "f119",
- "f120", "f121", "f122", "f123", "f124", "f125", "f126", "f127",
-
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
-
- "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
-
- "vfp", "vrap",
-
- "pr", "ip", "psr", "cfm",
-
- "kr0", "kr1", "kr2", "kr3", "kr4", "kr5", "kr6", "kr7",
- "", "", "", "", "", "", "", "",
- "rsc", "bsp", "bspstore", "rnat",
- "", "fcr", "", "",
- "eflag", "csd", "ssd", "cflg", "fsr", "fir", "fdr", "",
- "ccv", "", "", "", "unat", "", "", "",
- "fpsr", "", "", "", "itc",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "",
- "pfs", "lc", "ec",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "",
- "nat0", "nat1", "nat2", "nat3", "nat4", "nat5", "nat6", "nat7",
- "nat8", "nat9", "nat10", "nat11", "nat12", "nat13", "nat14", "nat15",
- "nat16", "nat17", "nat18", "nat19", "nat20", "nat21", "nat22", "nat23",
- "nat24", "nat25", "nat26", "nat27", "nat28", "nat29", "nat30", "nat31",
- "nat32", "nat33", "nat34", "nat35", "nat36", "nat37", "nat38", "nat39",
- "nat40", "nat41", "nat42", "nat43", "nat44", "nat45", "nat46", "nat47",
- "nat48", "nat49", "nat50", "nat51", "nat52", "nat53", "nat54", "nat55",
- "nat56", "nat57", "nat58", "nat59", "nat60", "nat61", "nat62", "nat63",
- "nat64", "nat65", "nat66", "nat67", "nat68", "nat69", "nat70", "nat71",
- "nat72", "nat73", "nat74", "nat75", "nat76", "nat77", "nat78", "nat79",
- "nat80", "nat81", "nat82", "nat83", "nat84", "nat85", "nat86", "nat87",
- "nat88", "nat89", "nat90", "nat91", "nat92", "nat93", "nat94", "nat95",
- "nat96", "nat97", "nat98", "nat99", "nat100","nat101","nat102","nat103",
- "nat104","nat105","nat106","nat107","nat108","nat109","nat110","nat111",
- "nat112","nat113","nat114","nat115","nat116","nat117","nat118","nat119",
- "nat120","nat121","nat122","nat123","nat124","nat125","nat126","nat127",
-
- "bof",
-
- "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
- "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
- "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
- "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
- "r64", "r65", "r66", "r67", "r68", "r69", "r70", "r71",
- "r72", "r73", "r74", "r75", "r76", "r77", "r78", "r79",
- "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87",
- "r88", "r89", "r90", "r91", "r92", "r93", "r94", "r95",
- "r96", "r97", "r98", "r99", "r100", "r101", "r102", "r103",
- "r104", "r105", "r106", "r107", "r108", "r109", "r110", "r111",
- "r112", "r113", "r114", "r115", "r116", "r117", "r118", "r119",
- "r120", "r121", "r122", "r123", "r124", "r125", "r126", "r127",
-
- "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
- "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
- "p16", "p17", "p18", "p19", "p20", "p21", "p22", "p23",
- "p24", "p25", "p26", "p27", "p28", "p29", "p30", "p31",
- "p32", "p33", "p34", "p35", "p36", "p37", "p38", "p39",
- "p40", "p41", "p42", "p43", "p44", "p45", "p46", "p47",
- "p48", "p49", "p50", "p51", "p52", "p53", "p54", "p55",
- "p56", "p57", "p58", "p59", "p60", "p61", "p62", "p63",
-};
-
-struct ia64_frame_cache
-{
- CORE_ADDR base; /* frame pointer base for frame */
- CORE_ADDR pc; /* function start pc for frame */
- CORE_ADDR saved_sp; /* stack pointer for frame */
- CORE_ADDR bsp; /* points at r32 for the current frame */
- CORE_ADDR cfm; /* cfm value for current frame */
- CORE_ADDR prev_cfm; /* cfm value for previous frame */
- int frameless;
- int sof; /* Size of frame (decoded from cfm value). */
- int sol; /* Size of locals (decoded from cfm value). */
- int sor; /* Number of rotating registers (decoded from
- cfm value). */
- CORE_ADDR after_prologue;
- /* Address of first instruction after the last
- prologue instruction; Note that there may
- be instructions from the function's body
- intermingled with the prologue. */
- int mem_stack_frame_size;
- /* Size of the memory stack frame (may be zero),
- or -1 if it has not been determined yet. */
- int fp_reg; /* Register number (if any) used a frame pointer
- for this frame. 0 if no register is being used
- as the frame pointer. */
-
- /* Saved registers. */
- CORE_ADDR saved_regs[NUM_IA64_RAW_REGS];
-
-};
-
-static int
-floatformat_valid (const struct floatformat *fmt, const void *from)
-{
- return 1;
-}
-
-static const struct floatformat floatformat_ia64_ext_little =
-{
- floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
- floatformat_intbit_yes, "floatformat_ia64_ext_little", floatformat_valid, NULL
-};
-
-static const struct floatformat floatformat_ia64_ext_big =
-{
- floatformat_big, 82, 46, 47, 17, 65535, 0x1ffff, 64, 64,
- floatformat_intbit_yes, "floatformat_ia64_ext_big", floatformat_valid
-};
-
-static const struct floatformat *floatformats_ia64_ext[2] =
-{
- &floatformat_ia64_ext_big,
- &floatformat_ia64_ext_little
-};
-
-static struct type *
-ia64_ext_type (struct gdbarch *gdbarch)
-{
- ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
-
- if (!tdep->ia64_ext_type)
- {
- type_allocator alloc (gdbarch);
- tdep->ia64_ext_type
- = init_float_type (alloc, 128, "builtin_type_ia64_ext",
- floatformats_ia64_ext);
- }
-
- return tdep->ia64_ext_type;
-}
-
-static int
-ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
- const struct reggroup *group)
-{
- int vector_p;
- int float_p;
- int raw_p;
- if (group == all_reggroup)
- return 1;
- vector_p = register_type (gdbarch, regnum)->is_vector ();
- float_p = register_type (gdbarch, regnum)->code () == TYPE_CODE_FLT;
- raw_p = regnum < NUM_IA64_RAW_REGS;
- if (group == float_reggroup)
- return float_p;
- if (group == vector_reggroup)
- return vector_p;
- if (group == general_reggroup)
- return (!vector_p && !float_p);
- if (group == save_reggroup || group == restore_reggroup)
- return raw_p;
- return 0;
-}
-
-static const char *
-ia64_register_name (struct gdbarch *gdbarch, int reg)
-{
- return ia64_register_names[reg];
-}
-
-struct type *
-ia64_register_type (struct gdbarch *arch, int reg)
-{
- if (reg >= IA64_FR0_REGNUM && reg <= IA64_FR127_REGNUM)
- return ia64_ext_type (arch);
- else
- return builtin_type (arch)->builtin_long;
-}
-
-static int
-ia64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
-{
- if (reg >= IA64_GR32_REGNUM && reg <= IA64_GR127_REGNUM)
- return V32_REGNUM + (reg - IA64_GR32_REGNUM);
- return reg;
-}
-
-
-/* Extract ``len'' bits from an instruction bundle starting at
- bit ``from''. */
-
-static long long
-extract_bit_field (const gdb_byte *bundle, int from, int len)
-{
- long long result = 0LL;
- int to = from + len;
- int from_byte = from / 8;
- int to_byte = to / 8;
- unsigned char *b = (unsigned char *) bundle;
- unsigned char c;
- int lshift;
- int i;
-
- c = b[from_byte];
- if (from_byte == to_byte)
- c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
- result = c >> (from % 8);
- lshift = 8 - (from % 8);
-
- for (i = from_byte+1; i < to_byte; i++)
- {
- result |= ((long long) b[i]) << lshift;
- lshift += 8;
- }
-
- if (from_byte < to_byte && (to % 8 != 0))
- {
- c = b[to_byte];
- c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
- result |= ((long long) c) << lshift;
- }
-
- return result;
-}
-
-/* Replace the specified bits in an instruction bundle. */
-
-static void
-replace_bit_field (gdb_byte *bundle, long long val, int from, int len)
-{
- int to = from + len;
- int from_byte = from / 8;
- int to_byte = to / 8;
- unsigned char *b = (unsigned char *) bundle;
- unsigned char c;
-
- if (from_byte == to_byte)
- {
- unsigned char left, right;
- c = b[from_byte];
- left = (c >> (to % 8)) << (to % 8);
- right = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
- c = (unsigned char) (val & 0xff);
- c = (unsigned char) (c << (from % 8 + 8 - to % 8)) >> (8 - to % 8);
- c |= right | left;
- b[from_byte] = c;
- }
- else
- {
- int i;
- c = b[from_byte];
- c = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
- c = c | (val << (from % 8));
- b[from_byte] = c;
- val >>= 8 - from % 8;
-
- for (i = from_byte+1; i < to_byte; i++)
- {
- c = val & 0xff;
- val >>= 8;
- b[i] = c;
- }
-
- if (to % 8 != 0)
- {
- unsigned char cv = (unsigned char) val;
- c = b[to_byte];
- c = c >> (to % 8) << (to % 8);
- c |= ((unsigned char) (cv << (8 - to % 8))) >> (8 - to % 8);
- b[to_byte] = c;
- }
- }
-}
-
-/* Return the contents of slot N (for N = 0, 1, or 2) in
- and instruction bundle. */
-
-static long long
-slotN_contents (gdb_byte *bundle, int slotnum)
-{
- return extract_bit_field (bundle, 5+41*slotnum, 41);
-}
-
-/* Store an instruction in an instruction bundle. */
-
-static void
-replace_slotN_contents (gdb_byte *bundle, long long instr, int slotnum)
-{
- replace_bit_field (bundle, instr, 5+41*slotnum, 41);
-}
-
-static const enum ia64_instruction_type template_encoding_table[32][3] =
-{
- { M, I, I }, /* 00 */
- { M, I, I }, /* 01 */
- { M, I, I }, /* 02 */
- { M, I, I }, /* 03 */
- { M, L, X }, /* 04 */
- { M, L, X }, /* 05 */
- { undefined, undefined, undefined }, /* 06 */
- { undefined, undefined, undefined }, /* 07 */
- { M, M, I }, /* 08 */
- { M, M, I }, /* 09 */
- { M, M, I }, /* 0A */
- { M, M, I }, /* 0B */
- { M, F, I }, /* 0C */
- { M, F, I }, /* 0D */
- { M, M, F }, /* 0E */
- { M, M, F }, /* 0F */
- { M, I, B }, /* 10 */
- { M, I, B }, /* 11 */
- { M, B, B }, /* 12 */
- { M, B, B }, /* 13 */
- { undefined, undefined, undefined }, /* 14 */
- { undefined, undefined, undefined }, /* 15 */
- { B, B, B }, /* 16 */
- { B, B, B }, /* 17 */
- { M, M, B }, /* 18 */
- { M, M, B }, /* 19 */
- { undefined, undefined, undefined }, /* 1A */
- { undefined, undefined, undefined }, /* 1B */
- { M, F, B }, /* 1C */
- { M, F, B }, /* 1D */
- { undefined, undefined, undefined }, /* 1E */
- { undefined, undefined, undefined }, /* 1F */
-};
-
-/* Fetch and (partially) decode an instruction at ADDR and return the
- address of the next instruction to fetch. */
-
-static CORE_ADDR
-fetch_instruction (CORE_ADDR addr, ia64_instruction_type *it, long long *instr)
-{
- gdb_byte bundle[BUNDLE_LEN];
- int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
- long long templ;
- int val;
-
- /* Warn about slot numbers greater than 2. We used to generate
- an error here on the assumption that the user entered an invalid
- address. But, sometimes GDB itself requests an invalid address.
- This can (easily) happen when execution stops in a function for
- which there are no symbols. The prologue scanner will attempt to
- find the beginning of the function - if the nearest symbol
- happens to not be aligned on a bundle boundary (16 bytes), the
- resulting starting address will cause GDB to think that the slot
- number is too large.
-
- So we warn about it and set the slot number to zero. It is
- not necessarily a fatal condition, particularly if debugging
- at the assembly language level. */
- if (slotnum > 2)
- {
- warning (_("Can't fetch instructions for slot numbers greater than 2.\n"
- "Using slot 0 instead"));
- slotnum = 0;
- }
-
- addr &= ~0x0f;
-
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
-
- if (val != 0)
- return 0;
-
- *instr = slotN_contents (bundle, slotnum);
- templ = extract_bit_field (bundle, 0, 5);
- *it = template_encoding_table[(int)templ][slotnum];
-
- if (slotnum == 2 || (slotnum == 1 && *it == L))
- addr += 16;
- else
- addr += (slotnum + 1) * SLOT_MULTIPLIER;
-
- return addr;
-}
-
-/* There are 5 different break instructions (break.i, break.b,
- break.m, break.f, and break.x), but they all have the same
- encoding. (The five bit template in the low five bits of the
- instruction bundle distinguishes one from another.)
-
- The runtime architecture manual specifies that break instructions
- used for debugging purposes must have the upper two bits of the 21
- bit immediate set to a 0 and a 1 respectively. A breakpoint
- instruction encodes the most significant bit of its 21 bit
- immediate at bit 36 of the 41 bit instruction. The penultimate msb
- is at bit 25 which leads to the pattern below.
-
- Originally, I had this set up to do, e.g, a "break.i 0x80000" But
- it turns out that 0x80000 was used as the syscall break in the early
- simulators. So I changed the pattern slightly to do "break.i 0x080001"
- instead. But that didn't work either (I later found out that this
- pattern was used by the simulator that I was using.) So I ended up
- using the pattern seen below.
-
- SHADOW_CONTENTS has byte-based addressing (PLACED_ADDRESS and SHADOW_LEN)
- while we need bit-based addressing as the instructions length is 41 bits and
- we must not modify/corrupt the adjacent slots in the same bundle.
- Fortunately we may store larger memory incl. the adjacent bits with the
- original memory content (not the possibly already stored breakpoints there).
- We need to be careful in ia64_memory_remove_breakpoint to always restore
- only the specific bits of this instruction ignoring any adjacent stored
- bits.
-
- We use the original addressing with the low nibble in the range <0..2> which
- gets incorrectly interpreted by generic non-ia64 breakpoint_restore_shadows
- as the direct byte offset of SHADOW_CONTENTS. We store whole BUNDLE_LEN
- bytes just without these two possibly skipped bytes to not to exceed to the
- next bundle.
-
- If we would like to store the whole bundle to SHADOW_CONTENTS we would have
- to store already the base address (`address & ~0x0f') into PLACED_ADDRESS.
- In such case there is no other place where to store
- SLOTNUM (`adress & 0x0f', value in the range <0..2>). We need to know
- SLOTNUM in ia64_memory_remove_breakpoint.
-
- There is one special case where we need to be extra careful:
- L-X instructions, which are instructions that occupy 2 slots
- (The L part is always in slot 1, and the X part is always in
- slot 2). We must refuse to insert breakpoints for an address
- that points at slot 2 of a bundle where an L-X instruction is
- present, since there is logically no instruction at that address.
- However, to make things more interesting, the opcode of L-X
- instructions is located in slot 2. This means that, to insert
- a breakpoint at an address that points to slot 1, we actually
- need to write the breakpoint in slot 2! Slot 1 is actually
- the extended operand, so writing the breakpoint there would not
- have the desired effect. Another side-effect of this issue
- is that we need to make sure that the shadow contents buffer
- does save byte 15 of our instruction bundle (this is the tail
- end of slot 2, which wouldn't be saved if we were to insert
- the breakpoint in slot 1).
-
- ia64 16-byte bundle layout:
- | 5 bits | slot 0 with 41 bits | slot 1 with 41 bits | slot 2 with 41 bits |
-
- The current addressing used by the code below:
- original PC placed_address placed_size required covered
- == bp_tgt->shadow_len reqd \subset covered
- 0xABCDE0 0xABCDE0 0x10 <0x0...0x5> <0x0..0xF>
- 0xABCDE1 0xABCDE1 0xF <0x5...0xA> <0x1..0xF>
- 0xABCDE2 0xABCDE2 0xE <0xA...0xF> <0x2..0xF>
-
- L-X instructions are treated a little specially, as explained above:
- 0xABCDE1 0xABCDE1 0xF <0xA...0xF> <0x1..0xF>
-
- `objdump -d' and some other tools show a bit unjustified offsets:
- original PC byte where starts the instruction objdump offset
- 0xABCDE0 0xABCDE0 0xABCDE0
- 0xABCDE1 0xABCDE5 0xABCDE6
- 0xABCDE2 0xABCDEA 0xABCDEC
- */
-
-#define IA64_BREAKPOINT 0x00003333300LL
-
-static int
-ia64_memory_insert_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
-{
- CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
- gdb_byte bundle[BUNDLE_LEN];
- int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
- long long instr_breakpoint;
- int val;
- int templ;
-
- if (slotnum > 2)
- error (_("Can't insert breakpoint for slot numbers greater than 2."));
-
- addr &= ~0x0f;
-
- /* Enable the automatic memory restoration from breakpoints while
- we read our instruction bundle for the purpose of SHADOW_CONTENTS.
- Otherwise, we could possibly store into the shadow parts of the adjacent
- placed breakpoints. It is due to our SHADOW_CONTENTS overlapping the real
- breakpoint instruction bits region. */
- scoped_restore restore_memory_0
- = make_scoped_restore_show_memory_breakpoints (0);
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
- if (val != 0)
- return val;
-
- /* SHADOW_SLOTNUM saves the original slot number as expected by the caller
- for addressing the SHADOW_CONTENTS placement. */
- shadow_slotnum = slotnum;
-
- /* Always cover the last byte of the bundle in case we are inserting
- a breakpoint on an L-X instruction. */
- bp_tgt->shadow_len = BUNDLE_LEN - shadow_slotnum;
-
- templ = extract_bit_field (bundle, 0, 5);
- if (template_encoding_table[templ][slotnum] == X)
- {
- /* X unit types can only be used in slot 2, and are actually
- part of a 2-slot L-X instruction. We cannot break at this
- address, as this is the second half of an instruction that
- lives in slot 1 of that bundle. */
- gdb_assert (slotnum == 2);
- error (_("Can't insert breakpoint for non-existing slot X"));
- }
- if (template_encoding_table[templ][slotnum] == L)
- {
- /* L unit types can only be used in slot 1. But the associated
- opcode for that instruction is in slot 2, so bump the slot number
- accordingly. */
- gdb_assert (slotnum == 1);
- slotnum = 2;
- }
-
- /* Store the whole bundle, except for the initial skipped bytes by the slot
- number interpreted as bytes offset in PLACED_ADDRESS. */
- memcpy (bp_tgt->shadow_contents, bundle + shadow_slotnum,
- bp_tgt->shadow_len);
-
- /* Re-read the same bundle as above except that, this time, read it in order
- to compute the new bundle inside which we will be inserting the
- breakpoint. Therefore, disable the automatic memory restoration from
- breakpoints while we read our instruction bundle. Otherwise, the general
- restoration mechanism kicks in and we would possibly remove parts of the
- adjacent placed breakpoints. It is due to our SHADOW_CONTENTS overlapping
- the real breakpoint instruction bits region. */
- scoped_restore restore_memory_1
- = make_scoped_restore_show_memory_breakpoints (1);
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
- if (val != 0)
- return val;
-
- /* Breakpoints already present in the code will get detected and not get
- reinserted by bp_loc_is_permanent. Multiple breakpoints at the same
- location cannot induce the internal error as they are optimized into
- a single instance by update_global_location_list. */
- instr_breakpoint = slotN_contents (bundle, slotnum);
- if (instr_breakpoint == IA64_BREAKPOINT)
- internal_error (_("Address %s already contains a breakpoint."),
- paddress (gdbarch, bp_tgt->placed_address));
- replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
-
- val = target_write_memory (addr + shadow_slotnum, bundle + shadow_slotnum,
- bp_tgt->shadow_len);
-
- return val;
-}
-
-static int
-ia64_memory_remove_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
-{
- CORE_ADDR addr = bp_tgt->placed_address;
- gdb_byte bundle_mem[BUNDLE_LEN], bundle_saved[BUNDLE_LEN];
- int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
- long long instr_breakpoint, instr_saved;
- int val;
- int templ;
-
- addr &= ~0x0f;
-
- /* Disable the automatic memory restoration from breakpoints while
- we read our instruction bundle. Otherwise, the general restoration
- mechanism kicks in and we would possibly remove parts of the adjacent
- placed breakpoints. It is due to our SHADOW_CONTENTS overlapping the real
- breakpoint instruction bits region. */
- scoped_restore restore_memory_1
- = make_scoped_restore_show_memory_breakpoints (1);
- val = target_read_memory (addr, bundle_mem, BUNDLE_LEN);
- if (val != 0)
- return val;
-
- /* SHADOW_SLOTNUM saves the original slot number as expected by the caller
- for addressing the SHADOW_CONTENTS placement. */
- shadow_slotnum = slotnum;
-
- templ = extract_bit_field (bundle_mem, 0, 5);
- if (template_encoding_table[templ][slotnum] == X)
- {
- /* X unit types can only be used in slot 2, and are actually
- part of a 2-slot L-X instruction. We refuse to insert
- breakpoints at this address, so there should be no reason
- for us attempting to remove one there, except if the program's
- code somehow got modified in memory. */
- gdb_assert (slotnum == 2);
- warning (_("Cannot remove breakpoint at address %s from non-existing "
- "X-type slot, memory has changed underneath"),
- paddress (gdbarch, bp_tgt->placed_address));
- return -1;
- }
- if (template_encoding_table[templ][slotnum] == L)
- {
- /* L unit types can only be used in slot 1. But the breakpoint
- was actually saved using slot 2, so update the slot number
- accordingly. */
- gdb_assert (slotnum == 1);
- slotnum = 2;
- }
-
- gdb_assert (bp_tgt->shadow_len == BUNDLE_LEN - shadow_slotnum);
-
- instr_breakpoint = slotN_contents (bundle_mem, slotnum);
- if (instr_breakpoint != IA64_BREAKPOINT)
- {
- warning (_("Cannot remove breakpoint at address %s, "
- "no break instruction at such address."),
- paddress (gdbarch, bp_tgt->placed_address));
- return -1;
- }
-
- /* Extract the original saved instruction from SLOTNUM normalizing its
- bit-shift for INSTR_SAVED. */
- memcpy (bundle_saved, bundle_mem, BUNDLE_LEN);
- memcpy (bundle_saved + shadow_slotnum, bp_tgt->shadow_contents,
- bp_tgt->shadow_len);
- instr_saved = slotN_contents (bundle_saved, slotnum);
-
- /* In BUNDLE_MEM, be careful to modify only the bits belonging to SLOTNUM
- and not any of the other ones that are stored in SHADOW_CONTENTS. */
- replace_slotN_contents (bundle_mem, instr_saved, slotnum);
- val = target_write_raw_memory (addr, bundle_mem, BUNDLE_LEN);
-
- return val;
-}
-
-/* Implement the breakpoint_kind_from_pc gdbarch method. */
-
-static int
-ia64_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
-{
- /* A place holder of gdbarch method breakpoint_kind_from_pc. */
- return 0;
-}
-
-/* As gdbarch_breakpoint_from_pc ranges have byte granularity and ia64
- instruction slots ranges are bit-granular (41 bits) we have to provide an
- extended range as described for ia64_memory_insert_breakpoint. We also take
- care of preserving the `break' instruction 21-bit (or 62-bit) parameter to
- make a match for permanent breakpoints. */
-
-static const gdb_byte *
-ia64_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
-{
- CORE_ADDR addr = *pcptr;
- static gdb_byte bundle[BUNDLE_LEN];
- int slotnum = (int) (*pcptr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
- long long instr_fetched;
- int val;
- int templ;
-
- if (slotnum > 2)
- error (_("Can't insert breakpoint for slot numbers greater than 2."));
-
- addr &= ~0x0f;
-
- /* Enable the automatic memory restoration from breakpoints while
- we read our instruction bundle to match bp_loc_is_permanent. */
- {
- scoped_restore restore_memory_0
- = make_scoped_restore_show_memory_breakpoints (0);
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
- }
-
- /* The memory might be unreachable. This can happen, for instance,
- when the user inserts a breakpoint at an invalid address. */
- if (val != 0)
- return NULL;
-
- /* SHADOW_SLOTNUM saves the original slot number as expected by the caller
- for addressing the SHADOW_CONTENTS placement. */
- shadow_slotnum = slotnum;
-
- /* Cover always the last byte of the bundle for the L-X slot case. */
- *lenptr = BUNDLE_LEN - shadow_slotnum;
-
- /* Check for L type instruction in slot 1, if present then bump up the slot
- number to the slot 2. */
- templ = extract_bit_field (bundle, 0, 5);
- if (template_encoding_table[templ][slotnum] == X)
- {
- gdb_assert (slotnum == 2);
- error (_("Can't insert breakpoint for non-existing slot X"));
- }
- if (template_encoding_table[templ][slotnum] == L)
- {
- gdb_assert (slotnum == 1);
- slotnum = 2;
- }
-
- /* A break instruction has its all its opcode bits cleared except for
- the parameter value. For L+X slot pair we are at the X slot (slot 2) so
- we should not touch the L slot - the upper 41 bits of the parameter. */
- instr_fetched = slotN_contents (bundle, slotnum);
- instr_fetched &= 0x1003ffffc0LL;
- replace_slotN_contents (bundle, instr_fetched, slotnum);
-
- return bundle + shadow_slotnum;
-}
-
-static CORE_ADDR
-ia64_read_pc (readable_regcache *regcache)
-{
- ULONGEST psr_value, pc_value;
- int slot_num;
-
- regcache->cooked_read (IA64_PSR_REGNUM, &psr_value);
- regcache->cooked_read (IA64_IP_REGNUM, &pc_value);
- slot_num = (psr_value >> 41) & 3;
-
- return pc_value | (slot_num * SLOT_MULTIPLIER);
-}
-
-void
-ia64_write_pc (struct regcache *regcache, CORE_ADDR new_pc)
-{
- int slot_num = (int) (new_pc & 0xf) / SLOT_MULTIPLIER;
- ULONGEST psr_value;
-
- regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr_value);
- psr_value &= ~(3LL << 41);
- psr_value |= (ULONGEST)(slot_num & 0x3) << 41;
-
- new_pc &= ~0xfLL;
-
- regcache_cooked_write_unsigned (regcache, IA64_PSR_REGNUM, psr_value);
- regcache_cooked_write_unsigned (regcache, IA64_IP_REGNUM, new_pc);
-}
-
-#define IS_NaT_COLLECTION_ADDR(addr) ((((addr) >> 3) & 0x3f) == 0x3f)
-
-/* Returns the address of the slot that's NSLOTS slots away from
- the address ADDR. NSLOTS may be positive or negative. */
-static CORE_ADDR
-rse_address_add(CORE_ADDR addr, int nslots)
-{
- CORE_ADDR new_addr;
- int mandatory_nat_slots = nslots / 63;
- int direction = nslots < 0 ? -1 : 1;
-
- new_addr = addr + 8 * (nslots + mandatory_nat_slots);
-
- if ((new_addr >> 9) != ((addr + 8 * 64 * mandatory_nat_slots) >> 9))
- new_addr += 8 * direction;
-
- if (IS_NaT_COLLECTION_ADDR(new_addr))
- new_addr += 8 * direction;
-
- return new_addr;
-}
-
-static enum register_status
-ia64_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
- int regnum, gdb_byte *buf)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- enum register_status status;
-
- if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
- {
-#ifdef HAVE_LIBUNWIND_IA64_H
- /* First try and use the libunwind special reg accessor,
- otherwise fallback to standard logic. */
- if (!libunwind_is_initialized ()
- || libunwind_get_reg_special (gdbarch, regcache, regnum, buf) != 0)
-#endif
- {
- /* The fallback position is to assume that r32-r127 are
- found sequentially in memory starting at $bof. This
- isn't always true, but without libunwind, this is the
- best we can do. */
- ULONGEST cfm;
- ULONGEST bsp;
- CORE_ADDR reg;
-
- status = regcache->cooked_read (IA64_BSP_REGNUM, &bsp);
- if (status != REG_VALID)
- return status;
-
- status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
- if (status != REG_VALID)
- return status;
-
- /* The bsp points at the end of the register frame so we
- subtract the size of frame from it to get start of
- register frame. */
- bsp = rse_address_add (bsp, -(cfm & 0x7f));
-
- if ((cfm & 0x7f) > regnum - V32_REGNUM)
- {
- ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
- reg = read_memory_integer ((CORE_ADDR)reg_addr, 8, byte_order);
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, reg);
- }
- else
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, 0);
- }
- }
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
- {
- ULONGEST unatN_val;
- ULONGEST unat;
-
- status = regcache->cooked_read (IA64_UNAT_REGNUM, &unat);
- if (status != REG_VALID)
- return status;
- unatN_val = (unat & (1LL << (regnum - IA64_NAT0_REGNUM))) != 0;
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, unatN_val);
- }
- else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- {
- ULONGEST natN_val = 0;
- ULONGEST bsp;
- ULONGEST cfm;
- CORE_ADDR gr_addr = 0;
-
- status = regcache->cooked_read (IA64_BSP_REGNUM, &bsp);
- if (status != REG_VALID)
- return status;
-
- status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
- if (status != REG_VALID)
- return status;
-
- /* The bsp points at the end of the register frame so we
- subtract the size of frame from it to get start of register frame. */
- bsp = rse_address_add (bsp, -(cfm & 0x7f));
-
- if ((cfm & 0x7f) > regnum - V32_REGNUM)
- gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
-
- if (gr_addr != 0)
- {
- /* Compute address of nat collection bits. */
- CORE_ADDR nat_addr = gr_addr | 0x1f8;
- ULONGEST nat_collection;
- int nat_bit;
- /* If our nat collection address is bigger than bsp, we have to get
- the nat collection from rnat. Otherwise, we fetch the nat
- collection from the computed address. */
- if (nat_addr >= bsp)
- regcache->cooked_read (IA64_RNAT_REGNUM, &nat_collection);
- else
- nat_collection = read_memory_integer (nat_addr, 8, byte_order);
- nat_bit = (gr_addr >> 3) & 0x3f;
- natN_val = (nat_collection >> nat_bit) & 1;
- }
-
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, natN_val);
- }
- else if (regnum == VBOF_REGNUM)
- {
- /* A virtual register frame start is provided for user convenience.
- It can be calculated as the bsp - sof (sizeof frame). */
- ULONGEST bsp, vbsp;
- ULONGEST cfm;
-
- status = regcache->cooked_read (IA64_BSP_REGNUM, &bsp);
- if (status != REG_VALID)
- return status;
- status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
- if (status != REG_VALID)
- return status;
-
- /* The bsp points at the end of the register frame so we
- subtract the size of frame from it to get beginning of frame. */
- vbsp = rse_address_add (bsp, -(cfm & 0x7f));
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, vbsp);
- }
- else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- ULONGEST pr;
- ULONGEST cfm;
- ULONGEST prN_val;
-
- status = regcache->cooked_read (IA64_PR_REGNUM, &pr);
- if (status != REG_VALID)
- return status;
- status = regcache->cooked_read (IA64_CFM_REGNUM, &cfm);
- if (status != REG_VALID)
- return status;
-
- if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- /* Fetch predicate register rename base from current frame
- marker for this frame. */
- int rrb_pr = (cfm >> 32) & 0x3f;
-
- /* Adjust the register number to account for register rotation. */
- regnum = VP16_REGNUM
- + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
- }
- prN_val = (pr & (1LL << (regnum - VP0_REGNUM))) != 0;
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, prN_val);
- }
- else
- memset (buf, 0, register_size (gdbarch, regnum));
-
- return REG_VALID;
-}
-
-static void
-ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, const gdb_byte *buf)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-
- if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
- {
- ULONGEST bsp;
- ULONGEST cfm;
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
-
- bsp = rse_address_add (bsp, -(cfm & 0x7f));
-
- if ((cfm & 0x7f) > regnum - V32_REGNUM)
- {
- ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
- write_memory (reg_addr, buf, 8);
- }
- }
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
- {
- ULONGEST unatN_val, unat, unatN_mask;
- regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
- unatN_val = extract_unsigned_integer (buf, register_size (gdbarch,
- regnum),
- byte_order);
- unatN_mask = (1LL << (regnum - IA64_NAT0_REGNUM));
- if (unatN_val == 0)
- unat &= ~unatN_mask;
- else if (unatN_val == 1)
- unat |= unatN_mask;
- regcache_cooked_write_unsigned (regcache, IA64_UNAT_REGNUM, unat);
- }
- else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- {
- ULONGEST natN_val;
- ULONGEST bsp;
- ULONGEST cfm;
- CORE_ADDR gr_addr = 0;
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
-
- /* The bsp points at the end of the register frame so we
- subtract the size of frame from it to get start of register frame. */
- bsp = rse_address_add (bsp, -(cfm & 0x7f));
-
- if ((cfm & 0x7f) > regnum - V32_REGNUM)
- gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
-
- natN_val = extract_unsigned_integer (buf, register_size (gdbarch,
- regnum),
- byte_order);
-
- if (gr_addr != 0 && (natN_val == 0 || natN_val == 1))
- {
- /* Compute address of nat collection bits. */
- CORE_ADDR nat_addr = gr_addr | 0x1f8;
- CORE_ADDR nat_collection;
- int natN_bit = (gr_addr >> 3) & 0x3f;
- ULONGEST natN_mask = (1LL << natN_bit);
- /* If our nat collection address is bigger than bsp, we have to get
- the nat collection from rnat. Otherwise, we fetch the nat
- collection from the computed address. */
- if (nat_addr >= bsp)
- {
- regcache_cooked_read_unsigned (regcache,
- IA64_RNAT_REGNUM,
- &nat_collection);
- if (natN_val)
- nat_collection |= natN_mask;
- else
- nat_collection &= ~natN_mask;
- regcache_cooked_write_unsigned (regcache, IA64_RNAT_REGNUM,
- nat_collection);
- }
- else
- {
- gdb_byte nat_buf[8];
- nat_collection = read_memory_integer (nat_addr, 8, byte_order);
- if (natN_val)
- nat_collection |= natN_mask;
- else
- nat_collection &= ~natN_mask;
- store_unsigned_integer (nat_buf, register_size (gdbarch, regnum),
- byte_order, nat_collection);
- write_memory (nat_addr, nat_buf, 8);
- }
- }
- }
- else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- ULONGEST pr;
- ULONGEST cfm;
- ULONGEST prN_val;
- ULONGEST prN_mask;
-
- regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
-
- if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- /* Fetch predicate register rename base from current frame
- marker for this frame. */
- int rrb_pr = (cfm >> 32) & 0x3f;
-
- /* Adjust the register number to account for register rotation. */
- regnum = VP16_REGNUM
- + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
- }
- prN_val = extract_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order);
- prN_mask = (1LL << (regnum - VP0_REGNUM));
- if (prN_val == 0)
- pr &= ~prN_mask;
- else if (prN_val == 1)
- pr |= prN_mask;
- regcache_cooked_write_unsigned (regcache, IA64_PR_REGNUM, pr);
- }
-}
-
-/* The ia64 needs to convert between various ieee floating-point formats
- and the special ia64 floating point register format. */
-
-static int
-ia64_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type)
-{
- return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM
- && type->code () == TYPE_CODE_FLT
- && type != ia64_ext_type (gdbarch));
-}
-
-static int
-ia64_register_to_value (const frame_info_ptr &frame, int regnum,
- struct type *valtype, gdb_byte *out,
- int *optimizedp, int *unavailablep)
-{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte in[IA64_FP_REGISTER_SIZE];
-
- /* Convert to TYPE. */
- auto in_view = gdb::make_array_view (in, register_size (gdbarch, regnum));
- frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame);
- if (!get_frame_register_bytes (next_frame, regnum, 0, in_view, optimizedp,
- unavailablep))
- return 0;
-
- target_float_convert (in, ia64_ext_type (gdbarch), out, valtype);
- *optimizedp = *unavailablep = 0;
- return 1;
-}
-
-static void
-ia64_value_to_register (const frame_info_ptr &frame, int regnum,
- struct type *valtype, const gdb_byte *in)
-{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte out[IA64_FP_REGISTER_SIZE];
- type *to_type = ia64_ext_type (gdbarch);
- target_float_convert (in, valtype, out, to_type);
- auto out_view = gdb::make_array_view (out, to_type->length ());
- put_frame_register (get_next_frame_sentinel_okay (frame), regnum, out_view);
-}
-
-
-/* Limit the number of skipped non-prologue instructions since examining
- of the prologue is expensive. */
-static int max_skip_non_prologue_insns = 40;
-
-/* Given PC representing the starting address of a function, and
- LIM_PC which is the (sloppy) limit to which to scan when looking
- for a prologue, attempt to further refine this limit by using
- the line data in the symbol table. If successful, a better guess
- on where the prologue ends is returned, otherwise the previous
- value of lim_pc is returned. TRUST_LIMIT is a pointer to a flag
- which will be set to indicate whether the returned limit may be
- used with no further scanning in the event that the function is
- frameless. */
-
-/* FIXME: cagney/2004-02-14: This function and logic have largely been
- superseded by skip_prologue_using_sal. */
-
-static CORE_ADDR
-refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit)
-{
- struct symtab_and_line prologue_sal;
- CORE_ADDR start_pc = pc;
- CORE_ADDR end_pc;
-
- /* The prologue can not possibly go past the function end itself,
- so we can already adjust LIM_PC accordingly. */
- if (find_pc_partial_function (pc, NULL, NULL, &end_pc) && end_pc < lim_pc)
- lim_pc = end_pc;
-
- /* Start off not trusting the limit. */
- *trust_limit = 0;
-
- prologue_sal = find_pc_line (pc, 0);
- if (prologue_sal.line != 0)
- {
- int i;
- CORE_ADDR addr = prologue_sal.end;
-
- /* Handle the case in which compiler's optimizer/scheduler
- has moved instructions into the prologue. We scan ahead
- in the function looking for address ranges whose corresponding
- line number is less than or equal to the first one that we
- found for the function. (It can be less than when the
- scheduler puts a body instruction before the first prologue
- instruction.) */
- for (i = 2 * max_skip_non_prologue_insns;
- i > 0 && (lim_pc == 0 || addr < lim_pc);
- i--)
- {
- struct symtab_and_line sal;
-
- sal = find_pc_line (addr, 0);
- if (sal.line == 0)
- break;
- if (sal.line <= prologue_sal.line
- && sal.symtab == prologue_sal.symtab)
- {
- prologue_sal = sal;
- }
- addr = sal.end;
- }
-
- if (lim_pc == 0 || prologue_sal.end < lim_pc)
- {
- lim_pc = prologue_sal.end;
- if (start_pc == get_pc_function_start (lim_pc))
- *trust_limit = 1;
- }
- }
- return lim_pc;
-}
-
-#define isScratch(_regnum_) ((_regnum_) == 2 || (_regnum_) == 3 \
- || (8 <= (_regnum_) && (_regnum_) <= 11) \
- || (14 <= (_regnum_) && (_regnum_) <= 31))
-#define imm9(_instr_) \
- ( ((((_instr_) & 0x01000000000LL) ? -1 : 0) << 8) \
- | (((_instr_) & 0x00008000000LL) >> 20) \
- | (((_instr_) & 0x00000001fc0LL) >> 6))
-
-/* Allocate and initialize a frame cache. */
-
-static struct ia64_frame_cache *
-ia64_alloc_frame_cache (void)
-{
- struct ia64_frame_cache *cache;
- int i;
-
- cache = FRAME_OBSTACK_ZALLOC (struct ia64_frame_cache);
-
- /* Base address. */
- cache->base = 0;
- cache->pc = 0;
- cache->cfm = 0;
- cache->prev_cfm = 0;
- cache->sof = 0;
- cache->sol = 0;
- cache->sor = 0;
- cache->bsp = 0;
- cache->fp_reg = 0;
- cache->frameless = 1;
-
- for (i = 0; i < NUM_IA64_RAW_REGS; i++)
- cache->saved_regs[i] = 0;
-
- return cache;
-}
-
-static CORE_ADDR
-examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
- const frame_info_ptr &this_frame,
- struct ia64_frame_cache *cache)
-{
- CORE_ADDR next_pc;
- CORE_ADDR last_prologue_pc = pc;
- ia64_instruction_type it;
- long long instr;
- int cfm_reg = 0;
- int ret_reg = 0;
- int fp_reg = 0;
- int unat_save_reg = 0;
- int pr_save_reg = 0;
- int mem_stack_frame_size = 0;
- int spill_reg = 0;
- CORE_ADDR spill_addr = 0;
- char instores[8];
- char infpstores[8];
- char reg_contents[256];
- int trust_limit;
- int frameless = 1;
- int i;
- CORE_ADDR addr;
- gdb_byte buf[8];
- CORE_ADDR bof, sor, sol, sof, cfm, rrb_gr;
-
- memset (instores, 0, sizeof instores);
- memset (infpstores, 0, sizeof infpstores);
- memset (reg_contents, 0, sizeof reg_contents);
-
- if (cache->after_prologue != 0
- && cache->after_prologue <= lim_pc)
- return cache->after_prologue;
-
- lim_pc = refine_prologue_limit (pc, lim_pc, &trust_limit);
- next_pc = fetch_instruction (pc, &it, &instr);
-
- /* We want to check if we have a recognizable function start before we
- look ahead for a prologue. */
- if (pc < lim_pc && next_pc
- && it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL))
- {
- /* alloc - start of a regular function. */
- int sol_bits = (int) ((instr & 0x00007f00000LL) >> 20);
- int sof_bits = (int) ((instr & 0x000000fe000LL) >> 13);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
-
- /* Verify that the current cfm matches what we think is the
- function start. If we have somehow jumped within a function,
- we do not want to interpret the prologue and calculate the
- addresses of various registers such as the return address.
- We will instead treat the frame as frameless. */
- if (!this_frame ||
- (sof_bits == (cache->cfm & 0x7f) &&
- sol_bits == ((cache->cfm >> 7) & 0x7f)))
- frameless = 0;
-
- cfm_reg = rN;
- last_prologue_pc = next_pc;
- pc = next_pc;
- }
- else
- {
- /* Look for a leaf routine. */
- if (pc < lim_pc && next_pc
- && (it == I || it == M)
- && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
- {
- /* adds rN = imm14, rM (or mov rN, rM when imm14 is 0) */
- int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13)
- | ((instr & 0x001f8000000LL) >> 20)
- | ((instr & 0x000000fe000LL) >> 13));
- int rM = (int) ((instr & 0x00007f00000LL) >> 20);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && rN == 2 && imm == 0 && rM == 12 && fp_reg == 0)
- {
- /* mov r2, r12 - beginning of leaf routine. */
- fp_reg = rN;
- last_prologue_pc = next_pc;
- }
- }
-
- /* If we don't recognize a regular function or leaf routine, we are
- done. */
- if (!fp_reg)
- {
- pc = lim_pc;
- if (trust_limit)
- last_prologue_pc = lim_pc;
- }
- }
-
- /* Loop, looking for prologue instructions, keeping track of
- where preserved registers were spilled. */
- while (pc < lim_pc)
- {
- next_pc = fetch_instruction (pc, &it, &instr);
- if (next_pc == 0)
- break;
-
- if (it == B && ((instr & 0x1e1f800003fLL) != 0x04000000000LL))
- {
- /* Exit loop upon hitting a non-nop branch instruction. */
- if (trust_limit)
- lim_pc = pc;
- break;
- }
- else if (((instr & 0x3fLL) != 0LL) &&
- (frameless || ret_reg != 0))
- {
- /* Exit loop upon hitting a predicated instruction if
- we already have the return register or if we are frameless. */
- if (trust_limit)
- lim_pc = pc;
- break;
- }
- else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL))
- {
- /* Move from BR */
- int b2 = (int) ((instr & 0x0000000e000LL) >> 13);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003f);
-
- if (qp == 0 && b2 == 0 && rN >= 32 && ret_reg == 0)
- {
- ret_reg = rN;
- last_prologue_pc = next_pc;
- }
- }
- else if ((it == I || it == M)
- && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
- {
- /* adds rN = imm14, rM (or mov rN, rM when imm14 is 0) */
- int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13)
- | ((instr & 0x001f8000000LL) >> 20)
- | ((instr & 0x000000fe000LL) >> 13));
- int rM = (int) ((instr & 0x00007f00000LL) >> 20);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003fLL);
-
- if (qp == 0 && rN >= 32 && imm == 0 && rM == 12 && fp_reg == 0)
- {
- /* mov rN, r12 */
- fp_reg = rN;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && rN == 12 && rM == 12)
- {
- /* adds r12, -mem_stack_frame_size, r12 */
- mem_stack_frame_size -= imm;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && rN == 2
- && ((rM == fp_reg && fp_reg != 0) || rM == 12))
- {
- CORE_ADDR saved_sp = 0;
- /* adds r2, spilloffset, rFramePointer
- or
- adds r2, spilloffset, r12
-
- Get ready for stf.spill or st8.spill instructions.
- The address to start spilling at is loaded into r2.
- FIXME: Why r2? That's what gcc currently uses; it
- could well be different for other compilers. */
-
- /* Hmm... whether or not this will work will depend on
- where the pc is. If it's still early in the prologue
- this'll be wrong. FIXME */
- if (this_frame)
- saved_sp = get_frame_register_unsigned (this_frame,
- sp_regnum);
- spill_addr = saved_sp
- + (rM == 12 ? 0 : mem_stack_frame_size)
- + imm;
- spill_reg = rN;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM-32] &&
- rN < 256 && imm == 0)
- {
- /* mov rN, rM where rM is an input register. */
- reg_contents[rN] = rM;
- last_prologue_pc = next_pc;
- }
- else if (frameless && qp == 0 && rN == fp_reg && imm == 0 &&
- rM == 2)
- {
- /* mov r12, r2 */
- last_prologue_pc = next_pc;
- break;
- }
- }
- else if (it == M
- && ( ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
- || ((instr & 0x1ffc8000000LL) == 0x0cec0000000LL) ))
- {
- /* stf.spill [rN] = fM, imm9
- or
- stf.spill [rN] = fM */
-
- int imm = imm9(instr);
- int rN = (int) ((instr & 0x00007f00000LL) >> 20);
- int fM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && rN == spill_reg && spill_addr != 0
- && ((2 <= fM && fM <= 5) || (16 <= fM && fM <= 31)))
- {
- cache->saved_regs[IA64_FR0_REGNUM + fM] = spill_addr;
-
- if ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
- spill_addr += imm;
- else
- spill_addr = 0; /* last one; must be done. */
- last_prologue_pc = next_pc;
- }
- }
- else if ((it == M && ((instr & 0x1eff8000000LL) == 0x02110000000LL))
- || (it == I && ((instr & 0x1eff8000000LL) == 0x00050000000LL)) )
- {
- /* mov.m rN = arM
- or
- mov.i rN = arM */
-
- int arM = (int) ((instr & 0x00007f00000LL) >> 20);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && isScratch (rN) && arM == 36 /* ar.unat */)
- {
- /* We have something like "mov.m r3 = ar.unat". Remember the
- r3 (or whatever) and watch for a store of this register... */
- unat_save_reg = rN;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == I && ((instr & 0x1eff8000000LL) == 0x00198000000LL))
- {
- /* mov rN = pr */
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && isScratch (rN))
- {
- pr_save_reg = rN;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == M
- && ( ((instr & 0x1ffc8000000LL) == 0x08cc0000000LL)
- || ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)))
- {
- /* st8 [rN] = rM
- or
- st8 [rN] = rM, imm9 */
- int rN = (int) ((instr & 0x00007f00000LL) >> 20);
- int rM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- int indirect = rM < 256 ? reg_contents[rM] : 0;
- if (qp == 0 && rN == spill_reg && spill_addr != 0
- && (rM == unat_save_reg || rM == pr_save_reg))
- {
- /* We've found a spill of either the UNAT register or the PR
- register. (Well, not exactly; what we've actually found is
- a spill of the register that UNAT or PR was moved to).
- Record that fact and move on... */
- if (rM == unat_save_reg)
- {
- /* Track UNAT register. */
- cache->saved_regs[IA64_UNAT_REGNUM] = spill_addr;
- unat_save_reg = 0;
- }
- else
- {
- /* Track PR register. */
- cache->saved_regs[IA64_PR_REGNUM] = spill_addr;
- pr_save_reg = 0;
- }
- if ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)
- /* st8 [rN] = rM, imm9 */
- spill_addr += imm9(instr);
- else
- spill_addr = 0; /* Must be done spilling. */
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
- {
- /* Allow up to one store of each input register. */
- instores[rM-32] = 1;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && 32 <= indirect && indirect < 40 &&
- !instores[indirect-32])
- {
- /* Allow an indirect store of an input register. */
- instores[indirect-32] = 1;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == M && ((instr & 0x1ff08000000LL) == 0x08c00000000LL))
- {
- /* One of
- st1 [rN] = rM
- st2 [rN] = rM
- st4 [rN] = rM
- st8 [rN] = rM
- Note that the st8 case is handled in the clause above.
-
- Advance over stores of input registers. One store per input
- register is permitted. */
- int rM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- int indirect = rM < 256 ? reg_contents[rM] : 0;
- if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
- {
- instores[rM-32] = 1;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && 32 <= indirect && indirect < 40 &&
- !instores[indirect-32])
- {
- /* Allow an indirect store of an input register. */
- instores[indirect-32] = 1;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == M && ((instr & 0x1ff88000000LL) == 0x0cc80000000LL))
- {
- /* Either
- stfs [rN] = fM
- or
- stfd [rN] = fM
-
- Advance over stores of floating point input registers. Again
- one store per register is permitted. */
- int fM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && 8 <= fM && fM < 16 && !infpstores[fM - 8])
- {
- infpstores[fM-8] = 1;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == M
- && ( ((instr & 0x1ffc8000000LL) == 0x08ec0000000LL)
- || ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)))
- {
- /* st8.spill [rN] = rM
- or
- st8.spill [rN] = rM, imm9 */
- int rN = (int) ((instr & 0x00007f00000LL) >> 20);
- int rM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && rN == spill_reg && 4 <= rM && rM <= 7)
- {
- /* We've found a spill of one of the preserved general purpose
- regs. Record the spill address and advance the spill
- register if appropriate. */
- cache->saved_regs[IA64_GR0_REGNUM + rM] = spill_addr;
- if ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)
- /* st8.spill [rN] = rM, imm9 */
- spill_addr += imm9(instr);
- else
- spill_addr = 0; /* Done spilling. */
- last_prologue_pc = next_pc;
- }
- }
-
- pc = next_pc;
- }
-
- /* If not frameless and we aren't called by skip_prologue, then we need
- to calculate registers for the previous frame which will be needed
- later. */
-
- if (!frameless && this_frame)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-
- /* Extract the size of the rotating portion of the stack
- frame and the register rename base from the current
- frame marker. */
- cfm = cache->cfm;
- sor = cache->sor;
- sof = cache->sof;
- sol = cache->sol;
- rrb_gr = (cfm >> 18) & 0x7f;
-
- /* Find the bof (beginning of frame). */
- bof = rse_address_add (cache->bsp, -sof);
-
- for (i = 0, addr = bof;
- i < sof;
- i++, addr += 8)
- {
- if (IS_NaT_COLLECTION_ADDR (addr))
- {
- addr += 8;
- }
- if (i+32 == cfm_reg)
- cache->saved_regs[IA64_CFM_REGNUM] = addr;
- if (i+32 == ret_reg)
- cache->saved_regs[IA64_VRAP_REGNUM] = addr;
- if (i+32 == fp_reg)
- cache->saved_regs[IA64_VFP_REGNUM] = addr;
- }
-
- /* For the previous argument registers we require the previous bof.
- If we can't find the previous cfm, then we can do nothing. */
- cfm = 0;
- if (cache->saved_regs[IA64_CFM_REGNUM] != 0)
- {
- cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM],
- 8, byte_order);
- }
- else if (cfm_reg != 0)
- {
- get_frame_register (this_frame, cfm_reg, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
- }
- cache->prev_cfm = cfm;
-
- if (cfm != 0)
- {
- sor = ((cfm >> 14) & 0xf) * 8;
- sof = (cfm & 0x7f);
- sol = (cfm >> 7) & 0x7f;
- rrb_gr = (cfm >> 18) & 0x7f;
-
- /* The previous bof only requires subtraction of the sol (size of
- locals) due to the overlap between output and input of
- subsequent frames. */
- bof = rse_address_add (bof, -sol);
-
- for (i = 0, addr = bof;
- i < sof;
- i++, addr += 8)
- {
- if (IS_NaT_COLLECTION_ADDR (addr))
- {
- addr += 8;
- }
- if (i < sor)
- cache->saved_regs[IA64_GR32_REGNUM
- + ((i + (sor - rrb_gr)) % sor)]
- = addr;
- else
- cache->saved_regs[IA64_GR32_REGNUM + i] = addr;
- }
-
- }
- }
-
- /* Try and trust the lim_pc value whenever possible. */
- if (trust_limit && lim_pc >= last_prologue_pc)
- last_prologue_pc = lim_pc;
-
- cache->frameless = frameless;
- cache->after_prologue = last_prologue_pc;
- cache->mem_stack_frame_size = mem_stack_frame_size;
- cache->fp_reg = fp_reg;
-
- return last_prologue_pc;
-}
-
-CORE_ADDR
-ia64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
-{
- struct ia64_frame_cache cache;
- cache.base = 0;
- cache.after_prologue = 0;
- cache.cfm = 0;
- cache.bsp = 0;
-
- /* Call examine_prologue with - as third argument since we don't
- have a next frame pointer to send. */
- return examine_prologue (pc, pc+1024, 0, &cache);
-}
-
-
-/* Normal frames. */
-
-static struct ia64_frame_cache *
-ia64_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct ia64_frame_cache *cache;
- gdb_byte buf[8];
- CORE_ADDR cfm;
-
- if (*this_cache)
- return (struct ia64_frame_cache *) *this_cache;
-
- cache = ia64_alloc_frame_cache ();
- *this_cache = cache;
-
- get_frame_register (this_frame, sp_regnum, buf);
- cache->saved_sp = extract_unsigned_integer (buf, 8, byte_order);
-
- /* We always want the bsp to point to the end of frame.
- This way, we can always get the beginning of frame (bof)
- by subtracting frame size. */
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- cache->bsp = extract_unsigned_integer (buf, 8, byte_order);
-
- get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
-
- get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
-
- cache->sof = (cfm & 0x7f);
- cache->sol = (cfm >> 7) & 0x7f;
- cache->sor = ((cfm >> 14) & 0xf) * 8;
-
- cache->cfm = cfm;
-
- cache->pc = get_frame_func (this_frame);
-
- if (cache->pc != 0)
- examine_prologue (cache->pc, get_frame_pc (this_frame), this_frame, cache);
-
- cache->base = cache->saved_sp + cache->mem_stack_frame_size;
-
- return cache;
-}
-
-static void
-ia64_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
- struct frame_id *this_id)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct ia64_frame_cache *cache =
- ia64_frame_cache (this_frame, this_cache);
-
- /* If outermost frame, mark with null frame id. */
- if (cache->base != 0)
- (*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp);
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog,
- "regular frame id: code %s, stack %s, "
- "special %s, this_frame %s\n",
- paddress (gdbarch, this_id->code_addr),
- paddress (gdbarch, this_id->stack_addr),
- paddress (gdbarch, cache->bsp),
- host_address_to_string (this_frame.get ()));
-}
-
-static struct value *
-ia64_frame_prev_register (const frame_info_ptr &this_frame, void **this_cache,
- int regnum)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
- gdb_byte buf[8];
-
- gdb_assert (regnum >= 0);
-
- if (!target_has_registers ())
- error (_("No registers."));
-
- if (regnum == gdbarch_sp_regnum (gdbarch))
- return frame_unwind_got_constant (this_frame, regnum, cache->base);
-
- else if (regnum == IA64_BSP_REGNUM)
- {
- struct value *val;
- CORE_ADDR prev_cfm, bsp, prev_bsp;
-
- /* We want to calculate the previous bsp as the end of the previous
- register stack frame. This corresponds to what the hardware bsp
- register will be if we pop the frame back which is why we might
- have been called. We know the beginning of the current frame is
- cache->bsp - cache->sof. This value in the previous frame points
- to the start of the output registers. We can calculate the end of
- that frame by adding the size of output:
- (sof (size of frame) - sol (size of locals)). */
- val = ia64_frame_prev_register (this_frame, this_cache, IA64_CFM_REGNUM);
- prev_cfm = extract_unsigned_integer (val->contents_all ().data (),
- 8, byte_order);
- bsp = rse_address_add (cache->bsp, -(cache->sof));
- prev_bsp =
- rse_address_add (bsp, (prev_cfm & 0x7f) - ((prev_cfm >> 7) & 0x7f));
-
- return frame_unwind_got_constant (this_frame, regnum, prev_bsp);
- }
-
- else if (regnum == IA64_CFM_REGNUM)
- {
- CORE_ADDR addr = cache->saved_regs[IA64_CFM_REGNUM];
-
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
-
- if (cache->prev_cfm)
- return frame_unwind_got_constant (this_frame, regnum, cache->prev_cfm);
-
- if (cache->frameless)
- return frame_unwind_got_register (this_frame, IA64_PFS_REGNUM,
- IA64_PFS_REGNUM);
- return frame_unwind_got_register (this_frame, regnum, 0);
- }
-
- else if (regnum == IA64_VFP_REGNUM)
- {
- /* If the function in question uses an automatic register (r32-r127)
- for the frame pointer, it'll be found by ia64_find_saved_register()
- above. If the function lacks one of these frame pointers, we can
- still provide a value since we know the size of the frame. */
- return frame_unwind_got_constant (this_frame, regnum, cache->base);
- }
-
- else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- struct value *pr_val;
- ULONGEST prN;
-
- pr_val = ia64_frame_prev_register (this_frame, this_cache,
- IA64_PR_REGNUM);
- if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- /* Fetch predicate register rename base from current frame
- marker for this frame. */
- int rrb_pr = (cache->cfm >> 32) & 0x3f;
-
- /* Adjust the register number to account for register rotation. */
- regnum = VP16_REGNUM + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
- }
- prN = extract_bit_field (pr_val->contents_all ().data (),
- regnum - VP0_REGNUM, 1);
- return frame_unwind_got_constant (this_frame, regnum, prN);
- }
-
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
- {
- struct value *unat_val;
- ULONGEST unatN;
- unat_val = ia64_frame_prev_register (this_frame, this_cache,
- IA64_UNAT_REGNUM);
- unatN = extract_bit_field (unat_val->contents_all ().data (),
- regnum - IA64_NAT0_REGNUM, 1);
- return frame_unwind_got_constant (this_frame, regnum, unatN);
- }
-
- else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- {
- int natval = 0;
- /* Find address of general register corresponding to nat bit we're
- interested in. */
- CORE_ADDR gr_addr;
-
- gr_addr = cache->saved_regs[regnum - IA64_NAT0_REGNUM + IA64_GR0_REGNUM];
-
- if (gr_addr != 0)
- {
- /* Compute address of nat collection bits. */
- CORE_ADDR nat_addr = gr_addr | 0x1f8;
- CORE_ADDR bsp;
- CORE_ADDR nat_collection;
- int nat_bit;
-
- /* If our nat collection address is bigger than bsp, we have to get
- the nat collection from rnat. Otherwise, we fetch the nat
- collection from the computed address. */
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
- if (nat_addr >= bsp)
- {
- get_frame_register (this_frame, IA64_RNAT_REGNUM, buf);
- nat_collection = extract_unsigned_integer (buf, 8, byte_order);
- }
- else
- nat_collection = read_memory_integer (nat_addr, 8, byte_order);
- nat_bit = (gr_addr >> 3) & 0x3f;
- natval = (nat_collection >> nat_bit) & 1;
- }
-
- return frame_unwind_got_constant (this_frame, regnum, natval);
- }
-
- else if (regnum == IA64_IP_REGNUM)
- {
- CORE_ADDR pc = 0;
- CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
-
- if (addr != 0)
- {
- read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
- pc = extract_unsigned_integer (buf, 8, byte_order);
- }
- else if (cache->frameless)
- {
- get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
- pc = extract_unsigned_integer (buf, 8, byte_order);
- }
- pc &= ~0xf;
- return frame_unwind_got_constant (this_frame, regnum, pc);
- }
-
- else if (regnum == IA64_PSR_REGNUM)
- {
- /* We don't know how to get the complete previous PSR, but we need it
- for the slot information when we unwind the pc (pc is formed of IP
- register plus slot information from PSR). To get the previous
- slot information, we mask it off the return address. */
- ULONGEST slot_num = 0;
- CORE_ADDR pc = 0;
- CORE_ADDR psr = 0;
- CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
-
- get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
-
- if (addr != 0)
- {
- read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
- pc = extract_unsigned_integer (buf, 8, byte_order);
- }
- else if (cache->frameless)
- {
- get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
- pc = extract_unsigned_integer (buf, 8, byte_order);
- }
- psr &= ~(3LL << 41);
- slot_num = pc & 0x3LL;
- psr |= (CORE_ADDR)slot_num << 41;
- return frame_unwind_got_constant (this_frame, regnum, psr);
- }
-
- else if (regnum == IA64_BR0_REGNUM)
- {
- CORE_ADDR addr = cache->saved_regs[IA64_BR0_REGNUM];
-
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
-
- return frame_unwind_got_constant (this_frame, regnum, 0);
- }
-
- else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM)
- || (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
- {
- CORE_ADDR addr = 0;
-
- if (regnum >= V32_REGNUM)
- regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
- addr = cache->saved_regs[regnum];
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
-
- if (cache->frameless)
- {
- struct value *reg_val;
- CORE_ADDR prev_cfm, prev_bsp, prev_bof;
-
- /* FIXME: brobecker/2008-05-01: Doesn't this seem redundant
- with the same code above? */
- if (regnum >= V32_REGNUM)
- regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
- reg_val = ia64_frame_prev_register (this_frame, this_cache,
- IA64_CFM_REGNUM);
- prev_cfm = extract_unsigned_integer
- (reg_val->contents_all ().data (), 8, byte_order);
- reg_val = ia64_frame_prev_register (this_frame, this_cache,
- IA64_BSP_REGNUM);
- prev_bsp = extract_unsigned_integer
- (reg_val->contents_all ().data (), 8, byte_order);
- prev_bof = rse_address_add (prev_bsp, -(prev_cfm & 0x7f));
-
- addr = rse_address_add (prev_bof, (regnum - IA64_GR32_REGNUM));
- return frame_unwind_got_memory (this_frame, regnum, addr);
- }
-
- return frame_unwind_got_constant (this_frame, regnum, 0);
- }
-
- else /* All other registers. */
- {
- CORE_ADDR addr = 0;
-
- if (IA64_FR32_REGNUM <= regnum && regnum <= IA64_FR127_REGNUM)
- {
- /* Fetch floating point register rename base from current
- frame marker for this frame. */
- int rrb_fr = (cache->cfm >> 25) & 0x7f;
-
- /* Adjust the floating point register number to account for
- register rotation. */
- regnum = IA64_FR32_REGNUM
- + ((regnum - IA64_FR32_REGNUM) + rrb_fr) % 96;
- }
-
- /* If we have stored a memory address, access the register. */
- addr = cache->saved_regs[regnum];
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
- /* Otherwise, punt and get the current value of the register. */
- else
- return frame_unwind_got_register (this_frame, regnum, regnum);
- }
-}
-
-static const struct frame_unwind ia64_frame_unwind =
-{
- "ia64 prologue",
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- &ia64_frame_this_id,
- &ia64_frame_prev_register,
- NULL,
- default_frame_sniffer
-};
-
-/* Signal trampolines. */
-
-static void
-ia64_sigtramp_frame_init_saved_regs (const frame_info_ptr &this_frame,
- struct ia64_frame_cache *cache)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
-
- if (tdep->sigcontext_register_address)
- {
- int regno;
-
- cache->saved_regs[IA64_VRAP_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_IP_REGNUM);
- cache->saved_regs[IA64_CFM_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_CFM_REGNUM);
- cache->saved_regs[IA64_PSR_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_PSR_REGNUM);
- cache->saved_regs[IA64_BSP_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_BSP_REGNUM);
- cache->saved_regs[IA64_RNAT_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_RNAT_REGNUM);
- cache->saved_regs[IA64_CCV_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_CCV_REGNUM);
- cache->saved_regs[IA64_UNAT_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_UNAT_REGNUM);
- cache->saved_regs[IA64_FPSR_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_FPSR_REGNUM);
- cache->saved_regs[IA64_PFS_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_PFS_REGNUM);
- cache->saved_regs[IA64_LC_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_LC_REGNUM);
-
- for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++)
- cache->saved_regs[regno] =
- tdep->sigcontext_register_address (gdbarch, cache->base, regno);
- for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
- cache->saved_regs[regno] =
- tdep->sigcontext_register_address (gdbarch, cache->base, regno);
- for (regno = IA64_FR2_REGNUM; regno <= IA64_FR31_REGNUM; regno++)
- cache->saved_regs[regno] =
- tdep->sigcontext_register_address (gdbarch, cache->base, regno);
- }
-}
-
-static struct ia64_frame_cache *
-ia64_sigtramp_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct ia64_frame_cache *cache;
- gdb_byte buf[8];
-
- if (*this_cache)
- return (struct ia64_frame_cache *) *this_cache;
-
- cache = ia64_alloc_frame_cache ();
-
- get_frame_register (this_frame, sp_regnum, buf);
- /* Note that frame size is hard-coded below. We cannot calculate it
- via prologue examination. */
- cache->base = extract_unsigned_integer (buf, 8, byte_order) + 16;
-
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- cache->bsp = extract_unsigned_integer (buf, 8, byte_order);
-
- get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
- cache->cfm = extract_unsigned_integer (buf, 8, byte_order);
- cache->sof = cache->cfm & 0x7f;
-
- ia64_sigtramp_frame_init_saved_regs (this_frame, cache);
-
- *this_cache = cache;
- return cache;
-}
-
-static void
-ia64_sigtramp_frame_this_id (const frame_info_ptr &this_frame,
- void **this_cache, struct frame_id *this_id)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct ia64_frame_cache *cache =
- ia64_sigtramp_frame_cache (this_frame, this_cache);
-
- (*this_id) = frame_id_build_special (cache->base,
- get_frame_pc (this_frame),
- cache->bsp);
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog,
- "sigtramp frame id: code %s, stack %s, "
- "special %s, this_frame %s\n",
- paddress (gdbarch, this_id->code_addr),
- paddress (gdbarch, this_id->stack_addr),
- paddress (gdbarch, cache->bsp),
- host_address_to_string (this_frame.get ()));
-}
-
-static struct value *
-ia64_sigtramp_frame_prev_register (const frame_info_ptr &this_frame,
- void **this_cache, int regnum)
-{
- struct ia64_frame_cache *cache =
- ia64_sigtramp_frame_cache (this_frame, this_cache);
-
- gdb_assert (regnum >= 0);
-
- if (!target_has_registers ())
- error (_("No registers."));
-
- if (regnum == IA64_IP_REGNUM)
- {
- CORE_ADDR pc = 0;
- CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
-
- if (addr != 0)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- pc = read_memory_unsigned_integer (addr, 8, byte_order);
- }
- pc &= ~0xf;
- return frame_unwind_got_constant (this_frame, regnum, pc);
- }
-
- else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM)
- || (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
- {
- CORE_ADDR addr = 0;
-
- if (regnum >= V32_REGNUM)
- regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
- addr = cache->saved_regs[regnum];
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
-
- return frame_unwind_got_constant (this_frame, regnum, 0);
- }
-
- else /* All other registers not listed above. */
- {
- CORE_ADDR addr = cache->saved_regs[regnum];
-
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
-
- return frame_unwind_got_constant (this_frame, regnum, 0);
- }
-}
-
-static int
-ia64_sigtramp_frame_sniffer (const struct frame_unwind *self,
- const frame_info_ptr &this_frame,
- void **this_cache)
-{
- gdbarch *arch = get_frame_arch (this_frame);
- ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (arch);
- if (tdep->pc_in_sigtramp)
- {
- CORE_ADDR pc = get_frame_pc (this_frame);
-
- if (tdep->pc_in_sigtramp (pc))
- return 1;
- }
-
- return 0;
-}
-
-static const struct frame_unwind ia64_sigtramp_frame_unwind =
-{
- "ia64 sigtramp",
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- ia64_sigtramp_frame_this_id,
- ia64_sigtramp_frame_prev_register,
- NULL,
- ia64_sigtramp_frame_sniffer
-};
-
-
-
-static CORE_ADDR
-ia64_frame_base_address (const frame_info_ptr &this_frame, void **this_cache)
-{
- struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
-
- return cache->base;
-}
-
-static const struct frame_base ia64_frame_base =
-{
- &ia64_frame_unwind,
- ia64_frame_base_address,
- ia64_frame_base_address,
- ia64_frame_base_address
-};
-
-#ifdef HAVE_LIBUNWIND_IA64_H
-
-struct ia64_unwind_table_entry
- {
- unw_word_t start_offset;
- unw_word_t end_offset;
- unw_word_t info_offset;
- };
-
-static __inline__ uint64_t
-ia64_rse_slot_num (uint64_t addr)
-{
- return (addr >> 3) & 0x3f;
-}
-
-/* Skip over a designated number of registers in the backing
- store, remembering every 64th position is for NAT. */
-static __inline__ uint64_t
-ia64_rse_skip_regs (uint64_t addr, long num_regs)
-{
- long delta = ia64_rse_slot_num(addr) + num_regs;
-
- if (num_regs < 0)
- delta -= 0x3e;
- return addr + ((num_regs + delta/0x3f) << 3);
-}
-
-/* Gdb ia64-libunwind-tdep callback function to convert from an ia64 gdb
- register number to a libunwind register number. */
-static int
-ia64_gdb2uw_regnum (int regnum)
-{
- if (regnum == sp_regnum)
- return UNW_IA64_SP;
- else if (regnum == IA64_BSP_REGNUM)
- return UNW_IA64_BSP;
- else if ((unsigned) (regnum - IA64_GR0_REGNUM) < 128)
- return UNW_IA64_GR + (regnum - IA64_GR0_REGNUM);
- else if ((unsigned) (regnum - V32_REGNUM) < 95)
- return UNW_IA64_GR + 32 + (regnum - V32_REGNUM);
- else if ((unsigned) (regnum - IA64_FR0_REGNUM) < 128)
- return UNW_IA64_FR + (regnum - IA64_FR0_REGNUM);
- else if ((unsigned) (regnum - IA64_PR0_REGNUM) < 64)
- return -1;
- else if ((unsigned) (regnum - IA64_BR0_REGNUM) < 8)
- return UNW_IA64_BR + (regnum - IA64_BR0_REGNUM);
- else if (regnum == IA64_PR_REGNUM)
- return UNW_IA64_PR;
- else if (regnum == IA64_IP_REGNUM)
- return UNW_REG_IP;
- else if (regnum == IA64_CFM_REGNUM)
- return UNW_IA64_CFM;
- else if ((unsigned) (regnum - IA64_AR0_REGNUM) < 128)
- return UNW_IA64_AR + (regnum - IA64_AR0_REGNUM);
- else if ((unsigned) (regnum - IA64_NAT0_REGNUM) < 128)
- return UNW_IA64_NAT + (regnum - IA64_NAT0_REGNUM);
- else
- return -1;
-}
-
-/* Gdb ia64-libunwind-tdep callback function to convert from a libunwind
- register number to a ia64 gdb register number. */
-static int
-ia64_uw2gdb_regnum (int uw_regnum)
-{
- if (uw_regnum == UNW_IA64_SP)
- return sp_regnum;
- else if (uw_regnum == UNW_IA64_BSP)
- return IA64_BSP_REGNUM;
- else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 32)
- return IA64_GR0_REGNUM + (uw_regnum - UNW_IA64_GR);
- else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 128)
- return V32_REGNUM + (uw_regnum - (IA64_GR0_REGNUM + 32));
- else if ((unsigned) (uw_regnum - UNW_IA64_FR) < 128)
- return IA64_FR0_REGNUM + (uw_regnum - UNW_IA64_FR);
- else if ((unsigned) (uw_regnum - UNW_IA64_BR) < 8)
- return IA64_BR0_REGNUM + (uw_regnum - UNW_IA64_BR);
- else if (uw_regnum == UNW_IA64_PR)
- return IA64_PR_REGNUM;
- else if (uw_regnum == UNW_REG_IP)
- return IA64_IP_REGNUM;
- else if (uw_regnum == UNW_IA64_CFM)
- return IA64_CFM_REGNUM;
- else if ((unsigned) (uw_regnum - UNW_IA64_AR) < 128)
- return IA64_AR0_REGNUM + (uw_regnum - UNW_IA64_AR);
- else if ((unsigned) (uw_regnum - UNW_IA64_NAT) < 128)
- return IA64_NAT0_REGNUM + (uw_regnum - UNW_IA64_NAT);
- else
- return -1;
-}
-
-/* Gdb ia64-libunwind-tdep callback function to reveal if register is
- a float register or not. */
-static int
-ia64_is_fpreg (int uw_regnum)
-{
- return unw_is_fpreg (uw_regnum);
-}
-
-/* Libunwind callback accessor function for general registers. */
-static int
-ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
- int write, void *arg)
-{
- int regnum = ia64_uw2gdb_regnum (uw_regnum);
- unw_word_t bsp, sof, cfm, psr, ip;
- struct frame_info *this_frame = (frame_info *) arg;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
-
- /* We never call any libunwind routines that need to write registers. */
- gdb_assert (!write);
-
- switch (uw_regnum)
- {
- case UNW_REG_IP:
- /* Libunwind expects to see the pc value which means the slot number
- from the psr must be merged with the ip word address. */
- ip = get_frame_register_unsigned (this_frame, IA64_IP_REGNUM);
- psr = get_frame_register_unsigned (this_frame, IA64_PSR_REGNUM);
- *val = ip | ((psr >> 41) & 0x3);
- break;
-
- case UNW_IA64_AR_BSP:
- /* Libunwind expects to see the beginning of the current
- register frame so we must account for the fact that
- ptrace() will return a value for bsp that points *after*
- the current register frame. */
- bsp = get_frame_register_unsigned (this_frame, IA64_BSP_REGNUM);
- cfm = get_frame_register_unsigned (this_frame, IA64_CFM_REGNUM);
- sof = tdep->size_of_register_frame (this_frame, cfm);
- *val = ia64_rse_skip_regs (bsp, -sof);
- break;
-
- case UNW_IA64_AR_BSPSTORE:
- /* Libunwind wants bspstore to be after the current register frame.
- This is what ptrace() and gdb treats as the regular bsp value. */
- *val = get_frame_register_unsigned (this_frame, IA64_BSP_REGNUM);
- break;
-
- default:
- /* For all other registers, just unwind the value directly. */
- *val = get_frame_register_unsigned (this_frame, regnum);
- break;
- }
-
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog,
- " access_reg: from cache: %4s=%s\n",
- (((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"),
- paddress (gdbarch, *val));
- return 0;
-}
-
-/* Libunwind callback accessor function for floating-point registers. */
-static int
-ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum,
- unw_fpreg_t *val, int write, void *arg)
-{
- int regnum = ia64_uw2gdb_regnum (uw_regnum);
- frame_info_ptr this_frame = (const frame_info_ptr &) arg;
-
- /* We never call any libunwind routines that need to write registers. */
- gdb_assert (!write);
-
- get_frame_register (this_frame, regnum, (gdb_byte *) val);
-
- return 0;
-}
-
-/* Libunwind callback accessor function for top-level rse registers. */
-static int
-ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum,
- unw_word_t *val, int write, void *arg)
-{
- int regnum = ia64_uw2gdb_regnum (uw_regnum);
- unw_word_t bsp, sof, cfm, psr, ip;
- struct regcache *regcache = (struct regcache *) arg;
- struct gdbarch *gdbarch = regcache->arch ();
-
- /* We never call any libunwind routines that need to write registers. */
- gdb_assert (!write);
-
- switch (uw_regnum)
- {
- case UNW_REG_IP:
- /* Libunwind expects to see the pc value which means the slot number
- from the psr must be merged with the ip word address. */
- regcache_cooked_read_unsigned (regcache, IA64_IP_REGNUM, &ip);
- regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr);
- *val = ip | ((psr >> 41) & 0x3);
- break;
-
- case UNW_IA64_AR_BSP:
- /* Libunwind expects to see the beginning of the current
- register frame so we must account for the fact that
- ptrace() will return a value for bsp that points *after*
- the current register frame. */
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
- sof = (cfm & 0x7f);
- *val = ia64_rse_skip_regs (bsp, -sof);
- break;
-
- case UNW_IA64_AR_BSPSTORE:
- /* Libunwind wants bspstore to be after the current register frame.
- This is what ptrace() and gdb treats as the regular bsp value. */
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, val);
- break;
-
- default:
- /* For all other registers, just unwind the value directly. */
- regcache_cooked_read_unsigned (regcache, regnum, val);
- break;
- }
-
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog,
- " access_rse_reg: from cache: %4s=%s\n",
- (((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"),
- paddress (gdbarch, *val));
-
- return 0;
-}
-
-/* Libunwind callback accessor function for top-level fp registers. */
-static int
-ia64_access_rse_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum,
- unw_fpreg_t *val, int write, void *arg)
-{
- int regnum = ia64_uw2gdb_regnum (uw_regnum);
- struct regcache *regcache = (struct regcache *) arg;
-
- /* We never call any libunwind routines that need to write registers. */
- gdb_assert (!write);
-
- regcache->cooked_read (regnum, (gdb_byte *) val);
-
- return 0;
-}
-
-/* Libunwind callback accessor function for accessing memory. */
-static int
-ia64_access_mem (unw_addr_space_t as,
- unw_word_t addr, unw_word_t *val,
- int write, void *arg)
-{
- if (addr - KERNEL_START < ktab_size)
- {
- unw_word_t *laddr = (unw_word_t*) ((char *) ktab
- + (addr - KERNEL_START));
-
- if (write)
- *laddr = *val;
- else
- *val = *laddr;
- return 0;
- }
-
- /* XXX do we need to normalize byte-order here? */
- if (write)
- return target_write_memory (addr, (gdb_byte *) val, sizeof (unw_word_t));
- else
- return target_read_memory (addr, (gdb_byte *) val, sizeof (unw_word_t));
-}
-
-/* Call low-level function to access the kernel unwind table. */
-static std::optional<gdb::byte_vector>
-getunwind_table ()
-{
- /* FIXME drow/2005-09-10: This code used to call
- ia64_linux_xfer_unwind_table directly to fetch the unwind table
- for the currently running ia64-linux kernel. That data should
- come from the core file and be accessed via the auxv vector; if
- we want to preserve fall back to the running kernel's table, then
- we should find a way to override the corefile layer's
- xfer_partial method. */
-
- return target_read_alloc (current_inferior ()->top_target (),
- TARGET_OBJECT_UNWIND_TABLE, NULL);
-}
-
-/* Get the kernel unwind table. */
-static int
-get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
-{
- static struct ia64_table_entry *etab;
-
- if (!ktab)
- {
- ktab_buf = getunwind_table ();
- if (!ktab_buf)
- return -UNW_ENOINFO;
-
- ktab = (struct ia64_table_entry *) ktab_buf->data ();
- ktab_size = ktab_buf->size ();
-
- for (etab = ktab; etab->start_offset; ++etab)
- etab->info_offset += KERNEL_START;
- }
-
- if (ip < ktab[0].start_offset || ip >= etab[-1].end_offset)
- return -UNW_ENOINFO;
-
- di->format = UNW_INFO_FORMAT_TABLE;
- di->gp = 0;
- di->start_ip = ktab[0].start_offset;
- di->end_ip = etab[-1].end_offset;
- di->u.ti.name_ptr = (unw_word_t) "<kernel>";
- di->u.ti.segbase = 0;
- di->u.ti.table_len = ((char *) etab - (char *) ktab) / sizeof (unw_word_t);
- di->u.ti.table_data = (unw_word_t *) ktab;
-
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog, "get_kernel_table: found table `%s': "
- "segbase=%s, length=%s, gp=%s\n",
- (char *) di->u.ti.name_ptr,
- hex_string (di->u.ti.segbase),
- pulongest (di->u.ti.table_len),
- hex_string (di->gp));
- return 0;
-}
-
-/* Find the unwind table entry for a specified address. */
-static int
-ia64_find_unwind_table (struct objfile *objfile, unw_word_t ip,
- unw_dyn_info_t *dip, void **buf)
-{
- Elf_Internal_Phdr *phdr, *p_text = NULL, *p_unwind = NULL;
- Elf_Internal_Ehdr *ehdr;
- unw_word_t segbase = 0;
- CORE_ADDR load_base;
- bfd *bfd;
- int i;
-
- bfd = objfile->obfd;
-
- ehdr = elf_tdata (bfd)->elf_header;
- phdr = elf_tdata (bfd)->phdr;
-
- load_base = objfile->text_section_offset ();
-
- for (i = 0; i < ehdr->e_phnum; ++i)
- {
- switch (phdr[i].p_type)
- {
- case PT_LOAD:
- if ((unw_word_t) (ip - load_base - phdr[i].p_vaddr)
- < phdr[i].p_memsz)
- p_text = phdr + i;
- break;
-
- case PT_IA_64_UNWIND:
- p_unwind = phdr + i;
- break;
-
- default:
- break;
- }
- }
-
- if (!p_text || !p_unwind)
- return -UNW_ENOINFO;
-
- /* Verify that the segment that contains the IP also contains
- the static unwind table. If not, we may be in the Linux kernel's
- DSO gate page in which case the unwind table is another segment.
- Otherwise, we are dealing with runtime-generated code, for which we
- have no info here. */
- segbase = p_text->p_vaddr + load_base;
-
- if ((p_unwind->p_vaddr - p_text->p_vaddr) >= p_text->p_memsz)
- {
- int ok = 0;
- for (i = 0; i < ehdr->e_phnum; ++i)
- {
- if (phdr[i].p_type == PT_LOAD
- && (p_unwind->p_vaddr - phdr[i].p_vaddr) < phdr[i].p_memsz)
- {
- ok = 1;
- /* Get the segbase from the section containing the
- libunwind table. */
- segbase = phdr[i].p_vaddr + load_base;
- }
- }
- if (!ok)
- return -UNW_ENOINFO;
- }
-
- dip->start_ip = p_text->p_vaddr + load_base;
- dip->end_ip = dip->start_ip + p_text->p_memsz;
- dip->gp = ia64_find_global_pointer (objfile->arch (), ip);
- dip->format = UNW_INFO_FORMAT_REMOTE_TABLE;
- dip->u.rti.name_ptr = (unw_word_t) bfd_get_filename (bfd);
- dip->u.rti.segbase = segbase;
- dip->u.rti.table_len = p_unwind->p_memsz / sizeof (unw_word_t);
- dip->u.rti.table_data = p_unwind->p_vaddr + load_base;
-
- return 0;
-}
-
-/* Libunwind callback accessor function to acquire procedure unwind-info. */
-static int
-ia64_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
- int need_unwind_info, void *arg)
-{
- struct obj_section *sec = find_pc_section (ip);
- unw_dyn_info_t di;
- int ret;
- void *buf = NULL;
-
- if (!sec)
- {
- /* XXX This only works if the host and the target architecture are
- both ia64 and if the have (more or less) the same kernel
- version. */
- if (get_kernel_table (ip, &di) < 0)
- return -UNW_ENOINFO;
-
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog, "ia64_find_proc_info_x: %s -> "
- "(name=`%s',segbase=%s,start=%s,end=%s,gp=%s,"
- "length=%s,data=%s)\n",
- hex_string (ip), (char *)di.u.ti.name_ptr,
- hex_string (di.u.ti.segbase),
- hex_string (di.start_ip), hex_string (di.end_ip),
- hex_string (di.gp),
- pulongest (di.u.ti.table_len),
- hex_string ((CORE_ADDR)di.u.ti.table_data));
- }
- else
- {
- ret = ia64_find_unwind_table (sec->objfile, ip, &di, &buf);
- if (ret < 0)
- return ret;
-
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog, "ia64_find_proc_info_x: %s -> "
- "(name=`%s',segbase=%s,start=%s,end=%s,gp=%s,"
- "length=%s,data=%s)\n",
- hex_string (ip), (char *)di.u.rti.name_ptr,
- hex_string (di.u.rti.segbase),
- hex_string (di.start_ip), hex_string (di.end_ip),
- hex_string (di.gp),
- pulongest (di.u.rti.table_len),
- hex_string (di.u.rti.table_data));
- }
-
- ret = libunwind_search_unwind_table (&as, ip, &di, pi, need_unwind_info,
- arg);
-
- /* We no longer need the dyn info storage so free it. */
- xfree (buf);
-
- return ret;
-}
-
-/* Libunwind callback accessor function for cleanup. */
-static void
-ia64_put_unwind_info (unw_addr_space_t as,
- unw_proc_info_t *pip, void *arg)
-{
- /* Nothing required for now. */
-}
-
-/* Libunwind callback accessor function to get head of the dynamic
- unwind-info registration list. */
-static int
-ia64_get_dyn_info_list (unw_addr_space_t as,
- unw_word_t *dilap, void *arg)
-{
- struct obj_section *text_sec;
- unw_word_t ip, addr;
- unw_dyn_info_t di;
- int ret;
-
- if (!libunwind_is_initialized ())
- return -UNW_ENOINFO;
-
- for (objfile *objfile : current_program_space->objfiles ())
- {
- void *buf = NULL;
-
- text_sec = objfile->sections + SECT_OFF_TEXT (objfile);
- ip = text_sec->addr ();
- ret = ia64_find_unwind_table (objfile, ip, &di, &buf);
- if (ret >= 0)
- {
- addr = libunwind_find_dyn_list (as, &di, arg);
- /* We no longer need the dyn info storage so free it. */
- xfree (buf);
-
- if (addr)
- {
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog,
- "dynamic unwind table in objfile %s "
- "at %s (gp=%s)\n",
- bfd_get_filename (objfile->obfd),
- hex_string (addr), hex_string (di.gp));
- *dilap = addr;
- return 0;
- }
- }
- }
- return -UNW_ENOINFO;
-}
-
-
-/* Frame interface functions for libunwind. */
-
-static void
-ia64_libunwind_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
- struct frame_id *this_id)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct frame_id id = outer_frame_id;
- gdb_byte buf[8];
- CORE_ADDR bsp;
-
- libunwind_frame_this_id (this_frame, this_cache, &id);
- if (id == outer_frame_id)
- {
- (*this_id) = outer_frame_id;
- return;
- }
-
- /* We must add the bsp as the special address for frame comparison
- purposes. */
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
-
- (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
-
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog,
- "libunwind frame id: code %s, stack %s, "
- "special %s, this_frame %s\n",
- paddress (gdbarch, id.code_addr),
- paddress (gdbarch, id.stack_addr),
- paddress (gdbarch, bsp),
- host_address_to_string (this_frame));
-}
-
-static struct value *
-ia64_libunwind_frame_prev_register (const frame_info_ptr &this_frame,
- void **this_cache, int regnum)
-{
- int reg = regnum;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct value *val;
-
- if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- reg = IA64_PR_REGNUM;
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- reg = IA64_UNAT_REGNUM;
-
- /* Let libunwind do most of the work. */
- val = libunwind_frame_prev_register (this_frame, this_cache, reg);
-
- if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- ULONGEST prN_val;
-
- if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- int rrb_pr = 0;
- ULONGEST cfm;
-
- /* Fetch predicate register rename base from current frame
- marker for this frame. */
- cfm = get_frame_register_unsigned (this_frame, IA64_CFM_REGNUM);
- rrb_pr = (cfm >> 32) & 0x3f;
-
- /* Adjust the register number to account for register rotation. */
- regnum = VP16_REGNUM + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
- }
- prN_val = extract_bit_field (val->contents_all ().data (),
- regnum - VP0_REGNUM, 1);
- return frame_unwind_got_constant (this_frame, regnum, prN_val);
- }
-
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- {
- ULONGEST unatN_val;
-
- unatN_val = extract_bit_field (val->contents_all ().data (),
- regnum - IA64_NAT0_REGNUM, 1);
- return frame_unwind_got_constant (this_frame, regnum, unatN_val);
- }
-
- else if (regnum == IA64_BSP_REGNUM)
- {
- struct value *cfm_val;
- CORE_ADDR prev_bsp, prev_cfm;
-
- /* We want to calculate the previous bsp as the end of the previous
- register stack frame. This corresponds to what the hardware bsp
- register will be if we pop the frame back which is why we might
- have been called. We know that libunwind will pass us back the
- beginning of the current frame so we should just add sof to it. */
- prev_bsp = extract_unsigned_integer (val->contents_all ().data (),
- 8, byte_order);
- cfm_val = libunwind_frame_prev_register (this_frame, this_cache,
- IA64_CFM_REGNUM);
- prev_cfm = extract_unsigned_integer (cfm_val->contents_all ().data (),
- 8, byte_order);
- prev_bsp = rse_address_add (prev_bsp, (prev_cfm & 0x7f));
-
- return frame_unwind_got_constant (this_frame, regnum, prev_bsp);
- }
- else
- return val;
-}
-
-static int
-ia64_libunwind_frame_sniffer (const struct frame_unwind *self,
- const frame_info_ptr &this_frame,
- void **this_cache)
-{
- if (libunwind_is_initialized ()
- && libunwind_frame_sniffer (self, this_frame, this_cache))
- return 1;
-
- return 0;
-}
-
-static const struct frame_unwind ia64_libunwind_frame_unwind =
-{
- "ia64 libunwind",
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- ia64_libunwind_frame_this_id,
- ia64_libunwind_frame_prev_register,
- NULL,
- ia64_libunwind_frame_sniffer,
- libunwind_frame_dealloc_cache
-};
-
-static void
-ia64_libunwind_sigtramp_frame_this_id (const frame_info_ptr &this_frame,
- void **this_cache,
- struct frame_id *this_id)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[8];
- CORE_ADDR bsp;
- struct frame_id id = outer_frame_id;
-
- libunwind_frame_this_id (this_frame, this_cache, &id);
- if (id == outer_frame_id)
- {
- (*this_id) = outer_frame_id;
- return;
- }
-
- /* We must add the bsp as the special address for frame comparison
- purposes. */
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
-
- /* For a sigtramp frame, we don't make the check for previous ip being 0. */
- (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
-
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog,
- "libunwind sigtramp frame id: code %s, "
- "stack %s, special %s, this_frame %s\n",
- paddress (gdbarch, id.code_addr),
- paddress (gdbarch, id.stack_addr),
- paddress (gdbarch, bsp),
- host_address_to_string (this_frame));
-}
-
-static struct value *
-ia64_libunwind_sigtramp_frame_prev_register (const frame_info_ptr &this_frame,
- void **this_cache, int regnum)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct value *prev_ip_val;
- CORE_ADDR prev_ip;
-
- /* If the previous frame pc value is 0, then we want to use the SIGCONTEXT
- method of getting previous registers. */
- prev_ip_val = libunwind_frame_prev_register (this_frame, this_cache,
- IA64_IP_REGNUM);
- prev_ip = extract_unsigned_integer (prev_ip_val->contents_all ().data (),
- 8, byte_order);
-
- if (prev_ip == 0)
- {
- void *tmp_cache = NULL;
- return ia64_sigtramp_frame_prev_register (this_frame, &tmp_cache,
- regnum);
- }
- else
- return ia64_libunwind_frame_prev_register (this_frame, this_cache, regnum);
-}
-
-static int
-ia64_libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
- const frame_info_ptr &this_frame,
- void **this_cache)
-{
- if (libunwind_is_initialized ())
- {
- if (libunwind_sigtramp_frame_sniffer (self, this_frame, this_cache))
- return 1;
- return 0;
- }
- else
- return ia64_sigtramp_frame_sniffer (self, this_frame, this_cache);
-}
-
-static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
-{
- "ia64 libunwind sigtramp",
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- ia64_libunwind_sigtramp_frame_this_id,
- ia64_libunwind_sigtramp_frame_prev_register,
- NULL,
- ia64_libunwind_sigtramp_frame_sniffer
-};
-
-/* Set of libunwind callback acccessor functions. */
-unw_accessors_t ia64_unw_accessors =
-{
- ia64_find_proc_info_x,
- ia64_put_unwind_info,
- ia64_get_dyn_info_list,
- ia64_access_mem,
- ia64_access_reg,
- ia64_access_fpreg,
- /* resume */
- /* get_proc_name */
-};
-
-/* Set of special libunwind callback acccessor functions specific for accessing
- the rse registers. At the top of the stack, we want libunwind to figure out
- how to read r32 - r127. Though usually they are found sequentially in
- memory starting from $bof, this is not always true. */
-unw_accessors_t ia64_unw_rse_accessors =
-{
- ia64_find_proc_info_x,
- ia64_put_unwind_info,
- ia64_get_dyn_info_list,
- ia64_access_mem,
- ia64_access_rse_reg,
- ia64_access_rse_fpreg,
- /* resume */
- /* get_proc_name */
-};
-
-/* Set of ia64-libunwind-tdep gdb callbacks and data for generic
- ia64-libunwind-tdep code to use. */
-struct libunwind_descr ia64_libunwind_descr =
-{
- ia64_gdb2uw_regnum,
- ia64_uw2gdb_regnum,
- ia64_is_fpreg,
- &ia64_unw_accessors,
- &ia64_unw_rse_accessors,
-};
-
-#endif /* HAVE_LIBUNWIND_IA64_H */
-
-static int
-ia64_use_struct_convention (struct type *type)
-{
- struct type *float_elt_type;
-
- /* Don't use the struct convention for anything but structure,
- union, or array types. */
- if (!(type->code () == TYPE_CODE_STRUCT
- || type->code () == TYPE_CODE_UNION
- || type->code () == TYPE_CODE_ARRAY))
- return 0;
-
- /* HFAs are structures (or arrays) consisting entirely of floating
- point values of the same length. Up to 8 of these are returned
- in registers. Don't use the struct convention when this is the
- case. */
- float_elt_type = is_float_or_hfa_type (type);
- if (float_elt_type != NULL
- && type->length () / float_elt_type->length () <= 8)
- return 0;
-
- /* Other structs of length 32 or less are returned in r8-r11.
- Don't use the struct convention for those either. */
- return type->length () > 32;
-}
-
-/* Return non-zero if TYPE is a structure or union type. */
-
-static int
-ia64_struct_type_p (const struct type *type)
-{
- return (type->code () == TYPE_CODE_STRUCT
- || type->code () == TYPE_CODE_UNION);
-}
-
-static void
-ia64_extract_return_value (struct type *type, struct regcache *regcache,
- gdb_byte *valbuf)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- struct type *float_elt_type;
-
- float_elt_type = is_float_or_hfa_type (type);
- if (float_elt_type != NULL)
- {
- gdb_byte from[IA64_FP_REGISTER_SIZE];
- int offset = 0;
- int regnum = IA64_FR8_REGNUM;
- int n = type->length () / float_elt_type->length ();
-
- while (n-- > 0)
- {
- regcache->cooked_read (regnum, from);
- target_float_convert (from, ia64_ext_type (gdbarch),
- valbuf + offset, float_elt_type);
- offset += float_elt_type->length ();
- regnum++;
- }
- }
- else if (!ia64_struct_type_p (type) && type->length () < 8)
- {
- /* This is an integral value, and its size is less than 8 bytes.
- These values are LSB-aligned, so extract the relevant bytes,
- and copy them into VALBUF. */
- /* brobecker/2005-12-30: Actually, all integral values are LSB aligned,
- so I suppose we should also add handling here for integral values
- whose size is greater than 8. But I wasn't able to create such
- a type, neither in C nor in Ada, so not worrying about these yet. */
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- ULONGEST val;
-
- regcache_cooked_read_unsigned (regcache, IA64_GR8_REGNUM, &val);
- store_unsigned_integer (valbuf, type->length (), byte_order, val);
- }
- else
- {
- ULONGEST val;
- int offset = 0;
- int regnum = IA64_GR8_REGNUM;
- int reglen = register_type (gdbarch, IA64_GR8_REGNUM)->length ();
- int n = type->length () / reglen;
- int m = type->length () % reglen;
-
- while (n-- > 0)
- {
- ULONGEST regval;
- regcache_cooked_read_unsigned (regcache, regnum, ®val);
- memcpy ((char *)valbuf + offset, ®val, reglen);
- offset += reglen;
- regnum++;
- }
-
- if (m)
- {
- regcache_cooked_read_unsigned (regcache, regnum, &val);
- memcpy ((char *)valbuf + offset, &val, m);
- }
- }
-}
-
-static void
-ia64_store_return_value (struct type *type, struct regcache *regcache,
- const gdb_byte *valbuf)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- struct type *float_elt_type;
-
- float_elt_type = is_float_or_hfa_type (type);
- if (float_elt_type != NULL)
- {
- gdb_byte to[IA64_FP_REGISTER_SIZE];
- int offset = 0;
- int regnum = IA64_FR8_REGNUM;
- int n = type->length () / float_elt_type->length ();
-
- while (n-- > 0)
- {
- target_float_convert (valbuf + offset, float_elt_type,
- to, ia64_ext_type (gdbarch));
- regcache->cooked_write (regnum, to);
- offset += float_elt_type->length ();
- regnum++;
- }
- }
- else
- {
- int offset = 0;
- int regnum = IA64_GR8_REGNUM;
- int reglen = register_type (gdbarch, IA64_GR8_REGNUM)->length ();
- int n = type->length () / reglen;
- int m = type->length () % reglen;
-
- while (n-- > 0)
- {
- ULONGEST val;
- memcpy (&val, (char *)valbuf + offset, reglen);
- regcache_cooked_write_unsigned (regcache, regnum, val);
- offset += reglen;
- regnum++;
- }
-
- if (m)
- {
- ULONGEST val;
- memcpy (&val, (char *)valbuf + offset, m);
- regcache_cooked_write_unsigned (regcache, regnum, val);
- }
- }
-}
-
-static enum return_value_convention
-ia64_return_value (struct gdbarch *gdbarch, struct value *function,
- struct type *valtype, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
-{
- int struct_return = ia64_use_struct_convention (valtype);
-
- if (writebuf != NULL)
- {
- gdb_assert (!struct_return);
- ia64_store_return_value (valtype, regcache, writebuf);
- }
-
- if (readbuf != NULL)
- {
- gdb_assert (!struct_return);
- ia64_extract_return_value (valtype, regcache, readbuf);
- }
-
- if (struct_return)
- return RETURN_VALUE_STRUCT_CONVENTION;
- else
- return RETURN_VALUE_REGISTER_CONVENTION;
-}
-
-static int
-is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
-{
- switch (t->code ())
- {
- case TYPE_CODE_FLT:
- if (*etp)
- return (*etp)->length () == t->length ();
- else
- {
- *etp = t;
- return 1;
- }
- break;
- case TYPE_CODE_ARRAY:
- return
- is_float_or_hfa_type_recurse (check_typedef (t->target_type ()),
- etp);
- break;
- case TYPE_CODE_STRUCT:
- {
- int i;
-
- for (i = 0; i < t->num_fields (); i++)
- if (!is_float_or_hfa_type_recurse
- (check_typedef (t->field (i).type ()), etp))
- return 0;
- return 1;
- }
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-/* Determine if the given type is one of the floating point types or
- and HFA (which is a struct, array, or combination thereof whose
- bottom-most elements are all of the same floating point type). */
-
-static struct type *
-is_float_or_hfa_type (struct type *t)
-{
- struct type *et = 0;
-
- return is_float_or_hfa_type_recurse (t, &et) ? et : 0;
-}
-
-
-/* Return 1 if the alignment of T is such that the next even slot
- should be used. Return 0, if the next available slot should
- be used. (See section 8.5.1 of the IA-64 Software Conventions
- and Runtime manual). */
-
-static int
-slot_alignment_is_next_even (struct type *t)
-{
- switch (t->code ())
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_FLT:
- if (t->length () > 8)
- return 1;
- else
- return 0;
- case TYPE_CODE_ARRAY:
- return
- slot_alignment_is_next_even (check_typedef (t->target_type ()));
- case TYPE_CODE_STRUCT:
- {
- int i;
-
- for (i = 0; i < t->num_fields (); i++)
- if (slot_alignment_is_next_even
- (check_typedef (t->field (i).type ())))
- return 1;
- return 0;
- }
- default:
- return 0;
- }
-}
-
-/* Attempt to find (and return) the global pointer for the given
- function.
-
- This is a rather nasty bit of code searchs for the .dynamic section
- in the objfile corresponding to the pc of the function we're trying
- to call. Once it finds the addresses at which the .dynamic section
- lives in the child process, it scans the Elf64_Dyn entries for a
- DT_PLTGOT tag. If it finds one of these, the corresponding
- d_un.d_ptr value is the global pointer. */
-
-static CORE_ADDR
-ia64_find_global_pointer_from_dynamic_section (struct gdbarch *gdbarch,
- CORE_ADDR faddr)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct obj_section *faddr_sect;
-
- faddr_sect = find_pc_section (faddr);
- if (faddr_sect != NULL)
- {
- for (obj_section *osect : faddr_sect->objfile->sections ())
- {
- if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
- {
- CORE_ADDR addr = osect->addr ();
- CORE_ADDR endaddr = osect->endaddr ();
-
- while (addr < endaddr)
- {
- int status;
- LONGEST tag;
- gdb_byte buf[8];
-
- status = target_read_memory (addr, buf, sizeof (buf));
- if (status != 0)
- break;
- tag = extract_signed_integer (buf, byte_order);
-
- if (tag == DT_PLTGOT)
- {
- CORE_ADDR global_pointer;
-
- status = target_read_memory (addr + 8, buf,
- sizeof (buf));
- if (status != 0)
- break;
- global_pointer
- = extract_unsigned_integer (buf, sizeof (buf),
- byte_order);
-
- /* The payoff... */
- return global_pointer;
- }
-
- if (tag == DT_NULL)
- break;
-
- addr += 16;
- }
-
- break;
- }
- }
- }
- return 0;
-}
-
-/* Attempt to find (and return) the global pointer for the given
- function. We first try the find_global_pointer_from_solib routine
- from the gdbarch tdep vector, if provided. And if that does not
- work, then we try ia64_find_global_pointer_from_dynamic_section. */
-
-static CORE_ADDR
-ia64_find_global_pointer (struct gdbarch *gdbarch, CORE_ADDR faddr)
-{
- ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
- CORE_ADDR addr = 0;
-
- if (tdep->find_global_pointer_from_solib)
- addr = tdep->find_global_pointer_from_solib (gdbarch, faddr);
- if (addr == 0)
- addr = ia64_find_global_pointer_from_dynamic_section (gdbarch, faddr);
- return addr;
-}
-
-/* Given a function's address, attempt to find (and return) the
- corresponding (canonical) function descriptor. Return 0 if
- not found. */
-static CORE_ADDR
-find_extant_func_descr (struct gdbarch *gdbarch, CORE_ADDR faddr)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct obj_section *faddr_sect;
-
- /* Return early if faddr is already a function descriptor. */
- faddr_sect = find_pc_section (faddr);
- if (faddr_sect && strcmp (faddr_sect->the_bfd_section->name, ".opd") == 0)
- return faddr;
-
- if (faddr_sect != NULL)
- {
- for (obj_section *osect : faddr_sect->objfile->sections ())
- {
- if (strcmp (osect->the_bfd_section->name, ".opd") == 0)
- {
- CORE_ADDR addr = osect->addr ();
- CORE_ADDR endaddr = osect->endaddr ();
-
- while (addr < endaddr)
- {
- int status;
- LONGEST faddr2;
- gdb_byte buf[8];
-
- status = target_read_memory (addr, buf, sizeof (buf));
- if (status != 0)
- break;
- faddr2 = extract_signed_integer (buf, byte_order);
-
- if (faddr == faddr2)
- return addr;
-
- addr += 16;
- }
-
- break;
- }
- }
- }
- return 0;
-}
-
-/* Attempt to find a function descriptor corresponding to the
- given address. If none is found, construct one on the
- stack using the address at fdaptr. */
-
-static CORE_ADDR
-find_func_descr (struct regcache *regcache, CORE_ADDR faddr, CORE_ADDR *fdaptr)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR fdesc;
-
- fdesc = find_extant_func_descr (gdbarch, faddr);
-
- if (fdesc == 0)
- {
- ULONGEST global_pointer;
- gdb_byte buf[16];
-
- fdesc = *fdaptr;
- *fdaptr += 16;
-
- global_pointer = ia64_find_global_pointer (gdbarch, faddr);
-
- if (global_pointer == 0)
- regcache_cooked_read_unsigned (regcache,
- IA64_GR1_REGNUM, &global_pointer);
-
- store_unsigned_integer (buf, 8, byte_order, faddr);
- store_unsigned_integer (buf + 8, 8, byte_order, global_pointer);
-
- write_memory (fdesc, buf, 16);
- }
-
- return fdesc;
-}
-
-/* Use the following routine when printing out function pointers
- so the user can see the function address rather than just the
- function descriptor. */
-static CORE_ADDR
-ia64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr,
- struct target_ops *targ)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct obj_section *s;
- gdb_byte buf[8];
-
- s = find_pc_section (addr);
-
- /* check if ADDR points to a function descriptor. */
- if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
- return read_memory_unsigned_integer (addr, 8, byte_order);
-
- /* Normally, functions live inside a section that is executable.
- So, if ADDR points to a non-executable section, then treat it
- as a function descriptor and return the target address iff
- the target address itself points to a section that is executable.
- Check first the memory of the whole length of 8 bytes is readable. */
- if (s && (s->the_bfd_section->flags & SEC_CODE) == 0
- && target_read_memory (addr, buf, 8) == 0)
- {
- CORE_ADDR pc = extract_unsigned_integer (buf, 8, byte_order);
- struct obj_section *pc_section = find_pc_section (pc);
-
- if (pc_section && (pc_section->the_bfd_section->flags & SEC_CODE))
- return pc;
- }
-
- /* There are also descriptors embedded in vtables. */
- if (s)
- {
- struct bound_minimal_symbol minsym;
-
- minsym = lookup_minimal_symbol_by_pc (addr);
-
- if (minsym.minsym
- && is_vtable_name (minsym.minsym->linkage_name ()))
- return read_memory_unsigned_integer (addr, 8, byte_order);
- }
-
- return addr;
-}
-
-static CORE_ADDR
-ia64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
-{
- return sp & ~0xfLL;
-}
-
-/* The default "allocate_new_rse_frame" ia64_infcall_ops routine for ia64. */
-
-static void
-ia64_allocate_new_rse_frame (struct regcache *regcache, ULONGEST bsp, int sof)
-{
- ULONGEST cfm, pfs, new_bsp;
-
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
-
- new_bsp = rse_address_add (bsp, sof);
- regcache_cooked_write_unsigned (regcache, IA64_BSP_REGNUM, new_bsp);
-
- regcache_cooked_read_unsigned (regcache, IA64_PFS_REGNUM, &pfs);
- pfs &= 0xc000000000000000LL;
- pfs |= (cfm & 0xffffffffffffLL);
- regcache_cooked_write_unsigned (regcache, IA64_PFS_REGNUM, pfs);
-
- cfm &= 0xc000000000000000LL;
- cfm |= sof;
- regcache_cooked_write_unsigned (regcache, IA64_CFM_REGNUM, cfm);
-}
-
-/* The default "store_argument_in_slot" ia64_infcall_ops routine for
- ia64. */
-
-static void
-ia64_store_argument_in_slot (struct regcache *regcache, CORE_ADDR bsp,
- int slotnum, gdb_byte *buf)
-{
- write_memory (rse_address_add (bsp, slotnum), buf, 8);
-}
-
-/* The default "set_function_addr" ia64_infcall_ops routine for ia64. */
-
-static void
-ia64_set_function_addr (struct regcache *regcache, CORE_ADDR func_addr)
-{
- /* Nothing needed. */
-}
-
-static CORE_ADDR
-ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
- struct regcache *regcache, CORE_ADDR bp_addr,
- int nargs, struct value **args, CORE_ADDR sp,
- function_call_return_method return_method,
- CORE_ADDR struct_addr)
-{
- ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int argno;
- struct value *arg;
- struct type *type;
- int len, argoffset;
- int nslots, rseslots, memslots, slotnum, nfuncargs;
- int floatreg;
- ULONGEST bsp;
- CORE_ADDR funcdescaddr, global_pointer;
- CORE_ADDR func_addr = find_function_addr (function, NULL);
-
- nslots = 0;
- nfuncargs = 0;
- /* Count the number of slots needed for the arguments. */
- for (argno = 0; argno < nargs; argno++)
- {
- arg = args[argno];
- type = check_typedef (arg->type ());
- len = type->length ();
-
- if ((nslots & 1) && slot_alignment_is_next_even (type))
- nslots++;
-
- if (type->code () == TYPE_CODE_FUNC)
- nfuncargs++;
-
- nslots += (len + 7) / 8;
- }
-
- /* Divvy up the slots between the RSE and the memory stack. */
- rseslots = (nslots > 8) ? 8 : nslots;
- memslots = nslots - rseslots;
-
- /* Allocate a new RSE frame. */
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- tdep->infcall_ops.allocate_new_rse_frame (regcache, bsp, rseslots);
-
- /* We will attempt to find function descriptors in the .opd segment,
- but if we can't we'll construct them ourselves. That being the
- case, we'll need to reserve space on the stack for them. */
- funcdescaddr = sp - nfuncargs * 16;
- funcdescaddr &= ~0xfLL;
-
- /* Adjust the stack pointer to it's new value. The calling conventions
- require us to have 16 bytes of scratch, plus whatever space is
- necessary for the memory slots and our function descriptors. */
- sp = sp - 16 - (memslots + nfuncargs) * 8;
- sp &= ~0xfLL; /* Maintain 16 byte alignment. */
-
- /* Place the arguments where they belong. The arguments will be
- either placed in the RSE backing store or on the memory stack.
- In addition, floating point arguments or HFAs are placed in
- floating point registers. */
- slotnum = 0;
- floatreg = IA64_FR8_REGNUM;
- for (argno = 0; argno < nargs; argno++)
- {
- struct type *float_elt_type;
-
- arg = args[argno];
- type = check_typedef (arg->type ());
- len = type->length ();
-
- /* Special handling for function parameters. */
- if (len == 8
- && type->code () == TYPE_CODE_PTR
- && type->target_type ()->code () == TYPE_CODE_FUNC)
- {
- gdb_byte val_buf[8];
- ULONGEST faddr = extract_unsigned_integer
- (arg->contents ().data (), 8, byte_order);
- store_unsigned_integer (val_buf, 8, byte_order,
- find_func_descr (regcache, faddr,
- &funcdescaddr));
- if (slotnum < rseslots)
- tdep->infcall_ops.store_argument_in_slot (regcache, bsp,
- slotnum, val_buf);
- else
- write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
- slotnum++;
- continue;
- }
-
- /* Normal slots. */
-
- /* Skip odd slot if necessary... */
- if ((slotnum & 1) && slot_alignment_is_next_even (type))
- slotnum++;
-
- argoffset = 0;
- while (len > 0)
- {
- gdb_byte val_buf[8];
-
- memset (val_buf, 0, 8);
- if (!ia64_struct_type_p (type) && len < 8)
- {
- /* Integral types are LSB-aligned, so we have to be careful
- to insert the argument on the correct side of the buffer.
- This is why we use store_unsigned_integer. */
- store_unsigned_integer
- (val_buf, 8, byte_order,
- extract_unsigned_integer (arg->contents ().data (), len,
- byte_order));
- }
- else
- {
- /* This is either an 8bit integral type, or an aggregate.
- For 8bit integral type, there is no problem, we just
- copy the value over.
-
- For aggregates, the only potentially tricky portion
- is to write the last one if it is less than 8 bytes.
- In this case, the data is Byte0-aligned. Happy news,
- this means that we don't need to differentiate the
- handling of 8byte blocks and less-than-8bytes blocks. */
- memcpy (val_buf, arg->contents ().data () + argoffset,
- (len > 8) ? 8 : len);
- }
-
- if (slotnum < rseslots)
- tdep->infcall_ops.store_argument_in_slot (regcache, bsp,
- slotnum, val_buf);
- else
- write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
-
- argoffset += 8;
- len -= 8;
- slotnum++;
- }
-
- /* Handle floating point types (including HFAs). */
- float_elt_type = is_float_or_hfa_type (type);
- if (float_elt_type != NULL)
- {
- argoffset = 0;
- len = type->length ();
- while (len > 0 && floatreg < IA64_FR16_REGNUM)
- {
- gdb_byte to[IA64_FP_REGISTER_SIZE];
- target_float_convert (arg->contents ().data () + argoffset,
- float_elt_type, to,
- ia64_ext_type (gdbarch));
- regcache->cooked_write (floatreg, to);
- floatreg++;
- argoffset += float_elt_type->length ();
- len -= float_elt_type->length ();
- }
- }
- }
-
- /* Store the struct return value in r8 if necessary. */
- if (return_method == return_method_struct)
- regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM,
- (ULONGEST) struct_addr);
-
- global_pointer = ia64_find_global_pointer (gdbarch, func_addr);
-
- if (global_pointer != 0)
- regcache_cooked_write_unsigned (regcache, IA64_GR1_REGNUM, global_pointer);
-
- /* The following is not necessary on HP-UX, because we're using
- a dummy code sequence pushed on the stack to make the call, and
- this sequence doesn't need b0 to be set in order for our dummy
- breakpoint to be hit. Nonetheless, this doesn't interfere, and
- it's needed for other OSes, so we do this unconditionaly. */
- regcache_cooked_write_unsigned (regcache, IA64_BR0_REGNUM, bp_addr);
-
- regcache_cooked_write_unsigned (regcache, sp_regnum, sp);
-
- tdep->infcall_ops.set_function_addr (regcache, func_addr);
-
- return sp;
-}
-
-static const struct ia64_infcall_ops ia64_infcall_ops =
-{
- ia64_allocate_new_rse_frame,
- ia64_store_argument_in_slot,
- ia64_set_function_addr
-};
-
-static struct frame_id
-ia64_dummy_id (struct gdbarch *gdbarch, const frame_info_ptr &this_frame)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[8];
- CORE_ADDR sp, bsp;
-
- get_frame_register (this_frame, sp_regnum, buf);
- sp = extract_unsigned_integer (buf, 8, byte_order);
-
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
-
- if (gdbarch_debug >= 1)
- gdb_printf (gdb_stdlog,
- "dummy frame id: code %s, stack %s, special %s\n",
- paddress (gdbarch, get_frame_pc (this_frame)),
- paddress (gdbarch, sp), paddress (gdbarch, bsp));
-
- return frame_id_build_special (sp, get_frame_pc (this_frame), bsp);
-}
-
-static CORE_ADDR
-ia64_unwind_pc (struct gdbarch *gdbarch, const frame_info_ptr &next_frame)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[8];
- CORE_ADDR ip, psr, pc;
-
- frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
- ip = extract_unsigned_integer (buf, 8, byte_order);
- frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
-
- pc = (ip & ~0xf) | ((psr >> 41) & 3);
- return pc;
-}
-
-static int
-ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
-{
- info->bytes_per_line = SLOT_MULTIPLIER;
- return default_print_insn (memaddr, info);
-}
-
-/* The default "size_of_register_frame" gdbarch_tdep routine for ia64. */
-
-static int
-ia64_size_of_register_frame (const frame_info_ptr &this_frame, ULONGEST cfm)
-{
- return (cfm & 0x7f);
-}
-
-static struct gdbarch *
-ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
-{
- /* If there is already a candidate, use it. */
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
-
- gdbarch *gdbarch
- = gdbarch_alloc (&info, gdbarch_tdep_up (new ia64_gdbarch_tdep));
- ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
-
- tdep->size_of_register_frame = ia64_size_of_register_frame;
-
- /* According to the ia64 specs, instructions that store long double
- floats in memory use a long-double format different than that
- used in the floating registers. The memory format matches the
- x86 extended float format which is 80 bits. An OS may choose to
- use this format (e.g. GNU/Linux) or choose to use a different
- format for storing long doubles (e.g. HPUX). In the latter case,
- the setting of the format may be moved/overridden in an
- OS-specific tdep file. */
- set_gdbarch_long_double_format (gdbarch, floatformats_i387_ext);
-
- set_gdbarch_short_bit (gdbarch, 16);
- set_gdbarch_int_bit (gdbarch, 32);
- set_gdbarch_long_bit (gdbarch, 64);
- set_gdbarch_long_long_bit (gdbarch, 64);
- set_gdbarch_float_bit (gdbarch, 32);
- set_gdbarch_double_bit (gdbarch, 64);
- set_gdbarch_long_double_bit (gdbarch, 128);
- set_gdbarch_ptr_bit (gdbarch, 64);
-
- set_gdbarch_num_regs (gdbarch, NUM_IA64_RAW_REGS);
- set_gdbarch_num_pseudo_regs (gdbarch,
- LAST_PSEUDO_REGNUM - FIRST_PSEUDO_REGNUM);
- set_gdbarch_sp_regnum (gdbarch, sp_regnum);
- set_gdbarch_fp0_regnum (gdbarch, IA64_FR0_REGNUM);
-
- set_gdbarch_register_name (gdbarch, ia64_register_name);
- set_gdbarch_register_type (gdbarch, ia64_register_type);
-
- set_gdbarch_pseudo_register_read (gdbarch, ia64_pseudo_register_read);
- set_gdbarch_deprecated_pseudo_register_write (gdbarch,
- ia64_pseudo_register_write);
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, ia64_dwarf_reg_to_regnum);
- set_gdbarch_register_reggroup_p (gdbarch, ia64_register_reggroup_p);
- set_gdbarch_convert_register_p (gdbarch, ia64_convert_register_p);
- set_gdbarch_register_to_value (gdbarch, ia64_register_to_value);
- set_gdbarch_value_to_register (gdbarch, ia64_value_to_register);
-
- set_gdbarch_skip_prologue (gdbarch, ia64_skip_prologue);
-
- set_gdbarch_return_value (gdbarch, ia64_return_value);
-
- set_gdbarch_memory_insert_breakpoint (gdbarch,
- ia64_memory_insert_breakpoint);
- set_gdbarch_memory_remove_breakpoint (gdbarch,
- ia64_memory_remove_breakpoint);
- set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc);
- set_gdbarch_breakpoint_kind_from_pc (gdbarch, ia64_breakpoint_kind_from_pc);
- set_gdbarch_read_pc (gdbarch, ia64_read_pc);
- set_gdbarch_write_pc (gdbarch, ia64_write_pc);
-
- /* Settings for calling functions in the inferior. */
- set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
- tdep->infcall_ops = ia64_infcall_ops;
- set_gdbarch_frame_align (gdbarch, ia64_frame_align);
- set_gdbarch_dummy_id (gdbarch, ia64_dummy_id);
-
- set_gdbarch_unwind_pc (gdbarch, ia64_unwind_pc);
-#ifdef HAVE_LIBUNWIND_IA64_H
- frame_unwind_append_unwinder (gdbarch,
- &ia64_libunwind_sigtramp_frame_unwind);
- frame_unwind_append_unwinder (gdbarch, &ia64_libunwind_frame_unwind);
- frame_unwind_append_unwinder (gdbarch, &ia64_sigtramp_frame_unwind);
- libunwind_frame_set_descr (gdbarch, &ia64_libunwind_descr);
-#else
- frame_unwind_append_unwinder (gdbarch, &ia64_sigtramp_frame_unwind);
-#endif
- frame_unwind_append_unwinder (gdbarch, &ia64_frame_unwind);
- frame_base_set_default (gdbarch, &ia64_frame_base);
-
- /* Settings that should be unnecessary. */
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-
- set_gdbarch_print_insn (gdbarch, ia64_print_insn);
- set_gdbarch_convert_from_func_ptr_addr (gdbarch,
- ia64_convert_from_func_ptr_addr);
-
- /* The virtual table contains 16-byte descriptors, not pointers to
- descriptors. */
- set_gdbarch_vtable_function_descriptors (gdbarch, 1);
-
- /* Hook in ABI-specific overrides, if they have been registered. */
- gdbarch_init_osabi (info, gdbarch);
-
- return gdbarch;
-}
-
-void _initialize_ia64_tdep ();
-void
-_initialize_ia64_tdep ()
-{
- gdbarch_register (bfd_arch_ia64, ia64_gdbarch_init, NULL);
-}
deleted file mode 100644
@@ -1,268 +0,0 @@
-/* Target-dependent code for the ia64.
-
- Copyright (C) 2004-2024 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 IA64_TDEP_H
-#define IA64_TDEP_H
-
-#include "gdbarch.h"
-
-#ifdef HAVE_LIBUNWIND_IA64_H
-#include "libunwind-ia64.h"
-#include "ia64-libunwind-tdep.h"
-#endif
-
-/* Register numbers of various important registers. */
-
-/* General registers; there are 128 of these 64 bit wide registers.
- The first 32 are static and the last 96 are stacked. */
-#define IA64_GR0_REGNUM 0
-#define IA64_GR1_REGNUM (IA64_GR0_REGNUM + 1)
-#define IA64_GR2_REGNUM (IA64_GR0_REGNUM + 2)
-#define IA64_GR3_REGNUM (IA64_GR0_REGNUM + 3)
-#define IA64_GR4_REGNUM (IA64_GR0_REGNUM + 4)
-#define IA64_GR5_REGNUM (IA64_GR0_REGNUM + 5)
-#define IA64_GR6_REGNUM (IA64_GR0_REGNUM + 6)
-#define IA64_GR7_REGNUM (IA64_GR0_REGNUM + 7)
-#define IA64_GR8_REGNUM (IA64_GR0_REGNUM + 8)
-#define IA64_GR9_REGNUM (IA64_GR0_REGNUM + 9)
-#define IA64_GR10_REGNUM (IA64_GR0_REGNUM + 10)
-#define IA64_GR11_REGNUM (IA64_GR0_REGNUM + 11)
-#define IA64_GR12_REGNUM (IA64_GR0_REGNUM + 12)
-#define IA64_GR31_REGNUM (IA64_GR0_REGNUM + 31)
-#define IA64_GR32_REGNUM (IA64_GR0_REGNUM + 32)
-#define IA64_GR127_REGNUM (IA64_GR0_REGNUM + 127)
-
-/* Floating point registers; 128 82-bit wide registers. */
-#define IA64_FR0_REGNUM 128
-#define IA64_FR1_REGNUM (IA64_FR0_REGNUM + 1)
-#define IA64_FR2_REGNUM (IA64_FR0_REGNUM + 2)
-#define IA64_FR8_REGNUM (IA64_FR0_REGNUM + 8)
-#define IA64_FR9_REGNUM (IA64_FR0_REGNUM + 9)
-#define IA64_FR10_REGNUM (IA64_FR0_REGNUM + 10)
-#define IA64_FR11_REGNUM (IA64_FR0_REGNUM + 11)
-#define IA64_FR12_REGNUM (IA64_FR0_REGNUM + 12)
-#define IA64_FR13_REGNUM (IA64_FR0_REGNUM + 13)
-#define IA64_FR14_REGNUM (IA64_FR0_REGNUM + 14)
-#define IA64_FR15_REGNUM (IA64_FR0_REGNUM + 15)
-#define IA64_FR16_REGNUM (IA64_FR0_REGNUM + 16)
-#define IA64_FR31_REGNUM (IA64_FR0_REGNUM + 31)
-#define IA64_FR32_REGNUM (IA64_FR0_REGNUM + 32)
-#define IA64_FR127_REGNUM (IA64_FR0_REGNUM + 127)
-
-/* Predicate registers; There are 64 of these one bit registers. It'd
- be more convenient (implementation-wise) to use a single 64 bit
- word with all of these register in them. Note that there's also a
- IA64_PR_REGNUM below which contains all the bits and is used for
- communicating the actual values to the target. */
-#define IA64_PR0_REGNUM 256
-#define IA64_PR1_REGNUM (IA64_PR0_REGNUM + 1)
-#define IA64_PR2_REGNUM (IA64_PR0_REGNUM + 2)
-#define IA64_PR3_REGNUM (IA64_PR0_REGNUM + 3)
-#define IA64_PR4_REGNUM (IA64_PR0_REGNUM + 4)
-#define IA64_PR5_REGNUM (IA64_PR0_REGNUM + 5)
-#define IA64_PR6_REGNUM (IA64_PR0_REGNUM + 6)
-#define IA64_PR7_REGNUM (IA64_PR0_REGNUM + 7)
-#define IA64_PR8_REGNUM (IA64_PR0_REGNUM + 8)
-#define IA64_PR9_REGNUM (IA64_PR0_REGNUM + 9)
-#define IA64_PR10_REGNUM (IA64_PR0_REGNUM + 10)
-#define IA64_PR11_REGNUM (IA64_PR0_REGNUM + 11)
-#define IA64_PR12_REGNUM (IA64_PR0_REGNUM + 12)
-#define IA64_PR13_REGNUM (IA64_PR0_REGNUM + 13)
-#define IA64_PR14_REGNUM (IA64_PR0_REGNUM + 14)
-#define IA64_PR15_REGNUM (IA64_PR0_REGNUM + 15)
-#define IA64_PR16_REGNUM (IA64_PR0_REGNUM + 16)
-#define IA64_PR17_REGNUM (IA64_PR0_REGNUM + 17)
-#define IA64_PR18_REGNUM (IA64_PR0_REGNUM + 18)
-#define IA64_PR19_REGNUM (IA64_PR0_REGNUM + 19)
-#define IA64_PR20_REGNUM (IA64_PR0_REGNUM + 20)
-#define IA64_PR21_REGNUM (IA64_PR0_REGNUM + 21)
-#define IA64_PR22_REGNUM (IA64_PR0_REGNUM + 22)
-#define IA64_PR23_REGNUM (IA64_PR0_REGNUM + 23)
-#define IA64_PR24_REGNUM (IA64_PR0_REGNUM + 24)
-#define IA64_PR25_REGNUM (IA64_PR0_REGNUM + 25)
-#define IA64_PR26_REGNUM (IA64_PR0_REGNUM + 26)
-#define IA64_PR27_REGNUM (IA64_PR0_REGNUM + 27)
-#define IA64_PR28_REGNUM (IA64_PR0_REGNUM + 28)
-#define IA64_PR29_REGNUM (IA64_PR0_REGNUM + 29)
-#define IA64_PR30_REGNUM (IA64_PR0_REGNUM + 30)
-#define IA64_PR31_REGNUM (IA64_PR0_REGNUM + 31)
-#define IA64_PR32_REGNUM (IA64_PR0_REGNUM + 32)
-#define IA64_PR33_REGNUM (IA64_PR0_REGNUM + 33)
-#define IA64_PR34_REGNUM (IA64_PR0_REGNUM + 34)
-#define IA64_PR35_REGNUM (IA64_PR0_REGNUM + 35)
-#define IA64_PR36_REGNUM (IA64_PR0_REGNUM + 36)
-#define IA64_PR37_REGNUM (IA64_PR0_REGNUM + 37)
-#define IA64_PR38_REGNUM (IA64_PR0_REGNUM + 38)
-#define IA64_PR39_REGNUM (IA64_PR0_REGNUM + 39)
-#define IA64_PR40_REGNUM (IA64_PR0_REGNUM + 40)
-#define IA64_PR41_REGNUM (IA64_PR0_REGNUM + 41)
-#define IA64_PR42_REGNUM (IA64_PR0_REGNUM + 42)
-#define IA64_PR43_REGNUM (IA64_PR0_REGNUM + 43)
-#define IA64_PR44_REGNUM (IA64_PR0_REGNUM + 44)
-#define IA64_PR45_REGNUM (IA64_PR0_REGNUM + 45)
-#define IA64_PR46_REGNUM (IA64_PR0_REGNUM + 46)
-#define IA64_PR47_REGNUM (IA64_PR0_REGNUM + 47)
-#define IA64_PR48_REGNUM (IA64_PR0_REGNUM + 48)
-#define IA64_PR49_REGNUM (IA64_PR0_REGNUM + 49)
-#define IA64_PR50_REGNUM (IA64_PR0_REGNUM + 50)
-#define IA64_PR51_REGNUM (IA64_PR0_REGNUM + 51)
-#define IA64_PR52_REGNUM (IA64_PR0_REGNUM + 52)
-#define IA64_PR53_REGNUM (IA64_PR0_REGNUM + 53)
-#define IA64_PR54_REGNUM (IA64_PR0_REGNUM + 54)
-#define IA64_PR55_REGNUM (IA64_PR0_REGNUM + 55)
-#define IA64_PR56_REGNUM (IA64_PR0_REGNUM + 56)
-#define IA64_PR57_REGNUM (IA64_PR0_REGNUM + 57)
-#define IA64_PR58_REGNUM (IA64_PR0_REGNUM + 58)
-#define IA64_PR59_REGNUM (IA64_PR0_REGNUM + 59)
-#define IA64_PR60_REGNUM (IA64_PR0_REGNUM + 60)
-#define IA64_PR61_REGNUM (IA64_PR0_REGNUM + 61)
-#define IA64_PR62_REGNUM (IA64_PR0_REGNUM + 62)
-#define IA64_PR63_REGNUM (IA64_PR0_REGNUM + 63)
-
-/* Branch registers: 8 64-bit registers for holding branch targets. */
-#define IA64_BR0_REGNUM 320
-#define IA64_BR1_REGNUM (IA64_BR0_REGNUM + 1)
-#define IA64_BR2_REGNUM (IA64_BR0_REGNUM + 2)
-#define IA64_BR3_REGNUM (IA64_BR0_REGNUM + 3)
-#define IA64_BR4_REGNUM (IA64_BR0_REGNUM + 4)
-#define IA64_BR5_REGNUM (IA64_BR0_REGNUM + 5)
-#define IA64_BR6_REGNUM (IA64_BR0_REGNUM + 6)
-#define IA64_BR7_REGNUM (IA64_BR0_REGNUM + 7)
-
-/* Virtual frame pointer; this matches IA64_FRAME_POINTER_REGNUM in
- gcc/config/ia64/ia64.h. */
-#define IA64_VFP_REGNUM 328
-
-/* Virtual return address pointer; this matches
- IA64_RETURN_ADDRESS_POINTER_REGNUM in gcc/config/ia64/ia64.h. */
-#define IA64_VRAP_REGNUM 329
-
-/* Predicate registers: There are 64 of these 1-bit registers. We
- define a single register which is used to communicate these values
- to/from the target. We will somehow contrive to make it appear
- that IA64_PR0_REGNUM thru IA64_PR63_REGNUM hold the actual values. */
-#define IA64_PR_REGNUM 330
-
-/* Instruction pointer: 64 bits wide. */
-#define IA64_IP_REGNUM 331
-
-/* Process Status Register. */
-#define IA64_PSR_REGNUM 332
-
-/* Current Frame Marker (raw form may be the cr.ifs). */
-#define IA64_CFM_REGNUM 333
-
-/* Application registers; 128 64-bit wide registers possible, but some
- of them are reserved. */
-#define IA64_AR0_REGNUM 334
-#define IA64_KR0_REGNUM (IA64_AR0_REGNUM + 0)
-#define IA64_KR7_REGNUM (IA64_KR0_REGNUM + 7)
-
-#define IA64_RSC_REGNUM (IA64_AR0_REGNUM + 16)
-#define IA64_BSP_REGNUM (IA64_AR0_REGNUM + 17)
-#define IA64_BSPSTORE_REGNUM (IA64_AR0_REGNUM + 18)
-#define IA64_RNAT_REGNUM (IA64_AR0_REGNUM + 19)
-#define IA64_FCR_REGNUM (IA64_AR0_REGNUM + 21)
-#define IA64_EFLAG_REGNUM (IA64_AR0_REGNUM + 24)
-#define IA64_CSD_REGNUM (IA64_AR0_REGNUM + 25)
-#define IA64_SSD_REGNUM (IA64_AR0_REGNUM + 26)
-#define IA64_CFLG_REGNUM (IA64_AR0_REGNUM + 27)
-#define IA64_FSR_REGNUM (IA64_AR0_REGNUM + 28)
-#define IA64_FIR_REGNUM (IA64_AR0_REGNUM + 29)
-#define IA64_FDR_REGNUM (IA64_AR0_REGNUM + 30)
-#define IA64_CCV_REGNUM (IA64_AR0_REGNUM + 32)
-#define IA64_UNAT_REGNUM (IA64_AR0_REGNUM + 36)
-#define IA64_FPSR_REGNUM (IA64_AR0_REGNUM + 40)
-#define IA64_ITC_REGNUM (IA64_AR0_REGNUM + 44)
-#define IA64_PFS_REGNUM (IA64_AR0_REGNUM + 64)
-#define IA64_LC_REGNUM (IA64_AR0_REGNUM + 65)
-#define IA64_EC_REGNUM (IA64_AR0_REGNUM + 66)
-
-/* NAT (Not A Thing) Bits for the general registers; there are 128 of
- these. */
-#define IA64_NAT0_REGNUM 462
-#define IA64_NAT31_REGNUM (IA64_NAT0_REGNUM + 31)
-#define IA64_NAT32_REGNUM (IA64_NAT0_REGNUM + 32)
-#define IA64_NAT127_REGNUM (IA64_NAT0_REGNUM + 127)
-
-class frame_info_ptr;
-struct regcache;
-
-/* A struct containing pointers to all the target-dependent operations
- performed to setup an inferior function call. */
-
-struct ia64_infcall_ops
-{
- /* Allocate a new register stack frame starting after the output
- region of the current frame. The new frame will contain SOF
- registers, all in the output region. This is one way of protecting
- the stacked registers of the current frame.
-
- Should do nothing if this operation is not permitted by the OS. */
- void (*allocate_new_rse_frame) (struct regcache *regcache, ULONGEST bsp,
- int sof);
-
- /* Store the argument stored in BUF into the appropriate location
- given the BSP and the SLOTNUM. */
- void (*store_argument_in_slot) (struct regcache *regcache, CORE_ADDR bsp,
- int slotnum, gdb_byte *buf);
-
- /* For targets where we cannot call the function directly, store
- the address of the function we want to call at the location
- expected by the calling sequence. */
- void (*set_function_addr) (struct regcache *regcache, CORE_ADDR func_addr);
-};
-
-struct ia64_gdbarch_tdep : gdbarch_tdep_base
-{
- CORE_ADDR (*sigcontext_register_address) (struct gdbarch *, CORE_ADDR, int)
- = nullptr;
- int (*pc_in_sigtramp) (CORE_ADDR) = nullptr;
-
- /* Return the total size of THIS_FRAME's register frame.
- CFM is THIS_FRAME's cfm register value.
-
- Normally, the size of the register frame is always obtained by
- extracting the lowest 7 bits ("cfm & 0x7f"). */
- int (*size_of_register_frame) (const frame_info_ptr &this_frame, ULONGEST cfm)
- = nullptr;
-
- /* Determine the function address FADDR belongs to a shared library.
- If it does, then return the associated global pointer. If no shared
- library was found to contain that function, then return zero.
-
- This pointer may be NULL. */
- CORE_ADDR (*find_global_pointer_from_solib) (struct gdbarch *gdbarch,
- CORE_ADDR faddr) = nullptr;
-
- /* ISA-specific data types. */
- struct type *ia64_ext_type = nullptr;
-
- struct ia64_infcall_ops infcall_ops {};
-};
-
-extern void ia64_write_pc (struct regcache *, CORE_ADDR);
-
-#ifdef HAVE_LIBUNWIND_IA64_H
-extern unw_accessors_t ia64_unw_accessors;
-extern unw_accessors_t ia64_unw_rse_accessors;
-extern struct libunwind_descr ia64_libunwind_descr;
-#endif
-
-#endif /* ia64-tdep.h */
deleted file mode 100644
@@ -1,162 +0,0 @@
-/* Target-dependent code for OpenVMS IA-64.
-
- Copyright (C) 2012-2024 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 "frame-unwind.h"
-#include "ia64-tdep.h"
-#include "osabi.h"
-#include "gdbtypes.h"
-#include "gdbcore.h"
-#include "gdbarch.h"
-
-#ifdef HAVE_LIBUNWIND_IA64_H
-
-/* Libunwind callback accessor function to acquire procedure unwind-info. */
-
-static int
-ia64_vms_find_proc_info_x (unw_addr_space_t as, unw_word_t ip,
- unw_proc_info_t *pi,
- int need_unwind_info, void *arg)
-{
- bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
- gdb_byte buf[32];
- const char *annex = core_addr_to_string (ip);
- LONGEST res;
- CORE_ADDR table_addr;
- unsigned int info_len;
-
- res = target_read (current_inferior ()->top_target (),
- TARGET_OBJECT_OPENVMS_UIB,
- annex + 2, buf, 0, sizeof (buf));
-
- if (res != sizeof (buf))
- return -UNW_ENOINFO;
-
- pi->format = UNW_INFO_FORMAT_REMOTE_TABLE;
- pi->start_ip = extract_unsigned_integer (buf + 0, 8, byte_order);
- pi->end_ip = extract_unsigned_integer (buf + 8, 8, byte_order);
- pi->gp = extract_unsigned_integer (buf + 24, 8, byte_order);
- table_addr = extract_unsigned_integer (buf + 16, 8, byte_order);
-
- if (table_addr == 0)
- {
- /* No unwind data. */
- pi->unwind_info = NULL;
- pi->unwind_info_size = 0;
- return 0;
- }
-
- res = target_read_memory (table_addr, buf, 8);
- if (res != 0)
- return -UNW_ENOINFO;
-
- /* Check version. */
- if (extract_unsigned_integer (buf + 6, 2, byte_order) != 1)
- return -UNW_EBADVERSION;
- info_len = extract_unsigned_integer (buf + 0, 4, byte_order);
- pi->unwind_info_size = 8 * info_len;
-
- /* Read info. */
- pi->unwind_info = xmalloc (pi->unwind_info_size);
-
- res = target_read_memory (table_addr + 8,
- (gdb_byte *) pi->unwind_info, pi->unwind_info_size);
- if (res != 0)
- {
- xfree (pi->unwind_info);
- pi->unwind_info = NULL;
- return -UNW_ENOINFO;
- }
-
- /* FIXME: Handle OSSD (OS Specific Data). This extension to ia64 unwind
- information by OpenVMS is currently not handled by libunwind, but
- looks to be used only in very specific context, and is not generated by
- GCC. */
-
- pi->lsda = table_addr + 8 + pi->unwind_info_size;
- if (extract_unsigned_integer (buf + 4, 2, byte_order) & 3)
- {
- pi->lsda += 8;
- /* There might be an handler, but this is not used for unwinding. */
- pi->handler = 0;
- }
-
- return 0;
-}
-
-/* Libunwind callback accessor function for cleanup. */
-
-static void
-ia64_vms_put_unwind_info (unw_addr_space_t as,
- unw_proc_info_t *pip, void *arg)
-{
- /* Nothing required for now. */
-}
-
-/* Libunwind callback accessor function to get head of the dynamic
- unwind-info registration list. */
-
-static int
-ia64_vms_get_dyn_info_list (unw_addr_space_t as,
- unw_word_t *dilap, void *arg)
-{
- return -UNW_ENOINFO;
-}
-
-/* Set of libunwind callback acccessor functions. */
-static unw_accessors_t ia64_vms_unw_accessors;
-static unw_accessors_t ia64_vms_unw_rse_accessors;
-
-/* Set of ia64-libunwind-tdep gdb callbacks and data for generic
- ia64-libunwind-tdep code to use. */
-static struct libunwind_descr ia64_vms_libunwind_descr;
-
-#endif /* HAVE_LIBUNWIND_IA64_H */
-
-static void
-ia64_openvms_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
-
-#ifdef HAVE_LIBUNWIND_IA64_H
- /* Override the default descriptor. */
- ia64_vms_unw_accessors = ia64_unw_accessors;
- ia64_vms_unw_accessors.find_proc_info = ia64_vms_find_proc_info_x;
- ia64_vms_unw_accessors.put_unwind_info = ia64_vms_put_unwind_info;
- ia64_vms_unw_accessors.get_dyn_info_list_addr = ia64_vms_get_dyn_info_list;
-
- ia64_vms_unw_rse_accessors = ia64_unw_rse_accessors;
- ia64_vms_unw_rse_accessors.find_proc_info = ia64_vms_find_proc_info_x;
- ia64_vms_unw_rse_accessors.put_unwind_info = ia64_vms_put_unwind_info;
- ia64_vms_unw_rse_accessors.get_dyn_info_list_addr = ia64_vms_get_dyn_info_list;
-
- ia64_vms_libunwind_descr = ia64_libunwind_descr;
- ia64_vms_libunwind_descr.accessors = &ia64_vms_unw_accessors;
- ia64_vms_libunwind_descr.special_accessors = &ia64_vms_unw_rse_accessors;
-
- libunwind_frame_set_descr (gdbarch, &ia64_vms_libunwind_descr);
-#endif
-}
-
-void _initialize_ia64_vms_tdep ();
-void
-_initialize_ia64_vms_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_OPENVMS,
- ia64_openvms_init_abi);
-}
@@ -466,9 +466,6 @@ inf_ptrace_target::xfer_partial (enum target_object object,
offset, len);
return *xfered_len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
- case TARGET_OBJECT_UNWIND_TABLE:
- return TARGET_XFER_E_IO;
-
case TARGET_OBJECT_AUXV:
#if defined (PT_IO) && defined (PIOD_READ_AUXV)
/* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO
@@ -278,13 +278,8 @@ linux_fork_to_function (gdb_byte *child_stack, int (*function) (void *))
child_stack = (gdb_byte *) xmalloc (STACK_SIZE * 4);
/* Use CLONE_VM instead of fork, to support uClinux (no MMU). */
-#ifdef __ia64__
- child_pid = __clone2 (function, child_stack, STACK_SIZE,
- CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);
-#else /* !__ia64__ */
child_pid = clone (function, child_stack + STACK_SIZE,
CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);
-#endif /* !__ia64__ */
#else /* !defined(__UCLIBC) && defined(HAS_NOMMU) */
child_pid = fork ();
@@ -2132,8 +2132,7 @@ cooked_write_test (struct gdbarch *gdbarch)
|| type->code () == TYPE_CODE_UNION
|| type->code () == TYPE_CODE_STRUCT)
{
- if (bfd_arch == bfd_arch_ia64
- || (regnum >= gdbarch_num_regs (gdbarch)
+ if ((regnum >= gdbarch_num_regs (gdbarch)
&& (bfd_arch == bfd_arch_xtensa
|| bfd_arch == bfd_arch_bfin
|| bfd_arch == bfd_arch_m32c
deleted file mode 100644
@@ -1,475 +0,0 @@
-name:ia64
-expedite:ip,psr,r12,bsp,cfm
-64:r0
-64:r1
-64:r2
-64:r3
-64:r4
-64:r5
-64:r6
-64:r7
-64:r8
-64:r9
-64:r10
-64:r11
-64:r12
-64:r13
-64:r14
-64:r15
-64:r16
-64:r17
-64:r18
-64:r19
-64:r20
-64:r21
-64:r22
-64:r23
-64:r24
-64:r25
-64:r26
-64:r27
-64:r28
-64:r29
-64:r30
-64:r31
-64:r32
-64:r33
-64:r34
-64:r35
-64:r36
-64:r37
-64:r38
-64:r39
-64:r40
-64:r41
-64:r42
-64:r43
-64:r44
-64:r45
-64:r46
-64:r47
-64:r48
-64:r49
-64:r50
-64:r51
-64:r52
-64:r53
-64:r54
-64:r55
-64:r56
-64:r57
-64:r58
-64:r59
-64:r60
-64:r61
-64:r62
-64:r63
-64:r64
-64:r65
-64:r66
-64:r67
-64:r68
-64:r69
-64:r70
-64:r71
-64:r72
-64:r73
-64:r74
-64:r75
-64:r76
-64:r77
-64:r78
-64:r79
-64:r80
-64:r81
-64:r82
-64:r83
-64:r84
-64:r85
-64:r86
-64:r87
-64:r88
-64:r89
-64:r90
-64:r91
-64:r92
-64:r93
-64:r94
-64:r95
-64:r96
-64:r97
-64:r98
-64:r99
-64:r100
-64:r101
-64:r102
-64:r103
-64:r104
-64:r105
-64:r106
-64:r107
-64:r108
-64:r109
-64:r110
-64:r111
-64:r112
-64:r113
-64:r114
-64:r115
-64:r116
-64:r117
-64:r118
-64:r119
-64:r120
-64:r121
-64:r122
-64:r123
-64:r124
-64:r125
-64:r126
-64:r127
-
-128:f0
-128:f1
-128:f2
-128:f3
-128:f4
-128:f5
-128:f6
-128:f7
-128:f8
-128:f9
-128:f10
-128:f11
-128:f12
-128:f13
-128:f14
-128:f15
-128:f16
-128:f17
-128:f18
-128:f19
-128:f20
-128:f21
-128:f22
-128:f23
-128:f24
-128:f25
-128:f26
-128:f27
-128:f28
-128:f29
-128:f30
-128:f31
-128:f32
-128:f33
-128:f34
-128:f35
-128:f36
-128:f37
-128:f38
-128:f39
-128:f40
-128:f41
-128:f42
-128:f43
-128:f44
-128:f45
-128:f46
-128:f47
-128:f48
-128:f49
-128:f50
-128:f51
-128:f52
-128:f53
-128:f54
-128:f55
-128:f56
-128:f57
-128:f58
-128:f59
-128:f60
-128:f61
-128:f62
-128:f63
-128:f64
-128:f65
-128:f66
-128:f67
-128:f68
-128:f69
-128:f70
-128:f71
-128:f72
-128:f73
-128:f74
-128:f75
-128:f76
-128:f77
-128:f78
-128:f79
-128:f80
-128:f81
-128:f82
-128:f83
-128:f84
-128:f85
-128:f86
-128:f87
-128:f88
-128:f89
-128:f90
-128:f91
-128:f92
-128:f93
-128:f94
-128:f95
-128:f96
-128:f97
-128:f98
-128:f99
-128:f100
-128:f101
-128:f102
-128:f103
-128:f104
-128:f105
-128:f106
-128:f107
-128:f108
-128:f109
-128:f110
-128:f111
-128:f112
-128:f113
-128:f114
-128:f115
-128:f116
-128:f117
-128:f118
-128:f119
-128:f120
-128:f121
-128:f122
-128:f123
-128:f124
-128:f125
-128:f126
-128:f127
-
-64:p0
-64:p1
-64:p2
-64:p3
-64:p4
-64:p5
-64:p6
-64:p7
-64:p8
-64:p9
-64:p10
-64:p11
-64:p12
-64:p13
-64:p14
-64:p15
-64:p16
-64:p17
-64:p18
-64:p19
-64:p20
-64:p21
-64:p22
-64:p23
-64:p24
-64:p25
-64:p26
-64:p27
-64:p28
-64:p29
-64:p30
-64:p31
-64:p32
-64:p33
-64:p34
-64:p35
-64:p36
-64:p37
-64:p38
-64:p39
-64:p40
-64:p41
-64:p42
-64:p43
-64:p44
-64:p45
-64:p46
-64:p47
-64:p48
-64:p49
-64:p50
-64:p51
-64:p52
-64:p53
-64:p54
-64:p55
-64:p56
-64:p57
-64:p58
-64:p59
-64:p60
-64:p61
-64:p62
-64:p63
-
-64:b0
-64:b1
-64:b2
-64:b3
-64:b4
-64:b5
-64:b6
-64:b7
-
-64:vfp
-64:vrap
-
-64:pr
-64:ip
-64:psr
-64:cfm
-
-64:kr0
-64:kr1
-64:kr2
-64:kr3
-64:kr4
-64:kr5
-64:kr6
-64:kr7
-
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-
-64:rsc
-64:bsp
-64:bspstore
-64:rnat
-
-64:
-64:fcr
-64:
-64:
-
-64:eflag
-64:csd
-64:ssd
-64:cflg
-64:fsr
-64:fir
-64:fdr
-64:
-64:ccv
-64:
-64:
-64:
-64:unat
-64:
-64:
-64:
-64:fpsr
-64:
-64:
-64:
-64:itc
-
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:pfs
-64:lc
-64:ec
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
-64:
deleted file mode 100644
@@ -1,2601 +0,0 @@
-/* GDB stub for Itanium OpenVMS
- Copyright (C) 2012-2024 Free Software Foundation, Inc.
-
- Contributed by Tristan Gingold, AdaCore.
-
- 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/>. */
-
-/* On VMS, the debugger (in our case the stub) is loaded in the process and
- executed (via SYS$IMGSTA) before the main entry point of the executable.
- In UNIX parlance, this is like using LD_PRELOAD and debug via installing
- SIGTRAP, SIGSEGV... handlers.
-
- This is currently a partial implementation. In particular, modifying
- registers is currently not implemented, as well as inferior procedure
- calls.
-
- This is written in very low-level C, in order not to use the C runtime,
- because it may have weird consequences on the program being debugged.
-*/
-
-#if __INITIAL_POINTER_SIZE != 64
-#error "Must be compiled with 64 bit pointers"
-#endif
-
-#define __NEW_STARLET 1
-#include <descrip.h>
-#include <iledef.h>
-#include <efndef.h>
-#include <in.h>
-#include <inet.h>
-#include <iodef.h>
-#include <ssdef.h>
-#include <starlet.h>
-#include <stsdef.h>
-#include <tcpip$inetdef.h>
-
-#include <lib$routines.h>
-#include <ots$routines.h>
-#include <str$routines.h>
-#include <libdef.h>
-#include <clidef.h>
-#include <iosbdef.h>
-#include <dvidef.h>
-#include <lnmdef.h>
-#include <builtins.h>
-#include <prtdef.h>
-#include <psldef.h>
-#include <chfdef.h>
-
-#include <lib_c/imcbdef.h>
-#include <lib_c/ldrimgdef.h>
-#include <lib_c/intstkdef.h>
-#include <lib_c/psrdef.h>
-#include <lib_c/ifddef.h>
-#include <lib_c/eihddef.h>
-
-#include <stdarg.h>
-#include <pthread_debug.h>
-
-#define VMS_PAGE_SIZE 0x2000
-#define VMS_PAGE_MASK (VMS_PAGE_SIZE - 1)
-
-/* Declared in lib$ots. */
-extern void ots$fill (void *addr, size_t len, unsigned char b);
-extern void ots$move (void *dst, size_t len, const void *src);
-extern int ots$strcmp_eql (const void *str1, size_t str1len,
- const void *str2, size_t str2len);
-
-/* Stub port number. */
-static unsigned int serv_port = 1234;
-
-/* DBGEXT structure. Not declared in any header. */
-struct dbgext_control_block
-{
- unsigned short dbgext$w_function_code;
-#define DBGEXT$K_NEXT_TASK 3
-#define DBGEXT$K_STOP_ALL_OTHER_TASKS 31
-#define DBGEXT$K_GET_REGS 33
- unsigned short dbgext$w_facility_id;
-#define CMA$_FACILITY 64
- unsigned int dbgext$l_status;
- unsigned int dbgext$l_flags;
- unsigned int dbgext$l_print_routine;
- unsigned int dbgext$l_evnt_code;
- unsigned int dbgext$l_evnt_name;
- unsigned int dbgext$l_evnt_entry;
- unsigned int dbgext$l_task_value;
- unsigned int dbgext$l_task_number;
- unsigned int dbgext$l_ada_flags;
- unsigned int dbgext$l_stop_value;
-#define dbgext$l_priority dbgext$l_stop_value;
-#define dbgext$l_symb_addr dbgext$l_stop_value;
-#define dbgext$l_time_slice dbgext$l_stop_value;
- unsigned int dbgext$l_active_registers;
-};
-
-#pragma pointer_size save
-#pragma pointer_size 32
-
-/* Pthread handler. */
-static int (*dbgext_func) (struct dbgext_control_block *blk);
-
-#pragma pointer_size restore
-
-/* Set to 1 if thread-aware. */
-static int has_threads;
-
-/* Current thread. */
-static pthread_t selected_thread;
-static pthreadDebugId_t selected_id;
-
-/* Internal debugging flags. */
-struct debug_flag
-{
- /* Name of the flag (as a string descriptor). */
- const struct dsc$descriptor_s name;
- /* Value. */
- int val;
-};
-
-/* Macro to define a debugging flag. */
-#define DEBUG_FLAG_ENTRY(str) \
- { { sizeof (str) - 1, DSC$K_DTYPE_T, DSC$K_CLASS_S, str }, 0}
-
-static struct debug_flag debug_flags[] =
-{
- /* Disp packets exchanged with gdb. */
- DEBUG_FLAG_ENTRY("packets"),
-#define trace_pkt (debug_flags[0].val)
- /* Display entry point informations. */
- DEBUG_FLAG_ENTRY("entry"),
-#define trace_entry (debug_flags[1].val)
- /* Be verbose about exceptions. */
- DEBUG_FLAG_ENTRY("excp"),
-#define trace_excp (debug_flags[2].val)
- /* Be verbose about unwinding. */
- DEBUG_FLAG_ENTRY("unwind"),
-#define trace_unwind (debug_flags[3].val)
- /* Display image at startup. */
- DEBUG_FLAG_ENTRY("images"),
-#define trace_images (debug_flags[4].val)
- /* Display pthread_debug info. */
- DEBUG_FLAG_ENTRY("pthreaddbg")
-#define trace_pthreaddbg (debug_flags[5].val)
-};
-
-#define NBR_DEBUG_FLAGS (sizeof (debug_flags) / sizeof (debug_flags[0]))
-
-/* Connect inet device I/O channel. */
-static unsigned short conn_channel;
-
-/* Widely used hex digit to ascii. */
-static const char hex[] = "0123456789abcdef";
-
-/* Socket characteristics. Apparently, there are no declaration for it in
- standard headers. */
-struct sockchar
-{
- unsigned short prot;
- unsigned char type;
- unsigned char af;
-};
-
-/* Chain of images loaded. */
-extern IMCB* ctl$gl_imglstptr;
-
-/* IA64 integer register representation. */
-union ia64_ireg
-{
- unsigned __int64 v;
- unsigned char b[8];
-};
-
-/* IA64 register numbers, as defined by ia64-tdep.h. */
-#define IA64_GR0_REGNUM 0
-#define IA64_GR32_REGNUM (IA64_GR0_REGNUM + 32)
-
-/* Floating point registers; 128 82-bit wide registers. */
-#define IA64_FR0_REGNUM 128
-
-/* Predicate registers; There are 64 of these one bit registers. It'd
- be more convenient (implementation-wise) to use a single 64 bit
- word with all of these register in them. Note that there's also a
- IA64_PR_REGNUM below which contains all the bits and is used for
- communicating the actual values to the target. */
-#define IA64_PR0_REGNUM 256
-
-/* Branch registers: 8 64-bit registers for holding branch targets. */
-#define IA64_BR0_REGNUM 320
-
-/* Virtual frame pointer; this matches IA64_FRAME_POINTER_REGNUM in
- gcc/config/ia64/ia64.h. */
-#define IA64_VFP_REGNUM 328
-
-/* Virtual return address pointer; this matches
- IA64_RETURN_ADDRESS_POINTER_REGNUM in gcc/config/ia64/ia64.h. */
-#define IA64_VRAP_REGNUM 329
-
-/* Predicate registers: There are 64 of these 1-bit registers. We
- define a single register which is used to communicate these values
- to/from the target. We will somehow contrive to make it appear
- that IA64_PR0_REGNUM thru IA64_PR63_REGNUM hold the actual values. */
-#define IA64_PR_REGNUM 330
-
-/* Instruction pointer: 64 bits wide. */
-#define IA64_IP_REGNUM 331
-
-/* Process Status Register. */
-#define IA64_PSR_REGNUM 332
-
-/* Current Frame Marker (raw form may be the cr.ifs). */
-#define IA64_CFM_REGNUM 333
-
-/* Application registers; 128 64-bit wide registers possible, but some
- of them are reserved. */
-#define IA64_AR0_REGNUM 334
-#define IA64_KR0_REGNUM (IA64_AR0_REGNUM + 0)
-#define IA64_KR7_REGNUM (IA64_KR0_REGNUM + 7)
-
-#define IA64_RSC_REGNUM (IA64_AR0_REGNUM + 16)
-#define IA64_BSP_REGNUM (IA64_AR0_REGNUM + 17)
-#define IA64_BSPSTORE_REGNUM (IA64_AR0_REGNUM + 18)
-#define IA64_RNAT_REGNUM (IA64_AR0_REGNUM + 19)
-#define IA64_FCR_REGNUM (IA64_AR0_REGNUM + 21)
-#define IA64_EFLAG_REGNUM (IA64_AR0_REGNUM + 24)
-#define IA64_CSD_REGNUM (IA64_AR0_REGNUM + 25)
-#define IA64_SSD_REGNUM (IA64_AR0_REGNUM + 26)
-#define IA64_CFLG_REGNUM (IA64_AR0_REGNUM + 27)
-#define IA64_FSR_REGNUM (IA64_AR0_REGNUM + 28)
-#define IA64_FIR_REGNUM (IA64_AR0_REGNUM + 29)
-#define IA64_FDR_REGNUM (IA64_AR0_REGNUM + 30)
-#define IA64_CCV_REGNUM (IA64_AR0_REGNUM + 32)
-#define IA64_UNAT_REGNUM (IA64_AR0_REGNUM + 36)
-#define IA64_FPSR_REGNUM (IA64_AR0_REGNUM + 40)
-#define IA64_ITC_REGNUM (IA64_AR0_REGNUM + 44)
-#define IA64_PFS_REGNUM (IA64_AR0_REGNUM + 64)
-#define IA64_LC_REGNUM (IA64_AR0_REGNUM + 65)
-#define IA64_EC_REGNUM (IA64_AR0_REGNUM + 66)
-
-/* NAT (Not A Thing) Bits for the general registers; there are 128 of
- these. */
-#define IA64_NAT0_REGNUM 462
-
-/* Process registers when a condition is caught. */
-struct ia64_all_regs
-{
- union ia64_ireg gr[32];
- union ia64_ireg br[8];
- union ia64_ireg ip;
- union ia64_ireg psr;
- union ia64_ireg bsp;
- union ia64_ireg cfm;
- union ia64_ireg pfs;
- union ia64_ireg pr;
-};
-
-static struct ia64_all_regs excp_regs;
-static struct ia64_all_regs sel_regs;
-static pthread_t sel_regs_pthread;
-
-/* IO channel for the terminal. */
-static unsigned short term_chan;
-
-/* Output buffer and length. */
-static char term_buf[128];
-static int term_buf_len;
-
-/* Buffer for communication with gdb. */
-static unsigned char gdb_buf[sizeof (struct ia64_all_regs) * 2 + 64];
-static unsigned int gdb_blen;
-
-/* Previous primary handler. */
-static void *prevhnd;
-
-/* Entry point address and bundle. */
-static unsigned __int64 entry_pc;
-static unsigned char entry_saved[16];
-
-/* Write on the terminal. */
-
-static void
-term_raw_write (const char *str, unsigned int len)
-{
- unsigned short status;
- struct _iosb iosb;
-
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- term_chan, /* I/O channel. */
- IO$_WRITEVBLK, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- (char *)str, /* P1 - buffer address. */
- len, /* P2 - buffer length. */
- 0, 0, 0, 0);
-
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
-}
-
-/* Flush ther term buffer. */
-
-static void
-term_flush (void)
-{
- if (term_buf_len != 0)
- {
- term_raw_write (term_buf, term_buf_len);
- term_buf_len = 0;
- }
-}
-
-/* Write a single character, without translation. */
-
-static void
-term_raw_putchar (char c)
-{
- if (term_buf_len == sizeof (term_buf))
- term_flush ();
- term_buf[term_buf_len++] = c;
-}
-
-/* Write character C. Translate '\n' to '\n\r'. */
-
-static void
-term_putc (char c)
-{
- if (c < 32)
- switch (c)
- {
- case '\r':
- case '\n':
- break;
- default:
- c = '.';
- break;
- }
- term_raw_putchar (c);
- if (c == '\n')
- {
- term_raw_putchar ('\r');
- term_flush ();
- }
-}
-
-/* Write a C string. */
-
-static void
-term_puts (const char *str)
-{
- while (*str)
- term_putc (*str++);
-}
-
-/* Write LEN bytes from STR. */
-
-static void
-term_write (const char *str, unsigned int len)
-{
- for (; len > 0; len--)
- term_putc (*str++);
-}
-
-/* Write using FAO formatting. */
-
-static void
-term_fao (const char *str, unsigned int str_len, ...)
-{
- int cnt;
- va_list vargs;
- int i;
- __int64 *args;
- int status;
- struct dsc$descriptor_s dstr =
- { str_len, DSC$K_DTYPE_T, DSC$K_CLASS_S, (__char_ptr32)str };
- char buf[128];
- $DESCRIPTOR (buf_desc, buf);
-
- va_start (vargs, str_len);
- va_count (cnt);
- args = (__int64 *) __ALLOCA (cnt * sizeof (__int64));
- cnt -= 2;
- for (i = 0; i < cnt; i++)
- args[i] = va_arg (vargs, __int64);
-
- status = sys$faol_64 (&dstr, &buf_desc.dsc$w_length, &buf_desc, args);
- if (status & 1)
- {
- /* FAO !/ already insert a line feed. */
- for (i = 0; i < buf_desc.dsc$w_length; i++)
- {
- term_raw_putchar (buf[i]);
- if (buf[i] == '\n')
- term_flush ();
- }
- }
-
- va_end (vargs);
-}
-
-#define TERM_FAO(STR, ...) term_fao (STR, sizeof (STR) - 1, __VA_ARGS__)
-
-/* New line. */
-
-static void
-term_putnl (void)
-{
- term_putc ('\n');
-}
-
-/* Initialize terminal. */
-
-static void
-term_init (void)
-{
- unsigned int status,i;
- unsigned short len;
- char resstring[LNM$C_NAMLENGTH];
- static const $DESCRIPTOR (tabdesc, "LNM$FILE_DEV");
- static const $DESCRIPTOR (logdesc, "SYS$OUTPUT");
- $DESCRIPTOR (term_desc, resstring);
- ILE3 item_lst[2];
-
- item_lst[0].ile3$w_length = LNM$C_NAMLENGTH;
- item_lst[0].ile3$w_code = LNM$_STRING;
- item_lst[0].ile3$ps_bufaddr = resstring;
- item_lst[0].ile3$ps_retlen_addr = &len;
- item_lst[1].ile3$w_length = 0;
- item_lst[1].ile3$w_code = 0;
-
- /* Translate the logical name. */
- status = SYS$TRNLNM (0, /* Attr of the logical name. */
- (void *) &tabdesc, /* Logical name table. */
- (void *) &logdesc, /* Logical name. */
- 0, /* Access mode. */
- item_lst); /* Item list. */
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
-
- term_desc.dsc$w_length = len;
-
- /* Examine 4-byte header. Skip escape sequence. */
- if (resstring[0] == 0x1B)
- {
- term_desc.dsc$w_length -= 4;
- term_desc.dsc$a_pointer += 4;
- }
-
- /* Assign a channel. */
- status = sys$assign (&term_desc, /* Device name. */
- &term_chan, /* I/O channel. */
- 0, /* Access mode. */
- 0);
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
-}
-
-/* Convert from native endianness to network endianness (and vice-versa). */
-
-static unsigned int
-wordswap (unsigned int v)
-{
- return ((v & 0xff) << 8) | ((v >> 8) & 0xff);
-}
-
-/* Initialize the socket connection, and wait for a client. */
-
-static void
-sock_init (void)
-{
- struct _iosb iosb;
- unsigned int status;
-
- /* Listen channel and characteristics. */
- unsigned short listen_channel;
- struct sockchar listen_sockchar;
-
- /* Client address. */
- unsigned short cli_addrlen;
- struct sockaddr_in cli_addr;
- ILE3 cli_itemlst;
-
- /* Our address. */
- struct sockaddr_in serv_addr;
- ILE2 serv_itemlst;
-
- /* Reuseaddr option value (on). */
- int optval = 1;
- ILE2 sockopt_itemlst;
- ILE2 reuseaddr_itemlst;
-
- /* TCP/IP network pseudodevice. */
- static const $DESCRIPTOR (inet_device, "TCPIP$DEVICE:");
-
- /* Initialize socket characteristics. */
- listen_sockchar.prot = TCPIP$C_TCP;
- listen_sockchar.type = TCPIP$C_STREAM;
- listen_sockchar.af = TCPIP$C_AF_INET;
-
- /* Assign I/O channels to network device. */
- status = sys$assign ((void *) &inet_device, &listen_channel, 0, 0);
- if (status & STS$M_SUCCESS)
- status = sys$assign ((void *) &inet_device, &conn_channel, 0, 0);
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to assign I/O channel(s)\n");
- LIB$SIGNAL (status);
- }
-
- /* Create a listen socket. */
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- listen_channel, /* I/O channel. */
- IO$_SETMODE, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- &listen_sockchar, /* P1 - socket characteristics. */
- 0, 0, 0, 0, 0);
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to create socket\n");
- LIB$SIGNAL (status);
- }
-
- /* Set reuse address option. */
- /* Initialize reuseaddr's item-list element. */
- reuseaddr_itemlst.ile2$w_length = sizeof (optval);
- reuseaddr_itemlst.ile2$w_code = TCPIP$C_REUSEADDR;
- reuseaddr_itemlst.ile2$ps_bufaddr = &optval;
-
- /* Initialize setsockopt's item-list descriptor. */
- sockopt_itemlst.ile2$w_length = sizeof (reuseaddr_itemlst);
- sockopt_itemlst.ile2$w_code = TCPIP$C_SOCKOPT;
- sockopt_itemlst.ile2$ps_bufaddr = &reuseaddr_itemlst;
-
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- listen_channel, /* I/O channel. */
- IO$_SETMODE, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- 0, /* P1. */
- 0, /* P2. */
- 0, /* P3. */
- 0, /* P4. */
- (__int64) &sockopt_itemlst, /* P5 - socket options. */
- 0);
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to set socket option\n");
- LIB$SIGNAL (status);
- }
-
- /* Bind server's ip address and port number to listen socket. */
- /* Initialize server's socket address structure. */
- ots$fill (&serv_addr, sizeof (serv_addr), 0);
- serv_addr.sin_family = TCPIP$C_AF_INET;
- serv_addr.sin_port = wordswap (serv_port);
- serv_addr.sin_addr.s_addr = TCPIP$C_INADDR_ANY;
-
- /* Initialize server's item-list descriptor. */
- serv_itemlst.ile2$w_length = sizeof (serv_addr);
- serv_itemlst.ile2$w_code = TCPIP$C_SOCK_NAME;
- serv_itemlst.ile2$ps_bufaddr = &serv_addr;
-
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- listen_channel, /* I/O channel. */
- IO$_SETMODE, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- 0, /* P1. */
- 0, /* P2. */
- (__int64) &serv_itemlst, /* P3 - local socket name. */
- 0, 0, 0);
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to bind socket\n");
- LIB$SIGNAL (status);
- }
-
- /* Set socket as a listen socket. */
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- listen_channel, /* I/O channel. */
- IO$_SETMODE, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- 0, /* P1. */
- 0, /* P2. */
- 0, /* P3. */
- 1, /* P4 - connection backlog. */
- 0, 0);
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to set socket passive\n");
- LIB$SIGNAL (status);
- }
-
- /* Accept connection from a client. */
- TERM_FAO ("Waiting for a client connection on port: !ZW!/",
- wordswap (serv_addr.sin_port));
-
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- listen_channel, /* I/O channel. */
- IO$_ACCESS|IO$M_ACCEPT, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- 0, /* P1. */
- 0, /* P2. */
- 0, /* P3. */
- (__int64) &conn_channel, /* P4 - I/O channel for conn. */
- 0, 0);
-
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to accept client connection\n");
- LIB$SIGNAL (status);
- }
-
- /* Log client connection request. */
- cli_itemlst.ile3$w_length = sizeof (cli_addr);
- cli_itemlst.ile3$w_code = TCPIP$C_SOCK_NAME;
- cli_itemlst.ile3$ps_bufaddr = &cli_addr;
- cli_itemlst.ile3$ps_retlen_addr = &cli_addrlen;
- ots$fill (&cli_addr, sizeof(cli_addr), 0);
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- conn_channel, /* I/O channel. */
- IO$_SENSEMODE, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- 0, /* P1. */
- 0, /* P2. */
- 0, /* P3. */
- (__int64) &cli_itemlst, /* P4 - peer socket name. */
- 0, 0);
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to get client name\n");
- LIB$SIGNAL (status);
- }
-
- TERM_FAO ("Accepted connection from host: !UB.!UB,!UB.!UB, port: !UW!/",
- (cli_addr.sin_addr.s_addr >> 0) & 0xff,
- (cli_addr.sin_addr.s_addr >> 8) & 0xff,
- (cli_addr.sin_addr.s_addr >> 16) & 0xff,
- (cli_addr.sin_addr.s_addr >> 24) & 0xff,
- wordswap (cli_addr.sin_port));
-}
-
-/* Close the socket. */
-
-static void
-sock_close (void)
-{
- struct _iosb iosb;
- unsigned int status;
-
- /* Close socket. */
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- conn_channel, /* I/O channel. */
- IO$_DEACCESS, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- 0, 0, 0, 0, 0, 0);
-
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to close socket\n");
- LIB$SIGNAL (status);
- }
-
- /* Deassign I/O channel to network device. */
- status = sys$dassgn (conn_channel);
-
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to deassign I/O channel\n");
- LIB$SIGNAL (status);
- }
-}
-
-/* Mark a page as R/W. Return old rights. */
-
-static unsigned int
-page_set_rw (unsigned __int64 startva, unsigned __int64 len,
- unsigned int *oldprot)
-{
- unsigned int status;
- unsigned __int64 retva;
- unsigned __int64 retlen;
-
- status = SYS$SETPRT_64 ((void *)startva, len, PSL$C_USER, PRT$C_UW,
- (void *)&retva, &retlen, oldprot);
- return status;
-}
-
-/* Restore page rights. */
-
-static void
-page_restore_rw (unsigned __int64 startva, unsigned __int64 len,
- unsigned int prot)
-{
- unsigned int status;
- unsigned __int64 retva;
- unsigned __int64 retlen;
- unsigned int oldprot;
-
- status = SYS$SETPRT_64 ((void *)startva, len, PSL$C_USER, prot,
- (void *)&retva, &retlen, &oldprot);
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
-}
-
-/* Get the TEB (thread environment block). */
-
-static pthread_t
-get_teb (void)
-{
- return (pthread_t)__getReg (_IA64_REG_TP);
-}
-
-/* Enable thread scheduling if VAL is true. */
-
-static unsigned int
-set_thread_scheduling (int val)
-{
- struct dbgext_control_block blk;
- unsigned int status;
-
- if (!dbgext_func)
- return 0;
-
- blk.dbgext$w_function_code = DBGEXT$K_STOP_ALL_OTHER_TASKS;
- blk.dbgext$w_facility_id = CMA$_FACILITY;
- blk.dbgext$l_stop_value = val;
-
- status = dbgext_func (&blk);
- if (!(status & STS$M_SUCCESS))
- {
- TERM_FAO ("set_thread_scheduling error, val=!SL, status=!XL!/",
- val, blk.dbgext$l_status);
- lib$signal (status);
- }
-
- return blk.dbgext$l_stop_value;
-}
-
-/* Get next thread (after THR). Start with 0. */
-
-static unsigned int
-thread_next (unsigned int thr)
-{
- struct dbgext_control_block blk;
- unsigned int status;
-
- if (!dbgext_func)
- return 0;
-
- blk.dbgext$w_function_code = DBGEXT$K_NEXT_TASK;
- blk.dbgext$w_facility_id = CMA$_FACILITY;
- blk.dbgext$l_ada_flags = 0;
- blk.dbgext$l_task_value = thr;
-
- status = dbgext_func (&blk);
- if (!(status & STS$M_SUCCESS))
- lib$signal (status);
-
- return blk.dbgext$l_task_value;
-}
-
-/* Pthread Debug callbacks. */
-
-static int
-read_callback (pthreadDebugClient_t context,
- pthreadDebugTargetAddr_t addr,
- pthreadDebugAddr_t buf,
- size_t size)
-{
- if (trace_pthreaddbg)
- TERM_FAO ("read_callback (!XH, !XH, !SL)!/", addr, buf, size);
- ots$move (buf, size, addr);
- return 0;
-}
-
-static int
-write_callback (pthreadDebugClient_t context,
- pthreadDebugTargetAddr_t addr,
- pthreadDebugLongConstAddr_t buf,
- size_t size)
-{
- if (trace_pthreaddbg)
- TERM_FAO ("write_callback (!XH, !XH, !SL)!/", addr, buf, size);
- ots$move (addr, size, buf);
- return 0;
-}
-
-static int
-suspend_callback (pthreadDebugClient_t context)
-{
- /* Always suspended. */
- return 0;
-}
-
-static int
-resume_callback (pthreadDebugClient_t context)
-{
- /* So no need to resume. */
- return 0;
-}
-
-static int
-kthdinfo_callback (pthreadDebugClient_t context,
- pthreadDebugKId_t kid,
- pthreadDebugKThreadInfo_p thread_info)
-{
- if (trace_pthreaddbg)
- term_puts ("kthinfo_callback");
- return ENOSYS;
-}
-
-static int
-hold_callback (pthreadDebugClient_t context,
- pthreadDebugKId_t kid)
-{
- if (trace_pthreaddbg)
- term_puts ("hold_callback");
- return ENOSYS;
-}
-
-static int
-unhold_callback (pthreadDebugClient_t context,
- pthreadDebugKId_t kid)
-{
- if (trace_pthreaddbg)
- term_puts ("unhold_callback");
- return ENOSYS;
-}
-
-static int
-getfreg_callback (pthreadDebugClient_t context,
- pthreadDebugFregs_t *reg,
- pthreadDebugKId_t kid)
-{
- if (trace_pthreaddbg)
- term_puts ("getfreg_callback");
- return ENOSYS;
-}
-
-static int
-setfreg_callback (pthreadDebugClient_t context,
- const pthreadDebugFregs_t *reg,
- pthreadDebugKId_t kid)
-{
- if (trace_pthreaddbg)
- term_puts ("setfreg_callback");
- return ENOSYS;
-}
-
-static int
-getreg_callback (pthreadDebugClient_t context,
- pthreadDebugRegs_t *reg,
- pthreadDebugKId_t kid)
-{
- if (trace_pthreaddbg)
- term_puts ("getreg_callback");
- return ENOSYS;
-}
-
-static int
-setreg_callback (pthreadDebugClient_t context,
- const pthreadDebugRegs_t *reg,
- pthreadDebugKId_t kid)
-{
- if (trace_pthreaddbg)
- term_puts ("setreg_callback");
- return ENOSYS;
-}
-
-static int
-output_callback (pthreadDebugClient_t context,
- pthreadDebugConstString_t line)
-{
- term_puts (line);
- term_putnl ();
- return 0;
-}
-
-static int
-error_callback (pthreadDebugClient_t context,
- pthreadDebugConstString_t line)
-{
- term_puts (line);
- term_putnl ();
- return 0;
-}
-
-static pthreadDebugAddr_t
-malloc_callback (pthreadDebugClient_t caller_context, size_t size)
-{
- unsigned int status;
- unsigned int res;
- int len;
-
- len = size + 16;
- status = lib$get_vm (&len, &res, 0);
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
- if (trace_pthreaddbg)
- TERM_FAO ("malloc_callback (!UL) -> !XA!/", size, res);
- *(unsigned int *)res = len;
- return (char *)res + 16;
-}
-
-static void
-free_callback (pthreadDebugClient_t caller_context, pthreadDebugAddr_t address)
-{
- unsigned int status;
- unsigned int res;
- int len;
-
- res = (unsigned int)address - 16;
- len = *(unsigned int *)res;
- if (trace_pthreaddbg)
- TERM_FAO ("free_callback (!XA)!/", address);
- status = lib$free_vm (&len, &res, 0);
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
-}
-
-static int
-speckthd_callback (pthreadDebugClient_t caller_context,
- pthreadDebugSpecialType_t type,
- pthreadDebugKId_t *kernel_tid)
-{
- return ENOTSUP;
-}
-
-static pthreadDebugCallbacks_t pthread_debug_callbacks = {
- PTHREAD_DEBUG_VERSION,
- read_callback,
- write_callback,
- suspend_callback,
- resume_callback,
- kthdinfo_callback,
- hold_callback,
- unhold_callback,
- getfreg_callback,
- setfreg_callback,
- getreg_callback,
- setreg_callback,
- output_callback,
- error_callback,
- malloc_callback,
- free_callback,
- speckthd_callback
-};
-
-/* Name of the pthread shared library. */
-static const $DESCRIPTOR (pthread_rtl_desc, "PTHREAD$RTL");
-
-/* List of symbols to extract from pthread debug library. */
-struct pthread_debug_entry
-{
- const unsigned int namelen;
- const __char_ptr32 name;
- __void_ptr32 func;
-};
-
-#define DEBUG_ENTRY(str) { sizeof(str) - 1, str, 0 }
-
-static struct pthread_debug_entry pthread_debug_entries[] = {
- DEBUG_ENTRY("pthreadDebugContextInit"),
- DEBUG_ENTRY("pthreadDebugThdSeqInit"),
- DEBUG_ENTRY("pthreadDebugThdSeqNext"),
- DEBUG_ENTRY("pthreadDebugThdSeqDestroy"),
- DEBUG_ENTRY("pthreadDebugThdGetInfo"),
- DEBUG_ENTRY("pthreadDebugThdGetInfoAddr"),
- DEBUG_ENTRY("pthreadDebugThdGetReg"),
- DEBUG_ENTRY("pthreadDebugCmd")
-};
-
-/* Pthread debug context. */
-static pthreadDebugContext_t debug_context;
-
-/* Wrapper around pthread debug entry points. */
-
-static int
-pthread_debug_thd_seq_init (pthreadDebugId_t *id)
-{
- return ((int (*)())pthread_debug_entries[1].func)
- (debug_context, id);
-}
-
-static int
-pthread_debug_thd_seq_next (pthreadDebugId_t *id)
-{
- return ((int (*)())pthread_debug_entries[2].func)
- (debug_context, id);
-}
-
-static int
-pthread_debug_thd_seq_destroy (void)
-{
- return ((int (*)())pthread_debug_entries[3].func)
- (debug_context);
-}
-
-static int
-pthread_debug_thd_get_info (pthreadDebugId_t id,
- pthreadDebugThreadInfo_t *info)
-{
- return ((int (*)())pthread_debug_entries[4].func)
- (debug_context, id, info);
-}
-
-static int
-pthread_debug_thd_get_info_addr (pthread_t thr,
- pthreadDebugThreadInfo_t *info)
-{
- return ((int (*)())pthread_debug_entries[5].func)
- (debug_context, thr, info);
-}
-
-static int
-pthread_debug_thd_get_reg (pthreadDebugId_t thr,
- pthreadDebugRegs_t *regs)
-{
- return ((int (*)())pthread_debug_entries[6].func)
- (debug_context, thr, regs);
-}
-
-static int
-stub_pthread_debug_cmd (const char *cmd)
-{
- return ((int (*)())pthread_debug_entries[7].func)
- (debug_context, cmd);
-}
-
-/* Show all the threads. */
-
-static void
-threads_show (void)
-{
- pthreadDebugId_t id;
- pthreadDebugThreadInfo_t info;
- int res;
-
- res = pthread_debug_thd_seq_init (&id);
- if (res != 0)
- {
- TERM_FAO ("seq init failed, res=!SL!/", res);
- return;
- }
- while (1)
- {
- if (pthread_debug_thd_get_info (id, &info) != 0)
- {
- TERM_FAO ("thd_get_info !SL failed!/", id);
- break;
- }
- if (pthread_debug_thd_seq_next (&id) != 0)
- break;
- }
- pthread_debug_thd_seq_destroy ();
-}
-
-/* Initialize pthread support. */
-
-static void
-threads_init (void)
-{
- static const $DESCRIPTOR (dbgext_desc, "PTHREAD$DBGEXT");
- static const $DESCRIPTOR (pthread_debug_desc, "PTHREAD$DBGSHR");
- static const $DESCRIPTOR (dbgsymtable_desc, "PTHREAD_DBG_SYMTABLE");
- int pthread_dbgext;
- int status;
- void *dbg_symtable;
- int i;
- void *caller_context = 0;
-
- status = lib$find_image_symbol
- ((void *) &pthread_rtl_desc, (void *) &dbgext_desc,
- (int *) &dbgext_func);
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
-
- status = lib$find_image_symbol
- ((void *) &pthread_rtl_desc, (void *) &dbgsymtable_desc,
- (int *) &dbg_symtable);
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
-
- /* Find entry points in pthread_debug. */
- for (i = 0;
- i < sizeof (pthread_debug_entries) / sizeof (pthread_debug_entries[0]);
- i++)
- {
- struct dsc$descriptor_s sym =
- { pthread_debug_entries[i].namelen,
- DSC$K_DTYPE_T, DSC$K_CLASS_S,
- pthread_debug_entries[i].name };
- status = lib$find_image_symbol
- ((void *) &pthread_debug_desc, (void *) &sym,
- (int *) &pthread_debug_entries[i].func);
- if (!(status & STS$M_SUCCESS))
- lib$signal (status);
- }
-
- if (trace_pthreaddbg)
- TERM_FAO ("debug symtable: !XH!/", dbg_symtable);
- status = ((int (*)()) pthread_debug_entries[0].func)
- (&caller_context, &pthread_debug_callbacks, dbg_symtable, &debug_context);
- if (status != 0)
- TERM_FAO ("cannot initialize pthread_debug: !UL!/", status);
- TERM_FAO ("pthread debug done!/", 0);
-}
-
-/* Convert an hexadecimal character to a nibble. Return -1 in case of
- error. */
-
-static int
-hex2nibble (unsigned char h)
-{
- if (h >= '0' && h <= '9')
- return h - '0';
- if (h >= 'A' && h <= 'F')
- return h - 'A' + 10;
- if (h >= 'a' && h <= 'f')
- return h - 'a' + 10;
- return -1;
-}
-
-/* Convert an hexadecimal 2 character string to a byte. Return -1 in case
- of error. */
-
-static int
-hex2byte (const unsigned char *p)
-{
- int h, l;
-
- h = hex2nibble (p[0]);
- l = hex2nibble (p[1]);
- if (h == -1 || l == -1)
- return -1;
- return (h << 4) | l;
-}
-
-/* Convert a byte V to a 2 character strings P. */
-
-static void
-byte2hex (unsigned char *p, unsigned char v)
-{
- p[0] = hex[v >> 4];
- p[1] = hex[v & 0xf];
-}
-
-/* Convert a quadword V to a 16 character strings P. */
-
-static void
-quad2hex (unsigned char *p, unsigned __int64 v)
-{
- int i;
- for (i = 0; i < 16; i++)
- {
- p[i] = hex[v >> 60];
- v <<= 4;
- }
-}
-
-static void
-long2pkt (unsigned int v)
-{
- int i;
-
- for (i = 0; i < 8; i++)
- {
- gdb_buf[gdb_blen + i] = hex[(v >> 28) & 0x0f];
- v <<= 4;
- }
- gdb_blen += 8;
-}
-
-/* Generate an error packet. */
-
-static void
-packet_error (unsigned int err)
-{
- gdb_buf[1] = 'E';
- byte2hex (gdb_buf + 2, err);
- gdb_blen = 4;
-}
-
-/* Generate an OK packet. */
-
-static void
-packet_ok (void)
-{
- gdb_buf[1] = 'O';
- gdb_buf[2] = 'K';
- gdb_blen = 3;
-}
-
-/* Append a register to the packet. */
-
-static void
-ireg2pkt (const unsigned char *p)
-{
- int i;
-
- for (i = 0; i < 8; i++)
- {
- byte2hex (gdb_buf + gdb_blen, p[i]);
- gdb_blen += 2;
- }
-}
-
-/* Append a C string (ASCIZ) to the packet. */
-
-static void
-str2pkt (const char *str)
-{
- while (*str)
- gdb_buf[gdb_blen++] = *str++;
-}
-
-/* Extract a number fro the packet. */
-
-static unsigned __int64
-pkt2val (const unsigned char *pkt, unsigned int *pos)
-{
- unsigned __int64 res = 0;
- unsigned int i;
-
- while (1)
- {
- int r = hex2nibble (pkt[*pos]);
-
- if (r < 0)
- return res;
- res = (res << 4) | r;
- (*pos)++;
- }
-}
-
-/* Append LEN bytes from B to the current gdb packet (encode in binary). */
-
-static void
-mem2bin (const unsigned char *b, unsigned int len)
-{
- unsigned int i;
- for (i = 0; i < len; i++)
- switch (b[i])
- {
- case '#':
- case '$':
- case '}':
- case '*':
- case 0:
- gdb_buf[gdb_blen++] = '}';
- gdb_buf[gdb_blen++] = b[i] ^ 0x20;
- break;
- default:
- gdb_buf[gdb_blen++] = b[i];
- break;
- }
-}
-
-/* Append LEN bytes from B to the current gdb packet (encode in hex). */
-
-static void
-mem2hex (const unsigned char *b, unsigned int len)
-{
- unsigned int i;
- for (i = 0; i < len; i++)
- {
- byte2hex (gdb_buf + gdb_blen, b[i]);
- gdb_blen += 2;
- }
-}
-
-/* Handle the 'q' packet. */
-
-static void
-handle_q_packet (const unsigned char *pkt, unsigned int pktlen)
-{
- /* For qfThreadInfo and qsThreadInfo. */
- static unsigned int first_thread;
- static unsigned int last_thread;
-
- static const char xfer_uib[] = "qXfer:uib:read:";
-#define XFER_UIB_LEN (sizeof (xfer_uib) - 1)
- static const char qfthreadinfo[] = "qfThreadInfo";
-#define QFTHREADINFO_LEN (sizeof (qfthreadinfo) - 1)
- static const char qsthreadinfo[] = "qsThreadInfo";
-#define QSTHREADINFO_LEN (sizeof (qsthreadinfo) - 1)
- static const char qthreadextrainfo[] = "qThreadExtraInfo,";
-#define QTHREADEXTRAINFO_LEN (sizeof (qthreadextrainfo) - 1)
- static const char qsupported[] = "qSupported:";
-#define QSUPPORTED_LEN (sizeof (qsupported) - 1)
-
- if (pktlen == 2 && pkt[1] == 'C')
- {
- /* Current thread. */
- gdb_buf[0] = '$';
- gdb_buf[1] = 'Q';
- gdb_buf[2] = 'C';
- gdb_blen = 3;
- if (has_threads)
- long2pkt ((unsigned long) get_teb ());
- return;
- }
- else if (pktlen > XFER_UIB_LEN
- && ots$strcmp_eql (pkt, XFER_UIB_LEN, xfer_uib, XFER_UIB_LEN))
- {
- /* Get unwind information block. */
- unsigned __int64 pc;
- unsigned int pos = XFER_UIB_LEN;
- unsigned int off;
- unsigned int len;
- union
- {
- unsigned char bytes[32];
- struct
- {
- unsigned __int64 code_start_va;
- unsigned __int64 code_end_va;
- unsigned __int64 uib_start_va;
- unsigned __int64 gp_value;
- } data;
- } uei;
- int res;
- int i;
-
- packet_error (0);
-
- pc = pkt2val (pkt, &pos);
- if (pkt[pos] != ':')
- return;
- pos++;
- off = pkt2val (pkt, &pos);
- if (pkt[pos] != ',' || off != 0)
- return;
- pos++;
- len = pkt2val (pkt, &pos);
- if (pkt[pos] != '#' || len != 0x20)
- return;
-
- res = SYS$GET_UNWIND_ENTRY_INFO (pc, &uei.data, 0);
- if (res == SS$_NODATA || res != SS$_NORMAL)
- ots$fill (uei.bytes, sizeof (uei.bytes), 0);
-
- if (trace_unwind)
- {
- TERM_FAO ("Unwind request for !XH, status=!XL, uib=!XQ, GP=!XQ!/",
- pc, res, uei.data.uib_start_va, uei.data.gp_value);
- }
-
- gdb_buf[0] = '$';
- gdb_buf[1] = 'l';
- gdb_blen = 2;
- mem2bin (uei.bytes, sizeof (uei.bytes));
- }
- else if (pktlen == QFTHREADINFO_LEN
- && ots$strcmp_eql (pkt, QFTHREADINFO_LEN,
- qfthreadinfo, QFTHREADINFO_LEN))
- {
- /* Get first thread(s). */
- gdb_buf[0] = '$';
- gdb_buf[1] = 'm';
- gdb_blen = 2;
-
- if (!has_threads)
- {
- gdb_buf[1] = 'l';
- return;
- }
- first_thread = thread_next (0);
- last_thread = first_thread;
- long2pkt (first_thread);
- }
- else if (pktlen == QSTHREADINFO_LEN
- && ots$strcmp_eql (pkt, QSTHREADINFO_LEN,
- qsthreadinfo, QSTHREADINFO_LEN))
- {
- /* Get subsequent threads. */
- gdb_buf[0] = '$';
- gdb_buf[1] = 'm';
- gdb_blen = 2;
- while (dbgext_func)
- {
- unsigned int res;
- res = thread_next (last_thread);
- if (res == first_thread)
- break;
- if (gdb_blen > 2)
- gdb_buf[gdb_blen++] = ',';
- long2pkt (res);
- last_thread = res;
- if (gdb_blen > sizeof (gdb_buf) - 16)
- break;
- }
-
- if (gdb_blen == 2)
- gdb_buf[1] = 'l';
- }
- else if (pktlen > QTHREADEXTRAINFO_LEN
- && ots$strcmp_eql (pkt, QTHREADEXTRAINFO_LEN,
- qthreadextrainfo, QTHREADEXTRAINFO_LEN))
- {
- /* Get extra info about a thread. */
- pthread_t thr;
- unsigned int pos = QTHREADEXTRAINFO_LEN;
- pthreadDebugThreadInfo_t info;
- int res;
-
- packet_error (0);
- if (!has_threads)
- return;
-
- thr = (pthread_t) pkt2val (pkt, &pos);
- if (pkt[pos] != '#')
- return;
- res = pthread_debug_thd_get_info_addr (thr, &info);
- if (res != 0)
- {
- TERM_FAO ("qThreadExtraInfo (!XH) failed: !SL!/", thr, res);
- return;
- }
- gdb_buf[0] = '$';
- gdb_blen = 1;
- mem2hex ((const unsigned char *)"VMS-thread", 11);
- }
- else if (pktlen > QSUPPORTED_LEN
- && ots$strcmp_eql (pkt, QSUPPORTED_LEN,
- qsupported, QSUPPORTED_LEN))
- {
- /* Get supported features. */
- pthread_t thr;
- unsigned int pos = QSUPPORTED_LEN;
- pthreadDebugThreadInfo_t info;
- int res;
-
- /* Ignore gdb features. */
- gdb_buf[0] = '$';
- gdb_blen = 1;
-
- str2pkt ("qXfer:uib:read+");
- return;
- }
- else
- {
- if (trace_pkt)
- {
- term_puts ("unknown <: ");
- term_write ((char *)pkt, pktlen);
- term_putnl ();
- }
- return;
- }
-}
-
-/* Handle the 'v' packet. */
-
-static int
-handle_v_packet (const unsigned char *pkt, unsigned int pktlen)
-{
- static const char vcontq[] = "vCont?";
-#define VCONTQ_LEN (sizeof (vcontq) - 1)
-
- if (pktlen == VCONTQ_LEN
- && ots$strcmp_eql (pkt, VCONTQ_LEN, vcontq, VCONTQ_LEN))
- {
- gdb_buf[0] = '$';
- gdb_blen = 1;
-
- str2pkt ("vCont;c;s");
- return 0;
- }
- else
- {
- if (trace_pkt)
- {
- term_puts ("unknown <: ");
- term_write ((char *)pkt, pktlen);
- term_putnl ();
- }
- return 0;
- }
-}
-
-/* Get regs for the selected thread. */
-
-static struct ia64_all_regs *
-get_selected_regs (void)
-{
- pthreadDebugRegs_t regs;
- int res;
-
- if (selected_thread == 0 || selected_thread == get_teb ())
- return &excp_regs;
-
- if (selected_thread == sel_regs_pthread)
- return &sel_regs;
-
- /* Read registers. */
- res = pthread_debug_thd_get_reg (selected_id, ®s);
- if (res != 0)
- {
- /* FIXME: return NULL ? */
- return &excp_regs;
- }
- sel_regs_pthread = selected_thread;
- sel_regs.gr[1].v = regs.gp;
- sel_regs.gr[4].v = regs.r4;
- sel_regs.gr[5].v = regs.r5;
- sel_regs.gr[6].v = regs.r6;
- sel_regs.gr[7].v = regs.r7;
- sel_regs.gr[12].v = regs.sp;
- sel_regs.br[0].v = regs.rp;
- sel_regs.br[1].v = regs.b1;
- sel_regs.br[2].v = regs.b2;
- sel_regs.br[3].v = regs.b3;
- sel_regs.br[4].v = regs.b4;
- sel_regs.br[5].v = regs.b5;
- sel_regs.ip.v = regs.ip;
- sel_regs.bsp.v = regs.bspstore; /* FIXME: it is correct ? */
- sel_regs.pfs.v = regs.pfs;
- sel_regs.pr.v = regs.pr;
- return &sel_regs;
-}
-
-/* Create a status packet. */
-
-static void
-packet_status (void)
-{
- gdb_blen = 0;
- if (has_threads)
- {
- str2pkt ("$T05thread:");
- long2pkt ((unsigned long) get_teb ());
- gdb_buf[gdb_blen++] = ';';
- }
- else
- str2pkt ("$S05");
-}
-
-/* Return 1 to continue. */
-
-static int
-handle_packet (unsigned char *pkt, unsigned int len)
-{
- unsigned int pos;
-
- /* By default, reply unsupported. */
- gdb_buf[0] = '$';
- gdb_blen = 1;
-
- pos = 1;
- switch (pkt[0])
- {
- case '?':
- if (len == 1)
- {
- packet_status ();
- return 0;
- }
- break;
- case 'c':
- if (len == 1)
- {
- /* Clear psr.ss. */
- excp_regs.psr.v &= ~(unsigned __int64)PSR$M_SS;
- return 1;
- }
- else
- packet_error (0);
- break;
- case 'g':
- if (len == 1)
- {
- unsigned int i;
- struct ia64_all_regs *regs = get_selected_regs ();
- unsigned char *p = regs->gr[0].b;
-
- for (i = 0; i < 8 * 32; i++)
- byte2hex (gdb_buf + 1 + 2 * i, p[i]);
- gdb_blen += 2 * 8 * 32;
- return 0;
- }
- break;
- case 'H':
- if (pkt[1] == 'g')
- {
- int res;
- unsigned __int64 val;
- pthreadDebugThreadInfo_t info;
-
- pos++;
- val = pkt2val (pkt, &pos);
- if (pos != len)
- {
- packet_error (0);
- return 0;
- }
- if (val == 0)
- {
- /* Default one. */
- selected_thread = get_teb ();
- selected_id = 0;
- }
- else if (!has_threads)
- {
- packet_error (0);
- return 0;
- }
- else
- {
- res = pthread_debug_thd_get_info_addr ((pthread_t) val, &info);
- if (res != 0)
- {
- TERM_FAO ("qThreadExtraInfo (!XH) failed: !SL!/", val, res);
- packet_error (0);
- return 0;
- }
- selected_thread = info.teb;
- selected_id = info.sequence;
- }
- packet_ok ();
- break;
- }
- else if (pkt[1] == 'c'
- && ((pkt[2] == '-' && pkt[3] == '1' && len == 4)
- || (pkt[2] == '0' && len == 3)))
- {
- /* Silently accept 'Hc0' and 'Hc-1'. */
- packet_ok ();
- break;
- }
- else
- {
- packet_error (0);
- return 0;
- }
- case 'k':
- SYS$EXIT (SS$_NORMAL);
- break;
- case 'm':
- {
- unsigned __int64 addr;
- unsigned __int64 paddr;
- unsigned int l;
- unsigned int i;
-
- addr = pkt2val (pkt, &pos);
- if (pkt[pos] != ',')
- {
- packet_error (0);
- return 0;
- }
- pos++;
- l = pkt2val (pkt, &pos);
- if (pkt[pos] != '#')
- {
- packet_error (0);
- return 0;
- }
-
- /* Check access. */
- i = l + (addr & VMS_PAGE_MASK);
- paddr = addr & ~VMS_PAGE_MASK;
- while (1)
- {
- if (__prober (paddr, 0) != 1)
- {
- packet_error (2);
- return 0;
- }
- if (i < VMS_PAGE_SIZE)
- break;
- i -= VMS_PAGE_SIZE;
- paddr += VMS_PAGE_SIZE;
- }
-
- /* Transfer. */
- for (i = 0; i < l; i++)
- byte2hex (gdb_buf + 1 + 2 * i, ((unsigned char *)addr)[i]);
- gdb_blen += 2 * l;
- }
- break;
- case 'M':
- {
- unsigned __int64 addr;
- unsigned __int64 paddr;
- unsigned int l;
- unsigned int i;
- unsigned int oldprot;
-
- addr = pkt2val (pkt, &pos);
- if (pkt[pos] != ',')
- {
- packet_error (0);
- return 0;
- }
- pos++;
- l = pkt2val (pkt, &pos);
- if (pkt[pos] != ':')
- {
- packet_error (0);
- return 0;
- }
- pos++;
- page_set_rw (addr, l, &oldprot);
-
- /* Check access. */
- i = l + (addr & VMS_PAGE_MASK);
- paddr = addr & ~VMS_PAGE_MASK;
- while (1)
- {
- if (__probew (paddr, 0) != 1)
- {
- page_restore_rw (addr, l, oldprot);
- return 0;
- }
- if (i < VMS_PAGE_SIZE)
- break;
- i -= VMS_PAGE_SIZE;
- paddr += VMS_PAGE_SIZE;
- }
-
- /* Write. */
- for (i = 0; i < l; i++)
- {
- int v = hex2byte (pkt + pos);
- pos += 2;
- ((unsigned char *)addr)[i] = v;
- }
-
- /* Sync caches. */
- for (i = 0; i < l; i += 15)
- __fc (addr + i);
- __fc (addr + l);
-
- page_restore_rw (addr, l, oldprot);
- packet_ok ();
- }
- break;
- case 'p':
- {
- unsigned int num = 0;
- unsigned int i;
- struct ia64_all_regs *regs = get_selected_regs ();
-
- num = pkt2val (pkt, &pos);
- if (pos != len)
- {
- packet_error (0);
- return 0;
- }
-
- switch (num)
- {
- case IA64_IP_REGNUM:
- ireg2pkt (regs->ip.b);
- break;
- case IA64_BR0_REGNUM:
- ireg2pkt (regs->br[0].b);
- break;
- case IA64_PSR_REGNUM:
- ireg2pkt (regs->psr.b);
- break;
- case IA64_BSP_REGNUM:
- ireg2pkt (regs->bsp.b);
- break;
- case IA64_CFM_REGNUM:
- ireg2pkt (regs->cfm.b);
- break;
- case IA64_PFS_REGNUM:
- ireg2pkt (regs->pfs.b);
- break;
- case IA64_PR_REGNUM:
- ireg2pkt (regs->pr.b);
- break;
- default:
- TERM_FAO ("gdbserv: unhandled reg !UW!/", num);
- packet_error (0);
- return 0;
- }
- }
- break;
- case 'q':
- handle_q_packet (pkt, len);
- break;
- case 's':
- if (len == 1)
- {
- /* Set psr.ss. */
- excp_regs.psr.v |= (unsigned __int64)PSR$M_SS;
- return 1;
- }
- else
- packet_error (0);
- break;
- case 'T':
- /* Thread status. */
- if (!has_threads)
- {
- packet_ok ();
- break;
- }
- else
- {
- int res;
- unsigned __int64 val;
- unsigned int fthr, thr;
-
- val = pkt2val (pkt, &pos);
- /* Default is error (but only after parsing is complete). */
- packet_error (0);
- if (pos != len)
- break;
-
- /* Follow the list. This makes a O(n2) algorithm, but we don't really
- have the choice. Note that pthread_debug_thd_get_info_addr
- doesn't look reliable. */
- fthr = thread_next (0);
- thr = fthr;
- do
- {
- if (val == thr)
- {
- packet_ok ();
- break;
- }
- thr = thread_next (thr);
- }
- while (thr != fthr);
- }
- break;
- case 'v':
- return handle_v_packet (pkt, len);
- break;
- case 'V':
- if (len > 3 && pkt[1] == 'M' && pkt[2] == 'S' && pkt[3] == ' ')
- {
- /* Temporary extension. */
- if (has_threads)
- {
- pkt[len] = 0;
- stub_pthread_debug_cmd ((char *)pkt + 4);
- packet_ok ();
- }
- else
- packet_error (0);
- }
- break;
- default:
- if (trace_pkt)
- {
- term_puts ("unknown <: ");
- term_write ((char *)pkt, len);
- term_putnl ();
- }
- break;
- }
- return 0;
-}
-
-/* Raw write to gdb. */
-
-static void
-sock_write (const unsigned char *buf, int len)
-{
- struct _iosb iosb;
- unsigned int status;
-
- /* Write data to connection. */
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- conn_channel, /* I/O channel. */
- IO$_WRITEVBLK, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- (char *)buf, /* P1 - buffer address. */
- len, /* P2 - buffer length. */
- 0, 0, 0, 0);
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to write data to gdb\n");
- LIB$SIGNAL (status);
- }
-}
-
-/* Compute the checksum and send the packet. */
-
-static void
-send_pkt (void)
-{
- unsigned char chksum = 0;
- unsigned int i;
-
- for (i = 1; i < gdb_blen; i++)
- chksum += gdb_buf[i];
-
- gdb_buf[gdb_blen] = '#';
- byte2hex (gdb_buf + gdb_blen + 1, chksum);
-
- sock_write (gdb_buf, gdb_blen + 3);
-
- if (trace_pkt > 1)
- {
- term_puts (">: ");
- term_write ((char *)gdb_buf, gdb_blen + 3);
- term_putnl ();
- }
-}
-
-/* Read and handle one command. Return 1 is execution must resume. */
-
-static int
-one_command (void)
-{
- struct _iosb iosb;
- unsigned int status;
- unsigned int off;
- unsigned int dollar_off = 0;
- unsigned int sharp_off = 0;
- unsigned int cmd_off;
- unsigned int cmd_len;
-
- /* Wait for a packet. */
- while (1)
- {
- off = 0;
- while (1)
- {
- /* Read data from connection. */
- status = sys$qiow (EFN$C_ENF, /* Event flag. */
- conn_channel, /* I/O channel. */
- IO$_READVBLK, /* I/O function code. */
- &iosb, /* I/O status block. */
- 0, /* Ast service routine. */
- 0, /* Ast parameter. */
- gdb_buf + off, /* P1 - buffer address. */
- sizeof (gdb_buf) - off, /* P2 - buffer leng. */
- 0, 0, 0, 0);
- if (status & STS$M_SUCCESS)
- status = iosb.iosb$w_status;
- if (!(status & STS$M_SUCCESS))
- {
- term_puts ("Failed to read data from connection\n" );
- LIB$SIGNAL (status);
- }
-
-#ifdef RAW_DUMP
- term_puts ("{: ");
- term_write ((char *)gdb_buf + off, iosb.iosb$w_bcnt);
- term_putnl ();
-#endif
-
- gdb_blen = off + iosb.iosb$w_bcnt;
-
- if (off == 0)
- {
- /* Search for '$'. */
- for (dollar_off = 0; dollar_off < gdb_blen; dollar_off++)
- if (gdb_buf[dollar_off] == '$')
- break;
- if (dollar_off >= gdb_blen)
- {
- /* Not found, discard the data. */
- off = 0;
- continue;
- }
- /* Search for '#'. */
- for (sharp_off = dollar_off + 1;
- sharp_off < gdb_blen;
- sharp_off++)
- if (gdb_buf[sharp_off] == '#')
- break;
- }
- else if (sharp_off >= off)
- {
- /* Search for '#'. */
- for (; sharp_off < gdb_blen; sharp_off++)
- if (gdb_buf[sharp_off] == '#')
- break;
- }
-
- /* Got packet with checksum. */
- if (sharp_off + 2 <= gdb_blen)
- break;
-
- off = gdb_blen;
- if (gdb_blen == sizeof (gdb_buf))
- {
- /* Packet too large, discard. */
- off = 0;
- }
- }
-
- /* Validate and acknowledge a packet. */
- {
- unsigned char chksum = 0;
- unsigned int i;
- int v;
-
- for (i = dollar_off + 1; i < sharp_off; i++)
- chksum += gdb_buf[i];
- v = hex2byte (gdb_buf + sharp_off + 1);
- if (v != chksum)
- {
- term_puts ("Discard bad checksum packet\n");
- continue;
- }
- else
- {
- sock_write ((const unsigned char *)"+", 1);
- break;
- }
- }
- }
-
- if (trace_pkt > 1)
- {
- term_puts ("<: ");
- term_write ((char *)gdb_buf + dollar_off, sharp_off - dollar_off + 1);
- term_putnl ();
- }
-
- cmd_off = dollar_off + 1;
- cmd_len = sharp_off - dollar_off - 1;
-
- if (handle_packet (gdb_buf + dollar_off + 1, sharp_off - dollar_off - 1) == 1)
- return 1;
-
- send_pkt ();
- return 0;
-}
-
-/* Display the condition given by SIG64. */
-
-static void
-display_excp (struct chf64$signal_array *sig64, struct chf$mech_array *mech)
-{
- unsigned int status;
- char msg[160];
- unsigned short msglen;
- $DESCRIPTOR (msg_desc, msg);
- unsigned char outadr[4];
-
- status = SYS$GETMSG (sig64->chf64$q_sig_name, &msglen, &msg_desc, 0, outadr);
- if (status & STS$M_SUCCESS)
- {
- char msg2[160];
- unsigned short msg2len;
- struct dsc$descriptor_s msg2_desc =
- { sizeof (msg2), DSC$K_DTYPE_T, DSC$K_CLASS_S, msg2};
- msg_desc.dsc$w_length = msglen;
- status = SYS$FAOL_64 (&msg_desc, &msg2len, &msg2_desc,
- &sig64->chf64$q_sig_arg1);
- if (status & STS$M_SUCCESS)
- term_write (msg2, msg2len);
- }
- else
- term_puts ("no message");
- term_putnl ();
-
- if (trace_excp > 1)
- {
- TERM_FAO (" Frame: !XH, Depth: !4SL, Esf: !XH!/",
- mech->chf$q_mch_frame, mech->chf$q_mch_depth,
- mech->chf$q_mch_esf_addr);
- }
-}
-
-/* Get all registers from current thread. */
-
-static void
-read_all_registers (struct chf$mech_array *mech)
-{
- struct _intstk *intstk =
- (struct _intstk *)mech->chf$q_mch_esf_addr;
- struct chf64$signal_array *sig64 =
- (struct chf64$signal_array *)mech->chf$ph_mch_sig64_addr;
- unsigned int cnt = sig64->chf64$w_sig_arg_count;
- unsigned __int64 pc = (&sig64->chf64$q_sig_name)[cnt - 2];
-
- excp_regs.ip.v = pc;
- excp_regs.psr.v = intstk->intstk$q_ipsr;
- /* GDB and linux expects bsp to point after the current register frame.
- Adjust. */
- {
- unsigned __int64 bsp = intstk->intstk$q_bsp;
- unsigned int sof = intstk->intstk$q_ifs & 0x7f;
- unsigned int delta = ((bsp >> 3) & 0x3f) + sof;
- excp_regs.bsp.v = bsp + ((sof + delta / 0x3f) << 3);
- }
- excp_regs.cfm.v = intstk->intstk$q_ifs & 0x3fffffffff;
- excp_regs.pfs.v = intstk->intstk$q_pfs;
- excp_regs.pr.v = intstk->intstk$q_preds;
- excp_regs.gr[0].v = 0;
- excp_regs.gr[1].v = intstk->intstk$q_gp;
- excp_regs.gr[2].v = intstk->intstk$q_r2;
- excp_regs.gr[3].v = intstk->intstk$q_r3;
- excp_regs.gr[4].v = intstk->intstk$q_r4;
- excp_regs.gr[5].v = intstk->intstk$q_r5;
- excp_regs.gr[6].v = intstk->intstk$q_r6;
- excp_regs.gr[7].v = intstk->intstk$q_r7;
- excp_regs.gr[8].v = intstk->intstk$q_r8;
- excp_regs.gr[9].v = intstk->intstk$q_r9;
- excp_regs.gr[10].v = intstk->intstk$q_r10;
- excp_regs.gr[11].v = intstk->intstk$q_r11;
- excp_regs.gr[12].v = (unsigned __int64)intstk + intstk->intstk$l_stkalign;
- excp_regs.gr[13].v = intstk->intstk$q_r13;
- excp_regs.gr[14].v = intstk->intstk$q_r14;
- excp_regs.gr[15].v = intstk->intstk$q_r15;
- excp_regs.gr[16].v = intstk->intstk$q_r16;
- excp_regs.gr[17].v = intstk->intstk$q_r17;
- excp_regs.gr[18].v = intstk->intstk$q_r18;
- excp_regs.gr[19].v = intstk->intstk$q_r19;
- excp_regs.gr[20].v = intstk->intstk$q_r20;
- excp_regs.gr[21].v = intstk->intstk$q_r21;
- excp_regs.gr[22].v = intstk->intstk$q_r22;
- excp_regs.gr[23].v = intstk->intstk$q_r23;
- excp_regs.gr[24].v = intstk->intstk$q_r24;
- excp_regs.gr[25].v = intstk->intstk$q_r25;
- excp_regs.gr[26].v = intstk->intstk$q_r26;
- excp_regs.gr[27].v = intstk->intstk$q_r27;
- excp_regs.gr[28].v = intstk->intstk$q_r28;
- excp_regs.gr[29].v = intstk->intstk$q_r29;
- excp_regs.gr[30].v = intstk->intstk$q_r30;
- excp_regs.gr[31].v = intstk->intstk$q_r31;
- excp_regs.br[0].v = intstk->intstk$q_b0;
- excp_regs.br[1].v = intstk->intstk$q_b1;
- excp_regs.br[2].v = intstk->intstk$q_b2;
- excp_regs.br[3].v = intstk->intstk$q_b3;
- excp_regs.br[4].v = intstk->intstk$q_b4;
- excp_regs.br[5].v = intstk->intstk$q_b5;
- excp_regs.br[6].v = intstk->intstk$q_b6;
- excp_regs.br[7].v = intstk->intstk$q_b7;
-}
-
-/* Write all registers to current thread. FIXME: not yet complete. */
-
-static void
-write_all_registers (struct chf$mech_array *mech)
-{
- struct _intstk *intstk =
- (struct _intstk *)mech->chf$q_mch_esf_addr;
-
- intstk->intstk$q_ipsr = excp_regs.psr.v;
-}
-
-/* Do debugging. Report status to gdb and execute commands. */
-
-static void
-do_debug (struct chf$mech_array *mech)
-{
- struct _intstk *intstk =
- (struct _intstk *)mech->chf$q_mch_esf_addr;
- unsigned int old_ast;
- unsigned int old_sch;
- unsigned int status;
-
- /* Disable ast. */
- status = sys$setast (0);
- switch (status)
- {
- case SS$_WASCLR:
- old_ast = 0;
- break;
- case SS$_WASSET:
- old_ast = 1;
- break;
- default:
- /* Should never happen! */
- lib$signal (status);
- }
-
- /* Disable thread scheduling. */
- if (has_threads)
- old_sch = set_thread_scheduling (0);
-
- read_all_registers (mech);
-
- /* Send stop reply packet. */
- packet_status ();
- send_pkt ();
-
- while (one_command () == 0)
- ;
-
- write_all_registers (mech);
-
- /* Re-enable scheduling. */
- if (has_threads)
- set_thread_scheduling (old_sch);
-
- /* Re-enable AST. */
- status = sys$setast (old_ast);
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
-}
-
-/* The condition handler. That's the core of the stub. */
-
-static int
-excp_handler (struct chf$signal_array *sig,
- struct chf$mech_array *mech)
-{
- struct chf64$signal_array *sig64 =
- (struct chf64$signal_array *)mech->chf$ph_mch_sig64_addr;
- unsigned int code = sig->chf$l_sig_name & STS$M_COND_ID;
- unsigned int cnt = sig64->chf64$w_sig_arg_count;
- unsigned __int64 pc;
- unsigned int ret;
- /* Self protection. FIXME: Should be per thread ? */
- static int in_handler = 0;
-
- /* Completely ignore some conditions (signaled indirectly by this stub). */
- switch (code)
- {
- case LIB$_KEYNOTFOU & STS$M_COND_ID:
- return SS$_RESIGNAL_64;
- default:
- break;
- }
-
- /* Protect against recursion. */
- in_handler++;
- if (in_handler > 1)
- {
- if (in_handler == 2)
- TERM_FAO ("gdbstub: exception in handler (pc=!XH)!!!/",
- (&sig64->chf64$q_sig_name)[cnt - 2]);
- sys$exit (sig->chf$l_sig_name);
- }
-
- pc = (&sig64->chf64$q_sig_name)[cnt - 2];
- if (trace_excp)
- TERM_FAO ("excp_handler: code: !XL, pc=!XH!/", code, pc);
-
- /* If break on the entry point, restore the bundle. */
- if (code == (SS$_BREAK & STS$M_COND_ID)
- && pc == entry_pc
- && entry_pc != 0)
- {
- static unsigned int entry_prot;
-
- if (trace_entry)
- term_puts ("initial entry breakpoint\n");
- page_set_rw (entry_pc, 16, &entry_prot);
-
- ots$move ((void *)entry_pc, 16, entry_saved);
- __fc (entry_pc);
- page_restore_rw (entry_pc, 16, entry_prot);
- }
-
- switch (code)
- {
- case SS$_ACCVIO & STS$M_COND_ID:
- if (trace_excp <= 1)
- display_excp (sig64, mech);
- /* Fall through. */
- case SS$_BREAK & STS$M_COND_ID:
- case SS$_OPCDEC & STS$M_COND_ID:
- case SS$_TBIT & STS$M_COND_ID:
- case SS$_DEBUG & STS$M_COND_ID:
- if (trace_excp > 1)
- {
- int i;
- struct _intstk *intstk =
- (struct _intstk *)mech->chf$q_mch_esf_addr;
-
- display_excp (sig64, mech);
-
- TERM_FAO (" intstk: !XH!/", intstk);
- for (i = 0; i < cnt + 1; i++)
- TERM_FAO (" !XH!/", ((unsigned __int64 *)sig64)[i]);
- }
- do_debug (mech);
- ret = SS$_CONTINUE_64;
- break;
-
- default:
- display_excp (sig64, mech);
- ret = SS$_RESIGNAL_64;
- break;
- }
-
- in_handler--;
- /* Discard selected thread registers. */
- sel_regs_pthread = 0;
- return ret;
-}
-
-/* Setup internal trace flags according to GDBSTUB$TRACE logical. */
-
-static void
-trace_init (void)
-{
- unsigned int status, i, start;
- unsigned short len;
- char resstring[LNM$C_NAMLENGTH];
- static const $DESCRIPTOR (tabdesc, "LNM$DCL_LOGICAL");
- static const $DESCRIPTOR (logdesc, "GDBSTUB$TRACE");
- $DESCRIPTOR (sub_desc, resstring);
- ILE3 item_lst[2];
-
- item_lst[0].ile3$w_length = LNM$C_NAMLENGTH;
- item_lst[0].ile3$w_code = LNM$_STRING;
- item_lst[0].ile3$ps_bufaddr = resstring;
- item_lst[0].ile3$ps_retlen_addr = &len;
- item_lst[1].ile3$w_length = 0;
- item_lst[1].ile3$w_code = 0;
-
- /* Translate the logical name. */
- status = SYS$TRNLNM (0, /* Attributes of the logical name. */
- (void *)&tabdesc, /* Logical name table. */
- (void *)&logdesc, /* Logical name. */
- 0, /* Access mode. */
- &item_lst); /* Item list. */
- if (status == SS$_NOLOGNAM)
- return;
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
-
- start = 0;
- for (i = 0; i <= len; i++)
- {
- if ((i == len || resstring[i] == ',' || resstring[i] == ';')
- && i != start)
- {
- int j;
-
- sub_desc.dsc$a_pointer = resstring + start;
- sub_desc.dsc$w_length = i - start;
-
- for (j = 0; j < NBR_DEBUG_FLAGS; j++)
- if (str$case_blind_compare (&sub_desc,
- (void *)&debug_flags[j].name) == 0)
- {
- debug_flags[j].val++;
- break;
- }
- if (j == NBR_DEBUG_FLAGS)
- TERM_FAO ("GDBSTUB$TRACE: unknown directive !AS!/", &sub_desc);
-
- start = i + 1;
- }
- }
-
- TERM_FAO ("GDBSTUB$TRACE=!AD ->", len, resstring);
- for (i = 0; i < NBR_DEBUG_FLAGS; i++)
- if (debug_flags[i].val > 0)
- TERM_FAO (" !AS=!ZL", &debug_flags[i].name, debug_flags[i].val);
- term_putnl ();
-}
-
-
-/* Entry point. */
-
-static int
-stub_start (unsigned __int64 *progxfer, void *cli_util,
- EIHD *imghdr, IFD *imgfile,
- unsigned int linkflag, unsigned int cliflag)
-{
- static int initialized;
- int i;
- int cnt;
- int is_attached;
- IMCB *imcb;
- if (initialized)
- term_puts ("gdbstub: re-entry\n");
- else
- initialized = 1;
-
- /* When attached (through SS$_DEBUG condition), the number of arguments
- is 4 and PROGXFER is the PC at interruption. */
- va_count (cnt);
- is_attached = cnt == 4;
-
- term_init ();
-
- /* Hello banner. */
- term_puts ("Hello from gdb stub\n");
-
- trace_init ();
-
- if (trace_entry && !is_attached)
- {
- TERM_FAO ("xfer: !XH, imghdr: !XH, ifd: !XH!/",
- progxfer, imghdr, imgfile);
- for (i = -2; i < 8; i++)
- TERM_FAO (" at !2SW: !XH!/", i, progxfer[i]);
- }
-
- /* Search for entry point. */
- if (!is_attached)
- {
- entry_pc = 0;
- for (i = 0; progxfer[i]; i++)
- entry_pc = progxfer[i];
-
- if (trace_entry)
- {
- if (entry_pc == 0)
- {
- term_puts ("No entry point\n");
- return 0;
- }
- else
- TERM_FAO ("Entry: !XH!/",entry_pc);
- }
- }
- else
- entry_pc = progxfer[0];
-
- has_threads = 0;
- for (imcb = ctl$gl_imglstptr->imcb$l_flink;
- imcb != ctl$gl_imglstptr;
- imcb = imcb->imcb$l_flink)
- {
- if (ots$strcmp_eql (pthread_rtl_desc.dsc$a_pointer,
- pthread_rtl_desc.dsc$w_length,
- imcb->imcb$t_log_image_name + 1,
- imcb->imcb$t_log_image_name[0]))
- has_threads = 1;
-
- if (trace_images)
- {
- unsigned int j;
- LDRIMG *ldrimg = imcb->imcb$l_ldrimg;
- LDRISD *ldrisd;
-
- TERM_FAO ("!XA-!XA ",
- imcb->imcb$l_starting_address,
- imcb->imcb$l_end_address);
-
- switch (imcb->imcb$b_act_code)
- {
- case IMCB$K_MAIN_PROGRAM:
- term_puts ("prog");
- break;
- case IMCB$K_MERGED_IMAGE:
- term_puts ("mrge");
- break;
- case IMCB$K_GLOBAL_IMAGE_SECTION:
- term_puts ("glob");
- break;
- default:
- term_puts ("????");
- }
- TERM_FAO (" !AD !40AC!/",
- 1, "KESU" + (imcb->imcb$b_access_mode & 3),
- imcb->imcb$t_log_image_name);
-
- if ((long) ldrimg < 0 || trace_images < 2)
- continue;
- ldrisd = ldrimg->ldrimg$l_segments;
- for (j = 0; j < ldrimg->ldrimg$l_segcount; j++)
- {
- unsigned int flags = ldrisd[j].ldrisd$i_flags;
- term_puts (" ");
- term_putc (flags & 0x04 ? 'R' : '-');
- term_putc (flags & 0x02 ? 'W' : '-');
- term_putc (flags & 0x01 ? 'X' : '-');
- term_puts (flags & 0x01000000 ? " Prot" : " ");
- term_puts (flags & 0x04000000 ? " Shrt" : " ");
- term_puts (flags & 0x08000000 ? " Shrd" : " ");
- TERM_FAO (" !XA-!XA!/",
- ldrisd[j].ldrisd$p_base,
- (unsigned __int64) ldrisd[j].ldrisd$p_base
- + ldrisd[j].ldrisd$i_len - 1);
- }
- ldrisd = ldrimg->ldrimg$l_dyn_seg;
- if (ldrisd)
- TERM_FAO (" dynamic !XA-!XA!/",
- ldrisd->ldrisd$p_base,
- (unsigned __int64) ldrisd->ldrisd$p_base
- + ldrisd->ldrisd$i_len - 1);
- }
- }
-
- if (has_threads)
- threads_init ();
-
- /* Wait for connection. */
- sock_init ();
-
- /* Set primary exception vector. */
- {
- unsigned int status;
- status = sys$setexv (0, excp_handler, PSL$C_USER, (__void_ptr32) &prevhnd);
- if (!(status & STS$M_SUCCESS))
- LIB$SIGNAL (status);
- }
-
- if (is_attached)
- {
- return excp_handler ((struct chf$signal_array *) progxfer[2],
- (struct chf$mech_array *) progxfer[3]);
- }
-
- /* Change first instruction to set a breakpoint. */
- {
- /*
- 01 08 00 40 00 00 [MII] break.m 0x80001
- 00 00 00 02 00 00 nop.i 0x0
- 00 00 04 00 nop.i 0x0;;
- */
- static const unsigned char initbp[16] =
- { 0x01, 0x08, 0x00, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0x00 };
- unsigned int entry_prot;
- unsigned int status;
-
- status = page_set_rw (entry_pc, 16, &entry_prot);
-
- if (!(status & STS$M_SUCCESS))
- {
- if ((status & STS$M_COND_ID) == (SS$_NOT_PROCESS_VA & STS$M_COND_ID))
- {
- /* Cannot write here. This can happen when pthreads are
- used. */
- entry_pc = 0;
- term_puts ("gdbstub: cannot set breakpoint on entry\n");
- }
- else
- LIB$SIGNAL (status);
- }
-
- if (entry_pc != 0)
- {
- ots$move (entry_saved, 16, (void *)entry_pc);
- ots$move ((void *)entry_pc, 16, (void *)initbp);
- __fc (entry_pc);
- page_restore_rw (entry_pc, 16, entry_prot);
- }
- }
-
- /* If it wasn't possible to set a breakpoint on the entry point,
- accept gdb commands now. Note that registers are not updated. */
- if (entry_pc == 0)
- {
- while (one_command () == 0)
- ;
- }
-
- /* We will see! */
- return SS$_CONTINUE;
-}
-
-/* Declare the entry point of this relocatable module. */
-
-struct xfer_vector
-{
- __int64 impure_start;
- __int64 impure_end;
- int (*entry) ();
-};
-
-#pragma __extern_model save
-#pragma __extern_model strict_refdef "XFER_PSECT"
-struct xfer_vector xfer_vector = {0, 0, stub_start};
-#pragma __extern_model restore
@@ -4040,10 +4040,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
while not getting into the function body.
The functions end point and an increasing SAL line are used as
- indicators of the prologue's endpoint.
-
- This code is based on the function refine_prologue_limit
- (found in ia64). */
+ indicators of the prologue's endpoint. */
CORE_ADDR
skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
@@ -154,8 +154,6 @@ enum target_object
/* Memory known to be part of the target code. This is cached even
if it is not in a region marked as such. */
TARGET_OBJECT_CODE_MEMORY,
- /* Kernel Unwind Table. See "ia64-tdep.c". */
- TARGET_OBJECT_UNWIND_TABLE,
/* Transfer auxilliary vector. */
TARGET_OBJECT_AUXV,
/* StackGhost cookie. See "sparc-tdep.c". */
@@ -2229,9 +2229,7 @@ else
# The following exceptions are taken from Libtool 1.4.3.
case $host_os in
aix*)
- if test $host_cpu != ia64; then
- RPATH_ENVVAR=LIBPATH
- fi ;;
+ RPATH_ENVVAR=LIBPATH ;;
darwin* | rhapsody*)
RPATH_ENVVAR=DYLD_LIBRARY_PATH ;;
esac
@@ -64,9 +64,7 @@ else
# The following exceptions are taken from Libtool 1.4.3.
case $host_os in
aix*)
- if test $host_cpu != ia64; then
- RPATH_ENVVAR=LIBPATH
- fi ;;
+ RPATH_ENVVAR=LIBPATH ;;
darwin* | rhapsody*)
RPATH_ENVVAR=DYLD_LIBRARY_PATH ;;
esac
deleted file mode 100644
@@ -1,44 +0,0 @@
-/* Copyright 2009-2024 Free Software Foundation, Inc.
-
- 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/>.
-
- This file is part of the gdb testsuite.
- It tests displaced stepping over various insns that require special
- handling. */
-
- .text
- .align 16
- .global main
- .proc main
-main:
- mov r2=r12
- mov r14=1
- ;;
-bundle:
- /* Store value 1 into `long' variable on stack. */
- st8.rel [r2]=r14
- /* This long constant requires L-X slot in this bundle. */
- movl r14=0x7fffffff
- ;;
- /* Store value 0x7fffffff into `long' variable on stack. */
- st8.rel [r2]=r14
- mov r14=r0
- ;;
- mov r8=r14
- mov r12=r2
- br.ret.sptk.many b0
-
- .endp main
-
- .section .note.GNU-stack,"",@progbits
deleted file mode 100644
@@ -1,73 +0,0 @@
-# Copyright 2009-2024 Free Software Foundation, Inc.
-
-# 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/>.
-
-require {istarget "ia64-*-*"}
-
-set testfile ia64-breakpoint-shadow
-set srcfile ${testfile}.S
-set binfile ${objdir}/${subdir}/${testfile}
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
- untested "failed to compile"
- return -1
-}
-
-clean_restart $binfile
-
-# We need to start the inferior to place the breakpoints in the memory at all.
-if ![runto_main] {
- return -1
-}
-
-# The default "auto" mode removes all the breakpoints when we stop (and not
-# running the nonstop mode). We would not be able to test the shadow.
-gdb_test "set breakpoint always-inserted on"
-gdb_test "show breakpoint always-inserted" "Always inserted breakpoint mode is on."
-
-set match "\nDump of assembler code for function main:\r\n(.*)End of assembler dump.\r\n$gdb_prompt $"
-
-set test "disassembly without breakpoints"
-gdb_test_multiple "disass main" $test {
- -re $match {
- set orig $expect_out(1,string)
- pass $test
- }
-}
-
-set test "slot 0 breakpoint placed"
-gdb_test_multiple "b bundle" $test {
- -re "Breakpoint \[0-9\] at (0x\[0-9a-f\]*0):.*$gdb_prompt $" {
- pass $test
- set bpt2address $expect_out(1,string)
- }
-}
-
-if ![info exists bpt2address] {
- return -1
-}
-
-gdb_test "b *($bpt2address + 1)" "Breakpoint \[0-9\] at .*" "slot 1 breakpoint placed"
-gdb_test "b *($bpt2address + 2)" "Can't insert breakpoint for non-existing slot X" "slot 2 (slot X) breakpoint refusal"
-
-set test "disassembly with breakpoints"
-gdb_test_multiple "disass main" $test {
- -re $match {
- set got $expect_out(1,string)
- if [string equal -nocase $orig $got] {
- pass $test
- } else {
- fail $test
- }
- }
-}
@@ -139,10 +139,6 @@ switch -glob -- [istarget] {
"m68k-*-*" {
set asm-arch m68k
}
- "ia64-*-*" {
- set asm-arch ia64
- set debug-flags "-gdwarf-2"
- }
"iq2000-*-*" {
set asm-arch iq2000
}
deleted file mode 100644
@@ -1,51 +0,0 @@
- comment "subroutine prologue"
- .macro gdbasm_enter
- alloc r33=ar.pfs,0,2,0,0
- mov r32=b0
- nop.i 0
- .endm
-
- comment "subroutine epilogue"
- .macro gdbasm_leave
- nop.m 0
- mov ar.pfs=r33
- mov b0=r32
- nop.m 0
- nop.f 0
- br.ret.sptk.many b0
- .endm
-
- .macro gdbasm_call subr
- nop.m 0
- nop.f 0
- br.call.sptk.many b0=\subr
- .endm
-
- .macro gdbasm_several_nops
- nop.m 0
- nop.i 0
- nop.i 0
- .endm
-
- comment "exit (0)"
- .macro gdbasm_exit0
- break.m 0x0
- nop.m 0
- nop.i 0
- .endm
-
- comment "crt0 startup"
- .macro gdbasm_startup
- gdbasm_enter
- mov r32=r0
- nop.i 0
- nop.i 0
- .endm
-
- comment "Declare a data variable"
- .purgem gdbasm_datavar
- .macro gdbasm_datavar name value
- .data
-\name:
- .long \value
- .endm
@@ -257,12 +257,7 @@ proc fetch_all_registers {test} {
exp_continue
}
-re "^bspstore\[ \t\]+\[^\r\n\]+\r\n" {
- if [istarget "ia64-*-*"] {
- # Filter out bspstore which is specially tied to bsp,
- # giving spurious differences.
- } else {
- lappend all_registers_lines $expect_out(0,string)
- }
+ lappend all_registers_lines $expect_out(0,string)
exp_continue
}
-re "^pstate\[ \t\]+\[^\r\n\]+\r\n" {
@@ -55,8 +55,6 @@ if {[is_aarch64_target]} {
}
} elseif {[istarget "i?86-*-*"] || [istarget "x86_64-*-*"]} {
gdb_test "info float" "R7:.*Status Word:.*Opcode:.*"
-} elseif {[istarget "ia64-*-*"]} {
- gdb_test "info float" "f0.*f1.*f127.*"
} elseif {[istarget "m68k-*-*"]} {
gdb_test_multiple "info float" "info_float" {
-re "fp0.*fp1.*fp7.*$gdb_prompt $" {
@@ -60,11 +60,10 @@ gdb_test "step" ".*${decimal}.*myglob.*" "step into"
# call?
# On PA64, we end up at a different instruction than PA32.
-# On IA-64, we also end up on callee instead of on the next line due
+# On MIPS, we also end up on callee instead of on the next line due
# to the restoration of the global pointer (which is a caller-save).
-# Similarly on MIPS PIC targets.
set test "step out"
-if { [istarget "ia64-*-*"] || [istarget "mips*-*-*"]} {
+if { [istarget "mips*-*-*"]} {
gdb_test_multiple "finish" "$test" {
-re ".*${decimal}.*a.*5.*= a.*3.*$gdb_prompt $" {
pass "$test"
@@ -153,10 +152,9 @@ gdb_test_multiple "finish" "$test" {
}
-re ".*${decimal}.*callee.*STEPI.*$gdb_prompt $" {
# On PA64, we end up at a different instruction than PA32.
- # On IA-64, we end up on callee instead of on the following line due
+ # On MIPS, we end up on callee instead of on the following line due
# to the restoration of the global pointer.
- # Similarly on MIPS PIC targets.
- if { [istarget "ia64-*-*"] || [istarget "mips*-*-*"] } {
+ if { [istarget "mips*-*-*"] } {
test_i "$test" "stepi" \
".*${decimal}.*callee.*STEPI" ".*${decimal}.*callee.*NEXTI"
} else {
@@ -4,7 +4,6 @@
/* HP-UX libunwind.so doesn't provide _UA_END_OF_STACK */
/* { dg-do run } */
/* { dg-options "-fexceptions" } */
-/* { dg-skip-if "" { "ia64-*-hpux11.*" } { "*" } { "" } } */
/* Verify DW_OP_* handling in the unwinder. */
#include <unwind.h>
@@ -50,12 +50,7 @@ main (int argc, char **argv)
#define CLONE_FLAGS (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)
-#ifdef __ia64__
- clone_pid = __clone2 (clone_fn, stack, STACK_SIZE, CLONE_FLAGS, NULL);
-#else
clone_pid = clone (clone_fn, stack + STACK_SIZE, CLONE_FLAGS, NULL);
-#endif
-
assert (clone_pid > 0);
/* Wait for alarm. */
@@ -46,12 +46,7 @@ thread_fn (void *arg)
stack = malloc (STACK_SIZE);
assert (stack != NULL);
-#ifdef __ia64__
- clone_pid = __clone2 (clone_fn, stack, STACK_SIZE, CLONE_VM, NULL);
-#else
clone_pid = clone (clone_fn, stack + STACK_SIZE, CLONE_VM, NULL);
-#endif
-
assert (clone_pid > 0);
/* Wait for child. */
deleted file mode 100644
@@ -1,371 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
- Copyright 2010-2024 Free Software Foundation, Inc.
-
- 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/>. */
-
-#define _GNU_SOURCE
-#include <pthread.h>
-#include <stdio.h>
-#include <limits.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <unistd.h>
-#include <asm/unistd.h>
-
-#define gettid() syscall (__NR_gettid)
-
-/* Terminate always in the main task, it can lock up with SIGSTOPped GDB
- otherwise. */
-#define TIMEOUT (gettid () == getpid() ? 10 : 15)
-
-static pid_t thread1_tid;
-static pthread_cond_t thread1_tid_cond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t thread1_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-
-static pid_t thread2_tid;
-static pthread_cond_t thread2_tid_cond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t thread2_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-
-static pthread_mutex_t terminate_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-
-static pthread_barrier_t threads_started_barrier;
-
-/* Do not use alarm as it would create a ptrace event which would hang up us if
- we are being traced by GDB which we stopped ourselves. */
-
-static void timed_mutex_lock (pthread_mutex_t *mutex)
-{
- int i;
- struct timespec start, now;
-
- i = clock_gettime (CLOCK_MONOTONIC, &start);
- assert (i == 0);
-
- do
- {
- i = pthread_mutex_trylock (mutex);
- if (i == 0)
- return;
- assert (i == EBUSY);
-
- i = clock_gettime (CLOCK_MONOTONIC, &now);
- assert (i == 0);
- assert (now.tv_sec >= start.tv_sec);
- }
- while (now.tv_sec - start.tv_sec < TIMEOUT);
-
- fprintf (stderr, "Timed out waiting for internal lock!\n");
- exit (EXIT_FAILURE);
-}
-
-static void *
-thread_func (void *threadno_voidp)
-{
- int threadno = (intptr_t) threadno_voidp;
- int i;
-
- pthread_barrier_wait (&threads_started_barrier);
-
- switch (threadno)
- {
- case 1:
- timed_mutex_lock (&thread1_tid_mutex);
-
- /* THREAD1_TID_MUTEX must be already locked to avoid race. */
- thread1_tid = gettid ();
-
- i = pthread_cond_signal (&thread1_tid_cond);
- assert (i == 0);
- i = pthread_mutex_unlock (&thread1_tid_mutex);
- assert (i == 0);
-
- break;
-
- case 2:
- timed_mutex_lock (&thread2_tid_mutex);
-
- /* THREAD2_TID_MUTEX must be already locked to avoid race. */
- thread2_tid = gettid ();
-
- i = pthread_cond_signal (&thread2_tid_cond);
- assert (i == 0);
- i = pthread_mutex_unlock (&thread2_tid_mutex);
- assert (i == 0);
-
- break;
-
- default:
- assert (0);
- }
-
-#ifdef __ia64__
- asm volatile ("label:\n"
- "nop.m 0\n"
- "nop.i 0\n"
- "nop.b 0\n");
-#endif
- /* break-here */
-
- /* Be sure the "t (tracing stop)" test can proceed for both threads. */
- timed_mutex_lock (&terminate_mutex);
- i = pthread_mutex_unlock (&terminate_mutex);
- assert (i == 0);
-
- return NULL;
-}
-
-static const char *
-proc_string (const char *filename, const char *line)
-{
- FILE *f;
- static char buf[LINE_MAX];
- size_t line_len = strlen (line);
-
- f = fopen (filename, "r");
- if (f == NULL)
- {
- fprintf (stderr, "fopen (\"%s\") for \"%s\": %s\n", filename, line,
- strerror (errno));
- exit (EXIT_FAILURE);
- }
- while (errno = 0, fgets (buf, sizeof (buf), f))
- {
- char *s;
-
- s = strchr (buf, '\n');
- assert (s != NULL);
- *s = 0;
-
- if (strncmp (buf, line, line_len) != 0)
- continue;
-
- if (fclose (f))
- {
- fprintf (stderr, "fclose (\"%s\") for \"%s\": %s\n", filename, line,
- strerror (errno));
- exit (EXIT_FAILURE);
- }
-
- return &buf[line_len];
- }
- if (errno != 0)
- {
- fprintf (stderr, "fgets (\"%s\": %s\n", filename, strerror (errno));
- exit (EXIT_FAILURE);
- }
- fprintf (stderr, "\"%s\": No line \"%s\" found.\n", filename, line);
- exit (EXIT_FAILURE);
-}
-
-static unsigned long
-proc_ulong (const char *filename, const char *line)
-{
- const char *s = proc_string (filename, line);
- long retval;
- char *end;
-
- errno = 0;
- retval = strtol (s, &end, 10);
- if (retval < 0 || retval >= LONG_MAX || (end && *end))
- {
- fprintf (stderr, "\"%s\":\"%s\": %ld, %s\n", filename, line, retval,
- strerror (errno));
- exit (EXIT_FAILURE);
- }
- return retval;
-}
-
-static void
-state_wait (pid_t process, const char *wanted)
-{
- char *filename;
- int i;
- struct timespec start, now;
- const char *state;
-
- i = asprintf (&filename, "/proc/%lu/status", (unsigned long) process);
- assert (i > 0);
-
- i = clock_gettime (CLOCK_MONOTONIC, &start);
- assert (i == 0);
-
- do
- {
- state = proc_string (filename, "State:\t");
-
- /* torvalds/linux-2.6.git 464763cf1c6df632dccc8f2f4c7e50163154a2c0
- has changed "T (tracing stop)" to "t (tracing stop)". Make the GDB
- testcase backward compatible with older Linux kernels. */
- if (strcmp (state, "T (tracing stop)") == 0)
- state = "t (tracing stop)";
-
- if (strcmp (state, wanted) == 0)
- {
- free (filename);
- return;
- }
-
- if (sched_yield ())
- {
- perror ("sched_yield()");
- exit (EXIT_FAILURE);
- }
-
- i = clock_gettime (CLOCK_MONOTONIC, &now);
- assert (i == 0);
- assert (now.tv_sec >= start.tv_sec);
- }
- while (now.tv_sec - start.tv_sec < TIMEOUT);
-
- fprintf (stderr, "Timed out waiting for PID %lu \"%s\" (now it is \"%s\")!\n",
- (unsigned long) process, wanted, state);
- exit (EXIT_FAILURE);
-}
-
-static volatile pid_t tracer = 0;
-static pthread_t thread1, thread2;
-
-static void
-cleanup (void)
-{
- printf ("Resuming GDB PID %lu.\n", (unsigned long) tracer);
-
- if (tracer)
- {
- int i;
- int tracer_save = tracer;
-
- tracer = 0;
-
- i = kill (tracer_save, SIGCONT);
- assert (i == 0);
- }
-}
-
-int
-main (int argc, char **argv)
-{
- int i;
- int standalone = 0;
-
- if (argc == 2 && strcmp (argv[1], "-s") == 0)
- standalone = 1;
- else
- assert (argc == 1);
-
- setbuf (stdout, NULL);
-
- timed_mutex_lock (&thread1_tid_mutex);
- timed_mutex_lock (&thread2_tid_mutex);
-
- timed_mutex_lock (&terminate_mutex);
-
- pthread_barrier_init (&threads_started_barrier, NULL, 3);
-
- i = pthread_create (&thread1, NULL, thread_func, (void *) (intptr_t) 1);
- assert (i == 0);
-
- i = pthread_create (&thread2, NULL, thread_func, (void *) (intptr_t) 2);
- assert (i == 0);
-
- if (!standalone)
- {
- tracer = proc_ulong ("/proc/self/status", "TracerPid:\t");
- if (tracer == 0)
- {
- fprintf (stderr, "The testcase must be run by GDB!\n");
- exit (EXIT_FAILURE);
- }
- if (tracer != getppid ())
- {
- fprintf (stderr, "The testcase parent must be our GDB tracer!\n");
- exit (EXIT_FAILURE);
- }
- }
-
- /* SIGCONT our debugger in the case of our crash as we would deadlock
- otherwise. */
-
- atexit (cleanup);
-
- /* Wait until all threads are seen running. On Linux (at least),
- new threads start stopped, and the debugger must resume them.
- Need to wait for that before stopping GDB. */
- pthread_barrier_wait (&threads_started_barrier);
-
- printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer);
-
- if (tracer)
- {
- i = kill (tracer, SIGSTOP);
- assert (i == 0);
- state_wait (tracer, "T (stopped)");
- }
-
- /* Threads are now waiting at timed_mutex_lock (thread1_tid_mutex) and so
- they could not trigger the breakpoint before GDB gets unstopped later.
- Threads get resumed at pthread_cond_wait below. Use `while' loops for
- protection against spurious pthread_cond_wait wakeups. */
-
- printf ("Waiting till the threads initialize their TIDs.\n");
-
- while (thread1_tid == 0)
- {
- i = pthread_cond_wait (&thread1_tid_cond, &thread1_tid_mutex);
- assert (i == 0);
- }
-
- while (thread2_tid == 0)
- {
- i = pthread_cond_wait (&thread2_tid_cond, &thread2_tid_mutex);
- assert (i == 0);
- }
-
- printf ("Thread 1 TID = %lu, thread 2 TID = %lu, PID = %lu.\n",
- (unsigned long) thread1_tid, (unsigned long) thread2_tid,
- (unsigned long) getpid ());
-
- printf ("Waiting till the threads get trapped by the breakpoint.\n");
-
- if (tracer)
- {
- /* s390x-unknown-linux-gnu will fail with "R (running)". */
-
- state_wait (thread1_tid, "t (tracing stop)");
-
- state_wait (thread2_tid, "t (tracing stop)");
- }
-
- cleanup ();
-
- printf ("Joining the threads.\n");
-
- i = pthread_mutex_unlock (&terminate_mutex);
- assert (i == 0);
-
- i = pthread_join (thread1, NULL);
- assert (i == 0);
-
- i = pthread_join (thread2, NULL);
- assert (i == 0);
-
- printf ("Exiting.\n"); /* break-at-exit */
-
- return EXIT_SUCCESS;
-}
deleted file mode 100644
@@ -1,77 +0,0 @@
-# This testcase is part of GDB, the GNU debugger.
-
-# Copyright 2010-2024 Free Software Foundation, Inc.
-
-# 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/>.
-
-# Test SIGILL generated by some special cases of breakpoints on ia64. Problem
-# was SIGILL being stored in non-current thread for later retrieval when its
-# breakpoint has been already deleted. moribund locations are not active in
-# the default all-stop mode.
-
-standard_testfile
-if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" ${binfile} executable [list debug additional_flags=-lrt]] != "" } {
- return -1
-}
-
-clean_restart $testfile
-
-if ![runto_main] {
- return -1
-}
-
-set test "info addr label"
-gdb_test_multiple $test $test {
- -re "Symbol \"label\" is at 0x\[0-9a-f\]+0 in .*\r\n$gdb_prompt $" {
- # Verify the label really starts at the start of ia64 bundle.
- pass $test
-
- # ia64 generates SIGILL for breakpoint at B slot of an MIB bundle.
- gdb_test "break *label+2" {Breakpoint [0-9]+ at 0x[0-9a-f]+2:.*}
- }
- -re "No symbol \"label\" in current context\\.\r\n$gdb_prompt $" {
- pass $test
-
- # Either this target never generates non-SIGTRAP signals or they do
- # not depend on the breakpoint address. Try any address.
- gdb_breakpoint [gdb_get_line_number "break-here"]
- }
-}
-
-gdb_test_no_output {set $sigill_bpnum=$bpnum}
-
-gdb_breakpoint [gdb_get_line_number "break-at-exit"]
-
-gdb_test_no_output "set debug infrun 1"
-
-# The ia64 SIGILL signal is visible only in the linux-nat debug output.
-
-set prompt "$gdb_prompt \\\[infrun\\\] fetch_inferior_event: exit\r\n$"
-gdb_test_multiple "continue" "continue" -prompt $prompt {
- -re "Breakpoint \[0-9\]+,( .* in)? thread_func .*$prompt$" {
- pass $gdb_test_name
- }
-}
-
-gdb_test_no_output {delete $sigill_bpnum}
-
-gdb_test_multiple "continue" "continue for the pending signal" -prompt $prompt {
- -re "Breakpoint \[0-9\]+, .*break-at-exit.*\r\n$prompt$" {
- # Breakpoint has been skipped in the other thread.
- pass $gdb_test_name
- }
- -re " received signal .*\r\n$gdb_prompt $" {
- fail $gdb_test_name
- }
-}
@@ -4572,7 +4572,6 @@ proc allow_hw_breakpoint_tests {} {
# These targets support hardware breakpoints natively
if { [istarget "i?86-*-*"]
|| [istarget "x86_64-*-*"]
- || [istarget "ia64-*-*"]
|| [istarget "arm*-*-*"]
|| [istarget "aarch64*-*-*"]
|| [istarget "s390*-*-*"] } {
@@ -4596,7 +4595,6 @@ proc allow_hw_watchpoint_tests {} {
# watchpoint support on Powerpc.
if { [istarget "i?86-*-*"]
|| [istarget "x86_64-*-*"]
- || [istarget "ia64-*-*"]
|| [istarget "arm*-*-*"]
|| [istarget "aarch64*-*-*"]
|| ([istarget "powerpc*-*-linux*"] && [has_hw_wp_support])
@@ -1423,16 +1423,6 @@ This GDB was configured as follows:\n\
--with-jit-reader-dir=%s%s\n\
"), JIT_READER_DIR, JIT_READER_DIR_RELOCATABLE ? " (relocatable)" : "");
-#if HAVE_LIBUNWIND_IA64_H
- gdb_printf (stream, _("\
- --with-libunwind-ia64\n\
-"));
-#else
- gdb_printf (stream, _("\
- --without-libunwind-ia64\n\
-"));
-#endif
-
#if HAVE_LIBLZMA
gdb_printf (stream, _("\
--with-lzma\n\
@@ -129,10 +129,6 @@ case "${gdbserver_host}" in
srv_tgtobj="${srv_tgtobj} nat/netbsd-nat.o"
srv_tgtobj="${srv_tgtobj} arch/i386.o"
;;
- ia64-*-linux*) srv_regobj=reg-ia64.o
- srv_tgtobj="$srv_linux_obj linux-ia64-low.o"
- srv_linux_usrregs=yes
- ;;
loongarch*-*-linux*) srv_tgtobj="arch/loongarch.o linux-loongarch-low.o"
srv_tgtobj="${srv_tgtobj} ${srv_linux_obj}"
srv_linux_regsets=yes
deleted file mode 100644
@@ -1,395 +0,0 @@
-/* GNU/Linux/IA64 specific low level interface, for the remote server for GDB.
- Copyright (C) 1995-2024 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 "linux-low.h"
-
-#ifdef HAVE_SYS_REG_H
-#include <sys/reg.h>
-#endif
-
-/* Linux target op definitions for the IA64 architecture. */
-
-class ia64_target : public linux_process_target
-{
-public:
-
- const regs_info *get_regs_info () override;
-
- const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
-
-protected:
-
- void low_arch_setup () override;
-
- bool low_cannot_fetch_register (int regno) override;
-
- bool low_cannot_store_register (int regno) override;
-
- bool low_fetch_register (regcache *regcache, int regno) override;
-
- bool low_breakpoint_at (CORE_ADDR pc) override;
-};
-
-/* The singleton target ops object. */
-
-static ia64_target the_ia64_target;
-
-const gdb_byte *
-ia64_target::sw_breakpoint_from_kind (int kind, int *size)
-{
- gdb_assert_not_reached ("target op sw_breakpoint_from_kind is not "
- "implemented by this target");
-}
-
-bool
-ia64_target::low_breakpoint_at (CORE_ADDR pc)
-{
- gdb_assert_not_reached ("linux target op low_breakpoint_at is not "
- "implemented by this target");
-}
-
-/* Defined in auto-generated file reg-ia64.c. */
-void init_registers_ia64 (void);
-extern const struct target_desc *tdesc_ia64;
-
-#define ia64_num_regs 462
-
-#include <asm/ptrace_offsets.h>
-
-static int ia64_regmap[] =
- {
- /* general registers */
- -1, /* gr0 not available; i.e, it's always zero */
- PT_R1,
- PT_R2,
- PT_R3,
- PT_R4,
- PT_R5,
- PT_R6,
- PT_R7,
- PT_R8,
- PT_R9,
- PT_R10,
- PT_R11,
- PT_R12,
- PT_R13,
- PT_R14,
- PT_R15,
- PT_R16,
- PT_R17,
- PT_R18,
- PT_R19,
- PT_R20,
- PT_R21,
- PT_R22,
- PT_R23,
- PT_R24,
- PT_R25,
- PT_R26,
- PT_R27,
- PT_R28,
- PT_R29,
- PT_R30,
- PT_R31,
- /* gr32 through gr127 not directly available via the ptrace interface */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- /* Floating point registers */
- -1, -1, /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */
- PT_F2,
- PT_F3,
- PT_F4,
- PT_F5,
- PT_F6,
- PT_F7,
- PT_F8,
- PT_F9,
- PT_F10,
- PT_F11,
- PT_F12,
- PT_F13,
- PT_F14,
- PT_F15,
- PT_F16,
- PT_F17,
- PT_F18,
- PT_F19,
- PT_F20,
- PT_F21,
- PT_F22,
- PT_F23,
- PT_F24,
- PT_F25,
- PT_F26,
- PT_F27,
- PT_F28,
- PT_F29,
- PT_F30,
- PT_F31,
- PT_F32,
- PT_F33,
- PT_F34,
- PT_F35,
- PT_F36,
- PT_F37,
- PT_F38,
- PT_F39,
- PT_F40,
- PT_F41,
- PT_F42,
- PT_F43,
- PT_F44,
- PT_F45,
- PT_F46,
- PT_F47,
- PT_F48,
- PT_F49,
- PT_F50,
- PT_F51,
- PT_F52,
- PT_F53,
- PT_F54,
- PT_F55,
- PT_F56,
- PT_F57,
- PT_F58,
- PT_F59,
- PT_F60,
- PT_F61,
- PT_F62,
- PT_F63,
- PT_F64,
- PT_F65,
- PT_F66,
- PT_F67,
- PT_F68,
- PT_F69,
- PT_F70,
- PT_F71,
- PT_F72,
- PT_F73,
- PT_F74,
- PT_F75,
- PT_F76,
- PT_F77,
- PT_F78,
- PT_F79,
- PT_F80,
- PT_F81,
- PT_F82,
- PT_F83,
- PT_F84,
- PT_F85,
- PT_F86,
- PT_F87,
- PT_F88,
- PT_F89,
- PT_F90,
- PT_F91,
- PT_F92,
- PT_F93,
- PT_F94,
- PT_F95,
- PT_F96,
- PT_F97,
- PT_F98,
- PT_F99,
- PT_F100,
- PT_F101,
- PT_F102,
- PT_F103,
- PT_F104,
- PT_F105,
- PT_F106,
- PT_F107,
- PT_F108,
- PT_F109,
- PT_F110,
- PT_F111,
- PT_F112,
- PT_F113,
- PT_F114,
- PT_F115,
- PT_F116,
- PT_F117,
- PT_F118,
- PT_F119,
- PT_F120,
- PT_F121,
- PT_F122,
- PT_F123,
- PT_F124,
- PT_F125,
- PT_F126,
- PT_F127,
- /* predicate registers - we don't fetch these individually */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* branch registers */
- PT_B0,
- PT_B1,
- PT_B2,
- PT_B3,
- PT_B4,
- PT_B5,
- PT_B6,
- PT_B7,
- /* virtual frame pointer and virtual return address pointer */
- -1, -1,
- /* other registers */
- PT_PR,
- PT_CR_IIP, /* ip */
- PT_CR_IPSR, /* psr */
- PT_CFM, /* cfm */
- /* kernel registers not visible via ptrace interface (?) */
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* hole */
- -1, -1, -1, -1, -1, -1, -1, -1,
- PT_AR_RSC,
- PT_AR_BSP,
- PT_AR_BSPSTORE,
- PT_AR_RNAT,
- -1,
- -1, /* Not available: FCR, IA32 floating control register */
- -1, -1,
- -1, /* Not available: EFLAG */
- -1, /* Not available: CSD */
- -1, /* Not available: SSD */
- -1, /* Not available: CFLG */
- -1, /* Not available: FSR */
- -1, /* Not available: FIR */
- -1, /* Not available: FDR */
- -1,
- PT_AR_CCV,
- -1, -1, -1,
- PT_AR_UNAT,
- -1, -1, -1,
- PT_AR_FPSR,
- -1, -1, -1,
- -1, /* Not available: ITC */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1,
- PT_AR_PFS,
- PT_AR_LC,
- PT_AR_EC,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1,
- };
-
-bool
-ia64_target::low_cannot_store_register (int regno)
-{
- return false;
-}
-
-bool
-ia64_target::low_cannot_fetch_register (int regno)
-{
- return false;
-}
-
-/* GDB register numbers. */
-#define IA64_GR0_REGNUM 0
-#define IA64_FR0_REGNUM 128
-#define IA64_FR1_REGNUM 129
-
-bool
-ia64_target::low_fetch_register (regcache *regcache, int regnum)
-{
- /* r0 cannot be fetched but is always zero. */
- if (regnum == IA64_GR0_REGNUM)
- {
- const gdb_byte zero[8] = { 0 };
-
- gdb_assert (sizeof (zero) == register_size (regcache->tdesc, regnum));
- supply_register (regcache, regnum, zero);
- return true;
- }
-
- /* fr0 cannot be fetched but is always zero. */
- if (regnum == IA64_FR0_REGNUM)
- {
- const gdb_byte f_zero[16] = { 0 };
-
- gdb_assert (sizeof (f_zero) == register_size (regcache->tdesc, regnum));
- supply_register (regcache, regnum, f_zero);
- return true;
- }
-
- /* fr1 cannot be fetched but is always one (1.0). */
- if (regnum == IA64_FR1_REGNUM)
- {
- const gdb_byte f_one[16] =
- { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 };
-
- gdb_assert (sizeof (f_one) == register_size (regcache->tdesc, regnum));
- supply_register (regcache, regnum, f_one);
- return true;
- }
-
- return false;
-}
-
-static struct usrregs_info ia64_usrregs_info =
- {
- ia64_num_regs,
- ia64_regmap,
- };
-
-static struct regs_info myregs_info =
- {
- NULL, /* regset_bitmap */
- &ia64_usrregs_info
- };
-
-const regs_info *
-ia64_target::get_regs_info ()
-{
- return &myregs_info;
-}
-
-void
-ia64_target::low_arch_setup ()
-{
- current_process ()->tdesc = tdesc_ia64;
-}
-
-/* The linux target ops object. */
-
-linux_process_target *the_linux_target = &the_ia64_target;
-
-void
-initialize_low_arch (void)
-{
- init_registers_ia64 ();
-}