Revise sleb128 and uleb128 reader

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Revise sleb128 and uleb128 reader

Alan Modra-3
This patch catches and reports errors when reading leb128 values,
addressing a FIXME in read_leb128.

        * dwarf.h (read_leb128): Update prototype.
        (report_leb_status): New inline function.
        (SKIP_ULEB, SKIP_SLEB, READ_ULEB, READ_SLEB): Define.
        * dwarf.c: Use above macros throughout file.  Formatting.
        (read_leb128): Reorder params.  Add status return param.
        Don't stop reading until finding terminator or end of data.
        Detect loss of significant bits.  Sign extend only on
        terminating byte.
        (read_sleb128, read_uleb128): Delete functions.
        (SKIP_ULEB, SKIP_SLEB, READ_ULEB, READ_SLEB): Delete macros.
        (read_and_print_leb128): Rewrite.
        (process_extended_line_op): Return a size_t.  Use size_t vars.
        Adjust to suit new macros.  Add proper name size to "data" when
        processing DW_LNE_define_file.
        (process_abbrev_section): Adjust to suit new macros.
        (decode_location_expression, skip_attr_bytes): Likewise.
        (get_type_signedness): Likewise.
        (read_and_display_attr_value): Likewise.  Consolidate block code.
        (process_debug_info): Adjust to suit new macros.
        (display_formatted_table, display_debug_lines_raw): Likewise.
        (display_debug_lines_decoded): Likewise.  Properly check for end
        of DW_LNS_extended_op.
        (display_debug_macinfo): Adjust to suit new macros.
        (get_line_filename_and_dirname, display_debug_macro): Likewise.
        (display_view_pair_list): Likewise.  Don't back off when hitting
        end of data.
        (display_loc_list): Adjust to suit new macros.
        (display_loclists_list, display_loc_list_dwo): Likewise.
        (display_debug_rnglists_list, read_cie): Likewise.
        (display_debug_frames): Likewise.
        * readelf.c: Use new ULEB macros throughout file.
        (read_uleb128): Delete.
        (decode_arm_unwind_bytecode): Use read_leb128.
        (decode_tic6x_unwind_bytecode): Likewise.
        (display_tag_value): Adjust to suit new macros.
        (display_arc_attribute, display_arm_attribute): Likewise.
        (display_gnu_attribute, display_power_gnu_attribute): Likewise.
        (display_s390_gnu_attribute, display_sparc_gnu_attribute): Likewise.
        (display_mips_gnu_attribute, display_tic6x_attribute): Likewise.
        (display_msp430x_attribute, display_msp430_gnu_attribute): Likewise.
        (display_riscv_attribute, process_attributes): Likewise.

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 06ef1f7285..30abee56c3 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -319,93 +319,56 @@ dwarf_vmatoa64 (dwarf_vma hvalue, dwarf_vma lvalue, char *buf,
 /* Read in a LEB128 encoded value starting at address DATA.
    If SIGN is true, return a signed LEB128 value.
    If LENGTH_RETURN is not NULL, return in it the number of bytes read.
+   If STATUS_RETURN in not NULL, return with bit 0 (LSB) set if the
+   terminating byte was not found and with bit 1 set if the value
+   overflows a dwarf_vma.
    No bytes will be read at address END or beyond.  */
 
 dwarf_vma
 read_leb128 (unsigned char *data,
-     unsigned int *length_return,
+     const unsigned char *const end,
      bfd_boolean sign,
-     const unsigned char * const end)
+     unsigned int *length_return,
+     int *status_return)
 {
   dwarf_vma result = 0;
   unsigned int num_read = 0;
   unsigned int shift = 0;
-  unsigned char byte = 0;
+  int status = 1;
 
   while (data < end)
     {
-      byte = *data++;
+      unsigned char byte = *data++;
       num_read++;
 
-      result |= ((dwarf_vma) (byte & 0x7f)) << shift;
+      if (shift < sizeof (result) * 8)
+ {
+  result |= ((dwarf_vma) (byte & 0x7f)) << shift;
+  if ((result >> shift) != (byte & 0x7f))
+    /* Overflow.  */
+    status |= 2;
+  shift += 7;
+ }
+      else if ((byte & 0x7f) != 0)
+ status |= 2;
 
-      shift += 7;
       if ((byte & 0x80) == 0)
- break;
-
-      /* PR 17512: file: 0ca183b8.
- FIXME: Should we signal this error somehow ?  */
-      if (shift >= sizeof (result) * 8)
- break;
+ {
+  status &= ~1;
+  if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
+    result |= -((dwarf_vma) 1 << shift);
+  break;
+ }
     }
 
   if (length_return != NULL)
     *length_return = num_read;
-
-  if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
-    result |= -((dwarf_vma) 1 << shift);
+  if (status_return != NULL)
+    *status_return = status;
 
   return result;
 }
 
-/* Create a signed version to avoid painful typecasts.  */
-static inline dwarf_signed_vma
-read_sleb128 (unsigned char * data,
-      unsigned int *  length_return,
-      const unsigned char * const end)
-{
-  return (dwarf_signed_vma) read_leb128 (data, length_return, TRUE, end);
-}
-
-static inline dwarf_vma
-read_uleb128 (unsigned char * data,
-      unsigned int *  length_return,
-      const unsigned char * const end)
-{
-  return read_leb128 (data, length_return, FALSE, end);
-}
-
-#define SKIP_ULEB() read_uleb128 (start, & length_return, end); start += length_return
-#define SKIP_SLEB() read_sleb128 (start, & length_return, end); start += length_return
-
-#define READ_ULEB(var) \
-  do \
-    { \
-      dwarf_vma _val; \
- \
-      (var) = _val = read_uleb128 (start, &length_return, end); \
-      if ((var) != _val) \
- error (_("Internal error: %s:%d: LEB value (%s) " \
- "too large for containing variable\n"), \
-       __FILE__, __LINE__, dwarf_vmatoa ("u", _val)); \
-      start += length_return; \
-    } \
-  while (0)
-
-#define READ_SLEB(var) \
-  do \
-    { \
-      dwarf_signed_vma _val; \
- \
-      (var) = _val = read_sleb128 (start, &length_return, end); \
-      if ((var) != _val) \
- error (_("Internal error: %s:%d: LEB value (%s) " \
- "too large for containing variable\n"), \
-       __FILE__, __LINE__, dwarf_vmatoa ("d", _val)); \
-      start += length_return; \
-    } \
-  while (0)
-
 /* Read AMOUNT bytes from PTR and store them in VAL as an unsigned value.
    Checks to make sure that the read will not reach or pass END
    and that VAL is big enough to hold AMOUNT bytes.  */
@@ -524,28 +487,26 @@ reset_state_machine (int is_stmt)
 /* Handled an extend line op.
    Returns the number of bytes read.  */
 
-static int
+static size_t
 process_extended_line_op (unsigned char * data,
   int is_stmt,
   unsigned char * end)
 {
   unsigned char op_code;
-  unsigned int bytes_read;
-  unsigned int len;
+  size_t len, header_len;
   unsigned char *name;
   unsigned char *orig_data = data;
-  dwarf_vma adr;
+  dwarf_vma adr, val;
 
-  len = read_uleb128 (data, & bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (len, data, end);
+  header_len = data - orig_data;
 
-  if (len == 0 || data == end || len > (uintptr_t) (end - data))
+  if (len == 0 || data == end || len > (size_t) (end - data))
     {
       warn (_("Badly formed extended line op encountered!\n"));
-      return bytes_read;
+      return header_len;
     }
 
-  len += bytes_read;
   op_code = *data++;
 
   printf (_("  Extended opcode %d: "), op_code);
@@ -559,14 +520,14 @@ process_extended_line_op (unsigned char * data,
 
     case DW_LNE_set_address:
       /* PR 17512: file: 002-100480-0.004.  */
-      if (len - bytes_read - 1 > 8)
+      if (len - 1 > 8)
  {
-  warn (_("Length (%d) of DW_LNE_set_address op is too long\n"),
- len - bytes_read - 1);
+  warn (_("Length (%lu) of DW_LNE_set_address op is too long\n"),
+ (unsigned long) len - 1);
   adr = 0;
  }
       else
- SAFE_BYTE_GET (adr, data, len - bytes_read - 1, end);
+ SAFE_BYTE_GET (adr, data, len - 1, end);
       printf (_("set Address to 0x%s\n"), dwarf_vmatoa ("x", adr));
       state_machine_regs.address = adr;
       state_machine_regs.view = 0;
@@ -583,23 +544,23 @@ process_extended_line_op (unsigned char * data,
 
  name = data;
  l = strnlen ((char *) data, end - data);
- data += len + 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)));
- data += bytes_read;
- printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
- data += bytes_read;
+ data += l + 1;
+ READ_ULEB (val, data, end);
+ printf ("%s\t", dwarf_vmatoa ("u", val));
+ READ_ULEB (val, data, end);
+ printf ("%s\t", dwarf_vmatoa ("u", val));
+ READ_ULEB (val, data, end);
+ printf ("%s\t", dwarf_vmatoa ("u", val));
  printf ("%.*s\n\n", (int) l, name);
       }
 
-      if (((unsigned int) (data - orig_data) != len) || data == end)
+      if (((size_t) (data - orig_data) != len + header_len) || data == end)
  warn (_("DW_LNE_define_file: Bad opcode length\n"));
       break;
 
     case DW_LNE_set_discriminator:
