+2021-02-17  Alan Modra  <amodra@gmail.com>
+
+       * wasm-module.c: Guard include of limits.h.
+       (CHAR_BIT): Provide backup define.
+       (wasm_read_leb128): Use CHAR_BIT to size "result" in bits.
+       Correct signed overflow checking.
+
 2021-02-17  Nelson Chu  <nelson.chu@sifive.com>
 
        PR 27200
 
 #include "sysdep.h"
 #include "alloca-conf.h"
 #include "bfd.h"
-#include <limits.h>
 #include "libiberty.h"
 #include "libbfd.h"
 #include "wasm-module.h"
 
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
 typedef struct
 {
   asymbol *      symbols;
   unsigned int num_read = 0;
   unsigned int shift = 0;
   unsigned char byte = 0;
+  unsigned char lost, mask;
   int status = 1;
 
   while (bfd_bread (&byte, 1, abfd) == 1)
     {
       num_read++;
 
-      if (shift < sizeof (result) * 8)
+      if (shift < CHAR_BIT * sizeof (result))
        {
          result |= ((bfd_vma) (byte & 0x7f)) << shift;
-         if ((result >> shift) != (byte & 0x7f))
-           /* Overflow.  */
-           status |= 2;
+         /* These bits overflowed.  */
+         lost = byte ^ (result >> shift);
+         /* And this is the mask of possible overflow bits.  */
+         mask = 0x7f ^ ((bfd_vma) 0x7f << shift >> shift);
          shift += 7;
        }
-      else if ((byte & 0x7f) != 0)
+      else
+       {
+         lost = byte;
+         mask = 0x7f;
+       }
+      if ((lost & mask) != (sign && (bfd_signed_vma) result < 0 ? mask : 0))
        status |= 2;
 
       if ((byte & 0x80) == 0)
        {
          status &= ~1;
-         if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
+         if (sign && shift < CHAR_BIT * sizeof (result) && (byte & 0x40))
            result |= -((bfd_vma) 1 << shift);
          break;
        }
 
+2021-02-17  Alan Modra  <amodra@gmail.com>
+
+       * dwarf.c: Include limits.h.
+       (CHAR_BIT): Provide backup define.
+       (read_leb128): Use CHAR_BIT to size "result" in bits.  Correct
+       signed overflow checking.
+       * testsuite/binutils-all/pr26548.s,
+       * testsuite/binutils-all/pr26548.d,
+       * testsuite/binutils-all/pr26548e.d: New tests.
+       * testsuite/binutils-all/readelf.exp: Run them.
+       (readelf_test): Drop unused "xfails" parameter.  Update all uses.
+
 2021-02-16  Jan Beulich  <jbeulich@suse.com>
 
        * dwarf.c (process_debug_info): Initialize "dwo_id".
 
 #include <elfutils/debuginfod.h>
 #endif
 
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
 #undef MAX
 #undef MIN
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 /* 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
+   If STATUS_RETURN is 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.  */
   while (data < end)
     {
       unsigned char byte = *data++;
-      bfd_boolean cont = (byte & 0x80) ? TRUE : FALSE;
+      unsigned char lost, mask;
 
-      byte &= 0x7f;
       num_read++;
 
-      if (shift < sizeof (result) * 8)
+      if (shift < CHAR_BIT * sizeof (result))
        {
-         result |= ((dwarf_vma) byte) << shift;
-         if (sign)
-           {
-             if ((((dwarf_signed_vma) result >> shift) & 0x7f) != byte)
-               /* Overflow.  */
-               status |= 2;
-           }
-         else if ((result >> shift) != byte)
-           {
-             /* Overflow.  */
-             status |= 2;
-           }
-
+         result |= ((dwarf_vma) (byte & 0x7f)) << shift;
+         /* These bits overflowed.  */
+         lost = byte ^ (result >> shift);
+         /* And this is the mask of possible overflow bits.  */
+         mask = 0x7f ^ ((dwarf_vma) 0x7f << shift >> shift);
          shift += 7;
        }
-      else if (byte != 0)
+      else
        {
-         status |= 2;
+         lost = byte;
+         mask = 0x7f;
        }
+      if ((lost & mask) != (sign && (dwarf_signed_vma) result < 0 ? mask : 0))
+       status |= 2;
 
-      if (!cont)
+      if ((byte & 0x80) == 0)
        {
          status &= ~1;
-         if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
+         if (sign && shift < CHAR_BIT * sizeof (result) && (byte & 0x40))
            result |= -((dwarf_vma) 1 << shift);
          break;
        }
 
--- /dev/null
+#source: pr26548.s
+#as:
+#readelf: -Wwi
+
+#...
+.*: Abbrev Number: 1 \(DW_TAG_variable\)
+.*   DW_AT_const_value : \(sdata\) 9223372036854775807
+.*: Abbrev Number: 1 \(DW_TAG_variable\)
+.*   DW_AT_const_value : \(sdata\) -9223372036854775808
+.*: Abbrev Number: 1 \(DW_TAG_variable\)
+.*   DW_AT_const_value : \(sdata\) -1
+.*: Abbrev Number: 1 \(DW_TAG_variable\)
+.*   DW_AT_const_value : \(sdata\) 1
 
--- /dev/null
+       .section .debug_abbrev
+1:
+       .uleb128 1
+# DW_TAG_variable
+       .uleb128 0x34
+# no children
+       .byte 0
+# DW_AT_const_value
+       .uleb128 0x1c
+# DW_FORM_sdata
+       .uleb128 0x0d
+       .byte 0,0
+       .byte 0
+
+       .section .debug_info
+       .4byte 9f-0f
+0:
+       .2byte 4
+       .4byte 1b
+       .byte 8
+ .ifndef ERROR
+       .uleb128 1
+       .sleb128  0x7fffffffffffffff
+       .uleb128 1
+       .sleb128 -0x8000000000000000
+       .uleb128 1
+# silly excess byte encoding of -1, no warning
+       .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f
+       .uleb128 1
+# silly excess byte encoding of 1, no warning
+       .byte 0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0
+ .else
+       .uleb128 1
+# encode +0x8000000000000000, readelf warning
+       .byte 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x01
+       .uleb128 1
+# encode -0x8000000000000001, readelf warning
+       .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e
+ .endif
+9:
 
--- /dev/null
+#source: pr26548.s
+#as: --defsym ERROR=1
+#readelf: -Wwi
+
+#...
+.*: Abbrev Number: 1 \(DW_TAG_variable\)
+.*   DW_AT_const_value : \(sdata\).*LEB value.*
+ -9223372036854775808
+.*: Abbrev Number: 1 \(DW_TAG_variable\)
+.*   DW_AT_const_value : \(sdata\).*LEB value.*
+ 9223372036854775807
 
 # Readelf's output is captured and then compared against the contents
 # of the regexp_file-readelf_size if it exists, else regexp_file.
 
-proc readelf_test { options binary_file regexp_file xfails } {
+proc readelf_test { options binary_file regexp_file } {
 
     global READELF
     global READELFFLAGS
     send_log "exec $READELF $READELFFLAGS $options $binary_file > readelf.out\n"
     set got [remote_exec host "$READELF $READELFFLAGS $options $binary_file" "" "/dev/null" "readelf.out"]
 
-    foreach xfail $xfails {
-       setup_xfail $xfail
-    }
-
     if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
        fail "$testname (reason: unexpected output)"
        send_log $got
     readelf_find_size $tempfile 1
 
     # Run the tests.
-    readelf_test -h $tempfile readelf.h  {}
-    readelf_test -S $tempfile readelf.s  {}
+    readelf_test -h $tempfile readelf.h
+    readelf_test -S $tempfile readelf.s
     setup_xfail "mips-*-*irix*"
-    readelf_test -s $tempfile readelf.ss {}
-    readelf_test -r $tempfile readelf.r  {}
+    readelf_test -s $tempfile readelf.ss
+    readelf_test -r $tempfile readelf.r
 }
 
 # Test demangling symbol names.
     }
 
     # Run the test.
-    readelf_test {--syms --demangle --wide} $tempfile readelf.demangled {}
+    readelf_test {--syms --demangle --wide} $tempfile readelf.demangled
 }
 
 readelf_wi_test
     run_dump_test "retain1b"
     run_dump_test "readelf-maskos-1a"
     run_dump_test "readelf-maskos-1b"
+    if {$readelf_size == 64 && ![istarget *-*-hpux*]} then {
+       run_dump_test pr26548
+       if {![binutils_assemble_flags $srcdir/$subdir/pr26548.s tmpdir/pr26548e.o {--defsym ERROR=1}]} then {
+           unsupported "pr26548e (failed to assemble)"
+       } else {
+           if ![is_remote host] {
+               set tempfile tmpdir/pr26548e.o
+           } else {
+               set tempfile [remote_download host tmpdir/pr26548e.o]
+           }
+           readelf_test -Wwi $tempfile pr26548e.d
+       }
+    }
 }
 
 # PR 13482 - Check for off-by-one errors when dumping .note sections.
        set tempfile [remote_download host tmpdir/version.o]
     }
 
