From: Guinevere Larsen Date: Wed, 12 Feb 2025 11:25:46 +0000 (-0300) Subject: gdb: Make dwarf support optional at compile time X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4b42385c470c5f72f158f382f4d9c36f927aa84f;p=thirdparty%2Fbinutils-gdb.git gdb: Make dwarf support optional at compile time This commit allows a user to enable or disable dwarf support at compilation time. To do that, a new configure option is introduced, in the form of --enable-gdb-dwarf-support (and the accompanying --disable version). By default, dwarf support is enabled, so no behavior changes occur if a user doesn't use the new feature. If support is disabled, no .c files inside the dwarf2/ subfolder will be compiled into the final binary. To achieve this, this commit also introduces the new macro DWARF_FORMAT_AVAILABLE, which guards the definitions of functions exported from the dwarf reader. If the macro is not defined, there are a couple behaviors that exported functions may have: * no-ops: several functions are used to register things at initialization time, like unwinders. These are turned into no-ops because the user hasn't attempted to read DWARF yet, there's no point in warning that DWARF is unavailable. * warnings: similar to the previous commit, if dwarf would be read or used, the funciton will emit the warning "No dwarf support available." * throw exceptions: If the code that calls a function expects an exceptin in case of errors, and has a try-catch block, an error with the previous message is thrown. I believe that the changed functions should probalby be moved to the dwarf2/public.h header, but that require a much larger refactor, so it is left as a future improvement. Finally, the --enable-gdb-compile configure option has been slightly changed, since compile requires dwarf support. If compile was requested and dwarf was disabled, configure will throw an error. If the option was not used, support will follow what was requested for dwarf (warning the user of what is decided). Reviewed-By: Eli Zaretskii Approved-By: Tom Tromey Approved-By: Andrew Burgess --- diff --git a/gdb/Makefile.in b/gdb/Makefile.in index a3760c6b3fd..998203ce1e2 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1092,36 +1092,6 @@ COMMON_SFILES = \ disasm.c \ displaced-stepping.c \ dummy-frame.c \ - dwarf2/abbrev.c \ - dwarf2/abbrev-table-cache.c \ - dwarf2/ada-imported.c \ - dwarf2/aranges.c \ - dwarf2/attribute.c \ - dwarf2/cooked-index.c \ - dwarf2/cooked-index-entry.c \ - dwarf2/cooked-index-shard.c \ - dwarf2/cooked-index-worker.c \ - dwarf2/cooked-indexer.c \ - dwarf2/cu.c \ - dwarf2/die.c \ - dwarf2/dwz.c \ - dwarf2/expr.c \ - dwarf2/frame-tailcall.c \ - dwarf2/frame.c \ - dwarf2/index-cache.c \ - dwarf2/index-common.c \ - dwarf2/index-write.c \ - dwarf2/leb.c \ - dwarf2/line-header.c \ - dwarf2/loc.c \ - dwarf2/macro.c \ - dwarf2/parent-map.c \ - dwarf2/read.c \ - dwarf2/read-debug-names.c \ - dwarf2/read-gdb-index.c \ - dwarf2/section.c \ - dwarf2/stringify.c \ - dwarf2/unit-head.c \ extract-store-integer.c \ eval.c \ event-top.c \ @@ -1911,6 +1881,40 @@ TAGFILES_NO_SRCDIR = $(SFILES) $(HFILES_NO_SRCDIR) $(ALLDEPFILES) \ $(CONFIG_SRCS) TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR) +# Files that are used to support certain debuginfo formats +DWARF2_SRCS = \ + dwarf2/abbrev.c \ + dwarf2/abbrev-table-cache.c \ + dwarf2/ada-imported.c \ + dwarf2/aranges.c \ + dwarf2/attribute.c \ + dwarf2/cooked-index.c \ + dwarf2/cooked-index-entry.c \ + dwarf2/cooked-index-shard.c \ + dwarf2/cooked-index-worker.c \ + dwarf2/cooked-indexer.c \ + dwarf2/cu.c \ + dwarf2/die.c \ + dwarf2/dwz.c \ + dwarf2/expr.c \ + dwarf2/frame-tailcall.c \ + dwarf2/frame.c \ + dwarf2/index-cache.c \ + dwarf2/index-common.c \ + dwarf2/index-write.c \ + dwarf2/leb.c \ + dwarf2/line-header.c \ + dwarf2/loc.c \ + dwarf2/macro.c \ + dwarf2/parent-map.c \ + dwarf2/read.c \ + dwarf2/read-debug-names.c \ + dwarf2/read-gdb-index.c \ + dwarf2/section.c \ + dwarf2/stringify.c \ + dwarf2/unit-head.c +DWARF2_OBS = $(patsubst %.c,%.o, $(DWARF2_SRCS)) + COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ mi/mi-common.o \ version.o \ diff --git a/gdb/NEWS b/gdb/NEWS index 5efe45605ab..ec71d899994 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -209,6 +209,10 @@ qXfer:threads:read subsystem to be disabled at configure time, in the form of --disable-gdb-compile. +* A new configure option was added, allowing support for DWARF debug + information to be disabled at configure time. The flag is + --disable-gdb-dwarf-support. + * A new configure option was added, allowing support for mdebug/ecoff debug information to be disabled at configure time. The flag to do that is --disable-gdb-mdebug-support. diff --git a/gdb/README b/gdb/README index ae331a4e816..eca4181c751 100644 --- a/gdb/README +++ b/gdb/README @@ -443,7 +443,11 @@ more obscure GDB `configure' options are not listed here. supported). `--disable-gdb-compile' - Build GDB without support for the 'compile' command. + Build GDB without support for the 'compile' command. DWARF support + is required for this feature. + +`--disable-gdb-dwarf-support' + Build GDB without support for reading DWARF debug information. `--disable-gdb-mdebug-support' Build GDB without support for reading mdebug debug information. diff --git a/gdb/config.in b/gdb/config.in index db55ad69cd2..c0a050c7bc5 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -39,6 +39,9 @@ /* Define to BFD's default target vector. */ #undef DEFAULT_BFD_VEC +/* defined if dwarf format was requested. */ +#undef DWARF_FORMAT_AVAILABLE + /* Handle .ctf type-info sections */ #undef ENABLE_LIBCTF diff --git a/gdb/configure b/gdb/configure index 01db0d0f1e2..d0fb74d7cd4 100755 --- a/gdb/configure +++ b/gdb/configure @@ -933,6 +933,7 @@ with_auto_load_dir with_auto_load_safe_path enable_targets enable_gdb_mdebug_support +enable_gdb_dwarf_support with_amd_dbgapi enable_tui enable_gdbtk @@ -1647,6 +1648,9 @@ Optional Features: --enable-gdb-mdebug-support Enable support for the mdebug debuginfo format (default 'yes') + --enable-gdb-dwarf-support + Enable support for the dwarf debuginfo format + (default 'yes') --enable-tui enable full-screen terminal user interface (TUI) --enable-gdbtk enable gdbtk graphical user interface (GUI) --enable-profiling enable profiling of GDB @@ -11503,7 +11507,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11506 "configure" +#line 11510 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11609,7 +11613,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11612 "configure" +#line 11616 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -24904,6 +24908,31 @@ $as_echo "#define MDEBUG_FORMAT_AVAILABLE 1" >>confdefs.h fi +# Check whether to support dwarf debug information +# Check whether --enable-gdb-dwarf-support was given. +if test "${enable_gdb_dwarf_support+set}" = set; then : + enableval=$enable_gdb_dwarf_support; + case $enableval in + yes | no) + ;; + *) + as_fn_error $? "bad value $enableval for --enable-gdb-dwarf-support" "$LINENO" 5 + ;; + esac + +else + enable_gdb_dwarf_support=yes +fi + + +if test "x${enable_gdb_dwarf_support}" != "xno"; then + +$as_echo "#define DWARF_FORMAT_AVAILABLE 1" >>confdefs.h + + CONFIG_SRCS="$CONFIG_SRCS \$(DWARF2_SRCS)" + CONFIG_OBS="$CONFIG_OBS \$(DWARF2_OBS)" +fi + # See whether 64-bit bfd lib has been enabled. OLD_CPPFLAGS=$CPPFLAGS # Put the old CPPFLAGS last, in case the user's CPPFLAGS point somewhere @@ -28973,21 +29002,37 @@ if test "${enable_gdb_compile+set}" = set; then : esac else - enable_gdb_compile=yes + enable_gdb_compile=default fi -if test "${enable_gdb_compile}" = yes; then - -$as_echo "#define HAVE_COMPILE 1" >>confdefs.h - - CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_GCC_COMPILE_OBS)" -else +case ${enable_gdb_compile}-${enable_gdb_dwarf_support} in + yes-no) + as_fn_error $? "enabling gdb compile requires dwarf support" "$LINENO" 5 + ;; + default-no) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Defaulting compile support to 'no'" >&5 +$as_echo "$as_me: WARNING: Defaulting compile support to 'no'" >&2;} + # Fallthrough. + ;& + no-*) # Even if compile support is not enabled, we need this file to define # the "compile" command. CONFIG_OBS="$CONFIG_OBS compile/compile.o" CONFIG_SRCS="$CONFIG_SRCS compile/compile.c" -fi + ;; + default-yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Defaulting compile support to 'yes'" >&5 +$as_echo "$as_me: WARNING: Defaulting compile support to 'yes'" >&2;} + # Fallthrough. + ;& + yes-*) + +$as_echo "#define HAVE_COMPILE 1" >>confdefs.h + + CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_GCC_COMPILE_OBS)" + ;; +esac # ---------------------------- # # Check for source highlight. # diff --git a/gdb/configure.ac b/gdb/configure.ac index e8ce4212ab9..9e418821604 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -206,6 +206,20 @@ if test "x${enable_gdb_mdebug_support}" != "xno"; then [defined if mdebug format was requested.]) fi +# Check whether to support dwarf debug information +AC_ARG_ENABLE(gdb-dwarf-support, +AS_HELP_STRING([--enable-gdb-dwarf-support], + [Enable support for the dwarf debuginfo format (default 'yes')]), +[GDB_CHECK_YES_NO_VAL([$enableval], [--enable-gdb-dwarf-support])], +[enable_gdb_dwarf_support=yes]) + +if test "x${enable_gdb_dwarf_support}" != "xno"; then + AC_DEFINE(DWARF_FORMAT_AVAILABLE, 1, + [defined if dwarf format was requested.]) + CONFIG_SRCS="$CONFIG_SRCS \$(DWARF2_SRCS)" + CONFIG_OBS="$CONFIG_OBS \$(DWARF2_OBS)" +fi + BFD_64_BIT # Provide defaults for some variables set by the per-host and per-target @@ -1234,17 +1248,31 @@ AC_ARG_ENABLE([gdb-compile], AS_HELP_STRING([--enable-gdb-compile], [enable support for the compile subsystem, default 'yes']), [GDB_CHECK_YES_NO_VAL([$enableval], [--enable-gdb-compile])], - [enable_gdb_compile=yes]) + [enable_gdb_compile=default]) -if test "${enable_gdb_compile}" = yes; then - AC_DEFINE(HAVE_COMPILE, 1, [Define if compiling support to gdb compile.]) - CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_GCC_COMPILE_OBS)" -else +case ${enable_gdb_compile}-${enable_gdb_dwarf_support} in + yes-no) + AC_MSG_ERROR([enabling gdb compile requires dwarf support]) + ;; + default-no) + AC_MSG_WARN([Defaulting compile support to 'no']) + # Fallthrough. + ;& + no-*) # Even if compile support is not enabled, we need this file to define # the "compile" command. CONFIG_OBS="$CONFIG_OBS compile/compile.o" CONFIG_SRCS="$CONFIG_SRCS compile/compile.c" -fi + ;; + default-yes) + AC_MSG_WARN([Defaulting compile support to 'yes']) + # Fallthrough. + ;& + yes-*) + AC_DEFINE(HAVE_COMPILE, 1, [Define if compiling support to gdb compile.]) + CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_GCC_COMPILE_OBS)" + ;; +esac # ---------------------------- # # Check for source highlight. # diff --git a/gdb/dwarf2/frame.h b/gdb/dwarf2/frame.h index f8fd8e8a940..9357cc1c180 100644 --- a/gdb/dwarf2/frame.h +++ b/gdb/dwarf2/frame.h @@ -198,6 +198,15 @@ struct dwarf2_frame_state bool armcc_cfa_offsets_reversed = false; }; +/* If DWARF supoprt was requested, create the real prototype for the + append_unwinders function. Otherwise, create a fake inline function. + + There is no need to emit a warning for some of these, because they aren't + actively reading DWARF when this is called, they're just initializing GDB. + + These should probably be moved to dwarf2/public.h. */ +#if defined(DWARF_FORMAT_AVAILABLE) + /* Set the architecture-specific register state initialization function for GDBARCH to INIT_REG. */ @@ -287,4 +296,56 @@ extern void *dwarf2_frame_get_fn_data (const frame_info_ptr &this_frame, void **this_cache, fn_prev_register cookie); +#else /* DWARF_FORMAT_AVAILABLE */ + +static inline void dwarf2_append_unwinders (struct gdbarch *gdbarch) { } + +static inline void dwarf2_frame_set_init_reg ( + gdbarch *gdbarch, void (*init_reg) (struct gdbarch *,int, + dwarf2_frame_state_reg *, + const frame_info_ptr &)) { } + +static inline const struct frame_base * + dwarf2_frame_base_sniffer (const frame_info_ptr &this_frame) +{ + warning (_("No dwarf support available.")); + return nullptr; +} + +static inline void dwarf2_frame_set_signal_frame_p + (gdbarch *gdbarch, int (*signal_frame_p) (struct gdbarch *, + const frame_info_ptr &)) { } + +static inline void *dwarf2_frame_get_fn_data (const frame_info_ptr &this_frame, + void **this_cache, + fn_prev_register cookie) +{ + return nullptr; +} + +static inline void *dwarf2_frame_allocate_fn_data + (const frame_info_ptr &this_frame, void **this_cache, + fn_prev_register cookie, unsigned long size) +{ + return nullptr; +} + +static inline int dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc, + struct dwarf2_per_cu_data *data, + int *regnum_out, LONGEST *offset_out, + CORE_ADDR *text_offset_out, + const gdb_byte **cfa_start_out, + const gdb_byte **cfa_end_out) +{ + return 0; +} + +static inline void + dwarf2_frame_set_adjust_regnum (struct gdbarch *gdbarch, + int (*adjust_regnum) (struct gdbarch *, + int, int)) +{} + +#endif /* DWARF_FORMAT_AVAILABLE */ + #endif /* GDB_DWARF2_FRAME_H */ diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h index ee88fd4db69..c67232069ae 100644 --- a/gdb/dwarf2/loc.h +++ b/gdb/dwarf2/loc.h @@ -103,28 +103,6 @@ struct property_addr_info const property_addr_info *next; }; -/* Converts a dynamic property into a static one. FRAME is the frame in which - the property is evaluated; if NULL, the selected frame (if any) is used - instead. - - ADDR_STACK is the stack of addresses that might be needed to evaluate the - property. When evaluating a property that is not related to a type, it can - be NULL. - - Returns true if PROP could be converted and the static value is passed - back into VALUE, otherwise returns false. - - Any values in PUSH_VALUES will be pushed before evaluating the location - expression, PUSH_VALUES[0] will be pushed first, then PUSH_VALUES[1], - etc. This means the during evaluation PUSH_VALUES[0] will be at the - bottom of the stack. */ - -bool dwarf2_evaluate_property (const struct dynamic_prop *prop, - const frame_info_ptr &frame, - const property_addr_info *addr_stack, - CORE_ADDR *value, - gdb::array_view push_values = {}); - /* A helper for the compiler interface that compiles a single dynamic property to C code. @@ -311,8 +289,53 @@ extern struct value *indirect_synthetic_pointer Function always returns non-NULL value. It throws NO_ENTRY_VALUE_ERROR if it cannot resolve the parameter for any reason. */ +#if defined(DWARF_FORMAT_AVAILABLE) + +/* Converts a dynamic property into a static one. FRAME is the frame in which + the property is evaluated; if NULL, the selected frame (if any) is used + instead. + + ADDR_STACK is the stack of addresses that might be needed to evaluate the + property. When evaluating a property that is not related to a type, it can + be NULL. + + Returns true if PROP could be converted and the static value is passed + back into VALUE, otherwise returns false. + + Any values in PUSH_VALUES will be pushed before evaluating the location + expression, PUSH_VALUES[0] will be pushed first, then PUSH_VALUES[1], + etc. This means the during evaluation PUSH_VALUES[0] will be at the + bottom of the stack. */ + +bool dwarf2_evaluate_property (const struct dynamic_prop *prop, + const frame_info_ptr &frame, + const property_addr_info *addr_stack, + CORE_ADDR *value, + gdb::array_view push_values = {}); + extern struct value *value_of_dwarf_reg_entry (struct type *type, const frame_info_ptr &frame, enum call_site_parameter_kind kind, union call_site_parameter_u kind_u); + +#else /* DWARF_FORMAT_AVAILABLE */ + +static inline bool +dwarf2_evaluate_property (const struct dynamic_prop *, const frame_info_ptr &, + const property_addr_info *, CORE_ADDR *, + gdb::array_view = {}) +{ + return false; +} + +static inline struct value * +value_of_dwarf_reg_entry (struct type *type, const frame_info_ptr &frame, + enum call_site_parameter_kind kind, + union call_site_parameter_u kind_u) +{ + error (_("No dwarf support available.")); +} + +#endif /* DWARF_FORMAT_AVAILABLE */ + #endif /* GDB_DWARF2_LOC_H */ diff --git a/gdb/dwarf2/public.h b/gdb/dwarf2/public.h index ed504c60437..f9e74882543 100644 --- a/gdb/dwarf2/public.h +++ b/gdb/dwarf2/public.h @@ -30,6 +30,8 @@ enum class dw_index_kind DEBUG_NAMES, }; +#if defined(DWARF_FORMAT_AVAILABLE) + /* Try to locate the sections we need for DWARF 2 debugging information. If these are found, begin reading the DWARF and return true. Otherwise, return false. NAMES points to the dwarf2 @@ -44,4 +46,27 @@ extern bool dwarf2_initialize_objfile extern void dwarf2_build_frame_info (struct objfile *); +/* Append the DWARF-2 frame unwinders to GDBARCH's list. */ + +void dwarf2_append_unwinders (struct gdbarch *gdbarch); + +#else /* DWARF_FORMAT_AVAILABLE */ + +static inline bool +dwarf2_initialize_objfile (struct objfile *, + const struct dwarf2_debug_sections * = nullptr, + bool = false) +{ + warning (_("No dwarf support available.")); + return false; +} + +static inline void +dwarf2_build_frame_info (struct objfile *) +{ + warning (_("No dwarf support available.")); +} + +#endif /* DWARF_FORMAT_AVAILABLE */ + #endif /* GDB_DWARF2_PUBLIC_H */ diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c index 9ed2dee714e..c60a349f153 100644 --- a/gdb/frame-unwind.c +++ b/gdb/frame-unwind.c @@ -49,6 +49,7 @@ static constexpr std::initializer_list standard_unwinders = { &dummy_frame_unwind, +#if defined(DWARF_FORMAT_AVAILABLE) /* The DWARF tailcall sniffer must come before the inline sniffer. Otherwise, we can end up in a situation where a DWARF frame finds tailcall information, but then the inline sniffer claims a frame @@ -57,6 +58,7 @@ static constexpr std::initializer_list activated if the newer frame was created using the DWARF unwinder, and it also found tailcall information. */ &dwarf2_tailcall_frame_unwind, +#endif &inline_frame_unwind, }; diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 624c9b15d3a..9c57f30a1dd 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -6184,12 +6184,22 @@ builtin_type (struct objfile *objfile) return builtin_type (objfile->arch ()); } -/* See gdbtypes.h. */ +/* See dwarf2/call-site.h. */ CORE_ADDR call_site::pc () const { + /* dwarf2_per_objfile is defined in dwarf/read.c, so if that is disabled + at configure time, we won't be able to use this relocate function. + This is dwarf-specific, and would ideally be in call-site.h, but + including dwarf2/read.h in dwarf2/call-site.h will lead to things being + included in the wrong order and many compilation errors will happen. + This is the next best thing. */ +#if defined(DWARF_FORMAT_AVAILABLE) return per_objfile->relocate (m_unrelocated_pc); +#else + gdb_assert_not_reached ("unexpected call_site object found"); +#endif } void _initialize_gdbtypes ();