From: Petr Machata Date: Mon, 11 Oct 2010 21:39:43 +0000 (+0200) Subject: dwarflint: Introduce read_generic_value into checked_read X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=21c4259c2e5a76a1e33f4ab326a38c1b16d326f4;p=thirdparty%2Felfutils.git dwarflint: Introduce read_generic_value into checked_read - the hope being several reading operations can be expressed in terms of read_generic_value --- diff --git a/dwarflint/check_debug_info.cc b/dwarflint/check_debug_info.cc index a8877f7ef..402e8df59 100644 --- a/dwarflint/check_debug_info.cc +++ b/dwarflint/check_debug_info.cc @@ -770,44 +770,33 @@ namespace /* Attribute value. */ uint64_t value; + read_ctx block; + storage_class_t storclass = form->storage_class (); - if (storclass == sc_string) + if (!read_generic_value (ctx, form->width (cu), storclass, + &where, &value, &block)) { - if (!read_ctx_read_str (ctx)) - goto cant_read; + // Note that for fw_uleb and fw_sleb we report the + // error the second time now. + wr_error (where) + << "can't read value of attribute " + << *attribute << '.' << std::endl; + return -1; } - else + if (storclass == sc_block) { - if (!read_sc_value (&value, form->width (cu), ctx, &where)) - { - // Note that for fw_uleb and fw_sleb we report the - // error the second time now. - cant_read: - wr_error (where) - << "can't read value of attribute " - << *attribute << '.' << std::endl; - return -1; - } - - if (storclass == sc_block) + if (cls == cl_exprloc) { - // Read & validate the block body. - if (cls == cl_exprloc) - { - uint64_t expr_start - = cu->head->offset + read_ctx_get_offset (ctx); - if (!check_location_expression - (file, ctx, cu, expr_start, reloc, value, &where)) - return false; - } - else - relocation_skip (reloc, - read_ctx_get_offset (ctx) + value, - &where, skip_mismatched); - - if (!read_ctx_skip (ctx, value)) - goto cant_read; + uint64_t expr_start + = cu->head->offset + read_ctx_get_offset (ctx) - value; + if (!check_location_expression + (ver, file, &block, cu, + expr_start, reloc, value, &where)) + return false; } + else + relocation_skip (reloc, read_ctx_get_offset (ctx), + &where, skip_mismatched); } /* Relocate the value if appropriate. */ diff --git a/dwarflint/checked_read.cc b/dwarflint/checked_read.cc index 4b73152dc..c6a714454 100644 --- a/dwarflint/checked_read.cc +++ b/dwarflint/checked_read.cc @@ -176,3 +176,41 @@ read_sc_value (uint64_t *valuep, form_width_t width, } UNREACHABLE; } + +bool +read_generic_value (read_ctx *ctx, + form_width_t width, storage_class_t storclass, + where const *where, uint64_t *valuep, read_ctx *blockp) +{ + uint64_t value; + if (storclass == sc_value + || storclass == sc_block) + { + if (!read_sc_value (&value, width, ctx, where)) + return false; + if (valuep != NULL) + *valuep = value; + if (storclass == sc_value) + return true; + } + + unsigned char const *start = ctx->ptr; + if (storclass == sc_string) + { + if (!read_ctx_read_str (ctx)) + return false; + } + else if (storclass == sc_block) + { + if (!read_ctx_skip (ctx, value)) + return false; + } + + if (blockp != NULL) + { + if (!read_ctx_init_sub (blockp, ctx, start, ctx->ptr)) + return false; + } + + return true; +} diff --git a/dwarflint/checked_read.hh b/dwarflint/checked_read.hh index 39927e5b1..0843aaf17 100644 --- a/dwarflint/checked_read.hh +++ b/dwarflint/checked_read.hh @@ -51,4 +51,14 @@ bool checked_read_leb128 (read_ctx *ctx, form_width_t width, uint64_t *ret, bool read_sc_value (uint64_t *valuep, form_width_t width, read_ctx *ctx, where const *where); +/// Read value depending on the form width and storage class. +/// Value is returned via VALUEP, if that is non-NULL; for block +/// forms, the value is block length. Block context is returned via +/// BLOCKP, in non-NULL; for string class, the block is the string +/// itself. +bool read_generic_value (read_ctx *ctx, + form_width_t width, storage_class_t storclass, + where const *where, uint64_t *valuep, + read_ctx *blockp); + #endif//DWARFLINT_CHECKED_READ_HH