-      printf (_("set Discriminator to %s\n"),
-      dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
+      READ_ULEB (val, data, end);
+      printf (_("set Discriminator to %s\n"), dwarf_vmatoa ("u", val));
       break;
 
     /* HP extensions.  */
@@ -635,7 +596,7 @@ process_extended_line_op (unsigned char * data,
       break;
     case DW_LNE_HP_source_file_correlation:
       {
- unsigned char *edata = data + len - bytes_read - 1;
+ unsigned char *edata = data + len - 1;
 
  printf ("DW_LNE_HP_source_file_correlation\n");
 
@@ -643,8 +604,7 @@ process_extended_line_op (unsigned char * data,
   {
     unsigned int opc;
 
-    opc = read_uleb128 (data, & bytes_read, edata);
-    data += bytes_read;
+    READ_ULEB (opc, data, edata);
 
     switch (opc)
       {
@@ -652,25 +612,18 @@ process_extended_line_op (unsigned char * data,
  printf ("    DW_LNE_HP_SFC_formfeed\n");
  break;
       case DW_LNE_HP_SFC_set_listing_line:
+ READ_ULEB (val, data, edata);
  printf ("    DW_LNE_HP_SFC_set_listing_line (%s)\n",
- dwarf_vmatoa ("u",
-      read_uleb128 (data, & bytes_read, edata)));
- data += bytes_read;
+ dwarf_vmatoa ("u", val));
  break;
       case DW_LNE_HP_SFC_associate:
  printf ("    DW_LNE_HP_SFC_associate ");
- printf ("(%s",
- dwarf_vmatoa ("u",
-      read_uleb128 (data, & bytes_read, edata)));
- data += bytes_read;
- printf (",%s",
- dwarf_vmatoa ("u",
-      read_uleb128 (data, & bytes_read, edata)));
- data += bytes_read;
- printf (",%s)\n",
- dwarf_vmatoa ("u",
-      read_uleb128 (data, & bytes_read, edata)));
- data += bytes_read;
+ READ_ULEB (val, data, edata);
+ printf ("(%s", dwarf_vmatoa ("u", val));
+ READ_ULEB (val, data, edata);
+ printf (",%s", dwarf_vmatoa ("u", val));
+ READ_ULEB (val, data, edata);
+ printf (",%s)\n", dwarf_vmatoa ("u", val));
  break;
       default:
  printf (_("    UNKNOWN DW_LNE_HP_SFC opcode (%u)\n"), opc);
@@ -683,7 +636,7 @@ process_extended_line_op (unsigned char * data,
 
     default:
       {
- unsigned int rlen = len - bytes_read - 1;
+ unsigned int rlen = len - 1;
 
  if (op_code >= DW_LNE_lo_user
     /* The test against DW_LNW_hi_user is redundant due to
@@ -701,7 +654,7 @@ process_extended_line_op (unsigned char * data,
       break;
     }
 
-  return len;
+  return len + header_len;
 }
 
 static const unsigned char *
@@ -941,14 +894,12 @@ process_abbrev_section (unsigned char *start, unsigned char *end)
 
   while (start < end)
     {
-      unsigned int bytes_read;
       unsigned long entry;
       unsigned long tag;
       unsigned long attribute;
       int children;
 
-      entry = read_uleb128 (start, & bytes_read, end);
-      start += bytes_read;
+      READ_ULEB (entry, start, end);
 
       /* A single zero is supposed to end the section according
  to the standard.  If there's more, then signal that to
@@ -958,8 +909,7 @@ process_abbrev_section (unsigned char *start, unsigned char *end)
       if (entry == 0)
  return start;
 
-      tag = read_uleb128 (start, & bytes_read, end);
-      start += bytes_read;
+      READ_ULEB (tag, start, end);
       if (start == end)
  return NULL;
 
@@ -973,20 +923,17 @@ process_abbrev_section (unsigned char *start, unsigned char *end)
   /* Initialize it due to a false compiler warning.  */
   bfd_signed_vma implicit_const = -1;
 
-  attribute = read_uleb128 (start, & bytes_read, end);
-  start += bytes_read;
+  READ_ULEB (attribute, start, end);
   if (start == end)
     break;
 
-  form = read_uleb128 (start, & bytes_read, end);
-  start += bytes_read;
+  READ_ULEB (form, start, end);
   if (start == end)
     break;
 
   if (form == DW_FORM_implicit_const)
     {
-      implicit_const = read_sleb128 (start, & bytes_read, end);
-      start += bytes_read;
+      READ_SLEB (implicit_const, start, end);
       if (start == end)
  break;
     }
@@ -1087,7 +1034,6 @@ decode_location_expression (unsigned char * data,
     struct dwarf_section * section)
 {
   unsigned op;
-  unsigned int bytes_read;
   dwarf_vma uvalue;
   dwarf_signed_vma svalue;
   unsigned char *end = data + length;
@@ -1143,14 +1089,12 @@ decode_location_expression (unsigned char * data,
   printf ("%ld", (long) svalue);
   break;
  case DW_OP_constu:
-  printf ("DW_OP_constu: %s",
-  dwarf_vmatoa ("u", read_uleb128 (data, &bytes_read, end)));
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
+  printf ("DW_OP_constu: %s", dwarf_vmatoa ("u", uvalue));
   break;
  case DW_OP_consts:
-  printf ("DW_OP_consts: %s",
-  dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read, end)));
-  data += bytes_read;
+  READ_SLEB (svalue, data, end);
+  printf ("DW_OP_consts: %s", dwarf_vmatoa ("d", svalue));
   break;
  case DW_OP_dup:
   printf ("DW_OP_dup");
@@ -1205,9 +1149,8 @@ decode_location_expression (unsigned char * data,
   printf ("DW_OP_plus");
   break;
  case DW_OP_plus_uconst:
-  printf ("DW_OP_plus_uconst: %s",
-  dwarf_vmatoa ("u", read_uleb128 (data, &bytes_read, end)));
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
+  printf ("DW_OP_plus_uconst: %s", dwarf_vmatoa ("u", uvalue));
   break;
  case DW_OP_shl:
   printf ("DW_OP_shl");
@@ -1351,37 +1294,31 @@ decode_location_expression (unsigned char * data,
  case DW_OP_breg29:
  case DW_OP_breg30:
  case DW_OP_breg31:
-  printf ("DW_OP_breg%d (%s): %s",
-  op - DW_OP_breg0,
-  regname (op - DW_OP_breg0, 1),
-  dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read, end)));
-  data += bytes_read;
+  READ_SLEB (svalue, data, end);
+  printf ("DW_OP_breg%d (%s): %s", op - DW_OP_breg0,
+  regname (op - DW_OP_breg0, 1), dwarf_vmatoa ("d", svalue));
   break;
 
  case DW_OP_regx:
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   printf ("DW_OP_regx: %s (%s)",
   dwarf_vmatoa ("u", uvalue), regname (uvalue, 1));
   break;
  case DW_OP_fbreg:
   need_frame_base = 1;
-  printf ("DW_OP_fbreg: %s",
-  dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read, end)));
-  data += bytes_read;
+  READ_SLEB (svalue, data, end);
+  printf ("DW_OP_fbreg: %s", dwarf_vmatoa ("d", svalue));
   break;
  case DW_OP_bregx:
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
+  READ_SLEB (svalue, data, end);
   printf ("DW_OP_bregx: %s (%s) %s",
   dwarf_vmatoa ("u", uvalue), regname (uvalue, 1),
-  dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read, end)));
-  data += bytes_read;
+  dwarf_vmatoa ("d", svalue));
   break;
  case DW_OP_piece:
-  printf ("DW_OP_piece: %s",
-  dwarf_vmatoa ("u", read_uleb128 (data, &bytes_read, end)));
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
+  printf ("DW_OP_piece: %s", dwarf_vmatoa ("u", uvalue));
   break;
  case DW_OP_deref_size:
   SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
@@ -1440,12 +1377,10 @@ decode_location_expression (unsigned char * data,
   break;
  case DW_OP_bit_piece:
   printf ("DW_OP_bit_piece: ");
-  printf (_("size: %s "),
-  dwarf_vmatoa ("u", read_uleb128 (data, &bytes_read, end)));
-  data += bytes_read;
-  printf (_("offset: %s "),
-  dwarf_vmatoa ("u", read_uleb128 (data, &bytes_read, end)));
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
+  printf (_("size: %s "), dwarf_vmatoa ("u", uvalue));
+  READ_ULEB (uvalue, data, end);
+  printf (_("offset: %s "), dwarf_vmatoa ("u", uvalue));
   break;
 
   /* DWARF 4 extensions.  */
@@ -1455,8 +1390,7 @@ decode_location_expression (unsigned char * data,
 
  case DW_OP_implicit_value:
   printf ("DW_OP_implicit_value");
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   data = display_block (data, uvalue, end, ' ');
   break;
 
@@ -1502,18 +1436,16 @@ decode_location_expression (unsigned char * data,
     {
       SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
     }
+  READ_SLEB (svalue, data, end);
   printf ("%s: <0x%s> %s",
   (op == DW_OP_implicit_pointer
    ? "DW_OP_implicit_pointer" : "DW_OP_GNU_implicit_pointer"),
   dwarf_vmatoa ("x", uvalue),
-  dwarf_vmatoa ("d", read_sleb128 (data,
-   &bytes_read, end)));
-  data += bytes_read;
+  dwarf_vmatoa ("d", svalue));
   break;
  case DW_OP_entry_value:
  case DW_OP_GNU_entry_value:
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   /* PR 17531: file: 0cc9cd00.  */
   if (uvalue > (dwarf_vma) (end - data))
     uvalue = end - data;
@@ -1530,8 +1462,7 @@ decode_location_expression (unsigned char * data,
   break;
  case DW_OP_const_type:
  case DW_OP_GNU_const_type:
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   printf ("%s: <0x%s> ",
   (op == DW_OP_const_type ? "DW_OP_const_type"
   : "DW_OP_GNU_const_type"),
@@ -1541,14 +1472,12 @@ decode_location_expression (unsigned char * data,
   break;
  case DW_OP_regval_type:
  case DW_OP_GNU_regval_type:
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   printf ("%s: %s (%s)",
   (op == DW_OP_regval_type ? "DW_OP_regval_type"
    : "DW_OP_GNU_regval_type"),
   dwarf_vmatoa ("u", uvalue), regname (uvalue, 1));
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue));
   break;
  case DW_OP_deref_type:
@@ -1558,22 +1487,19 @@ decode_location_expression (unsigned char * data,
   (op == DW_OP_deref_type ? "DW_OP_deref_type"
   : "DW_OP_GNU_deref_type"),
   (long) uvalue);
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue));
   break;
  case DW_OP_convert:
  case DW_OP_GNU_convert:
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   printf ("%s <0x%s>",
   (op == DW_OP_convert ? "DW_OP_convert" : "DW_OP_GNU_convert"),
   dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0));
   break;
  case DW_OP_reinterpret:
  case DW_OP_GNU_reinterpret:
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   printf ("%s <0x%s>",
   (op == DW_OP_reinterpret ? "DW_OP_reinterpret"
    : "DW_OP_GNU_reinterpret"),
@@ -1585,13 +1511,11 @@ decode_location_expression (unsigned char * data,
   dwarf_vmatoa ("x", cu_offset + uvalue));
   break;
  case DW_OP_GNU_addr_index:
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   printf ("DW_OP_GNU_addr_index <0x%s>", dwarf_vmatoa ("x", uvalue));
   break;
  case DW_OP_GNU_const_index:
-  uvalue = read_uleb128 (data, &bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (uvalue, data, end);
   printf ("DW_OP_GNU_const_index <0x%s>", dwarf_vmatoa ("x", uvalue));
   break;
  case DW_OP_GNU_variable_value:
@@ -1869,8 +1793,8 @@ skip_attr_bytes (unsigned long          form,
  int                    dwarf_version,
  dwarf_vma *            value_return)
 {
-  unsigned int  bytes_read;
-  dwarf_vma     uvalue = 0;
+  dwarf_signed_vma svalue;
+  dwarf_vma uvalue = 0;
 
   * value_return = 0;
 
@@ -1918,16 +1842,15 @@ skip_attr_bytes (unsigned long          form,
       break;
 
     case DW_FORM_sdata:
-      uvalue = read_sleb128 (data, & bytes_read, end);
-      data += bytes_read;
+      READ_SLEB (svalue, data, end);
+      uvalue = svalue;
       break;
 
     case DW_FORM_ref_udata:
     case DW_FORM_udata:
     case DW_FORM_GNU_str_index:
     case DW_FORM_GNU_addr_index:
-      uvalue = read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
+      READ_ULEB (uvalue, data, end);
       break;
 
     case DW_FORM_ref8:
@@ -1945,8 +1868,7 @@ skip_attr_bytes (unsigned long          form,
 
     case DW_FORM_block:
     case DW_FORM_exprloc:
-      uvalue = read_uleb128 (data, & bytes_read, end);
-      data += bytes_read + uvalue;
+      READ_ULEB (uvalue, data, end);
       break;
 
     case DW_FORM_block1:
@@ -1994,14 +1916,12 @@ get_type_signedness (unsigned char *        start,
      bfd_boolean    is_nested)
 {
   unsigned long   abbrev_number;
-  unsigned int    bytes_read;
   abbrev_entry *  entry;
   abbrev_attr *   attr;
 
   * is_signed = FALSE;
 
-  abbrev_number = read_uleb128 (data, & bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (abbrev_number, data, end);
 
   for (entry = first_abbrev;
        entry != NULL && entry->entry != abbrev_number;
@@ -2081,16 +2001,12 @@ read_and_print_leb128 (unsigned char *        data,
        unsigned const char *  end,
        bfd_boolean            is_signed)
 {
-  if (is_signed)
-    {
-      dwarf_signed_vma sval = read_sleb128 (data, bytes_read, end);
-      printf ("%ld", (long) sval);
-    }
+  int status;
+  dwarf_vma val = read_leb128 (data, end, is_signed, bytes_read, &status);
+  if (status != 0)
+    report_leb_status (status);
   else
-    {
-      dwarf_vma uval = read_uleb128 (data, bytes_read, end);
-      printf ("%lu", (unsigned long) uval);
-    }
+    printf ("%s", dwarf_vmatoa (is_signed ? "d" : "u", val));
 }
 
 static void
@@ -2202,10 +2118,10 @@ read_and_display_attr_value (unsigned long           attribute,
      char                    delimiter,
      int                     level)
 {
+  dwarf_signed_vma svalue;
   dwarf_vma        uvalue = 0;
   unsigned char *  block_start = NULL;
   unsigned char *  orig_data = data;
-  unsigned int     bytes_read;
 
   if (data > end || (data == end && form != DW_FORM_flag_present))
     {
@@ -2261,41 +2177,29 @@ read_and_display_attr_value (unsigned long           attribute,
       break;
 
     case DW_FORM_sdata:
-      uvalue = read_sleb128 (data, & bytes_read, end);
-      data += bytes_read;
+      READ_SLEB (svalue, data, end);
+      uvalue = svalue;
       break;
 
     case DW_FORM_GNU_str_index:
-      uvalue = read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
-      break;
-
     case DW_FORM_ref_udata:
     case DW_FORM_udata:
-      uvalue = read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
+    case DW_FORM_GNU_addr_index:
+      READ_ULEB (uvalue, data, end);
       break;
 
     case DW_FORM_indirect:
-      form = read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
+      READ_ULEB (form, data, end);
       if (!do_loc)
  printf ("%c%s", delimiter, get_FORM_name (form));
       if (form == DW_FORM_implicit_const)
- {
-  implicit_const = read_sleb128 (data, & bytes_read, end);
-  data += bytes_read;
- }
+ READ_SLEB (implicit_const, data, end);
       return read_and_display_attr_value (attribute, form, implicit_const,
   start, data, end,
   cu_offset, pointer_size,
   offset_size, dwarf_version,
   debug_info_p, do_loc,
   section, this_set, delimiter, level);
-    case DW_FORM_GNU_addr_index:
-      uvalue = read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
-      break;
     }
 
   switch (form)
@@ -2403,8 +2307,9 @@ read_and_display_attr_value (unsigned long           attribute,
 
     case DW_FORM_block:
     case DW_FORM_exprloc:
-      uvalue = read_uleb128 (data, & bytes_read, end);
-      block_start = data + bytes_read;
+      READ_ULEB (uvalue, data, end);
+    do_block:
+      block_start = data;
       if (block_start >= end)
  {
   warn (_("Block ends prematurely\n"));
@@ -2421,59 +2326,16 @@ read_and_display_attr_value (unsigned long           attribute,
       break;
 
     case DW_FORM_block1:
-      SAFE_BYTE_GET (uvalue, data, 1, end);
-      block_start = data + 1;
-      if (block_start >= end)
- {
-  warn (_("Block ends prematurely\n"));
-  uvalue = 0;
-  block_start = end;
- }
-
-      uvalue = check_uvalue (block_start, uvalue, end);
-
-      if (do_loc)
- data = block_start + uvalue;
-      else
- data = display_block (block_start, uvalue, end, delimiter);
-      break;
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+      goto do_block;
 
     case DW_FORM_block2:
-      SAFE_BYTE_GET (uvalue, data, 2, end);
-      block_start = data + 2;
-      if (block_start >= end)
- {
-  warn (_("Block ends prematurely\n"));
-  uvalue = 0;
-  block_start = end;
- }
-
-      uvalue = check_uvalue (block_start, uvalue, end);
-
-      if (do_loc)
- data = block_start + uvalue;
-      else
- data = display_block (block_start, uvalue, end, delimiter);
-      break;
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
+      goto do_block;
 
     case DW_FORM_block4:
-      SAFE_BYTE_GET (uvalue, data, 4, end);
-      block_start = data + 4;
-      /* PR 17512: file: 3371-3907-0.004.  */
-      if (block_start >= end)
- {
-  warn (_("Block ends prematurely\n"));
-  uvalue = 0;
-  block_start = end;
- }
-
-      uvalue = check_uvalue (block_start, uvalue, end);
-
-      if (do_loc)
- data = block_start + uvalue;
-      else
- data = display_block (block_start, uvalue, end, delimiter);
-      break;
+      SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
+      goto do_block;
 
     case DW_FORM_strp:
       if (!do_loc)
@@ -3070,9 +2932,10 @@ read_and_display_attr_value (unsigned long           attribute,
  else
   {
     unsigned long abbrev_number;
-    abbrev_entry * entry;
+    abbrev_entry *entry;
+    unsigned char *p = section->start + uvalue;
 
-    abbrev_number = read_uleb128 (section->start + uvalue, NULL, end);
+    READ_ULEB (abbrev_number, p, end);
 
     printf (_("\t[Abbrev Number: %ld"), abbrev_number);
     /* Don't look up abbrev for DW_FORM_ref_addr, as it very often will
@@ -3517,7 +3380,6 @@ process_debug_info (struct dwarf_section *           section,
       saved_level = -1;
       while (tags < start)
  {
-  unsigned int bytes_read;
   unsigned long abbrev_number;
   unsigned long die_offset;
   abbrev_entry *entry;
@@ -3526,8 +3388,7 @@ process_debug_info (struct dwarf_section *           section,
 
   die_offset = tags - section_begin;
 
-  abbrev_number = read_uleb128 (tags, & bytes_read, start);
-  tags += bytes_read;
+  READ_ULEB (abbrev_number, tags, start);
 
   /* A null DIE marks the end of a list of siblings or it may also be
      a section padding.  */
@@ -3871,16 +3732,14 @@ display_formatted_table (unsigned char *                   data,
 {
   unsigned char *format_start, format_count, *format, formati;
   dwarf_vma data_count, datai;
-  unsigned int bytes_read, namepass, last_entry = 0;
+  unsigned int namepass, last_entry = 0;
 
   SAFE_BYTE_GET_AND_INC (format_count, data, 1, end);
   format_start = data;
   for (formati = 0; formati < format_count; formati++)
     {
-      read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
-      read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
+      SKIP_ULEB (data, end);
+      SKIP_ULEB (data, end);
       if (data == end)
  {
   if (is_dir)
@@ -3891,8 +3750,7 @@ display_formatted_table (unsigned char *                   data,
  }
     }
 
-  data_count = read_uleb128 (data, & bytes_read, end);
-  data += bytes_read;
+  READ_ULEB (data_count, data, end);
   if (data == end)
     {
       if (is_dir)
@@ -3927,8 +3785,7 @@ display_formatted_table (unsigned char *                   data,
  {
   dwarf_vma content_type;
 
-  content_type = read_uleb128 (format, & bytes_read, end);
-  format += bytes_read;
+  READ_ULEB (content_type, format, end);
   if ((content_type == DW_LNCT_path) == (namepass == 1))
     switch (content_type)
       {
@@ -3951,8 +3808,7 @@ display_formatted_table (unsigned char *                   data,
  printf (_("\t(Unknown format content type %s)"),
  dwarf_vmatoa ("u", content_type));
       }
-  read_uleb128 (format, & bytes_read, end);
-  format += bytes_read;
+  SKIP_ULEB (format, end);
  }
     }
   putchar ('\n');
@@ -3971,12 +3827,10 @@ display_formatted_table (unsigned char *                   data,
     {
       dwarf_vma content_type, form;
 
-      content_type = read_uleb128 (format, & bytes_read, end);
-      format += bytes_read;
-      form = read_uleb128 (format, & bytes_read, end);
-      format += bytes_read;
-      data = read_and_display_attr_value (0, form, 0, start, data, end, 0, 0,
-  linfo->li_offset_size,
+      READ_ULEB (content_type, format, end);
+      READ_ULEB (form, format, end);
+      data = read_and_display_attr_value (0, form, 0, start, data, end,
+  0, 0, linfo->li_offset_size,
   linfo->li_version, NULL,
     ((content_type == DW_LNCT_path) != (namepass == 1)),
   section, NULL, '\t', -1);
@@ -4137,21 +3991,18 @@ display_debug_lines_raw (struct dwarf_section *  section,
   while (data < end && *data != 0)
     {
       unsigned char *name;
-      unsigned int bytes_read;
+      dwarf_vma val;
 
       printf ("  %d\t", ++state_machine_regs.last_file_entry);
       name = data;
       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)));
-      data += bytes_read;
-      printf ("%s\t",
-      dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
-      data += bytes_read;
+      READ_ULEB (val, data, end);
+      printf ("%s\t", dwarf_vmatoa ("u", val));
+      READ_ULEB (val, data, end);
+      printf ("%s\t", dwarf_vmatoa ("u", val));
+      READ_ULEB (val, data, end);
+      printf ("%s\t", dwarf_vmatoa ("u", val));
       printf ("%.*s\n", (int)(end - name), name);
 
       if (data == end)
@@ -4182,7 +4033,6 @@ display_debug_lines_raw (struct dwarf_section *  section,
       unsigned char op_code;
       dwarf_signed_vma adv;
       dwarf_vma uladv;
-      unsigned int bytes_read;
 
       printf ("  [0x%08lx]", (long)(data - start));
 
@@ -4236,169 +4086,166 @@ display_debug_lines_raw (struct dwarf_section *  section,
     putchar ('\n');
   state_machine_regs.view++;
  }
-      else switch (op_code)
-     {
-     case DW_LNS_extended_op:
-       data += process_extended_line_op (data, linfo.li_default_is_stmt, end);
-       break;
-
-     case DW_LNS_copy:
-       printf (_("  Copy"));
-       if (verbose_view || state_machine_regs.view)
- printf (_(" (view %u)\n"), state_machine_regs.view);
-       else
- putchar ('\n');
-       state_machine_regs.view++;
-       break;
-
-     case DW_LNS_advance_pc:
-       uladv = read_uleb128 (data, & bytes_read, end);
-       data += bytes_read;
-       if (linfo.li_max_ops_per_insn == 1)
- {
-   uladv *= linfo.li_min_insn_length;
-   state_machine_regs.address += uladv;
-   if (uladv)
-     state_machine_regs.view = 0;
-   printf (_("  Advance PC by %s to 0x%s%s\n"),
-   dwarf_vmatoa ("u", uladv),
-   dwarf_vmatoa ("x", state_machine_regs.address),
-   verbose_view && uladv
-   ? _(" (reset view)") : "");
- }
-       else
- {
-   unsigned addrdelta
-     = ((state_machine_regs.op_index + uladv)
- / linfo.li_max_ops_per_insn)
-     * linfo.li_min_insn_length;
-   state_machine_regs.address
-     += addrdelta;
-   state_machine_regs.op_index
-     = (state_machine_regs.op_index + uladv)
-     % linfo.li_max_ops_per_insn;
-   if (addrdelta)
-     state_machine_regs.view = 0;
-   printf (_("  Advance PC by %s to 0x%s[%d]%s\n"),
-   dwarf_vmatoa ("u", uladv),
-   dwarf_vmatoa ("x", state_machine_regs.address),
-   state_machine_regs.op_index,
-   verbose_view && addrdelta
-   ? _(" (reset view)") : "");
- }
-       break;
-
-     case DW_LNS_advance_line:
-       adv = read_sleb128 (data, & bytes_read, end);
-       data += bytes_read;
-       state_machine_regs.line += adv;
-       printf (_("  Advance Line by %s to %d\n"),
-       dwarf_vmatoa ("d", adv),
-       state_machine_regs.line);
-       break;
-
-     case DW_LNS_set_file:
-       adv = read_uleb128 (data, & bytes_read, end);
-       data += bytes_read;
-       printf (_("  Set File Name to entry %s in the File Name Table\n"),
-       dwarf_vmatoa ("d", adv));
-       state_machine_regs.file = adv;
-       break;
-
-     case DW_LNS_set_column:
-       uladv = read_uleb128 (data, & bytes_read, end);
-       data += bytes_read;
-       printf (_("  Set column to %s\n"),
-       dwarf_vmatoa ("u", uladv));
-       state_machine_regs.column = uladv;
-       break;
-
-     case DW_LNS_negate_stmt:
-       adv = state_machine_regs.is_stmt;
-       adv = ! adv;
-       printf (_("  Set is_stmt to %s\n"), dwarf_vmatoa ("d", adv));
-       state_machine_regs.is_stmt = adv;
-       break;
-
-     case DW_LNS_set_basic_block:
-       printf (_("  Set basic block\n"));
-       state_machine_regs.basic_block = 1;
-       break;
-
-     case DW_LNS_const_add_pc:
-       uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
-       if (linfo.li_max_ops_per_insn)
- {
-   uladv *= linfo.li_min_insn_length;
-   state_machine_regs.address += uladv;
-   if (uladv)
-     state_machine_regs.view = 0;
-   printf (_("  Advance PC by constant %s to 0x%s%s\n"),
-   dwarf_vmatoa ("u", uladv),
-   dwarf_vmatoa ("x", state_machine_regs.address),
-   verbose_view && uladv
-   ? _(" (reset view)") : "");
- }
-       else
- {
-   unsigned addrdelta
-     = ((state_machine_regs.op_index + uladv)
- / linfo.li_max_ops_per_insn)
-     * linfo.li_min_insn_length;
-   state_machine_regs.address
-     += addrdelta;
-   state_machine_regs.op_index
-     = (state_machine_regs.op_index + uladv)
-     % linfo.li_max_ops_per_insn;
-   if (addrdelta)
-     state_machine_regs.view = 0;
-   printf (_("  Advance PC by constant %s to 0x%s[%d]%s\n"),
-   dwarf_vmatoa ("u", uladv),
-   dwarf_vmatoa ("x", state_machine_regs.address),
-   state_machine_regs.op_index,
-   verbose_view && addrdelta
-   ? _(" (reset view)") : "");
- }
-       break;
-
-     case DW_LNS_fixed_advance_pc:
-       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"),
-       dwarf_vmatoa ("u", uladv),
-       dwarf_vmatoa ("x", state_machine_regs.address));
-       /* Do NOT reset view.  */
-       break;
-
-     case DW_LNS_set_prologue_end:
-       printf (_("  Set prologue_end to true\n"));
-       break;
-
-     case DW_LNS_set_epilogue_begin:
-       printf (_("  Set epilogue_begin to true\n"));
-       break;
-
-     case DW_LNS_set_isa:
-       uladv = read_uleb128 (data, & bytes_read, end);
-       data += bytes_read;
-       printf (_("  Set ISA to %s\n"), dwarf_vmatoa ("u", uladv));
-       break;
-
-     default:
-       printf (_("  Unknown opcode %d with operands: "), op_code);
-
-       if (standard_opcodes != NULL)
- for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
-   {
-     printf ("0x%s%s", dwarf_vmatoa ("x", read_uleb128 (data,
- &bytes_read, end)),
-     i == 1 ? "" : ", ");
-     data += bytes_read;
-   }
-       putchar ('\n');
-       break;
-     }
+      else
+ switch (op_code)
+  {
+  case DW_LNS_extended_op:
+    data += process_extended_line_op (data,
+      linfo.li_default_is_stmt,
+      end);
+    break;
+
+  case DW_LNS_copy:
+    printf (_("  Copy"));
+    if (verbose_view || state_machine_regs.view)
+      printf (_(" (view %u)\n"), state_machine_regs.view);
+    else
+      putchar ('\n');
+    state_machine_regs.view++;
+    break;
+
+  case DW_LNS_advance_pc:
+    READ_ULEB (uladv, data, end);
+    if (linfo.li_max_ops_per_insn == 1)
+      {
+ uladv *= linfo.li_min_insn_length;
+ state_machine_regs.address += uladv;
+ if (uladv)
+  state_machine_regs.view = 0;
+ printf (_("  Advance PC by %s to 0x%s%s\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address),
+ verbose_view && uladv
+ ? _(" (reset view)") : "");
+      }
+    else
+      {
+ unsigned addrdelta
+  = ((state_machine_regs.op_index + uladv)
+     / linfo.li_max_ops_per_insn)
+  * linfo.li_min_insn_length;
+ state_machine_regs.address
+  += addrdelta;
+ state_machine_regs.op_index
+  = (state_machine_regs.op_index + uladv)
+  % linfo.li_max_ops_per_insn;
+ if (addrdelta)
+  state_machine_regs.view = 0;
+ printf (_("  Advance PC by %s to 0x%s[%d]%s\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address),
+ state_machine_regs.op_index,
+ verbose_view && addrdelta
+ ? _(" (reset view)") : "");
+      }
+    break;
+
+  case DW_LNS_advance_line:
+    READ_SLEB (adv, data, end);
+    state_machine_regs.line += adv;
+    printf (_("  Advance Line by %s to %d\n"),
+    dwarf_vmatoa ("d", adv),
+    state_machine_regs.line);
+    break;
+
+  case DW_LNS_set_file:
+    READ_ULEB (uladv, data, end);
+    printf (_("  Set File Name to entry %s in the File Name Table\n"),
+    dwarf_vmatoa ("u", uladv));
+    state_machine_regs.file = uladv;
+    break;
+
+  case DW_LNS_set_column:
+    READ_ULEB (uladv, data, end);
+    printf (_("  Set column to %s\n"),
+    dwarf_vmatoa ("u", uladv));
+    state_machine_regs.column = uladv;
+    break;
+
+  case DW_LNS_negate_stmt:
+    adv = state_machine_regs.is_stmt;
+    adv = ! adv;
+    printf (_("  Set is_stmt to %s\n"), dwarf_vmatoa ("d", adv));
+    state_machine_regs.is_stmt = adv;
+    break;
+
+  case DW_LNS_set_basic_block:
+    printf (_("  Set basic block\n"));
+    state_machine_regs.basic_block = 1;
+    break;
+
+  case DW_LNS_const_add_pc:
+    uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
+    if (linfo.li_max_ops_per_insn)
+      {
+ uladv *= linfo.li_min_insn_length;
+ state_machine_regs.address += uladv;
+ if (uladv)
+  state_machine_regs.view = 0;
+ printf (_("  Advance PC by constant %s to 0x%s%s\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address),
+ verbose_view && uladv
+ ? _(" (reset view)") : "");
+      }
+    else
+      {
+ unsigned addrdelta
+  = ((state_machine_regs.op_index + uladv)
+     / linfo.li_max_ops_per_insn)
+  * linfo.li_min_insn_length;
+ state_machine_regs.address
+  += addrdelta;
+ state_machine_regs.op_index
+  = (state_machine_regs.op_index + uladv)
+  % linfo.li_max_ops_per_insn;
+ if (addrdelta)
+  state_machine_regs.view = 0;
+ printf (_("  Advance PC by constant %s to 0x%s[%d]%s\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address),
+ state_machine_regs.op_index,
+ verbose_view && addrdelta
+ ? _(" (reset view)") : "");
+      }
+    break;
+
+  case DW_LNS_fixed_advance_pc:
+    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"),
+    dwarf_vmatoa ("u", uladv),
+    dwarf_vmatoa ("x", state_machine_regs.address));
+    /* Do NOT reset view.  */
+    break;
+
+  case DW_LNS_set_prologue_end:
+    printf (_("  Set prologue_end to true\n"));
+    break;
+
+  case DW_LNS_set_epilogue_begin:
+    printf (_("  Set epilogue_begin to true\n"));
+    break;
+
+  case DW_LNS_set_isa:
+    READ_ULEB (uladv, data, end);
+    printf (_("  Set ISA to %s\n"), dwarf_vmatoa ("u", uladv));
+    break;
+
+  default:
+    printf (_("  Unknown opcode %d with operands: "), op_code);
+
+    if (standard_opcodes != NULL)
+      for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
+ {
+  READ_ULEB (uladv, data, end);
+  printf ("0x%s%s", dwarf_vmatoa ("x", uladv),
+  i == 1 ? "" : ", ");
+ }
+    putchar ('\n');
+    break;
+  }
     }
   putchar ('\n');
  }
@@ -4490,7 +4337,6 @@ display_debug_lines_decoded (struct dwarf_section *  section,
     {
       unsigned char *format_start, format_count, *format;
       dwarf_vma formati, entryi;
-      unsigned int bytes_read;
 
       load_debug_section_with_follow (line_str, fileptr);
 
@@ -4499,14 +4345,11 @@ display_debug_lines_decoded (struct dwarf_section *  section,
       format_start = data;
       for (formati = 0; formati < format_count; formati++)
  {
-  read_uleb128 (data, & bytes_read, end);
-  data += bytes_read;
-  read_uleb128 (data, & bytes_read, end);
-  data += bytes_read;
+  SKIP_ULEB (data, end);
+  SKIP_ULEB (data, end);
  }
 
-      n_directories = read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
+      READ_ULEB (n_directories, data, end);
       if (data == end)
  {
   warn (_("Corrupt directories list\n"));
@@ -4526,10 +4369,8 @@ display_debug_lines_decoded (struct dwarf_section *  section,
       dwarf_vma content_type, form;
       dwarf_vma uvalue;
 
-      content_type = read_uleb128 (format, & bytes_read, end);
-      format += bytes_read;
-      form = read_uleb128 (format, & bytes_read, end);
-      format += bytes_read;
+      READ_ULEB (content_type, format, end);
+      READ_ULEB (form, format, end);
       if (data == end)
  {
   warn (_("Corrupt directories list\n"));
@@ -4553,8 +4394,8 @@ display_debug_lines_decoded (struct dwarf_section *  section,
     }
   break;
  }
-      data = read_and_display_attr_value (0, form, 0, start, data, end,
-                                          0, 0,
+      data = read_and_display_attr_value (0, form, 0, start,
+  data, end, 0, 0,
   linfo.li_offset_size,
   linfo.li_version,
   NULL, 1, section,
@@ -4572,14 +4413,11 @@ display_debug_lines_decoded (struct dwarf_section *  section,
       format_start = data;
       for (formati = 0; formati < format_count; formati++)
  {
-  read_uleb128 (data, & bytes_read, end);
-  data += bytes_read;
-  read_uleb128 (data, & bytes_read, end);
-  data += bytes_read;
+  SKIP_ULEB (data, end);
+  SKIP_ULEB (data, end);
  }
 
-      n_files = read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
+      READ_ULEB (n_files, data, end);
       if (data == end)
  {
   warn (_("Corrupt file name list\n"));
@@ -4598,11 +4436,10 @@ display_debug_lines_decoded (struct dwarf_section *  section,
     {
       dwarf_vma content_type, form;
       dwarf_vma uvalue;
+      unsigned char *tmp;
 
-      content_type = read_uleb128 (format, & bytes_read, end);
-      format += bytes_read;
-      form = read_uleb128 (format, & bytes_read, end);
-      format += bytes_read;
+      READ_ULEB (content_type, format, end);
+      READ_ULEB (form, format, end);
       if (data == end)
  {
   warn (_("Corrupt file name list\n"));
@@ -4637,14 +4474,14 @@ display_debug_lines_decoded (struct dwarf_section *  section,
      end);
       break;
     case DW_FORM_udata:
-      file->directory_index = read_uleb128 (data, NULL,
-    end);
+      tmp = data;
+      READ_ULEB (file->directory_index, tmp, end);
       break;
     }
   break;
  }
-      data = read_and_display_attr_value (0, form, 0, start, data, end,
-  0, 0,
+      data = read_and_display_attr_value (0, form, 0, start,
+  data, end, 0, 0,
   linfo.li_offset_size,
   linfo.li_version,
   NULL, 1, section,
@@ -4700,18 +4537,12 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 
   while (data < end && *data != 0)
     {
-      unsigned int bytes_read;
-
-      /* Skip Name, directory index, last modification time and length
- of file.  */
+      /* Skip Name, directory index, last modification
+ time and length of file.  */
       data += strnlen ((char *) data, end - data) + 1;
-      read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
-      read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
-      read_uleb128 (data, & bytes_read, end);
-      data += bytes_read;
-
+      SKIP_ULEB (data, end);
+      SKIP_ULEB (data, end);
+      SKIP_ULEB (data, end);
       n_files++;
     }
 
@@ -4728,21 +4559,17 @@ display_debug_lines_decoded (struct dwarf_section *  section,
   i = 0;
   while (*ptr_file_name_table != 0)
     {
-      unsigned int bytes_read;
-
       file_table[i].name = ptr_file_name_table;
       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,
-    & bytes_read, end);
-      ptr_file_name_table += bytes_read;
-      file_table[i].modification_date = read_uleb128 (ptr_file_name_table,
-      & bytes_read, end);
-      ptr_file_name_table += bytes_read;
-      file_table[i].length = read_uleb128 (ptr_file_name_table, & bytes_read, end);
-      ptr_file_name_table += bytes_read;
+      READ_ULEB (file_table[i].directory_index,
+ ptr_file_name_table, end);
+      READ_ULEB (file_table[i].modification_date,
+ ptr_file_name_table, end);
+      READ_ULEB (file_table[i].length,
+ ptr_file_name_table, end);
       i++;
     }
   i = 0;
@@ -4793,7 +4620,6 @@ display_debug_lines_decoded (struct dwarf_section *  section,
   int xop;
   int adv;
   unsigned long int uladv;
-  unsigned int bytes_read;
   int is_special_opcode = 0;
 
   op_code = *data++;
@@ -4830,228 +4656,216 @@ display_debug_lines_decoded (struct dwarf_section *  section,
       is_special_opcode = 1;
       /* Increment view after printing this row.  */
     }
-  else switch (op_code)
- {
- case DW_LNS_extended_op:
-   {
-     unsigned int ext_op_code_len;
-     unsigned char ext_op_code;
-     unsigned char *op_code_data = data;
-
-     ext_op_code_len = read_uleb128 (op_code_data, &bytes_read,
-     end_of_sequence);
-     op_code_data += bytes_read;
-
-     if (ext_op_code_len == 0)
-       {
- warn (_("Badly formed extended line op encountered!\n"));
- break;
-       }
-     ext_op_code_len += bytes_read;
-     ext_op_code = *op_code_data++;
-     xop = ext_op_code;
-     xop = -xop;
-
-     switch (ext_op_code)
-       {
-       case DW_LNE_end_sequence:
- /* Reset stuff after printing this row.  */
- break;
-       case DW_LNE_set_address:
- 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;
- state_machine_regs.view = 0;
- break;
-       case DW_LNE_define_file:
- {
-   file_table = (File_Entry *) xrealloc
-     (file_table, (n_files + 1) * sizeof (File_Entry));
-
-   ++state_machine_regs.last_file_entry;
-   /* Source file name.  */
-   file_table[n_files].name = op_code_data;
-   op_code_data += strlen ((char *) op_code_data) + 1;
-   /* Directory index.  */
-   file_table[n_files].directory_index =
-     read_uleb128 (op_code_data, & bytes_read,
-   end_of_sequence);
-   op_code_data += bytes_read;
-   /* Last modification time.  */
-   file_table[n_files].modification_date =
-     read_uleb128 (op_code_data, & bytes_read,
-   end_of_sequence);
-   op_code_data += bytes_read;
-   /* File length.  */
-   file_table[n_files].length =
-     read_uleb128 (op_code_data, & bytes_read,
-   end_of_sequence);
-
-   n_files++;
-   break;
- }
-       case DW_LNE_set_discriminator:
-       case DW_LNE_HP_set_sequence:
- /* Simply ignored.  */
- break;
-
-       default:
- printf (_("UNKNOWN (%u): length %d\n"),
- ext_op_code, ext_op_code_len - bytes_read);
- break;
-       }
-     data += ext_op_code_len;
-     break;
-   }
- case DW_LNS_copy:
-   /* Increment view after printing this row.  */
-   break;
-
- case DW_LNS_advance_pc:
-   uladv = read_uleb128 (data, & bytes_read, end);
-   data += bytes_read;
-   if (linfo.li_max_ops_per_insn == 1)
-     {
-       uladv *= linfo.li_min_insn_length;
-       state_machine_regs.address += uladv;
-       if (uladv)
- state_machine_regs.view = 0;
-     }
-   else
-     {
-       unsigned addrdelta
- = ((state_machine_regs.op_index + uladv)
-    / linfo.li_max_ops_per_insn)
- * linfo.li_min_insn_length;
-       state_machine_regs.address
- += addrdelta;
-       state_machine_regs.op_index
- = (state_machine_regs.op_index + uladv)
- % linfo.li_max_ops_per_insn;
-       if (addrdelta)
- state_machine_regs.view = 0;
-     }
-   break;
-
- case DW_LNS_advance_line:
-   adv = read_sleb128 (data, & bytes_read, end);
-   data += bytes_read;
-   state_machine_regs.line += adv;
-   break;
-
- case DW_LNS_set_file:
-   adv = read_uleb128 (data, & bytes_read, end);
-   data += bytes_read;
-   state_machine_regs.file = adv;
-
-   {
-     unsigned file = state_machine_regs.file - 1;
-     unsigned dir;
-
-     if (file_table == NULL || n_files == 0)
-       printf (_("\n [Use file table entry %d]\n"), file);
-     /* PR 20439 */
-     else if (file >= n_files)
-       {
- warn (_("file index %u > number of files %u\n"), file + 1, n_files);
- printf (_("\n <over large file table index %u>"), file);
-       }
-     else if ((dir = file_table[file].directory_index) == 0)
-       /* If directory index is 0, that means current directory.  */
-       printf ("\n./%s:[++]\n", file_table[file].name);
-     else if (directory_table == NULL || n_directories == 0)
-       printf (_("\n [Use file %s in directory table entry %d]\n"),
-       file_table[file].name, dir);
-     /* PR 20439 */
-     else if (dir > n_directories)
-       {
- warn (_("directory index %u > number of directories %s\n"),
-       dir, dwarf_vmatoa ("u", n_directories));
- printf (_("\n <over large directory table entry %u>\n"), dir);
-       }
-     else
-       printf ("\n%s/%s:\n",
-       /* The directory index starts counting at 1.  */
-       directory_table[dir - 1], file_table[file].name);
-   }
-   break;
-
- case DW_LNS_set_column:
-   uladv = read_uleb128 (data, & bytes_read, end);
-   data += bytes_read;
-   state_machine_regs.column = uladv;
-   break;
-
- case DW_LNS_negate_stmt:
-   adv = state_machine_regs.is_stmt;
-   adv = ! adv;
-   state_machine_regs.is_stmt = adv;
-   break;
-
- case DW_LNS_set_basic_block:
-   state_machine_regs.basic_block = 1;
-   break;
-
- case DW_LNS_const_add_pc:
-   uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
-   if (linfo.li_max_ops_per_insn == 1)
-     {
-       uladv *= linfo.li_min_insn_length;
-       state_machine_regs.address += uladv;
-       if (uladv)
- state_machine_regs.view = 0;
-     }
-   else
-     {
-       unsigned addrdelta
- = ((state_machine_regs.op_index + uladv)
-    / linfo.li_max_ops_per_insn)
- * linfo.li_min_insn_length;
-       state_machine_regs.address
- += addrdelta;
-       state_machine_regs.op_index
- = (state_machine_regs.op_index + uladv)
- % linfo.li_max_ops_per_insn;
-       if (addrdelta)
- state_machine_regs.view = 0;
-     }
-   break;
-
- case DW_LNS_fixed_advance_pc:
-   SAFE_BYTE_GET_AND_INC (uladv, data, 2, end);
-   state_machine_regs.address += uladv;
-   state_machine_regs.op_index = 0;
-   /* Do NOT reset view.  */
-   break;
-
- case DW_LNS_set_prologue_end:
-   break;
-
- case DW_LNS_set_epilogue_begin:
-   break;
-
- case DW_LNS_set_isa:
-   uladv = read_uleb128 (data, & bytes_read, end);
-   data += bytes_read;
-   printf (_("  Set ISA to %lu\n"), uladv);
-   break;
-
- default:
-   printf (_("  Unknown opcode %d with operands: "), op_code);
-
-   if (standard_opcodes != NULL)
-     for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
-       {
- printf ("0x%s%s", dwarf_vmatoa ("x", read_uleb128 (data,
-    &bytes_read, end)),
- i == 1 ? "" : ", ");
- data += bytes_read;
-       }
-   putchar ('\n');
-   break;
- }
+  else
+    switch (op_code)
+      {
+      case DW_LNS_extended_op:
+ {
+  unsigned int ext_op_code_len;
+  unsigned char ext_op_code;
+  unsigned char *op_code_end;
+  unsigned char *op_code_data = data;
+
+  READ_ULEB (ext_op_code_len, op_code_data, end_of_sequence);
+  op_code_end = op_code_data + ext_op_code_len;
+  if (ext_op_code_len == 0 || op_code_end > end_of_sequence)
+    {
+      warn (_("Badly formed extended line op encountered!\n"));
+      break;
+    }
+  ext_op_code = *op_code_data++;
+  xop = ext_op_code;
+  xop = -xop;
+
+  switch (ext_op_code)
+    {
+    case DW_LNE_end_sequence:
+      /* Reset stuff after printing this row.  */
+      break;
+    case DW_LNE_set_address:
+      SAFE_BYTE_GET_AND_INC (state_machine_regs.address,
+     op_code_data,
+     op_code_end - op_code_data,
+     op_code_end);
+      state_machine_regs.op_index = 0;
+      state_machine_regs.view = 0;
+      break;
+    case DW_LNE_define_file:
+      file_table = (File_Entry *) xrealloc
+ (file_table, (n_files + 1) * sizeof (File_Entry));
+
+      ++state_machine_regs.last_file_entry;
+      /* Source file name.  */
+      file_table[n_files].name = op_code_data;
+      op_code_data += strlen ((char *) op_code_data) + 1;
+      /* Directory index.  */
+      READ_ULEB (file_table[n_files].directory_index,
+ op_code_data, op_code_end);
+      /* Last modification time.  */
+      READ_ULEB (file_table[n_files].modification_date,
+ op_code_data, op_code_end);
+      /* File length.  */
+      READ_ULEB (file_table[n_files].length,
+ op_code_data, op_code_end);
+      n_files++;
+      break;
+
+    case DW_LNE_set_discriminator:
+    case DW_LNE_HP_set_sequence:
+      /* Simply ignored.  */
+      break;
+
+    default:
+      printf (_("UNKNOWN (%u): length %ld\n"),
+      ext_op_code, op_code_data - data);
+      break;
+    }
+  data = op_code_end;
+  break;
+ }
+      case DW_LNS_copy:
+ /* Increment view after printing this row.  */
+ break;
+
+      case DW_LNS_advance_pc:
+ READ_ULEB (uladv, data, end);
+ if (linfo.li_max_ops_per_insn == 1)
+  {
+    uladv *= linfo.li_min_insn_length;
+    state_machine_regs.address += uladv;
+    if (uladv)
+      state_machine_regs.view = 0;
+  }
+ else
+  {
+    unsigned addrdelta
+      = ((state_machine_regs.op_index + uladv)
+ / linfo.li_max_ops_per_insn)
+      * linfo.li_min_insn_length;
+    state_machine_regs.address
+      += addrdelta;
+    state_machine_regs.op_index
+      = (state_machine_regs.op_index + uladv)
+      % linfo.li_max_ops_per_insn;
+    if (addrdelta)
+      state_machine_regs.view = 0;
+  }
+ break;
+
+      case DW_LNS_advance_line:
+ READ_SLEB (adv, data, end);
+ state_machine_regs.line += adv;
+ break;
+
+      case DW_LNS_set_file:
+ READ_ULEB (uladv, data, end);
+ state_machine_regs.file = uladv;
+
+ {
+  unsigned file = state_machine_regs.file - 1;
+  unsigned dir;
+
+  if (file_table == NULL || n_files == 0)
+    printf (_("\n [Use file table entry %d]\n"), file);
+  /* PR 20439 */
+  else if (file >= n_files)
+    {
+      warn (_("file index %u > number of files %u\n"), file + 1, n_files);
+      printf (_("\n <over large file table index %u>"), file);
+    }
+  else if ((dir = file_table[file].directory_index) == 0)
+    /* If directory index is 0, that means current directory.  */
+    printf ("\n./%s:[++]\n", file_table[file].name);
+  else if (directory_table == NULL || n_directories == 0)
+    printf (_("\n [Use file %s in directory table entry %d]\n"),
+    file_table[file].name, dir);
+  /* PR 20439 */
+  else if (dir > n_directories)
+    {
+      warn (_("directory index %u > number of directories %s\n"),
+    dir, dwarf_vmatoa ("u", n_directories));
+      printf (_("\n <over large directory table entry %u>\n"), dir);
+    }
+  else
+    printf ("\n%s/%s:\n",
+    /* The directory index starts counting at 1.  */
+    directory_table[dir - 1], file_table[file].name);
+ }
+ break;
+
+      case DW_LNS_set_column:
+ READ_ULEB (uladv, data, end);
+ state_machine_regs.column = uladv;
+ break;
+
+      case DW_LNS_negate_stmt:
+ adv = state_machine_regs.is_stmt;
+ adv = ! adv;
+ state_machine_regs.is_stmt = adv;
+ break;
+
+      case DW_LNS_set_basic_block:
+ state_machine_regs.basic_block = 1;
+ break;
+
+      case DW_LNS_const_add_pc:
+ uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
+ if (linfo.li_max_ops_per_insn == 1)
+  {
+    uladv *= linfo.li_min_insn_length;
+    state_machine_regs.address += uladv;
+    if (uladv)
+      state_machine_regs.view = 0;
+  }
+ else
+  {
+    unsigned addrdelta
+      = ((state_machine_regs.op_index + uladv)
+ / linfo.li_max_ops_per_insn)
+      * linfo.li_min_insn_length;
+    state_machine_regs.address
+      += addrdelta;
+    state_machine_regs.op_index
+      = (state_machine_regs.op_index + uladv)
+      % linfo.li_max_ops_per_insn;
+    if (addrdelta)
+      state_machine_regs.view = 0;
+  }
+ break;
+
+      case DW_LNS_fixed_advance_pc:
+ SAFE_BYTE_GET_AND_INC (uladv, data, 2, end);
+ state_machine_regs.address += uladv;
+ state_machine_regs.op_index = 0;
+ /* Do NOT reset view.  */
+ break;
+
+      case DW_LNS_set_prologue_end:
+ break;
+
+      case DW_LNS_set_epilogue_begin:
+ break;
+
+      case DW_LNS_set_isa:
+ READ_ULEB (uladv, data, end);
+ printf (_("  Set ISA to %lu\n"), uladv);
+ break;
+
+      default:
+ printf (_("  Unknown opcode %d with operands: "), op_code);
+
+ if (standard_opcodes != NULL)
+  for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
+    {
+      dwarf_vma val;
+
+      READ_ULEB (val, data, end);
+      printf ("0x%s%s", dwarf_vmatoa ("x", val),
+      i == 1 ? "" : ", ");
+    }
+ putchar ('\n');
+ break;
+      }
 
   /* Only Special opcodes, DW_LNS_copy and DW_LNE_end_sequence adds a row
      to the DWARF address/line matrix.  */
@@ -5373,7 +5187,6 @@ display_debug_macinfo (struct dwarf_section *section,
   unsigned char *start = section->start;
   unsigned char *end = start + section->size;
   unsigned char *curr = start;
-  unsigned int bytes_read;
   enum dwarf_macinfo_record_type op;
 
   introduce (section, FALSE);
@@ -5392,11 +5205,8 @@ display_debug_macinfo (struct dwarf_section *section,
   {
     unsigned int filenum;
 
-    lineno = read_uleb128 (curr, & bytes_read, end);
-    curr += bytes_read;
-    filenum = read_uleb128 (curr, & bytes_read, end);
-    curr += bytes_read;
-
+    READ_ULEB (lineno, curr, end);
+    READ_ULEB (filenum, curr, end);
     printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"),
     lineno, filenum);
   }
@@ -5407,8 +5217,7 @@ display_debug_macinfo (struct dwarf_section *section,
   break;
 
  case DW_MACINFO_define:
-  lineno = read_uleb128 (curr, & bytes_read, end);
-  curr += bytes_read;
+  READ_ULEB (lineno, curr, end);
   string = curr;
   curr += strnlen ((char *) string, end - string) + 1;
   printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"),
@@ -5416,8 +5225,7 @@ display_debug_macinfo (struct dwarf_section *section,
   break;
 
  case DW_MACINFO_undef:
-  lineno = read_uleb128 (curr, & bytes_read, end);
-  curr += bytes_read;
+  READ_ULEB (lineno, curr, end);
   string = curr;
   curr += strnlen ((char *) string, end - string) + 1;
   printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"),
@@ -5428,8 +5236,7 @@ display_debug_macinfo (struct dwarf_section *section,
   {
     unsigned int constant;
 
-    constant = read_uleb128 (curr, & bytes_read, end);
-    curr += bytes_read;
+    READ_ULEB (constant, curr, end);
     string = curr;
     curr += strnlen ((char *) string, end - string) + 1;
     printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"),
@@ -5454,7 +5261,7 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
   struct dwarf_section *section = &debug_displays [line].section;
   unsigned char *hdrptr, *dirtable, *file_name;
   unsigned int offset_size, initial_length_size;
-  unsigned int version, opcode_base, bytes_read;
+  unsigned int version, opcode_base;
   dwarf_vma length, diridx;
   const unsigned char * end;
 
@@ -5514,12 +5321,9 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
   for (; hdrptr < end && *hdrptr != '\0' && fileidx > 1; fileidx--)
     {
       hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
-      read_uleb128 (hdrptr, &bytes_read, end);
-      hdrptr += bytes_read;
-      read_uleb128 (hdrptr, &bytes_read, end);
-      hdrptr += bytes_read;
-      read_uleb128 (hdrptr, &bytes_read, end);
-      hdrptr += bytes_read;
+      SKIP_ULEB (hdrptr, end);
+      SKIP_ULEB (hdrptr, end);
+      SKIP_ULEB (hdrptr, end);
     }
   if (hdrptr >= end || *hdrptr == '\0')
     return NULL;
@@ -5528,7 +5332,7 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
   hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
   if (hdrptr >= end)
     return NULL;
-  diridx = read_uleb128 (hdrptr, &bytes_read, end);
+  READ_ULEB (diridx, hdrptr, end);
   if (diridx == 0)
     return file_name;
   for (; dirtable < end && *dirtable != '\0' && diridx > 1; diridx--)
@@ -5547,7 +5351,6 @@ display_debug_macro (struct dwarf_section *section,
   unsigned char *end = start + section->size;
   unsigned char *curr = start;
   unsigned char *extended_op_buf[256];
-  unsigned int bytes_read;
 
   load_debug_section_with_follow (str, file);
   load_debug_section_with_follow (line, file);
@@ -5599,8 +5402,7 @@ display_debug_macro (struct dwarf_section *section,
  {
   SAFE_BYTE_GET_AND_INC (op, curr, 1, end);
   extended_ops[op] = curr;
-  nargs = read_uleb128 (curr, &bytes_read, end);
-  curr += bytes_read;
+  READ_ULEB (nargs, curr, end);
   if (nargs == 0)
     printf (_("    DW_MACRO_%02x has no arguments\n"), op);
   else
@@ -5663,10 +5465,8 @@ display_debug_macro (struct dwarf_section *section,
  unsigned int filenum;
  unsigned char *file_name = NULL, *dir_name = NULL;
 
- lineno = read_uleb128 (curr, &bytes_read, end);
- curr += bytes_read;
- filenum = read_uleb128 (curr, &bytes_read, end);
- curr += bytes_read;
+ READ_ULEB (lineno, curr, end);
+ READ_ULEB (filenum, curr, end);
 
  if ((flags & 2) == 0)
   error (_("DW_MACRO_start_file used, but no .debug_line offset provided.\n"));
@@ -5690,8 +5490,7 @@ display_debug_macro (struct dwarf_section *section,
       break;
 
     case DW_MACRO_define:
-      lineno = read_uleb128 (curr, &bytes_read, end);
-      curr += bytes_read;
+      READ_ULEB (lineno, curr, end);
       string = curr;
       curr += strnlen ((char *) string, end - string) + 1;
       printf (_(" DW_MACRO_define - lineno : %d macro : %s\n"),
@@ -5699,8 +5498,7 @@ display_debug_macro (struct dwarf_section *section,
       break;
 
     case DW_MACRO_undef:
-      lineno = read_uleb128 (curr, &bytes_read, end);
-      curr += bytes_read;
+      READ_ULEB (lineno, curr, end);
       string = curr;
       curr += strnlen ((char *) string, end - string) + 1;
       printf (_(" DW_MACRO_undef - lineno : %d macro : %s\n"),
@@ -5708,8 +5506,7 @@ display_debug_macro (struct dwarf_section *section,
       break;
 
     case DW_MACRO_define_strp:
-      lineno = read_uleb128 (curr, &bytes_read, end);
-      curr += bytes_read;
+      READ_ULEB (lineno, curr, end);
       SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
       string = fetch_indirect_string (offset);
       printf (_(" DW_MACRO_define_strp - lineno : %d macro : %s\n"),
@@ -5717,8 +5514,7 @@ display_debug_macro (struct dwarf_section *section,
       break;
 
     case DW_MACRO_undef_strp:
-      lineno = read_uleb128 (curr, &bytes_read, end);
-      curr += bytes_read;
+      READ_ULEB (lineno, curr, end);
       SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
       string = fetch_indirect_string (offset);
       printf (_(" DW_MACRO_undef_strp - lineno : %d macro : %s\n"),
@@ -5732,16 +5528,14 @@ display_debug_macro (struct dwarf_section *section,
       break;
 
     case DW_MACRO_define_sup:
-      lineno = read_uleb128 (curr, &bytes_read, end);
-      curr += bytes_read;
+      READ_ULEB (lineno, curr, end);
       SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
       printf (_(" DW_MACRO_define_sup - lineno : %d macro offset : 0x%lx\n"),
       lineno, (unsigned long) offset);
       break;
 
     case DW_MACRO_undef_sup:
-      lineno = read_uleb128 (curr, &bytes_read, end);
-      curr += bytes_read;
+      READ_ULEB (lineno, curr, end);
       SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
       printf (_(" DW_MACRO_undef_sup - lineno : %d macro offset : 0x%lx\n"),
       lineno, (unsigned long) offset);
@@ -5764,8 +5558,7 @@ display_debug_macro (struct dwarf_section *section,
   /* Skip over unhandled opcodes.  */
   dwarf_vma nargs, n;
   unsigned char *desc = extended_ops[op];
-  nargs = read_uleb128 (desc, &bytes_read, end);
-  desc += bytes_read;
+  READ_ULEB (nargs, desc, end);
   if (nargs == 0)
     {
       printf (_(" DW_MACRO_%02x\n"), op);
@@ -5882,18 +5675,11 @@ display_view_pair_list (struct dwarf_section *section,
       dwarf_vma off = vstart - section->start;
       dwarf_vma vbegin, vend;
 
-      unsigned int bytes_read;
-      vbegin = read_uleb128 (vstart, &bytes_read, section_end);
-      vstart += bytes_read;
+      READ_ULEB (vbegin, vstart, section_end);
       if (vstart == section_end)
- {
-  vstart -= bytes_read;
-  break;
- }
-
-      vend = read_uleb128 (vstart, &bytes_read, section_end);
-      vstart += bytes_read;
+ break;
 
+      READ_ULEB (vend, vstart, section_end);
       printf ("    %8.8lx ", (unsigned long) off);
 
       print_dwarf_view (vbegin, pointer_size, 1);
@@ -5993,16 +5779,12 @@ display_loc_list (struct dwarf_section *section,
 
       if (vstart)
  {
-  unsigned int bytes_read;
-
   off = offset + (vstart - *start_ptr);
 
-  vbegin = read_uleb128 (vstart, &bytes_read, section_end);
-  vstart += bytes_read;
+  READ_ULEB (vbegin, vstart, section_end);
   print_dwarf_view (vbegin, pointer_size, 1);
 
-  vend = read_uleb128 (vstart, &bytes_read, section_end);
-  vstart += bytes_read;
+  READ_ULEB (vend, vstart, section_end);
   print_dwarf_view (vend, pointer_size, 1);
 
   printf (_("views at %8.8lx for:\n    %*s "),
@@ -6071,7 +5853,6 @@ display_loclists_list (struct dwarf_section *section,
   unsigned int pointer_size;
   unsigned int offset_size;
   int dwarf_version;
-  unsigned int bytes_read;
 
   /* Initialize it due to a false compiler warning.  */
   dwarf_vma begin = -1, vbegin = -1;
@@ -6119,12 +5900,10 @@ display_loclists_list (struct dwarf_section *section,
  {
   off = offset + (vstart - *start_ptr);
 
-  vbegin = read_uleb128 (vstart, &bytes_read, section_end);
-  vstart += bytes_read;
+  READ_ULEB (vbegin, vstart, section_end);
   print_dwarf_view (vbegin, pointer_size, 1);
 
-  vend = read_uleb128 (vstart, &bytes_read, section_end);
-  vstart += bytes_read;
+  READ_ULEB (vend, vstart, section_end);
   print_dwarf_view (vend, pointer_size, 1);
 
   printf (_("views at %8.8lx for:\n    %*s "),
@@ -6137,10 +5916,8 @@ display_loclists_list (struct dwarf_section *section,
   printf (_("<End of list>\n"));
   break;
  case DW_LLE_offset_pair:
-  begin = read_uleb128 (start, &bytes_read, section_end);
-  start += bytes_read;
-  end = read_uleb128 (start, &bytes_read, section_end);
-  start += bytes_read;
+  READ_ULEB (begin, start, section_end);
+  READ_ULEB (end, start, section_end);
   break;
  case DW_LLE_base_address:
   SAFE_BYTE_GET_AND_INC (base_address, start, pointer_size,
@@ -6152,12 +5929,10 @@ display_loclists_list (struct dwarf_section *section,
  case DW_LLE_view_pair:
   if (vstart)
     printf (_("View pair entry in loclist with locviews attribute\n"));
-  vbegin = read_uleb128 (start, &bytes_read, section_end);
-  start += bytes_read;
+  READ_ULEB (vbegin, start, section_end);
   print_dwarf_view (vbegin, pointer_size, 1);
 
-  vend = read_uleb128 (start, &bytes_read, section_end);
-  start += bytes_read;
+  READ_ULEB (vend, start, section_end);
   print_dwarf_view (vend, pointer_size, 1);
 
   printf (_("views for:\n"));
@@ -6179,8 +5954,7 @@ display_loclists_list (struct dwarf_section *section,
   break;
  }
 
-      length = read_uleb128 (start, &bytes_read, section_end);
-      start += bytes_read;
+      READ_ULEB (length, start, section_end);
 
       print_dwarf_vma (begin + base_address, pointer_size);
       print_dwarf_vma (end + base_address, pointer_size);
@@ -6248,7 +6022,6 @@ display_loc_list_dwo (struct dwarf_section *section,
   unsigned short length;
   int need_frame_base;
   unsigned int idx;
-  unsigned int bytes_read;
 
   if (debug_info_entry >= num_debug_info_entries)
     {
@@ -6295,12 +6068,10 @@ display_loc_list_dwo (struct dwarf_section *section,
       dwarf_vma view;
       dwarf_vma off = offset + (vstart - *start_ptr);
 
-      view = read_uleb128 (vstart, &bytes_read, section_end);
-      vstart += bytes_read;
+      READ_ULEB (view, vstart, section_end);
       print_dwarf_view (view, 8, 1);
 
-      view = read_uleb128 (vstart, &bytes_read, section_end);
-      vstart += bytes_read;
+      READ_ULEB (view, vstart, section_end);
       print_dwarf_view (view, 8, 1);
 
       printf (_("views at %8.8lx for:\n    %*s "),
@@ -6318,23 +6089,19 @@ display_loc_list_dwo (struct dwarf_section *section,
   printf (_("<End of list>\n"));
   return;
  case 1: /* A base-address entry.  */
-  idx = read_uleb128 (start, &bytes_read, section_end);
-  start += bytes_read;
+  READ_ULEB (idx, start, section_end);
   print_addr_index (idx, 8);
   printf ("%*s", 9 + (vstart ? 2 * 6 : 0), "");
   printf (_("(base address selection entry)\n"));
   continue;
  case 2: /* A start/end entry.  */
-  idx = read_uleb128 (start, &bytes_read, section_end);
-  start += bytes_read;
+  READ_ULEB (idx, start, section_end);
   print_addr_index (idx, 8);
-  idx = read_uleb128 (start, &bytes_read, section_end);
-  start += bytes_read;
+  READ_ULEB (idx, start, section_end);
   print_addr_index (idx, 8);
   break;
  case 3: /* A start/length entry.  */
-  idx = read_uleb128 (start, &bytes_read, section_end);
-  start += bytes_read;
+  READ_ULEB (idx, start, section_end);
   print_addr_index (idx, 8);
   SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
   printf ("%08x ", idx);
@@ -7079,7 +6846,6 @@ display_debug_rnglists_list (unsigned char *start, unsigned char *finish,
       enum dwarf_range_list_entry rlet;
       /* Initialize it due to a false compiler warning.  */
       dwarf_vma begin = -1, length, end = -1;
-      unsigned int bytes_read;
 
       if (start + 1 > finish)
  {
@@ -7104,15 +6870,12 @@ display_debug_rnglists_list (unsigned char *start, unsigned char *finish,
   break;
  case DW_RLE_start_length:
   SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish);
-  length = read_uleb128 (start, &bytes_read, finish);
-  start += bytes_read;
+  READ_ULEB (length, start, finish);
   end = begin + length;
   break;
  case DW_RLE_offset_pair:
-  begin = read_uleb128 (start, &bytes_read, finish);
-  start += bytes_read;
-  end = read_uleb128 (start, &bytes_read, finish);
-  start += bytes_read;
+  READ_ULEB (begin, start, finish);
+  READ_ULEB (end, start, finish);
   break;
  case DW_RLE_start_end:
   SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish);
@@ -7836,7 +7599,6 @@ read_cie (unsigned char *start, unsigned char *end,
 {
   int version;
   Frame_Chunk *fc;
-  unsigned int length_return;
   unsigned char *augmentation_data = NULL;
   bfd_size_type augmentation_data_len = 0;
 
@@ -7893,8 +7655,8 @@ read_cie (unsigned char *start, unsigned char *end,
       fc->segment_size = 0;
     }
 
-  READ_ULEB (fc->code_factor);
-  READ_SLEB (fc->data_factor);
+  READ_ULEB (fc->code_factor, start, end);
+  READ_SLEB (fc->data_factor, start, end);
 
   if (version == 1)
     {
@@ -7902,12 +7664,12 @@ read_cie (unsigned char *start, unsigned char *end,
     }
   else
     {
-      READ_ULEB (fc->ra);
+      READ_ULEB (fc->ra, start, end);
     }
 
   if (fc->augmentation[0] == 'z')
     {
-      READ_ULEB (augmentation_data_len);
+      READ_ULEB (augmentation_data_len, start, end);
       augmentation_data = start;
       /* PR 17512: file: 11042-2589-0.004.  */
       if (augmentation_data_len > (bfd_size_type) (end - start))
@@ -8014,7 +7776,6 @@ display_debug_frames (struct dwarf_section *section,
   Frame_Chunk *remembered_state = NULL;
   Frame_Chunk *rs;
   bfd_boolean is_eh = strcmp (section->name, ".eh_frame") == 0;
-  unsigned int length_return;
   unsigned int max_regs = 0;
   const char *bad_reg = _("bad register: ");
   unsigned int saved_eh_addr_size = eh_addr_size;
@@ -8279,7 +8040,7 @@ display_debug_frames (struct dwarf_section *section,
 
   if (cie->augmentation[0] == 'z')
     {
-      READ_ULEB (augmentation_data_len);
+      READ_ULEB (augmentation_data_len, start, end);
       augmentation_data = start;
       /* PR 17512 file: 722-8446-0.004 and PR 22386.  */
       if (augmentation_data_len > (bfd_size_type) (end - start))
@@ -8346,7 +8107,7 @@ display_debug_frames (struct dwarf_section *section,
  case DW_CFA_advance_loc:
   break;
  case DW_CFA_offset:
-  SKIP_ULEB ();
+  SKIP_ULEB (start, end);
   if (frame_need_space (fc, opa) >= 0)
     fc->col_type[opa] = DW_CFA_undefined;
   break;
@@ -8368,44 +8129,44 @@ display_debug_frames (struct dwarf_section *section,
   break;
  case DW_CFA_offset_extended:
  case DW_CFA_val_offset:
-  READ_ULEB (reg);
-  SKIP_ULEB ();
+  READ_ULEB (reg, start, end);
+  SKIP_ULEB (start, end);
   if (frame_need_space (fc, reg) >= 0)
     fc->col_type[reg] = DW_CFA_undefined;
   break;
  case DW_CFA_restore_extended:
-  READ_ULEB (reg);
+  READ_ULEB (reg, start, end);
   if (frame_need_space (fc, reg) >= 0)
     fc->col_type[reg] = DW_CFA_undefined;
   break;
  case DW_CFA_undefined:
-  READ_ULEB (reg);
+  READ_ULEB (reg, start, end);
   if (frame_need_space (fc, reg) >= 0)
     fc->col_type[reg] = DW_CFA_undefined;
   break;
  case DW_CFA_same_value:
-  READ_ULEB (reg);
+  READ_ULEB (reg, start, end);
   if (frame_need_space (fc, reg) >= 0)
     fc->col_type[reg] = DW_CFA_undefined;
   break;
  case DW_CFA_register:
-  READ_ULEB (reg);
-  SKIP_ULEB ();
+  READ_ULEB (reg, start, end);
+  SKIP_ULEB (start, end);
   if (frame_need_space (fc, reg) >= 0)
     fc->col_type[reg] = DW_CFA_undefined;
   break;
  case DW_CFA_def_cfa:
-  SKIP_ULEB ();
-  SKIP_ULEB ();
+  SKIP_ULEB (start, end);
+  SKIP_ULEB (start, end);
   break;
  case DW_CFA_def_cfa_register:
-  SKIP_ULEB ();
+  SKIP_ULEB (start, end);
   break;
  case DW_CFA_def_cfa_offset:
-  SKIP_ULEB ();
+  SKIP_ULEB (start, end);
   break;
  case DW_CFA_def_cfa_expression:
-  READ_ULEB (temp);
+  READ_ULEB (temp, start, end);
   new_start = start + temp;
   if (new_start < start)
     {
@@ -8417,8 +8178,8 @@ display_debug_frames (struct dwarf_section *section,
   break;
  case DW_CFA_expression:
  case DW_CFA_val_expression:
-  READ_ULEB (reg);
-  READ_ULEB (temp);
+  READ_ULEB (reg, start, end);
+  READ_ULEB (temp, start, end);
   new_start = start + temp;
   if (new_start < start)
     {
@@ -8433,27 +8194,27 @@ display_debug_frames (struct dwarf_section *section,
   break;
  case DW_CFA_offset_extended_sf:
  case DW_CFA_val_offset_sf:
-  READ_ULEB (reg);
-  SKIP_SLEB ();
+  READ_ULEB (reg, start, end);
+  SKIP_SLEB (start, end);
   if (frame_need_space (fc, reg) >= 0)
     fc->col_type[reg] = DW_CFA_undefined;
   break;
  case DW_CFA_def_cfa_sf:
-  SKIP_ULEB ();
-  SKIP_SLEB ();
+  SKIP_ULEB (start, end);
+  SKIP_SLEB (start, end);
   break;
  case DW_CFA_def_cfa_offset_sf:
-  SKIP_SLEB ();
+  SKIP_SLEB (start, end);
   break;
  case DW_CFA_MIPS_advance_loc8:
   start += 8;
   break;
  case DW_CFA_GNU_args_size:
-  SKIP_ULEB ();
+  SKIP_ULEB (start, end);
   break;
  case DW_CFA_GNU_negative_offset_extended:
-  READ_ULEB (reg);
-  SKIP_ULEB ();
+  READ_ULEB (reg, start, end);
+  SKIP_ULEB (start, end);
   if (frame_need_space (fc, reg) >= 0)
     fc->col_type[reg] = DW_CFA_undefined;
   break;
@@ -8509,7 +8270,7 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_offset:
-      READ_ULEB (roffs);
+      READ_ULEB (roffs, start, end);
       if (opa >= (unsigned int) fc->ncols)
  reg_prefix = bad_reg;
       if (! do_debug_frames_interp || *reg_prefix != '\0')
@@ -8596,8 +8357,8 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_offset_extended:
-      READ_ULEB (reg);
-      READ_ULEB (roffs);
+      READ_ULEB (reg, start, end);
+      READ_ULEB (roffs, start, end);
       if (reg >= (unsigned int) fc->ncols)
  reg_prefix = bad_reg;
       if (! do_debug_frames_interp || *reg_prefix != '\0')
@@ -8612,8 +8373,8 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_val_offset:
-      READ_ULEB (reg);
-      READ_ULEB (roffs);
+      READ_ULEB (reg, start, end);
+      READ_ULEB (roffs, start, end);
       if (reg >= (unsigned int) fc->ncols)
  reg_prefix = bad_reg;
       if (! do_debug_frames_interp || *reg_prefix != '\0')
@@ -8628,7 +8389,7 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_restore_extended:
-      READ_ULEB (reg);
+      READ_ULEB (reg, start, end);
       if (reg >= (unsigned int) fc->ncols)
  reg_prefix = bad_reg;
       if (! do_debug_frames_interp || *reg_prefix != '\0')
@@ -8650,7 +8411,7 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_undefined:
-      READ_ULEB (reg);
+      READ_ULEB (reg, start, end);
       if (reg >= (unsigned int) fc->ncols)
  reg_prefix = bad_reg;
       if (! do_debug_frames_interp || *reg_prefix != '\0')
@@ -8664,7 +8425,7 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_same_value:
-      READ_ULEB (reg);
+      READ_ULEB (reg, start, end);
       if (reg >= (unsigned int) fc->ncols)
  reg_prefix = bad_reg;
       if (! do_debug_frames_interp || *reg_prefix != '\0')
@@ -8678,8 +8439,8 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_register:
-      READ_ULEB (reg);
-      READ_ULEB (roffs);
+      READ_ULEB (reg, start, end);
+      READ_ULEB (roffs, start, end);
       if (reg >= (unsigned int) fc->ncols)
  reg_prefix = bad_reg;
       if (! do_debug_frames_interp || *reg_prefix != '\0')
@@ -8742,8 +8503,8 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_def_cfa:
-      READ_ULEB (fc->cfa_reg);
-      READ_ULEB (fc->cfa_offset);
+      READ_ULEB (fc->cfa_reg, start, end);
+      READ_ULEB (fc->cfa_offset, start, end);
       fc->cfa_exp = 0;
       if (! do_debug_frames_interp)
  printf ("  DW_CFA_def_cfa: %s ofs %d\n",
@@ -8751,7 +8512,7 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_def_cfa_register:
-      READ_ULEB (fc->cfa_reg);
+      READ_ULEB (fc->cfa_reg, start, end);
       fc->cfa_exp = 0;
       if (! do_debug_frames_interp)
  printf ("  DW_CFA_def_cfa_register: %s\n",
@@ -8759,7 +8520,7 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_def_cfa_offset:
-      READ_ULEB (fc->cfa_offset);
+      READ_ULEB (fc->cfa_offset, start, end);
       if (! do_debug_frames_interp)
  printf ("  DW_CFA_def_cfa_offset: %d\n", (int) fc->cfa_offset);
       break;
@@ -8770,7 +8531,7 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_def_cfa_expression:
-      READ_ULEB (ul);
+      READ_ULEB (ul, start, end);
       if (start >= block_end || ul > (unsigned long) (block_end - start))
  {
   printf (_("  DW_CFA_def_cfa_expression: <corrupt len %lu>\n"), ul);
@@ -8788,8 +8549,8 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_expression:
-      READ_ULEB (reg);
-      READ_ULEB (ul);
+      READ_ULEB (reg, start, end);
+      READ_ULEB (ul, start, end);
       if (reg >= (unsigned int) fc->ncols)
  reg_prefix = bad_reg;
       /* PR 17512: file: 069-133014-0.006.  */
@@ -8814,8 +8575,8 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_val_expression:
-      READ_ULEB (reg);
-      READ_ULEB (ul);
+      READ_ULEB (reg, start, end);
+      READ_ULEB (ul, start, end);
       if (reg >= (unsigned int) fc->ncols)
  reg_prefix = bad_reg;
       tmp = start + ul;
@@ -8838,8 +8599,8 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_offset_extended_sf:
-      READ_ULEB (reg);
-      READ_SLEB (l);
+      READ_ULEB (reg, start, end);
+      READ_SLEB (l, start, end);
       if (frame_need_space (fc, reg) < 0)
  reg_prefix = bad_reg;
       if (! do_debug_frames_interp || *reg_prefix != '\0')
@@ -8854,8 +8615,8 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_val_offset_sf:
-      READ_ULEB (reg);
-      READ_SLEB (l);
+      READ_ULEB (reg, start, end);
+      READ_SLEB (l, start, end);
       if (frame_need_space (fc, reg) < 0)
  reg_prefix = bad_reg;
       if (! do_debug_frames_interp || *reg_prefix != '\0')
@@ -8870,8 +8631,8 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_def_cfa_sf:
-      READ_ULEB (fc->cfa_reg);
-      READ_ULEB (fc->cfa_offset);
+      READ_ULEB (fc->cfa_reg, start, end);
+      READ_ULEB (fc->cfa_offset, start, end);
       fc->cfa_offset = fc->cfa_offset * fc->data_factor;
       fc->cfa_exp = 0;
       if (! do_debug_frames_interp)
@@ -8880,7 +8641,7 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_def_cfa_offset_sf:
-      READ_ULEB (fc->cfa_offset);
+      READ_ULEB (fc->cfa_offset, start, end);
       fc->cfa_offset *= fc->data_factor;
       if (! do_debug_frames_interp)
  printf ("  DW_CFA_def_cfa_offset_sf: %d\n", (int) fc->cfa_offset);
@@ -8905,14 +8666,14 @@ display_debug_frames (struct dwarf_section *section,
       break;
 
     case DW_CFA_GNU_args_size:
-      READ_ULEB (ul);
+      READ_ULEB (ul, start, end);
       if (! do_debug_frames_interp)
  printf ("  DW_CFA_GNU_args_size: %ld\n", ul);
       break;
 
     case DW_CFA_GNU_negative_offset_extended:
-      READ_ULEB (reg);
-      READ_SLEB (l);
+      READ_ULEB (reg, start, end);
+      READ_SLEB (l, start, end);
       l = - l;
       if (frame_need_space (fc, reg) < 0)
  reg_prefix = bad_reg;
@@ -9203,10 +8964,9 @@ display_debug_names (struct dwarf_section *section, void *file)
       unsigned char *abbrevptr = abbrev_table;
       for (;;)
  {
-  unsigned int bytes_read;
-  const dwarf_vma abbrev_tag = read_uleb128 (abbrevptr, &bytes_read,
-     abbrev_table_end);
-  abbrevptr += bytes_read;
+  dwarf_vma abbrev_tag;
+
+  READ_ULEB (abbrev_tag, abbrevptr, abbrev_table_end);
   if (abbrev_tag == 0)
     break;
   if (abbrev_lookup_used == abbrev_lookup_allocated)
@@ -9234,17 +8994,13 @@ display_debug_names (struct dwarf_section *section, void *file)
   entry->abbrev_lookup_ptr = abbrevptr;
 
   /* Skip DWARF tag.  */
-  read_uleb128 (abbrevptr, &bytes_read, abbrev_table_end);
-  abbrevptr += bytes_read;
+  SKIP_ULEB (abbrevptr, abbrev_table_end);
   for (;;)
     {
-      const dwarf_vma xindex = read_uleb128 (abbrevptr,
-     &bytes_read,
-     abbrev_table_end);
-      abbrevptr += bytes_read;
-      const dwarf_vma form = read_uleb128 (abbrevptr, &bytes_read,
-   abbrev_table_end);
-      abbrevptr += bytes_read;
+      dwarf_vma xindex, form;
+
+      READ_ULEB (xindex, abbrevptr, abbrev_table_end);
+      READ_ULEB (form, abbrevptr, abbrev_table_end);
       if (xindex == 0 && form == 0)
  break;
     }
@@ -9277,10 +9033,11 @@ display_debug_names (struct dwarf_section *section, void *file)
   dwarf_vma second_abbrev_tag = -1;
   for (;;)
     {
-      unsigned int bytes_read;
-      const dwarf_vma abbrev_tag = read_uleb128 (entryptr, &bytes_read,
- unit_end);
-      entryptr += bytes_read;
+      dwarf_vma abbrev_tag;
+      dwarf_vma dwarf_tag;
+      const struct abbrev_lookup_entry *entry;
+
+      READ_ULEB (abbrev_tag, entryptr, unit_end);
       if (tagno == -1)
  {
   second_abbrev_tag = abbrev_tag;
@@ -9295,7 +9052,6 @@ display_debug_names (struct dwarf_section *section, void *file)
         (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"),
  (unsigned long) abbrev_tag);
 
-      const struct abbrev_lookup_entry *entry;
       for (entry = abbrev_lookup;
    entry < abbrev_lookup + abbrev_lookup_used;
    entry++)
@@ -9310,20 +9066,15 @@ display_debug_names (struct dwarf_section *section, void *file)
   break;
  }
       abbrevptr = entry->abbrev_lookup_ptr;
-      const dwarf_vma dwarf_tag = read_uleb128 (abbrevptr, &bytes_read,
- abbrev_table_end);
-      abbrevptr += bytes_read;
+      READ_ULEB (dwarf_tag, abbrevptr, abbrev_table_end);
       if (tagno >= 0)
  printf (" %s", get_TAG_name (dwarf_tag));
       for (;;)
  {
-  const dwarf_vma xindex = read_uleb128 (abbrevptr,
- &bytes_read,
- abbrev_table_end);
-  abbrevptr += bytes_read;
-  const dwarf_vma form = read_uleb128 (abbrevptr, &bytes_read,
-       abbrev_table_end);
-  abbrevptr += bytes_read;
+  dwarf_vma xindex, form;
+
+  READ_ULEB (xindex, abbrevptr, abbrev_table_end);
+  READ_ULEB (form, abbrevptr, abbrev_table_end);
   if (xindex == 0 && form == 0)
     break;
 
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 5ea85d920a..cfb3abea3b 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -248,9 +248,65 @@ extern void * xcalloc2 (size_t, size_t);
 extern void * xcmalloc (size_t, size_t);
 extern void * xcrealloc (void *, size_t, size_t);
 
-extern dwarf_vma read_leb128 (unsigned char *, unsigned int *, bfd_boolean, const unsigned char * const);
-
 /* A callback into the client.  Returns TRUE if there is a
    relocation against the given debug section at the given
    offset.  */
 extern bfd_boolean reloc_at (struct dwarf_section *, dwarf_vma);
+
+extern dwarf_vma read_leb128 (unsigned char *, const unsigned char *const,
+      bfd_boolean, unsigned int *, int *);
+
+static inline void
+report_leb_status (int status)
+{
+  if ((status & 1) != 0)
+    error (_("LEB end of data\n"));
+  else if ((status & 2) != 0)
+    error (_("LEB value too large\n"));
+}
+
+#define SKIP_ULEB(start, end) \
+  do \
+    { \
+      unsigned int _len; \
+      read_leb128 (start, end, FALSE, &_len, NULL); \
+      start += _len; \
+    } while (0)
+
+#define SKIP_SLEB(start, end) \
+  do \
+    { \
+      unsigned int _len; \
+      read_leb128 (start, end, TRUE, &_len, NULL); \
+      start += _len; \
+    } while (0)
+
+#define READ_ULEB(var, start, end) \
+  do \
+    { \
+      dwarf_vma _val; \
+      unsigned int _len; \
+      int _status; \
+ \
+      _val = read_leb128 (start, end, FALSE, &_len, &_status); \
+      start += _len; \
+      (var) = _val; \
+      if ((var) != _val) \
+ _status |= 2; \
+      report_leb_status (_status); \
+    } while (0)
+
+#define READ_SLEB(var, start, end) \
+  do \
+    { \
+      dwarf_signed_vma _val; \
+      unsigned int _len; \
+      int _status; \
+ \
+      _val = read_leb128 (start, end, TRUE, &_len, &_status); \
+      start += _len; \
+      (var) = _val; \
+      if ((var) != _val) \
+ _status |= 2; \
+      report_leb_status (_status); \
+    } while (0)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 1d8f62bf50..0853c1f0a1 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -749,17 +749,6 @@ find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
   return find_section (filedata, name);
 }
 
-/* Read an unsigned LEB128 encoded value from DATA.
-   Set *LENGTH_RETURN to the number of bytes read.  */
-
-static inline unsigned long
-read_uleb128 (unsigned char * data,
-      unsigned int * length_return,
-      const unsigned char * const end)
-{
-  return read_leb128 (data, length_return, FALSE, end);
-}
-
 /* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
    This OS has so many departures from the ELF standard that we test it at
    many places.  */
@@ -8782,7 +8771,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
     }
   else
     {
-      offset = read_uleb128 (buf, &len, buf + i + 1);
+      offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
       assert (len == i + 1);
       offset = offset * 4 + 0x204;
       printf ("vsp = vsp + %ld", offset);
@@ -9001,7 +8990,7 @@ decode_tic6x_unwind_bytecode (Filedata *                 filedata,
       return FALSE;
     }
 
-  offset = read_uleb128 (buf, &len, buf + i + 1);
+  offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
   assert (len == i + 1);
   offset = offset * 8 + 0x408;
   printf (_("sp = sp + %ld"), offset);
@@ -14492,10 +14481,7 @@ display_tag_value (signed int tag,
     }
   else
     {
-      unsigned int len;
-
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("%ld (0x%lx)\n", val, val);
     }
 
@@ -14510,17 +14496,14 @@ display_arc_attribute (unsigned char * p,
        const unsigned char * const end)
 {
   unsigned int tag;
-  unsigned int len;
   unsigned int val;
 
-  tag = read_uleb128 (p, &len, end);
-  p += len;
+  READ_ULEB (tag, p, end);
 
   switch (tag)
     {
     case Tag_ARC_PCS_config:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_PCS_config: ");
       switch (val)
  {
@@ -14546,8 +14529,7 @@ display_arc_attribute (unsigned char * p,
       break;
 
     case Tag_ARC_CPU_base:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_CPU_base: ");
       switch (val)
  {
@@ -14571,8 +14553,7 @@ display_arc_attribute (unsigned char * p,
       break;
 
     case Tag_ARC_CPU_variation:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_CPU_variation: ");
       switch (val)
  {
@@ -14595,21 +14576,18 @@ display_arc_attribute (unsigned char * p,
       break;
 
     case Tag_ARC_ABI_rf16:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
       break;
 
     case Tag_ARC_ABI_osver:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_ABI_osver: v%d\n", val);
       break;
 
     case Tag_ARC_ABI_pic:
     case Tag_ARC_ABI_sda:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf (tag == Tag_ARC_ABI_sda ? "  Tag_ARC_ABI_sda: "
       : "  Tag_ARC_ABI_pic: ");
       switch (val)
@@ -14630,28 +14608,24 @@ display_arc_attribute (unsigned char * p,
       break;
 
     case Tag_ARC_ABI_tls:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
       break;
 
     case Tag_ARC_ABI_enumsize:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
       _("smallest"));
       break;
 
     case Tag_ARC_ABI_exceptions:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
       : _("default"));
       break;
 
     case Tag_ARC_ABI_double_size:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_ABI_double_size: %d\n", val);
       break;
 
@@ -14666,14 +14640,12 @@ display_arc_attribute (unsigned char * p,
       break;
 
     case Tag_ARC_ISA_mpy_option:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_ISA_mpy_option: %d\n", val);
       break;
 
     case Tag_ARC_ATR_version:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ARC_ATR_version: %d\n", val);
       break;
 
@@ -14818,14 +14790,12 @@ display_arm_attribute (unsigned char * p,
        const unsigned char * const end)
 {
   unsigned int tag;
-  unsigned int len;
   unsigned int val;
   arm_attr_public_tag * attr;
   unsigned i;
   unsigned int type;
 
-  tag = read_uleb128 (p, &len, end);
-  p += len;
+  READ_ULEB (tag, p, end);
   attr = NULL;
   for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
     {
@@ -14845,8 +14815,7 @@ display_arm_attribute (unsigned char * p,
   switch (tag)
     {
     case 7: /* Tag_CPU_arch_profile.  */
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       switch (val)
  {
  case 0: printf (_("None\n")); break;
@@ -14859,8 +14828,7 @@ display_arm_attribute (unsigned char * p,
       break;
 
     case 24: /* Tag_align_needed.  */
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       switch (val)
  {
  case 0: printf (_("None\n")); break;
@@ -14878,8 +14846,7 @@ display_arm_attribute (unsigned char * p,
       break;
 
     case 25: /* Tag_align_preserved.  */
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       switch (val)
  {
  case 0: printf (_("None\n")); break;
@@ -14898,8 +14865,7 @@ display_arm_attribute (unsigned char * p,
 
     case 32: /* Tag_compatibility.  */
       {
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
  printf (_("flag = %d, vendor = "), val);
  if (p < end - 1)
   {
@@ -14925,12 +14891,10 @@ display_arm_attribute (unsigned char * p,
       break;
 
     case 65: /* Tag_also_compatible_with.  */
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       if (val == 6 /* Tag_CPU_arch.  */)
  {
-  val = read_uleb128 (p, &len, end);
-  p += len;
+  READ_ULEB (val, p, end);
   if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
     printf ("??? (%d)\n", val);
   else
@@ -14955,8 +14919,7 @@ display_arm_attribute (unsigned char * p,
 
  default:
   assert (attr->type & 0x80);
-  val = read_uleb128 (p, &len, end);
-  p += len;
+  READ_ULEB (val, p, end);
   type = attr->type & 0x7f;
   if (val >= type)
     printf ("??? (%d)\n", val);
@@ -14974,19 +14937,16 @@ display_gnu_attribute (unsigned char * p,
        unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
        const unsigned char * const end)
 {
-  int tag;
-  unsigned int len;
+  unsigned int tag;
   unsigned int val;
 
-  tag = read_uleb128 (p, &len, end);
-  p += len;
+  READ_ULEB (tag, p, end);
 
   /* Tag_compatibility is the only generic GNU attribute defined at
      present.  */
   if (tag == 32)
     {
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
 
       printf (_("flag = %d, vendor = "), val);
       if (p == end)
@@ -15024,19 +14984,17 @@ display_power_gnu_attribute (unsigned char * p,
      unsigned int tag,
      const unsigned char * const end)
 {
-  unsigned int len;
   unsigned int val;
 
   if (tag == Tag_GNU_Power_ABI_FP)
     {
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_GNU_Power_ABI_FP: ");
-      if (len == 0)
+      if (p == end)
  {
   printf (_("<corrupt>\n"));
   return p;
  }
+      READ_ULEB (val, p, end);
 
       if (val > 15)
  printf ("(%#x), ", val);
@@ -15077,14 +15035,13 @@ display_power_gnu_attribute (unsigned char * p,
 
   if (tag == Tag_GNU_Power_ABI_Vector)
     {
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_GNU_Power_ABI_Vector: ");
-      if (len == 0)
+      if (p == end)
  {
   printf (_("<corrupt>\n"));
   return p;
  }
+      READ_ULEB (val, p, end);
 
       if (val > 3)
  printf ("(%#x), ", val);
@@ -15109,14 +15066,13 @@ display_power_gnu_attribute (unsigned char * p,
 
   if (tag == Tag_GNU_Power_ABI_Struct_Return)
     {
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_GNU_Power_ABI_Struct_Return: ");
-      if (len == 0)
+      if (p == end)
  {
   printf (_("<corrupt>\n"));
   return p;
  }
+      READ_ULEB (val, p, end);
 
       if (val > 2)
  printf ("(%#x), ", val);
@@ -15147,14 +15103,12 @@ display_s390_gnu_attribute (unsigned char * p,
     unsigned int tag,
     const unsigned char * const end)
 {
-  unsigned int len;
-  int val;
+  unsigned int val;
 
   if (tag == Tag_GNU_S390_ABI_Vector)
     {
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_GNU_S390_ABI_Vector: ");
+      READ_ULEB (val, p, end);
 
       switch (val)
  {
@@ -15262,21 +15216,18 @@ display_sparc_gnu_attribute (unsigned char * p,
      unsigned int tag,
      const unsigned char * const end)
 {
-  unsigned int len;
-  int val;
+  unsigned int val;
 
   if (tag == Tag_GNU_Sparc_HWCAPS)
     {
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_GNU_Sparc_HWCAPS: ");
       display_sparc_hwcaps (val);
       return p;
     }
   if (tag == Tag_GNU_Sparc_HWCAPS2)
     {
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_GNU_Sparc_HWCAPS2: ");
       display_sparc_hwcaps2 (val);
       return p;
@@ -15330,26 +15281,20 @@ display_mips_gnu_attribute (unsigned char * p,
 {
   if (tag == Tag_GNU_MIPS_ABI_FP)
     {
-      unsigned int len;
       unsigned int val;
 
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_GNU_MIPS_ABI_FP: ");
-
+      READ_ULEB (val, p, end);
       print_mips_fp_abi_value (val);
-
       return p;
    }
 
   if (tag == Tag_GNU_MIPS_ABI_MSA)
     {
-      unsigned int len;
       unsigned int val;
 
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_GNU_MIPS_ABI_MSA: ");
+      READ_ULEB (val, p, end);
 
       switch (val)
  {
@@ -15374,18 +15319,15 @@ display_tic6x_attribute (unsigned char * p,
  const unsigned char * const end)
 {
   unsigned int tag;
-  unsigned int len;
-  int val;
+  unsigned int val;
 
-  tag = read_uleb128 (p, &len, end);
-  p += len;
+  READ_ULEB (tag, p, end);
 
   switch (tag)
     {
     case Tag_ISA:
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_ISA: ");
+      READ_ULEB (val, p, end);
 
       switch (val)
  {
@@ -15417,9 +15359,8 @@ display_tic6x_attribute (unsigned char * p,
       return p;
 
     case Tag_ABI_wchar_t:
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_ABI_wchar_t: ");
+      READ_ULEB (val, p, end);
       switch (val)
  {
  case 0:
@@ -15438,9 +15379,8 @@ display_tic6x_attribute (unsigned char * p,
       return p;
 
     case Tag_ABI_stack_align_needed:
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_ABI_stack_align_needed: ");
+      READ_ULEB (val, p, end);
       switch (val)
  {
  case 0:
@@ -15456,8 +15396,7 @@ display_tic6x_attribute (unsigned char * p,
       return p;
 
     case Tag_ABI_stack_align_preserved:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ABI_stack_align_preserved: ");
       switch (val)
  {
@@ -15474,8 +15413,7 @@ display_tic6x_attribute (unsigned char * p,
       return p;
 
     case Tag_ABI_DSBT:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ABI_DSBT: ");
       switch (val)
  {
@@ -15492,8 +15430,7 @@ display_tic6x_attribute (unsigned char * p,
       return p;
 
     case Tag_ABI_PID:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ABI_PID: ");
       switch (val)
  {
@@ -15513,8 +15450,7 @@ display_tic6x_attribute (unsigned char * p,
       return p;
 
     case Tag_ABI_PIC:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ABI_PIC: ");
       switch (val)
  {
@@ -15531,8 +15467,7 @@ display_tic6x_attribute (unsigned char * p,
       return p;
 
     case Tag_ABI_array_object_alignment:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ABI_array_object_alignment: ");
       switch (val)
  {
@@ -15552,8 +15487,7 @@ display_tic6x_attribute (unsigned char * p,
       return p;
 
     case Tag_ABI_array_object_align_expected:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       printf ("  Tag_ABI_array_object_align_expected: ");
       switch (val)
  {
@@ -15574,8 +15508,7 @@ display_tic6x_attribute (unsigned char * p,
 
     case Tag_ABI_compatibility:
       {
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
  printf ("  Tag_ABI_compatibility: ");
  printf (_("flag = %d, vendor = "), val);
  if (p < end - 1)
@@ -15666,19 +15599,16 @@ static unsigned char *
 display_msp430x_attribute (unsigned char * p,
    const unsigned char * const end)
 {
-  unsigned int len;
   unsigned int val;
   unsigned int tag;
 
-  tag = read_uleb128 (p, & len, end);
-  p += len;
+  READ_ULEB (tag, p, end);
 
   switch (tag)
     {
     case OFBA_MSPABI_Tag_ISA:
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_ISA: ");
+      READ_ULEB (val, p, end);
       switch (val)
  {
  case 0: printf (_("None\n")); break;
@@ -15689,9 +15619,8 @@ display_msp430x_attribute (unsigned char * p,
       break;
 
     case OFBA_MSPABI_Tag_Code_Model:
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_Code_Model: ");
+      READ_ULEB (val, p, end);
       switch (val)
  {
  case 0: printf (_("None\n")); break;
@@ -15702,9 +15631,8 @@ display_msp430x_attribute (unsigned char * p,
       break;
 
     case OFBA_MSPABI_Tag_Data_Model:
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_Data_Model: ");
+      READ_ULEB (val, p, end);
       switch (val)
  {
  case 0: printf (_("None\n")); break;
@@ -15737,8 +15665,7 @@ display_msp430x_attribute (unsigned char * p,
  }
       else
  {
-  val = read_uleb128 (p, &len, end);
-  p += len;
+  READ_ULEB (val, p, end);
   printf ("%d (0x%x)\n", val, val);
  }
       break;
@@ -15755,12 +15682,10 @@ display_msp430_gnu_attribute (unsigned char * p,
 {
   if (tag == Tag_GNU_MSP430_Data_Region)
     {
-      unsigned int len;
-      int val;
+      unsigned int val;
 
-      val = read_uleb128 (p, &len, end);
-      p += len;
       printf ("  Tag_GNU_MSP430_Data_Region: ");
+      READ_ULEB (val, p, end);
 
       switch (val)
  {
@@ -15771,7 +15696,7 @@ display_msp430_gnu_attribute (unsigned char * p,
   printf (_("Lower Region Only\n"));
   break;
  default:
-  printf ("??? (%d)\n", val);
+  printf ("??? (%u)\n", val);
  }
       return p;
     }
@@ -15780,7 +15705,7 @@ display_msp430_gnu_attribute (unsigned char * p,
 
 struct riscv_attr_tag_t {
   const char *name;
-  int tag;
+  unsigned int tag;
 };
 
 static struct riscv_attr_tag_t riscv_attr_tag[] =
@@ -15799,14 +15724,12 @@ static unsigned char *
 display_riscv_attribute (unsigned char *p,
  const unsigned char * const end)
 {
-  unsigned int len;
-  int val;
-  int tag;
+  unsigned int val;
+  unsigned int tag;
   struct riscv_attr_tag_t *attr = NULL;
   unsigned i;
 
-  tag = read_uleb128 (p, &len, end);
-  p += len;
+  READ_ULEB (tag, p, end);
 
   /* Find the name of attribute. */
   for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
@@ -15828,13 +15751,11 @@ display_riscv_attribute (unsigned char *p,
     case Tag_RISCV_priv_spec:
     case Tag_RISCV_priv_spec_minor:
     case Tag_RISCV_priv_spec_revision:
-      val = read_uleb128 (p, &len, end);
-      p += len;
-      printf (_("%d\n"), val);
+      READ_ULEB (val, p, end);
+      printf (_("%u\n"), val);
       break;
     case Tag_RISCV_unaligned_access:
-      val = read_uleb128 (p, &len, end);
-      p += len;
+      READ_ULEB (val, p, end);
       switch (val)
  {
  case 0:
@@ -15846,9 +15767,8 @@ display_riscv_attribute (unsigned char *p,
  }
       break;
     case Tag_RISCV_stack_align:
-      val = read_uleb128 (p, &len, end);
-      p += len;
-      printf (_("%d-bytes\n"), val);
+      READ_ULEB (val, p, end);
+      printf (_("%u-bytes\n"), val);
       break;
     case Tag_RISCV_arch:
       p = display_tag_value (-1, p, end);
@@ -15967,7 +15887,7 @@ process_attributes (Filedata * filedata,
       while (attr_len > 0 && p < contents + sect->sh_size)
  {
   int tag;
-  int val;
+  unsigned int val;
   bfd_vma size;
   unsigned char * end;
 
@@ -16018,10 +15938,7 @@ process_attributes (Filedata * filedata,
     do_numlist:
       for (;;)
  {
-  unsigned int j;
-
-  val = read_uleb128 (p, &j, end);
-  p += j;
+  READ_ULEB (val, p, end);
   if (val == 0)
     break;
   printf (" %d", val);

--
Alan Modra
Australia Development Lab, IBM
Reply | Threaded
Open this post in threaded view
|

Committed: fix binutils/dwarf.c after "Revise sleb128 and uleb128 reader"

Hans-Peter Nilsson
> From: Alan Modra <[hidden email]>
> Date: Mon, 23 Dec 2019 08:31:14 +0100

> This patch catches and reports errors when reading leb128 values,
> addressing a FIXME in read_leb128.

> * dwarf.c: Use above macros throughout file.  Formatting.
...
> (display_debug_lines_decoded): Likewise.  Properly check for end
> of DW_LNS_extended_op.

gcc -O2 -m32 -DHAVE_CONFIG_H -I. -I/tmp/hpautotest-binutils/bsrc/src/binutils  -I. -I/tmp/hpautotest-binutils/bsrc/src/binutils -I../bfd -I/tmp/hpautotest-binutils/bsrc/src/binutils/../bfd -I/tmp/hpautotest-binutils/bsrc/src/binutils/../include -DLOCALEDIR="\"/usr/local/share/locale\"" -Dbin_dummy_emulation=bin_vanilla_emulation  -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -Werror -I/tmp/hpautotest-binutils/bsrc/src/binutils/../zlib -g -O2 -MT dwarf.o -MD -MP -MF $depbase.Tpo -c -o dwarf.o /tmp/hpautotest-binutils/bsrc/src/binutils/dwarf.c &&\
mv -f $depbase.Tpo $depbase.Po
In file included from /tmp/hpautotest-binutils/bsrc/src/binutils/sysdep.h:151:0,
                 from /tmp/hpautotest-binutils/bsrc/src/binutils/dwarf.c:21:
/tmp/hpautotest-binutils/bsrc/src/binutils/dwarf.c: In function 'display_debug_lines_decoded':
/tmp/hpautotest-binutils/bsrc/src/binutils/dwarf.c:4719:19: error: format '%ld' expects argument of type 'long int', but argument 3 has type 'int' [-Werror=format=]
         printf (_("UNKNOWN (%u): length %ld\n"),
                   ^
/tmp/hpautotest-binutils/bsrc/src/binutils/dwarf.c:4719:17: note: in expansion of macro '_'
         printf (_("UNKNOWN (%u): length %ld\n"),
                 ^
cc1: all warnings being treated as errors
Makefile:1085: recipe for target 'dwarf.o' failed
make[4]: *** [dwarf.o] Error 1
make[4]: Leaving directory '/tmp/hpautotest-binutils/cris-axis-elf/binutils'
make[3]: *** [all-recursive] Error 1

(Key issue: "32-bit build".  See options and file paths for full build context.)

Fixes the build (and tests fine for cris-elf), committed as obvious:

binutils:    
    * dwarf.c (display_debug_lines_decoded): Cast printf parameter to
    format type to correct last change.

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 30abee5..9797312 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -4717,7 +4717,7 @@ display_debug_lines_decoded (struct dwarf_section *  section,
 
     default:
       printf (_("UNKNOWN (%u): length %ld\n"),
-      ext_op_code, op_code_data - data);
+      ext_op_code, (long int) (op_code_data - data));
       break;
     }
   data = op_code_end;

Merry Christmas.
brgds, H-P
Reply | Threaded
Open this post in threaded view
|

Re: Revise sleb128 and uleb128 reader

Alan Modra-3
In reply to this post by Alan Modra-3
A missing part of git commit cd30bcef4a685.

        * od-macho.c: Include elfcomm.h.
        (dump_dyld_info_rebase, dump_dyld_info_bind): Fix read_leb128 args.
        (dump_dyld_info_export_1, dump_segment_split_info): Likewise.

diff --git a/binutils/od-macho.c b/binutils/od-macho.c
index ada86b5236..1c75c5dbcc 100644
--- a/binutils/od-macho.c
+++ b/binutils/od-macho.c
@@ -26,6 +26,7 @@
 #include "bfd.h"
 #include "objdump.h"
 #include "bucomm.h"
+#include "elfcomm.h"
 #include "dwarf.h"
 #include "bfdlink.h"
 #include "mach-o.h"
@@ -709,13 +710,13 @@ dump_dyld_info_rebase (bfd *abfd, unsigned char *buf, unsigned int len,
   bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
   break;
  case BFD_MACH_O_REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("set segment: %u and offset: 0x%08x\n",
   imm, (unsigned) leb);
   i += leblen;
   break;
  case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_ULEB:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
   i += leblen;
   break;
@@ -726,20 +727,20 @@ dump_dyld_info_rebase (bfd *abfd, unsigned char *buf, unsigned int len,
   printf ("rebase imm times: %u\n", imm);
   break;
  case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("rebase uleb times: %u\n", (unsigned) leb);
   i += leblen;
   break;
  case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("rebase add addr uleb: %u\n", (unsigned) leb);
   i += leblen;
   break;
  case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("rebase uleb times (%u)", (unsigned) leb);
   i += leblen;
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf (" skipping uleb (%u)\n", (unsigned) leb);
   i += leblen;
   break;
@@ -776,7 +777,7 @@ dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len,
   printf ("set dylib ordinal imm: %u\n", imm);
   break;
  case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("set dylib ordinal uleb: %u\n", imm);
   i += leblen;
   break;
@@ -799,19 +800,19 @@ dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len,
  case BFD_MACH_O_BIND_OPCODE_SET_ADDEND_SLEB:
   {
     bfd_signed_vma svma;
-    svma = read_leb128 (buf + i, &leblen, 0, buf + len);
+    svma = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
     printf ("set addend sleb: 0x%08x\n", (unsigned) svma);
     i += leblen;
   }
   break;
  case BFD_MACH_O_BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("set segment: %u and offset: 0x%08x\n",
   imm, (unsigned) leb);
   i += leblen;
   break;
  case BFD_MACH_O_BIND_OPCODE_ADD_ADDR_ULEB:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
   i += leblen;
   break;
@@ -819,7 +820,7 @@ dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len,
   printf ("do bind\n");
   break;
  case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("do bind add addr uleb: 0x%08x\n", (unsigned) leb);
   i += leblen;
   break;
@@ -827,10 +828,10 @@ dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len,
   printf ("do bind add addr imm scaled: %u\n", imm * ptrsize);
   break;
  case BFD_MACH_O_BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf ("do bind uleb times (%u)", (unsigned) leb);
   i += leblen;
-  leb = read_leb128 (buf + i, &leblen, 0, buf + len);
+  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
   printf (" skipping uleb (%u)\n", (unsigned) leb);
   i += leblen;
   break;
@@ -858,7 +859,7 @@ dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
   unsigned int child_count;
   unsigned int i;
 
-  size = read_leb128 (buf + off, &leblen, 0, buf + len);
+  size = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
   off += leblen;
 
   if (size != 0)
@@ -866,7 +867,7 @@ dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
       bfd_vma flags;
       struct export_info_data *d;
 
-      flags = read_leb128 (buf + off, &leblen, 0, buf + len);
+      flags = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
       off += leblen;
 
       fputs ("   ", stdout);
@@ -889,7 +890,7 @@ dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
  {
   bfd_vma lib;
 
-  lib = read_leb128 (buf + off, &leblen, 0, buf + len);
+  lib = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
   off += leblen;
 
   fputs (" [reexport] ", stdout);
@@ -911,12 +912,12 @@ dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
   bfd_vma offset;
   bfd_vma resolv = 0;
 
-  offset = read_leb128 (buf + off, &leblen, 0, buf + len);
+  offset = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
   off += leblen;
 
   if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
     {
-      resolv = read_leb128 (buf + off, &leblen, 0, buf + len);
+      resolv = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
       off += leblen;
     }
 
@@ -929,7 +930,7 @@ dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
  }
     }
 
-  child_count = read_leb128 (buf + off, &leblen, 0, buf + len);
+  child_count = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
   off += leblen;
 
   for (i = 0; i < child_count; i++)
@@ -943,7 +944,7 @@ dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
 
       off += strlen ((const char *)buf + off) + 1;
 
-      sub_off = read_leb128 (buf + off, &leblen, 0, buf + len);
+      sub_off = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
       off += leblen;
 
       dump_dyld_info_export_1 (abfd, buf, len, sub_off, &sub_data, base);
@@ -1311,7 +1312,7 @@ dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
     }
   for (p = buf + 1; *p != 0; p += len)
     {
-      addr += read_leb128 (p, &len, 0, buf + cmd->datasize);
+      addr += read_leb128 (p, buf + cmd->datasize, 0, &len, NULL);
       fputs ("    ", stdout);
       bfd_printf_vma (abfd, addr);
       putchar ('\n');

--
Alan Modra
Australia Development Lab, IBM