-    readelf_test -n $tempfile readelf.n  {}
+    readelf_test -n $tempfile readelf.n
 }
 
 
        set tempfile [remote_download host tmpdir/pr18374.o]
     }
 
-    readelf_test --debug-dump=loc $tempfile readelf.pr18374  {}
+    readelf_test --debug-dump=loc $tempfile readelf.pr18374
 }
 
 
        set tempfile [remote_download host tmpdir/locview-1.o]
     }
 
-    readelf_test --debug-dump=loc $tempfile readelf.locview-1  {}
+    readelf_test --debug-dump=loc $tempfile readelf.locview-1
 }
 if {![binutils_assemble $srcdir/$subdir/locview-2.s tmpdir/locview-2.o]} then {
     unsupported "readelf --debug-dump=loc locview-2 (failed to assemble)"
        set tempfile [remote_download host tmpdir/locview-2.o]
     }
 
-    readelf_test --debug-dump=loc $tempfile readelf.locview-2  {}
+    readelf_test --debug-dump=loc $tempfile readelf.locview-2
 }
 
 
        set tempfile [remote_download host tmpdir/z.o]
     }
 
-    readelf_test {--decompress --hex-dump .debug_loc} $tempfile readelf.z  {}
+    readelf_test {--decompress --hex-dump .debug_loc} $tempfile readelf.z
 }
 
 # Skip the next test for the RISCV architectures because they
        readelf_find_size $tempfile 2
 
        # Make sure that readelf can decode the contents.
