From patchwork Wed May 8 15:56:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Monakov X-Patchwork-Id: 242603 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id F3C592C00D5 for ; Thu, 9 May 2013 02:00:04 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=r7bAp+kSh2K6rKMn2MrfHKWw2RUfifBagNBIXxCSTt24M8w/Sx /vqc2SVj4gi/KyAbjdks340bOn+ZuFMxSmUAGsjw2iVG29QkOOIPtFVS86HkgrD7 SiQ0Xq3n+0g84E+47y9vRQsxUdoDwey39/+dfM1qS7Sx7OUTpZehrAVqg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=R8spNxnHkcjZBEmAwlosi72VUYQ=; b=HX+DAP1mWwtB4Ujkwuyc p/JlmGJbJwWn3N/9608nG5tvea9wcJa4+WZ7ZNyDnmnyM+gNRyzyfIpD0MmL0/bD e+pTYedwhuC226b/yp+r5Z4KfMx5vF9g3E5lN4GemgWeHANv3LTP9Nvo54DzkfHW 1brO63UYq5pMVNsh4VUPcLI= Received: (qmail 16938 invoked by alias); 8 May 2013 15:59:57 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 16919 invoked by uid 89); 8 May 2013 15:59:56 -0000 X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, TW_FC autolearn=ham version=3.3.1 Received: from smtp.ispras.ru (HELO smtp.ispras.ru) (83.149.199.79) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 08 May 2013 15:59:54 +0000 Received: from [10.10.3.121] (unknown [83.149.199.91]) by smtp.ispras.ru (Postfix) with ESMTP id 708A4224A5; Wed, 8 May 2013 19:59:51 +0400 (MSK) Date: Wed, 8 May 2013 19:56:18 +0400 (MSK) From: Alexander Monakov To: gcc-patches@gcc.gnu.org cc: Ian Lance Taylor Subject: [PATCH,RFC] Make libbacktrace more standalone Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Hello, I'd like to make libbacktrace easier to import for use in other software. Right now it's mostly standalone, but depends on rest of GCC in the following: 1. Build system. 2. Trivially depends on "filenames.h". 3. Depends on "dwarf2.{def,h}" to obtain DW_* enumeration values. My autotools-foo is not strong enough to elegantly resolve build system dependencies (and for my intended use in APITrace I will need to write a CMake-based build recipe anyhow). To remove dependency on GCC dwarf2.h, I'm proposing to enable building with system dwarf.h header. However, in that header the enums are anonymous, and some enum values may be missing. My preference is that references to named enums are retained, so I'm typedef'ing those to 'int' if unavailable. To deal with potentially missing enum values, I'm adding configure checks and wrapping uses in HAVE_foo. I'm also removing one use of DW_LNS_extended_op: the standard does not seem to define that name, but instead says that value 0 is treated specially. The following patch is the best compromise I have found between adding ugly fixups and making libbacktrace buildable standalone (with the caveat that either a different build system is used, or autotools files are hacked to remove GCC dependencies). Comments? libbacktrace/Changelog: 2013-05-08 Alexander Monakov * btest.c: [!IN_GCC] (IS_DIR_SEPARATOR): Define. * configure.ac: (HAVE_DWARF2_FISSION, HAVE_DWARF2_DWZ_MULTIFILE): New tests. Use ... * dwarf.c: (read_attribute): ... here. [!IN_GCC] Use system dwarf.h. [!IN_GCC] (dwarf_attribute, dwarf_form, dwarf_tag): Typedef to int. Update all uses. [!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 #include +#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..2728d4d 100644 --- a/libbacktrace/configure.ac +++ b/libbacktrace/configure.ac @@ -72,7 +72,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]) @@ -314,6 +314,40 @@ if test "$have_getexecname" = "yes"; then AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.]) fi +# Test if DWARF2 extensions enumeration values are declared +if test -n "${with_target_subdir}"; 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 ], + [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 ], + [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 for standalone build])]) +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_MULTIFILE, 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..49a57a3 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -37,11 +37,20 @@ POSSIBILITY OF SUCH DAMAGE. */ #include #include +#include "backtrace.h" +#include "internal.h" + +#ifdef IN_GCC #include "dwarf2.h" #include "filenames.h" +#else +#include +typedef int dwarf_attribute; +typedef int dwarf_form; +typedef int dwarf_tag; -#include "backtrace.h" -#include "internal.h" +#define IS_ABSOLUTE_PATH(f) ((f)[0] == '/') +#endif #if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN @@ -89,9 +98,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 +110,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 +662,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 +769,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 +788,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 +797,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_MULTIFILE case DW_FORM_GNU_ref_alt: val->encoding = ATTR_VAL_REF_SECTION; val->u.uint = read_offset (buf, is_dwarf64); @@ -795,6 +807,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 +1100,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 +1134,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 +1759,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..26ef020 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -5011,7 +5011,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 @@ -12371,6 +12371,73 @@ $as_echo "#define HAVE_GETEXECNAME 1" >>confdefs.h fi +# Check for DWARF2 extensions +if test -n "${with_target_subdir}"; 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 +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 +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_MULTIFILE 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_MULTIFILE + +/* 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