-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libunwind] Remove unnecessary dependencies on fprintf and stdio.h for increased baremetal friendliness #72040
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-libunwind Author: Michael Kenzel (michael-kenzel) Changeslibunwind 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 Full diff: https://github.com/llvm/llvm-project/pull/72040.diff 2 Files Affected:
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 ®isters,
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.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy with this as is but I'd wait for at least one other positive review before merging.
✅ With the latest revision this PR passed the C/C++ code formatter. |
0074210
to
7e285a5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like an improvement to me. I have a comment/question about the stdio.h
include which is now dangling, but apart from that I'm happy with the patch.
f98bbd2
to
0bedd8b
Compare
a72cef2
to
f8b562d
Compare
As discussed, I've removed unnecessary includes of AddressSpace.hpp was using Finally, I've added I've updated the title of the commit and PR to reflect the now extended scope of these changes. Unfortunately, I can't really exercise all these code paths here as these changes now span code specific to multiple different platforms. I'll trust that if all the tests pass, that means it works… |
…baremetal friendliness
f8b562d
to
fcdccb3
Compare
As discussed with @arichardson, I've replaced |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! LGTM once CI is happy.
The CI issues are flakes (we just made major changes to our infrastructure and we're still adjusting). I think this is good to go. |
libunwind already puts logging facilities behind macros so that they can be turned on and off. The two places where this isn't done yet are for debug output tracing during DWARF evaluation and compact unwinding. The code there directly calls
fprintf
. This becomes a problem when one wants to build libunwind for a baremetal target wherefprintf
isn't available. This change introduces a set of_LIBUNWIND_TRACE_DWARF_EVAL
and_LIBUNWIND_TRACE_COMPACT_UNWIND
macros in the style of the already existing macros to remove the direct use offprintf
. It also removes unnecessary includes ofstdio.h
.