PR binutils/15205
authorNick Clifton <nickc@redhat.com>
Tue, 26 Mar 2013 22:51:12 +0000 (22:51 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 26 Mar 2013 22:51:12 +0000 (22:51 +0000)
* dwarf.c (SAFE_BYTE_GET): New macro - checks remaining buffer
space before calling byte_get.
(SAFE_BYTE_GET_AND_INC): New macro.
(SAFE_SIGNED_BYTE_GET): New macro.
(SAFE_SIGNED_BYTE_GET_AND_INC): New macro.
(SAFE_BYTE_GET64): New macro.
(process_extened_line_op): Use new macros.  Use strnlen when
appropriate.
(fetch_indirect_string): Likewise.
(get_FORM_name): Likewise.
(decode_location_expression): Likewise.
(read_and_display_attr_value): Likewise.
(process_debug_info): Likewise.
(display_debug_lines_raw): Likewise.
(display_debug_lines_decoded): Likewise.
(display_debug_pubnames): Likewise.
(display_debug_macinfo): Likewise.
(get_line_filename_and_dirname): Likewise.
(display_debug_macro): Likewise.
(display_loc_list): Likewise.
(display_loc_list_dwo): Likewise.
(display_debug_aranges): Likewise.
(display_debug_ranges): Likewise.
(frame_display_row): Likewise.
(display_debug_frames): Likewise.

binutils/ChangeLog
binutils/dwarf.c

index ebede029adbd8d59486f304f6ff01096141d0343..35233c11485842dfb32641b192c6c89dbda66385 100644 (file)
@@ -1,3 +1,32 @@
+2013-03-26  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/15205
+       * dwarf.c (SAFE_BYTE_GET): New macro - checks remaining buffer
+       space before calling byte_get.
+       (SAFE_BYTE_GET_AND_INC): New macro.
+       (SAFE_SIGNED_BYTE_GET): New macro.
+       (SAFE_SIGNED_BYTE_GET_AND_INC): New macro.
+       (SAFE_BYTE_GET64): New macro.
+       (process_extened_line_op): Use new macros.  Use strnlen when
+       appropriate.
+       (fetch_indirect_string): Likewise.
+       (get_FORM_name): Likewise.
+       (decode_location_expression): Likewise.
+       (read_and_display_attr_value): Likewise.
+       (process_debug_info): Likewise.
+       (display_debug_lines_raw): Likewise.
+       (display_debug_lines_decoded): Likewise.
+       (display_debug_pubnames): Likewise.
+       (display_debug_macinfo): Likewise.
+       (get_line_filename_and_dirname): Likewise.
+       (display_debug_macro): Likewise.
+       (display_loc_list): Likewise.
+       (display_loc_list_dwo): Likewise.
+       (display_debug_aranges): Likewise.
+       (display_debug_ranges): Likewise.
+       (frame_display_row): Likewise.
+       (display_debug_frames): Likewise.
+
 2013-03-25  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/15202
index 4a11aa5c5da9bdadf375f10a2eb84b6c15e945c4..24a5906f8468d9d1c40f3b0821dbb082cd3b74ef 100644 (file)
@@ -278,6 +278,73 @@ read_uleb128 (unsigned char * data,
   return read_leb128 (data, length_return, FALSE, end);
 }
 
+#define SAFE_BYTE_GET(VAL, PTR, AMOUNT, END)   \
+  do                                           \
+    {                                          \
+      unsigned int amount = (AMOUNT);          \
+      if (((PTR) + amount) >= (END))           \
+       {                                       \
+         if ((PTR) < (END))                    \
+           amount = (END) - (PTR);             \
+         else                                  \
+           amount = 0;                         \
+       }                                       \
+      if (amount)                              \
+       VAL = byte_get ((PTR), amount);         \
+      else                                     \
+       VAL = 0;                                \
+    }                                          \
+  while (0)
+
+#define SAFE_BYTE_GET_AND_INC(VAL, PTR, AMOUNT, END)   \
+  do                                                   \
+    {                                                  \
+      SAFE_BYTE_GET (VAL, PTR, AMOUNT, END);           \
+      PTR += AMOUNT;                                   \
+    }                                                  \
+  while (0)
+
+#define SAFE_SIGNED_BYTE_GET(VAL, PTR, AMOUNT, END)    \
+  do                                                   \
+    {                                                  \
+      unsigned int amount = (AMOUNT);                  \
+      if (((PTR) + amount) >= (END))                   \
+       {                                               \
+         if ((PTR) < (END))                            \
+           amount = (END) - (PTR);                     \
+         else                                          \
+           amount = 0;                                 \
+       }                                               \
+      if (amount)                                      \
+       VAL = byte_get_signed ((PTR), amount);          \
+      else                                             \
+       VAL = 0;                                        \
+    }                                                  \
+  while (0)
+
+#define SAFE_SIGNED_BYTE_GET_AND_INC(VAL, PTR, AMOUNT, END)    \
+  do                                                           \
+    {                                                          \
+      SAFE_SIGNED_BYTE_GET (VAL, PTR, AMOUNT, END);            \
+      PTR += AMOUNT;                                           \
+    }                                                          \
+  while (0)
+
+#define SAFE_BYTE_GET64(PTR, HIGH, LOW, END)           \
+  do                                                   \
+    {                                                  \
+      if (((PTR) + 8) < (END))                         \
+       {                                               \
+         byte_get_64 ((PTR), (HIGH), (LOW));           \
+       }                                               \
+      else                                             \
+       {                                               \
+         PTR = END;                                    \
+         * (LOW) = * (HIGH) = 0;                       \
+       }                                               \
+    }                                                  \
+  while (0)
+
 typedef struct State_Machine_Registers
 {
   dwarf_vma address;
@@ -346,7 +413,7 @@ process_extended_line_op (unsigned char * data,
       break;
 
     case DW_LNE_set_address:
-      adr = byte_get (data, len - bytes_read - 1);
+      SAFE_BYTE_GET (adr, data, len - bytes_read - 1, end);
       printf (_("set Address to 0x%s\n"), dwarf_vmatoa ("x", adr));
       state_machine_regs.address = adr;
       state_machine_regs.op_index = 0;
@@ -358,7 +425,7 @@ process_extended_line_op (unsigned char * data,
       printf ("   %d\t", ++state_machine_regs.last_file_entry);
 
       name = data;
-      data += strlen ((char *) data) + 1;
+      data += strnlen ((char *) data, end - data) + 1;
       printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
       data += bytes_read;
       printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
@@ -478,13 +545,13 @@ process_extended_line_op (unsigned char * data,
   return len;
 }
 
-static const char *
+static const unsigned char *
 fetch_indirect_string (dwarf_vma offset)
 {
   struct dwarf_section *section = &debug_displays [str].section;
 
   if (section->start == NULL)
-    return _("<no .debug_str section>");
+    return (const unsigned char *) _("<no .debug_str section>");
 
   /* DWARF sections under Mach-O have non-zero addresses.  */
   offset -= section->address;
@@ -492,10 +559,10 @@ fetch_indirect_string (dwarf_vma offset)
     {
       warn (_("DW_FORM_strp offset too big: %s\n"),
            dwarf_vmatoa ("x", offset));
-      return _("<offset is too big>");
+      return (const unsigned char *) _("<offset is too big>");
     }
 
-  return (const char *) section->start + offset;
+  return (const unsigned char *) section->start + offset;
 }
 
 static const char *
@@ -757,10 +824,17 @@ get_FORM_name (unsigned long form)
 }
 
 static unsigned char *
-display_block (unsigned char *data, dwarf_vma length)
+display_block (unsigned char *data,
+              dwarf_vma length,
+              const unsigned char * const end)
 {
+  dwarf_vma maxlen;
+
   printf (_(" %s byte block: "), dwarf_vmatoa ("u", length));
 
+  maxlen = (dwarf_vma) (end - data);
+  length = length > maxlen ? maxlen : length;
+
   while (length --)
     printf ("%lx ", (unsigned long) byte_get (data++, 1));
 
@@ -779,6 +853,7 @@ decode_location_expression (unsigned char * data,
   unsigned op;
   unsigned int bytes_read;
   dwarf_vma uvalue;
+  dwarf_signed_vma svalue;
   unsigned char *end = data + length;
   int need_frame_base = 0;
 
@@ -789,44 +864,47 @@ decode_location_expression (unsigned char * data,
       switch (op)
        {
        case DW_OP_addr:
-         printf ("DW_OP_addr: %s",
-                 dwarf_vmatoa ("x", byte_get (data, pointer_size)));
-         data += pointer_size;
+         SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
+         printf ("DW_OP_addr: %s", dwarf_vmatoa ("x", uvalue));
          break;
        case DW_OP_deref:
          printf ("DW_OP_deref");
          break;
        case DW_OP_const1u:
-         printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+         printf ("DW_OP_const1u: %lu", (unsigned long) uvalue);
          break;
        case DW_OP_const1s:
-         printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1));
+         SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 1, end);
+         printf ("DW_OP_const1s: %ld", (long) svalue);
          break;
        case DW_OP_const2u:
-         printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
-         data += 2;
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+         printf ("DW_OP_const2u: %lu", (unsigned long) uvalue);
          break;
        case DW_OP_const2s:
-         printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2));
-         data += 2;
+         SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 2, end);
+         printf ("DW_OP_const2s: %ld", (long) svalue);
          break;
        case DW_OP_const4u:
-         printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
-         data += 4;
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
+         printf ("DW_OP_const4u: %lu", (unsigned long) uvalue);
          break;
        case DW_OP_const4s:
-         printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4));
-         data += 4;
+         SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 4, end);
+         printf ("DW_OP_const4s: %ld", (long) svalue);
          break;
        case DW_OP_const8u:
