This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2 2/3] 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 <jistone@redhat.com>
---
 libdw/ChangeLog           |  15 +++++++
 libdw/Makefile.am         |   3 +-
 libdw/dwarf_getlocation.c |   3 +-
 libdw/memory-access.c     |  50 ----------------------
 libdw/memory-access.h     | 107 ++++++++++++++++------------------------------
 5 files changed, 55 insertions(+), 123 deletions(-)
 delete mode 100644 libdw/memory-access.c

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index a2e4b142a107..aa7b9ca486c2 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,18 @@
+2013-12-10  Josh Stone  <jistone@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.
+	* 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  <jistone@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/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index 4124ae36b84f..8dffb83f496f 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 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..d0ee63c53f99 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.
-- 
1.8.4.2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]