> > 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

Reply via email to