-         printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
-                 (unsigned long) byte_get (data + 4, 4));
-         data += 8;
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
+         printf ("DW_OP_const8u: %lu ", (unsigned long) uvalue);
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
+         printf ("%lu", (unsigned long) uvalue);
          break;
        case DW_OP_const8s:
-         printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
-                 (long) byte_get (data + 4, 4));
-         data += 8;
+         SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 4, end);
+         printf ("DW_OP_const8s: %ld ", (long) svalue);
+         SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 4, end);
+         printf ("%ld", (long) svalue);
          break;
        case DW_OP_constu:
          printf ("DW_OP_constu: %s",
@@ -848,7 +926,8 @@ decode_location_expression (unsigned char * data,
          printf ("DW_OP_over");
          break;
        case DW_OP_pick:
-         printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+         printf ("DW_OP_pick: %ld", (unsigned long) uvalue);
          break;
        case DW_OP_swap:
          printf ("DW_OP_swap");
@@ -907,8 +986,8 @@ decode_location_expression (unsigned char * data,
          printf ("DW_OP_xor");
          break;
        case DW_OP_bra:
-         printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2));
-         data += 2;
+         SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 2, end);
+         printf ("DW_OP_bra: %ld", (long) svalue);
          break;
        case DW_OP_eq:
          printf ("DW_OP_eq");
@@ -929,8 +1008,8 @@ decode_location_expression (unsigned char * data,
          printf ("DW_OP_ne");
          break;
        case DW_OP_skip:
-         printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2));
-         data += 2;
+         SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 2, end);
+         printf ("DW_OP_skip: %ld", (long) svalue);
          break;
 
        case DW_OP_lit0:
@@ -1069,10 +1148,12 @@ decode_location_expression (unsigned char * data,
          data += bytes_read;
          break;
        case DW_OP_deref_size:
-         printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+         printf ("DW_OP_deref_size: %ld", (long) uvalue);
          break;
        case DW_OP_xderef_size:
-         printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+         printf ("DW_OP_xderef_size: %ld", (long) uvalue);
          break;
        case DW_OP_nop:
          printf ("DW_OP_nop");
@@ -1085,18 +1166,16 @@ decode_location_expression (unsigned char * data,
        case DW_OP_call2:
          /* XXX: Strictly speaking for 64-bit DWARF3 files
             this ought to be an 8-byte wide computation.  */
+         SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 2, end);
          printf ("DW_OP_call2: <0x%s>",
-                 dwarf_vmatoa ("x", (dwarf_signed_vma) byte_get (data, 2)
-                                    + cu_offset));
-         data += 2;
+                 dwarf_vmatoa ("x", svalue + cu_offset));
          break;
        case DW_OP_call4:
          /* XXX: Strictly speaking for 64-bit DWARF3 files
             this ought to be an 8-byte wide computation.  */