-       readelf_test -wiaoRlL $tempfile dw5.W {}
+       readelf_test -wiaoRlL $tempfile dw5.W
     }
 }
 
     readelf_find_size $tempfile 3
 
     # Make sure that readelf can decode the contents.
-    readelf_test -wi $tempfile dwarf-attributes.W {}
+    readelf_test -wi $tempfile dwarf-attributes.W
 }
 
 # Check that debug link sections can be dumped.
        set tempfile [remote_download host tmpdir/debuglink.o]
     }
 
-    readelf_test {--debug-dump=links -wN} $tempfile readelf.k  {}
+    readelf_test {--debug-dump=links -wN} $tempfile readelf.k
 
     # Check that debug link sections can be followed.
     if {![binutils_assemble $srcdir/$subdir/linkdebug.s tmpdir/linkdebug.debug]} then {
            set tempfile2 [remote_download host tmpdir/linkdebug.debug]
        }
 
-       readelf_test {-wKis} $tempfile readelf.wKis  {}
+       readelf_test {-wKis} $tempfile readelf.wKis
     }
 }
 
        set tempfile [remote_download host tmpdir/dwo.o]
     }
 
-    readelf_test {--debug-dump=links --debug-dump=no-follow-links} $tempfile readelf.k2  {}
+    readelf_test {--debug-dump=links --debug-dump=no-follow-links} $tempfile readelf.k2
 }
 
 if {![binutils_assemble $srcdir/$subdir/zero-sec.s tmpdir/zero-sec.o]} then {
        set tempfile [remote_download host tmpdir/zero-sec.o]
     }
 
-    readelf_test {--enable-checks --sections --wide} $tempfile zero-sec.r {}
+    readelf_test {--enable-checks --sections --wide} $tempfile zero-sec.r
 }
 
 if ![is_remote host] {
     if {[catch "system \"bzip2 -dc $test > $tempfile\""] != 0} {
        untested "bzip2 -dc ($testname)"
     } else {
-       readelf_test {--debug-dump=macro -wN} $tempfile pr26112.r {}
+       readelf_test {--debug-dump=macro -wN} $tempfile pr26112.r
     }
 }
 
+2021-02-17  Alan Modra  <amodra@gmail.com>
+
+       * wasm32-dis.c: Include limits.h.
+       (CHAR_BIT): Provide backup define.
+       (wasm_read_leb128): Use CHAR_BIT to size "result" in bits.
+       Correct signed overflow checking.
+
 2021-02-16  Jan Beulich  <jbeulich@suse.com>
 
        * i386-opc.tbl: Split CVTPI2PD template. Add SSE2AVX variant.
 
 #include "elf/wasm32.h"
 #include "bfd_stdint.h"
 
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
 /* Type names for blocks and signatures.  */
 #define BLOCK_TYPE_NONE              0x40
 #define BLOCK_TYPE_I32               0x7f
   unsigned int num_read = 0;
   unsigned int shift = 0;
   unsigned char byte = 0;
+  unsigned char lost, mask;
   int status = 1;
 
   while (info->read_memory_func (pc + num_read, &byte, 1, info) == 0)
     {
       num_read++;
 
-      if (shift < sizeof (result) * 8)
+      if (shift < CHAR_BIT * sizeof (result))
        {
          result |= ((uint64_t) (byte & 0x7f)) << shift;
-         if ((result >> shift) != (byte & 0x7f))
-           /* Overflow.  */
-           status |= 2;
+         /* These bits overflowed.  */
+         lost = byte ^ (result >> shift);
+         /* And this is the mask of possible overflow bits.  */
+         mask = 0x7f ^ ((uint64_t) 0x7f << shift >> shift);
          shift += 7;
        }
-      else if ((byte & 0x7f) != 0)
+      else
+       {
+         lost = byte;
+         mask = 0x7f;
+       }
+      if ((lost & mask) != (sign && (int64_t) result < 0 ? mask : 0))
        status |= 2;
 
       if ((byte & 0x80) == 0)
        {
          status &= ~1;
-         if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
+         if (sign && shift < CHAR_BIT * sizeof (result) && (byte & 0x40))
            result |= -((uint64_t) 1 << shift);
          break;
        }