]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Move check_zero_padding to read_ctx module
authorPetr Machata <pmachata@redhat.com>
Tue, 21 Sep 2010 18:30:40 +0000 (20:30 +0200)
committerPetr Machata <pmachata@redhat.com>
Tue, 21 Sep 2010 18:30:40 +0000 (20:30 +0200)
- and promote the reporting part back to callers

dwarflint/check_debug_info.cc
dwarflint/check_debug_line.cc
dwarflint/check_debug_pub.cc
dwarflint/low.c
dwarflint/low.h
dwarflint/readctx.c
dwarflint/readctx.h

index 77515328a4fb4b88727b566306e4a6bfda1763f7..353f4a2900d3021621987b68805d4a2c0d43ece0 100644 (file)
@@ -168,6 +168,7 @@ namespace
   {
     struct read_ctx ctx;
     read_ctx_init (&ctx, sec->data, file->other_byte_order);
+    uint64_t off_start, off_end;
 
     std::vector <cu_head> ret;
     while (!read_ctx_eof (&ctx))
@@ -183,9 +184,14 @@ namespace
        /* Reading CU head is a bit tricky, because we don't know if
           we have run into (superfluous but allowed) zero padding
           between CUs.  */
+
        if (!read_ctx_need_data (&ctx, 4)
-           && check_zero_padding (&ctx, cat (mc_info, mc_header), &where))
-         break;
+           && read_check_zero_padding (&ctx, &off_start, &off_end))
+         {
+           wr_message_padding_0 (cat (mc_info, mc_header), &where,
+                                 off_start, off_end);
+           break;
+         }
 
        /* CU length.  In DWARF 2, (uint32_t)-1 is simply a CU of that
           length.  In DWARF 3+ that's an escape for 64bit length.
@@ -199,8 +205,12 @@ namespace
            throw check_base::failed ();
          }
        if (size32 == 0
-           && check_zero_padding (&ctx, cat (mc_info, mc_header), &where))
-         break;
+           && read_check_zero_padding (&ctx, &off_start, &off_end))
+         {
+           wr_message_padding_0 (cat (mc_info, mc_header), &where,
+                                 off_start, off_end);
+           break;
+         }
 
        Dwarf_Off cu_size;
        if (!read_size_extra (&ctx, size32, &cu_size,
@@ -1146,14 +1156,18 @@ check_debug_info::check_info_structural ()
          break;
        }
 
-      if (cu_ctx.ptr != cu_ctx.end
-         && !check_zero_padding (&cu_ctx, mc_info, &where))
+      if (cu_ctx.ptr != cu_ctx.end)
        {
-         // Garbage coordinates:
-         uint64_t start
-           = read_ctx_get_offset (&ctx) + read_ctx_get_offset (&cu_ctx);
-         uint64_t end = read_ctx_get_offset (&ctx) + head.total_size;
-         wr_message_padding_n0 (mc_info, &where, start, end);
+         uint64_t off_start, off_end;
+         if (read_check_zero_padding (&cu_ctx, &off_start, &off_end))
+           wr_message_padding_0 (mc_info, &where, off_start, off_end);
+         else
+           {
+             // Garbage coordinates:
+             uint64_t start = read_ctx_get_offset (&ctx) + off_start;
+             uint64_t end = read_ctx_get_offset (&ctx) + head.total_size;
+             wr_message_padding_n0 (mc_info, &where, start, end);
+           }
        }
 
       int i = read_ctx_skip (&ctx, head.total_size);
index a383e953fec47452eec1818afc1a9bb1c3f6402e..e57fdb8d5e195478c925058b5cfc933bec2e2ee7 100644 (file)
@@ -1,5 +1,5 @@
 /* Low-level checking of .debug_line.
-   Copyright (C) 2009 Red Hat, Inc.
+   Copyright (C) 2009, 2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -362,10 +362,13 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint)
       else if (sub_ctx.ptr < program_start)
        {
          struct where wh = WHERE (sec_line, NULL);
-         if (!check_zero_padding (&sub_ctx, cat (mc_line, mc_header), &where))
+         uint64_t off_start, off_end;
+         if (read_check_zero_padding (&sub_ctx, &off_start, &off_end))
+           wr_message_padding_0 (cat (mc_line, mc_header), &wh,
+                                 off_start, off_end);
+         else
            wr_message_padding_n0 (cat (mc_line, mc_header), &wh,
-                                  read_ctx_get_offset (&sub_ctx),
-                                  program_start - sub_ctx.begin);
+                                  off_start, program_start - sub_ctx.begin);
          sub_ctx.ptr = program_start;
        }
 
@@ -479,13 +482,18 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint)
                  }
                else if (sub_ctx.ptr < next)
                  {
-                   if (handled
-                       && !check_zero_padding (&sub_ctx, mc_line, &where))
+                   uint64_t off_start, off_end;
+                   if (handled)
                      {
                        struct where wh = WHERE (sec_line, NULL);
-                       wr_message_padding_n0 (mc_line, &wh,
-                                              read_ctx_get_offset (&sub_ctx),
-                                              next - sub_ctx.begin);
+                       if (read_check_zero_padding (&sub_ctx,
+                                                    &off_start, &off_end))
+                         wr_message_padding_0 (mc_line, &wh,
+                                               off_start, off_end);
+                       else
+                         wr_message_padding_n0 (mc_line, &wh,
+                                                off_start,
+                                                next - sub_ctx.begin);
                      }
                    sub_ctx.ptr = next;
                  }
@@ -596,11 +604,15 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint)
        wr_error (where)
          << "sequence of opcodes not terminated with DW_LNE_end_sequence."
          << std::endl;
-      else if (sub_ctx.ptr != sub_ctx.end
-              && !check_zero_padding (&sub_ctx, mc_line, &wh))
-       wr_message_padding_n0 (mc_line, &wh,
-                              /*begin*/read_ctx_get_offset (&sub_ctx),
-                              /*end*/sub_ctx.end - sub_ctx.begin);
+      else if (sub_ctx.ptr != sub_ctx.end)
+       {
+         uint64_t off_start, off_end;
+         if (read_check_zero_padding (&sub_ctx, &off_start, &off_end))
+           wr_message_padding_0 (mc_line, &wh, off_start, off_end);
+         else
+           wr_message_padding_n0 (mc_line, &wh,
+                                  off_start, sub_ctx.end - sub_ctx.begin);
+       }
       }
 
     next:
