[libunwind] [libunwind] introduce _LIBUNWIND_TRACE_DWARF_EVAL for increased baremetal friendliness (PR #72040)

Michael Kenzel via cfe-commits cfe-commits at lists.llvm.org
Sat Nov 11 13:26:22 PST 2023


https://github.com/michael-kenzel created https://github.com/llvm/llvm-project/pull/72040

libunwind already puts logging facilities behind macros so that they can be turned on and off. The one place where this isn't done yet is for debug output tracing DWARF evaluation. The code there directly calls `fprintf`. This becomes a problem when one wants to build libunwind for a baremetal target where `fprintf` isn't available. This change introduces a set of `_LIBUNWIND_TRACE_DWARF_EVAL` macros in the style of the already existing macros to remove the direct dependency on `fprintf`.

>From 85eb8a3f5accfdb8c90b8e45a7ff0f7480e648ce Mon Sep 17 00:00:00 2001
From: Michael Kenzel <michael.kenzel at gmail.com>
Date: Sat, 11 Nov 2023 22:09:05 +0100
Subject: [PATCH] [libunwind] introduce _LIBUNWIND_TRACE_DWARF_EVAL

---
 libunwind/src/DwarfInstructions.hpp | 161 ++++++++++------------------
 libunwind/src/config.h              |  15 +++
 2 files changed, 70 insertions(+), 106 deletions(-)

diff --git a/libunwind/src/DwarfInstructions.hpp b/libunwind/src/DwarfInstructions.hpp
index 9962c2ffa0ca34f..015489bab1d3ac1 100644
--- a/libunwind/src/DwarfInstructions.hpp
+++ b/libunwind/src/DwarfInstructions.hpp
@@ -381,24 +381,22 @@ typename A::pint_t
 DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
                                             const R &registers,
                                             pint_t initialStackValue) {
-  const bool log = false;
   pint_t p = expression;
   pint_t expressionEnd = expression + 20; // temp, until len read
   pint_t length = (pint_t)addressSpace.getULEB128(p, expressionEnd);
   expressionEnd = p + length;
-  if (log)
-    fprintf(stderr, "evaluateExpression(): length=%" PRIu64 "\n",
-            (uint64_t)length);
+  _LIBUNWIND_TRACE_DWARF_EVAL("evaluateExpression(): length=%" PRIu64 "\n",
+          (uint64_t)length);
   pint_t stack[100];
   pint_t *sp = stack;
   *(++sp) = initialStackValue;
 
   while (p < expressionEnd) {
-    if (log) {
-      for (pint_t *t = sp; t > stack; --t) {
-        fprintf(stderr, "sp[] = 0x%" PRIx64 "\n", (uint64_t)(*t));
-      }
+#if _LIBUNWIND_TRACING_DWARF_EVAL
+    for (pint_t *t = sp; t > stack; --t) {
+      _LIBUNWIND_TRACE_DWARF_EVAL("sp[] = 0x%" PRIx64 "\n", (uint64_t)(*t));
     }
+#endif
     uint8_t opcode = addressSpace.get8(p++);
     sint_t svalue, svalue2;
     pint_t value;
@@ -409,16 +407,14 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       value = addressSpace.getP(p);
       p += sizeof(pint_t);
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_deref:
       // pop stack, dereference, push result
       value = *sp--;
       *(++sp) = addressSpace.getP(value);
-      if (log)
-        fprintf(stderr, "dereference 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("dereference 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_const1u:
@@ -426,8 +422,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       value = addressSpace.get8(p);
       p += 1;
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_const1s:
@@ -435,8 +430,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       svalue = (int8_t) addressSpace.get8(p);
       p += 1;
       *(++sp) = (pint_t)svalue;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)svalue);
       break;
 
     case DW_OP_const2u:
@@ -444,8 +438,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       value = addressSpace.get16(p);
       p += 2;
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_const2s:
@@ -453,8 +446,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       svalue = (int16_t) addressSpace.get16(p);
       p += 2;
       *(++sp) = (pint_t)svalue;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)svalue);
       break;
 
     case DW_OP_const4u:
@@ -462,8 +454,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       value = addressSpace.get32(p);
       p += 4;
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_const4s:
@@ -471,8 +462,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       svalue = (int32_t)addressSpace.get32(p);
       p += 4;
       *(++sp) = (pint_t)svalue;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)svalue);
       break;
 
     case DW_OP_const8u:
@@ -480,8 +470,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       value = (pint_t)addressSpace.get64(p);
       p += 8;
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_const8s:
@@ -489,47 +478,41 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       value = (pint_t)addressSpace.get64(p);
       p += 8;
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_constu:
       // push immediate ULEB128 value
       value = (pint_t)addressSpace.getULEB128(p, expressionEnd);
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_consts:
       // push immediate SLEB128 value
       svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
       *(++sp) = (pint_t)svalue;
