]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Simplify and inline get_uleb128 and get_sleb128
authorJosh Stone <jistone@redhat.com>
Tue, 10 Dec 2013 22:19:09 +0000 (14:19 -0800)
committerJosh Stone <jistone@redhat.com>
Fri, 13 Dec 2013 17:48:07 +0000 (09:48 -0800)
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
libdw/Makefile.am
libdw/dwarf_getlocation.c
libdw/memory-access.c [deleted file]
libdw/memory-access.h

index a2e4b142a107ce2c8733446e548148239638d97a..aa7b9ca486c26297bb9de4dd09b35b3bd55c67f7 100644 (file)
@@ -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
index a22166a99e7355e96aeb50991cacfe97630e413a..cd9e3143531790683a54dc4d14e89489edd0d7a2 100644 (file)
@@ -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 \
index 4124ae36b84fc89471d09465fa3a9591bdfc3837..8dffb83f496f33caa7ea2d1aa1b52aa3d17a9987 100644 (file)
@@ -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 (file)
index 7666fb6..0000000
+++ /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);
-}
index 16471990dfa032258842bdb8da641822de587060..d0ee63c53f99d170d0064b7232a1256f6451a823 100644 (file)
 
 /* 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.