From: Roland McGrath Date: Tue, 22 Jun 2010 06:00:35 +0000 (-0700) Subject: Fix readelf for large SLEB128 values. X-Git-Tag: elfutils-0.148~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0c5638c2ac488a4a49f76ddb074e87bdebe90288;p=platform%2Fupstream%2Felfutils.git Fix readelf for large SLEB128 values. --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 34c7ba3..dff21fa 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2010-06-21 Roland McGrath + + * memory-access.h (get_sleb128_rest_return): Fix sign extension for + 10-byte case. + 2010-06-20 Roland McGrath * libdw_findcu.c (__libdw_findcu): Take new flag argument, diff --git a/libdw/memory-access.h b/libdw/memory-access.h index 13f79ec..b7799e9 100644 --- a/libdw/memory-access.h +++ b/libdw/memory-access.h @@ -1,5 +1,5 @@ /* Unaligned memory access functionality. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2009 Red Hat, Inc. + Copyright (C) 2000-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper , 2001. @@ -90,7 +90,7 @@ _v |= (uint64_t) (__b & 0x7f) << (nth * 7); \ if (likely ((__b & 0x80) == 0)) \ { \ - var = (_v << (64 - (nth * 7) - 7) >> (64 - (nth * 7) - 7)); \ + var = (_v << (64 - (nth * 7) - 7)) >> (64 - (nth * 7) - 7); \ break; \ } \ else do {} while (0) @@ -109,9 +109,13 @@ { \ get_sleb128_step (var, *addrp, i, return var); \ } \ - /* Other implementations set VALUE to INT_MAX in this \ - case. So we better do this as well. */ \ - return INT64_MAX; \ + __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 @@ -122,14 +126,14 @@ extern int64_t __libdw_get_sleb128 (int64_t acc, unsigned int i, const unsigned char **addrp) internal_function attribute_hidden; #else -static uint64_t +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 int64_t +static inline int64_t __attribute__ ((unused)) __libdw_get_sleb128 (int64_t acc, unsigned int i, const unsigned char **addrp) { diff --git a/src/ChangeLog b/src/ChangeLog index 59e8b8b..bcb9729 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2010-06-21 Roland McGrath + + * readelf.c (dwarf_tag_string): Handle new v4 tags. + + * readelf.c (print_ops): Use 64-bit types for LEB128 operands. + (print_cfa_program): Likewise. + 2010-06-20 Roland McGrath * readelf.c (print_debug_units): New function, broken out of ... diff --git a/src/readelf.c b/src/readelf.c index f5be7f1..76b4fe4 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -3227,6 +3227,9 @@ dwarf_tag_string (unsigned int tag) [DW_TAG_mutable_type] = "mutable_type", [DW_TAG_condition] = "condition", [DW_TAG_shared_type] = "shared_type", + [DW_TAG_type_unit] = "type_unit", + [DW_TAG_rvalue_reference_type] = "rvalue_reference_type", + [DW_TAG_template_alias] = "template_alias", }; const unsigned int nknown_tags = (sizeof (known_tags) / sizeof (known_tags[0])); @@ -4092,9 +4095,9 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_plus_uconst: case DW_OP_constu:; const unsigned char *start = data; - unsigned int uleb; + uint64_t uleb; get_uleb128 (uleb, data); /* XXX check overrun */ - printf ("%*s[%4" PRIuMAX "] %s %u\n", + printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", indent, "", (uintmax_t) offset, known[op], uleb); len -= data - start; offset += 1 + (data - start); @@ -4102,10 +4105,10 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_bit_piece: start = data; - unsigned int uleb2; + uint64_t uleb2; get_uleb128 (uleb, data); /* XXX check overrun */ get_uleb128 (uleb2, data); /* XXX check overrun */ - printf ("%*s[%4" PRIuMAX "] %s %u, %u\n", + printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n", indent, "", (uintmax_t) offset, known[op], uleb, uleb2); len -= data - start; offset += 1 + (data - start); @@ -4115,9 +4118,9 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_breg0 ... DW_OP_breg31: case DW_OP_consts: start = data; - unsigned int sleb; + int64_t sleb; get_sleb128 (sleb, data); /* XXX check overrun */ - printf ("%*s[%4" PRIuMAX "] %s %d\n", + printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n", indent, "", (uintmax_t) offset, known[op], sleb); len -= data - start; offset += 1 + (data - start); @@ -4127,7 +4130,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, start = data; get_uleb128 (uleb, data); /* XXX check overrun */ get_sleb128 (sleb, data); /* XXX check overrun */ - printf ("%*s[%4" PRIuMAX "] %s %u %d\n", + printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n", indent, "", (uintmax_t) offset, known[op], uleb, sleb); len -= data - start; offset += 1 + (data - start); @@ -4615,10 +4618,10 @@ print_cfa_program (const unsigned char *readp, const unsigned char *const endp, opcode & 0x3f, pc += (opcode & 0x3f) * code_align); else if (opcode < DW_CFA_restore) { - unsigned int offset; + uint64_t offset; // XXX overflow check get_uleb128 (offset, readp); - printf (" offset r%u (%s) at cfa%+d\n", + printf (" offset r%u (%s) at cfa%+" PRId64 "\n", opcode & 0x3f, regname (opcode & 0x3f), offset * data_align); } else @@ -5430,7 +5433,7 @@ print_debug_units (Dwfl_Module *dwflmod, " Version: %" PRIu16 ", Abbreviation section offset: %" PRIu64 ", Address size: %" PRIu8 ", Offset size: %" PRIu8 "\n Type signature: %#" PRIx64 - ", Type offset: %" PRIu64 "\n"), + ", Type offset: %#" PRIx64 "\n"), (uint64_t) offset, version, abbroffset, addrsize, offsize, typesig, (uint64_t) typeoff); else