-      if (log)
-        fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push 0x%" PRIx64 "\n", (uint64_t)svalue);
       break;
 
     case DW_OP_dup:
       // push top of stack
       value = *sp;
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "duplicate top of stack\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("duplicate top of stack\n");
       break;
 
     case DW_OP_drop:
       // pop
       --sp;
-      if (log)
-        fprintf(stderr, "pop top of stack\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("pop top of stack\n");
       break;
 
     case DW_OP_over:
       // dup second
       value = sp[-1];
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "duplicate second in stack\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("duplicate second in stack\n");
       break;
 
     case DW_OP_pick:
@@ -538,8 +521,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       p += 1;
       value = sp[-(int)reg];
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "duplicate %d in stack\n", reg);
+      _LIBUNWIND_TRACE_DWARF_EVAL("duplicate %d in stack\n", reg);
       break;
 
     case DW_OP_swap:
@@ -547,8 +529,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       value = sp[0];
       sp[0] = sp[-1];
       sp[-1] = value;
-      if (log)
-        fprintf(stderr, "swap top of stack\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("swap top of stack\n");
       break;
 
     case DW_OP_rot:
@@ -557,133 +538,115 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       sp[0] = sp[-1];
       sp[-1] = sp[-2];
       sp[-2] = value;
-      if (log)
-        fprintf(stderr, "rotate top three of stack\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("rotate top three of stack\n");
       break;
 
     case DW_OP_xderef:
       // pop stack, dereference, push result
       value = *sp--;
       *sp = *((pint_t*)value);
-      if (log)
-        fprintf(stderr, "x-dereference 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("x-dereference 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_abs:
       svalue = (sint_t)*sp;
       if (svalue < 0)
         *sp = (pint_t)(-svalue);
-      if (log)
-        fprintf(stderr, "abs\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("abs\n");
       break;
 
     case DW_OP_and:
       value = *sp--;
       *sp &= value;
-      if (log)
-        fprintf(stderr, "and\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("and\n");
       break;
 
     case DW_OP_div:
       svalue = (sint_t)(*sp--);
       svalue2 = (sint_t)*sp;
       *sp = (pint_t)(svalue2 / svalue);
-      if (log)
-        fprintf(stderr, "div\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("div\n");
       break;
 
     case DW_OP_minus:
       value = *sp--;
       *sp = *sp - value;
-      if (log)
-        fprintf(stderr, "minus\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("minus\n");
       break;
 
     case DW_OP_mod:
       svalue = (sint_t)(*sp--);
       svalue2 = (sint_t)*sp;
       *sp = (pint_t)(svalue2 % svalue);
-      if (log)
-        fprintf(stderr, "module\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("module\n");
       break;
 
     case DW_OP_mul:
       svalue = (sint_t)(*sp--);
       svalue2 = (sint_t)*sp;
       *sp = (pint_t)(svalue2 * svalue);
-      if (log)
-        fprintf(stderr, "mul\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("mul\n");
       break;
 
     case DW_OP_neg:
       *sp = 0 - *sp;
-      if (log)
-        fprintf(stderr, "neg\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("neg\n");
       break;
 
     case DW_OP_not:
       svalue = (sint_t)(*sp);
       *sp = (pint_t)(~svalue);
-      if (log)
-        fprintf(stderr, "not\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("not\n");
       break;
 
     case DW_OP_or:
       value = *sp--;
       *sp |= value;
-      if (log)
-        fprintf(stderr, "or\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("or\n");
       break;
 
     case DW_OP_plus:
       value = *sp--;
       *sp += value;
-      if (log)
-        fprintf(stderr, "plus\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("plus\n");
       break;
 
     case DW_OP_plus_uconst:
       // pop stack, add uelb128 constant, push result
       *sp += static_cast<pint_t>(addressSpace.getULEB128(p, expressionEnd));
-      if (log)
-        fprintf(stderr, "add constant\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("add constant\n");
       break;
 
     case DW_OP_shl:
       value = *sp--;
       *sp = *sp << value;
-      if (log)
-        fprintf(stderr, "shift left\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("shift left\n");
       break;
 
     case DW_OP_shr:
       value = *sp--;
       *sp = *sp >> value;
-      if (log)
-        fprintf(stderr, "shift left\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("shift left\n");
       break;
 
     case DW_OP_shra:
       value = *sp--;
       svalue = (sint_t)*sp;
       *sp = (pint_t)(svalue >> value);
-      if (log)
-        fprintf(stderr, "shift left arithmetic\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("shift left arithmetic\n");
       break;
 
     case DW_OP_xor:
       value = *sp--;
       *sp ^= value;
-      if (log)
-        fprintf(stderr, "xor\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("xor\n");
       break;
 
     case DW_OP_skip:
       svalue = (int16_t) addressSpace.get16(p);
       p += 2;
       p = (pint_t)((sint_t)p + svalue);
-      if (log)
-        fprintf(stderr, "skip %" PRIu64 "\n", (uint64_t)svalue);
+      _LIBUNWIND_TRACE_DWARF_EVAL("skip %" PRIu64 "\n", (uint64_t)svalue);
       break;
 
     case DW_OP_bra:
@@ -691,50 +654,43 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       p += 2;
       if (*sp--)
         p = (pint_t)((sint_t)p + svalue);
-      if (log)
-        fprintf(stderr, "bra %" PRIu64 "\n", (uint64_t)svalue);
+      _LIBUNWIND_TRACE_DWARF_EVAL("bra %" PRIu64 "\n", (uint64_t)svalue);
       break;
 
     case DW_OP_eq:
       value = *sp--;
       *sp = (*sp == value);
-      if (log)
-        fprintf(stderr, "eq\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("eq\n");
       break;
 
     case DW_OP_ge:
       value = *sp--;
       *sp = (*sp >= value);
-      if (log)
-        fprintf(stderr, "ge\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("ge\n");
       break;
 
     case DW_OP_gt:
       value = *sp--;
       *sp = (*sp > value);
-      if (log)
-        fprintf(stderr, "gt\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("gt\n");
       break;
 
     case DW_OP_le:
       value = *sp--;
       *sp = (*sp <= value);
-      if (log)
-        fprintf(stderr, "le\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("le\n");
       break;
 
     case DW_OP_lt:
       value = *sp--;
       *sp = (*sp < value);
-      if (log)
-        fprintf(stderr, "lt\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("lt\n");
       break;
 
     case DW_OP_ne:
       value = *sp--;
       *sp = (*sp != value);
-      if (log)
-        fprintf(stderr, "ne\n");
+      _LIBUNWIND_TRACE_DWARF_EVAL0("ne\n");
       break;
 
     case DW_OP_lit0:
@@ -771,8 +727,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
     case DW_OP_lit31:
       value = static_cast<pint_t>(opcode - DW_OP_lit0);
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "push literal 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push literal 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_reg0:
@@ -809,15 +764,13 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
     case DW_OP_reg31:
       reg = static_cast<uint32_t>(opcode - DW_OP_reg0);
       *(++sp) = registers.getRegister((int)reg);
-      if (log)
-        fprintf(stderr, "push reg %d\n", reg);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push reg %d\n", reg);
       break;
 
     case DW_OP_regx:
       reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd));
       *(++sp) = registers.getRegister((int)reg);
-      if (log)
-        fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
       break;
 
     case DW_OP_breg0:
@@ -856,8 +809,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
       svalue += static_cast<sint_t>(registers.getRegister((int)reg));
       *(++sp) = (pint_t)(svalue);
-      if (log)
-        fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
       break;
 
     case DW_OP_bregx:
@@ -865,8 +817,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
       svalue += static_cast<sint_t>(registers.getRegister((int)reg));
       *(++sp) = (pint_t)(svalue);
-      if (log)
-        fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
+      _LIBUNWIND_TRACE_DWARF_EVAL("push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
       break;
 
     case DW_OP_fbreg:
@@ -897,8 +848,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
         _LIBUNWIND_ABORT("DW_OP_deref_size with bad size");
       }
       *(++sp) = value;
-      if (log)
-        fprintf(stderr, "sized dereference 0x%" PRIx64 "\n", (uint64_t)value);
+      _LIBUNWIND_TRACE_DWARF_EVAL("sized dereference 0x%" PRIx64 "\n", (uint64_t)value);
       break;
 
     case DW_OP_xderef_size:
@@ -912,8 +862,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
     }
 
   }
-  if (log)
-    fprintf(stderr, "expression evaluates to 0x%" PRIx64 "\n", (uint64_t)*sp);
+  _LIBUNWIND_TRACE_DWARF_EVAL("expression evaluates to 0x%" PRIx64 "\n", (uint64_t)*sp);
   return *sp;
 }
 
diff --git a/libunwind/src/config.h b/libunwind/src/config.h
index deb5a4d4d73d467..c31d4113401cd03 100644
--- a/libunwind/src/config.h
+++ b/libunwind/src/config.h
@@ -223,6 +223,21 @@
     } while (0)
 #endif
 
+#define _LIBUNWIND_TRACING_DWARF_EVAL (0)
+#if !_LIBUNWIND_TRACING_DWARF_EVAL
+#define _LIBUNWIND_TRACE_DWARF_EVAL0(msg)
+#define _LIBUNWIND_TRACE_DWARF_EVAL(msg, ...)
+#else
+#define _LIBUNWIND_TRACE_DWARF_EVAL0(msg)                                      \
+    do {                                                                       \
+      fprintf(stderr, msg);                                                    \
+    } while(0)
+#define _LIBUNWIND_TRACE_DWARF_EVAL(msg, ...)                                  \
+    do {                                                                       \
+      fprintf(stderr, msg, __VA_ARGS__);                                       \
+    } while(0)
+#endif
+
 #ifdef __cplusplus
 // Used to fit UnwindCursor and Registers_xxx types against unw_context_t /
 // unw_cursor_t sized memory blocks.



More information about the cfe-commits mailing list