aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2012-10-03 22:07:12 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-10-03 22:07:12 +0000
commitbe4ba8aef398e6177b62d3ced6c9a086082d94f2 (patch)
tree0b7f834cad3ef78befbe7181d423d4ee7dde5768
parent91ba65f2f0cacac286907b8a465f42b4e56aeda3 (diff)
downloadgcc-be4ba8aef398e6177b62d3ced6c9a086082d94f2.zip
gcc-be4ba8aef398e6177b62d3ced6c9a086082d94f2.tar.gz
gcc-be4ba8aef398e6177b62d3ced6c9a086082d94f2.tar.bz2
dwarf.c (read_uleb128): Fix overflow test.
* dwarf.c (read_uleb128): Fix overflow test. (read_sleb128): Likewise. (build_address_map): Don't change unit_buf.start. From-SVN: r192053
-rw-r--r--libbacktrace/ChangeLog6
-rw-r--r--libbacktrace/dwarf.c29
2 files changed, 25 insertions, 10 deletions
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index eca8014..88a7eb0 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,9 @@
+2012-10-03 Ian Lance Taylor <iant@google.com>
+
+ * dwarf.c (read_uleb128): Fix overflow test.
+ (read_sleb128): Likewise.
+ (build_address_map): Don't change unit_buf.start.
+
2012-10-02 Uros Bizjak <ubizjak@gmail.com>
PR other/54761
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 68ebb4e..25973cb 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -524,10 +524,12 @@ read_uleb128 (struct dwarf_buf *buf)
{
uint64_t ret;
unsigned int shift;
+ int overflow;
unsigned char b;
ret = 0;
shift = 0;
+ overflow = 0;
do
{
const unsigned char *p;
@@ -536,14 +538,17 @@ read_uleb128 (struct dwarf_buf *buf)
if (!advance (buf, 1))
return 0;
b = *p;
- ret |= ((uint64_t) (b & 0x7f)) << shift;
+ if (shift < 64)
+ ret |= ((uint64_t) (b & 0x7f)) << shift;
+ else if (!overflow)
+ {
+ dwarf_buf_error (buf, "LEB128 overflows uint64_t");
+ overflow = 1;
+ }
shift += 7;
}
while ((b & 0x80) != 0);
- if (shift > 64)
- dwarf_buf_error (buf, "LEB128 overflows uint64_5");
-
return ret;
}
@@ -554,10 +559,12 @@ read_sleb128 (struct dwarf_buf *buf)
{
uint64_t val;
unsigned int shift;
+ int overflow;
unsigned char b;
val = 0;
shift = 0;
+ overflow = 0;
do
{
const unsigned char *p;
@@ -566,15 +573,18 @@ read_sleb128 (struct dwarf_buf *buf)
if (!advance (buf, 1))
return 0;
b = *p;
- val |= ((uint64_t) (b & 0x7f)) << shift;
+ if (shift < 64)
+ val |= ((uint64_t) (b & 0x7f)) << shift;
+ else if (!overflow)
+ {
+ dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
+ overflow = 1;
+ }
shift += 7;
}
while ((b & 0x80) != 0);
- if (shift > 64)
- dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
-
- if ((b & 0x40) != 0)
+ if ((b & 0x40) != 0 && shift < 64)
val |= ((uint64_t) -1) << shift;
return (int64_t) val;
@@ -1262,7 +1272,6 @@ build_address_map (struct backtrace_state *state,
}
unit_buf = info;
- unit_buf.start = info.buf;
unit_buf.left = len;
if (!advance (&info, len))