55// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66//
77// ===----------------------------------------------------------------------===//
8-
98#include " lldb/Expression/DWARFExpression.h"
9+ #include " ValueMatcher.h"
1010#ifdef ARCH_AARCH64
1111#include " Plugins/ABI/AArch64/ABISysV_arm64.h"
1212#endif
@@ -135,40 +135,18 @@ class MockRegisterContext : public RegisterContext {
135135};
136136} // namespace
137137
138- static llvm::Expected<Scalar > Evaluate (llvm::ArrayRef<uint8_t > expr,
139- lldb::ModuleSP module_sp = {},
140- DWARFUnit *unit = nullptr ,
141- ExecutionContext *exe_ctx = nullptr ,
142- RegisterContext *reg_ctx = nullptr ) {
138+ static llvm::Expected<Value > Evaluate (llvm::ArrayRef<uint8_t > expr,
139+ lldb::ModuleSP module_sp = {},
140+ DWARFUnit *unit = nullptr ,
141+ ExecutionContext *exe_ctx = nullptr ,
142+ RegisterContext *reg_ctx = nullptr ) {
143143 DataExtractor extractor (expr.data (), expr.size (), lldb::eByteOrderLittle,
144144 /* addr_size*/ 4 );
145145
146- llvm::Expected<Value> result = DWARFExpression::Evaluate (
147- exe_ctx, reg_ctx, module_sp, extractor, unit, lldb::eRegisterKindLLDB,
148- /* initial_value_ptr=*/ nullptr ,
149- /* object_address_ptr=*/ nullptr );
150- if (!result)
151- return result.takeError ();
152-
153- switch (result->GetValueType ()) {
154- case Value::ValueType::Scalar:
155- return result->GetScalar ();
156- case Value::ValueType::LoadAddress:
157- return LLDB_INVALID_ADDRESS;
158- case Value::ValueType::HostAddress: {
159- // Convert small buffers to scalars to simplify the tests.
160- DataBufferHeap &buf = result->GetBuffer ();
161- if (buf.GetByteSize () <= 8 ) {
162- uint64_t val = 0 ;
163- memcpy (&val, buf.GetBytes (), buf.GetByteSize ());
164- return Scalar (llvm::APInt (buf.GetByteSize () * 8 , val, false ));
165- }
166- }
167- [[fallthrough]];
168- default :
169- break ;
170- }
171- return llvm::createStringError (" unsupported value type" );
146+ return DWARFExpression::Evaluate (exe_ctx, reg_ctx, module_sp, extractor, unit,
147+ lldb::eRegisterKindLLDB,
148+ /* initial_value_ptr=*/ nullptr ,
149+ /* object_address_ptr=*/ nullptr );
172150}
173151
174152class DWARFExpressionTester : public YAMLModuleTester {
@@ -177,18 +155,11 @@ class DWARFExpressionTester : public YAMLModuleTester {
177155 : YAMLModuleTester(yaml_data, cu_index) {}
178156
179157 using YAMLModuleTester::YAMLModuleTester;
180- llvm::Expected<Scalar > Eval (llvm::ArrayRef<uint8_t > expr) {
158+ llvm::Expected<Value > Eval (llvm::ArrayRef<uint8_t > expr) {
181159 return ::Evaluate (expr, m_module_sp, m_dwarf_unit);
182160 }
183161};
184162
185- // / Unfortunately Scalar's operator==() is really picky.
186- static Scalar GetScalar (unsigned bits, uint64_t value, bool sign) {
187- Scalar scalar (value);
188- scalar.TruncOrExtendTo (bits, sign);
189- return scalar;
190- }
191-
192163// / This is needed for the tests that use a mock process.
193164class DWARFExpressionMockProcessTest : public ::testing::Test {
194165public:
@@ -255,48 +226,48 @@ class MockTarget : public Target {
255226
256227TEST (DWARFExpression, DW_OP_pick) {
257228 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 0 }),
258- llvm::HasValue (0 ));
229+ ExpectScalar (0 ));
259230 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 1 }),
260- llvm::HasValue (1 ));
231+ ExpectScalar (1 ));
261232 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 2 }),
262233 llvm::Failed ());
263234}
264235
265236TEST (DWARFExpression, DW_OP_const) {
266237 // Extend to address size.
267- EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const1u, 0x88 }), llvm::HasValue (0x88 ));
238+ EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const1u, 0x88 }), ExpectScalar (0x88 ));
268239 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const1s, 0x88 }),
269- llvm::HasValue (0xffffff88 ));
240+ ExpectScalar (0xffffff88 ));
270241 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const2u, 0x47 , 0x88 }),
271- llvm::HasValue (0x8847 ));
242+ ExpectScalar (0x8847 ));
272243 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const2s, 0x47 , 0x88 }),
273- llvm::HasValue (0xffff8847 ));
244+ ExpectScalar (0xffff8847 ));
274245 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const4u, 0x44 , 0x42 , 0x47 , 0x88 }),
275- llvm::HasValue (0x88474244 ));
246+ ExpectScalar (0x88474244 ));
276247 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const4s, 0x44 , 0x42 , 0x47 , 0x88 }),
277- llvm::HasValue (0x88474244 ));
248+ ExpectScalar (0x88474244 ));
278249
279250 // Truncate to address size.
280251 EXPECT_THAT_EXPECTED (
281252 Evaluate ({DW_OP_const8u, 0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x42 , 0x47 , 0x88 }),
282- llvm::HasValue (0x33221100 ));
253+ ExpectScalar (0x33221100 ));
283254 EXPECT_THAT_EXPECTED (
284255 Evaluate ({DW_OP_const8s, 0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x42 , 0x47 , 0x88 }),
285- llvm::HasValue (0x33221100 ));
256+ ExpectScalar (0x33221100 ));
286257
287258 // Don't truncate to address size for compatibility with clang (pr48087).
288259 EXPECT_THAT_EXPECTED (
289260 Evaluate ({DW_OP_constu, 0x81 , 0x82 , 0x84 , 0x88 , 0x90 , 0xa0 , 0x40 }),
290- llvm::HasValue (0x01010101010101 ));
261+ ExpectScalar (0x01010101010101 ));
291262 EXPECT_THAT_EXPECTED (
292263 Evaluate ({DW_OP_consts, 0x81 , 0x82 , 0x84 , 0x88 , 0x90 , 0xa0 , 0x40 }),
293- llvm::HasValue (0xffff010101010101 ));
264+ ExpectScalar (0xffff010101010101 ));
294265}
295266
296267TEST (DWARFExpression, DW_OP_skip) {
297268 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const1u, 0x42 , DW_OP_skip, 0x02 , 0x00 ,
298269 DW_OP_const1u, 0xff }),
299- llvm::HasValue (0x42 ));
270+ ExpectScalar (0x42 ));
300271}
301272
302273TEST (DWARFExpression, DW_OP_bra) {
@@ -309,7 +280,7 @@ TEST(DWARFExpression, DW_OP_bra) {
309280 DW_OP_const1u, 0xff , // push 0xff
310281 }),
311282 // clang-format on
312- llvm::HasValue (0x42 ));
283+ ExpectScalar (0x42 ));
313284
314285 EXPECT_THAT_ERROR (Evaluate ({DW_OP_bra, 0x01 , 0x00 }).takeError (),
315286 llvm::Failed ());
@@ -414,42 +385,42 @@ TEST(DWARFExpression, DW_OP_convert) {
414385 EXPECT_THAT_EXPECTED (
415386 t.Eval ({DW_OP_const4u, 0x11 , 0x22 , 0x33 , 0x44 , //
416387 DW_OP_convert, offs_uint32_t , DW_OP_stack_value}),
417- llvm::HasValue ( GetScalar ( 64 , 0x44332211 , not_signed) ));
388+ ExpectScalar ( 64 , 0x44332211 , not_signed));
418389
419390 // Zero-extend to 64 bits.
420391 EXPECT_THAT_EXPECTED (
421392 t.Eval ({DW_OP_const4u, 0x11 , 0x22 , 0x33 , 0x44 , //
422393 DW_OP_convert, offs_uint64_t , DW_OP_stack_value}),
423- llvm::HasValue ( GetScalar ( 64 , 0x44332211 , not_signed) ));
394+ ExpectScalar ( 64 , 0x44332211 , not_signed));
424395
425396 // Sign-extend to 64 bits.
426397 EXPECT_THAT_EXPECTED (
427398 t.Eval ({DW_OP_const4s, 0xcc , 0xdd , 0xee , 0xff , //
428399 DW_OP_convert, offs_sint64_t , DW_OP_stack_value}),
429- llvm::HasValue ( GetScalar ( 64 , 0xffffffffffeeddcc , is_signed) ));
400+ ExpectScalar ( 64 , 0xffffffffffeeddcc , is_signed));
430401
431402 // Sign-extend, then truncate.
432403 EXPECT_THAT_EXPECTED (
433404 t.Eval ({DW_OP_const4s, 0xcc , 0xdd , 0xee , 0xff , //
434405 DW_OP_convert, offs_sint64_t , //
435406 DW_OP_convert, offs_uint32_t , DW_OP_stack_value}),
436- llvm::HasValue ( GetScalar ( 32 , 0xffeeddcc , not_signed) ));
407+ ExpectScalar ( 32 , 0xffeeddcc , not_signed));
437408
438409 // Truncate to default unspecified (pointer-sized) type.
439410 EXPECT_THAT_EXPECTED (t.Eval ({DW_OP_const4s, 0xcc , 0xdd , 0xee , 0xff , //
440411 DW_OP_convert, offs_sint64_t , //
441412 DW_OP_convert, 0x00 , DW_OP_stack_value}),
442- llvm::HasValue ( GetScalar ( 32 , 0xffeeddcc , not_signed) ));
413+ ExpectScalar ( 32 , 0xffeeddcc , not_signed));
443414
444415 // Truncate to 8 bits.
445416 EXPECT_THAT_EXPECTED (t.Eval ({DW_OP_const4s, ' A' , ' B' , ' C' , ' D' , DW_OP_convert,
446417 offs_uchar, DW_OP_stack_value}),
447- llvm::HasValue ( GetScalar ( 8 , ' A' , not_signed) ));
418+ ExpectScalar ( 8 , ' A' , not_signed));
448419
449420 // Also truncate to 8 bits.
450421 EXPECT_THAT_EXPECTED (t.Eval ({DW_OP_const4s, ' A' , ' B' , ' C' , ' D' , DW_OP_convert,
451422 offs_schar, DW_OP_stack_value}),
452- llvm::HasValue ( GetScalar ( 8 , ' A' , is_signed) ));
423+ ExpectScalar ( 8 , ' A' , is_signed));
453424
454425 //
455426 // Errors.
@@ -479,41 +450,29 @@ TEST(DWARFExpression, DW_OP_stack_value) {
479450TEST (DWARFExpression, DW_OP_piece) {
480451 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_const2u, 0x11 , 0x22 , DW_OP_piece, 2 ,
481452 DW_OP_const2u, 0x33 , 0x44 , DW_OP_piece, 2 }),
482- llvm::HasValue ( GetScalar ( 32 , 0x44332211 , true ) ));
453+ ExpectHostAddress ({ 0x11 , 0x22 , 0x33 , 0x44 } ));
483454 EXPECT_THAT_EXPECTED (
484455 Evaluate ({DW_OP_piece, 1 , DW_OP_const1u, 0xff , DW_OP_piece, 1 }),
485456 // Note that the "00" should really be "undef", but we can't
486457 // represent that yet.
487- llvm::HasValue (GetScalar (16 , 0xff00 , true )));
488- }
489-
490- TEST (DWARFExpression, DW_OP_piece_host_address) {
491- static const uint8_t expr_data[] = {DW_OP_lit2, DW_OP_stack_value,
492- DW_OP_piece, 40 };
493- llvm::ArrayRef<uint8_t > expr (expr_data, sizeof (expr_data));
494- DataExtractor extractor (expr.data (), expr.size (), lldb::eByteOrderLittle, 4 );
458+ ExpectHostAddress ({0x00 , 0xff }));
495459
496460 // This tests if ap_int is extended to the right width.
497461 // expect 40*8 = 320 bits size.
498- llvm::Expected<Value> result =
499- DWARFExpression::Evaluate (nullptr , nullptr , nullptr , extractor, nullptr ,
500- lldb::eRegisterKindDWARF, nullptr , nullptr );
501- ASSERT_THAT_EXPECTED (result, llvm::Succeeded ());
502- ASSERT_EQ (result->GetValueType (), Value::ValueType::HostAddress);
503- ASSERT_EQ (result->GetBuffer ().GetByteSize (), 40ul );
504- const uint8_t *data = result->GetBuffer ().GetBytes ();
505- ASSERT_EQ (data[0 ], 2 );
506- for (int i = 1 ; i < 40 ; i++) {
507- ASSERT_EQ (data[i], 0 );
508- }
462+ std::vector<uint8_t > expected_host_buffer (40 , 0 );
463+ expected_host_buffer[0 ] = 2 ;
464+
465+ EXPECT_THAT_EXPECTED (
466+ Evaluate ({{DW_OP_lit2, DW_OP_stack_value, DW_OP_piece, 40 }}),
467+ ExpectHostAddress (expected_host_buffer));
509468}
510469
511470TEST (DWARFExpression, DW_OP_implicit_value) {
512471 unsigned char bytes = 4 ;
513472
514473 EXPECT_THAT_EXPECTED (
515474 Evaluate ({DW_OP_implicit_value, bytes, 0x11 , 0x22 , 0x33 , 0x44 }),
516- llvm::HasValue ( GetScalar ( 8 * bytes, 0x44332211 , true ) ));
475+ ExpectHostAddress ({ 0x11 , 0x22 , 0x33 , 0x44 } ));
517476}
518477
519478TEST (DWARFExpression, DW_OP_unknown) {
@@ -548,20 +507,13 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
548507 // Implicit location: *0x4.
549508 EXPECT_THAT_EXPECTED (
550509 Evaluate ({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value}, {}, {}, &exe_ctx),
551- llvm::HasValue ( GetScalar ( 32 , 0x07060504 , false ) ));
510+ ExpectScalar ( 32 , 0x07060504 , false ));
552511 // Memory location: *(*0x4).
553- // Evaluate returns LLDB_INVALID_ADDRESS for all load addresses.
554512 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_lit4, DW_OP_deref}, {}, {}, &exe_ctx),
555- llvm::HasValue ( Scalar (LLDB_INVALID_ADDRESS) ));
513+ ExpectLoadAddress ( 0x07060504 ));
556514 // Memory location: *0x4.
557- // Evaluate returns LLDB_INVALID_ADDRESS for all load addresses.
558515 EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_lit4}, {}, {}, &exe_ctx),
559- llvm::HasValue (Scalar (4 )));
560- // Implicit location: *0x4.
561- // Evaluate returns LLDB_INVALID_ADDRESS for all load addresses.
562- EXPECT_THAT_EXPECTED (
563- Evaluate ({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value}, {}, {}, &exe_ctx),
564- llvm::HasValue (GetScalar (32 , 0x07060504 , false )));
516+ ExpectScalar (Scalar (4 )));
565517}
566518
567519TEST_F (DWARFExpressionMockProcessTest, WASM_DW_OP_addr) {
@@ -581,18 +533,9 @@ TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr) {
581533
582534 ExecutionContext exe_ctx (target_sp, false );
583535 // DW_OP_addr takes a single operand of address size width:
584- uint8_t expr[] = {DW_OP_addr, 0x40 , 0x0 , 0x0 , 0x0 };
585- DataExtractor extractor (expr, sizeof (expr), lldb::eByteOrderLittle,
586- /* addr_size*/ 4 );
587-
588- llvm::Expected<Value> result = DWARFExpression::Evaluate (
589- &exe_ctx, /* reg_ctx*/ nullptr , /* module_sp*/ {}, extractor,
590- /* unit*/ nullptr , lldb::eRegisterKindLLDB,
591- /* initial_value_ptr*/ nullptr ,
592- /* object_address_ptr*/ nullptr );
593-
594- ASSERT_THAT_EXPECTED (result, llvm::Succeeded ());
595- ASSERT_EQ (result->GetValueType (), Value::ValueType::LoadAddress);
536+ EXPECT_THAT_EXPECTED (
537+ Evaluate ({DW_OP_addr, 0x40 , 0x0 , 0x0 , 0x0 }, {}, {}, &exe_ctx),
538+ ExpectLoadAddress (0x40 ));
596539}
597540
598541TEST_F (DWARFExpressionMockProcessTest, WASM_DW_OP_addr_index) {
@@ -676,15 +619,11 @@ TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr_index) {
676619 DWARFExpression expr (extractor);
677620
678621 llvm::Expected<Value> result = evaluate (expr);
679- ASSERT_THAT_EXPECTED (result, llvm::Succeeded ());
680- ASSERT_EQ (result->GetValueType (), Value::ValueType::LoadAddress);
681- ASSERT_EQ (result->GetScalar ().UInt (), 0x5678u );
622+ EXPECT_THAT_EXPECTED (result, ExpectLoadAddress (0x5678u ));
682623
683624 ASSERT_TRUE (expr.Update_DW_OP_addr (dwarf_cu, 0xdeadbeef ));
684625 result = evaluate (expr);
685- ASSERT_THAT_EXPECTED (result, llvm::Succeeded ());
686- ASSERT_EQ (result->GetValueType (), Value::ValueType::LoadAddress);
687- ASSERT_EQ (result->GetScalar ().UInt (), 0xdeadbeefu );
626+ EXPECT_THAT_EXPECTED (result, ExpectLoadAddress (0xdeadbeefu ));
688627}
689628
690629class CustomSymbolFileDWARF : public SymbolFileDWARF {
@@ -778,11 +717,12 @@ static auto testExpressionVendorExtensions(lldb::ModuleSP module_sp,
778717 RegisterContext *reg_ctx) {
779718 // Test that expression extensions can be evaluated, for example
780719 // DW_OP_WASM_location which is not currently handled by DWARFExpression:
781- EXPECT_THAT_EXPECTED (Evaluate ({DW_OP_WASM_location, 0x03 , // WASM_GLOBAL:0x03
782- 0x04 , 0x00 , 0x00 , // index:u32
783- 0x00 , DW_OP_stack_value},
784- module_sp, &dwarf_unit, nullptr , reg_ctx),
785- llvm::HasValue (GetScalar (32 , 42 , false )));
720+ EXPECT_THAT_EXPECTED (
721+ Evaluate ({DW_OP_WASM_location, 0x03 , // WASM_GLOBAL:0x03
722+ 0x04 , 0x00 , 0x00 , // index:u32
723+ 0x00 , DW_OP_stack_value},
724+ module_sp, &dwarf_unit, nullptr , reg_ctx),
725+ ExpectScalar (32 , 42 , false , Value::ContextType::RegisterInfo));
786726
787727 // Test that searches for opcodes work in the presence of extensions:
788728 uint8_t expr[] = {DW_OP_WASM_location, 0x03 , 0x04 , 0x00 , 0x00 , 0x00 ,
@@ -1148,17 +1088,8 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_piece_file_addr) {
11481088
11491089 uint8_t expr[] = {DW_OP_addr, 0x40 , 0x0 , 0x0 , 0x0 , DW_OP_piece, 1 ,
11501090 DW_OP_addr, 0x50 , 0x0 , 0x0 , 0x0 , DW_OP_piece, 1 };
1151- DataExtractor extractor (expr, sizeof (expr), lldb::eByteOrderLittle,
1152- /* addr_size=*/ 4 );
1153- llvm::Expected<Value> result = DWARFExpression::Evaluate (
1154- &exe_ctx, /* reg_ctx=*/ nullptr , /* module_sp=*/ {}, extractor,
1155- /* unit=*/ nullptr , lldb::eRegisterKindLLDB,
1156- /* initial_value_ptr=*/ nullptr ,
1157- /* object_address_ptr=*/ nullptr );
1158-
1159- ASSERT_THAT_EXPECTED (result, llvm::Succeeded ());
1160- ASSERT_EQ (result->GetValueType (), Value::ValueType::HostAddress);
1161- ASSERT_THAT (result->GetBuffer ().GetData (), ElementsAre (0x11 , 0x22 ));
1091+ EXPECT_THAT_EXPECTED (Evaluate (expr, {}, {}, &exe_ctx),
1092+ ExpectHostAddress ({0x11 , 0x22 }));
11621093}
11631094
11641095// / A Process whose `ReadMemory` override queries a DenseMap.
@@ -1228,28 +1159,15 @@ TEST_F(DWARFExpressionMockProcessTestWithAArch, DW_op_deref_no_ptr_fixing) {
12281159 process_sp->GetThreadList ().AddThread (thread);
12291160
12301161 auto evaluate_expr = [&](auto &expr_data) {
1231- DataExtractor extractor (expr_data, sizeof (expr_data),
1232- lldb::eByteOrderLittle,
1233- /* addr_size*/ 8 );
1234- DWARFExpression expr (extractor);
1235-
12361162 ExecutionContext exe_ctx (process_sp);
1237- llvm::Expected<Value> result = DWARFExpression::Evaluate (
1238- &exe_ctx, reg_ctx_sp.get (), /* module_sp*/ nullptr , extractor,
1239- /* unit*/ nullptr , lldb::eRegisterKindLLDB,
1240- /* initial_value_ptr=*/ nullptr ,
1241- /* object_address_ptr=*/ nullptr );
1242- return result;
1163+ return Evaluate (expr_data, {}, {}, &exe_ctx, reg_ctx_sp.get ());
12431164 };
12441165
12451166 uint8_t expr_reg[] = {DW_OP_breg22, 0 };
12461167 llvm::Expected<Value> result_reg = evaluate_expr (expr_reg);
1247- ASSERT_THAT_EXPECTED (result_reg, llvm::Succeeded ());
1248- ASSERT_EQ (result_reg->GetValueType (), Value::ValueType::LoadAddress);
1249- ASSERT_EQ (result_reg->GetScalar ().ULongLong (), addr);
1168+ EXPECT_THAT_EXPECTED (result_reg, ExpectLoadAddress (addr));
12501169
12511170 uint8_t expr_deref[] = {DW_OP_breg22, 0 , DW_OP_deref};
12521171 llvm::Expected<Value> result_deref = evaluate_expr (expr_deref);
1253- ASSERT_THAT_EXPECTED (result_deref, llvm::Succeeded ());
1254- ASSERT_EQ (result_deref->GetScalar ().ULongLong (), expected_value);
1172+ EXPECT_THAT_EXPECTED (result_deref, ExpectLoadAddress (expected_value));
12551173}
0 commit comments