From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21773 invoked by alias); 26 Dec 2017 19:38:55 -0000 Mailing-List: contact elfutils-devel-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: elfutils-devel-owner@sourceware.org Received: (qmail 21748 invoked by uid 89); 26 Dec 2017 19:38:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.2 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.4 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 spammy=4520, 4336 X-Spam-Status: No, score=-23.4 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: gnu.wildebeest.org Received: from wildebeest.demon.nl (HELO gnu.wildebeest.org) (212.238.236.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 26 Dec 2017 19:38:52 +0000 Received: from stream.wildebeest.org (a80-101-194-232.adsl.xs4all.nl [80.101.194.232]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id B06CF302BAA6; Tue, 26 Dec 2017 20:38:49 +0100 (CET) Received: by stream.wildebeest.org (Postfix, from userid 1000) id 77994109054; Tue, 26 Dec 2017 20:38:49 +0100 (CET) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: Mark Wielaard Subject: [PATCH 1/2] libdw: New get_uleb128_unchecked to use with already checked Dwarf_Abbrev. Date: Tue, 26 Dec 2017 19:38:00 -0000 Message-Id: <20171226193840.27387-2-mark@klomp.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20171226193840.27387-1-mark@klomp.org> References: <20171226193840.27387-1-mark@klomp.org> X-Spam-Flag: NO X-IsSubscribed: yes X-SW-Source: 2017-q4/txt/msg00125.txt.bz2 When creating a Dwarf_Abbrev in dwarf_getabbrev (__libdw_getabbrev) we already check it is fully readable from the .debug_abbrev section. So whenever we reread it later using the attrp pointer we don't have to check it again. Introduce get_uleb128_unchecked to use for ulebs we know are safe to read directly. Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 10 ++++++++++ libdw/dwarf_child.c | 19 +++++-------------- libdw/dwarf_getabbrevattr.c | 10 +++++----- libdw/dwarf_getattrs.c | 20 +++++--------------- libdw/dwarf_hasattr.c | 22 +++++----------------- libdw/memory-access.h | 18 ++++++++++++++++++ 6 files changed, 48 insertions(+), 51 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index eb1cb709..3e3b7169 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,13 @@ +2017-12-26 Mark Wielaard + + * memory-access.h (__libdw_get_uleb128_unchecked): New function. + (get_uleb128_unchecked): New define. + * dwarf_child.c (__libdw_find_attr): Use get_uleb128_unchecked to + read attr name and form. + * dwarf_getabbrevattr.c (dwarf_getabbrevattr): Likewise. + * dwarf_getattrs.c (dwarf_getattrs): Likewise. + * dwarf_hasattr.c (dwarf_hasattr): Likewise. + 2017-05-09 Ulf Hermann Mark Wielaard diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c index cc95fb3f..248338eb 100644 --- a/libdw/dwarf_child.c +++ b/libdw/dwarf_child.c @@ -1,5 +1,5 @@ /* Return child of current DIE. - Copyright (C) 2003-2011, 2014 Red Hat, Inc. + Copyright (C) 2003-2011, 2014, 2017 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2003. @@ -43,36 +43,27 @@ internal_function __libdw_find_attr (Dwarf_Die *die, unsigned int search_name, unsigned int *codep, unsigned int *formp) { - Dwarf *dbg = die->cu->dbg; const unsigned char *readp; /* Find the abbreviation entry. */ Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &readp); if (unlikely (abbrevp == DWARF_END_ABBREV)) { - invalid_dwarf: __libdw_seterrno (DWARF_E_INVALID_DWARF); return NULL; } - /* Search the name attribute. */ - unsigned char *const endp - = ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf - + dbg->sectiondata[IDX_debug_abbrev]->d_size); - + /* Search the name attribute. Attribute has been checked when + Dwarf_Abbrev was created, we can read unchecked. */ const unsigned char *attrp = abbrevp->attrp; while (1) { /* Get attribute name and form. */ - if (unlikely (attrp >= endp)) - goto invalid_dwarf; unsigned int attr_name; - get_uleb128 (attr_name, attrp, endp); + get_uleb128_unchecked (attr_name, attrp); - if (unlikely (attrp >= endp)) - goto invalid_dwarf; unsigned int attr_form; - get_uleb128 (attr_form, attrp, endp); + get_uleb128_unchecked (attr_form, attrp); /* We can stop if we found the attribute with value zero. */ if (attr_name == 0 && attr_form == 0) diff --git a/libdw/dwarf_getabbrevattr.c b/libdw/dwarf_getabbrevattr.c index 3b4da99c..57fe3637 100644 --- a/libdw/dwarf_getabbrevattr.c +++ b/libdw/dwarf_getabbrevattr.c @@ -1,5 +1,5 @@ /* Get specific attribute of abbreviation. - Copyright (C) 2003, 2004, 2005, 2014 Red Hat, Inc. + Copyright (C) 2003, 2004, 2005, 2014, 2017 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2003. @@ -53,10 +53,10 @@ dwarf_getabbrevattr (Dwarf_Abbrev *abbrev, size_t idx, unsigned int *namep, { start_attrp = attrp; - /* Attribute code and form are encoded as ULEB128 values.i - XXX We have no way to bounds check. */ - get_uleb128 (name, attrp, attrp + len_leb128 (name)); - get_uleb128 (form, attrp, attrp + len_leb128 (form)); + /* Attribute code and form are encoded as ULEB128 values. + Already checked when Dwarf_Abbrev was created, read unchecked. */ + get_uleb128_unchecked (name, attrp); + get_uleb128_unchecked (form, attrp); /* If both values are zero the index is out of range. */ if (name == 0 && form == 0) diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c index 0da8b5ba..7f55fafc 100644 --- a/libdw/dwarf_getattrs.c +++ b/libdw/dwarf_getattrs.c @@ -1,5 +1,5 @@ /* Get attributes of the DIE. - Copyright (C) 2004, 2005, 2008, 2009, 2014 Red Hat, Inc. + Copyright (C) 2004, 2005, 2008, 2009, 2014, 2017 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2004. @@ -51,7 +51,6 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), if (unlikely (abbrevp == DWARF_END_ABBREV)) { - invalid_dwarf: __libdw_seterrno (DWARF_E_INVALID_DWARF); return -1l; } @@ -61,24 +60,15 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), const unsigned char *const offset_attrp = abbrevp->attrp + offset; /* Go over the list of attributes. */ - Dwarf *dbg = die->cu->dbg; - const unsigned char *endp; - endp = ((const unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf - + dbg->sectiondata[IDX_debug_abbrev]->d_size); while (1) { - /* Are we still in bounds? */ - if (unlikely (attrp >= endp)) - goto invalid_dwarf; - - /* Get attribute name and form. */ + /* Get attribute name and form. Dwarf_Abbrev was checked when + created, so we can read unchecked. */ Dwarf_Attribute attr; const unsigned char *remembered_attrp = attrp; - get_uleb128 (attr.code, attrp, endp); - if (unlikely (attrp >= endp)) - goto invalid_dwarf; - get_uleb128 (attr.form, attrp, endp); + get_uleb128_unchecked (attr.code, attrp); + get_uleb128_unchecked (attr.form, attrp); /* We can stop if we found the attribute with value zero. */ if (attr.code == 0 && attr.form == 0) diff --git a/libdw/dwarf_hasattr.c b/libdw/dwarf_hasattr.c index 2bb8dc82..90b333e6 100644 --- a/libdw/dwarf_hasattr.c +++ b/libdw/dwarf_hasattr.c @@ -1,5 +1,5 @@ /* Check whether given DIE has specific attribute. - Copyright (C) 2003, 2005, 2014 Red Hat, Inc. + Copyright (C) 2003, 2005, 2014, 2017 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 2003. @@ -45,32 +45,20 @@ dwarf_hasattr (Dwarf_Die *die, unsigned int search_name) Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL); if (unlikely (abbrevp == DWARF_END_ABBREV)) { - invalid_dwarf: __libdw_seterrno (DWARF_E_INVALID_DWARF); return 0; } - Dwarf *dbg = die->cu->dbg; - - /* Search the name attribute. */ - unsigned char *const endp - = ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf - + dbg->sectiondata[IDX_debug_abbrev]->d_size); - + /* Search the name attribute. Dwarf_Abbrev was checked when created, + so we can read unchecked here. */ const unsigned char *attrp = abbrevp->attrp; while (1) { - /* Are we still in bounds? This test needs to be refined. */ - if (unlikely (attrp >= endp)) - goto invalid_dwarf; - /* Get attribute name and form. */ unsigned int attr_name; - get_uleb128 (attr_name, attrp, endp); + get_uleb128_unchecked (attr_name, attrp); unsigned int attr_form; - if (unlikely (attrp >= endp)) - goto invalid_dwarf; - get_uleb128 (attr_form, attrp, endp); + get_uleb128_unchecked (attr_form, attrp); /* We can stop if we found the attribute with value zero. */ if (attr_name == 0 || attr_form == 0) diff --git a/libdw/memory-access.h b/libdw/memory-access.h index afb651fc..ed68bdb9 100644 --- a/libdw/memory-access.h +++ b/libdw/memory-access.h @@ -87,8 +87,26 @@ __libdw_get_uleb128 (const unsigned char **addrp, const unsigned char *end) return UINT64_MAX; } +static inline uint64_t +__libdw_get_uleb128_unchecked (const unsigned char **addrp) +{ + uint64_t acc = 0; + + /* Unroll the first step to help the compiler optimize + for the common single-byte case. */ + get_uleb128_step (acc, *addrp, 0); + + const size_t max = len_leb128 (uint64_t); + for (size_t i = 1; i < max; ++i) + get_uleb128_step (acc, *addrp, i); + /* Other implementations set VALUE to UINT_MAX in this + case. So we better do this as well. */ + return UINT64_MAX; +} + /* Note, addr needs to me smaller than end. */ #define get_uleb128(var, addr, end) ((var) = __libdw_get_uleb128 (&(addr), end)) +#define get_uleb128_unchecked(var, addr) ((var) = __libdw_get_uleb128_unchecked (&(addr))) /* The signed case is similar, but we sign-extend the result. */ -- 2.14.3