index 0ce3ff60e97e723f6067802e47fd16134783f870..1db93bf9a4fee24d0bff620f70a3d5d69292b274 100644 (file)
@@ -1,5 +1,5 @@
 /* Low-level checking of .debug_pub*.
-   Copyright (C) 2009 Red Hat, Inc.
+   Copyright (C) 2009, 2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -226,14 +226,17 @@ check_debug_pub<sec_id>::check_pub_structural ()
        }
 
        struct where wh = WHERE (_m_sec->sect.id, NULL);
-       if (sub_ctx.ptr != sub_ctx.end
-           && !check_zero_padding (&sub_ctx, mc_pubtables, &wh))
+       if (sub_ctx.ptr != sub_ctx.end)
          {
-           wh = WHERE (_m_sec->sect.id, NULL);
-           wr_message_padding_n0 (mc_pubtables | mc_error, &wh,
-                                  read_ctx_get_offset (&sub_ctx),
-                                  read_ctx_get_offset (&sub_ctx) + size);
-           retval = false;
+           uint64_t off_start, off_end;
+           if (read_check_zero_padding (&sub_ctx, &off_start, &off_end))
+             wr_message_padding_0 (mc_pubtables, &wh, off_start, off_end);
+           else
+             {
+               wr_message_padding_n0 (mc_pubtables | mc_error, &wh,
+                                      off_start, off_start + size);
+               retval = false;
+             }
          }
       }
 
index 945af7b44f29e73fb6edc42f30d0db8a027cb1b5..d49819a5d445b05ca3c59f8ca7b240494d9301b4 100644 (file)
@@ -134,26 +134,6 @@ cu_find_cu (struct cu *cu_chain, uint64_t offset)
   return NULL;
 }
 
-bool
-check_zero_padding (struct read_ctx *ctx,
-                   enum message_category category,
-                   struct where const *wh)
-{
-  assert (ctx->ptr != ctx->end);
-  const unsigned char *save_ptr = ctx->ptr;
-  while (!read_ctx_eof (ctx))
-    if (*ctx->ptr++ != 0)
-      {
-       ctx->ptr = save_ptr;
-       return false;
-      }
-
-  wr_message_padding_0 (category, wh,
-                       (uint64_t)(save_ptr - ctx->begin),
-                       (uint64_t)(ctx->end - ctx->begin));
-  return true;
-}
-
 bool
 supported_version (unsigned version,
                   size_t num_supported, struct where *where, ...)
@@ -463,15 +443,19 @@ check_aranges_structural (struct elf_file *file,
            aranges_coverage_add (address, length);
        }
 
-      if (sub_ctx.ptr != sub_ctx.end
-         && !check_zero_padding (&sub_ctx, mc_aranges,
-                                 &WHERE (where.section, NULL)))
+      if (sub_ctx.ptr != sub_ctx.end)
        {
-         wr_message_padding_n0 (mc_aranges | mc_error,
-                                &WHERE (where.section, NULL),
-                                read_ctx_get_offset (&sub_ctx),
-                                read_ctx_get_offset (&sub_ctx) + size);
-         retval = false;
+         uint64_t start, end;
+         if (read_check_zero_padding (&sub_ctx, &start, &end))
+           wr_message_padding_0 (mc_aranges, &WHERE (where.section, NULL),
+                                 start, end);
+         else
+           {
+             wr_message_padding_n0 (mc_aranges | mc_error,
+                                    &WHERE (where.section, NULL),
+                                    start, start + size);
+             retval = false;
+           }
        }
 
     next:
index 309e13c171f077b031815034c5a9b07c644ab9cc..42361f8d0df06f4ae76e8f3d39e2588465cffbf2 100644 (file)
@@ -101,9 +101,6 @@ extern "C"
 #define PRI_NOT_ENOUGH ": not enough data for %s.\n"
   extern bool supported_version (unsigned version,
                                 size_t num_supported, struct where *where, ...);
-  extern bool check_zero_padding (struct read_ctx *ctx,
-                                 enum message_category category,
-                                 struct where const *wh);
 
   struct section_coverage
   {
index a17bd5a5452e0d7a1d4e66294d59592aca9a966b..a8ca038b3d9851b9d64281391a8187d22b84307c 100644 (file)
@@ -379,3 +379,32 @@ read_address_size (struct read_ctx *ctx,
   return true;
 }
 
+static void
+update_off (struct read_ctx *ctx,
+           uint64_t *ret_off)
+{
+  if (ret_off != NULL)
+    *ret_off = (uint64_t)(ctx->ptr - ctx->begin);
+}
+
+bool
+read_check_zero_padding (struct read_ctx *ctx,
+                        uint64_t *ret_off_start,
+                        uint64_t *ret_off_end)
+{
+  assert (ctx->ptr != ctx->end);
+  update_off (ctx, ret_off_start);
+  bool ret = true;
+
+  const unsigned char *save_ptr = ctx->ptr;
+  while (!read_ctx_eof (ctx))
+    if (*ctx->ptr++ != 0)
+      {
+       ctx->ptr = save_ptr;
+       goto done;
+      }
+
+ done:
+  update_off (ctx, ret_off_end);
+  return ret;
+}
index d6f94bf8eb552419f7d82bf9164d817843dd7ea2..99b1c7da553bcb23f9c2add6a703e847d84245ae 100644 (file)
@@ -28,6 +28,8 @@
 
 #include <stdbool.h>
 #include "../libelf/libelf.h"
+
+// xxx We don't really like this one
 #include "where.h"
 
 #ifdef __cplusplus
@@ -87,6 +89,14 @@ bool read_address_size (struct read_ctx *ctx,
                        int *address_sizep,
                        struct where const *where);
 
+/* See if what remains in the read context is just a zero padding.  If
+   yes, return true.  If it isn't, revert the read pointer back as if
+   nothing had happened and return false.  Furthermore, in any case,
+   if any of the ret pointers is non-NULL, it is filled, respectively,
+   with start and end offset of the zero padding run.  */
+bool read_check_zero_padding (struct read_ctx *ctx,
+                             uint64_t *ret_off_start,
+                             uint64_t *ret_off_end);
 #ifdef __cplusplus
 }
 #endif