aboutsummaryrefslogtreecommitdiff
path: root/bfd/wasm-module.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/wasm-module.c')
-rw-r--r--bfd/wasm-module.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/bfd/wasm-module.c b/bfd/wasm-module.c
index dc13564..a8f6547 100644
--- a/bfd/wasm-module.c
+++ b/bfd/wasm-module.c
@@ -28,11 +28,17 @@
#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;
@@ -111,27 +117,34 @@ wasm_read_leb128 (bfd * abfd,
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;
}