]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Introduce read_generic_value into checked_read
authorPetr Machata <pmachata@redhat.com>
Mon, 11 Oct 2010 21:39:43 +0000 (23:39 +0200)
committerPetr Machata <pmachata@redhat.com>
Mon, 11 Oct 2010 21:39:43 +0000 (23:39 +0200)
- the hope being several reading operations can be expressed in terms of
  read_generic_value

dwarflint/check_debug_info.cc
dwarflint/checked_read.cc
dwarflint/checked_read.hh

index a8877f7efe2a84db05df0c5f2d98390ef8cc7625..402e8df59f6330b4940f930e4a915207e92286fe 100644 (file)
@@ -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.  */
index 4b73152dc4489fe13a472027ca378ee1fc62440b..c6a7144541b74a87729ad77cfe84b27a6c32908f 100644 (file)
@@ -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;
+}
index 39927e5b13569712d867e07106ba4887dca9c5b2..0843aaf17fd9f2ccd11858fa0fb9afd3bb0ba50b 100644 (file)
@@ -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