mirror of
https://github.com/openharmony/third_party_elfutils.git
synced 2026-07-20 23:45:11 -04:00
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>
This commit is contained in:
@@ -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
|
||||
|
||||
+1
-2
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
+39
-70
@@ -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); \
|
||||
#define len_leb128(var) ((8 * sizeof (var) + 6) / 7)
|
||||
|
||||
#define get_uleb128_step(var, addr, nth) \
|
||||
do { \
|
||||
unsigned char __b = *(addr)++; \
|
||||
(var) |= (typeof (var)) (__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)); \
|
||||
return (var); \
|
||||
} while (0)
|
||||
|
||||
#define get_uleb128_rest_return(var, i, addrp) \
|
||||
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; \
|
||||
} while (0)
|
||||
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_uleb128(var, addr) ((var) = __libdw_get_uleb128 (&(addr)))
|
||||
|
||||
/* 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); \
|
||||
#define get_sleb128_step(var, addr, nth) \
|
||||
do { \
|
||||
unsigned char __b = *(addr)++; \
|
||||
if (likely ((__b & 0x80) == 0)) \
|
||||
{ \
|
||||
var = (_v << (64 - (nth * 7) - 7)) >> (64 - (nth * 7) - 7); \
|
||||
break; \
|
||||
struct { signed int i:7; } __s = { .i = __b }; \
|
||||
(var) |= (typeof (var)) __s.i << ((nth) * 7); \
|
||||
return (var); \
|
||||
} \
|
||||
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)); \
|
||||
(var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7); \
|
||||
} while (0)
|
||||
|
||||
#define get_sleb128_rest_return(var, i, addrp) \
|
||||
do { \
|
||||
for (; i < 9; ++i) \
|
||||
{ \
|
||||
get_sleb128_step (var, *addrp, i, 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; \
|
||||
} 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.
|
||||
|
||||
Reference in New Issue
Block a user