commit 81bde8f873216c116988a98a0804dd79009b3d40
Author: Mark Wielaard <mjw@redhat.com>
Date: Mon Jun 22 16:57:59 2015 +0200
runtime/unwind.c: Also sanity check DWARF regno for DW_CFA_restore[_extended].
When processCFI wanted to restore a register state to its initial value it
wasn't checking whether the register was actually interesting (or existing).
DWARF_REG_MAP might return a marker (9999) that we don't know or don't care
about this register. This was checked in all the set_*_rule functions, but
not in the case we reset the rule of the register. Add this check also for
DW_CFA_restore[_extended].
diff --git a/runtime/unwind.c b/runtime/unwind.c
index d38363b..4dbab33 100644
--- a/runtime/unwind.c
+++ b/runtime/unwind.c
@@ -426,7 +426,8 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
value, DWARF_REG_MAP(value));
value = DWARF_REG_MAP(value);
}
- memcpy(®_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
+ if (value < ARRAY_SIZE(REG_STATE.regs))
+ memcpy(®_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
break;
case DW_CFA_undefined:
value = get_uleb128(&ptr.p8, end);
@@ -641,7 +642,8 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
value, DWARF_REG_MAP(value));
value = DWARF_REG_MAP(value);
}
- memcpy(®_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
+ if (value < ARRAY_SIZE(REG_STATE.regs))
+ memcpy(®_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
break;
}
dbug_unwind(1, "targetLoc=%lx state->loc=%lx\n", targetLoc, state->loc);
commit db6670607f9ba837a7a7af8a0ea076595e9eca1d
Author: David Smith <dsmith@redhat.com>
Date: Tue Jun 30 15:24:54 2015 -0500
Two small stat code fixes found by source analysis.
* runtime/stat-common.c (_stp_stat_print_histogram_buf): Fixed small
potential overflow problem by widening values.
* runtime/stat.c (_stp_stat_init): Fixed missing 'va_end' call in an error
situation.
diff --git a/runtime/stat-common.c b/runtime/stat-common.c
index f8372ac..4491b27 100644
--- a/runtime/stat-common.c
+++ b/runtime/stat-common.c
@@ -261,10 +261,10 @@ static void _stp_stat_print_histogram_buf(char *buf, size_t size, Hist st,
val_prefix = "<";
} else if (i == st->buckets-1) {
/* overflow */
- val = st->start + (i - 2) * st->interval;
+ val = st->start + (int64_t)(i - 2) * st->interval;
val_prefix = ">";
} else
- val = st->start + (i - 1) * st->interval;
+ val = st->start + (int64_t)(i - 1) * st->interval;
} else
val = _stp_bucket_to_val(i);
diff --git a/runtime/stat.c b/runtime/stat.c
index 63ffccc..fa5939b 100644
--- a/runtime/stat.c
+++ b/runtime/stat.c
@@ -71,8 +71,10 @@ static Stat _stp_stat_init (int type, ...)
interval = va_arg(ap, int);
buckets = _stp_stat_calc_buckets(stop, start, interval);
- if (!buckets)
+ if (!buckets) {
+ va_end (ap);
return NULL;
+ }
}
va_end (ap);
}
commit 39c6af0c27dfd5cdd71ee60e1667d40d101ff8ac
Author: Mark Wielaard <mjw@redhat.com>
Date: Tue Jun 30 21:54:28 2015 +0200
unwind.c (compute_expr): Don't fallthrough after div/mod/shr.
When processing DW_OP_div, DW_OP_mod or DW_OP_shr compute_expr
would accidentially fallthrough to the next case statement causing
the DWARF value stack to contain wrong values.
diff --git a/runtime/unwind.c b/runtime/unwind.c
index 4dbab33..b5c8f6f 100644
--- a/runtime/unwind.c
+++ b/runtime/unwind.c
@@ -1036,6 +1036,7 @@ static int compute_expr(const u8 *expr, struct unwind_frame_info *frame,
if (b == 0)
goto divzero;
PUSH (a % b);
+ break;
}
case DW_OP_div: {
@@ -1044,12 +1045,14 @@ static int compute_expr(const u8 *expr, struct unwind_frame_info *frame,
if (b == 0)
goto divzero;
PUSH (a / b);
+ break;
}
case DW_OP_shr: {
unsigned long b = POP;
unsigned long a = POP;
PUSH (a >> b);
+ break;
}
case DW_OP_not:
diff --git a/runtime/unwind/unwind.h b/runtime/unwind/unwind.h
index e81e741..d72f68d 100644
--- a/runtime/unwind/unwind.h
+++ b/runtime/unwind/unwind.h
@@ -157,6 +157,7 @@ static unsigned long read_ptr_sect(const u8 **pLoc, const void *end,
#else
BUILD_BUG_ON(sizeof(u32) != sizeof(value));
#endif
+ /* fallthrough, see above. */
case DW_EH_PE_absptr:
if (compat_task)
{