+         SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 4, end);
          printf ("DW_OP_call4: <0x%s>",
-                 dwarf_vmatoa ("x", (dwarf_signed_vma) byte_get (data, 4)
-                                    + cu_offset));
-         data += 4;
+                 dwarf_vmatoa ("x", svalue + cu_offset));
          break;
        case DW_OP_call_ref:
          /* XXX: Strictly speaking for 64-bit DWARF3 files
@@ -1109,16 +1188,13 @@ decode_location_expression (unsigned char * data,
            }
          if (dwarf_version == 2)
            {
-             printf ("DW_OP_call_ref: <0x%s>",
-                     dwarf_vmatoa ("x", byte_get (data, pointer_size)));
-             data += pointer_size;
+             SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
            }
          else
            {
-             printf ("DW_OP_call_ref: <0x%s>",
-                     dwarf_vmatoa ("x", byte_get (data, offset_size)));
-             data += offset_size;
+             SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
            }
+         printf ("DW_OP_call_ref: <0x%s>", dwarf_vmatoa ("x", uvalue));
          break;
        case DW_OP_form_tls_address:
          printf ("DW_OP_form_tls_address");
@@ -1145,7 +1221,7 @@ decode_location_expression (unsigned char * data,
          printf ("DW_OP_implicit_value");
          uvalue = read_uleb128 (data, &bytes_read, end);
          data += bytes_read;
-         display_block (data, uvalue);
+         display_block (data, uvalue, end);
          data += uvalue;
          break;
 
@@ -1181,20 +1257,17 @@ decode_location_expression (unsigned char * data,
            }
          if (dwarf_version == 2)
            {
-             printf ("DW_OP_GNU_implicit_pointer: <0x%s> %s",
-                     dwarf_vmatoa ("x", byte_get (data, pointer_size)),
-                     dwarf_vmatoa ("d", read_sleb128 (data + pointer_size,
-                                                      &bytes_read, end)));
-             data += pointer_size + bytes_read;
+             SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
            }
          else
            {
-             printf ("DW_OP_GNU_implicit_pointer: <0x%s> %s",
-                     dwarf_vmatoa ("x", byte_get (data, offset_size)),
-                     dwarf_vmatoa ("d", read_sleb128 (data + offset_size,
-                                                      &bytes_read, end)));
-             data += offset_size + bytes_read;
+             SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
            }
+         printf ("DW_OP_GNU_implicit_pointer: <0x%s> %s",
+                 dwarf_vmatoa ("x", uvalue),
+                 dwarf_vmatoa ("d", read_sleb128 (data,
+                                                  &bytes_read, end)));
+         data += bytes_read;
          break;
        case DW_OP_GNU_entry_value:
          uvalue = read_uleb128 (data, &bytes_read, end);
@@ -1212,8 +1285,8 @@ decode_location_expression (unsigned char * data,
          data += bytes_read;
          printf ("DW_OP_GNU_const_type: <0x%s> ",
                  dwarf_vmatoa ("x", cu_offset + uvalue));
-         uvalue = byte_get (data++, 1);
-         display_block (data, uvalue);
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+         display_block (data, uvalue, end);
          data += uvalue;
          break;
        case DW_OP_GNU_regval_type:
@@ -1226,7 +1299,8 @@ decode_location_expression (unsigned char * data,
          printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue));
          break;
        case DW_OP_GNU_deref_type:
-         printf ("DW_OP_GNU_deref_type: %ld", (long) byte_get (data++, 1));
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+         printf ("DW_OP_GNU_deref_type: %ld", (long) uvalue);
          uvalue = read_uleb128 (data, &bytes_read, end);
          data += bytes_read;
          printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue));
@@ -1244,9 +1318,9 @@ decode_location_expression (unsigned char * data,
                  dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0));
          break;
        case DW_OP_GNU_parameter_ref:
+         SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
          printf ("DW_OP_GNU_parameter_ref: <0x%s>",
-                 dwarf_vmatoa ("x", cu_offset + byte_get (data, 4)));
-         data += 4;
+                 dwarf_vmatoa ("x", cu_offset + uvalue));
          break;
         case DW_OP_GNU_addr_index:
           uvalue = read_uleb128 (data, &bytes_read, end);
@@ -1363,6 +1437,12 @@ read_and_display_attr_value (unsigned long attribute,
   unsigned char * orig_data = data;
   unsigned int bytes_read;
 
+  if (data == end)
+    {
+      warn (_("corrupt attribute\n"));
+      return data;
+    }
+
   switch (form)
     {
     default:
@@ -1370,31 +1450,23 @@ read_and_display_attr_value (unsigned long attribute,
 
     case DW_FORM_ref_addr:
       if (dwarf_version == 2)
-       {
-         uvalue = byte_get (data, pointer_size);
-         data += pointer_size;
-       }
+       SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
       else if (dwarf_version == 3 || dwarf_version == 4)
-       {
-         uvalue = byte_get (data, offset_size);
-         data += offset_size;
-       }
+       SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
       else
        error (_("Internal error: DWARF version is not 2, 3 or 4.\n"));
 
       break;
 
     case DW_FORM_addr:
-      uvalue = byte_get (data, pointer_size);
-      data += pointer_size;
+      SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
       break;
 
     case DW_FORM_strp:
     case DW_FORM_sec_offset:
     case DW_FORM_GNU_ref_alt:
     case DW_FORM_GNU_strp_alt:
-      uvalue = byte_get (data, offset_size);
-      data += offset_size;
+      SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
       break;
 
     case DW_FORM_flag_present:
@@ -1404,19 +1476,17 @@ read_and_display_attr_value (unsigned long attribute,
     case DW_FORM_ref1:
     case DW_FORM_flag:
     case DW_FORM_data1:
-      uvalue = byte_get (data++, 1);
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
       break;
 
     case DW_FORM_ref2:
     case DW_FORM_data2:
-      uvalue = byte_get (data, 2);
-      data += 2;
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
       break;
 
     case DW_FORM_ref4:
     case DW_FORM_data4:
-      uvalue = byte_get (data, 4);
-      data += 4;
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
       break;
 
     case DW_FORM_sdata:
@@ -1495,25 +1565,28 @@ read_and_display_attr_value (unsigned long attribute,
          dwarf_vma high_bits;
          char buf[64];
 
-         byte_get_64 (data, &high_bits, &uvalue);
+         SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
+
          printf (" 0x%s",
                  dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
        }
+
       if ((do_loc || do_debug_loc || do_debug_ranges)
          && num_debug_info_entries == 0)
        {
          if (sizeof (uvalue) == 8)
-           uvalue = byte_get (data, 8);
+           SAFE_BYTE_GET (uvalue, data, 8, end);
          else
            error (_("DW_FORM_data8 is unsupported when sizeof (dwarf_vma) != 8\n"));
        }
+
       data += 8;
       break;
 
     case DW_FORM_string:
       if (!do_loc)
-       printf (" %s", data);
-      data += strlen ((char *) data) + 1;
+       printf (" %.*s", end - data, data);
+      data += strnlen ((char *) data, end - data) + 1;
       break;
 
     case DW_FORM_block:
@@ -1523,34 +1596,34 @@ read_and_display_attr_value (unsigned long attribute,
       if (do_loc)
        data = block_start + uvalue;
       else
-       data = display_block (block_start, uvalue);
+       data = display_block (block_start, uvalue, end);
       break;
 
     case DW_FORM_block1:
-      uvalue = byte_get (data, 1);
+      SAFE_BYTE_GET (uvalue, data, 1, end);
       block_start = data + 1;
       if (do_loc)
        data = block_start + uvalue;
       else
-       data = display_block (block_start, uvalue);
+       data = display_block (block_start, uvalue, end);
       break;
 
     case DW_FORM_block2:
-      uvalue = byte_get (data, 2);
+      SAFE_BYTE_GET (uvalue, data, 2, end);
       block_start = data + 2;
       if (do_loc)
        data = block_start + uvalue;
       else
-       data = display_block (block_start, uvalue);
+       data = display_block (block_start, uvalue, end);
       break;
 
     case DW_FORM_block4:
-      uvalue = byte_get (data, 4);
+      SAFE_BYTE_GET (uvalue, data, 4, end);
       block_start = data + 4;
       if (do_loc)
        data = block_start + uvalue;
       else
-       data = display_block (block_start, uvalue);
+       data = display_block (block_start, uvalue, end);
       break;
 
     case DW_FORM_strp:
@@ -1588,7 +1661,7 @@ read_and_display_attr_value (unsigned long attribute,
          dwarf_vma high_bits;
          char buf[64];
 
-         byte_get_64 (data, &high_bits, &uvalue);
+         SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
          printf (" signature: 0x%s",
                  dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
        }
@@ -2045,11 +2118,11 @@ process_debug_info (struct dwarf_section *section,
          /* Read the first 4 bytes.  For a 32-bit DWARF section, this
             will be the length.  For a 64-bit DWARF section, it'll be
             the escape code 0xffffffff followed by an 8 byte length.  */
