]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Move a bunch more over to check_debug_loc_range
authorPetr Machata <pmachata@redhat.com>
Mon, 23 Nov 2009 18:40:44 +0000 (19:40 +0100)
committerPetr Machata <pmachata@redhat.com>
Wed, 18 Aug 2010 12:55:14 +0000 (14:55 +0200)
src/dwarflint/check_debug_info.cc
src/dwarflint/check_debug_loc_range.cc
src/dwarflint/check_debug_loc_range.hh
src/dwarflint/low.c
src/dwarflint/low.h
src/dwarflint/pri.cc
src/dwarflint/pri.hh

index 25ae93a2fb4d8b23e3bb4a869d44eddc5090dfe6..db76d67dd09f0608730888b5d6053c2df4594dfa 100644 (file)
@@ -42,6 +42,7 @@
 #include "checks-low.hh"
 #include "pri.hh"
 #include "config.h"
+#include "check_debug_loc_range.hh"
 
 namespace
 {
index a09fd7241e6ae53444625bc29128cbeb51ff8fd8..1f07843e89d774744466d85e1d648e02c683fb75 100644 (file)
@@ -39,6 +39,8 @@
 #include "low.h"
 #include "config.h"
 #include "check_debug_loc_range.hh"
+#include "dwarf-opcodes.h"
+#include "pri.hh"
 
 namespace
 {
@@ -123,6 +125,12 @@ namespace
     return true;
   }
 
+  struct coverage_map_hole_info
+  {
+    struct elf_file *elf;
+    struct hole_info info;
+  };
+
   /* begin is inclusive, end is exclusive. */
   bool
   coverage_map_found_hole (uint64_t begin, uint64_t end,
@@ -677,6 +685,314 @@ check_debug_loc::check_debug_loc (dwarflint &lint)
     throw check_base::failed ();
 }
 
+namespace
+{
+  /* Operands are passed back as attribute forms.  In particular,
+     DW_FORM_dataX for X-byte operands, DW_FORM_[us]data for
+     ULEB128/SLEB128 operands, and DW_FORM_addr for 32b/64b operands.
+     If the opcode takes no operands, 0 is passed.
+
+     Return value is false if we couldn't determine (i.e. invalid
+     opcode).
+  */
+
+  bool
+  get_location_opcode_operands (uint8_t opcode, uint8_t *op1, uint8_t *op2)
+  {
+    switch (opcode)
+      {
+#define DW_OP_2(OPCODE, OP1, OP2)                              \
+       case OPCODE: *op1 = OP1; *op2 = OP2; return true;
+#define DW_OP_1(OPCODE, OP1) DW_OP_2(OPCODE, OP1, 0)
+#define DW_OP_0(OPCODE) DW_OP_2(OPCODE, 0, 0)
+
+       DW_OP_OPERANDS
+
+#undef DEF_DW_OP_2
+#undef DEF_DW_OP_1
+#undef DEF_DW_OP_0
+      default:
+       return false;
+      };
+  }
+
+  /* The value passed back in uint64_t VALUEP may actually be
+     type-casted signed quantity.  WHAT and WHERE describe error
+     message and context for LEB128 loading.
+
+     If IS_BLOCKP is non-NULL, block values are accepted, and
+     *IS_BLOCKP is initialized depending on whether FORM is a block
+     form.  For block forms, the value passed back in VALUEP is block
+     length.  */
+  bool
+  read_ctx_read_form (struct read_ctx *ctx, int address_size, uint8_t form,
+                     uint64_t *valuep, struct where *where, const char *what,
+                     bool *is_blockp)
+  {
+    if (is_blockp != NULL)
+      *is_blockp = false;
+    switch (form)
+      {
+      case DW_FORM_addr:
+       return read_ctx_read_offset (ctx, address_size == 8, valuep);
+      case DW_FORM_udata:
+       return checked_read_uleb128 (ctx, valuep, where, what);
+      case DW_FORM_sdata:
+       return checked_read_sleb128 (ctx, (int64_t *)valuep, where, what);
+      case DW_FORM_data1:
+       {
+         uint8_t v;
+         if (!read_ctx_read_ubyte (ctx, &v))
+           return false;
+         if (valuep != NULL)
+           *valuep = v;
+         return true;
+       }
+      case DW_FORM_data2:
+       {
+         uint16_t v;
+         if (!read_ctx_read_2ubyte (ctx, &v))
+           return false;
+         if (valuep != NULL)
+           *valuep = v;
+         return true;
+       }
+      case DW_FORM_data4:
+       {
+         uint32_t v;
+         if (!read_ctx_read_4ubyte (ctx, &v))
+           return false;
+         if (valuep != NULL)
+           *valuep = v;
+         return true;
+       }
+      case DW_FORM_data8:
+       return read_ctx_read_8ubyte (ctx, valuep);
+      };
+
+    if (is_blockp != NULL)
+      {
+       int dform;
+       switch (form)
+         {
+#define HANDLE(BFORM, DFORM)                   \
+           case BFORM:                         \
+             dform = DFORM;                    \
+             break
+           HANDLE (DW_FORM_block, DW_FORM_udata);
+           HANDLE (DW_FORM_block1, DW_FORM_data1);
+           HANDLE (DW_FORM_block2, DW_FORM_data2);
+           HANDLE (DW_FORM_block4, DW_FORM_data4);
+#undef HANDLE
+         default:
+           return false;
+         }
+
+       *is_blockp = true;
+       return read_ctx_read_form (ctx, address_size, dform,
+                                  valuep, where, what, NULL)
+         && read_ctx_skip (ctx, *valuep);
+      }
+
+    return false;
+  }
+
+  static enum section_id
+  reloc_target_loc (uint8_t opcode)
+  {
+    switch (opcode)
+      {
+      case DW_OP_call2:
+      case DW_OP_call4:
+       return sec_info;
+
+      case DW_OP_addr:
+       return rel_address;
+
+      case DW_OP_call_ref:
+       assert (!"Can't handle call_ref!");
+      };
+
+    std::cout << "XXX don't know how to handle opcode="
+             << pri::locexpr_opcode (opcode) << std::endl;
+
+    return rel_value;
+  }
+
+  bool
+  op_read_form (struct elf_file *file,
+               struct read_ctx *ctx,
+               struct cu *cu,
+               uint64_t init_off,
+               struct relocation_data *reloc,
+               int opcode,
+               int form,
+               uint64_t *valuep,
+               char const *str,
+               struct where *where)
+  {
+    if (form == 0)
+      return true;
+
+    bool isblock;
+    uint64_t off = read_ctx_get_offset (ctx) + init_off;
+
+    if (!read_ctx_read_form (ctx, cu->head->address_size, form,
+                            valuep, where, str, &isblock))
+      {
+       wr_error (*where)
+         << "opcode \"" << pri::locexpr_opcode (opcode)
+         << "\": can't read " << str << " (form \""
+         << pri::form (form) << "\")." << std::endl;
+       return false;
+      }
+
+    /* For non-block forms, allow relocation of the datum.  For block
+       form, allow relocation of block contents, but not the
+       block length).  */
+
+    struct relocation *rel;
+    if ((rel = relocation_next (reloc, off,
+                               where, skip_mismatched)))
+      {
+       if (!isblock)
+         relocate_one (file, reloc, rel,
+                       cu->head->address_size, valuep, where,
+                       reloc_target_loc (opcode), NULL);
+       else
+         wr_error (where, ": relocation relocates a length field.\n");
+      }
+    if (isblock)
+      {
+       uint64_t off_block_end = read_ctx_get_offset (ctx) + init_off - 1;
+       relocation_next (reloc, off_block_end, where, skip_ok);
+      }
+
+    return true;
+  }
+}
+
+bool
+check_location_expression (struct elf_file *file,
+                          struct read_ctx *parent_ctx,
+                          struct cu *cu,
+                          uint64_t init_off,
+                          struct relocation_data *reloc,
+                          size_t length,
+                          struct where *wh)
+{
+  struct read_ctx ctx;
+  if (!read_ctx_init_sub (&ctx, parent_ctx, parent_ctx->ptr,
+                         parent_ctx->ptr + length))
+    {
+      wr_error (wh, PRI_NOT_ENOUGH, "location expression");
+      return false;
+    }
+
+  struct ref_record oprefs;
+  WIPE (oprefs);
+
+  struct addr_record opaddrs;
+  WIPE (opaddrs);
+
+  while (!read_ctx_eof (&ctx))
+    {
+      struct where where = WHERE (sec_locexpr, wh);
+      uint64_t opcode_off = read_ctx_get_offset (&ctx) + init_off;
+      where_reset_1 (&where, opcode_off);
+      addr_record_add (&opaddrs, opcode_off);
+
+      uint8_t opcode;
+      if (!read_ctx_read_ubyte (&ctx, &opcode))
+       {
+         wr_error (&where, ": can't read opcode.\n");
+         break;
+       }
+
+      uint8_t op1, op2;
+      if (!get_location_opcode_operands (opcode, &op1, &op2))
+       {
+         wr_error (where)
+           << "can't decode opcode \""
+           << pri::locexpr_opcode (opcode) << "\"." << std::endl;
+         break;
+       }
+
+      uint64_t value1, value2;
+      if (!op_read_form (file, &ctx, cu, init_off, reloc,
+                        opcode, op1, &value1, "1st operand", &where)
+         || !op_read_form (file, &ctx, cu, init_off, reloc,
+                           opcode, op2, &value2, "2st operand", &where))
+       goto out;
+
+      switch (opcode)
+       {
+       case DW_OP_bra:
+       case DW_OP_skip:
+         {
+           int16_t skip = (uint16_t)value1;
+
+           if (skip == 0)
+             wr_message (where, cat (mc_loc, mc_acc_bloat, mc_impact_3))
+               << pri::locexpr_opcode (opcode)
+               << " with skip 0." << std::endl;
+           else if (skip > 0 && !read_ctx_need_data (&ctx, (size_t)skip))
+             wr_error (where)
+               << pri::locexpr_opcode (opcode)
+               << " branches out of location expression." << std::endl;
+           /* Compare with the offset after the two-byte skip value.  */
+           else if (skip < 0 && ((uint64_t)-skip) > read_ctx_get_offset (&ctx))
+             wr_error (where)
+               << pri::locexpr_opcode (opcode)
+               << " branches before the beginning of location expression."
+               << std::endl;
+           else
+             {
+               uint64_t off_after = read_ctx_get_offset (&ctx) + init_off;
+               ref_record_add (&oprefs, off_after + skip, &where);
+             }
+
+           break;
+         }
+
+       case DW_OP_const8u:
+       case DW_OP_const8s:
+         if (cu->head->address_size == 4)
+           wr_error (where)
+             << pri::locexpr_opcode (opcode) << " on 32-bit machine."
+             << std::endl;
+         break;
+
+       default:
+         if (cu->head->address_size == 4
+             && (opcode == DW_OP_constu
+                 || opcode == DW_OP_consts
+                 || opcode == DW_OP_deref_size
+                 || opcode == DW_OP_plus_uconst)
+             && (value1 > (uint64_t)(uint32_t)-1))
+           wr_message (where, cat (mc_loc, mc_acc_bloat, mc_impact_3))
+             << pri::locexpr_opcode (opcode)
+             << " with operand " << pri::hex (value1)
+             << " on a 32-bit machine." << std::endl;
+       };
+    }
+
+ out:
+  for (size_t i = 0; i < oprefs.size; ++i)
+    {
+      struct ref *ref = oprefs.refs + i;
+      if (!addr_record_has_addr (&opaddrs, ref->addr))
+       wr_error (&ref->who,
+                 ": unresolved reference to opcode at %#" PRIx64 ".\n",
+                 ref->addr);
+    }
+
+  addr_record_free (&opaddrs);
+  ref_record_free (&oprefs);
+
+  return true;
+}
+
 bool
 found_hole (uint64_t start, uint64_t length, void *data)
 {
index b5711d887e4f5c579651aa41691d4a08209453d2..893b553fc3a9af0ddc41b257f554a7cb0418022a 100644 (file)
@@ -46,4 +46,22 @@ public:
   explicit check_debug_loc (dwarflint &lint);
 };
 
+struct hole_info
+{
+  enum section_id section;
+  enum message_category category;
+  void *data;
+  unsigned align;
+};
+
+/* DATA has to be a pointer to an instance of struct hole_info.
+   DATA->data has to point at d_buf of section in question.  */
 extern bool found_hole (uint64_t start, uint64_t length, void *data);
+
+extern bool check_location_expression (struct elf_file *file,
+                                      struct read_ctx *parent_ctx,
+                                      struct cu *cu,
+                                      uint64_t init_off,
+                                      struct relocation_data *reloc,
+                                      size_t length,
+                                      struct where *wh);
index 2f0f20235f1abdc2e868c806cc466ed0e56a6899..89e8c60ae236d71624a2be884ec7dbde59fb24f1 100644 (file)
@@ -47,7 +47,6 @@
 #include "low.h"
 #include "readctx.h"
 #include "config.h"
-#include "dwarf-opcodes.h"
 #include "tables.h"
 
 #define PRI_CU "CU 0x%" PRIx64
@@ -103,86 +102,6 @@ checked_read_sleb128 (struct read_ctx *ctx, int64_t *ret,
   return st >= 0;
 }
 
-/* The value passed back in uint64_t VALUEP may actually be
-   type-casted signed quantity.  WHAT and WHERE describe error message
-   and context for LEB128 loading.
-
-   If IS_BLOCKP is non-NULL, block values are accepted, and *IS_BLOCKP
-   is initialized depending on whether FORM is a block form.  For
-   block forms, the value passed back in VALUEP is block length.  */
-static bool
-read_ctx_read_form (struct read_ctx *ctx, int address_size, uint8_t form,
-                   uint64_t *valuep, struct where *where, const char *what,
-                   bool *is_blockp)
-{
-  if (is_blockp != NULL)
-    *is_blockp = false;
-  switch (form)
-    {
-    case DW_FORM_addr:
-      return read_ctx_read_offset (ctx, address_size == 8, valuep);
-    case DW_FORM_udata:
-      return checked_read_uleb128 (ctx, valuep, where, what);
-    case DW_FORM_sdata:
-      return checked_read_sleb128 (ctx, (int64_t *)valuep, where, what);
-    case DW_FORM_data1:
-      {
-       uint8_t v;
-       if (!read_ctx_read_ubyte (ctx, &v))
-         return false;
-       if (valuep != NULL)
-         *valuep = v;
-       return true;
-      }
-    case DW_FORM_data2:
-      {
-       uint16_t v;
-       if (!read_ctx_read_2ubyte (ctx, &v))
-         return false;
-       if (valuep != NULL)
-         *valuep = v;
-       return true;
-      }
-    case DW_FORM_data4:
-      {
-       uint32_t v;
-       if (!read_ctx_read_4ubyte (ctx, &v))
-         return false;
-       if (valuep != NULL)
-         *valuep = v;
-       return true;
-      }
-    case DW_FORM_data8:
-      return read_ctx_read_8ubyte (ctx, valuep);
-    };
-
-  if (is_blockp != NULL)
-    {
-      int dform;
-      switch (form)
-       {
-#define HANDLE(BFORM, DFORM)                   \
-         case BFORM:                           \
-           dform = DFORM;                      \
-           break
-         HANDLE (DW_FORM_block, DW_FORM_udata);
-         HANDLE (DW_FORM_block1, DW_FORM_data1);
-         HANDLE (DW_FORM_block2, DW_FORM_data2);
-         HANDLE (DW_FORM_block4, DW_FORM_data4);
-#undef HANDLE
-       default:
-         return false;
-       }
-
-      *is_blockp = true;
-      return read_ctx_read_form (ctx, address_size, dform,
-                                valuep, where, what, NULL)
-       && read_ctx_skip (ctx, *valuep);
-    }
-
-  return false;
-}
-
 int
 check_sibling_form (dwarf_version_h ver, uint64_t form)
 {
@@ -280,28 +199,6 @@ check_zero_padding (struct read_ctx *ctx,
   return true;
 }
 
-static enum section_id
-reloc_target_loc (uint8_t opcode)
-{
-  switch (opcode)
-    {
-    case DW_OP_call2:
-    case DW_OP_call4:
-      return sec_info;
-
-    case DW_OP_addr:
-      return rel_address;
-
-    case DW_OP_call_ref:
-      assert (!"Can't handle call_ref!");
-    };
-
-  printf ("XXX don't know how to handle opcode=%s\n",
-         dwarf_locexpr_opcode_string (opcode));
-
-  return rel_value;
-}
-
 bool
 supported_version (unsigned version,
                   size_t num_supported, struct where *where, ...)
@@ -832,202 +729,6 @@ check_pub_structural (struct elf_file *file,
   return retval;
 }
 
-
-/* Operands are passed back as attribute forms.  In particular,
-   DW_FORM_dataX for X-byte operands, DW_FORM_[us]data for
-   ULEB128/SLEB128 operands, and DW_FORM_addr for 32b/64b operands.
-   If the opcode takes no operands, 0 is passed.
-
-   Return value is false if we couldn't determine (i.e. invalid
-   opcode).
- */
-static bool
-get_location_opcode_operands (uint8_t opcode, uint8_t *op1, uint8_t *op2)
-{
-  switch (opcode)
-    {
-#define DW_OP_2(OPCODE, OP1, OP2) \
-      case OPCODE: *op1 = OP1; *op2 = OP2; return true;
-#define DW_OP_1(OPCODE, OP1) DW_OP_2(OPCODE, OP1, 0)
-#define DW_OP_0(OPCODE) DW_OP_2(OPCODE, 0, 0)
-
-      DW_OP_OPERANDS
-
-#undef DEF_DW_OP_2
-#undef DEF_DW_OP_1
-#undef DEF_DW_OP_0
-    default:
-      return false;
-    };
-}
-
-static bool
-op_read_form (struct elf_file *file,
-             struct read_ctx *ctx,
-             struct cu *cu,
-             uint64_t init_off,
-             struct relocation_data *reloc,
-             int opcode,
-             int form,
-             uint64_t *valuep,
-             char const *str,
-             struct where *where)
-{
-  if (form == 0)
-    return true;
-
-  bool isblock;
-  uint64_t off = read_ctx_get_offset (ctx) + init_off;
-
-  if (!read_ctx_read_form (ctx, cu->head->address_size, form,
-                          valuep, where, str, &isblock))
-    {
-      wr_error (where, ": opcode \"%s\": can't read %s (form \"%s\").\n",
-               dwarf_locexpr_opcode_string (opcode),
-               str, dwarf_form_string (form));
-      return false;
-    }
-
-  /* For non-block forms, allow relocation of the datum.  For block
-     form, allow relocation of block contents, but not the
-     block length).  */
-
-  struct relocation *rel;
-  if ((rel = relocation_next (reloc, off,
-                             where, skip_mismatched)))
-    {
-      if (!isblock)
-       relocate_one (file, reloc, rel,
-                     cu->head->address_size, valuep, where,
-                     reloc_target_loc (opcode), NULL);
-      else
-       wr_error (where, ": relocation relocates a length field.\n");
-    }
-  if (isblock)
-    {
-      uint64_t off_block_end = read_ctx_get_offset (ctx) + init_off - 1;
-      relocation_next (reloc, off_block_end, where, skip_ok);
-    }
-
-  return true;
-}
-
-bool
-check_location_expression (struct elf_file *file,
-                          struct read_ctx *parent_ctx,
-                          struct cu *cu,
-                          uint64_t init_off,
-                          struct relocation_data *reloc,
-                          size_t length,
-                          struct where *wh)
-{
-  struct read_ctx ctx;
-  if (!read_ctx_init_sub (&ctx, parent_ctx, parent_ctx->ptr,
-                         parent_ctx->ptr + length))
-    {
-      wr_error (wh, PRI_NOT_ENOUGH, "location expression");
-      return false;
-    }
-
-  struct ref_record oprefs;
-  WIPE (oprefs);
-
-  struct addr_record opaddrs;
-  WIPE (opaddrs);
-
-  while (!read_ctx_eof (&ctx))
-    {
-      struct where where = WHERE (sec_locexpr, wh);
-      uint64_t opcode_off = read_ctx_get_offset (&ctx) + init_off;
-      where_reset_1 (&where, opcode_off);
-      addr_record_add (&opaddrs, opcode_off);
-
-      uint8_t opcode;
-      if (!read_ctx_read_ubyte (&ctx, &opcode))
-       {
-         wr_error (&where, ": can't read opcode.\n");
-         break;
-       }
-
-      uint8_t op1, op2;
-      if (!get_location_opcode_operands (opcode, &op1, &op2))
-       {
-         wr_error (&where, ": can't decode opcode \"%s\".\n",
-                   dwarf_locexpr_opcode_string (opcode));
-         break;
-       }
-
-      uint64_t value1, value2;
-      if (!op_read_form (file, &ctx, cu, init_off, reloc,
-                        opcode, op1, &value1, "1st operand", &where)
-         || !op_read_form (file, &ctx, cu, init_off, reloc,
-                           opcode, op2, &value2, "2st operand", &where))
-       goto out;
-
-      switch (opcode)
-       {
-       case DW_OP_bra:
-       case DW_OP_skip:
-         {
-           int16_t skip = (uint16_t)value1;
-
-           if (skip == 0)
-             wr_message (mc_loc | mc_acc_bloat | mc_impact_3, &where,
-                         ": %s with skip 0.\n",
-                         dwarf_locexpr_opcode_string (opcode));
-           else if (skip > 0 && !read_ctx_need_data (&ctx, (size_t)skip))
-             wr_error (&where, ": %s branches out of location expression.\n",
-                       dwarf_locexpr_opcode_string (opcode));
-           /* Compare with the offset after the two-byte skip value.  */
-           else if (skip < 0 && ((uint64_t)-skip) > read_ctx_get_offset (&ctx))
-             wr_error (&where,
-                       ": %s branches before the beginning of location expression.\n",
-                       dwarf_locexpr_opcode_string (opcode));
-           else
-             {
-               uint64_t off_after = read_ctx_get_offset (&ctx) + init_off;
-               ref_record_add (&oprefs, off_after + skip, &where);
-             }
-
-           break;
-         }
-
-       case DW_OP_const8u:
-       case DW_OP_const8s:
-         if (cu->head->address_size == 4)
-           wr_error (&where, ": %s on 32-bit machine.\n",
-                     dwarf_locexpr_opcode_string (opcode));
-         break;
-
-       default:
-         if (cu->head->address_size == 4
-             && (opcode == DW_OP_constu
-                 || opcode == DW_OP_consts
-                 || opcode == DW_OP_deref_size
-                 || opcode == DW_OP_plus_uconst)
-             && (value1 > (uint64_t)(uint32_t)-1))
-           wr_message (mc_loc | mc_acc_bloat | mc_impact_3, &where,
-                       ": %s with operand %#" PRIx64 " on 32-bit machine.\n",
-                       dwarf_locexpr_opcode_string (opcode), value1);
-       };
-    }
-
- out:
-  for (size_t i = 0; i < oprefs.size; ++i)
-    {
-      struct ref *ref = oprefs.refs + i;
-      if (!addr_record_has_addr (&opaddrs, ref->addr))
-       wr_error (&ref->who,
-                 ": unresolved reference to opcode at %#" PRIx64 ".\n",
-                 ref->addr);
-    }
-
-  addr_record_free (&opaddrs);
-  ref_record_free (&oprefs);
-
-  return true;
-}
-
 static GElf_Rela *
 get_rel_or_rela (Elf_Data *data, int ndx,
                 GElf_Rela *dst, size_t type)
index fd6183bede8010446c60df307eb449bb127b9c6e..ee345aa6d216b9638e1910b52e28a8591481cace 100644 (file)
@@ -156,13 +156,6 @@ extern "C"
   extern bool check_line_structural (struct elf_file *file,
                                     struct sec *sec,
                                     struct addr_record *line_tables);
-  extern bool check_location_expression (struct elf_file *file,
-                                        struct read_ctx *parent_ctx,
-                                        struct cu *cu,
-                                        uint64_t init_off,
-                                        struct relocation_data *reloc,
-                                        size_t length,
-                                        struct where *wh);
   extern void check_range_relocations (enum message_category cat,
                                       struct where *where,
                                       struct elf_file *file,
@@ -175,28 +168,6 @@ extern "C"
   extern int check_sibling_form (dwarf_version_h ver, uint64_t form);
   extern bool is_location_attrib (uint64_t name);
 
-  struct hole_info
-  {
-    enum section_id section;
-    enum message_category category;
-    void *data;
-    unsigned align;
-  };
-
-  /* DATA has to be a pointer to an instance of struct hole_info.
-     DATA->data has to point at d_buf of section in question.  */
-  bool found_hole (uint64_t begin, uint64_t end, void *data);
-
-  struct coverage_map_hole_info
-  {
-    struct elf_file *elf;
-    struct hole_info info;
-  };
-
-  /* DATA has to be a pointer to an instance of struct hole_info.
-     DATA->info.data has to be NULL, it is used by the callback.  */
-  bool coverage_map_found_hole (uint64_t begin, uint64_t end,
-                               struct section_coverage *sco, void *data);
   bool checked_read_uleb128 (struct read_ctx *ctx, uint64_t *ret,
                             struct where *where, const char *what);
   bool checked_read_sleb128 (struct read_ctx *ctx, int64_t *ret,
index 741b7a2ab5a4bf64c7456a28d2d59ca988a8262d..166428f1363ccf3998ccbe3da50f416d8ee8b197 100644 (file)
@@ -20,6 +20,10 @@ pri::tag::tag (int die_tag)
   : pribase (dwarf_tag_string (die_tag))
 {}
 
+pri::locexpr_opcode::locexpr_opcode (int opcode)
+  : pribase (dwarf_locexpr_opcode_string (opcode))
+{}
+
 std::ostream &
 pri::operator << (std::ostream &os, pri::ref const &obj)
 {
index 5e49e02135640bb4114126d62191beb0bfd5a238..ccdbb1ec47206b7318b350e80e980aab80975e6e 100644 (file)
@@ -54,6 +54,12 @@ namespace pri
     tag (int tag);
   };
 
+  struct locexpr_opcode
+    : public pribase
+  {
+    locexpr_opcode (int opcode);
+  };
+
   class ref
   {
     Dwarf_Off off;