From: Josh Stone Date: Tue, 10 Dec 2013 22:19:09 +0000 (-0800) Subject: libdw: Simplify and inline get_uleb128 and get_sleb128 X-Git-Tag: elfutils-0.158~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e2787c2674bdb152e275edb3ed4d9939c8f62d7;p=thirdparty%2Felfutils.git libdw: Simplify and inline get_uleb128 and get_sleb128 This removes the IS_LIBDW distinction so LEB128 operations are now always inlined, and the implementations are simplified, more direct. Signed-off-by: Josh Stone --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index a2e4b142a..aa7b9ca48 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,18 @@ +2013-12-10 Josh Stone + + * memory-access.h (get_uleb128_rest_return): Removed. + (get_sleb128_rest_return): Removed. + (get_uleb128_step): Make this a self-contained block. + (get_sleb128_step): Ditto, and use a bitfield to extend signs. + (get_uleb128): Make this wholly implemented by __libdw_get_uleb128. + (get_sleb128): Make this wholly implemented by __libdw_get_sleb128. + (__libdw_get_uleb128): Simplify and inline for all callers. + (__libdw_get_sleb128): Ditto. + * dwarf_getlocation.c (store_implicit_value): Void the unused uleb128. + * memory-access.c: Delete file. + * Makefile.am (libdw_a_SOURCES): Remove it. + (DEFS): Remove the now unused -DIS_LIBDW. + 2013-12-09 Josh Stone * libdw_form.c (__libdw_form_val_compute_len): Renamed function from diff --git a/libdw/Makefile.am b/libdw/Makefile.am index a22166a99..cd9e31435 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -28,7 +28,6 @@ ## not, see . ## include $(top_srcdir)/config/eu.am -DEFS += -DIS_LIBDW if BUILD_STATIC AM_CFLAGS += -fpic endif @@ -79,7 +78,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ dwarf_getfuncs.c \ dwarf_decl_file.c dwarf_decl_line.c dwarf_decl_column.c \ dwarf_func_inline.c dwarf_getsrc_file.c \ - libdw_findcu.c libdw_form.c libdw_alloc.c memory-access.c \ + libdw_findcu.c libdw_form.c libdw_alloc.c \ libdw_visit_scopes.c \ dwarf_entry_breakpoints.c \ dwarf_next_cfi.c \ diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index 4124ae36b..8dffb83f4 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -100,8 +100,7 @@ store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op) struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s, sizeof (struct loc_block_s), 1); const unsigned char *data = (const unsigned char *) (uintptr_t) op->number2; - Dwarf_Word blength; // Ignored, equal to op->number. - get_uleb128 (blength, data); + (void) __libdw_get_uleb128 (&data); // Ignored, equal to op->number. block->addr = op; block->data = (unsigned char *) data; block->length = op->number; diff --git a/libdw/memory-access.c b/libdw/memory-access.c deleted file mode 100644 index 7666fb60a..000000000 --- a/libdw/memory-access.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Out of line functions for memory-access.h macros. - Copyright (C) 2005, 2006 Red Hat, Inc. - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify - it under the terms of either - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "libdwP.h" -#include "memory-access.h" - -uint64_t -internal_function -__libdw_get_uleb128 (uint64_t acc, unsigned int i, const unsigned char **addrp) -{ - unsigned char __b; - get_uleb128_rest_return (acc, i, addrp); -} - -int64_t -internal_function -__libdw_get_sleb128 (int64_t acc, unsigned int i, const unsigned char **addrp) -{ - unsigned char __b; - int64_t _v = acc; - get_sleb128_rest_return (acc, i, addrp); -} diff --git a/libdw/memory-access.h b/libdw/memory-access.h index 16471990d..d0ee63c53 100644 --- a/libdw/memory-access.h +++ b/libdw/memory-access.h @@ -37,90 +37,59 @@ /* Number decoding macros. See 7.6 Variable Length Data. */ -#define get_uleb128_step(var, addr, nth, break) \ - __b = *(addr)++; \ - var |= (uintmax_t) (__b & 0x7f) << (nth * 7); \ - if (likely ((__b & 0x80) == 0)) \ - break - -#define get_uleb128(var, addr) \ - do { \ - unsigned char __b; \ - var = 0; \ - get_uleb128_step (var, addr, 0, break); \ - var = __libdw_get_uleb128 (var, 1, &(addr)); \ - } while (0) +#define len_leb128(var) ((8 * sizeof (var) + 6) / 7) -#define get_uleb128_rest_return(var, i, addrp) \ +#define get_uleb128_step(var, addr, nth) \ do { \ - for (; i < 10; ++i) \ - { \ - get_uleb128_step (var, *addrp, i, return var); \ - } \ - /* Other implementations set VALUE to UINT_MAX in this \ - case. So we better do this as well. */ \ - return UINT64_MAX; \ + unsigned char __b = *(addr)++; \ + (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7); \ + if (likely ((__b & 0x80) == 0)) \ + return (var); \ } while (0) -/* The signed case is similar, but we sign-extend the result. */ +static inline uint64_t +__libdw_get_uleb128 (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); + for (unsigned int i = 1; i < len_leb128 (acc); ++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; +} -#define get_sleb128_step(var, addr, nth, break) \ - __b = *(addr)++; \ - _v |= (uint64_t) (__b & 0x7f) << (nth * 7); \ - if (likely ((__b & 0x80) == 0)) \ - { \ - var = (_v << (64 - (nth * 7) - 7)) >> (64 - (nth * 7) - 7); \ - break; \ - } \ - else do {} while (0) +#define get_uleb128(var, addr) ((var) = __libdw_get_uleb128 (&(addr))) -#define get_sleb128(var, addr) \ - do { \ - unsigned char __b; \ - int64_t _v = 0; \ - get_sleb128_step (var, addr, 0, break); \ - var = __libdw_get_sleb128 (_v, 1, &(addr)); \ - } while (0) +/* The signed case is similar, but we sign-extend the result. */ -#define get_sleb128_rest_return(var, i, addrp) \ +#define get_sleb128_step(var, addr, nth) \ do { \ - for (; i < 9; ++i) \ + unsigned char __b = *(addr)++; \ + if (likely ((__b & 0x80) == 0)) \ { \ - get_sleb128_step (var, *addrp, i, return var); \ + struct { signed int i:7; } __s = { .i = __b }; \ + (var) |= (typeof (var)) __s.i << ((nth) * 7); \ + return (var); \ } \ - __b = *(*addrp)++; \ - if (likely ((__b & 0x80) == 0)) \ - return var | ((uint64_t) __b << 63); \ - else \ - /* Other implementations set VALUE to INT_MAX in this \ - case. So we better do this as well. */ \ - return INT64_MAX; \ + (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7); \ } while (0) -#ifdef IS_LIBDW -extern uint64_t __libdw_get_uleb128 (uint64_t acc, unsigned int i, - const unsigned char **addrp) - internal_function attribute_hidden; -extern int64_t __libdw_get_sleb128 (int64_t acc, unsigned int i, - const unsigned char **addrp) - internal_function attribute_hidden; -#else -static inline uint64_t -__attribute__ ((unused)) -__libdw_get_uleb128 (uint64_t acc, unsigned int i, const unsigned char **addrp) -{ - unsigned char __b; - get_uleb128_rest_return (acc, i, addrp); -} static inline int64_t -__attribute__ ((unused)) -__libdw_get_sleb128 (int64_t acc, unsigned int i, const unsigned char **addrp) +__libdw_get_sleb128 (const unsigned char **addrp) { - unsigned char __b; - int64_t _v = acc; - get_sleb128_rest_return (acc, i, addrp); + int64_t acc = 0; + /* Unrolling 0 like uleb128 didn't prove to benefit optimization. */ + for (unsigned int i = 0; i < len_leb128 (acc); ++i) + get_sleb128_step (acc, *addrp, i); + /* Other implementations set VALUE to INT_MAX in this + case. So we better do this as well. */ + return INT64_MAX; } -#endif + +#define get_sleb128(var, addr) ((var) = __libdw_get_sleb128 (&(addr))) /* We use simple memory access functions in case the hardware allows it.