-         length = byte_get (section_begin, 4);
+         SAFE_BYTE_GET (length, section_begin, 4, end);
 
          if (length == 0xffffffff)
            {
-             length = byte_get (section_begin + 4, 8);
+             SAFE_BYTE_GET (length, section_begin + 4, 8, end);
              section_begin += length + 12;
            }
          else if (length >= 0xfffffff0 && length < 0xffffffff)
@@ -2127,13 +2200,11 @@ process_debug_info (struct dwarf_section *section,
 
       hdrptr = start;
 
-      compunit.cu_length = byte_get (hdrptr, 4);
-      hdrptr += 4;
+      SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 4, end);
 
       if (compunit.cu_length == 0xffffffff)
        {
-         compunit.cu_length = byte_get (hdrptr, 8);
-         hdrptr += 8;
+         SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 8, end);
          offset_size = 8;
          initial_length_size = 12;
        }
@@ -2143,15 +2214,13 @@ process_debug_info (struct dwarf_section *section,
          initial_length_size = 4;
        }
 
-      compunit.cu_version = byte_get (hdrptr, 2);
-      hdrptr += 2;
+      SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end);
 
       cu_offset = start - section_begin;
 
       this_set = find_cu_tu_set_v2 (cu_offset, do_types);
 
-      compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
-      hdrptr += offset_size;
+      SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size, end);
 
       if (this_set == NULL)
        {
@@ -2164,15 +2233,12 @@ process_debug_info (struct dwarf_section *section,
          abbrev_size = this_set->section_sizes [DW_SECT_ABBREV];
        }
 
-      compunit.cu_pointer_size = byte_get (hdrptr, 1);
-      hdrptr += 1;
+      SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end);
 
       if (do_types)
         {
-          byte_get_64 (hdrptr, &signature_high, &signature_low);
-          hdrptr += 8;
-          type_offset = byte_get (hdrptr, offset_size);
-          hdrptr += offset_size;
+         SAFE_BYTE_GET64 (hdrptr, &signature_high, &signature_low, end);
+         SAFE_BYTE_GET_AND_INC (type_offset, hdrptr, offset_size, end);
         }
 
       if ((do_loc || do_debug_loc || do_debug_ranges)
@@ -2498,14 +2564,12 @@ display_debug_lines_raw (struct dwarf_section *section,
       hdroff = hdrptr - start;
 
       /* Check the length of the block.  */
-      linfo.li_length = byte_get (hdrptr, 4);
-      hdrptr += 4;
+      SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 4, end);
 
       if (linfo.li_length == 0xffffffff)
        {
          /* This section is 64-bit DWARF 3.  */
-         linfo.li_length = byte_get (hdrptr, 8);
-         hdrptr += 8;
+         SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 8, end);
          offset_size = 8;
          initial_length_size = 12;
        }
@@ -2524,8 +2588,7 @@ display_debug_lines_raw (struct dwarf_section *section,
        }
 
       /* Check its version number.  */
-      linfo.li_version = byte_get (hdrptr, 2);
-      hdrptr += 2;
+      SAFE_BYTE_GET_AND_INC (linfo.li_version, hdrptr, 2, end);
       if (linfo.li_version != 2
          && linfo.li_version != 3
          && linfo.li_version != 4)
@@ -2534,14 +2597,13 @@ display_debug_lines_raw (struct dwarf_section *section,
          return 0;
        }
 
