================
@@ -632,6 +632,461 @@ TEST(DWARFExpression, DW_OP_unknown) {
"unhandled opcode DW_OP_unknown_ff in DWARFExpression"));
}
+TEST(DWARFExpression, DW_OP_addr) {
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_addr, 0x10, 0x20, 0x30, 0x40, DW_OP_stack_value}),
+ ExpectScalar(uint32_t{0x40302010}));
+}
+
+TEST(DWARFExpression, DW_OP_nop) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_nop}), ExpectScalar(5));
+}
+
+TEST(DWARFExpression, DW_OP_neg) {
+ // neg interprets the operand as signed.
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_neg}),
+ ExpectScalar(static_cast<int32_t>(-5)));
+}
+
+TEST(DWARFExpression, DW_OP_abs) {
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_const1s, static_cast<uint8_t>(-5), DW_OP_abs}),
+ ExpectScalar(5));
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_abs}), ExpectScalar(5));
+}
+
+TEST(DWARFExpression, DW_OP_div_int_min_by_neg_one) {
+ // INT32_MIN / -1 is C++ UB; the evaluator must not crash.
+ auto result = Evaluate({DW_OP_const4s, 0x00, 0x00, 0x00, 0x80, DW_OP_const1s,
+ static_cast<uint8_t>(-1), DW_OP_div});
+ if (!result)
+ llvm::consumeError(result.takeError());
+ SUCCEED();
+}
+
+TEST(DWARFExpression, DW_OP_div) {
+ // Signed division: -10 / 3 = -3 (truncation toward zero).
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1s, static_cast<uint8_t>(-10),
+ DW_OP_const1s, 3, DW_OP_div}),
+ ExpectScalar(static_cast<int32_t>(-3)));
+}
+
+TEST(DWARFExpression, DW_OP_mod) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1s, static_cast<uint8_t>(-7),
+ DW_OP_const1s, 3, DW_OP_mod}),
+ ExpectScalar(static_cast<int32_t>(-1)));
+}
+
+TEST(DWARFExpression, DW_OP_minus) {
+ // Generic arithmetic wraps modulo address-size: 0 - 1 = 0xFFFFFFFF.
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit0, DW_OP_lit1, DW_OP_minus}),
+ ExpectScalar(uint32_t{0xFFFFFFFF}));
+}
+
+TEST(DWARFExpression, DW_OP_plus) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_lit3, DW_OP_plus}),
+ ExpectScalar(8));
+}
+
+TEST(DWARFExpression, DW_OP_mul) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_lit3, DW_OP_mul}),
+ ExpectScalar(15));
+}
+
+TEST(DWARFExpression, DW_OP_plus_uconst) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1s, static_cast<uint8_t>(-10),
+ DW_OP_plus_uconst, 5}),
+ ExpectScalar(static_cast<int32_t>(-5)));
+}
+
+TEST(DWARFExpression, DW_OP_and) {
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_const1u, 0x0F, DW_OP_const1u, 0x33, DW_OP_and}),
+ ExpectScalar(0x03));
+}
+
+TEST(DWARFExpression, DW_OP_or) {
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_const1u, 0x0F, DW_OP_const1u, 0x30, DW_OP_or}),
+ ExpectScalar(0x3F));
+}
+
+TEST(DWARFExpression, DW_OP_xor) {
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_const1u, 0x0F, DW_OP_const1u, 0x33, DW_OP_xor}),
+ ExpectScalar(0x3C));
+}
+
+TEST(DWARFExpression, DW_OP_not) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit0, DW_OP_not}),
+ ExpectScalar(uint32_t{0xFFFFFFFF}));
+}
+
+TEST(DWARFExpression, DW_OP_lt) {
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_const1s, static_cast<uint8_t>(-1), DW_OP_lit0,
DW_OP_lt}),
+ ExpectScalar(1));
+}
+
+TEST(DWARFExpression, DW_OP_gt) {
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_lit0, DW_OP_const1s, static_cast<uint8_t>(-1),
DW_OP_gt}),
+ ExpectScalar(1));
+}
+
+TEST(DWARFExpression, DW_OP_le) {
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_const1s, static_cast<uint8_t>(-1), DW_OP_lit0,
DW_OP_le}),
+ ExpectScalar(1));
+}
+
+TEST(DWARFExpression, DW_OP_ge) {
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_lit0, DW_OP_const1s, static_cast<uint8_t>(-1),
DW_OP_ge}),
+ ExpectScalar(1));
+}
+
+TEST(DWARFExpression, DW_OP_eq) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_lit5, DW_OP_eq}),
+ ExpectScalar(1));
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_lit3, DW_OP_eq}),
+ ExpectScalar(0));
+}
+
+TEST(DWARFExpression, DW_OP_ne) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_lit3, DW_OP_ne}),
+ ExpectScalar(1));
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_lit5, DW_OP_ne}),
+ ExpectScalar(0));
+}
+
+TEST(DWARFExpression, DW_OP_swap) {
+ // After swap, top is the value pushed first (lit1).
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_swap}),
+ ExpectScalar(1));
+}
+
+TEST(DWARFExpression, DW_OP_rot) {
+ // Stack pre-rot (top last): [1, 2, 3]. Post-rot: [2, 3, 1]. Top = 2.
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_rot}),
+ ExpectScalar(2));
+}
+
+TEST(DWARFExpression, DW_OP_over) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_over}),
+ ExpectScalar(1));
+}
+
+TEST(DWARFExpression, DW_OP_dup) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_dup}), ExpectScalar(5));
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_dup}), llvm::Failed());
+}
+
+TEST(DWARFExpression, DW_OP_drop) {
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit3, DW_OP_lit5, DW_OP_drop}),
+ ExpectScalar(3));
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_drop}), llvm::Failed());
+}
+
+TEST(DWARFExpression, DW_OP_skip_backward) {
+ // Layout (offsets):
+ // 0: skip +5 → end_offset=3, target=8
+ // 3: const1u 0x42 ← target of backward branch
+ // 5: skip +3 → end_offset=8, target=11 (== expr.size, exits)
+ // 8: skip -8 → end_offset=11, target=3
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_skip, 0x05, 0x00, DW_OP_const1u, 0x42, DW_OP_skip, 0x03,
+ 0x00, DW_OP_skip, 0xF8, 0xFF}),
+ ExpectScalar(0x42));
+}
+
+TEST(DWARFExpression, DW_OP_skip_to_end) {
+ // skip 0 from end-of-skip lands at end-of-expression and terminates cleanly.
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit5, DW_OP_skip, 0x00, 0x00}),
+ ExpectScalar(5));
+}
+
+TEST(DWARFExpression, DW_OP_bra_false) {
+ // Top is 0 → no branch, fall through to next opcode.
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_lit5, DW_OP_lit0, DW_OP_bra, 0x63, 0x00}),
+ ExpectScalar(5));
+}
+
+TEST(DWARFExpression, DW_OP_lit_all) {
+ for (uint8_t n = 0; n <= 31; ++n) {
+ uint8_t opcode = DW_OP_lit0 + n;
+ EXPECT_THAT_EXPECTED(Evaluate({opcode}), ExpectScalar(n))
+ << "DW_OP_lit" << static_cast<int>(n) << " failed";
+ }
----------------
s-barannikov wrote:
Should we have tests for DW_OP_const*? In particular, that s and u versions
correctly sign- and zero-extend to pointer size.
https://github.com/llvm/llvm-project/pull/196218
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits