> > In the case where IN_GCC is defined, where are the types > > dwarf_attribute, dwarf_form, and dwarf_tag defined? > > In GCC's own dwarf2.h as enum tags; dwarf.h uses anonymous enums.
Ah, I still should have typedef'ed those types to enum tags when IN_GCC. I've verified the following patch bootstraps and passes testing. libbacktrace/Changelog: 2013-05-14 Alexander Monakov <amona...@ispras.ru> * btest.c: [!IN_GCC] (IS_DIR_SEPARATOR): Define. * configure.ac: (standalone): New configuration flag. (EXTRA_FLAGS): Add -DIN_GCC. (HAVE_DWARF2_FISSION, HAVE_DWARF2_DWZ_MULTIFILE): New tests. Use ... * dwarf.c: (read_attribute): ... here. [IN_GCC] (dwarf_attribute, dwarf_form, dwarf_tag): Typedef to corresponding enums from dwarf2.h. Update all uses. [!IN_GCC] Use system dwarf.h. [!IN_GCC] (dwarf_attribute, dwarf_form, dwarf_tag): Typedef to int. [!IN_GCC] (IS_ABSOLUTE_PATH): Define. (read_line_program): Avoid use of DW_LNS_extended_op. * configure: Regenerate. * config.h.in: Regenerate. * Makefile.in: Regenerate. diff --git a/libbacktrace/btest.c b/libbacktrace/btest.c index cc647b8..1516099 100644 --- a/libbacktrace/btest.c +++ b/libbacktrace/btest.c @@ -38,7 +38,11 @@ POSSIBILITY OF SUCH DAMAGE. */ #include <stdlib.h> #include <string.h> +#ifdef IN_GCC #include "filenames.h" +#else +#define IS_DIR_SEPARATOR(c) ((c) == '/') +#endif #include "backtrace.h" #include "backtrace-supported.h" diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac index 28b2a1c..ae23da4 100644 --- a/libbacktrace/configure.ac +++ b/libbacktrace/configure.ac @@ -58,6 +58,9 @@ AM_MAINTAINER_MODE AC_ARG_WITH(target-subdir, [ --with-target-subdir=SUBDIR Configuring in a subdirectory for target]) +AC_ARG_ENABLE(standalone, +[ --enable-standalone Do not use internal GCC headers]) + # We must force CC to /not/ be precious variables; otherwise # the wrong, non-multilib-adjusted value will be used in multilibs. # As a side effect, we have to subst CFLAGS ourselves. @@ -72,7 +75,7 @@ AC_PROG_RANLIB AC_PROG_AWK case "$AWK" in -"") AC_MSG_ERROR([can't build without awk]) ;; +"") AC_MSG_ERROR([cannot build without awk]) ;; esac LT_INIT([disable-shared]) @@ -125,6 +128,10 @@ else EXTRA_FLAGS="$EXTRA_FLAGS -frandom-seed=\$@" fi fi + +if test "${enable_standalone}" != "yes"; then + EXTRA_FLAGS="$EXTRA_FLAGS -DIN_GCC" +fi AC_SUBST(EXTRA_FLAGS) ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wstrict-prototypes \ @@ -314,6 +321,40 @@ if test "$have_getexecname" = "yes"; then AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.]) fi +# Check for DWARF2 extensions +if test "${enable_standalone}" != "yes"; then + have_dwarf2_fission=yes + have_dwarf2_dwz_multifile=yes +else + AC_CHECK_HEADER([dwarf.h], + [ + AC_MSG_CHECKING([for DW_FORM_GNU_addr_index]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include <dwarf.h>], + [int i = DW_FORM_GNU_addr_index;])], + [have_dwarf2_fission=yes], + [have_dwarf2_fission=no]) + AC_MSG_RESULT([$have_dwarf2_fission]) + AC_MSG_CHECKING([for DW_FORM_GNU_ref_alt]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include <dwarf.h>], + [int i = DW_FORM_GNU_ref_alt;])], + [have_dwarf2_dwz_multifile=yes], + [have_dwarf2_dwz_multifile=no]) + AC_MSG_RESULT([$have_dwarf2_dwz_multifile])], + [AC_MSG_ERROR([dwarf.h required when building standalone])]) +fi +if test "$have_dwarf2_fission" = "yes"; then + AC_DEFINE(HAVE_DWARF2_FISSION, 1, + [Define if DWARF2 Fission enumeration values are defined.]) +fi +if test "$have_dwarf2_dwz_multifile" = "yes"; then + AC_DEFINE(HAVE_DWARF2_DWZ_MULTFILE, 1, + [Define if DWARF2 DWZ multifile enumeration values are defined.]) +fi + AC_CACHE_CHECK([whether tests can run], [libbacktrace_cv_sys_native], [AC_RUN_IFELSE([AC_LANG_PROGRAM([], [return 0;])], diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c index 501afe5..6170ca0 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -37,9 +37,22 @@ POSSIBILITY OF SUCH DAMAGE. */ #include <string.h> #include <sys/types.h> +#ifdef IN_GCC #include "dwarf2.h" #include "filenames.h" +typedef enum dwarf_attribute dwarf_attribute; +typedef enum dwarf_form dwarf_form; +typedef enum dwarf_tag dwarf_tag; +#else +#include <dwarf.h> +#define IS_ABSOLUTE_PATH(f) ((f)[0] == '/') + +typedef int dwarf_attribute; +typedef int dwarf_form; +typedef int dwarf_tag; +#endif + #include "backtrace.h" #include "internal.h" @@ -89,9 +102,9 @@ struct dwarf_buf struct attr { /* The attribute name. */ - enum dwarf_attribute name; + dwarf_attribute name; /* The attribute form. */ - enum dwarf_form form; + dwarf_form form; }; /* A single DWARF abbreviation. */ @@ -101,7 +114,7 @@ struct abbrev /* The abbrev code--the number used to refer to the abbrev. */ uint64_t code; /* The entry tag. */ - enum dwarf_tag tag; + dwarf_tag tag; /* Non-zero if this abbrev has child entries. */ int has_children; /* The number of attributes. */ @@ -653,7 +666,7 @@ free_abbrevs (struct backtrace_state *state, struct abbrevs *abbrevs, forms, because we don't care about them. */ static int -read_attribute (enum dwarf_form form, struct dwarf_buf *buf, +read_attribute (dwarf_form form, struct dwarf_buf *buf, int is_dwarf64, int version, int addrsize, const unsigned char *dwarf_str, size_t dwarf_str_size, struct attr_val *val) @@ -760,7 +773,7 @@ read_attribute (enum dwarf_form form, struct dwarf_buf *buf, uint64_t form; form = read_uleb128 (buf); - return read_attribute ((enum dwarf_form) form, buf, is_dwarf64, + return read_attribute ((dwarf_form) form, buf, is_dwarf64, version, addrsize, dwarf_str, dwarf_str_size, val); } @@ -779,6 +792,7 @@ read_attribute (enum dwarf_form form, struct dwarf_buf *buf, val->encoding = ATTR_VAL_REF_TYPE; val->u.uint = read_uint64 (buf); return 1; +#ifdef HAVE_DWARF2_FISSION case DW_FORM_GNU_addr_index: val->encoding = ATTR_VAL_REF_SECTION; val->u.uint = read_uleb128 (buf); @@ -787,6 +801,8 @@ read_attribute (enum dwarf_form form, struct dwarf_buf *buf, val->encoding = ATTR_VAL_REF_SECTION; val->u.uint = read_uleb128 (buf); return 1; +#endif +#ifdef HAVE_DWARF2_DWZ_MULTFILE case DW_FORM_GNU_ref_alt: val->encoding = ATTR_VAL_REF_SECTION; val->u.uint = read_offset (buf, is_dwarf64); @@ -795,6 +811,7 @@ read_attribute (enum dwarf_form form, struct dwarf_buf *buf, val->encoding = ATTR_VAL_REF_SECTION; val->u.uint = read_offset (buf, is_dwarf64); return 1; +#endif default: dwarf_buf_error (buf, "unrecognized DWARF form"); return 0; @@ -1087,7 +1104,7 @@ read_abbrevs (struct backtrace_state *state, uint64_t abbrev_offset, break; a.code = code; - a.tag = (enum dwarf_tag) read_uleb128 (&abbrev_buf); + a.tag = (dwarf_tag) read_uleb128 (&abbrev_buf); a.has_children = read_byte (&abbrev_buf); count_buf = abbrev_buf; @@ -1121,8 +1138,8 @@ read_abbrevs (struct backtrace_state *state, uint64_t abbrev_offset, form = read_uleb128 (&abbrev_buf); if (name == 0) break; - attrs[num_attrs].name = (enum dwarf_attribute) name; - attrs[num_attrs].form = (enum dwarf_form) form; + attrs[num_attrs].name = (dwarf_attribute) name; + attrs[num_attrs].form = (dwarf_form) form; ++num_attrs; } } @@ -1746,10 +1763,11 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata, add_line (state, ddata, address, filename, lineno, line_buf->error_callback, line_buf->data, vec); } - else if (op == DW_LNS_extended_op) + else if (!op) { uint64_t len; + /* Extended opcode. */ len = read_uleb128 (line_buf); op = read_byte (line_buf); switch (op) diff --git a/libbacktrace/configure b/libbacktrace/configure index 46ad9ee..8724e6d 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -723,6 +723,7 @@ ac_user_opts=' enable_option_checking enable_maintainer_mode with_target_subdir +enable_standalone enable_shared enable_static with_pic @@ -1363,6 +1364,7 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer + --enable-standalone Do not use internal GCC headers --enable-shared[=PKGS] build shared libraries [default=no] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] @@ -4326,6 +4328,12 @@ if test "${with_target_subdir+set}" = set; then : fi +# Check whether --enable-standalone was given. +if test "${enable_standalone+set}" = set; then : + enableval=$enable_standalone; +fi + + # We must force CC to /not/ be precious variables; otherwise # the wrong, non-multilib-adjusted value will be used in multilibs. # As a side effect, we have to subst CFLAGS ourselves. @@ -5011,7 +5019,7 @@ fi done case "$AWK" in -"") as_fn_error "can't build without awk" "$LINENO" 5 ;; +"") as_fn_error "cannot build without awk" "$LINENO" 5 ;; esac case `pwd` in @@ -11081,7 +11089,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11084 "configure" +#line 11092 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11187,7 +11195,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11190 "configure" +#line 11198 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11557,6 +11565,10 @@ $as_echo "$libbacktrace_cv_c_random_seed_string" >&6; } fi fi +if test "${enable_standalone}" != "yes"; then + EXTRA_FLAGS="$EXTRA_FLAGS -DIN_GCC" +fi + WARN_FLAGS= save_CFLAGS="$CFLAGS" @@ -12371,6 +12383,73 @@ $as_echo "#define HAVE_GETEXECNAME 1" >>confdefs.h fi +# Check for DWARF2 extensions +if test "${enable_standalone}" != "yes"; then + have_dwarf2_fission=yes + have_dwarf2_dwz_multifile=yes +else + ac_fn_c_check_header_mongrel "$LINENO" "dwarf.h" "ac_cv_header_dwarf_h" "$ac_includes_default" +if test "x$ac_cv_header_dwarf_h" = x""yes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DW_FORM_GNU_addr_index" >&5 +$as_echo_n "checking for DW_FORM_GNU_addr_index... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <dwarf.h> +int +main () +{ +int i = DW_FORM_GNU_addr_index; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + have_dwarf2_fission=yes +else + have_dwarf2_fission=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_dwarf2_fission" >&5 +$as_echo "$have_dwarf2_fission" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DW_FORM_GNU_ref_alt" >&5 +$as_echo_n "checking for DW_FORM_GNU_ref_alt... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <dwarf.h> +int +main () +{ +int i = DW_FORM_GNU_ref_alt; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + have_dwarf2_dwz_multifile=yes +else + have_dwarf2_dwz_multifile=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_dwarf2_dwz_multifile" >&5 +$as_echo "$have_dwarf2_dwz_multifile" >&6; } +else + as_fn_error "dwarf.h required when building standalone" "$LINENO" 5 +fi + + +fi +if test "$have_dwarf2_fission" = "yes"; then + +$as_echo "#define HAVE_DWARF2_FISSION 1" >>confdefs.h + +fi +if test "$have_dwarf2_dwz_multifile" = "yes"; then + +$as_echo "#define HAVE_DWARF2_DWZ_MULTFILE 1" >>confdefs.h + +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether tests can run" >&5 $as_echo_n "checking whether tests can run... " >&6; } if test "${libbacktrace_cv_sys_native+set}" = set; then : diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in index 48ff63f..46a3a65 100644 --- a/libbacktrace/config.h.in +++ b/libbacktrace/config.h.in @@ -13,6 +13,12 @@ /* Define if dl_iterate_phdr is available. */ #undef HAVE_DL_ITERATE_PHDR +/* Define if DWARF2 DWZ multifile enumeration values are defined. */ +#undef HAVE_DWARF2_DWZ_MULTFILE + +/* Define if DWARF2 Fission enumeration values are defined. */ +#undef HAVE_DWARF2_FISSION + /* Define to 1 if you have the fcntl function */ #undef HAVE_FCNTL diff --git a/libbacktrace/Makefile.in b/libbacktrace/Makefile.in index 971406b..eff3ba9 100644 --- a/libbacktrace/Makefile.in +++ b/libbacktrace/Makefile.in @@ -16,7 +16,7 @@ @SET_MAKE@ # Makefile.am -- Backtrace Makefile. -# Copyright (C) 2012 Free Software Foundation, Inc. +# Copyright (C) 2012-2013 Free Software Foundation, Inc. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are