-      linfo.li_prologue_length = byte_get (hdrptr, offset_size);
-      hdrptr += offset_size;
-      linfo.li_min_insn_length = byte_get (hdrptr, 1);
-      hdrptr++;
+      SAFE_BYTE_GET_AND_INC (linfo.li_prologue_length, hdrptr, offset_size, end);
+      SAFE_BYTE_GET_AND_INC (linfo.li_min_insn_length, hdrptr, 1, end);
+
       if (linfo.li_version >= 4)
        {
-         linfo.li_max_ops_per_insn = byte_get (hdrptr, 1);
-         hdrptr++;
+         SAFE_BYTE_GET_AND_INC (linfo.li_max_ops_per_insn, hdrptr, 1, end);
+
          if (linfo.li_max_ops_per_insn == 0)
            {
              warn (_("Invalid maximum operations per insn.\n"));
@@ -2550,14 +2612,11 @@ display_debug_lines_raw (struct dwarf_section *section,
        }
       else
        linfo.li_max_ops_per_insn = 1;
-      linfo.li_default_is_stmt = byte_get (hdrptr, 1);
-      hdrptr++;
-      linfo.li_line_base = byte_get (hdrptr, 1);
-      hdrptr++;
-      linfo.li_line_range = byte_get (hdrptr, 1);
-      hdrptr++;
-      linfo.li_opcode_base = byte_get (hdrptr, 1);
-      hdrptr++;
+
+      SAFE_BYTE_GET_AND_INC (linfo.li_default_is_stmt, hdrptr, 1, end);
+      SAFE_BYTE_GET_AND_INC (linfo.li_line_base, hdrptr, 1, end);
+      SAFE_BYTE_GET_AND_INC (linfo.li_line_range, hdrptr, 1, end);
+      SAFE_BYTE_GET_AND_INC (linfo.li_opcode_base, hdrptr, 1, end);
 
       /* Sign extend the line base field.  */
       linfo.li_line_base <<= 24;
@@ -2600,7 +2659,7 @@ display_debug_lines_raw (struct dwarf_section *section,
            {
              printf ("  %s\n", data);
 
-             data += strlen ((char *) data) + 1;
+             data += strnlen ((char *) data, end - data) + 1;
            }
        }
 
@@ -2622,7 +2681,7 @@ display_debug_lines_raw (struct dwarf_section *section,
 
              printf ("  %d\t", ++state_machine_regs.last_file_entry);
              name = data;
-             data += strlen ((char *) data) + 1;
+             data += strnlen ((char *) data, end - data) + 1;
 
              printf ("%s\t",
                      dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
@@ -2792,8 +2851,7 @@ display_debug_lines_raw (struct dwarf_section *section,
              break;
 
            case DW_LNS_fixed_advance_pc:
-             uladv = byte_get (data, 2);
-             data += 2;
+             SAFE_BYTE_GET_AND_INC (uladv, data, 2, end);
              state_machine_regs.address += uladv;
              state_machine_regs.op_index = 0;
              printf (_("  Advance PC by fixed size amount %s to 0x%s\n"),
@@ -2874,14 +2932,12 @@ display_debug_lines_decoded (struct dwarf_section *section,
         (section 6.2.4 in the Dwarf3 doc).  */
 
       /* Get the length of this CU's line number information block.  */
-      linfo.li_length = byte_get (hdrptr, 4);
-      hdrptr += 4;
+      SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 4, end);
 
       if (linfo.li_length == 0xffffffff)
         {
           /* This section is 64-bit DWARF 3.  */
-          linfo.li_length = byte_get (hdrptr, 8);
-          hdrptr += 8;
+         SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 8, end);
           offset_size = 8;
           initial_length_size = 12;
         }
@@ -2899,8 +2955,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
         }
 
       /* Get this CU's Line Number Block version number.  */
-      linfo.li_version = byte_get (hdrptr, 2);
-      hdrptr += 2;
+      SAFE_BYTE_GET_AND_INC (linfo.li_version, hdrptr, 2, end);
       if (linfo.li_version != 2
          && linfo.li_version != 3
          && linfo.li_version != 4)
@@ -2910,14 +2965,12 @@ display_debug_lines_decoded (struct dwarf_section *section,
           return 0;
         }
 
-      linfo.li_prologue_length = byte_get (hdrptr, offset_size);
-      hdrptr += offset_size;
-      linfo.li_min_insn_length = byte_get (hdrptr, 1);
-      hdrptr++;
+      SAFE_BYTE_GET_AND_INC (linfo.li_prologue_length, hdrptr, offset_size, end);
+      SAFE_BYTE_GET_AND_INC (linfo.li_min_insn_length, hdrptr, 1, end);
+
       if (linfo.li_version >= 4)
        {
-         linfo.li_max_ops_per_insn = byte_get (hdrptr, 1);
-         hdrptr++;
+         SAFE_BYTE_GET_AND_INC (linfo.li_max_ops_per_insn, hdrptr, 1, end);
          if (linfo.li_max_ops_per_insn == 0)
            {
              warn (_("Invalid maximum operations per insn.\n"));
@@ -2926,14 +2979,11 @@ display_debug_lines_decoded (struct dwarf_section *section,
        }
       else
        linfo.li_max_ops_per_insn = 1;
-      linfo.li_default_is_stmt = byte_get (hdrptr, 1);
-      hdrptr++;
-      linfo.li_line_base = byte_get (hdrptr, 1);
-      hdrptr++;
-      linfo.li_line_range = byte_get (hdrptr, 1);
-      hdrptr++;
-      linfo.li_opcode_base = byte_get (hdrptr, 1);
-      hdrptr++;
+
+      SAFE_BYTE_GET_AND_INC (linfo.li_default_is_stmt, hdrptr, 1, end);
+      SAFE_BYTE_GET_AND_INC (linfo.li_line_base, hdrptr, 1, end);
+      SAFE_BYTE_GET_AND_INC (linfo.li_line_range, hdrptr, 1, end);
+      SAFE_BYTE_GET_AND_INC (linfo.li_opcode_base, hdrptr, 1, end);
 
       /* Sign extend the line base field.  */
       linfo.li_line_base <<= 24;
@@ -2955,7 +3005,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
 
          while (*data != 0)
            {
-             data += strlen ((char *) data) + 1;
+             data += strnlen ((char *) data, end - data) + 1;
              n_directories++;
            }
 
@@ -2967,7 +3017,8 @@ display_debug_lines_decoded (struct dwarf_section *section,
           while (*ptr_directory_table != 0)
             {
               directory_table[i] = ptr_directory_table;
-              ptr_directory_table += strlen ((char *) ptr_directory_table) + 1;
+              ptr_directory_table += strnlen ((char *) ptr_directory_table,
+                                             ptr_directory_table - end) + 1;
               i++;
             }
         }
@@ -2985,7 +3036,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
 
               /* Skip Name, directory index, last modification time and length
                  of file.  */
-              data += strlen ((char *) data) + 1;
+              data += strnlen ((char *) data, end - data) + 1;
               read_uleb128 (data, & bytes_read, end);
               data += bytes_read;
               read_uleb128 (data, & bytes_read, end);
@@ -3005,7 +3056,8 @@ display_debug_lines_decoded (struct dwarf_section *section,
               unsigned int bytes_read;
 
               file_table[i].name = ptr_file_name_table;
-              ptr_file_name_table += strlen ((char *) ptr_file_name_table) + 1;
+              ptr_file_name_table += strnlen ((char *) ptr_file_name_table,
+                                             end - ptr_file_name_table) + 1;
 
               /* We are not interested in directory, time or size.  */
               file_table[i].directory_index = read_uleb128 (ptr_file_name_table,
@@ -3030,6 +3082,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
             {
               unsigned int ix = file_table[0].directory_index;
               const char *directory = ix ? (char *)directory_table[ix - 1] : ".";
+
               if (do_wide || strlen (directory) < 76)
                printf (_("CU: %s/%s:\n"), directory, file_table[0].name);
               else
@@ -3103,8 +3156,9 @@ display_debug_lines_decoded (struct dwarf_section *section,
                     reset_state_machine (linfo.li_default_is_stmt);
                     break;
                   case DW_LNE_set_address:
-                    state_machine_regs.address =
-                    byte_get (op_code_data, ext_op_code_len - bytes_read - 1);
+                   SAFE_BYTE_GET_AND_INC (state_machine_regs.address,
+                                          op_code_data, ext_op_code_len - bytes_read - 1,
+                                          end);
                    state_machine_regs.op_index = 0;
                     break;
                   case DW_LNE_define_file:
@@ -3231,8 +3285,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
               break;
 
             case DW_LNS_fixed_advance_pc:
-              uladv = byte_get (data, 2);
-              data += 2;
+             SAFE_BYTE_GET_AND_INC (uladv, data, 2, end);
               state_machine_regs.address += uladv;
              state_machine_regs.op_index = 0;
               break;
@@ -3388,12 +3441,10 @@ display_debug_pubnames (struct dwarf_section *section,
 
       data = start;
 
-      names.pn_length = byte_get (data, 4);
-      data += 4;
+      SAFE_BYTE_GET_AND_INC (names.pn_length, data, 4, end);
       if (names.pn_length == 0xffffffff)
        {
-         names.pn_length = byte_get (data, 8);
-         data += 8;
+         SAFE_BYTE_GET_AND_INC (names.pn_length, data, 8, end);
          offset_size = 8;
          initial_length_size = 12;
        }
@@ -3403,11 +3454,8 @@ display_debug_pubnames (struct dwarf_section *section,
          initial_length_size = 4;
        }
 
-      names.pn_version = byte_get (data, 2);
-      data += 2;
-
-      names.pn_offset = byte_get (data, offset_size);
-      data += offset_size;
+      SAFE_BYTE_GET_AND_INC (names.pn_version, data, 2, end);
+      SAFE_BYTE_GET_AND_INC (names.pn_offset, data, offset_size, end);
 
       if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE
          && num_debug_info_entries > 0
@@ -3415,8 +3463,7 @@ display_debug_pubnames (struct dwarf_section *section,
        warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
              (unsigned long) names.pn_offset, section->name);
 
-      names.pn_size = byte_get (data, offset_size);
-      data += offset_size;
+      SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, end);
 
       start += names.pn_length + initial_length_size;
 
@@ -3446,13 +3493,13 @@ display_debug_pubnames (struct dwarf_section *section,
 
       do
        {
-         offset = byte_get (data, offset_size);
+         SAFE_BYTE_GET (offset, data, offset_size, end);
 
          if (offset != 0)
            {
              data += offset_size;
              printf ("    %-6lx\t%s\n", offset, data);
-             data += strlen ((char *) data) + 1;
+             data += strnlen ((char *) data, end - data) + 1;
            }
        }
       while (offset != 0);
@@ -3477,7 +3524,7 @@ display_debug_macinfo (struct dwarf_section *section,
   while (curr < end)
     {
       unsigned int lineno;
-      const char *string;
+      const unsigned char *string;
 
       op = (enum dwarf_macinfo_record_type) *curr;
       curr++;
@@ -3505,8 +3552,8 @@ display_debug_macinfo (struct dwarf_section *section,
        case DW_MACINFO_define:
          lineno = read_uleb128 (curr, & bytes_read, end);
          curr += bytes_read;
-         string = (char *) curr;
-         curr += strlen (string) + 1;
+         string = curr;
+         curr += strnlen ((char *) string, end - string) + 1;
          printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"),
                  lineno, string);
          break;
@@ -3514,8 +3561,8 @@ display_debug_macinfo (struct dwarf_section *section,
        case DW_MACINFO_undef:
          lineno = read_uleb128 (curr, & bytes_read, end);
          curr += bytes_read;
-         string = (char *) curr;
-         curr += strlen (string) + 1;
+         string = curr;
+         curr += strnlen ((char *) string, end - string) + 1;
          printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"),
                  lineno, string);
          break;
@@ -3526,8 +3573,8 @@ display_debug_macinfo (struct dwarf_section *section,
 
            constant = read_uleb128 (curr, & bytes_read, end);
            curr += bytes_read;
-           string = (char *) curr;
-           curr += strlen (string) + 1;
+           string = curr;
+           curr += strnlen ((char *) string, end - string) + 1;
            printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"),
                    constant, string);
          }
@@ -3562,13 +3609,12 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
 
   hdrptr = section->start + line_offset;
   end = section->start + section->size;
-  length = byte_get (hdrptr, 4);
-  hdrptr += 4;
+
+  SAFE_BYTE_GET_AND_INC (length, hdrptr, 4, end);
   if (length == 0xffffffff)
     {
       /* This section is 64-bit DWARF 3.  */
-      length = byte_get (hdrptr, 8);
-      hdrptr += 8;
+      SAFE_BYTE_GET_AND_INC (length, hdrptr, 8, end);
       offset_size = 8;
       initial_length_size = 12;
     }
@@ -3579,28 +3625,29 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
     }
   if (length + initial_length_size > section->size)
     return NULL;
-  version = byte_get (hdrptr, 2);
-  hdrptr += 2;
+
+  SAFE_BYTE_GET_AND_INC (version, hdrptr, 2, end);
   if (version != 2 && version != 3 && version != 4)
     return NULL;
   hdrptr += offset_size + 1;/* Skip prologue_length and min_insn_length.  */
   if (version >= 4)
     hdrptr++;              /* Skip max_ops_per_insn.  */
   hdrptr += 3;             /* Skip default_is_stmt, line_base, line_range.  */
-  opcode_base = byte_get (hdrptr, 1);
+
+  SAFE_BYTE_GET_AND_INC (opcode_base, hdrptr, 1, end);
   if (opcode_base == 0)
     return NULL;
-  hdrptr++;
+
   hdrptr += opcode_base - 1;
   dirtable = hdrptr;
   /* Skip over dirname table.  */
   while (*hdrptr != '\0')
-    hdrptr += strlen ((char *) hdrptr) + 1;
+    hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
   hdrptr++;                /* Skip the NUL at the end of the table.  */
   /* Now skip over preceding filename table entries.  */
   for (; *hdrptr != '\0' && fileidx > 1; fileidx--)
     {
-      hdrptr += strlen ((char *) hdrptr) + 1;
+      hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
       read_uleb128 (hdrptr, &bytes_read, end);
       hdrptr += bytes_read;
       read_uleb128 (hdrptr, &bytes_read, end);
@@ -3611,12 +3658,12 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
   if (hdrptr == end || *hdrptr == '\0')
     return NULL;
   file_name = hdrptr;
-  hdrptr += strlen ((char *) hdrptr) + 1;
+  hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
   diridx = read_uleb128 (hdrptr, &bytes_read, end);
   if (diridx == 0)
     return file_name;
   for (; *dirtable != '\0' && diridx > 1; diridx--)
-    dirtable += strlen ((char *) dirtable) + 1;
+    dirtable += strnlen ((char *) dirtable, end - dirtable) + 1;
   if (*dirtable == '\0')
     return NULL;
   *dir_name = dirtable;
@@ -3642,13 +3689,11 @@ display_debug_macro (struct dwarf_section *section,
     {
       unsigned int lineno, version, flags;
       unsigned int offset_size = 4;
-      const char *string;
+      const unsigned char *string;
       dwarf_vma line_offset = 0, sec_offset = curr - start, offset;
       unsigned char **extended_ops = NULL;
 
-      version = byte_get (curr, 2);
-      curr += 2;
-
+      SAFE_BYTE_GET_AND_INC (version, curr, 2, end);
       if (version != 4)
        {
          error (_("Only GNU extension to DWARF 4 of %s is currently supported.\n"),
@@ -3656,7 +3701,7 @@ display_debug_macro (struct dwarf_section *section,
          return 0;
        }
 
-      flags = byte_get (curr++, 1);
+      SAFE_BYTE_GET_AND_INC (flags, curr, 1, end);
       if (flags & 1)
        offset_size = 8;
       printf (_("  Offset:                      0x%lx\n"),
@@ -3665,15 +3710,17 @@ display_debug_macro (struct dwarf_section *section,
       printf (_("  Offset size:                 %d\n"), offset_size);
       if (flags & 2)
        {
-         line_offset = byte_get (curr, offset_size);
-         curr += offset_size;
+         SAFE_BYTE_GET_AND_INC (line_offset, curr, offset_size, end);
          printf (_("  Offset into .debug_line:     0x%lx\n"),
                  (unsigned long) line_offset);
        }
       if (flags & 4)
        {
-         unsigned int i, count = byte_get (curr++, 1), op;
+         unsigned int i, count, op;
          dwarf_vma nargs, n;
+
+         SAFE_BYTE_GET_AND_INC (count, curr, 1, end);
+         
          memset (extended_op_buf, 0, sizeof (extended_op_buf));
          extended_ops = extended_op_buf;
          if (count)
@@ -3681,7 +3728,7 @@ display_debug_macro (struct dwarf_section *section,
              printf (_("  Extension opcode arguments:\n"));
              for (i = 0; i < count; i++)
                {
-                 op = byte_get (curr++, 1);
+                 SAFE_BYTE_GET_AND_INC (op, curr, 1, end);
                  extended_ops[op] = curr;
                  nargs = read_uleb128 (curr, &bytes_read, end);
                  curr += bytes_read;
@@ -3692,7 +3739,9 @@ display_debug_macro (struct dwarf_section *section,
                      printf (_("    DW_MACRO_GNU_%02x arguments: "), op);
                      for (n = 0; n < nargs; n++)
                        {
-                         unsigned int form = byte_get (curr++, 1);
+                         unsigned int form;
+
+                         SAFE_BYTE_GET_AND_INC (form, curr, 1, end);
                          printf ("%s%s", get_FORM_name (form),
                                  n == nargs - 1 ? "\n" : ", ");
                          switch (form)
@@ -3734,7 +3783,7 @@ display_debug_macro (struct dwarf_section *section,
              return 0;
            }
 
-         op = byte_get (curr++, 1);
+         SAFE_BYTE_GET_AND_INC (op, curr, 1, end);
          if (op == 0)
            break;
 
@@ -3774,8 +3823,8 @@ display_debug_macro (struct dwarf_section *section,
            case DW_MACRO_GNU_define:
              lineno = read_uleb128 (curr, &bytes_read, end);
              curr += bytes_read;
-             string = (char *) curr;
-             curr += strlen (string) + 1;
+             string = curr;
+             curr += strnlen ((char *) string, end - string) + 1;
              printf (_(" DW_MACRO_GNU_define - lineno : %d macro : %s\n"),
                      lineno, string);
              break;
@@ -3783,8 +3832,8 @@ display_debug_macro (struct dwarf_section *section,
            case DW_MACRO_GNU_undef:
              lineno = read_uleb128 (curr, &bytes_read, end);
              curr += bytes_read;
-             string = (char *) curr;
-             curr += strlen (string) + 1;
+             string = curr;
+             curr += strnlen ((char *) string, end - string) + 1;
              printf (_(" DW_MACRO_GNU_undef - lineno : %d macro : %s\n"),
                      lineno, string);
              break;
@@ -3792,8 +3841,7 @@ display_debug_macro (struct dwarf_section *section,
            case DW_MACRO_GNU_define_indirect:
              lineno = read_uleb128 (curr, &bytes_read, end);
              curr += bytes_read;
-             offset = byte_get (curr, offset_size);
-             curr += offset_size;
+             SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
              string = fetch_indirect_string (offset);
              printf (_(" DW_MACRO_GNU_define_indirect - lineno : %d macro : %s\n"),
                      lineno, string);
@@ -3802,16 +3850,14 @@ display_debug_macro (struct dwarf_section *section,
            case DW_MACRO_GNU_undef_indirect:
              lineno = read_uleb128 (curr, &bytes_read, end);
              curr += bytes_read;
-             offset = byte_get (curr, offset_size);
-             curr += offset_size;
+             SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
              string = fetch_indirect_string (offset);
              printf (_(" DW_MACRO_GNU_undef_indirect - lineno : %d macro : %s\n"),
                      lineno, string);
              break;
 
            case DW_MACRO_GNU_transparent_include:
-             offset = byte_get (curr, offset_size);
-             curr += offset_size;
+             SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
              printf (_(" DW_MACRO_GNU_transparent_include - offset : 0x%lx\n"),
                      (unsigned long) offset);
              break;
@@ -3819,8 +3865,7 @@ display_debug_macro (struct dwarf_section *section,
            case DW_MACRO_GNU_define_indirect_alt:
              lineno = read_uleb128 (curr, &bytes_read, end);
              curr += bytes_read;
-             offset = byte_get (curr, offset_size);
-             curr += offset_size;
+             SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
              printf (_(" DW_MACRO_GNU_define_indirect_alt - lineno : %d macro offset : 0x%lx\n"),
                      lineno, (unsigned long) offset);
              break;
@@ -3828,15 +3873,13 @@ display_debug_macro (struct dwarf_section *section,
            case DW_MACRO_GNU_undef_indirect_alt:
              lineno = read_uleb128 (curr, &bytes_read, end);
              curr += bytes_read;
-             offset = byte_get (curr, offset_size);
-             curr += offset_size;
+             SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
              printf (_(" DW_MACRO_GNU_undef_indirect_alt - lineno : %d macro offset : 0x%lx\n"),
                      lineno, (unsigned long) offset);
              break;
 
            case DW_MACRO_GNU_transparent_include_alt:
-             offset = byte_get (curr, offset_size);
-             curr += offset_size;
+             SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
              printf (_(" DW_MACRO_GNU_transparent_include_alt - offset : 0x%lx\n"),
                      (unsigned long) offset);
              break;
@@ -3862,8 +3905,11 @@ display_debug_macro (struct dwarf_section *section,
                  printf (_(" DW_MACRO_GNU_%02x -"), op);
                  for (n = 0; n < nargs; n++)
                    {
+                     int val;
+
+                     SAFE_BYTE_GET_AND_INC (val, desc, 1, end);
                      curr
-                       = read_and_display_attr_value (0, byte_get (desc++, 1),
+                       = read_and_display_attr_value (0, val,
                                                       curr, end, 0, 0, offset_size,
                                                       version, NULL, 0, NULL,
                                                       NULL);
@@ -3965,10 +4011,8 @@ display_loc_list (struct dwarf_section *section,
          the -1 escape value.  Sign extension into the top 32 bits of a 32-bit
          address will not affect the values that we display since we always show
          hex values, and always the bottom 32-bits.  */
-      begin = byte_get_signed (start, pointer_size);
-      start += pointer_size;
-      end = byte_get_signed (start, pointer_size);
-      start += pointer_size;
+      SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, section_end);
+      SAFE_BYTE_GET_AND_INC (end, start, pointer_size, section_end);
 
       if (begin == 0 && end == 0)
         {
@@ -3993,8 +4037,7 @@ display_loc_list (struct dwarf_section *section,
           break;
         }
 
-      length = byte_get (start, 2);
-      start += 2;
+      SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
 
       if (start + length > section_end)
         {
@@ -4076,8 +4119,7 @@ display_loc_list_dwo (struct dwarf_section *section,
           break;
         }
 
-      entry_type = byte_get (start, 1);
-      start++;
+      SAFE_BYTE_GET_AND_INC (entry_type, start, 1, section_end);
       switch (entry_type)
         {
           case 0: /* A terminating entry.  */
@@ -4103,16 +4145,13 @@ display_loc_list_dwo (struct dwarf_section *section,
             idx = read_uleb128 (start, &bytes_read, section_end);
             start += bytes_read;
             print_addr_index (idx, 8);
-            idx = byte_get (start, 4);
-            start += 4;
+           SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
             printf ("%08x ", idx);
             break;
           case 4: /* An offset pair entry.  */
-            idx = byte_get (start, 4);
-            start += 4;
+           SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
             printf ("%08x ", idx);
-            idx = byte_get (start, 4);
-            start += 4;
+           SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
             printf ("%08x ", idx);
             break;
           default:
@@ -4128,9 +4167,7 @@ display_loc_list_dwo (struct dwarf_section *section,
           break;
         }
 
-      length = byte_get (start, 2);
-      start += 2;
-
+      SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
       if (start + length > section_end)
         {
           warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
@@ -4432,13 +4469,10 @@ display_debug_aranges (struct dwarf_section *section,
 
       hdrptr = start;
 
-      arange.ar_length = byte_get (hdrptr, 4);
-      hdrptr += 4;
-
+      SAFE_BYTE_GET_AND_INC (arange.ar_length, hdrptr, 4, end);
       if (arange.ar_length == 0xffffffff)
        {
-         arange.ar_length = byte_get (hdrptr, 8);
-         hdrptr += 8;
+         SAFE_BYTE_GET_AND_INC (arange.ar_length, hdrptr, 8, end);
          offset_size = 8;
          initial_length_size = 12;
        }
@@ -4448,11 +4482,8 @@ display_debug_aranges (struct dwarf_section *section,
          initial_length_size = 4;
        }
 
-      arange.ar_version = byte_get (hdrptr, 2);
-      hdrptr += 2;
-
-      arange.ar_info_offset = byte_get (hdrptr, offset_size);
-      hdrptr += offset_size;
+      SAFE_BYTE_GET_AND_INC (arange.ar_version, hdrptr, 2, end);
+      SAFE_BYTE_GET_AND_INC (arange.ar_info_offset, hdrptr, offset_size, end);
 
       if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE
          && num_debug_info_entries > 0
@@ -4460,11 +4491,8 @@ display_debug_aranges (struct dwarf_section *section,
        warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
              (unsigned long) arange.ar_info_offset, section->name);
 
-      arange.ar_pointer_size = byte_get (hdrptr, 1);
-      hdrptr += 1;
-
-      arange.ar_segment_size = byte_get (hdrptr, 1);
-      hdrptr += 1;
+      SAFE_BYTE_GET_AND_INC (arange.ar_pointer_size, hdrptr, 1, end);
+      SAFE_BYTE_GET_AND_INC (arange.ar_segment_size, hdrptr, 1, end);
 
       if (arange.ar_version != 2 && arange.ar_version != 3)
        {
@@ -4514,13 +4542,8 @@ display_debug_aranges (struct dwarf_section *section,
 
       while (addr_ranges + 2 * address_size <= start)
        {
-         address = byte_get (addr_ranges, address_size);
-
-         addr_ranges += address_size;
-
-         length  = byte_get (addr_ranges, address_size);
-
-         addr_ranges += address_size;
+         SAFE_BYTE_GET_AND_INC (address, addr_ranges, address_size, end);
+         SAFE_BYTE_GET_AND_INC (length, addr_ranges, address_size, end);
 
          printf ("    ");
          print_dwarf_vma (address, address_size);
@@ -4761,12 +4784,10 @@ display_debug_ranges (struct dwarf_section *section,
             top 32 bits of a 32-bit address will not affect the values
             that we display since we always show hex values, and always
             the bottom 32-bits.  */
-         begin = byte_get_signed (start, pointer_size);
-         start += pointer_size;
+         SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish);
          if (start >= finish)
            break;
-         end = byte_get_signed (start, pointer_size);
-         start += pointer_size;
+         SAFE_SIGNED_BYTE_GET_AND_INC (end, start, pointer_size, finish);
 
          printf ("    %8.8lx ", offset);
 
@@ -5028,7 +5049,7 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
   printf ("\n");
 }
 
-#define GET(N) byte_get (start, N); start += N
+#define GET(VAR, N)    SAFE_BYTE_GET_AND_INC (VAR, start, N, end);
 #define LEB()  read_uleb128 (start, & length_return, end); start += length_return
 #define SLEB() read_sleb128 (start, & length_return, end); start += length_return
 
@@ -5066,8 +5087,8 @@ display_debug_frames (struct dwarf_section *section,
       int initial_length_size;
 
       saved_start = start;
-      length = byte_get (start, 4); start += 4;
 
+      SAFE_BYTE_GET_AND_INC (length, start, 4, end);
       if (length == 0)
        {
          printf ("\n%08lx ZERO terminator\n\n",
@@ -5077,8 +5098,7 @@ display_debug_frames (struct dwarf_section *section,
 
       if (length == 0xffffffff)
        {
-         length = byte_get (start, 8);
-         start += 8;
+         SAFE_BYTE_GET_AND_INC (length, start, 8, end);
          offset_size = 8;
          initial_length_size = 12;
        }
@@ -5095,7 +5115,8 @@ display_debug_frames (struct dwarf_section *section,
                length, (unsigned long)(saved_start - section_start));
          block_end = end;
        }
-      cie_id = byte_get (start, offset_size); start += offset_size;
+
+      SAFE_BYTE_GET_AND_INC (cie_id, start, offset_size, end);
 
       if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
        {
@@ -5122,8 +5143,8 @@ display_debug_frames (struct dwarf_section *section,
 
          if (version >= 4)
            {
-             fc->ptr_size = GET (1);
-             fc->segment_size = GET (1);
+             GET (fc->ptr_size, 1);
+             GET (fc->segment_size, 1);
              eh_addr_size = fc->ptr_size;
            }
          else
@@ -5135,7 +5156,7 @@ display_debug_frames (struct dwarf_section *section,
          fc->data_factor = SLEB ();
          if (version == 1)
            {
-             fc->ra = GET (1);
+             GET (fc->ra, 1);
            }
          else
            {
@@ -5263,14 +5284,17 @@ display_debug_frames (struct dwarf_section *section,
          segment_selector = 0;
          if (fc->segment_size)
            {
-             segment_selector = byte_get (start, fc->segment_size);
-             start += fc->segment_size;
+             SAFE_BYTE_GET_AND_INC (segment_selector, start, fc->segment_size, end);
            }
          fc->pc_begin = get_encoded_value (start, fc->fde_encoding, section);
          start += encoded_ptr_size;
-         fc->pc_range = byte_get (start, encoded_ptr_size);
-         start += encoded_ptr_size;
 
+         /* FIXME: It appears that sometimes the final pc_range value is
+            encoded in less than encoded_ptr_size bytes.  See the x86_64
+            run of the "objcopy on compressed debug sections" test for an
+            example of this.  */
+         SAFE_BYTE_GET_AND_INC (fc->pc_range, start, encoded_ptr_size, end);
+         
          if (cie->augmentation[0] == 'z')
            {
              augmentation_data_len = LEB ();
@@ -5497,7 +5521,7 @@ display_debug_frames (struct dwarf_section *section,
              break;
 
            case DW_CFA_advance_loc1:
-             ofs = byte_get (start, 1); start += 1;
+             SAFE_BYTE_GET_AND_INC (ofs, start, 1, end);
              if (do_debug_frames_interp)
                frame_display_row (fc, &need_col_headers, &max_regs);
              else
@@ -5508,7 +5532,7 @@ display_debug_frames (struct dwarf_section *section,
              break;
 
            case DW_CFA_advance_loc2:
-             ofs = byte_get (start, 2); start += 2;
+             SAFE_BYTE_GET_AND_INC (ofs, start, 2, end);
              if (do_debug_frames_interp)
                frame_display_row (fc, &need_col_headers, &max_regs);
              else
@@ -5519,7 +5543,7 @@ display_debug_frames (struct dwarf_section *section,
              break;
 
            case DW_CFA_advance_loc4:
-             ofs = byte_get (start, 4); start += 4;
+             SAFE_BYTE_GET_AND_INC (ofs, start, 4, end);
              if (do_debug_frames_interp)
                frame_display_row (fc, &need_col_headers, &max_regs);
              else
@@ -5782,7 +5806,7 @@ display_debug_frames (struct dwarf_section *section,
              break;
 
            case DW_CFA_MIPS_advance_loc8:
-             ofs = byte_get (start, 8); start += 8;
+             SAFE_BYTE_GET_AND_INC (ofs, start, 8, end);
              if (do_debug_frames_interp)
                frame_display_row (fc, &need_col_headers, &max_regs);
              else