libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libunwind-devel] [PATCH] Fix undefined behavior in dwarf_eval_expr


From: Ulrich Weigand
Subject: [Libunwind-devel] [PATCH] Fix undefined behavior in dwarf_eval_expr
Date: Tue, 17 Dec 2013 14:59:28 +0100 (CET)

[PATCH] Fix undefined behavior in dwarf_eval_expr

The dwarf_eval_expr routine uses macros push, pop, and pick to
manipulate the DWARF expression stack.  When these macros are
nested, e.g. in the implementation of DW_OP_dup:
          push (pick (0));
the combination can lead to unfortunate results.

In particular, when substituting into:
do {
  if (tos >= MAX_EXPR_STACK_SIZE)
    {
      Debug (1, "Stack overflow\n");
      return -UNW_EINVAL;
    }
  stack[tos++] = (x);
} while (0)
a value of "x" that makes use of "tos" (as instances of the
pick or pop macros do), the resulting expression will both
use and modify tos without an intervening sequence point,
which is undefined behavior according to the C standard.

And in fact with current GCC on PowerPC, this leads to a
miscompilation of the DW_OP_dup implementation.

This patch fixes the problem by assigning "x" to a
temporary variable before modifying tos.

Signed-off-by: Ulrich Weigand <address@hidden>
---
 src/dwarf/Gexpr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/dwarf/Gexpr.c b/src/dwarf/Gexpr.c
index 502021c..4b04846 100644
--- a/src/dwarf/Gexpr.c
+++ b/src/dwarf/Gexpr.c
@@ -212,12 +212,13 @@ dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t 
*addr, unw_word_t len,
 })
 # define push(x)                               \
 do {                                           \
+  unw_word_t _x = (x);                         \
   if (tos >= MAX_EXPR_STACK_SIZE)              \
     {                                          \
       Debug (1, "Stack overflow\n");           \
       return -UNW_EINVAL;                      \
     }                                          \
-  stack[tos++] = (x);                          \
+  stack[tos++] = _x;                           \
 } while (0)
 # define pick(n)                               \
 ({                                             \
-- 
1.8.5

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  address@hidden




reply via email to

[Prev in Thread] Current Thread [Next in Thread]