Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:tabraham1:branches:home:jeff_mahoney:crash-python:devel
gdb
0016-bfd-add-kdumpfile-target.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0016-bfd-add-kdumpfile-target.patch of Package gdb
From d75a0db552cda31129961a1b7c857df16ce26fb8 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney <jeffm@suse.com> Date: Fri, 15 Jul 2022 14:33:01 -0400 Subject: [PATCH 16/17] bfd: add kdumpfile target --- bfd/Makefile.am | 6 +- bfd/Makefile.in | 11 +- bfd/aclocal.m4 | 1 + bfd/bfd-in2.h | 4 +- bfd/config.bfd | 4 + bfd/configure | 279 +++++++++++++++- bfd/configure.ac | 15 + bfd/kdumpfile.c | 804 +++++++++++++++++++++++++++++++++++++++++++++++ bfd/kdumpfile.h | 37 +++ bfd/targets.c | 6 +- 10 files changed, 1160 insertions(+), 7 deletions(-) create mode 100644 bfd/kdumpfile.c create mode 100644 bfd/kdumpfile.h diff --git a/bfd/Makefile.am b/bfd/Makefile.am index b9a3f8207ac..0e516dc3d4b 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -55,9 +55,11 @@ endif ZLIB = @zlibdir@ -lz ZLIBINC = @zlibinc@ +KDUMP_CFLAGS = @KDUMP_CFLAGS@ + WARN_CFLAGS = @WARN_CFLAGS@ NO_WERROR = @NO_WERROR@ -AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) +AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) $(KDUMP_CFLAGS) AM_CPPFLAGS = -DBINDIR='"$(bindir)"' -DLIBDIR='"$(libdir)"' @LARGEFILE_CPPFLAGS@ if PLUGINS bfdinclude_HEADERS += $(INCDIR)/plugin-api.h @@ -577,6 +579,7 @@ BFD64_BACKENDS = \ elfxx-x86.lo \ elf64-bpf.lo \ elf64.lo \ + kdumpfile.lo \ mach-o-aarch64.lo \ mach-o-x86-64.lo \ mmo.lo \ @@ -620,6 +623,7 @@ BFD64_BACKENDS_CFILES = \ elfxx-loongarch.c \ elfxx-mips.c \ elfxx-riscv.c \ + kdumpfile.c \ mach-o-aarch64.c \ mach-o-x86-64.c \ mmo.c \ diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 934dd4bc066..ee63d165c0b 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -122,6 +122,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/nls.m4 \ $(top_srcdir)/../config/override.m4 \ + $(top_srcdir)/../config/pkg.m4 \ $(top_srcdir)/../config/plugins.m4 \ $(top_srcdir)/../config/po.m4 \ $(top_srcdir)/../config/progtest.m4 \ @@ -371,6 +372,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTOBJEXT = @INSTOBJEXT@ +KDUMP_CFLAGS = @KDUMP_CFLAGS@ +KDUMP_LIBS = @KDUMP_LIBS@ LARGEFILE_CPPFLAGS = @LARGEFILE_CPPFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ @@ -405,6 +408,9 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKGVERSION = @PKGVERSION@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSUB = @POSUB@ RANLIB = @RANLIB@ REPORT_BUGS_TEXI = @REPORT_BUGS_TEXI@ @@ -526,7 +532,7 @@ libbfd_la_LDFLAGS = $(am__append_1) -release `cat libtool-soversion` \ # case both are empty. ZLIB = @zlibdir@ -lz ZLIBINC = @zlibinc@ -AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) +AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) $(KDUMP_CFLAGS) AM_CPPFLAGS = -DBINDIR='"$(bindir)"' -DLIBDIR='"$(libdir)"' \ @LARGEFILE_CPPFLAGS@ @HDEFINES@ @COREFLAG@ @TDEFINES@ \ $(CSEARCH) $(CSWITCHES) $(HAVEVECS) @INCINTL@ @@ -1046,6 +1052,7 @@ BFD64_BACKENDS = \ elfxx-x86.lo \ elf64-bpf.lo \ elf64.lo \ + kdumpfile.lo \ mach-o-aarch64.lo \ mach-o-x86-64.lo \ mmo.lo \ @@ -1089,6 +1096,7 @@ BFD64_BACKENDS_CFILES = \ elfxx-loongarch.c \ elfxx-mips.c \ elfxx-riscv.c \ + kdumpfile.c \ mach-o-aarch64.c \ mach-o-x86-64.c \ mmo.c \ @@ -1688,6 +1696,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ihex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irix-core.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdumpfile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbfd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linker.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lynx-core.Plo@am__quote@ diff --git a/bfd/aclocal.m4 b/bfd/aclocal.m4 index 0f8aa1d4518..0a6c0da95da 100644 --- a/bfd/aclocal.m4 +++ b/bfd/aclocal.m4 @@ -1176,6 +1176,7 @@ m4_include([../config/largefile.m4]) m4_include([../config/lead-dot.m4]) m4_include([../config/nls.m4]) m4_include([../config/override.m4]) +m4_include([../config/pkg.m4]) m4_include([../config/plugins.m4]) m4_include([../config/po.m4]) m4_include([../config/progtest.m4]) diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index c0b563aec02..d59f03594cc 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -6855,6 +6855,7 @@ struct bfd struct bfd_pef_data_struct *pef_data; struct bfd_pef_xlib_data_struct *pef_xlib_data; struct bfd_sym_data_struct *sym_data; + struct bfd_kdumpfile_data_struct *kdumpfile_data; void *any; } tdata; @@ -7383,7 +7384,8 @@ enum bfd_flavour bfd_target_mach_o_flavour, bfd_target_pef_flavour, bfd_target_pef_xlib_flavour, - bfd_target_sym_flavour + bfd_target_sym_flavour, + bfd_target_kdumpfile_flavour }; enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; diff --git a/bfd/config.bfd b/bfd/config.bfd index 872685cfb72..be80cdd3629 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -787,6 +787,10 @@ case "${targ}" in iq2000-*-elf) targ_defvec=iq2000_elf32_vec ;; + kdumpfile | *-kdumpfile) + targ_defvec=kdumpfile_vec + targ_archs= + ;; lm32-*-elf | lm32-*-rtems*) targ_defvec=lm32_elf32_vec diff --git a/bfd/configure b/bfd/configure index 0ef4c206fb0..e2d5445dd8c 100755 --- a/bfd/configure +++ b/bfd/configure @@ -649,6 +649,11 @@ all_backends bfd64_libs wordsize TDEFINES +KDUMP_LIBS +KDUMP_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG SHARED_LIBADD SHARED_LDFLAGS LIBM @@ -845,6 +850,7 @@ enable_maintainer_mode enable_install_libbfd enable_nls with_system_zlib +with_kdumpfile ' ac_precious_vars='build_alias host_alias @@ -854,7 +860,12 @@ CFLAGS LDFLAGS LIBS CPPFLAGS -CPP' +CPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +KDUMP_CFLAGS +KDUMP_LIBS' # Initialize some variables set by options. @@ -1517,6 +1528,7 @@ Optional Packages: Binutils" --with-bugurl=URL Direct users to URL to report a bug --with-system-zlib use installed libz + --with-kdumpfile enable kdumpfile target Some influential environment variables: CC C compiler command @@ -1527,6 +1539,14 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + KDUMP_CFLAGS + C compiler flags for KDUMP, overriding pkg-config + KDUMP_LIBS linker flags for KDUMP, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -11086,7 +11106,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11089 "configure" +#line 11109 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11192,7 +11212,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11195 "configure" +#line 11215 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -13256,6 +13276,257 @@ fi # target stuff: +# Check whether --with-kdumpfile was given. +if test "${with_kdumpfile+set}" = set; then : + withval=$with_kdumpfile; case "${withval}" in + yes) want_kdumpfile=true ;; + no) want_kdumpfile=false ;; + *) as_fn_error $? "bad value ${withval} for BFD with-kdumpfile option" "$LINENO" 5 ;; +esac +else + want_kdumpfile=false +fi + +if test "$want_kdumpfile" = "true"; then + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libkdumpfile libaddrxlat" >&5 +$as_echo_n "checking for libkdumpfile libaddrxlat... " >&6; } + +if test -n "$KDUMP_CFLAGS"; then + pkg_cv_KDUMP_CFLAGS="$KDUMP_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libkdumpfile libaddrxlat\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libkdumpfile libaddrxlat") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_KDUMP_CFLAGS=`$PKG_CONFIG --cflags "libkdumpfile libaddrxlat" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$KDUMP_LIBS"; then + pkg_cv_KDUMP_LIBS="$KDUMP_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libkdumpfile libaddrxlat\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libkdumpfile libaddrxlat") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_KDUMP_LIBS=`$PKG_CONFIG --libs "libkdumpfile libaddrxlat" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + +if test $pkg_failed = no; then + pkg_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $pkg_cv_KDUMP_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + pkg_failed=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$pkg_save_LDFLAGS +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + KDUMP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libkdumpfile libaddrxlat" 2>&1` + else + KDUMP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libkdumpfile libaddrxlat" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$KDUMP_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libkdumpfile libaddrxlat) were not met: + +$KDUMP_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables KDUMP_CFLAGS +and KDUMP_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables KDUMP_CFLAGS +and KDUMP_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/>. +See \`config.log' for more details" "$LINENO" 5; } +else + KDUMP_CFLAGS=$pkg_cv_KDUMP_CFLAGS + KDUMP_LIBS=$pkg_cv_KDUMP_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + + canon_targets="$canon_targets kdumpfile" +fi + # Canonicalize the secondary target names. if test -n "$enable_targets" ; then for targ in `echo $enable_targets | sed 's/,/ /g'` @@ -13444,6 +13715,7 @@ do ia64_pei_vec) tb="$tb pei-ia64.lo pepigen.lo $coff"; target_size=64 ;; ip2k_elf32_vec) tb="$tb elf32-ip2k.lo elf32.lo $elf" ;; iq2000_elf32_vec) tb="$tb elf32-iq2000.lo elf32.lo $elf" ;; + kdumpfile_vec) tb="$tb kdumpfile.lo" ;; k1om_elf64_vec) tb="$tb elf64-x86-64.lo elfxx-x86.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;; k1om_elf64_fbsd_vec) tb="$tb elf64-x86-64.lo elfxx-x86.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;; l1om_elf64_vec) tb="$tb elf64-x86-64.lo elfxx-x86.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;; @@ -14751,6 +15023,7 @@ _ACEOF fi + if test "$plugins" = "yes"; then supports_plugins=1 else diff --git a/bfd/configure.ac b/bfd/configure.ac index 9e873736792..fc00fcaea5c 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -334,6 +334,19 @@ AC_SUBST(SHARED_LDFLAGS) AC_SUBST(SHARED_LIBADD) # target stuff: +AC_ARG_WITH(kdumpfile, +[ --with-kdumpfile enable kdumpfile target ], +[case "${withval}" in + yes) want_kdumpfile=true ;; + no) want_kdumpfile=false ;; + *) AC_MSG_ERROR(bad value ${withval} for BFD with-kdumpfile option) ;; +esac],[want_kdumpfile=false])dnl + +if test "$want_kdumpfile" = "true"; then + PKG_CHECK_MODULES([KDUMP], [libkdumpfile libaddrxlat], [], []) + AC_SUBST(KDUMP_CFLAGS) + canon_targets="$canon_targets kdumpfile" +fi # Canonicalize the secondary target names. if test -n "$enable_targets" ; then @@ -523,6 +536,7 @@ do ia64_pei_vec) tb="$tb pei-ia64.lo pepigen.lo $coff"; target_size=64 ;; ip2k_elf32_vec) tb="$tb elf32-ip2k.lo elf32.lo $elf" ;; iq2000_elf32_vec) tb="$tb elf32-iq2000.lo elf32.lo $elf" ;; + kdumpfile_vec) tb="$tb kdumpfile.lo" ;; k1om_elf64_vec) tb="$tb elf64-x86-64.lo elfxx-x86.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;; k1om_elf64_fbsd_vec) tb="$tb elf64-x86-64.lo elfxx-x86.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;; l1om_elf64_vec) tb="$tb elf64-x86-64.lo elfxx-x86.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;; @@ -1068,6 +1082,7 @@ if test -n "$TRAD_HEADER"; then [Name of host specific header file to include in trad-core.c.]) fi + if test "$plugins" = "yes"; then supports_plugins=1 else diff --git a/bfd/kdumpfile.c b/bfd/kdumpfile.c new file mode 100644 index 00000000000..9009ac0e028 --- /dev/null +++ b/bfd/kdumpfile.c @@ -0,0 +1,806 @@ +#include "config.h" +#include <errno.h> +#include <string.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <zlib.h> +#include <dlfcn.h> +#include <libiberty.h> +#include "bfd.h" +#include "libbfd.h" + +/* + * This is super hacky but it means that we don't force every consumer + * of the library to link with libkdumpfile when it won't need it. + */ +#define KDUMPFILE_USE_DLOPEN 1 + +#if KDUMPFILE_USE_DLOPEN +#define kdump_new indirect_kdump_new +#define kdump_free indirect_kdump_free +#define kdump_read indirect_kdump_read +#define kdump_get_err indirect_kdump_get_err +#define kdump_get_attr indirect_kdump_get_attr +#define kdump_get_typed_attr indirect_kdump_get_typed_attr +#define kdump_set_attr indirect_kdump_set_attr +#define kdump_attr_ref_get indirect_kdump_attr_ref_get +#define kdump_get_addrxlat indirect_kdump_get_addrxlat +#define kdump_attr_iter_start indirect_kdump_attr_iter_start +#define kdump_attr_iter_next indirect_kdump_attr_iter_next +#define kdump_attr_iter_end indirect_kdump_attr_iter_end +#define addrxlat_sys_get_meth indirect_addrxlat_sys_get_meth +#define addrxlat_sys_get_map indirect_addrxlat_sys_get_map +#define addrxlat_map_ranges indirect_addrxlat_map_ranges +#endif + +#include "kdumpfile.h" + +#if KDUMPFILE_USE_DLOPEN + +kdump_ctx_t *(*kdump_new_p)(void); +void (*kdump_free_p)(kdump_ctx_t *); +kdump_status (*kdump_read_p)(kdump_ctx_t *, kdump_addrspace_t, kdump_addr_t, void *, size_t *); +const char * (*kdump_get_err_p)(kdump_ctx_t *); +kdump_status (*kdump_get_attr_p)(kdump_ctx_t *, const char *, kdump_attr_t *); +kdump_status (*kdump_get_typed_attr_p)(kdump_ctx_t *, const char *, kdump_attr_t *); +kdump_status (*kdump_set_attr_p)(kdump_ctx_t *, const char *, const kdump_attr_t *); +kdump_status (*kdump_attr_ref_get_p)(kdump_ctx_t *, const kdump_attr_ref_t *, kdump_attr_t *); +kdump_status (*kdump_get_addrxlat_p)(kdump_ctx_t *, addrxlat_ctx_t **, addrxlat_sys_t **); +kdump_status (*kdump_attr_iter_start_p)(kdump_ctx_t *, const char *, kdump_attr_iter_t *); +kdump_status (*kdump_attr_iter_next_p)(kdump_ctx_t *, kdump_attr_iter_t *); +void (*kdump_attr_iter_end_p)(kdump_ctx_t *, kdump_attr_iter_t *); +const addrxlat_meth_t *(*addrxlat_sys_get_meth_p)(const addrxlat_sys_t *, addrxlat_sys_meth_t); +addrxlat_map_t *(*addrxlat_sys_get_map_p)(const addrxlat_sys_t *, addrxlat_sys_map_t); +size_t (*addrxlat_map_len_p)(const addrxlat_map_t *map); +const addrxlat_range_t *(*addrxlat_map_ranges_p)(const addrxlat_map_t *map); + +typedef void (*funcptr_t)(void); + +struct required_fn { + const char *name; + funcptr_t *target; +} required_fns[] = { + { "kdump_new", (funcptr_t *)&kdump_new_p, }, + { "kdump_free", (funcptr_t *)&kdump_free_p, }, + { "kdump_read", (funcptr_t *)&kdump_read_p, }, + { "kdump_get_err", (funcptr_t *)&kdump_get_err_p, }, + { "kdump_get_attr", (funcptr_t *)&kdump_get_attr_p, }, + { "kdump_get_typed_attr", (funcptr_t *)&kdump_get_typed_attr_p, }, + { "kdump_set_attr", (funcptr_t *)&kdump_set_attr_p, }, + { "kdump_attr_ref_get", (funcptr_t *)&kdump_attr_ref_get_p, }, + { "kdump_attr_iter_start", (funcptr_t *)&kdump_attr_iter_start_p, }, + { "kdump_attr_iter_next", (funcptr_t *)&kdump_attr_iter_next_p, }, + { "kdump_attr_iter_end", (funcptr_t *)&kdump_attr_iter_end_p, }, + { "kdump_get_addrxlat", (funcptr_t *)&kdump_get_addrxlat_p, }, + { "addrxlat_sys_get_meth", (funcptr_t *)&addrxlat_sys_get_meth_p, }, + { "addrxlat_sys_get_map", (funcptr_t *)&addrxlat_sys_get_map_p, }, + { "addrxlat_map_len", (funcptr_t *)&addrxlat_map_len_p, }, + { "addrxlat_map_ranges", (funcptr_t *)&addrxlat_map_ranges_p, }, +}; + + +extern kdump_ctx_t * +kdump_new(void); + +kdump_ctx_t * +kdump_new(void) +{ + return kdump_new_p (); +} + +void +kdump_free(kdump_ctx_t *ctx) +{ + return kdump_free_p(ctx); +} + +kdump_status +kdump_read(kdump_ctx_t *ctx, kdump_addrspace_t as, kdump_addr_t addr, + void *buffer, size_t *plength) +{ + return kdump_read_p(ctx, as, addr, buffer, plength); +} + +const char * +kdump_get_err(kdump_ctx_t *ctx) +{ + return kdump_get_err_p (ctx); +} + +kdump_status +kdump_get_attr(kdump_ctx_t *ctx, const char *key, kdump_attr_t *valp) +{ + return kdump_get_attr_p (ctx, key, valp); +} + +kdump_status +kdump_get_typed_attr(kdump_ctx_t *ctx, const char *key, kdump_attr_t *valp) +{ + return kdump_get_typed_attr_p (ctx, key, valp); +} + +kdump_status +kdump_set_attr(kdump_ctx_t *ctx, const char *key, const kdump_attr_t *valp) +{ + return kdump_set_attr_p (ctx, key, valp); +} + +kdump_status +kdump_attr_ref_get(kdump_ctx_t *ctx, const kdump_attr_ref_t *ref, + kdump_attr_t *valp) +{ + return kdump_attr_ref_get_p (ctx, ref, valp); +} + + +kdump_status +kdump_attr_iter_start(kdump_ctx_t *ctx, const char *path, + kdump_attr_iter_t *iter) +{ + return kdump_attr_iter_start_p(ctx, path, iter); +} + +kdump_status +kdump_attr_iter_next(kdump_ctx_t *ctx, kdump_attr_iter_t *iter) +{ + return kdump_attr_iter_next_p(ctx, iter); +} + +void +kdump_attr_iter_end(kdump_ctx_t *ctx, kdump_attr_iter_t *iter) +{ + return kdump_attr_iter_end_p(ctx, iter); +} + +kdump_status +kdump_get_addrxlat(kdump_ctx_t *ctx, + addrxlat_ctx_t **axctx, addrxlat_sys_t **axsys) +{ + return kdump_get_addrxlat_p (ctx, axctx, axsys); +} + +const addrxlat_meth_t * +addrxlat_sys_get_meth(const addrxlat_sys_t *sys, addrxlat_sys_meth_t idx) +{ + return addrxlat_sys_get_meth_p (sys, idx); +} + +addrxlat_map_t * +addrxlat_sys_get_map(const addrxlat_sys_t *sys, addrxlat_sys_map_t idx) +{ + return addrxlat_sys_get_map_p (sys, idx); +} + +const addrxlat_range_t * +addrxlat_map_ranges(const addrxlat_map_t *map) +{ + return addrxlat_map_ranges_p(map); +} + + +size_t +addrxlat_map_len (const addrxlat_map_t *map) +{ + return addrxlat_map_len_p(map); +} + +static void * +locate_symbol(void *handle, const char *symname) +{ + char *error; + void *fn; + + fn = dlsym(handle, symname); + error = dlerror(); + if (error != NULL) + { + fprintf(stderr, "failed to locate required symbol %s\n", symname); + return NULL; + } + + return fn; +} + +static bool +kdumpfile_init_libs(void) +{ + int i; + void *libkdumpfile; + int count = ARRAY_SIZE(required_fns); + + if (*required_fns[count - 1].target != NULL) + return true; + + libkdumpfile = dlopen("libkdumpfile.so.10", RTLD_NOW); + if (!libkdumpfile) + libkdumpfile = dlopen("libkdumpfile.so.9", RTLD_NOW); + if (!libkdumpfile) + return false; + + for (i = 0; i < count; i++) { + void *fn = locate_symbol(libkdumpfile, required_fns[i].name); + if (fn == NULL) + return false; + *(required_fns[i].target) = fn; + } + + return true; +} +#else +static inline bool kdumpfile_init_libs(void) { return true; } +#endif + +static const char *addrxlat_sys_meth_descr(addrxlat_sys_meth_t meth) +{ + static char buf[32]; + + switch (meth) + { + case ADDRXLAT_SYS_METH_NONE: + return "none"; + case ADDRXLAT_SYS_METH_PGT: + return "pgt"; + case ADDRXLAT_SYS_METH_UPGT: + return "upgt"; + case ADDRXLAT_SYS_METH_DIRECT: + return "direct"; + case ADDRXLAT_SYS_METH_KTEXT: + return "ktext"; + case ADDRXLAT_SYS_METH_VMEMMAP: + return "vmemmap"; + case ADDRXLAT_SYS_METH_RDIRECT: + return "direct"; + case ADDRXLAT_SYS_METH_MACHPHYS_KPHYS: + return "machphys_kphys"; + case ADDRXLAT_SYS_METH_KPHYS_MACHPHYS: + return "phys_machkphys"; + case ADDRXLAT_SYS_METH_CUSTOM: + return "custom-meth-0"; + }; + + snprintf(buf, sizeof(buf), "custom-meth-%d", meth - ADDRXLAT_SYS_METH_CUSTOM); + + return buf; +} + +static int +check_kphys_direct_map(addrxlat_sys_t *sys, addrxlat_addr_t target_addr) +{ + addrxlat_map_t *map; + size_t i, n; + const addrxlat_range_t *range; + addrxlat_addr_t addr; + + map = addrxlat_sys_get_map(sys, ADDRXLAT_SYS_MAP_KPHYS_DIRECT); + if (!map) + { + fprintf(stderr, "Can't get MAP_KPHYS_DIRECT map\n"); + bfd_set_error (bfd_error_wrong_format); + return -1; + } + + n = addrxlat_map_len(map); + addr = 0; + range = addrxlat_map_ranges(map); + + for (i = 0; i < n; ++i) + { + if (addr == target_addr && range->meth == ADDRXLAT_SYS_METH_RDIRECT) + { + return 1; + } + addr += range->endoff + 1; + ++range; + } + + return 0; +} + +/* + * This should be as simple as requesting cpu.0.PRSTATUS and checking its size. + * Unfortunately, there is padding in the elf_prstatus structure and the + * blob ends up being unusable by gdb. + */ +static int +get_register_section(kdump_ctx_t *ctx, void *data, int datasize) +{ + const char *attrname = "cpu.0.reg"; + kdump_attr_iter_t iter; + kdump_attr_t attr = { .type = KDUMP_NUMBER ,}; + kdump_status res; + int count = 0; + int regsize; + + res = kdump_get_typed_attr(ctx, "arch.ptr_size", &attr); + if (res != KDUMP_OK) + return -1; + + regsize = attr.val.number; + + res = kdump_attr_iter_start(ctx, attrname, &iter); + if (res != KDUMP_OK) + return -1; + + while (iter.key) + { + if (data) + { + int offset; + + res = kdump_attr_ref_get (ctx, &iter.pos, &attr); + if (res != KDUMP_OK) + break; + + offset = count * regsize; + + if (offset + regsize > datasize) + { + res = KDUMP_ERR_NODATA; + break; + } + + memcpy(data + offset, &attr.val.number, regsize); + } + + count += 1; + res = kdump_attr_iter_next(ctx, &iter); + if (res != KDUMP_OK) + break; + } + + kdump_attr_iter_end(ctx, &iter); + if (res != KDUMP_OK) + return -1; + + return count * regsize; +} + +static bool +create_range_sections(bfd *abfd, struct bfd_kdumpfile_data_struct *tdata) +{ + kdump_ctx_t *ctx = tdata->kdump_ctx; + kdump_status res; + asection *asect; + addrxlat_sys_t *sys; + + addrxlat_map_t *map; + addrxlat_addr_t addr; + const addrxlat_range_t *range; + size_t i, n; + const char *kaslr_offset_str; + struct kdumpfile_section_data *secdata; + kdump_addrspace_t as; + int size; + + res = kdump_get_addrxlat (ctx, NULL, &sys); + if (res != KDUMP_OK) + { + fprintf(stderr, "Can't get addrxlat\n"); + bfd_set_error (bfd_error_wrong_format); + return false; + } + + map = addrxlat_sys_get_map(sys, ADDRXLAT_SYS_MAP_KV_PHYS); + if (!map) + { + fprintf(stderr, "Can't get MAP_KV_PHYS map\n"); + bfd_set_error (bfd_error_wrong_format); + return false; + } + + res = kdump_get_string_attr (ctx, "linux.vmcoreinfo.lines.KERNELOFFSET", + &kaslr_offset_str); + if (res != KDUMP_OK && res != KDUMP_ERR_NOKEY) + { + fprintf(stderr, "Can't get kaslr offset\n"); + bfd_set_error (bfd_error_wrong_format); + return false; + + } + + if (res == KDUMP_OK) + { + errno = 0; + tdata->kaslr_offset = strtoul(kaslr_offset_str, NULL, 16); + if (errno) + { + fprintf(stderr, "Can't parse kaslr offset\n"); + bfd_set_error (bfd_error_wrong_format); + return false; + } + abfd->start_address = tdata->kaslr_offset; + } + + n = addrxlat_map_len(map); + addr = 0; + range = addrxlat_map_ranges(map); + + for (i = 0; i < n; ++i) + { + char *name; + int ret; + + switch (range->meth) + { + case ADDRXLAT_SYS_METH_PGT: + case ADDRXLAT_SYS_METH_VMEMMAP: + case ADDRXLAT_SYS_METH_DIRECT: + case ADDRXLAT_SYS_METH_KTEXT: + break; + case ADDRXLAT_SYS_METH_NONE: + case ADDRXLAT_SYS_METH_UPGT: + case ADDRXLAT_SYS_METH_RDIRECT: + case ADDRXLAT_SYS_METH_MACHPHYS_KPHYS: + case ADDRXLAT_SYS_METH_KPHYS_MACHPHYS: + default: + goto next_range; + }; + + ret = check_kphys_direct_map (sys, addr); + if (ret < 0) + return false; + + if (ret == 0) + { + if (asprintf(&name, ".kv_phys.%s.%" ADDRXLAT_PRIxADDR, + addrxlat_sys_meth_descr (range->meth), addr) < 0) + { + bfd_set_error (bfd_error_no_memory); + return false; + } + as = KDUMP_KVADDR; + } + else + { + /* physical mapping */ + if (asprintf(&name, ".kphys_direct.%" ADDRXLAT_PRIxADDR, addr) < 0) + { + bfd_set_error (bfd_error_no_memory); + return false; + } + as = KDUMP_KPHYSADDR; + } + + asect = bfd_make_section_with_flags (abfd, name, + (SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD)); + if (asect == NULL) + return false; + + secdata = bfd_alloc(abfd, sizeof(struct kdumpfile_section_data)); + if (secdata == NULL) + return false; + + secdata->as = as; + secdata->type = KDUMPFILE_SECTION_MEMORY; + + asect->vma = addr; + asect->size = range->endoff; + asect->used_by_bfd = secdata; + +next_range: + addr += range->endoff + 1; + ++range; + } + + asect = bfd_make_section_with_flags (abfd, ".reg", SEC_HAS_CONTENTS); + if (asect == NULL) + return false; + + secdata = bfd_alloc(abfd, sizeof(struct kdumpfile_section_data)); + if (secdata == NULL) + return false; + + size = get_register_section(ctx, NULL, 0); + if (size < 0) + return false; + + asect->size = size; + asect->used_by_bfd = secdata; + secdata->type = KDUMPFILE_SECTION_PRSTATUS; + + return true; +} + +static const struct arch_map { + const char *uts_machine; + enum bfd_architecture arch; + unsigned long mach; +} arch_map[] = { + { "aarch64", bfd_arch_arm, bfd_mach_arm_8 }, + { "alpha", bfd_arch_alpha, 0 }, + { "arm", bfd_arch_arm, bfd_mach_arm_7 }, + { "ia32", bfd_arch_i386, bfd_mach_i386_i386 }, + { "ia64", bfd_arch_ia64, bfd_mach_ia64_elf64 }, + { "mips", bfd_arch_mips, 0 }, + { "ppc", bfd_arch_powerpc, bfd_mach_ppc }, + { "ppc64", bfd_arch_powerpc, bfd_mach_ppc64 }, + { "s390", bfd_arch_s390, bfd_mach_s390_31 }, + { "s390x", bfd_arch_s390, bfd_mach_s390_64 }, + { "x86_64", bfd_arch_i386, bfd_mach_x86_64 }, +}; + +static bfd_cleanup +kdumpfile_core_file_p (bfd *abfd) +{ + struct bfd_kdumpfile_data_struct *tdata = NULL; + kdump_status res; + addrxlat_sys_t *xlatsys; + kdump_attr_t archattr; + const struct arch_map *map = NULL; + unsigned int i; + + if (!kdumpfile_init_libs()) + { + bfd_set_error (bfd_error_missing_dso); + goto fail; + } + + tdata = bfd_zalloc(abfd, sizeof(*tdata)); + if (!tdata) + goto fail; + + tdata->kdump_ctx = kdump_new(); + if (!tdata->kdump_ctx) + { + bfd_set_error (bfd_error_no_memory); + goto fail; + } + + if (abfd->iostream == NULL || (abfd->flags & BFD_IN_MEMORY) == BFD_IN_MEMORY) + { + fprintf(stderr, "Can't get file descriptor %p %x\n", + abfd->iostream, abfd->flags & BFD_IN_MEMORY); + bfd_set_error (bfd_error_invalid_target); + goto fail; + } + + res = kdump_set_number_attr(tdata->kdump_ctx, KDUMP_ATTR_FILE_FD, + fileno((FILE *)(abfd->iostream))); + if (res != KDUMP_OK) + { + fprintf(stderr, "Can't set file descriptor\n"); + bfd_set_error (bfd_error_wrong_format); + goto fail; + } + + res = kdump_set_string_attr(tdata->kdump_ctx, "addrxlat.ostype", "linux"); + if (res != KDUMP_OK) + { + fprintf(stderr, "Can't set ostype: %s\n", kdump_get_err(tdata->kdump_ctx)); + bfd_set_error (bfd_error_wrong_format); + goto fail; + } + + res = kdump_get_attr (tdata->kdump_ctx, "addrxlat.ostype", &archattr); + if (res != KDUMP_OK) + { + fprintf(stderr, "Can't get ostype: %s\n", kdump_get_err(tdata->kdump_ctx)); + bfd_set_error (bfd_error_wrong_format); + goto fail; + } + + + res = kdump_get_addrxlat (tdata->kdump_ctx, NULL, &xlatsys); + if (res != KDUMP_OK) + { + fprintf(stderr, "Can't get addrxlat\n"); + bfd_set_error (bfd_error_wrong_format); + goto fail; + } + + res = kdump_get_attr(tdata->kdump_ctx, "arch.name", &archattr); + if (res != KDUMP_OK) + { + fprintf(stderr, "Can't resolve arch\n"); + bfd_set_error (bfd_error_invalid_target); + goto fail; + + } + + for (i = 0; i < ARRAY_SIZE(arch_map); i++) + { + if (strcmp(arch_map[i].uts_machine, archattr.val.string) == 0) { + map = &arch_map[i]; + break; + } + } + + if (!map) + { + fprintf(stderr, "Can't determine architecture\n"); + goto fail; + } + + /* Select architecture */ + bfd_default_set_arch_mach(abfd, map->arch, map->mach); + + if (!create_range_sections(abfd, tdata)) + goto fail; + + abfd->tdata.kdumpfile_data = tdata; + return _bfd_no_cleanup; + + fail: + if (tdata) + { + if (tdata->kdump_ctx) + kdump_free (tdata->kdump_ctx); + bfd_release (abfd, tdata); + abfd->tdata.kdumpfile_data = NULL; + } + bfd_section_list_clear (abfd); + return NULL; +} + +static char * +kdumpfile_core_file_failing_command (bfd *abfd) +{ + struct bfd_kdumpfile_data_struct *tdata = abfd->tdata.kdumpfile_data; + + if (!*tdata->failing_command) + { + kdump_attr_t sysname, release; + kdump_status res; + + res = kdump_get_attr(tdata->kdump_ctx, "linux.uts.sysname", &sysname); + if (res != KDUMP_OK) + return "<unknown>"; + res = kdump_get_attr(tdata->kdump_ctx, "linux.uts.release", &release); + if (res != KDUMP_OK) + return "<unknown>"; + + snprintf(tdata->failing_command, sizeof(tdata->failing_command), "%s %s", + sysname.val.string, release.val.string); + } + + return tdata->failing_command; +} + +static int +kdumpfile_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED) +{ + /*return core_signal (abfd);*/ + return 0; +} + +static bool +kdumpfile_core_file_matches_executable_p (bfd *core_bfd ATTRIBUTE_UNUSED, + bfd *exec_bfd ATTRIBUTE_UNUSED) +{ + /* + * We need a symbol table for exec_bfd to compare our release against + * the kernel release. This doesn't actually impact anything other than + * whether a warning is printed. + */ + return true; +} + +static int +kdumpfile_core_file_pid (bfd *ignore_abfd ATTRIBUTE_UNUSED) +{ + return 0; +} + +static bool +kdumpfile_get_section_contents (bfd *abfd ATTRIBUTE_UNUSED, + sec_ptr section ATTRIBUTE_UNUSED, + void *location ATTRIBUTE_UNUSED, + file_ptr offset ATTRIBUTE_UNUSED, + bfd_size_type count ATTRIBUTE_UNUSED) +{ + + struct bfd_kdumpfile_data_struct *tdata = abfd->tdata.kdumpfile_data; + kdump_status res; + size_t len = count; + uint64_t addr = section->vma + offset; + const struct kdumpfile_section_data *secdata = section->used_by_bfd; + + if (secdata->type == KDUMPFILE_SECTION_MEMORY) + { + res = kdump_read(tdata->kdump_ctx, secdata->as, addr, location, &len); + return (res == KDUMP_OK && len == count); + } + + if (secdata->type == KDUMPFILE_SECTION_PRSTATUS) + { + res = get_register_section (tdata->kdump_ctx, location, count); + return true; + } + + printf("Couldn't read section %s\n", section->name); + + return false; +} + +static bool +kdumpfile_get_section_contents_in_window(bfd *abfd ATTRIBUTE_UNUSED, + sec_ptr section ATTRIBUTE_UNUSED, + bfd_window *w ATTRIBUTE_UNUSED, + file_ptr offset ATTRIBUTE_UNUSED, + bfd_size_type count ATTRIBUTE_UNUSED) +{ + fprintf(stderr, "Reading window\n"); + return false; +} + +/* If somebody calls any byte-swapping routines, shoot them. */ + +static void +swap_abort (void) +{ + /* This way doesn't require any declaration for ANSI to fuck up. */ + abort (); +} + +#define NO_GET ((bfd_vma (*) (const void *)) swap_abort) +#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) +#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) + +#define kdumpfile_close_and_cleanup _bfd_generic_close_and_cleanup +#define kdumpfile_bfd_free_cached_info _bfd_generic_bfd_free_cached_info +#define kdumpfile_new_section_hook _bfd_generic_new_section_hook + +const bfd_target kdumpfile_vec = + { + "kdumpfile", + bfd_target_kdumpfile_flavour, + BFD_ENDIAN_UNKNOWN, /* Target byte order. */ + BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */ + (HAS_RELOC | EXEC_P | /* Object flags. */ + HAS_LINENO | HAS_DEBUG | + HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), + (SEC_HAS_CONTENTS | /* Section flags. */ + SEC_ALLOC | SEC_LOAD | SEC_RELOC), + 0, /* Symbol prefix. */ + ' ', /* ar_pad_char. */ + 16, /* ar_max_namelen. */ + 0, /* Match priority. */ + TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */ + + NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data. */ + NO_GET, NO_GETS, NO_PUT, /* 32 bit data. */ + NO_GET, NO_GETS, NO_PUT, /* 16 bit data. */ + NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs. */ + NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs. */ + NO_GET, NO_GETS, NO_PUT, /* 16 bit hdrs. */ + + { /* bfd_check_format. */ + _bfd_dummy_target, /* Unknown format. */ + _bfd_dummy_target, /* Object file. */ + _bfd_dummy_target, /* Archive. */ + kdumpfile_core_file_p /* A core file. */ + }, + { /* bfd_set_format. */ + _bfd_bool_bfd_false_error, + _bfd_bool_bfd_false_error, + _bfd_bool_bfd_false_error, + _bfd_bool_bfd_false_error + }, + { /* bfd_write_contents. */ + _bfd_bool_bfd_false_error, + _bfd_bool_bfd_false_error, + _bfd_bool_bfd_false_error, + _bfd_bool_bfd_false_error + }, + + BFD_JUMP_TABLE_GENERIC (kdumpfile), + BFD_JUMP_TABLE_COPY (_bfd_generic), + BFD_JUMP_TABLE_CORE (kdumpfile), + BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), + BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), + BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), + BFD_JUMP_TABLE_WRITE (_bfd_generic), + BFD_JUMP_TABLE_LINK (_bfd_nolink), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + NULL, + + NULL /* Backend_data. */ + }; diff --git a/bfd/kdumpfile.h b/bfd/kdumpfile.h new file mode 100644 index 00000000000..6496bfbb886 --- /dev/null +++ b/bfd/kdumpfile.h @@ -0,0 +1,37 @@ +#ifndef _BFD_KDUMPFILE_H_ +#define _BFD_KDUMPFILE_H_ + +#include "bfd.h" +#include <libkdumpfile/kdumpfile.h> +#include <libkdumpfile/addrxlat.h> + +#ifdef __cplusplus +extern "C" { +#endif +struct bfd_kdumpfile_data_struct +{ + kdump_ctx_t *kdump_ctx; + uint64_t kaslr_offset; + char failing_command[132]; +}; + +enum kdumpfile_section_type { + KDUMPFILE_SECTION_MEMORY = 1, + KDUMPFILE_SECTION_PRSTATUS = 2, +}; + +struct kdumpfile_section_data { + kdump_addrspace_t as; + enum kdumpfile_section_type type; +}; + +extern const bfd_target kdumpfile_vec; + +#define bfd_kdumpfile_get_data(abfd) ((abfd)->tdata.kdumpfile_data) + +#ifdef __cplusplus +} +#endif + + +#endif /* _BFD_KDUMPFILE_H_ */ diff --git a/bfd/targets.c b/bfd/targets.c index 417743efc0e..19876cf7ddf 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -967,6 +967,9 @@ extern const bfd_target core_ptrace_vec; extern const bfd_target core_sco5_vec; extern const bfd_target core_trad_vec; +extern const bfd_target kdumpfile_vec; + + static const bfd_target * const _bfd_target_vector[] = { #ifdef SELECT_VECS @@ -1373,6 +1376,7 @@ static const bfd_target * const _bfd_target_vector[] = &loongarch_elf32_vec, &loongarch_elf64_vec, #endif + &kdumpfile_vec, #endif /* not SELECT_VECS */ @@ -1428,7 +1432,6 @@ static const bfd_target * const _bfd_target_vector[] = #ifdef TRAD_CORE &core_trad_vec, #endif - NULL /* end of list marker */ }; const bfd_target *const *const bfd_target_vector = _bfd_target_vector; @@ -1814,6 +1817,7 @@ bfd_flavour_name (enum bfd_flavour flavour) case bfd_target_pef_flavour: return "PEF"; case bfd_target_pef_xlib_flavour: return "PEF_XLIB"; case bfd_target_sym_flavour: return "SYM"; + case bfd_target_kdumpfile_flavour: return "kdumpfile"; /* There is no "default" case here so that -Wswitch (part of -Wall) catches missing entries. */ } -- 2.37.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor