[PATCH 2/3] Simplify and inline get_uleb128 and get_sleb128
Josh Stone
jistone at redhat.com
Wed Dec 11 01:35:41 UTC 2013
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 <jistone at redhat.com>
---
libdw/ChangeLog | 14 +++++++
libdw/Makefile.am | 3 +-
libdw/memory-access.c | 50 -----------------------
libdw/memory-access.h | 108 +++++++++++++++++++-------------------------------
4 files changed, 56 insertions(+), 119 deletions(-)
delete mode 100644 libdw/memory-access.c
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index a2e4b142a107..93396e404d97 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,17 @@
+2013-12-10 Josh Stone <jistone at redhat.com>
+
+ * 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.
+ * memory-access.c: Delete file.
+ * Makefile.am (libdw_a_SOURCES): Remove it.
+ (DEFS): Remove the now unused -DIS_LIBDW.
+
2013-12-09 Josh Stone <jistone at redhat.com>
* libdw_form.c (__libdw_form_val_compute_len): Renamed function from
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index a22166a99e73..cd9e31435317 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -28,7 +28,6 @@
## not, see <http://www.gnu.org/licenses/>.
##
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/memory-access.c b/libdw/memory-access.c
deleted file mode 100644
index 7666fb60a64c..000000000000
--- 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 <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#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 16471990dfa0..0aa46c9994b9 100644
--- a/libdw/memory-access.h
+++ b/libdw/memory-access.h
@@ -37,90 +37,64 @@
/* 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 len_leb128(var) ((8 * sizeof (var) + 6) / 7)
-#define get_uleb128(var, addr) \
+#define get_uleb128_step(var, addr, nth) \
do { \
- unsigned char __b; \
- var = 0; \
- get_uleb128_step (var, addr, 0, break); \
- var = __libdw_get_uleb128 (var, 1, &(addr)); \
+ unsigned char __b = *(addr)++; \
+ (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7); \
+ if (likely ((__b & 0x80) == 0)) \
+ return (var); \
} while (0)
-#define get_uleb128_rest_return(var, i, addrp) \
+static inline uint64_t
+__libdw_get_uleb128 (const unsigned char **addrp)
+{
+ uint64_t acc = 0;
+ 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_uleb128(var, addr) \
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; \
+ (var) = __libdw_get_uleb128(&(addr)); \
+ (void)(var); \
} while (0)
/* The signed case is similar, but we sign-extend the result. */
-#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_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)
-
-#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;
+ 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) \
+ do { \
+ (var) = __libdw_get_sleb128(&(addr)); \
+ (void)(var); \
+ } while (0)
/* We use simple memory access functions in case the hardware allows it.
--
1.8.4.2
More information about the elfutils-devel
mailing list