diff options
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test/functionalities')
3 files changed, 181 insertions, 0 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/param_entry_vals/basic_entry_values_x86_64/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/param_entry_vals/basic_entry_values_x86_64/Makefile new file mode 100644 index 00000000000..0c26fc72697 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/param_entry_vals/basic_entry_values_x86_64/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -O1 -glldb -Xclang -femit-debug-entry-values diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/param_entry_vals/basic_entry_values_x86_64/TestBasicEntryValuesX86_64.py b/lldb/packages/Python/lldbsuite/test/functionalities/param_entry_vals/basic_entry_values_x86_64/TestBasicEntryValuesX86_64.py new file mode 100644 index 00000000000..5b5099bff5d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/param_entry_vals/basic_entry_values_x86_64/TestBasicEntryValuesX86_64.py @@ -0,0 +1,8 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), + [decorators.skipUnlessDarwin, + decorators.skipUnlessArch('x86_64'), + decorators.skipUnlessHasCallSiteInfo, + decorators.skipIf(dwarf_version=['<', '4'])]) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/param_entry_vals/basic_entry_values_x86_64/main.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/param_entry_vals/basic_entry_values_x86_64/main.cpp new file mode 100644 index 00000000000..6efd5708a73 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/param_entry_vals/basic_entry_values_x86_64/main.cpp @@ -0,0 +1,169 @@ +// Note: This test requires the SysV AMD64 ABI to be in use, and requires +// compiler support for DWARF entry values. + +// Inhibit dead-arg-elim by using 'x'. +template<typename T> __attribute__((noinline)) void use(T x) { + asm volatile ("" + /* Outputs */ : + /* Inputs */ : "g"(x) + /* Clobbers */ : + ); +} + +// Destroy %rsi in the current frame. +#define DESTROY_RSI \ + asm volatile ("xorq %%rsi, %%rsi" \ + /* Outputs */ : \ + /* Inputs */ : \ + /* Clobbers */ : "rsi" \ + ); + +struct S1 { + int field1 = 123; + int *field2 = &field1; +}; + +__attribute__((noinline)) +void func1(int &sink, int x) { + use(x); + + // Destroy 'x' in the current frame. + DESTROY_RSI; + + //% self.filecheck("image lookup -va $pc", "main.cpp", "-check-prefix=FUNC1-DESC") + // FUNC1-DESC: name = "x", type = "int", location = DW_OP_entry_value( rsi) + + ++sink; +} + +__attribute__((noinline)) +void func2(int &sink, int x) { + use(x); + + // Destroy 'x' in the current frame. + DESTROY_RSI; + + //% self.filecheck("expr x", "main.cpp", "-check-prefix=FUNC2-EXPR") + // FUNC2-EXPR: (int) ${{.*}} = 123 + + ++sink; +} + +__attribute__((noinline)) +void func3(int &sink, int *p) { + use(p); + + // Destroy 'p' in the current frame. + DESTROY_RSI; + + //% self.filecheck("expr *p", "main.cpp", "-check-prefix=FUNC3-EXPR") + // FUNC3-EXPR: (int) ${{.*}} = 123 + + ++sink; +} + +__attribute__((noinline)) +void func4_amb(int &sink, int x) { + use(x); + + // Destroy 'x' in the current frame. + DESTROY_RSI; + + //% self.filecheck("expr x", "main.cpp", "-check-prefix=FUNC4-EXPR", expect_cmd_failure=True) + // FUNC4-EXPR: couldn't get the value of variable x: Could not evaluate DW_OP_entry_value. + + ++sink; +} + +__attribute__((noinline)) +void func5_amb() {} + +__attribute__((noinline)) +void func6(int &sink, int x) { + if (sink > 0) + func4_amb(sink, x); /* tail (taken) */ + else + func5_amb(); /* tail */ +} + +__attribute__((noinline)) +void func7(int &sink, int x) { + //% self.filecheck("bt", "main.cpp", "-check-prefix=FUNC7-BT") + // FUNC7-BT: func7 + // FUNC7-BT-NEXT: [inlined] func8_inlined + // FUNC7-BT-NEXT: [inlined] func9_inlined + // FUNC7-BT-NEXT: func10 + use(x); + + // Destroy 'x' in the current frame. + DESTROY_RSI; + + //% self.filecheck("expr x", "main.cpp", "-check-prefix=FUNC7-EXPR") + // FUNC7-EXPR: (int) ${{.*}} = 123 + + ++sink; +} + +__attribute__((always_inline)) +void func8_inlined(int &sink, int x) { + func7(sink, x); +} + +__attribute__((always_inline)) +void func9_inlined(int &sink, int x) { + func8_inlined(sink, x); +} + +__attribute__((noinline, disable_tail_calls)) +void func10(int &sink, int x) { + func9_inlined(sink, x); +} + +__attribute__((noinline)) +void func11_tailcalled(int &sink, int x) { + //% self.filecheck("bt", "main.cpp", "-check-prefix=FUNC11-BT") + // FUNC11-BT: func11_tailcalled{{.*}} + // FUNC11-BT-NEXT: func12{{.*}} [artificial] + use(x); + + // Destroy 'x' in the current frame. + DESTROY_RSI; + + //% self.filecheck("expr x", "main.cpp", "-check-prefix=FUNC11-EXPR") + // FUNC11-EXPR: (int) ${{.*}} = 123 + + ++sink; +} + +__attribute__((noinline)) +void func12(int &sink, int x) { + func11_tailcalled(sink, x); +} + +__attribute__((disable_tail_calls)) +int main() { + int sink = 0; + S1 s1; + + // Test location dumping for DW_OP_entry_value. + func1(sink, 123); + + // Test evaluation of "DW_OP_constu" in the parent frame. + func2(sink, 123); + + // Test evaluation of "DW_OP_fbreg -24, DW_OP_deref" in the parent frame. + func3(sink, s1.field2); + + // The sequences `main -> func4 -> func{5,6}_amb -> sink` are both plausible. + // Test that lldb doesn't attempt to guess which one occurred: entry value + // evaluation should fail. + func6(sink, 123); + + // Test that evaluation can "see through" inlining. + func10(sink, 123); + + // Test that evaluation can "see through" tail calls. + func12(sink, 123); + + return 0; +} |