diff options
Diffstat (limited to 'lldb/test')
139 files changed, 4736 insertions, 741 deletions
diff --git a/lldb/test/API/commands/command/script/add/TestAddParsedCommand.py b/lldb/test/API/commands/command/script/add/TestAddParsedCommand.py index 6fac1eba919b..9deebe29eaae 100644 --- a/lldb/test/API/commands/command/script/add/TestAddParsedCommand.py +++ b/lldb/test/API/commands/command/script/add/TestAddParsedCommand.py @@ -34,6 +34,7 @@ class ParsedCommandTestCase(TestBase): else: (short_opt, type, long_opt) = elem substrs.append(f"-{short_opt} <{type}> ( --{long_opt} <{type}> )") + self.expect("help " + cmd_name, substrs=substrs) def run_one_repeat(self, commands, expected_num_errors): @@ -215,6 +216,19 @@ class ParsedCommandTestCase(TestBase): "bool-arg (set: True): False", "shlib-name (set: True): Something", "disk-file-name (set: False):", + "flag-value (set: False):", + "line-num (set: False):", + "enum-option (set: False):", + ], + ) + # Make sure flag values work: + self.expect( + "no-args -b false -s Something -f", + substrs=[ + "bool-arg (set: True): False", + "shlib-name (set: True): Something", + "disk-file-name (set: False):", + "flag-value (set: True):", "line-num (set: False):", "enum-option (set: False):", ], @@ -295,7 +309,7 @@ class ParsedCommandTestCase(TestBase): # no-args turns off auto-repeat results = self.run_one_repeat("no-args\n\n", 1) - self.assertIn("No auto repeat", results, "Got auto-repeat error") + self.assertIn("no auto repeat", results, "Got auto-repeat error") # one-args does the normal repeat results = self.run_one_repeat("one-arg-no-opt ONE_ARG\n\n", 0) diff --git a/lldb/test/API/commands/command/script/add/test_commands.py b/lldb/test/API/commands/command/script/add/test_commands.py index b15ea935c058..db302796819a 100644 --- a/lldb/test/API/commands/command/script/add/test_commands.py +++ b/lldb/test/API/commands/command/script/add/test_commands.py @@ -16,10 +16,16 @@ class ReportingCmd(ParsedCommand): if len(opt_def): result.AppendMessage("Options:\n") for long_option, elem in opt_def.items(): - dest = elem["dest"] - result.AppendMessage( - f"{long_option} (set: {elem['_value_set']}): {object.__getattribute__(self.get_parser(), dest)}\n" - ) + if "value_type" in elem: + print(f"Looking at {long_option} - {elem}") + dest = elem["dest"] + result.AppendMessage( + f"{long_option} (set: {elem['_value_set']}): {object.__getattribute__(self.get_parser(), dest)}\n" + ) + else: + result.AppendMessage( + f"{long_option} (set: {elem['_value_set']}): flag value\n" + ) else: result.AppendMessage("No options\n") @@ -78,6 +84,8 @@ class NoArgsCommand(ReportingCmd): default=None, ) + ov_parser.add_option("f", "flag-value", "This is a flag value") + ov_parser.add_option( "l", "line-num", diff --git a/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py index a488276c2e54..ed028a1a4ea3 100644 --- a/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py @@ -11,7 +11,6 @@ class TestCase(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py index 38b8508b516d..0fb6e883597d 100644 --- a/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py @@ -11,7 +11,6 @@ class TestBasicDeque(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py index 85eaa8fe39ea..e631a8737637 100644 --- a/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py @@ -12,7 +12,6 @@ class TestDbgInfoContentDeque(TestBase): @skipIf(compiler=no_match("clang")) @skipIf(compiler="clang", compiler_version=["<", "18.0"]) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardListFromStdModule.py index a3a409d678ee..1d0f9ccf18c6 100644 --- a/lldb/test/API/commands/expression/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardListFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardListFromStdModule.py @@ -11,7 +11,6 @@ class TestDbgInfoContentForwardList(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py index c9f4a1588f39..a6ba0810e68e 100644 --- a/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py @@ -11,7 +11,6 @@ class TestBasicForwardList(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/iterator/TestIteratorFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/iterator/TestIteratorFromStdModule.py index 5c82ac352abb..370c3674faec 100644 --- a/lldb/test/API/commands/expression/import-std-module/iterator/TestIteratorFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/iterator/TestIteratorFromStdModule.py @@ -11,7 +11,6 @@ class TestCase(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py index 0ecc244412da..b26bd7dedda8 100644 --- a/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py @@ -13,7 +13,6 @@ class TestDbgInfoContentList(TestBase): @skipIf(compiler=no_match("clang")) @skipIf(compiler="clang", compiler_version=["<", "12.0"]) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py index f29f353ae079..6253a35e926d 100644 --- a/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py @@ -11,7 +11,6 @@ class TestBasicList(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/non-module-type-separation/TestNonModuleTypeSeparation.py b/lldb/test/API/commands/expression/import-std-module/non-module-type-separation/TestNonModuleTypeSeparation.py index 5e0ab48cfa5c..cc91ddcc538b 100644 --- a/lldb/test/API/commands/expression/import-std-module/non-module-type-separation/TestNonModuleTypeSeparation.py +++ b/lldb/test/API/commands/expression/import-std-module/non-module-type-separation/TestNonModuleTypeSeparation.py @@ -12,7 +12,6 @@ class TestCase(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): """ This test is creating ValueObjects with both C++ module and debug diff --git a/lldb/test/API/commands/expression/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContentFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContentFromStdModule.py index 50419b6f761c..5bfdb9baf663 100644 --- a/lldb/test/API/commands/expression/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContentFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContentFromStdModule.py @@ -11,7 +11,6 @@ class TestSharedPtrDbgInfoContent(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/shared_ptr/TestSharedPtrFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/shared_ptr/TestSharedPtrFromStdModule.py index 9f04361c48d7..da86466018bb 100644 --- a/lldb/test/API/commands/expression/import-std-module/shared_ptr/TestSharedPtrFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/shared_ptr/TestSharedPtrFromStdModule.py @@ -10,9 +10,8 @@ from lldbsuite.test import lldbutil class TestSharedPtr(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) - @skipIf(compiler="clang", compiler_version=["<", "17.0"]) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin + @skipIf(compiler="clang", compiler_version=["<", "17.0"]) def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/vector-dbg-info-content/TestDbgInfoContentVectorFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/vector-dbg-info-content/TestDbgInfoContentVectorFromStdModule.py index ba4df40bbbc5..1c32222e64f1 100644 --- a/lldb/test/API/commands/expression/import-std-module/vector-dbg-info-content/TestDbgInfoContentVectorFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/vector-dbg-info-content/TestDbgInfoContentVectorFromStdModule.py @@ -14,7 +14,6 @@ class TestDbgInfoContentVector(TestBase): @skipIf(compiler="clang", compiler_version=["<", "12.0"]) @skipIf(macos_version=["<", "14.0"]) @skipIfDarwin # https://github.com/llvm/llvm-project/issues/106475 - @skipIfLinux def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/vector-of-vectors/TestVectorOfVectorsFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/vector-of-vectors/TestVectorOfVectorsFromStdModule.py index 6fa9dd5b6f56..2cddce09aa8b 100644 --- a/lldb/test/API/commands/expression/import-std-module/vector-of-vectors/TestVectorOfVectorsFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/vector-of-vectors/TestVectorOfVectorsFromStdModule.py @@ -11,7 +11,6 @@ class TestVectorOfVectors(TestBase): @add_test_categories(["libc++"]) @skipIf(compiler=no_match("clang")) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtrFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtrFromStdModule.py index 19d24c1bcb89..28edf1999362 100644 --- a/lldb/test/API/commands/expression/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtrFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtrFromStdModule.py @@ -12,7 +12,6 @@ class TestDbgInfoContentWeakPtr(TestBase): @skipIf(compiler=no_match("clang")) @skipIf(compiler="clang", compiler_version=["<", "17.0"]) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/expression/import-std-module/weak_ptr/TestWeakPtrFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/weak_ptr/TestWeakPtrFromStdModule.py index e3cc9b92569c..f0a0a46a73e9 100644 --- a/lldb/test/API/commands/expression/import-std-module/weak_ptr/TestWeakPtrFromStdModule.py +++ b/lldb/test/API/commands/expression/import-std-module/weak_ptr/TestWeakPtrFromStdModule.py @@ -12,7 +12,6 @@ class TestSharedPtr(TestBase): @skipIf(compiler=no_match("clang")) @skipIf(compiler="clang", compiler_version=["<", "17.0"]) @skipIf(macos_version=["<", "15.0"]) - @skipUnlessDarwin def test(self): self.build() diff --git a/lldb/test/API/commands/frame/select/TestFrameSelect.py b/lldb/test/API/commands/frame/select/TestFrameSelect.py index cb10105c0fe7..9e21495d4b53 100644 --- a/lldb/test/API/commands/frame/select/TestFrameSelect.py +++ b/lldb/test/API/commands/frame/select/TestFrameSelect.py @@ -23,12 +23,12 @@ class TestFrameSelect(TestBase): self.expect( "frame select -r -1", error=True, - substrs=["Already at the bottom of the stack."], + substrs=["already at the bottom of the stack"], ) self.expect( "frame select -r -2147483647", error=True, - substrs=["Already at the bottom of the stack."], + substrs=["already at the bottom of the stack"], ) self.expect( "frame select -r -2147483648", @@ -61,7 +61,7 @@ class TestFrameSelect(TestBase): self.expect( "frame select -r 1", error=True, - substrs=["Already at the top of the stack."], + substrs=["already at the top of the stack"], ) @no_debug_info_test diff --git a/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py b/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py index 0f5605718939..f47e86266f47 100644 --- a/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py +++ b/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py @@ -66,30 +66,27 @@ class TestFrameVarDILArraySubscript(TestBase): self.expect( "frame var 'int_arr[1.0]'", error=True, - substrs=["expected 'r_square', got: <'.'"], + substrs=["failed to parse integer constant: <'1.0' (float_constant)>"], ) - # Base should be a "pointer to T" and index should be of an integral type. - self.expect( - "frame var 'idx_1[0]'", - error=True, - substrs=["subscripted value is not an array or pointer"], - ) + # Test accessing bits in scalar types. + self.expect_var_path("idx_1[0]", value="1") + self.expect_var_path("idx_1[1]", value="0") + self.expect_var_path("1[0]", value="1") + + # Bit access not valid for a reference. self.expect( "frame var 'idx_1_ref[0]'", error=True, - substrs=["subscripted value is not an array or pointer"], + substrs=["bitfield range 0-0 is not valid"], ) + + # Base should be a "pointer to T" and index should be of an integral type. self.expect( "frame var 'int_arr[int_ptr]'", error=True, substrs=["failed to parse integer constant"], ) - self.expect( - "frame var '1[2]'", - error=True, - substrs=["Unexpected token"], - ) # Base should not be a pointer to void self.expect( @@ -105,6 +102,8 @@ class TestFrameVarDILArraySubscript(TestBase): ) self.runCmd("settings set target.experimental.use-DIL true") + self.runCmd("script from myArraySynthProvider import *") + self.runCmd("type synth add -l myArraySynthProvider myArray") # Test synthetic value subscription self.expect_var_path("vector[1]", value="2") @@ -113,3 +112,7 @@ class TestFrameVarDILArraySubscript(TestBase): error=True, substrs=["array index 100 is not valid"], ) + self.expect( + "frame var 'ma_ptr[0]'", + substrs=["(myArray) ma_ptr[0] = ([0] = 7, [1] = 8, [2] = 9, [3] = 10)"], + ) diff --git a/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/main.cpp index a9a3612dfae5..03ad3e872ca7 100644 --- a/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/main.cpp +++ b/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/main.cpp @@ -1,5 +1,11 @@ #include <vector> +class myArray { +public: + int m_array[4] = {7, 8, 9, 10}; + int m_arr_size = 4; +}; + int main(int argc, char **argv) { int int_arr[] = {1, 2, 3}; int *int_ptr = int_arr; @@ -29,5 +35,8 @@ int main(int argc, char **argv) { std::vector<int> vector = {1, 2, 3}; + myArray ma; + myArray *ma_ptr = &ma; + return 0; // Set a breakpoint here } diff --git a/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/myArraySynthProvider.py b/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/myArraySynthProvider.py new file mode 100644 index 000000000000..167899bd3907 --- /dev/null +++ b/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/myArraySynthProvider.py @@ -0,0 +1,33 @@ +import lldb + + +class myArraySynthProvider: + def __init__(self, valobj, dict): + self.valobj = valobj + + def num_children(self): + size_valobj = self.valobj.GetChildMemberWithName("m_arr_size") + if size_valobj: + return size_valobj.GetValueAsUnsigned(0) + return 0 + + def get_child_at_index(self, index): + size_valobj = self.valobj.GetChildMemberWithName("m_arr_size") + arr = self.valobj.GetChildMemberWithName("m_array") + if not size_valobj or not arr: + return None + max_idx = size_valobj.GetValueAsUnsigned(0) + if index >= max_idx: + return None + return arr.GetChildAtIndex(index) + + def get_child_index(self, name): + if name == "[0]": + return 0 + if name == "[1]": + return + if name == "[2]": + return 2 + if name == "[3]": + return 3 + return -1 diff --git a/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py b/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py index 38c72131d797..28eba4f1a70b 100644 --- a/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py +++ b/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py @@ -35,7 +35,7 @@ class TestFrameVarDILIndirection(TestBase): self.expect( "frame variable '*1'", error=True, - substrs=["Unexpected token: <'1' (numeric_constant)>"], + substrs=["dereference failed: not a pointer, reference or array type"], ) self.expect( "frame variable '*val'", diff --git a/lldb/test/API/commands/frame/var-dil/expr/Literals/Makefile b/lldb/test/API/commands/frame/var-dil/expr/Literals/Makefile new file mode 100644 index 000000000000..99998b20bcb0 --- /dev/null +++ b/lldb/test/API/commands/frame/var-dil/expr/Literals/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py b/lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py new file mode 100644 index 000000000000..431ec2829bc7 --- /dev/null +++ b/lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py @@ -0,0 +1,88 @@ +""" +Test DIL literals. +""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from lldbsuite.test import lldbutil + + +class TestFrameVarDILLiterals(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + def test_literals(self): + self.build() + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp") + ) + + self.runCmd("settings set target.experimental.use-DIL true") + + # Check number literals parsing + self.expect_var_path("1.0", value="1", type="double") + self.expect_var_path("1.0f", value="1", type="float") + self.expect_var_path("0x1.2p+3f", value="9", type="float") + self.expect_var_path("1", value="1", type="int") + self.expect_var_path("1u", value="1", type="unsigned int") + self.expect_var_path("0b1l", value="1", type="long") + self.expect_var_path("01ul", value="1", type="unsigned long") + self.expect_var_path("01lu", value="1", type="unsigned long") + self.expect_var_path("0o1ll", value="1", type="long long") + self.expect_var_path("0x1ULL", value="1", type="unsigned long long") + self.expect_var_path("0x1llu", value="1", type="unsigned long long") + self.expect( + "frame var '1LLL'", + error=True, + substrs=["Failed to parse token as numeric-constant"], + ) + self.expect( + "frame var '1ullu'", + error=True, + substrs=["Failed to parse token as numeric-constant"], + ) + + # Check integer literal type edge cases (dil::Interpreter::PickIntegerType) + frame = thread.GetFrameAtIndex(0) + v = frame.GetValueForVariablePath("argc") + # Creating an SBType from a BasicType still requires any value from the frame + int_size = v.GetType().GetBasicType(lldb.eBasicTypeInt).GetByteSize() + long_size = v.GetType().GetBasicType(lldb.eBasicTypeLong).GetByteSize() + longlong_size = v.GetType().GetBasicType(lldb.eBasicTypeLongLong).GetByteSize() + + longlong_str = "0x" + "F" * longlong_size * 2 + longlong_str = str(int(longlong_str, 16)) + self.assert_literal_type(frame, longlong_str, lldb.eBasicTypeUnsignedLongLong) + toolong_str = "0x" + "F" * longlong_size * 2 + "F" + self.expect( + f"frame var '{toolong_str}'", + error=True, + substrs=[ + "integer literal is too large to be represented in any integer type" + ], + ) + + # These check only apply if adjacent types have different sizes + if int_size < long_size: + # For exmaple, 0xFFFFFFFF and 4294967295 will have different types + # even though the numeric value is the same + hex_str = "0x" + "F" * int_size * 2 + dec_str = str(int(hex_str, 16)) + self.assert_literal_type(frame, hex_str, lldb.eBasicTypeUnsignedInt) + self.assert_literal_type(frame, dec_str, lldb.eBasicTypeLong) + long_str = "0x" + "F" * int_size * 2 + "F" + ulong_str = long_str + "u" + self.assert_literal_type(frame, long_str, lldb.eBasicTypeLong) + self.assert_literal_type(frame, ulong_str, lldb.eBasicTypeUnsignedLong) + if long_size < longlong_size: + longlong_str = "0x" + "F" * long_size * 2 + "F" + ulonglong_str = longlong_str + "u" + self.assert_literal_type(frame, longlong_str, lldb.eBasicTypeLongLong) + self.assert_literal_type( + frame, ulonglong_str, lldb.eBasicTypeUnsignedLongLong + ) + + def assert_literal_type(self, frame, literal, expected_type): + value = frame.GetValueForVariablePath(literal) + basic_type = value.GetType().GetBasicType() + self.assertEqual(basic_type, expected_type) diff --git a/lldb/test/API/commands/frame/var-dil/expr/Literals/main.cpp b/lldb/test/API/commands/frame/var-dil/expr/Literals/main.cpp new file mode 100644 index 000000000000..c9bd8afb0d71 --- /dev/null +++ b/lldb/test/API/commands/frame/var-dil/expr/Literals/main.cpp @@ -0,0 +1,3 @@ +int main(int argc, char **argv) { + return 0; // Set a breakpoint here +} diff --git a/lldb/test/API/commands/statistics/basic/TestStats.py b/lldb/test/API/commands/statistics/basic/TestStats.py index e9ee8b8661e5..c8527abf3c84 100644 --- a/lldb/test/API/commands/statistics/basic/TestStats.py +++ b/lldb/test/API/commands/statistics/basic/TestStats.py @@ -1,6 +1,7 @@ import json import os import re +import shutil import lldb from lldbsuite.test.decorators import * @@ -179,6 +180,7 @@ class TestCase(TestBase): "totalDebugInfoParseTime", "totalDwoFileCount", "totalLoadedDwoFileCount", + "totalDwoErrorCount", ] self.verify_keys(debug_stats, '"debug_stats"', debug_stat_keys, None) if self.getPlatform() != "windows": @@ -291,6 +293,7 @@ class TestCase(TestBase): "totalDebugInfoParseTime", "totalDwoFileCount", "totalLoadedDwoFileCount", + "totalDwoErrorCount", ] self.verify_keys(debug_stats, '"debug_stats"', debug_stat_keys, None) stats = debug_stats["targets"][0] @@ -331,6 +334,7 @@ class TestCase(TestBase): "totalDebugInfoByteSize", "totalDwoFileCount", "totalLoadedDwoFileCount", + "totalDwoErrorCount", ] self.verify_keys(debug_stats, '"debug_stats"', debug_stat_keys, None) @@ -385,6 +389,7 @@ class TestCase(TestBase): "totalDebugInfoByteSize", "totalDwoFileCount", "totalLoadedDwoFileCount", + "totalDwoErrorCount", ] self.verify_keys(debug_stats, '"debug_stats"', debug_stat_keys, None) stats = debug_stats["targets"][0] @@ -407,6 +412,7 @@ class TestCase(TestBase): "symbolTableSavedToCache", "dwoFileCount", "loadedDwoFileCount", + "dwoErrorCount", "triple", "uuid", ] @@ -497,6 +503,7 @@ class TestCase(TestBase): "totalDebugInfoByteSize", "totalDwoFileCount", "totalLoadedDwoFileCount", + "totalDwoErrorCount", ] self.verify_keys(debug_stats, '"debug_stats"', debug_stat_keys, None) target_stats = debug_stats["targets"][0] @@ -655,6 +662,99 @@ class TestCase(TestBase): self.assertEqual(debug_stats["totalDwoFileCount"], 2) self.assertEqual(debug_stats["totalLoadedDwoFileCount"], 2) + @add_test_categories(["dwo"]) + def test_dwo_missing_error_stats(self): + """ + Test that DWO missing errors are reported correctly in statistics. + This test: + 1) Builds a program with split DWARF (.dwo files) + 2) Delete one of the two .dwo files + 3) Verify that 1 DWO error is reported in statistics + """ + da = { + "CXX_SOURCES": "dwo_error_main.cpp dwo_error_foo.cpp", + "EXE": self.getBuildArtifact("a.out"), + } + # -gsplit-dwarf creates separate .dwo files, + # Expected output: dwo_error_main.dwo (contains main) and dwo_error_foo.dwo (contains foo struct/function) + self.build(dictionary=da, debug_info="dwo") + exe = self.getBuildArtifact("a.out") + + expected_dwo_files = [ + self.getBuildArtifact("dwo_error_main.dwo"), + self.getBuildArtifact("dwo_error_foo.dwo"), + ] + + # Verify expected files exist + for dwo_file in expected_dwo_files: + self.assertTrue( + os.path.exists(dwo_file), + f"Expected .dwo file does not exist: {dwo_file}", + ) + + # Remove one of .dwo files to trigger DWO load error + dwo_main_file = self.getBuildArtifact("dwo_error_main.dwo") + os.remove(dwo_main_file) + + target = self.createTestTarget(file_path=exe) + debug_stats = self.get_stats() + + # Check DWO load error statistics are reported + self.assertIn("totalDwoErrorCount", debug_stats) + self.assertEqual(debug_stats["totalDwoErrorCount"], 1) + + # Since there's only one module, module stats should have the same count as total count + self.assertIn("dwoErrorCount", debug_stats["modules"][0]) + self.assertEqual(debug_stats["modules"][0]["dwoErrorCount"], 1) + + @add_test_categories(["dwo"]) + def test_dwo_id_mismatch_error_stats(self): + """ + Test that DWO ID mismatch errors are reported correctly in statistics. + This test: + 1) Builds a program with split DWARF (.dwo files) + 2) Replace one of the .dwo files with a mismatched one to cause a DWO ID mismatch error + 3) Verifies that a DWO error is reported in statistics + """ + da = { + "CXX_SOURCES": "dwo_error_main.cpp dwo_error_foo.cpp", + "EXE": self.getBuildArtifact("a.out"), + } + # -gsplit-dwarf creates separate .dwo files, + # Expected output: dwo_error_main.dwo (contains main) and dwo_error_foo.dwo (contains foo struct/function) + self.build(dictionary=da, debug_info="dwo") + exe = self.getBuildArtifact("a.out") + + expected_dwo_files = [ + self.getBuildArtifact("dwo_error_main.dwo"), + self.getBuildArtifact("dwo_error_foo.dwo"), + ] + + # Verify expected files exist + for dwo_file in expected_dwo_files: + self.assertTrue( + os.path.exists(dwo_file), + f"Expected .dwo file does not exist: {dwo_file}", + ) + + # Replace one of the original .dwo file content with another one to trigger DWO ID mismatch error + dwo_foo_file = self.getBuildArtifact("dwo_error_foo.dwo") + dwo_main_file = self.getBuildArtifact("dwo_error_main.dwo") + + shutil.copy(dwo_main_file, dwo_foo_file) + + # Create a new target and get stats + target = self.createTestTarget(file_path=exe) + debug_stats = self.get_stats() + + # Check that DWO load error statistics are reported + self.assertIn("totalDwoErrorCount", debug_stats) + self.assertEqual(debug_stats["totalDwoErrorCount"], 1) + + # Since there's only one module, module stats should have the same count as total count + self.assertIn("dwoErrorCount", debug_stats["modules"][0]) + self.assertEqual(debug_stats["modules"][0]["dwoErrorCount"], 1) + @skipUnlessDarwin @no_debug_info_test def test_dsym_binary_has_symfile_in_stats(self): diff --git a/lldb/test/API/commands/statistics/basic/dwo_error_foo.cpp b/lldb/test/API/commands/statistics/basic/dwo_error_foo.cpp new file mode 100644 index 000000000000..41618bdcee95 --- /dev/null +++ b/lldb/test/API/commands/statistics/basic/dwo_error_foo.cpp @@ -0,0 +1,10 @@ +struct foo { + int x; + bool y; +}; + +void dwo_error_foo() { + foo f; + f.x = 1; + f.y = true; +} diff --git a/lldb/test/API/commands/statistics/basic/dwo_error_main.cpp b/lldb/test/API/commands/statistics/basic/dwo_error_main.cpp new file mode 100644 index 000000000000..4f09bd74e1fd --- /dev/null +++ b/lldb/test/API/commands/statistics/basic/dwo_error_main.cpp @@ -0,0 +1,5 @@ +void dwo_error_foo(); +int main() { + dwo_error_foo(); + return 0; +} diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py index 66f6e3e7502c..8ae2d4a60d60 100644 --- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py +++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py @@ -2,7 +2,6 @@ Test that ASan memory history provider returns correct stack traces """ - import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -10,6 +9,7 @@ from lldbsuite.test import lldbplatform from lldbsuite.test import lldbutil from lldbsuite.test_event.build_exception import BuildError + class MemoryHistoryTestCase(TestBase): @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default @expectedFailureNetBSD @@ -94,6 +94,11 @@ class MemoryHistoryTestCase(TestBase): ) self.check_traces() + if self.platformIsDarwin(): + # Make sure we're not stopped in the sanitizer library but instead at the + # point of failure in the user-code. + self.assertEqual(self.frame().GetFunctionName(), "main") + # do the same using SB API process = self.dbg.GetSelectedTarget().process val = ( @@ -218,6 +223,11 @@ class MemoryHistoryTestCase(TestBase): self.check_traces() + if self.platformIsDarwin(): + # Make sure we're not stopped in the sanitizer library but instead at the + # point of failure in the user-code. + self.assertEqual(self.frame().GetFunctionName(), "main") + # make sure the 'memory history' command still works even when we're # generating a report now self.expect( diff --git a/lldb/test/API/functionalities/asan/TestReportData.py b/lldb/test/API/functionalities/asan/TestReportData.py index dd6834a01b80..c832436b0f44 100644 --- a/lldb/test/API/functionalities/asan/TestReportData.py +++ b/lldb/test/API/functionalities/asan/TestReportData.py @@ -2,7 +2,6 @@ Test the AddressSanitizer runtime support for report breakpoint and data extraction. """ - import json import lldb from lldbsuite.test.decorators import * @@ -10,6 +9,7 @@ from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil from lldbsuite.test_event.build_exception import BuildError + class AsanTestReportDataCase(TestBase): @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default @expectedFailureNetBSD @@ -67,6 +67,11 @@ class AsanTestReportDataCase(TestBase): lldb.eStopReasonInstrumentation, ) + if self.platformIsDarwin(): + # Make sure we're not stopped in the sanitizer library but instead at the + # point of failure in the user-code. + self.assertEqual(self.frame().GetFunctionName(), "main") + self.expect( "bt", "The backtrace should show the crashing line", diff --git a/lldb/test/API/functionalities/completion/TestCompletion.py b/lldb/test/API/functionalities/completion/TestCompletion.py index e7c53729f209..45750c7ac081 100644 --- a/lldb/test/API/functionalities/completion/TestCompletion.py +++ b/lldb/test/API/functionalities/completion/TestCompletion.py @@ -676,8 +676,8 @@ class CommandLineCompletionTestCase(TestBase): self.check_completion_with_desc( "breakpoint set -", [ - ["-h", "Set the breakpoint on exception catcH."], - ["-w", "Set the breakpoint on exception throW."], + ["-h", "Set the breakpoint on exception catch."], + ["-w", "Set the breakpoint on exception throw."], ], ) @@ -685,8 +685,8 @@ class CommandLineCompletionTestCase(TestBase): self.check_completion_with_desc( "breakpoint set --", [ - ["--on-catch", "Set the breakpoint on exception catcH."], - ["--on-throw", "Set the breakpoint on exception throW."], + ["--on-catch", "Set the breakpoint on exception catch."], + ["--on-throw", "Set the breakpoint on exception throw."], ], ) @@ -694,8 +694,8 @@ class CommandLineCompletionTestCase(TestBase): self.check_completion_with_desc( "breakpoint set --on-", [ - ["--on-catch", "Set the breakpoint on exception catcH."], - ["--on-throw", "Set the breakpoint on exception throW."], + ["--on-catch", "Set the breakpoint on exception catch."], + ["--on-throw", "Set the breakpoint on exception throw."], ], ) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ranges/ref_view/TestDataFormatterStdRangesRefView.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ranges/ref_view/TestDataFormatterStdRangesRefView.py index f135da70c7b4..9ba10575d6fe 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ranges/ref_view/TestDataFormatterStdRangesRefView.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ranges/ref_view/TestDataFormatterStdRangesRefView.py @@ -29,7 +29,6 @@ class StdRangesRefViewDataFormatterTestCase(TestBase): def do_test(self): """Test that std::ranges::ref_view is formatted correctly when printed.""" - self.build() (self.target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, "Break here", lldb.SBFileSpec("main.cpp", False) ) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py index fec20bae997e..6a27b5d2f078 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py @@ -80,6 +80,8 @@ class StdStringDataFormatterTestCase(TestBase): '(%s::string) Q = "quite a long std::strin with lots of info inside it"' % ns, "(%s::string *) null_str = nullptr" % ns, + '(CustomString) custom_str = "hello!"', + '(CustomWString) custom_wstr = L"hello!"', ], ) @@ -143,6 +145,10 @@ class StdStringDataFormatterTestCase(TestBase): '(%s::u16string) u16_empty = u""' % ns, '(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns, '(%s::u32string) u32_empty = U""' % ns, + '(CustomStringU16) custom_u16 = u"ß水氶"', + '(CustomStringU16) custom_u16_empty = u""', + '(CustomStringU32) custom_u32 = U"🍄🍅🍆🍌"', + '(CustomStringU32) custom_u32_empty = U""', ], ) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp index f22c890861d0..577b78e35fc1 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp @@ -1,6 +1,33 @@ +#include <cstdlib> #include <stdint.h> #include <string> +template <typename T> struct CustomAlloc { + using value_type = T; + using pointer = value_type *; + using const_pointer = const value_type *; + using size_type = std::size_t; + + pointer allocate(size_type n) { return (T *)malloc(n * sizeof(T)); } + + void deallocate(pointer p, size_type) { + if (p) + free(p); + } +}; + +using CustomString = + std::basic_string<char, std::char_traits<char>, CustomAlloc<char>>; + +using CustomWString = + std::basic_string<wchar_t, std::char_traits<wchar_t>, CustomAlloc<wchar_t>>; + +using CustomStringU16 = std::basic_string<char16_t, std::char_traits<char16_t>, + CustomAlloc<char16_t>>; + +using CustomStringU32 = std::basic_string<char32_t, std::char_traits<char32_t>, + CustomAlloc<char32_t>>; + size_t touch_string(std::string &in_str) { return in_str.size(); // Break here to look at bad string } @@ -99,8 +126,16 @@ int main() { std::string *pq = &q; std::string *pQ = &Q; + CustomString custom_str("hello!"); + CustomWString custom_wstr(L"hello!"); + CustomStringU16 custom_u16(u16_string.c_str()); + CustomStringU16 custom_u16_empty(u""); + CustomStringU32 custom_u32(u32_string.c_str()); + CustomStringU32 custom_u32_empty(U""); + S.assign(L"!!!!!"); // Set break point at this line. std::string *not_a_string = (std::string *)0x0; touch_string(*not_a_string); + return 0; } diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/invalid-vector/TestDataFormatterLibcxxInvalidVectorSimulator.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/invalid-vector/TestDataFormatterLibcxxInvalidVectorSimulator.py index 1a23d9a19fe1..c3d51a49c3f5 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/invalid-vector/TestDataFormatterLibcxxInvalidVectorSimulator.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/invalid-vector/TestDataFormatterLibcxxInvalidVectorSimulator.py @@ -21,21 +21,21 @@ class LibcxxInvalidVectorDataFormatterSimulatorTestCase(TestBase): self.expect( "frame variable v1", - substrs=["size=error: Invalid value for end of vector."], + substrs=["size=error: invalid value for end of vector"], ) self.expect( "frame variable v2", - substrs=["size=error: Invalid value for start of vector."], + substrs=["size=error: invalid value for start of vector"], ) self.expect( "frame variable v3", - substrs=["size=error: Start of vector data begins after end pointer."], + substrs=["size=error: start of vector data begins after end pointer"], ) self.expect( "frame variable v4", - substrs=["size=error: Failed to determine start/end of vector data."], + substrs=["size=error: failed to determine start/end of vector data"], ) self.expect( "frame variable v5", - substrs=["size=error: Size not multiple of element size."], + substrs=["size=error: size not multiple of element size"], ) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/invalid-vector/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/invalid-vector/main.cpp index f10811817c0d..5943b35deab8 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/invalid-vector/main.cpp +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/invalid-vector/main.cpp @@ -1,4 +1,4 @@ -#define COMPRESSED_PAIR_REV 3 +#define COMPRESSED_PAIR_REV 4 #include <libcxx-simulators-common/compressed_pair.h> namespace std { diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py index c8d9c2e389a0..f27fc2e3c456 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py @@ -28,7 +28,7 @@ class LibcxxStringDataFormatterSimulatorTestCase(TestBase): for v in [None, "ALTERNATE_LAYOUT"]: for r in range(6): - for c in range(4): + for c in range(5): name = "test_r%d_c%d" % (r, c) defines = ["REVISION=%d" % r, "COMPRESSED_PAIR_REV=%d" % c] if v: diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp index cf431e524069..b19c05159670 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp @@ -209,7 +209,7 @@ public: __long &getLongRep() { #if COMPRESSED_PAIR_REV == 0 return __r_.first().__l; -#elif COMPRESSED_PAIR_REV <= 3 +#else return __rep_.__l; #endif } @@ -217,14 +217,14 @@ public: __short &getShortRep() { #if COMPRESSED_PAIR_REV == 0 return __r_.first().__s; -#elif COMPRESSED_PAIR_REV <= 3 +#else return __rep_.__s; #endif } #if COMPRESSED_PAIR_REV == 0 std::__lldb::__compressed_pair<__rep, allocator_type> __r_; -#elif COMPRESSED_PAIR_REV <= 3 +#else _LLDB_COMPRESSED_PAIR(__rep, __rep_, allocator_type, __alloc_); #endif diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py index e623c3a1413b..1e25ac947203 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py @@ -26,7 +26,7 @@ class LibcxxUniquePtrDataFormatterSimulatorTestCase(TestBase): ) -for r in range(4): +for r in range(5): name = "test_r%d" % r defines = ["COMPRESSED_PAIR_REV=%d" % r] diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/main.cpp index 3d174a91cc26..bd840aaceffa 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/main.cpp +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/main.cpp @@ -20,8 +20,7 @@ public: std::__lldb::__compressed_pair<pointer, deleter_type> __ptr_; explicit unique_ptr(pointer __p) noexcept : __ptr_(__p, std::__lldb::__value_init_tag()) {} -#elif COMPRESSED_PAIR_REV == 1 || COMPRESSED_PAIR_REV == 2 || \ - COMPRESSED_PAIR_REV == 3 +#else _LLDB_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_); explicit unique_ptr(pointer __p) noexcept : __ptr_(__p), __deleter_() {} #endif diff --git a/lldb/test/API/functionalities/disassembler-variables/Makefile b/lldb/test/API/functionalities/disassembler-variables/Makefile new file mode 100644 index 000000000000..3d4bcd22fa65 --- /dev/null +++ b/lldb/test/API/functionalities/disassembler-variables/Makefile @@ -0,0 +1,32 @@ +# List all assembler inputs stable test fixtures. +ASM_SOURCES := \ + d_original_example.s \ + regs_int_params.s \ + regs_fp_params.s \ + regs_mixed_params.s \ + live_across_call.s \ + loop_reg_rotate.s \ + seed_reg_const_undef.s + +ASM_OBJS := $(ASM_SOURCES:.s=.o) + +# Provide a tiny dummy so the harness can link an exe without ASM_OBJS. +C_SOURCES := dummy_main.c + +# Generating the dummy source on demand. +dummy_main.c: + @echo 'int main(void){return 0;}' > $@ + +# Assemble .s → .o using the configured compiler. +%.o: %.s + $(CC) -c -x assembler $< -o $@ + +# Default target: build all .o fixtures and the dummy exe. +.PHONY: all +all: $(ASM_OBJS) $(EXE) + +# Keeping things tidy. +clean:: + $(RM) -f $(ASM_OBJS) dummy_main.c + +include Makefile.rules diff --git a/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py new file mode 100644 index 000000000000..f107efbdddde --- /dev/null +++ b/lldb/test/API/functionalities/disassembler-variables/TestVariableAnnotationsDisassembler.py @@ -0,0 +1,118 @@ +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldb +import os +import re + + +# Requires ELF assembler directives (.section … @progbits, .ident, etc.); +# not compatible with COFF/Mach-O toolchains. +@skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"]) +class TestVariableAnnotationsDisassembler(TestBase): + def _build_obj(self, obj_name: str) -> str: + # Let the Makefile build all .o’s (pattern rule). Then grab the one we need. + self.build() + obj = self.getBuildArtifact(obj_name) + self.assertTrue(os.path.exists(obj), f"missing object: {obj}") + return obj + + def _create_target(self, path): + target = self.dbg.CreateTarget(path) + self.assertTrue(target, f"failed to create target for {path}") + return target + + def _disassemble_verbose_symbol(self, symname): + self.runCmd(f"disassemble -n {symname} -v", check=True) + return self.res.GetOutput() + + @skipIf(archs=no_match(["x86_64"])) + def test_d_original_example_O1(self): + obj = self._build_obj("d_original_example.o") + target = self._create_target(obj) + out = self._disassemble_verbose_symbol("main") + print(out) + self.assertIn("argc = ", out) + self.assertIn("argv = ", out) + self.assertIn("i = ", out) + self.assertNotIn("<decoding error>", out) + + @no_debug_info_test + @skipIf(archs=no_match(["x86_64"])) + def test_regs_int_params(self): + obj = self._build_obj("regs_int_params.o") + target = self._create_target(obj) + out = self._disassemble_verbose_symbol("regs_int_params") + print(out) + self.assertRegex(out, r"\ba\s*=\s*(DW_OP_reg5\b|RDI\b)") + self.assertRegex(out, r"\bb\s*=\s*(DW_OP_reg4\b|RSI\b)") + self.assertRegex(out, r"\bc\s*=\s*(DW_OP_reg1\b|RDX\b)") + self.assertRegex(out, r"\bd\s*=\s*(DW_OP_reg2\b|RCX\b)") + self.assertRegex(out, r"\be\s*=\s*(DW_OP_reg8\b|R8\b)") + self.assertRegex(out, r"\bf\s*=\s*(DW_OP_reg9\b|R9\b)") + self.assertNotIn("<decoding error>", out) + + @no_debug_info_test + @skipIf(archs=no_match(["x86_64"])) + def test_regs_fp_params(self): + obj = self._build_obj("regs_fp_params.o") + target = self._create_target(obj) + out = self._disassemble_verbose_symbol("regs_fp_params") + print(out) + self.assertRegex(out, r"\ba\s*=\s*(DW_OP_reg17\b|XMM0\b)") + self.assertRegex(out, r"\bb\s*=\s*(DW_OP_reg18\b|XMM1\b)") + self.assertRegex(out, r"\bc\s*=\s*(DW_OP_reg19\b|XMM2\b)") + self.assertRegex(out, r"\bd\s*=\s*(DW_OP_reg20\b|XMM3\b)") + self.assertRegex(out, r"\be\s*=\s*(DW_OP_reg21\b|XMM4\b)") + self.assertRegex(out, r"\bf\s*=\s*(DW_OP_reg22\b|XMM5\b)") + self.assertNotIn("<decoding error>", out) + + @no_debug_info_test + @skipIf(archs=no_match(["x86_64"])) + def test_regs_mixed_params(self): + obj = self._build_obj("regs_mixed_params.o") + target = self._create_target(obj) + out = self._disassemble_verbose_symbol("regs_mixed_params") + print(out) + self.assertRegex(out, r"\ba\s*=\s*(DW_OP_reg5\b|RDI\b)") + self.assertRegex(out, r"\bb\s*=\s*(DW_OP_reg4\b|RSI\b)") + self.assertRegex(out, r"\bx\s*=\s*(DW_OP_reg17\b|XMM0\b|DW_OP_reg\d+\b)") + self.assertRegex(out, r"\by\s*=\s*(DW_OP_reg18\b|XMM1\b|DW_OP_reg\d+\b)") + self.assertRegex(out, r"\bc\s*=\s*(DW_OP_reg1\b|RDX\b)") + self.assertRegex(out, r"\bz\s*=\s*(DW_OP_reg19\b|XMM2\b|DW_OP_reg\d+\b)") + self.assertNotIn("<decoding error>", out) + + @no_debug_info_test + @skipIf(archs=no_match(["x86_64"])) + def test_live_across_call(self): + obj = self._build_obj("live_across_call.o") + target = self._create_target(obj) + out = self._disassemble_verbose_symbol("live_across_call") + print(out) + self.assertRegex(out, r"\bx\s*=\s*(DW_OP_reg5\b|RDI\b)") + self.assertIn("call", out) + self.assertRegex(out, r"\br\s*=\s*(DW_OP_reg0\b|RAX\b|DW_OP_reg\d+\b)") + self.assertNotIn("<decoding error>", out) + + @no_debug_info_test + @skipIf(archs=no_match(["x86_64"])) + def test_loop_reg_rotate(self): + obj = self._build_obj("loop_reg_rotate.o") + target = self._create_target(obj) + out = self._disassemble_verbose_symbol("loop_reg_rotate") + print(out) + self.assertRegex(out, r"\bn\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)") + self.assertRegex(out, r"\bseed\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)") + self.assertRegex(out, r"\bk\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)") + self.assertRegex(out, r"\bj\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)") + self.assertRegex(out, r"\bi\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)") + self.assertNotIn("<decoding error>", out) + + @no_debug_info_test + @skipIf(archs=no_match(["x86_64"])) + def test_seed_reg_const_undef(self): + obj = self._build_obj("seed_reg_const_undef.o") + target = self._create_target(obj) + out = self._disassemble_verbose_symbol("main") + print(out) + self.assertRegex(out, r"\b(i|argc)\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)") + self.assertNotIn("<decoding error>", out) diff --git a/lldb/test/API/functionalities/disassembler-variables/d_original_example.s b/lldb/test/API/functionalities/disassembler-variables/d_original_example.s new file mode 100644 index 000000000000..c38742cfc683 --- /dev/null +++ b/lldb/test/API/functionalities/disassembler-variables/d_original_example.s @@ -0,0 +1,461 @@ +/* Original C (for context): +* #include <stdio.h> +* +* int main(int argc, char **argv) { +* for (int i = 1; i < argc; ++i) +* puts(argv[i]); +* return 0; +* } +*/ + .file "d_original_example.c" + .text + .globl main # -- Begin function main + .p2align 4 + .type main,@function +main: # @main +.Lfunc_begin0: + .file 0 "." "d_original_example.c" md5 0x25192a1d5a6018cf37d369f9004fab00 + .cfi_startproc +# %bb.0: # %entry + #DEBUG_VALUE: main:argc <- $edi + #DEBUG_VALUE: main:argv <- $rsi + #DEBUG_VALUE: i <- 1 + .loc 0 4 21 prologue_end # d_original_example.c:4:21 + cmpl $2, %edi +.Ltmp0: + .loc 0 4 3 is_stmt 0 # d_original_example.c:4:3 + jl .LBB0_4 +.Ltmp1: +# %bb.1: # %for.body.preheader + #DEBUG_VALUE: main:argc <- $edi + #DEBUG_VALUE: main:argv <- $rsi + #DEBUG_VALUE: i <- 1 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + pushq %r15 + pushq %r14 + pushq %rbx + pushq %rax + .cfi_offset %rbx, -40 + .cfi_offset %r14, -32 + .cfi_offset %r15, -24 + movq %rsi, %rbx +.Ltmp2: + .loc 0 4 21 # d_original_example.c:4:21 + movl %edi, %r14d +.Ltmp3: + #DEBUG_VALUE: main:argc <- $r14d + .loc 0 0 21 # d_original_example.c:0:21 + movl $1, %r15d +.Ltmp4: + .p2align 4 +.LBB0_2: # %for.body + # =>This Inner Loop Header: Depth=1 + #DEBUG_VALUE: main:argc <- $r14d + #DEBUG_VALUE: main:argv <- $rbx + #DEBUG_VALUE: i <- $r15 + .loc 0 5 10 is_stmt 1 # d_original_example.c:5:10 + movq (%rbx,%r15,8), %rdi + .loc 0 5 5 is_stmt 0 # d_original_example.c:5:5 + callq puts@PLT +.Ltmp5: + .loc 0 4 29 is_stmt 1 # d_original_example.c:4:29 + incq %r15 +.Ltmp6: + #DEBUG_VALUE: i <- $r15 + .loc 0 4 21 is_stmt 0 # d_original_example.c:4:21 + cmpq %r15, %r14 +.Ltmp7: + .loc 0 4 3 # d_original_example.c:4:3 + jne .LBB0_2 +.Ltmp8: +# %bb.3: + #DEBUG_VALUE: main:argc <- $r14d + #DEBUG_VALUE: main:argv <- $rbx + #DEBUG_VALUE: i <- $r15 + .loc 0 0 3 # d_original_example.c:0:3 + addq $8, %rsp + popq %rbx +.Ltmp9: + #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi + popq %r14 +.Ltmp10: + #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi + popq %r15 + popq %rbp + .cfi_def_cfa %rsp, 8 + .cfi_restore %rbx + .cfi_restore %r14 + .cfi_restore %r15 + .cfi_restore %rbp +.Ltmp11: +.LBB0_4: # %for.cond.cleanup + #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi + #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi + .loc 0 6 3 is_stmt 1 # d_original_example.c:6:3 + xorl %eax, %eax + retq +.Ltmp12: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + .file 1 "/usr/include" "stdio.h" md5 0xf31eefcc3f15835fc5a4023a625cf609 + # -- End function + .section .debug_loclists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 3 # Offset entry count +.Lloclists_table_base0: + .long .Ldebug_loc0-.Lloclists_table_base0 + .long .Ldebug_loc1-.Lloclists_table_base0 + .long .Ldebug_loc2-.Lloclists_table_base0 +.Ldebug_loc0: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp3-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 85 # super-register DW_OP_reg5 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp3-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp10-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 94 # super-register DW_OP_reg14 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp10-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 85 # super-register DW_OP_reg5 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc1: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 84 # DW_OP_reg4 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp4-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp9-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 83 # DW_OP_reg3 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp9-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 84 # DW_OP_reg4 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc2: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 1 # 1 + .byte 159 # DW_OP_stack_value + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp4-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp8-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 95 # DW_OP_reg15 + .byte 0 # DW_LLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .ascii "\214\001" # DW_AT_loclists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 11 # DW_TAG_lexical_block + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 72 # DW_TAG_call_site + .byte 0 # DW_CHILDREN_no + .byte 127 # DW_AT_call_origin + .byte 19 # DW_FORM_ref4 + .byte 125 # DW_AT_call_return_pc + .byte 27 # DW_FORM_addrx + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 5 # DW_FORM_data2 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 11 # Abbreviation Code + .byte 38 # DW_TAG_const_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x7f DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 29 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lloclists_table_base0 # DW_AT_loclists_base + .byte 2 # Abbrev [2] 0x27:0x38 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + # DW_AT_call_all_calls + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + # DW_AT_prototyped + .long 110 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x36:0x9 DW_TAG_formal_parameter + .byte 0 # DW_AT_location + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long 110 # DW_AT_type + .byte 3 # Abbrev [3] 0x3f:0x9 DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long 128 # DW_AT_type + .byte 4 # Abbrev [4] 0x48:0x10 DW_TAG_lexical_block + .byte 0 # DW_AT_low_pc + .long .Ltmp8-.Lfunc_begin0 # DW_AT_high_pc + .byte 5 # Abbrev [5] 0x4e:0x9 DW_TAG_variable + .byte 2 # DW_AT_location + .byte 9 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 110 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0x58:0x6 DW_TAG_call_site + .long 95 # DW_AT_call_origin + .byte 1 # DW_AT_call_return_pc + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x5f:0xf DW_TAG_subprogram + .byte 3 # DW_AT_name + .byte 1 # DW_AT_decl_file + .short 661 # DW_AT_decl_line + # DW_AT_prototyped + .long 110 # DW_AT_type + # DW_AT_declaration + # DW_AT_external + .byte 8 # Abbrev [8] 0x68:0x5 DW_TAG_formal_parameter + .long 114 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 9 # Abbrev [9] 0x6e:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 10 # Abbrev [10] 0x72:0x5 DW_TAG_pointer_type + .long 119 # DW_AT_type + .byte 11 # Abbrev [11] 0x77:0x5 DW_TAG_const_type + .long 124 # DW_AT_type + .byte 9 # Abbrev [9] 0x7c:0x4 DW_TAG_base_type + .byte 5 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 10 # Abbrev [10] 0x80:0x5 DW_TAG_pointer_type + .long 133 # DW_AT_type + .byte 10 # Abbrev [10] 0x85:0x5 DW_TAG_pointer_type + .long 124 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 44 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0 +.Linfo_string1: + .asciz "d_original_example.c" # string offset=119 +.Linfo_string2: + .asciz "." # string offset=140 +.Linfo_string3: + .asciz "puts" # string offset=142 +.Linfo_string4: + .asciz "int" # string offset=147 +.Linfo_string5: + .asciz "char" # string offset=151 +.Linfo_string6: + .asciz "main" # string offset=156 +.Linfo_string7: + .asciz "argc" # string offset=161 +.Linfo_string8: + .asciz "argv" # string offset=166 +.Linfo_string9: + .asciz "i" # string offset=171 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Ltmp5 +.Ldebug_addr_end0: + .ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/test/API/functionalities/disassembler-variables/live_across_call.s b/lldb/test/API/functionalities/disassembler-variables/live_across_call.s new file mode 100644 index 000000000000..cd9f08afe6fd --- /dev/null +++ b/lldb/test/API/functionalities/disassembler-variables/live_across_call.s @@ -0,0 +1,371 @@ +/* Original C (for context): +* // Declare a real external call so the compiler must respect ABI clobbers. +* extern int leaf(int) __attribute__((noinline)); +* +* __attribute__((noinline)) +* int live_across_call(int x) { +* volatile int a = x; // a starts in a GPR (from arg) +* asm volatile("" :: "r"(a)); // keep 'a' live in a register +* int r = leaf(a); // 'a' is live across the call +* asm volatile("" :: "r"(a), "r"(r));// still live afterwards +* return a + r; +* } +*/ + .file "live_across_call.c" + .text + .globl live_across_call # -- Begin function live_across_call + .p2align 4 + .type live_across_call,@function +live_across_call: # @live_across_call +.Lfunc_begin0: + .file 0 "." "live_across_call.c" md5 0x351c37295026edf0d468774d35f47e5e + .loc 0 5 0 # live_across_call.c:5:0 + .cfi_startproc +# %bb.0: # %entry + #DEBUG_VALUE: live_across_call:x <- $edi + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $16, %rsp +.Ltmp0: + .loc 0 6 16 prologue_end # live_across_call.c:6:16 + movl %edi, -4(%rbp) + .loc 0 7 26 # live_across_call.c:7:26 + movl -4(%rbp), %eax + .loc 0 7 3 is_stmt 0 # live_across_call.c:7:3 + #APP + #NO_APP + .loc 0 8 16 is_stmt 1 # live_across_call.c:8:16 + movl -4(%rbp), %edi +.Ltmp1: + #DEBUG_VALUE: live_across_call:x <- [DW_OP_LLVM_entry_value 1] $edi + .loc 0 8 11 is_stmt 0 # live_across_call.c:8:11 + callq leaf@PLT +.Ltmp2: + #DEBUG_VALUE: live_across_call:r <- $eax + .loc 0 9 26 is_stmt 1 # live_across_call.c:9:26 + movl -4(%rbp), %ecx + .loc 0 9 3 is_stmt 0 # live_across_call.c:9:3 + #APP + #NO_APP + .loc 0 10 12 is_stmt 1 # live_across_call.c:10:12 + addl -4(%rbp), %eax +.Ltmp3: + .loc 0 10 3 epilogue_begin is_stmt 0 # live_across_call.c:10:3 + addq $16, %rsp + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp4: +.Lfunc_end0: + .size live_across_call, .Lfunc_end0-live_across_call + .cfi_endproc + # -- End function + .section .debug_loclists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 2 # Offset entry count +.Lloclists_table_base0: + .long .Ldebug_loc0-.Lloclists_table_base0 + .long .Ldebug_loc1-.Lloclists_table_base0 +.Ldebug_loc0: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 85 # super-register DW_OP_reg5 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 85 # super-register DW_OP_reg5 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc1: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp2-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp3-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 80 # super-register DW_OP_reg0 + .byte 0 # DW_LLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .ascii "\214\001" # DW_AT_loclists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 72 # DW_TAG_call_site + .byte 0 # DW_CHILDREN_no + .byte 127 # DW_AT_call_origin + .byte 19 # DW_FORM_ref4 + .byte 125 # DW_AT_call_return_pc + .byte 27 # DW_FORM_addrx + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 53 # DW_TAG_volatile_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x66 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 29 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lloclists_table_base0 # DW_AT_loclists_base + .byte 2 # Abbrev [2] 0x27:0x33 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + # DW_AT_call_all_calls + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + # DW_AT_prototyped + .long 104 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x36:0x9 DW_TAG_formal_parameter + .byte 0 # DW_AT_location + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .long 104 # DW_AT_type + .byte 4 # Abbrev [4] 0x3f:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + .long 108 # DW_AT_type + .byte 5 # Abbrev [5] 0x4a:0x9 DW_TAG_variable + .byte 1 # DW_AT_location + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 104 # DW_AT_type + .byte 6 # Abbrev [6] 0x53:0x6 DW_TAG_call_site + .long 90 # DW_AT_call_origin + .byte 1 # DW_AT_call_return_pc + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x5a:0xe DW_TAG_subprogram + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_prototyped + .long 104 # DW_AT_type + # DW_AT_declaration + # DW_AT_external + .byte 8 # Abbrev [8] 0x62:0x5 DW_TAG_formal_parameter + .long 104 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 9 # Abbrev [9] 0x68:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 10 # Abbrev [10] 0x6c:0x5 DW_TAG_volatile_type + .long 104 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 40 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0 +.Linfo_string1: + .asciz "live_across_call.c" # string offset=119 +.Linfo_string2: + .asciz "." # string offset=138 +.Linfo_string3: + .asciz "leaf" # string offset=140 +.Linfo_string4: + .asciz "int" # string offset=145 +.Linfo_string5: + .asciz "live_across_call" # string offset=149 +.Linfo_string6: + .asciz "a" # string offset=166 +.Linfo_string7: + .asciz "x" # string offset=168 +.Linfo_string8: + .asciz "r" # string offset=170 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Ltmp2 +.Ldebug_addr_end0: + .ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/test/API/functionalities/disassembler-variables/loop_reg_rotate.s b/lldb/test/API/functionalities/disassembler-variables/loop_reg_rotate.s new file mode 100644 index 000000000000..c01e2b28fd2b --- /dev/null +++ b/lldb/test/API/functionalities/disassembler-variables/loop_reg_rotate.s @@ -0,0 +1,557 @@ +/* Original C (for context): +* __attribute__((noinline)) +* int loop_reg_rotate(int n, int seed) { +* volatile int acc = seed; // keep as a named local +* int i = 0, j = 1, k = 2; // extra pressure but not enough to spill +* +* for (int t = 0; t < n; ++t) { +* // Mix uses so the allocator may reshuffle regs for 'acc' +* acc = acc + i; +* asm volatile("" :: "r"(acc)); // pin 'acc' live here +* acc = acc ^ j; +* asm volatile("" :: "r"(acc)); // and here +* acc = acc + k; +* i ^= acc; j += acc; k ^= j; +* } +* +* asm volatile("" :: "r"(acc)); +* return acc + i + j + k; +* } +*/ + .file "loop_reg_rotate.c" + .text + .globl loop_reg_rotate # -- Begin function loop_reg_rotate + .p2align 4 + .type loop_reg_rotate,@function +loop_reg_rotate: # @loop_reg_rotate +.Lfunc_begin0: + .file 0 "." "loop_reg_rotate.c" md5 0x388f52de76e9442230e689fb9be1b4ef + .loc 0 2 0 # loop_reg_rotate.c:2:0 + .cfi_startproc +# %bb.0: # %entry + #DEBUG_VALUE: loop_reg_rotate:n <- $edi + #DEBUG_VALUE: loop_reg_rotate:seed <- $esi + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + .loc 0 3 16 prologue_end # loop_reg_rotate.c:3:16 + movl %esi, -4(%rbp) +.Ltmp1: + #DEBUG_VALUE: loop_reg_rotate:i <- 0 + #DEBUG_VALUE: loop_reg_rotate:j <- 1 + #DEBUG_VALUE: loop_reg_rotate:k <- 2 + #DEBUG_VALUE: t <- 0 + .loc 0 6 21 # loop_reg_rotate.c:6:21 + testl %edi, %edi +.Ltmp2: + .loc 0 6 3 is_stmt 0 # loop_reg_rotate.c:6:3 + jle .LBB0_1 +.Ltmp3: +# %bb.3: # %for.body.preheader + #DEBUG_VALUE: loop_reg_rotate:n <- $edi + #DEBUG_VALUE: loop_reg_rotate:seed <- $esi + #DEBUG_VALUE: loop_reg_rotate:i <- 0 + #DEBUG_VALUE: loop_reg_rotate:j <- 1 + #DEBUG_VALUE: loop_reg_rotate:k <- 2 + #DEBUG_VALUE: t <- 0 + .loc 0 0 3 # loop_reg_rotate.c:0:3 + xorl %eax, %eax + movl $1, %edx + movl $2, %ecx +.Ltmp4: + .p2align 4 +.LBB0_4: # %for.body + # =>This Inner Loop Header: Depth=1 + #DEBUG_VALUE: loop_reg_rotate:n <- [DW_OP_LLVM_entry_value 1] $edi + #DEBUG_VALUE: loop_reg_rotate:seed <- [DW_OP_LLVM_entry_value 1] $esi + #DEBUG_VALUE: t <- [DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_minus, DW_OP_consts 18446744073709551615, DW_OP_div, DW_OP_stack_value] undef, undef + #DEBUG_VALUE: loop_reg_rotate:k <- $ecx + #DEBUG_VALUE: loop_reg_rotate:j <- $edx + #DEBUG_VALUE: loop_reg_rotate:i <- $eax + .loc 0 8 9 is_stmt 1 # loop_reg_rotate.c:8:9 + addl %eax, -4(%rbp) + .loc 0 9 28 # loop_reg_rotate.c:9:28 + movl -4(%rbp), %esi + .loc 0 9 5 is_stmt 0 # loop_reg_rotate.c:9:5 + #APP + #NO_APP + .loc 0 10 9 is_stmt 1 # loop_reg_rotate.c:10:9 + xorl %edx, -4(%rbp) + .loc 0 11 28 # loop_reg_rotate.c:11:28 + movl -4(%rbp), %esi + .loc 0 11 5 is_stmt 0 # loop_reg_rotate.c:11:5 + #APP + #NO_APP + .loc 0 12 9 is_stmt 1 # loop_reg_rotate.c:12:9 + addl %ecx, -4(%rbp) + .loc 0 13 7 # loop_reg_rotate.c:13:7 + xorl -4(%rbp), %eax +.Ltmp5: + #DEBUG_VALUE: loop_reg_rotate:i <- $eax + .loc 0 13 17 is_stmt 0 # loop_reg_rotate.c:13:17 + addl -4(%rbp), %edx +.Ltmp6: + #DEBUG_VALUE: loop_reg_rotate:j <- $edx + .loc 0 13 27 # loop_reg_rotate.c:13:27 + xorl %edx, %ecx +.Ltmp7: + #DEBUG_VALUE: loop_reg_rotate:k <- $ecx + #DEBUG_VALUE: t <- [DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_minus, DW_OP_consts 18446744073709551615, DW_OP_div, DW_OP_consts 1, DW_OP_plus, DW_OP_stack_value] undef, undef + .loc 0 6 21 is_stmt 1 # loop_reg_rotate.c:6:21 + decl %edi +.Ltmp8: + .loc 0 6 3 is_stmt 0 # loop_reg_rotate.c:6:3 + jne .LBB0_4 + jmp .LBB0_2 +.Ltmp9: +.LBB0_1: + #DEBUG_VALUE: loop_reg_rotate:n <- $edi + #DEBUG_VALUE: loop_reg_rotate:seed <- $esi + #DEBUG_VALUE: loop_reg_rotate:i <- 0 + #DEBUG_VALUE: loop_reg_rotate:j <- 1 + #DEBUG_VALUE: loop_reg_rotate:k <- 2 + #DEBUG_VALUE: t <- 0 + .loc 0 0 3 # loop_reg_rotate.c:0:3 + movl $2, %ecx + movl $1, %edx + xorl %eax, %eax +.Ltmp10: +.LBB0_2: # %for.cond.cleanup + #DEBUG_VALUE: loop_reg_rotate:n <- [DW_OP_LLVM_entry_value 1] $edi + #DEBUG_VALUE: loop_reg_rotate:seed <- [DW_OP_LLVM_entry_value 1] $esi + .loc 0 16 26 is_stmt 1 # loop_reg_rotate.c:16:26 + movl -4(%rbp), %esi + .loc 0 16 3 is_stmt 0 # loop_reg_rotate.c:16:3 + #APP + #NO_APP + .loc 0 17 14 is_stmt 1 # loop_reg_rotate.c:17:14 + addl %edx, %eax + .loc 0 17 18 is_stmt 0 # loop_reg_rotate.c:17:18 + addl %ecx, %eax + .loc 0 17 22 # loop_reg_rotate.c:17:22 + addl -4(%rbp), %eax + .loc 0 17 3 epilogue_begin # loop_reg_rotate.c:17:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp11: +.Lfunc_end0: + .size loop_reg_rotate, .Lfunc_end0-loop_reg_rotate + .cfi_endproc + # -- End function + .section .debug_loclists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 6 # Offset entry count +.Lloclists_table_base0: + .long .Ldebug_loc0-.Lloclists_table_base0 + .long .Ldebug_loc1-.Lloclists_table_base0 + .long .Ldebug_loc2-.Lloclists_table_base0 + .long .Ldebug_loc3-.Lloclists_table_base0 + .long .Ldebug_loc4-.Lloclists_table_base0 + .long .Ldebug_loc5-.Lloclists_table_base0 +.Ldebug_loc0: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 85 # super-register DW_OP_reg5 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp4-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp9-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 85 # super-register DW_OP_reg5 + .byte 159 # DW_OP_stack_value + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp9-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp10-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 85 # super-register DW_OP_reg5 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp10-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 85 # super-register DW_OP_reg5 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc1: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 84 # super-register DW_OP_reg4 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp4-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp9-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 84 # super-register DW_OP_reg4 + .byte 159 # DW_OP_stack_value + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp9-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp10-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 84 # super-register DW_OP_reg4 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp10-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 84 # super-register DW_OP_reg4 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc2: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 0 # 0 + .byte 159 # DW_OP_stack_value + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp4-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp9-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 80 # super-register DW_OP_reg0 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp9-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp10-.Lfunc_begin0 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 0 # 0 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc3: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 1 # 1 + .byte 159 # DW_OP_stack_value + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp4-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp9-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 81 # super-register DW_OP_reg1 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp9-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp10-.Lfunc_begin0 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 1 # 1 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc4: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 2 # 2 + .byte 159 # DW_OP_stack_value + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp4-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp9-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 82 # super-register DW_OP_reg2 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp9-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp10-.Lfunc_begin0 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 2 # 2 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc5: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 0 # 0 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .ascii "\214\001" # DW_AT_loclists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 11 # DW_TAG_lexical_block + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 53 # DW_TAG_volatile_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x7d DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 29 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lloclists_table_base0 # DW_AT_loclists_base + .byte 2 # Abbrev [2] 0x27:0x58 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + # DW_AT_call_all_calls + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_prototyped + .long 127 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x36:0x9 DW_TAG_formal_parameter + .byte 0 # DW_AT_location + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 127 # DW_AT_type + .byte 3 # Abbrev [3] 0x3f:0x9 DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 127 # DW_AT_type + .byte 4 # Abbrev [4] 0x48:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long 131 # DW_AT_type + .byte 5 # Abbrev [5] 0x53:0x9 DW_TAG_variable + .byte 2 # DW_AT_location + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 127 # DW_AT_type + .byte 5 # Abbrev [5] 0x5c:0x9 DW_TAG_variable + .byte 3 # DW_AT_location + .byte 9 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 127 # DW_AT_type + .byte 5 # Abbrev [5] 0x65:0x9 DW_TAG_variable + .byte 4 # DW_AT_location + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 127 # DW_AT_type + .byte 6 # Abbrev [6] 0x6e:0x10 DW_TAG_lexical_block + .byte 1 # DW_AT_low_pc + .long .Ltmp9-.Ltmp1 # DW_AT_high_pc + .byte 5 # Abbrev [5] 0x74:0x9 DW_TAG_variable + .byte 5 # DW_AT_location + .byte 11 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + .long 127 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x7f:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 8 # Abbrev [8] 0x83:0x5 DW_TAG_volatile_type + .long 127 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 52 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0 +.Linfo_string1: + .asciz "loop_reg_rotate.c" # string offset=119 +.Linfo_string2: + .asciz "." # string offset=137 +.Linfo_string3: + .asciz "loop_reg_rotate" # string offset=139 +.Linfo_string4: + .asciz "int" # string offset=155 +.Linfo_string5: + .asciz "acc" # string offset=159 +.Linfo_string6: + .asciz "n" # string offset=163 +.Linfo_string7: + .asciz "seed" # string offset=165 +.Linfo_string8: + .asciz "i" # string offset=170 +.Linfo_string9: + .asciz "j" # string offset=172 +.Linfo_string10: + .asciz "k" # string offset=174 +.Linfo_string11: + .asciz "t" # string offset=176 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .long .Linfo_string11 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Ltmp1 +.Ldebug_addr_end0: + .ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/test/API/functionalities/disassembler-variables/regs_fp_params.s b/lldb/test/API/functionalities/disassembler-variables/regs_fp_params.s new file mode 100644 index 000000000000..502ab151e0c5 --- /dev/null +++ b/lldb/test/API/functionalities/disassembler-variables/regs_fp_params.s @@ -0,0 +1,304 @@ +/* Original C (for context): +* __attribute__((noinline)) +* double regs_fp_params(double a, double b, double c, double d, double e, double f) { +* asm volatile("" :: "x"(a), "x"(b), "x"(c), "x"(d), "x"(e), "x"(f)); +* return a + b + c + d + e + f; +* }*/ + .file "regs_fp_params.c" + .text + .globl regs_fp_params # -- Begin function regs_fp_params + .p2align 4 + .type regs_fp_params,@function +regs_fp_params: # @regs_fp_params +.Lfunc_begin0: + .file 0 "." "regs_fp_params.c" md5 0xdd883927454b0ea1cdce7b3c16c6a643 + .loc 0 2 0 # regs_fp_params.c:2:0 + .cfi_startproc +# %bb.0: # %entry + #DEBUG_VALUE: regs_fp_params:a <- $xmm0 + #DEBUG_VALUE: regs_fp_params:b <- $xmm1 + #DEBUG_VALUE: regs_fp_params:c <- $xmm2 + #DEBUG_VALUE: regs_fp_params:d <- $xmm3 + #DEBUG_VALUE: regs_fp_params:e <- $xmm4 + #DEBUG_VALUE: regs_fp_params:f <- $xmm5 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + .loc 0 3 3 prologue_end # regs_fp_params.c:3:3 + #APP + #NO_APP + .loc 0 4 12 # regs_fp_params.c:4:12 + addsd %xmm1, %xmm0 +.Ltmp1: + #DEBUG_VALUE: regs_fp_params:a <- [DW_OP_LLVM_entry_value 1] $xmm0 + .loc 0 4 16 is_stmt 0 # regs_fp_params.c:4:16 + addsd %xmm2, %xmm0 + .loc 0 4 20 # regs_fp_params.c:4:20 + addsd %xmm3, %xmm0 + .loc 0 4 24 # regs_fp_params.c:4:24 + addsd %xmm4, %xmm0 + .loc 0 4 28 # regs_fp_params.c:4:28 + addsd %xmm5, %xmm0 + .loc 0 4 3 epilogue_begin # regs_fp_params.c:4:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp2: +.Lfunc_end0: + .size regs_fp_params, .Lfunc_end0-regs_fp_params + .cfi_endproc + # -- End function + .section .debug_loclists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 1 # Offset entry count +.Lloclists_table_base0: + .long .Ldebug_loc0-.Lloclists_table_base0 +.Ldebug_loc0: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 97 # DW_OP_reg17 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 97 # DW_OP_reg17 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .ascii "\214\001" # DW_AT_loclists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x6b DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 29 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lloclists_table_base0 # DW_AT_loclists_base + .byte 2 # Abbrev [2] 0x27:0x4b DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + # DW_AT_call_all_calls + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_prototyped + .long 114 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x36:0x9 DW_TAG_formal_parameter + .byte 0 # DW_AT_location + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 4 # Abbrev [4] 0x3f:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 98 + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 4 # Abbrev [4] 0x49:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 99 + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 4 # Abbrev [4] 0x53:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 100 + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 4 # Abbrev [4] 0x5d:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 101 + .byte 9 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 4 # Abbrev [4] 0x67:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 102 + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0x72:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 4 # DW_AT_encoding + .byte 8 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 48 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0 +.Linfo_string1: + .asciz "regs_fp_params.c" # string offset=119 +.Linfo_string2: + .asciz "." # string offset=136 +.Linfo_string3: + .asciz "regs_fp_params" # string offset=138 +.Linfo_string4: + .asciz "double" # string offset=153 +.Linfo_string5: + .asciz "a" # string offset=160 +.Linfo_string6: + .asciz "b" # string offset=162 +.Linfo_string7: + .asciz "c" # string offset=164 +.Linfo_string8: + .asciz "d" # string offset=166 +.Linfo_string9: + .asciz "e" # string offset=168 +.Linfo_string10: + .asciz "f" # string offset=170 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/test/API/functionalities/disassembler-variables/regs_int_params.s b/lldb/test/API/functionalities/disassembler-variables/regs_int_params.s new file mode 100644 index 000000000000..0b2a60e2b4d5 --- /dev/null +++ b/lldb/test/API/functionalities/disassembler-variables/regs_int_params.s @@ -0,0 +1,312 @@ +/* Original C (for context): +* __attribute__((noinline)) +* int regs_int_params(int a, int b, int c, int d, int e, int f) { +* // Keep all params in regs; avoid spilling to the stack. +* // The compiler will usually keep a..f in the 6 integer-arg regs. +* asm volatile("" :: "r"(a), "r"(b), "r"(c), "r"(d), "r"(e), "r"(f)); +* return a + b + c + d + e + f; +* } +*/ + .file "regs_int_params.c" + .text + .globl regs_int_params # -- Begin function regs_int_params + .p2align 4 + .type regs_int_params,@function +regs_int_params: # @regs_int_params +.Lfunc_begin0: + .file 0 "." "regs_int_params.c" md5 0xcf39432098ab893043cc8b4606354bd2 + .loc 0 2 0 # regs_int_params.c:2:0 + .cfi_startproc +# %bb.0: # %entry + #DEBUG_VALUE: regs_int_params:a <- $edi + #DEBUG_VALUE: regs_int_params:b <- $esi + #DEBUG_VALUE: regs_int_params:c <- $edx + #DEBUG_VALUE: regs_int_params:d <- $ecx + #DEBUG_VALUE: regs_int_params:e <- $r8d + #DEBUG_VALUE: regs_int_params:f <- $r9d + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + # kill: def $r9d killed $r9d def $r9 + # kill: def $r8d killed $r8d def $r8 + # kill: def $ecx killed $ecx def $rcx + # kill: def $edx killed $edx def $rdx + # kill: def $esi killed $esi def $rsi + # kill: def $edi killed $edi def $rdi +.Ltmp0: + .loc 0 5 3 prologue_end # regs_int_params.c:5:3 + #APP + #NO_APP + .loc 0 6 12 # regs_int_params.c:6:12 + addl %edi, %esi +.Ltmp1: + #DEBUG_VALUE: regs_int_params:b <- [DW_OP_LLVM_entry_value 1] $esi + .loc 0 6 16 is_stmt 0 # regs_int_params.c:6:16 + leal (%rdx,%rcx), %eax + .loc 0 6 20 # regs_int_params.c:6:20 + addl %esi, %eax + .loc 0 6 28 # regs_int_params.c:6:28 + addl %r8d, %eax + addl %r9d, %eax + .loc 0 6 3 epilogue_begin # regs_int_params.c:6:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp2: +.Lfunc_end0: + .size regs_int_params, .Lfunc_end0-regs_int_params + .cfi_endproc + # -- End function + .section .debug_loclists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 1 # Offset entry count +.Lloclists_table_base0: + .long .Ldebug_loc0-.Lloclists_table_base0 +.Ldebug_loc0: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 84 # super-register DW_OP_reg4 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 84 # super-register DW_OP_reg4 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .ascii "\214\001" # DW_AT_loclists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x6b DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 29 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lloclists_table_base0 # DW_AT_loclists_base + .byte 2 # Abbrev [2] 0x27:0x4b DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + # DW_AT_call_all_calls + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_prototyped + .long 114 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x36:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 85 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 4 # Abbrev [4] 0x40:0x9 DW_TAG_formal_parameter + .byte 0 # DW_AT_location + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 3 # Abbrev [3] 0x49:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 81 + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 3 # Abbrev [3] 0x53:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 82 + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 3 # Abbrev [3] 0x5d:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 88 + .byte 9 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 3 # Abbrev [3] 0x67:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 89 + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 114 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0x72:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 48 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0 +.Linfo_string1: + .asciz "regs_int_params.c" # string offset=119 +.Linfo_string2: + .asciz "." # string offset=137 +.Linfo_string3: + .asciz "regs_int_params" # string offset=139 +.Linfo_string4: + .asciz "int" # string offset=155 +.Linfo_string5: + .asciz "a" # string offset=159 +.Linfo_string6: + .asciz "b" # string offset=161 +.Linfo_string7: + .asciz "c" # string offset=163 +.Linfo_string8: + .asciz "d" # string offset=165 +.Linfo_string9: + .asciz "e" # string offset=167 +.Linfo_string10: + .asciz "f" # string offset=169 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/test/API/functionalities/disassembler-variables/regs_mixed_params.s b/lldb/test/API/functionalities/disassembler-variables/regs_mixed_params.s new file mode 100644 index 000000000000..691180b42f24 --- /dev/null +++ b/lldb/test/API/functionalities/disassembler-variables/regs_mixed_params.s @@ -0,0 +1,375 @@ +/* Original C (for context): +* __attribute__((noinline)) +* double regs_mixed_params(int a, int b, double x, double y, int c, double z) { +* // Keep everything live; avoid spills. +* asm volatile("" :: "r"(a), "r"(b), "x"(x), "x"(y), "r"(c), "x"(z)); +* // Some mixing so values stay in regs long enough to annotate. +* double r = (double)(a + b + c) + x + y + z; +* asm volatile("" :: "x"(r), "r"(a), "x"(x)); +* return r; +* } +*/ + .file "regs_mixed_params.c" + .file 0 "." "regs_mixed_params.c" md5 0x73c4bda40238ae460aaecb3a6a2603cf + .text + .globl regs_mixed_params # -- Begin function regs_mixed_params + .p2align 4 + .type regs_mixed_params,@function +regs_mixed_params: # @regs_mixed_params +.Lfunc_begin0: + .loc 0 2 0 # regs_mixed_params.c:2:0 + .cfi_startproc +# %bb.0: # %entry + #DEBUG_VALUE: regs_mixed_params:a <- $edi + #DEBUG_VALUE: regs_mixed_params:b <- $esi + #DEBUG_VALUE: regs_mixed_params:x <- $xmm0 + #DEBUG_VALUE: regs_mixed_params:y <- $xmm1 + #DEBUG_VALUE: regs_mixed_params:c <- $edx + #DEBUG_VALUE: regs_mixed_params:z <- $xmm2 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + .loc 0 4 3 prologue_end # regs_mixed_params.c:4:3 + #APP + #NO_APP + .loc 0 6 25 # regs_mixed_params.c:6:25 + addl %edi, %esi +.Ltmp1: + #DEBUG_VALUE: regs_mixed_params:b <- [DW_OP_LLVM_entry_value 1] $esi + .loc 0 6 29 is_stmt 0 # regs_mixed_params.c:6:29 + addl %edx, %esi + .loc 0 6 14 # regs_mixed_params.c:6:14 + cvtsi2sd %esi, %xmm4 + .loc 0 6 34 # regs_mixed_params.c:6:34 + movapd %xmm0, %xmm3 + addsd %xmm4, %xmm3 + .loc 0 6 38 # regs_mixed_params.c:6:38 + addsd %xmm1, %xmm3 + .loc 0 6 42 # regs_mixed_params.c:6:42 + addsd %xmm2, %xmm3 +.Ltmp2: + #DEBUG_VALUE: regs_mixed_params:r <- $xmm3 + .loc 0 7 3 is_stmt 1 # regs_mixed_params.c:7:3 + #APP + #NO_APP + .loc 0 8 3 # regs_mixed_params.c:8:3 + movapd %xmm3, %xmm0 +.Ltmp3: + #DEBUG_VALUE: regs_mixed_params:x <- [DW_OP_LLVM_entry_value 1] $xmm0 + .loc 0 8 3 epilogue_begin is_stmt 0 # regs_mixed_params.c:8:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp4: +.Lfunc_end0: + .size regs_mixed_params, .Lfunc_end0-regs_mixed_params + .cfi_endproc + # -- End function + .section .debug_loclists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 3 # Offset entry count +.Lloclists_table_base0: + .long .Ldebug_loc0-.Lloclists_table_base0 + .long .Ldebug_loc1-.Lloclists_table_base0 + .long .Ldebug_loc2-.Lloclists_table_base0 +.Ldebug_loc0: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 84 # super-register DW_OP_reg4 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 84 # super-register DW_OP_reg4 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc1: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp3-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 97 # DW_OP_reg17 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp3-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # Loc expr size + .byte 163 # DW_OP_entry_value + .byte 1 # 1 + .byte 97 # DW_OP_reg17 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loc2: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp2-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 100 # DW_OP_reg20 + .byte 0 # DW_LLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .ascii "\214\001" # DW_AT_loclists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x77 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 29 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lloclists_table_base0 # DW_AT_loclists_base + .byte 2 # Abbrev [2] 0x27:0x4 DW_TAG_base_type + .byte 3 # DW_AT_name + .byte 4 # DW_AT_encoding + .byte 8 # DW_AT_byte_size + .byte 3 # Abbrev [3] 0x2b:0x53 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + # DW_AT_call_all_calls + .byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_prototyped + .long 39 # DW_AT_type + # DW_AT_external + .byte 4 # Abbrev [4] 0x3a:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 85 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 126 # DW_AT_type + .byte 5 # Abbrev [5] 0x44:0x9 DW_TAG_formal_parameter + .byte 0 # DW_AT_location + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 126 # DW_AT_type + .byte 5 # Abbrev [5] 0x4d:0x9 DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 39 # DW_AT_type + .byte 4 # Abbrev [4] 0x56:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 98 + .byte 9 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 39 # DW_AT_type + .byte 4 # Abbrev [4] 0x60:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 81 + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 126 # DW_AT_type + .byte 4 # Abbrev [4] 0x6a:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 99 + .byte 11 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 39 # DW_AT_type + .byte 6 # Abbrev [6] 0x74:0x9 DW_TAG_variable + .byte 2 # DW_AT_location + .byte 12 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + .long 39 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 2 # Abbrev [2] 0x7e:0x4 DW_TAG_base_type + .byte 6 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 56 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0 +.Linfo_string1: + .asciz "regs_mixed_params.c" # string offset=119 +.Linfo_string2: + .asciz "." # string offset=139 +.Linfo_string3: + .asciz "double" # string offset=141 +.Linfo_string4: + .asciz "regs_mixed_params" # string offset=148 +.Linfo_string5: + .asciz "a" # string offset=166 +.Linfo_string6: + .asciz "int" # string offset=168 +.Linfo_string7: + .asciz "b" # string offset=172 +.Linfo_string8: + .asciz "x" # string offset=174 +.Linfo_string9: + .asciz "y" # string offset=176 +.Linfo_string10: + .asciz "c" # string offset=178 +.Linfo_string11: + .asciz "z" # string offset=180 +.Linfo_string12: + .asciz "r" # string offset=182 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .long .Linfo_string11 + .long .Linfo_string12 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/test/API/functionalities/disassembler-variables/seed_reg_const_undef.s b/lldb/test/API/functionalities/disassembler-variables/seed_reg_const_undef.s new file mode 100644 index 000000000000..f85b8a712cbb --- /dev/null +++ b/lldb/test/API/functionalities/disassembler-variables/seed_reg_const_undef.s @@ -0,0 +1,289 @@ +/* Original C (for context): +* __attribute__((noinline)) +* int main(int argc, char **argv) { +* int i = argc; // i in a reg (DW_OP_regN) +* asm volatile("" :: "r"(i)); // keep i live here +* i = 0; // i becomes const 0 (DW_OP_constu 0, stack_value) +* asm volatile("" :: "r"(i)); // keep the const range materialized +* return 0; // i ends -> <undef> after its range +* } +*/ + + .file "seed_reg_const_undef.c" + .text + .globl main # -- Begin function main + .p2align 4 + .type main,@function +main: # @main +.Lfunc_begin0: + .file 0 "." "seed_reg_const_undef.c" md5 0x5e8dbf089d1bd72d395da802210b3138 + .loc 0 3 0 # seed_reg_const_undef.c:3:0 + .cfi_startproc +# %bb.0: # %entry + #DEBUG_VALUE: main:argc <- $edi + #DEBUG_VALUE: main:argv <- $rsi + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp +.Ltmp0: + #DEBUG_VALUE: main:i <- $edi + .loc 0 5 3 prologue_end # seed_reg_const_undef.c:5:3 + #APP + #NO_APP +.Ltmp1: + #DEBUG_VALUE: main:i <- 0 + .loc 0 7 3 # seed_reg_const_undef.c:7:3 + xorl %eax, %eax + #APP + #NO_APP + .loc 0 8 3 # seed_reg_const_undef.c:8:3 + xorl %eax, %eax + .loc 0 8 3 epilogue_begin is_stmt 0 # seed_reg_const_undef.c:8:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp2: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_loclists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 1 # Offset entry count +.Lloclists_table_base0: + .long .Ldebug_loc0-.Lloclists_table_base0 +.Ldebug_loc0: + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp0-.Lfunc_begin0 # starting offset + .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset + .byte 1 # Loc expr size + .byte 85 # super-register DW_OP_reg5 + .byte 4 # DW_LLE_offset_pair + .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 0 # 0 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .ascii "\214\001" # DW_AT_loclists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 34 # DW_FORM_loclistx + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x5b DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 29 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lloclists_table_base0 # DW_AT_loclists_base + .byte 2 # Abbrev [2] 0x27:0x2d DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + # DW_AT_call_all_calls + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + # DW_AT_prototyped + .long 84 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x36:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 85 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long 84 # DW_AT_type + .byte 3 # Abbrev [3] 0x40:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 84 + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .long 88 # DW_AT_type + .byte 4 # Abbrev [4] 0x4a:0x9 DW_TAG_variable + .byte 0 # DW_AT_location + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 84 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0x54:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 6 # Abbrev [6] 0x58:0x5 DW_TAG_pointer_type + .long 93 # DW_AT_type + .byte 6 # Abbrev [6] 0x5d:0x5 DW_TAG_pointer_type + .long 98 # DW_AT_type + .byte 5 # Abbrev [5] 0x62:0x4 DW_TAG_base_type + .byte 7 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 40 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0 +.Linfo_string1: + .asciz "seed_reg_const_undef.c" # string offset=119 +.Linfo_string2: + .asciz "." # string offset=142 +.Linfo_string3: + .asciz "main" # string offset=144 +.Linfo_string4: + .asciz "int" # string offset=149 +.Linfo_string5: + .asciz "argc" # string offset=153 +.Linfo_string6: + .asciz "argv" # string offset=158 +.Linfo_string7: + .asciz "char" # string offset=163 +.Linfo_string8: + .asciz "i" # string offset=168 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestqOffsets.py b/lldb/test/API/functionalities/gdb_remote_client/TestqOffsets.py index a1adc20e864b..629361c6ae5b 100644 --- a/lldb/test/API/functionalities/gdb_remote_client/TestqOffsets.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestqOffsets.py @@ -12,6 +12,8 @@ class TestqOffsets(GDBRemoteTestBase): def test(self): self.server.responder = TestqOffsets.Responder() + # This ensures that we do not pick up any binaries on the host. + self.runCmd("platform select remote-linux") target = self.createTarget("qOffsets.yaml") text = target.modules[0].FindSection(".text") self.assertEqual(text.GetLoadAddress(target), lldb.LLDB_INVALID_ADDRESS) diff --git a/lldb/test/API/functionalities/inferior-crashing/TestInferiorCrashingStep.py b/lldb/test/API/functionalities/inferior-crashing/TestInferiorCrashingStep.py index 774c61ad24d4..15bef0153ed0 100644 --- a/lldb/test/API/functionalities/inferior-crashing/TestInferiorCrashingStep.py +++ b/lldb/test/API/functionalities/inferior-crashing/TestInferiorCrashingStep.py @@ -201,7 +201,7 @@ class CrashingInferiorStepTestCase(TestBase): self.expect("next", substrs=["Process", expected_state]) if expected_state == "exited": - self.expect("thread list", error=True, substrs=["Process must be launched"]) + self.expect("thread list", error=True, substrs=["process must be launched"]) else: self.check_stop_reason() diff --git a/lldb/test/API/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferiorStep.py b/lldb/test/API/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferiorStep.py index 1464f2ef8664..1ad4c7902494 100644 --- a/lldb/test/API/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferiorStep.py +++ b/lldb/test/API/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferiorStep.py @@ -98,7 +98,7 @@ class CrashingRecursiveInferiorStepTestCase(TestBase): self.expect("next", substrs=["Process", expected_state]) if expected_state == "exited": - self.expect("thread list", error=True, substrs=["Process must be launched"]) + self.expect("thread list", error=True, substrs=["process must be launched"]) else: self.check_stop_reason() diff --git a/lldb/test/API/functionalities/multiword-commands/TestMultiWordCommands.py b/lldb/test/API/functionalities/multiword-commands/TestMultiWordCommands.py index c34fd3f3892a..0fa3254127e0 100644 --- a/lldb/test/API/functionalities/multiword-commands/TestMultiWordCommands.py +++ b/lldb/test/API/functionalities/multiword-commands/TestMultiWordCommands.py @@ -26,5 +26,5 @@ class MultiwordCommandsTestCase(TestBase): self.expect( 'platform ""', error=True, - substrs=["Need to specify a non-empty subcommand."], + substrs=["need to specify a non-empty subcommand"], ) diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py index a68175dc4e4d..e9403b56ae19 100644 --- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py +++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -696,6 +696,43 @@ class LinuxCoreTestCase(TestBase): self.expect("register read --all") + @skipIfLLVMTargetMissing("ARM") + def test_arm_core_vfp(self): + # check reading VFP registers + target = self.dbg.CreateTarget(None) + self.assertTrue(target, VALID_TARGET) + process = target.LoadCore("linux-arm-vfp.core") + + values = { + "d0": "0.5", + "d1": "1.5", + "d14": "14.5", + "d15": "15.5", + "s4": "4.5", + "s5": "5.5", + "s6": "6.5", + "s7": "7.5", + "fpscr": "0x20000000", + # s0 and s1 overlap d0, s2 and s3 overlap d1 and so on. Therefore, + # the following values are not as neat as those in the explicitly + # set registers. + "s0": "0", + "s1": "1.75", + "s2": "0", + "s3": "1.9375", + "s28": "0", + "s29": "2.703125", + "s30": "0", + "s31": "2.734375", + } + for regname, value in values.items(): + self.expect( + "register read {}".format(regname), + substrs=["{} = {}".format(regname, value)], + ) + + self.expect("register read --all") + @skipIfLLVMTargetMissing("RISCV") def test_riscv64_regs_gpr_fpr(self): # check basic registers using 64 bit RISC-V core file diff --git a/lldb/test/API/functionalities/postmortem/elf-core/gcore/TestGCore.py b/lldb/test/API/functionalities/postmortem/elf-core/gcore/TestGCore.py index 020a226924ea..497b8e8a19a8 100644 --- a/lldb/test/API/functionalities/postmortem/elf-core/gcore/TestGCore.py +++ b/lldb/test/API/functionalities/postmortem/elf-core/gcore/TestGCore.py @@ -37,7 +37,7 @@ class GCoreTestCase(TestBase): for thread in process: reason = thread.GetStopReason() self.assertStopReason(reason, lldb.eStopReasonSignal) - signal = thread.GetStopReasonDataAtIndex(1) + signal = thread.GetStopReasonDataAtIndex(0) # Check we got signal 19 (SIGSTOP) self.assertEqual(signal, 19) diff --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-arm-vfp.c b/lldb/test/API/functionalities/postmortem/elf-core/linux-arm-vfp.c new file mode 100644 index 000000000000..afc1dce04f9a --- /dev/null +++ b/lldb/test/API/functionalities/postmortem/elf-core/linux-arm-vfp.c @@ -0,0 +1,24 @@ +// linux-arm-vfp.core was generated with: +// > gcc-12 -march=armv7+fp -nostdlib -static -Wl,--build-id=none \ +// linux-arm-vfp.c -o linux-arm-vfp.out +// > ulimit -c 1000 +// > ulimit -s 8 +// > env -i ./linux-arm-vfp.out + +static void foo(char *boom) { + asm volatile(R"( + vmov.f64 d0, #0.5 + vmov.f64 d1, #1.5 + vmov.f64 d14, #14.5 + vmov.f64 d15, #15.5 + vmov.f32 s4, #4.5 + vmov.f32 s5, #5.5 + vmov.f32 s6, #6.5 + vmov.f32 s7, #7.5 + vcmp.f32 s7, s6 + )"); + + *boom = 47; +} + +void _start(void) { foo(0); } diff --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-arm-vfp.core b/lldb/test/API/functionalities/postmortem/elf-core/linux-arm-vfp.core Binary files differnew file mode 100644 index 000000000000..217ba18fdf6d --- /dev/null +++ b/lldb/test/API/functionalities/postmortem/elf-core/linux-arm-vfp.core diff --git a/lldb/test/API/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py b/lldb/test/API/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py index 4a848d1c2eb9..6d9aef286a79 100644 --- a/lldb/test/API/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py +++ b/lldb/test/API/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py @@ -91,7 +91,7 @@ class LinuxCoreThreadsTestCase(TestBase): reason = thread.GetStopReason() if thread.GetThreadID() == tid: self.assertStopReason(reason, lldb.eStopReasonSignal) - signal = thread.GetStopReasonDataAtIndex(1) + signal = thread.GetStopReasonDataAtIndex(0) # Check we got signal 4 (SIGILL) self.assertEqual(signal, 4) else: diff --git a/lldb/test/API/functionalities/rerun_and_expr_dylib/TestRerunAndExprDylib.py b/lldb/test/API/functionalities/rerun_and_expr_dylib/TestRerunAndExprDylib.py index 74e7c895c0fa..19edaac964e6 100644 --- a/lldb/test/API/functionalities/rerun_and_expr_dylib/TestRerunAndExprDylib.py +++ b/lldb/test/API/functionalities/rerun_and_expr_dylib/TestRerunAndExprDylib.py @@ -20,14 +20,15 @@ def isUbuntu18_04(): with open(path) as f: contents = f.read() if "Ubuntu 18.04" in contents: - return True + return "Ubuntu 18.04 is not supported." - return False + return None class TestRerunExprDylib(TestBase): @skipTestIfFn(isUbuntu18_04, bugnumber="rdar://103831050") @skipIfWindows + @skipIfRemote def test(self): """ Tests whether re-launching a process without destroying diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index 9519c576689d..5916e62c44f2 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -284,6 +284,6 @@ class ScriptedProcesTestCase(TestBase): break self.assertEqual(idx, int(reg.value, 16)) - self.assertTrue(frame.IsArtificial(), "Frame is not artificial") + self.assertTrue(frame.IsSynthetic(), "Frame is not synthetic") pc = frame.GetPCAddress().GetLoadAddress(target_0) self.assertEqual(pc, 0x0100001B00) diff --git a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py index 2721d961bcb9..835267221ddb 100644 --- a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py +++ b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py @@ -5,6 +5,7 @@ from typing import Any, Dict import lldb from lldb.plugins.scripted_process import ScriptedProcess from lldb.plugins.scripted_process import ScriptedThread +from lldb.plugins.scripted_process import ScriptedFrame class DummyStopHook: @@ -22,7 +23,7 @@ class DummyScriptedProcess(ScriptedProcess): def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData): super().__init__(exe_ctx, args) - self.threads[0] = DummyScriptedThread(self, None) + self.threads[0] = DummyScriptedThread(self, args) self.memory = {} addr = 0x500000000 debugger = self.target.GetDebugger() @@ -69,6 +70,9 @@ class DummyScriptedThread(ScriptedThread): def __init__(self, process, args): super().__init__(process, args) self.frames.append({"pc": 0x0100001B00}) + self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "baz123")) + self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "bar")) + self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "foo")) def get_thread_id(self) -> int: return 0x19 @@ -109,6 +113,65 @@ class DummyScriptedThread(ScriptedThread): ) +class DummyScriptedFrame(ScriptedFrame): + def __init__(self, thread, args, id, name, sym_ctx=None): + super().__init__(thread, args) + self.id = id + self.name = name + self.sym_ctx = sym_ctx + + def get_id(self): + return self.id + + def get_function_name(self): + return self.name + + def get_register_context(self) -> str: + return struct.pack( + "21Q", + 0x10001, + 0x10002, + 0x10003, + 0x10004, + 0x10005, + 0x10006, + 0x10007, + 0x10008, + 0x10009, + 0x100010, + 0x100011, + 0x100012, + 0x100013, + 0x100014, + 0x100015, + 0x100016, + 0x100017, + 0x100018, + 0x100019, + 0x100020, + 0x100021, + ) + + def get_symbol_context(self): + def get_symbol_context_for_function(func_name): + module = self.target.FindModule(self.target.GetExecutable()) + if not module.IsValid(): + return None + + sym_ctx_list = module.FindFunctions(func_name) + if not sym_ctx_list.IsValid() or sym_ctx_list.GetSize() == 0: + return None + + return sym_ctx_list.GetContextAtIndex(0) + + return ( + self.sym_ctx if self.sym_ctx else get_symbol_context_for_function(self.name) + ) + + def get_scripted_frame_plugin(self): + return DummyScriptedFrame.__module__ + "." + DummyScriptedFrame.__name__ + + def __lldb_init_module(debugger, dict): # This is used when loading the script in an interactive debug session to # automatically, register the stop-hook and launch the scripted process. diff --git a/lldb/test/API/functionalities/statusline/TestStatusline.py b/lldb/test/API/functionalities/statusline/TestStatusline.py index 33cd79736dc3..ca376cc595f3 100644 --- a/lldb/test/API/functionalities/statusline/TestStatusline.py +++ b/lldb/test/API/functionalities/statusline/TestStatusline.py @@ -124,6 +124,7 @@ class TestStatusline(PExpectTest): @skipIfRemote @skipIfWindows @skipIfDarwin + @skipIfLinux # https://github.com/llvm/llvm-project/issues/154763 @add_test_categories(["lldb-server"]) def test_modulelist_deadlock(self): """Regression test for a deadlock that occurs when the status line is enabled before connecting diff --git a/lldb/test/API/functionalities/thread/step_until/TestStepUntil.py b/lldb/test/API/functionalities/thread/step_until/TestStepUntil.py index 965da02ed0f9..afdc92dd4000 100644 --- a/lldb/test/API/functionalities/thread/step_until/TestStepUntil.py +++ b/lldb/test/API/functionalities/thread/step_until/TestStepUntil.py @@ -1,10 +1,9 @@ """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" - -import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil +from lldbsuite.test_event.build_exception import BuildError class StepUntilTestCase(TestBase): @@ -112,10 +111,15 @@ class StepUntilTestCase(TestBase): @no_debug_info_test @skipIf(oslist=lldbplatformutil.getDarwinOSTriples() + ["windows"]) @skipIf(archs=no_match(["x86_64", "aarch64"])) + @skipIf(compiler=no_match(["clang"])) def test_bad_line_discontinuous(self): """Test that we get an error if attempting to step outside the current function -- and the function is discontinuous""" - self.build(dictionary=self._build_dict_for_discontinuity()) + try: + self.build(dictionary=self._build_dict_for_discontinuity()) + except BuildError as ex: + self.skipTest(f"failed to build with linker script.") + _, _, thread, _ = lldbutil.run_to_source_breakpoint( self, "At the start", lldb.SBFileSpec(self.main_source) ) diff --git a/lldb/test/API/functionalities/thread/step_until/TestStepUntilAPI.py b/lldb/test/API/functionalities/thread/step_until/TestStepUntilAPI.py index 59e028acf014..08d78fb996c7 100644 --- a/lldb/test/API/functionalities/thread/step_until/TestStepUntilAPI.py +++ b/lldb/test/API/functionalities/thread/step_until/TestStepUntilAPI.py @@ -1,7 +1,7 @@ -import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil +from lldbsuite.test_event.build_exception import BuildError class TestStepUntilAPI(TestBase): @@ -74,15 +74,20 @@ class TestStepUntilAPI(TestBase): @skipIf(oslist=lldbplatformutil.getDarwinOSTriples() + ["windows"]) @skipIf(archs=no_match(["x86_64", "aarch64"])) + @skipIf(compiler=no_match(["clang"])) def test_hitting_discontinuous(self): """Test SBThread.StepOverUntil - targeting a line and hitting it -- with discontinuous functions""" - self._do_until( - self._build_dict_for_discontinuity(), - None, - self.less_than_two, - self.less_than_two, - ) + try: + self._do_until( + self._build_dict_for_discontinuity(), + None, + self.less_than_two, + self.less_than_two, + ) + except BuildError as ex: + self.skipTest(f"failed to build with linker script.") + self._assertDiscontinuity() def test_missing(self): @@ -93,15 +98,20 @@ class TestStepUntilAPI(TestBase): @skipIf(oslist=lldbplatformutil.getDarwinOSTriples() + ["windows"]) @skipIf(archs=no_match(["x86_64", "aarch64"])) + @skipIf(compiler=no_match(["clang"])) def test_missing_discontinuous(self): """Test SBThread.StepOverUntil - targeting a line and missing it by stepping out to call site -- with discontinuous functions""" - self._do_until( - self._build_dict_for_discontinuity(), - ["foo", "bar", "baz"], - self.less_than_two, - self.back_out_in_main, - ) + try: + self._do_until( + self._build_dict_for_discontinuity(), + ["foo", "bar", "baz"], + self.less_than_two, + self.back_out_in_main, + ) + except BuildError as ex: + self.skipTest(f"failed to build with linker script.") + self._assertDiscontinuity() def test_bad_line(self): @@ -120,13 +130,19 @@ class TestStepUntilAPI(TestBase): @skipIf(oslist=lldbplatformutil.getDarwinOSTriples() + ["windows"]) @skipIf(archs=no_match(["x86_64", "aarch64"])) + @skipIf(compiler=no_match(["clang"])) def test_bad_line_discontinuous(self): """Test that we get an error if attempting to step outside the current function -- and the function is discontinuous""" - self.build(dictionary=self._build_dict_for_discontinuity()) - _, _, thread, _ = lldbutil.run_to_source_breakpoint( - self, "At the start", self.main_spec - ) + + try: + self.build(dictionary=self._build_dict_for_discontinuity()) + _, _, thread, _ = lldbutil.run_to_source_breakpoint( + self, "At the start", self.main_spec + ) + except BuildError as ex: + self.skipTest(f"failed to build with linker script.") + self.assertIn( "step until target not in current function", thread.StepOverUntil( diff --git a/lldb/test/API/functionalities/tsan/basic/TestTsanBasic.py b/lldb/test/API/functionalities/tsan/basic/TestTsanBasic.py index ca8b74e35dff..51a28c501307 100644 --- a/lldb/test/API/functionalities/tsan/basic/TestTsanBasic.py +++ b/lldb/test/API/functionalities/tsan/basic/TestTsanBasic.py @@ -63,11 +63,14 @@ class TsanBasicTestCase(TestBase): substrs=["1 match found"], ) - # We should be stopped in __tsan_on_report process = self.dbg.GetSelectedTarget().process thread = process.GetSelectedThread() frame = thread.GetSelectedFrame() - self.assertIn("__tsan_on_report", frame.GetFunctionName()) + if self.platformIsDarwin(): + # We should not be stopped in the sanitizer library. + self.assertIn("f2", frame.GetFunctionName()) + else: + self.assertIn("__tsan_on_report", frame.GetFunctionName()) # The stopped thread backtrace should contain either line1 or line2 # from main.c. diff --git a/lldb/test/API/functionalities/ubsan/basic/TestUbsanBasic.py b/lldb/test/API/functionalities/ubsan/basic/TestUbsanBasic.py index 868a2864d2b5..9e9ea2114196 100644 --- a/lldb/test/API/functionalities/ubsan/basic/TestUbsanBasic.py +++ b/lldb/test/API/functionalities/ubsan/basic/TestUbsanBasic.py @@ -52,8 +52,11 @@ class UbsanBasicTestCase(TestBase): substrs=["1 match found"], ) - # We should be stopped in __ubsan_on_report - self.assertIn("__ubsan_on_report", frame.GetFunctionName()) + if self.platformIsDarwin(): + # We should not be stopped in the sanitizer library. + self.assertIn("main", frame.GetFunctionName()) + else: + self.assertIn("__ubsan_on_report", frame.GetFunctionName()) # The stopped thread backtrace should contain either 'align line' found = False diff --git a/lldb/test/API/functionalities/unwind/cortex-m-exception/Makefile b/lldb/test/API/functionalities/unwind/cortex-m-exception/Makefile new file mode 100644 index 000000000000..22f1051530f8 --- /dev/null +++ b/lldb/test/API/functionalities/unwind/cortex-m-exception/Makefile @@ -0,0 +1 @@ +include Makefile.rules diff --git a/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py b/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py new file mode 100644 index 000000000000..30b2a525eaab --- /dev/null +++ b/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py @@ -0,0 +1,73 @@ +""" +Test that we can backtrace up an ARM Cortex-M Exception return stack +""" + +import lldb +import json +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCortexMExceptionUnwind(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + # on the lldb-remote-linux-ubuntu CI, the binary.json's triple of + # armv7m-apple is not being set in the Target triple, and we're + # picking the wrong ABI plugin, ABISysV_arm. + # ABISysV_arm::CreateDefaultUnwindPlan() doesn't have a way to detect + # arm/thumb for a stack frame, or even the Target's triple for a + # Cortex-M part that is always thumb. It hardcodes r11 as the frame + # pointer register, which is correct for arm code but not thumb. + # It is never correct # on a Cortex-M target. + # The Darwin ABIMacOSX_arm diverges from AAPCS and always uses r7 for + # the frame pointer -- the thumb convention -- whether executing arm or + # thumb. So its CreateDefaultUnwindPlan picks the correct register for + # the frame pointer, and we can walk the stack. + # ABISysV_arm::CreateDefaultUnwindPlan will only get one frame and + # not be able to continue. + # + # This may only be occuring on a 32-bit Ubuntu bot; need to test + # 64-bit Ubuntu and confirm. + @skipUnlessDarwin + def test_no_fpu(self): + """Test that we can backtrace correctly through an ARM Cortex-M Exception return stack""" + + target = self.dbg.CreateTarget("") + exe = "binary.json" + with open(exe) as f: + exe_json = json.load(f) + exe_uuid = exe_json["uuid"] + + target.AddModule(exe, "", exe_uuid) + self.assertTrue(target.IsValid()) + + core = self.getBuildArtifact("core") + self.yaml2macho_core("armv7m-nofpu-exception.yaml", core, exe_uuid) + + process = target.LoadCore(core) + self.assertTrue(process.IsValid()) + + if self.TraceOn(): + self.runCmd("target list") + self.runCmd("image list") + self.runCmd("target modules dump sections") + self.runCmd("target modules dump symtab") + self.runCmd("bt") + + thread = process.GetThreadAtIndex(0) + self.assertTrue(thread.IsValid()) + + # We have 4 named stack frames and two unnamed + # frames above that. The topmost two stack frames + # were not interesting for this test, so I didn't + # create symbols for them. + self.assertEqual(thread.GetNumFrames(), 6) + stackframe_names = [ + "exception_catcher", + "exception_catcher", + "exception_thrower", + "main", + ] + for i, name in enumerate(stackframe_names): + self.assertEqual(name, thread.GetFrameAtIndex(i).GetSymbol().GetName()) diff --git a/lldb/test/API/functionalities/unwind/cortex-m-exception/armv7m-nofpu-exception.yaml b/lldb/test/API/functionalities/unwind/cortex-m-exception/armv7m-nofpu-exception.yaml new file mode 100644 index 000000000000..9ce5ff49d9b6 --- /dev/null +++ b/lldb/test/API/functionalities/unwind/cortex-m-exception/armv7m-nofpu-exception.yaml @@ -0,0 +1,64 @@ +cpu: armv7m +threads: + - regsets: + - flavor: gpr + registers: [{name: sp, value: 0x2000fe70}, {name: r7, value: 0x2000fe80}, + {name: pc, value: 0x0020392c}, {name: lr, value: 0x0020392d}] +memory-regions: + # stack memory fetched via + # (lldb) p/x $sp + # (lldb) x/128wx $sp + # % pbpaste | sed -e 's,.*: ,,' -e 's/ /, /g' -e 's/$/,/' + - addr: 0x2000fe70 + UInt32: [ + 0x0000002a, 0x20010e58, 0x00203923, 0x00000001, + 0x2000fe88, 0x00203911, 0x2000ffdc, 0xfffffff9, + 0x00000102, 0x00000002, 0x000003f0, 0x0000002a, + 0x20012620, 0x00203215, 0x00203366, 0x81000200, + 0x00203215, 0x200128b0, 0x0024928d, 0x2000fecc, + 0x002491ed, 0x20010e58, 0x20010e4c, 0x2000ffa0, + 0x200107a0, 0x0000003c, 0x200116e8, 0x200108b0, + 0x0020b895, 0x00000000, 0x0000e200, 0x2001227d, + 0x200121fd, 0x0000e000, 0x00000000, 0x200129a0, + 0x002035bf, 0x00000029, 0x000003d8, 0x20011120, + 0x200116e0, 0x40003800, 0x20011120, 0x00000000, + 0x00205169, 0x00203713, 0x00000000, 0x0022dcb9, + 0x40003800, 0x20011240, 0x00000000, 0xf7d71ecf, + 0xfc7676d6, 0x00000000, 0x968782d3, 0xe75afbbb, + 0x600d77c8, 0xc1c05886, 0x17f3e76d, 0xefc3054d, + 0x11940aaa, 0x00000000, 0x93bffabb, 0x6db85af0, + 0x00000000, 0x2001d76f, 0xcb35f653, 0x00000000, + 0x00000000, 0x079d5058, 0x00000000, 0x00000000, + 0xc5622949, 0x68682572, 0x00000075, 0x0000e500, + 0x20012c30, 0x00000000, 0xcdfcd8c2, 0x76efc90f, + 0x0024495f, 0x20012bf0, 0x0000e400, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x0029089c, 0x0029089c, 0x00000000, 0x2000ffe4, + 0x00202a87, 0x2000ffec, 0x00200257, 0x2000fff4, + 0x00200211, 0x00000000, 0x00000000, 0x7badb3f6, + 0x20010794, 0x20010fac, 0x200109b0, 0x002887a4, + 0x00285688, 0x002854c8, 0x00288f74, 0x0028a618, + 0x0028a6f8, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x002037dd, 0x00000000, + 0x00000002, 0x00000100, 0x00000000, 0x20010064, + 0x00000000, 0x00000000, 0x00000000, 0x200109c0, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 + ] + # exception_catcher() function bytes + # (lldb) dis + # binary`exception_catcher: + # 0x203910 <+0>: push {r3, r4, r5, r6, r7, lr} + # 0x203912 <+2>: add r7, sp, #0x10 + # ... + # (lldb) x/44bx 0x203910 + # % pbpaste | sed -e 's,.*: ,,' -e 's/ /, /g' -e 's/$/,/' + - addr: 0x203910 + UInt8: [ + 0xf8, 0xb5, 0x04, 0xaf, 0x06, 0x4c, 0x07, 0x49, + 0x74, 0xf0, 0x2e, 0xf8, 0x01, 0xac, 0x74, 0xf0, + 0x61, 0xf8, 0x05, 0x48, 0x76, 0xf0, 0xdf, 0xfe, + 0x74, 0xf0, 0x0b, 0xf9, 0xfe, 0xe7, 0x00, 0xbf, + 0x4c, 0x0e, 0x01, 0x20, 0x0d, 0x35, 0x20, 0x00, + 0x98, 0xae, 0x28, 0x00 + ] + diff --git a/lldb/test/API/functionalities/unwind/cortex-m-exception/binary.json b/lldb/test/API/functionalities/unwind/cortex-m-exception/binary.json new file mode 100644 index 000000000000..8fcd5307ff82 --- /dev/null +++ b/lldb/test/API/functionalities/unwind/cortex-m-exception/binary.json @@ -0,0 +1,41 @@ +{ + "triple": "armv7m-apple", + "uuid": "2D157DBA-53C9-3AC7-B5A1-9D336EC831CB", + "type": "executable", + "sections": [ + { + "user_id": 100, + "name": "TEXT", + "type": "code", + "address": 2097664, + "size": 598872, + "file_offset": 0, + "file_size": 598872, + "alignment": 2, + "flags": 514, + "read": true, + "write": false, + "execute": true + } + ], + "symbols": [ + { + "name": "main", + "type": "code", + "size": 10, + "address": 2108030 + }, + { + "name": "exception_catcher", + "type": "code", + "size": 44, + "address": 2111760 + }, + { + "name": "exception_thrower", + "type": "code", + "size": 2652, + "address": 2108040 + } + ] +} diff --git a/lldb/test/API/lang/cpp/abi_tag_structors/Makefile b/lldb/test/API/lang/cpp/abi_tag_structors/Makefile new file mode 100644 index 000000000000..99998b20bcb0 --- /dev/null +++ b/lldb/test/API/lang/cpp/abi_tag_structors/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py b/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py new file mode 100644 index 000000000000..87d8adb42b82 --- /dev/null +++ b/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py @@ -0,0 +1,116 @@ +""" +Test that we can call structors/destructors +annotated (and thus mangled) with ABI tags. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class AbiTagStructorsTestCase(TestBase): + @expectedFailureAll(oslist=["windows"]) + def test_with_structor_linkage_names(self): + self.build(dictionary={"CXXFLAGS_EXTRAS": "-gstructor-decl-linkage-names"}) + + lldbutil.run_to_source_breakpoint( + self, "Break here", lldb.SBFileSpec("main.cpp", False) + ) + + self.expect_expr( + "Tagged()", + result_type="Tagged", + result_children=[ValueCheck(name="x", value="15")], + ) + self.expect_expr( + "Tagged(-17)", + result_type="Tagged", + result_children=[ValueCheck(name="x", value="-17")], + ) + self.expect_expr("t1 = t2", result_type="Tagged") + + self.expect("expr Tagged t3(t1)", error=False) + self.expect("expr t1.~Tagged()", error=False) + + self.expect("expr t1.~Tagged()", error=False) + + self.expect( + "expression -- struct $Derived : virtual public Tagged { int y; $Derived(int val) : Tagged(val) { y = x; } };", + error=False, + ) + self.expect( + "expression -- struct $Derived2 : virtual public $Derived { int z; $Derived2() : $Derived(10) { z = y; } };", + error=False, + ) + self.expect_expr( + "$Derived2 d; d", + result_type="$Derived2", + result_children=[ + ValueCheck( + name="$Derived", + children=[ + ValueCheck( + name="Tagged", children=[ValueCheck(name="x", value="15")] + ), + ValueCheck(name="y", value="15"), + ], + ), + ValueCheck(name="z", value="15"), + ], + ) + + # Calls to deleting and base object destructor variants (D0 and D2 in Itanium ABI) + self.expect_expr( + "struct D : public HasVirtualDtor {}; D d; d.func()", + result_type="int", + result_value="10", + ) + + @expectedFailureAll(oslist=["windows"]) + def test_no_structor_linkage_names(self): + """ + Test that without linkage names on structor declarations we can't call + ABI-tagged structors. + """ + self.build(dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"}) + + lldbutil.run_to_source_breakpoint( + self, "Break here", lldb.SBFileSpec("main.cpp", False) + ) + + self.expect("expression Tagged(17)", error=True) + self.expect("expr Tagged t3(t1)", error=True) + self.expect("expr t1.~Tagged()", error=True) + + ## Calls to deleting and base object destructor variants (D0 and D2 in Itanium ABI) + self.expect( + "expression -- struct D : public HasVirtualDtor {}; D d; d.func()", + error=True, + ) + + self.expect("expression -- Derived d(16); d", error=True) + + def do_nested_structor_test(self): + """ + Test that calling ABI-tagged ctors of function local classes is not supported, + but calling un-tagged functions is. + """ + lldbutil.run_to_source_breakpoint( + self, "Break nested", lldb.SBFileSpec("main.cpp", False) + ) + + self.expect("expression Local()", error=False) + self.expect( + "expression TaggedLocal()", error=True, substrs=["Couldn't look up symbols"] + ) + + @expectedFailureAll(oslist=["windows"]) + def test_nested_no_structor_linkage_names(self): + self.build(dictionary={"CXXFLAGS_EXTRAS": "-gstructor-decl-linkage-names"}) + self.do_nested_structor_test() + + @expectedFailureAll(oslist=["windows"]) + def test_nested_with_structor_linkage_names(self): + self.build(dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"}) + self.do_nested_structor_test() diff --git a/lldb/test/API/lang/cpp/abi_tag_structors/main.cpp b/lldb/test/API/lang/cpp/abi_tag_structors/main.cpp new file mode 100644 index 000000000000..ddf237491b83 --- /dev/null +++ b/lldb/test/API/lang/cpp/abi_tag_structors/main.cpp @@ -0,0 +1,62 @@ +#include <cstdio> + +struct Tagged { + [[gnu::abi_tag("Default")]] Tagged() : x(15) { std::puts(__func__); } + [[gnu::abi_tag("Value")]] Tagged(int val) : x(val) { std::puts(__func__); } + [[gnu::abi_tag("Copy")]] Tagged(const Tagged &lhs) : x(lhs.x) { + std::puts(__func__); + } + [[gnu::abi_tag("CopyAssign")]] Tagged &operator=(const Tagged &) { + std::puts(__func__); + return *this; + } + [[gnu::abi_tag("Dtor")]] ~Tagged() { std::puts(__func__); } + + int x; +}; + +struct Base { + virtual ~Base() { std::puts(__func__); } + virtual int func() { return 5; } +}; + +struct HasVirtualDtor : public Base { + int func() override { return 10; } + + [[gnu::abi_tag("VirtualDtor")]] ~HasVirtualDtor() override { + std::puts(__func__); + } +}; + +struct HasNestedCtor { + HasNestedCtor() { + struct TaggedLocal { + [[gnu::abi_tag("Local")]] TaggedLocal() { std::puts(__func__); } + }; + + struct Local { + Local() { std::puts(__func__); } + }; + + TaggedLocal l1; + Local l2; + std::puts("Break nested"); + } +}; + +int main() { + Tagged t; + Tagged t1(10); + Tagged t2(t1); + t1 = t2; + + Base b; + HasVirtualDtor vdtor; + vdtor.func(); + + std::puts("Break here"); + + HasNestedCtor nested; + + return 0; +} diff --git a/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py b/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py index 70d7fd096c7c..c0545c70c84e 100644 --- a/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py +++ b/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py @@ -5,15 +5,14 @@ from lldbsuite.test import lldbutil class ExprDefinitionInDylibTestCase(TestBase): - NO_DEBUG_INFO_TESTCASE = True @skipIfWindows - def test(self): + def test_with_structor_linkage_names(self): """ Tests that we can call functions whose definition is in a different LLDB module than it's declaration. """ - self.build() + self.build(dictionary={"CXXFLAGS_EXTRAS": "-gstructor-decl-linkage-names"}) target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) @@ -31,10 +30,71 @@ class ExprDefinitionInDylibTestCase(TestBase): ) self.expect_expr("f.method()", result_value="-72", result_type="int") - self.expect_expr("Foo()", result_type="Foo") - # FIXME: mangled name lookup for ABI-tagged ctors fails because - # the debug-info AST doesn't have ABI-tag information. - self.expect( - "expr Bar()", error=True, substrs=["error: Couldn't look up symbols"] + self.expect_expr("Foo(10)", result_type="Foo") + + self.expect_expr("Base()", result_type="Base") + + self.expect_expr("Bar()", result_type="Bar") + + # Test a more complex setup: expression that has a three bases: + # 1. definition is in local module + # 2. definition is in different module + # 3. definition is in expression context (and has it's own virtual base) + self.expect_expr( + "struct ExprBase : virtual Foo { int z; ExprBase() : Foo(11) { z = x; } }; struct Expr : virtual Local, virtual Foo, virtual ExprBase { int w; Expr() : Local(), Foo(12), ExprBase() { w = y; } }; Expr tmp; tmp", + result_type="Expr", + result_children=[ + ValueCheck( + name="Local", + children=[ + ValueCheck( + name="Foo", children=[ValueCheck(name="x", value="12")] + ), + ValueCheck(name="y", value="12"), + ], + ), + ValueCheck(name="Foo", children=[ValueCheck(name="x", value="12")]), + ValueCheck( + name="ExprBase", + children=[ + ValueCheck( + name="Foo", children=[ValueCheck(name="x", value="12")] + ), + ValueCheck(name="z", value="12"), + ], + ), + ValueCheck(name="w", value="12"), + ], ) + + @skipIfWindows + def test_no_structor_linkage_names(self): + """ + Tests that if structor declarations don't have linkage names, we can't + call ABI-tagged constructors. But non-tagged ones are fine. + """ + self.build(dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"}) + + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + env = self.registerSharedLibrariesWithTarget(target, ["lib"]) + + breakpoint = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", line_number("main.cpp", "return") + ) + + process = target.LaunchSimple(None, env, self.get_process_working_directory()) + + self.assertIsNotNone( + lldbutil.get_one_thread_stopped_at_breakpoint_id(self.process(), breakpoint) + ) + + self.expect_expr("f.method()", result_value="-72", result_type="int") + + self.expect_expr("Foo(10)", result_type="Foo") + + self.expect("Base()", error=True) + + self.expect("Bar()", error=True) diff --git a/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.cpp b/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.cpp index 1a08817f5cda..aa3921ffe0b1 100644 --- a/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.cpp +++ b/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.cpp @@ -4,10 +4,14 @@ int Foo::method() { return -72; } -Foo::Foo() { std::puts(__func__); } +Foo::Foo(int val) : x(val) { std::puts(__func__); } Foo::~Foo() { std::puts(__func__); } Bar::Bar() { std::puts(__func__); } Bar::~Bar() { std::puts(__func__); } + +Base::Base() { std::puts(__func__); } + +Base::~Base() { std::puts(__func__); } diff --git a/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.h b/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.h index 5ec227946cba..513c9a0f9c87 100644 --- a/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.h +++ b/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.h @@ -3,11 +3,18 @@ struct Foo { int method(); - Foo(); + Foo(int val); ~Foo(); + + int x; +}; + +struct Base { + [[gnu::abi_tag("BaseCtor")]] Base(); + [[gnu::abi_tag("BaseDtor")]] ~Base(); }; -struct Bar { +struct Bar : public Base { [[gnu::abi_tag("Ctor")]] Bar(); [[gnu::abi_tag("Dtor")]] ~Bar(); }; diff --git a/lldb/test/API/lang/cpp/expr-definition-in-dylib/main.cpp b/lldb/test/API/lang/cpp/expr-definition-in-dylib/main.cpp index 4d6bece21eca..ff43190b991c 100644 --- a/lldb/test/API/lang/cpp/expr-definition-in-dylib/main.cpp +++ b/lldb/test/API/lang/cpp/expr-definition-in-dylib/main.cpp @@ -1,7 +1,18 @@ #include "lib.h" +struct Local : public virtual Foo { + Local(); + ~Local(); + int y; +}; + +Local::Local() : Foo(5) { y = x; } +Local::~Local() {} + int main() { - Foo f; - Bar b; + Foo f(5); + Base b1; + Bar b2; + Local l1; return f.method(); } diff --git a/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py index 8efa53bdbf72..d8a729b322fe 100644 --- a/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py +++ b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py @@ -9,7 +9,7 @@ class LibCxxInternalsRecognizerTestCase(TestBase): NO_DEBUG_INFO_TESTCASE = True @add_test_categories(["libc++"]) - @skipIf(compiler="clang", compiler_version=["<", "16.0"]) + @skipIf(compiler="clang", compiler_version=["<", "19.0"]) def test_frame_recognizer(self): """Test that implementation details of libc++ are hidden""" self.build() @@ -40,6 +40,7 @@ class LibCxxInternalsRecognizerTestCase(TestBase): "Callable::operator()(int) const": ["::invoke", "test_invoke"], # Containers "MyKey::operator<(MyKey const&) const": [ + "::operator()", "less", "::emplace", "test_containers", diff --git a/lldb/test/API/linux/aarch64/tls_registers/TestAArch64LinuxTLSRegisters.py b/lldb/test/API/linux/aarch64/tls_registers/TestAArch64LinuxTLSRegisters.py index ec8eb1c05dfb..2fa963efcc8f 100644 --- a/lldb/test/API/linux/aarch64/tls_registers/TestAArch64LinuxTLSRegisters.py +++ b/lldb/test/API/linux/aarch64/tls_registers/TestAArch64LinuxTLSRegisters.py @@ -53,6 +53,8 @@ class AArch64LinuxTLSRegisters(TestBase): tls_reg.IsValid(), "{} register not found.".format(register) ) self.assertEqual(tls_reg.GetValueAsUnsigned(), values[register]) + if register == "tpidr": + self.expect("reg read tp", substrs=[hex(values[register])]) def check_tls_reg(self, registers): self.setup(registers) diff --git a/lldb/test/API/macosx/arm-corefile-regctx/Makefile b/lldb/test/API/macosx/arm-corefile-regctx/Makefile deleted file mode 100644 index e1d0354441cd..000000000000 --- a/lldb/test/API/macosx/arm-corefile-regctx/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -MAKE_DSYM := NO - -CXX_SOURCES := create-arm-corefiles.cpp - -include Makefile.rules - diff --git a/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py b/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py index 6754288a65e1..a2890cdfeaa4 100644 --- a/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py +++ b/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py @@ -13,20 +13,14 @@ from lldbsuite.test import lldbutil class TestArmMachoCorefileRegctx(TestBase): NO_DEBUG_INFO_TESTCASE = True - @skipUnlessDarwin - def setUp(self): - TestBase.setUp(self) - self.build() - self.create_corefile = self.getBuildArtifact("a.out") - self.corefile = self.getBuildArtifact("core") - def test_armv7_corefile(self): ### Create corefile - retcode = call(self.create_corefile + " armv7 " + self.corefile, shell=True) + corefile = self.getBuildArtifact("core") + self.yaml2macho_core("armv7m.yaml", corefile) target = self.dbg.CreateTarget("") err = lldb.SBError() - process = target.LoadCore(self.corefile) + process = target.LoadCore(corefile) self.assertTrue(process.IsValid()) thread = process.GetSelectedThread() frame = thread.GetSelectedFrame() @@ -50,11 +44,12 @@ class TestArmMachoCorefileRegctx(TestBase): def test_arm64_corefile(self): ### Create corefile - retcode = call(self.create_corefile + " arm64 " + self.corefile, shell=True) + corefile = self.getBuildArtifact("core") + self.yaml2macho_core("arm64.yaml", corefile) target = self.dbg.CreateTarget("") err = lldb.SBError() - process = target.LoadCore(self.corefile) + process = target.LoadCore(corefile) self.assertTrue(process.IsValid()) thread = process.GetSelectedThread() frame = thread.GetSelectedFrame() diff --git a/lldb/test/API/macosx/arm-corefile-regctx/arm64.yaml b/lldb/test/API/macosx/arm-corefile-regctx/arm64.yaml new file mode 100644 index 000000000000..fe06f2d4054b --- /dev/null +++ b/lldb/test/API/macosx/arm-corefile-regctx/arm64.yaml @@ -0,0 +1,30 @@ +cpu: arm64 +threads: + # (lldb) reg read + # % pbpaste | grep = | sed 's, ,,g' | awk -F= '{print "{name: " $1 ", value: " $2 "},"}' + - regsets: + - flavor: gpr + registers: [ + {name: x0, value: 0x0000000000000001}, {name: x1, value: 0x000000016fdff3c0}, + {name: x2, value: 0x000000016fdff3d0}, {name: x3, value: 0x000000016fdff510}, + {name: x4, value: 0x0000000000000000}, {name: x5, value: 0x0000000000000000}, + {name: x6, value: 0x0000000000000000}, {name: x7, value: 0x0000000000000000}, + {name: x8, value: 0x000000010000d910}, {name: x9, value: 0x0000000000000001}, + {name: x10, value: 0xe1e88de000000000}, {name: x11, value: 0x0000000000000003}, + {name: x12, value: 0x0000000000000148}, {name: x13, value: 0x0000000000004000}, + {name: x14, value: 0x0000000000000008}, {name: x15, value: 0x0000000000000000}, + {name: x16, value: 0x0000000000000000}, {name: x17, value: 0x0000000100003f5c}, + {name: x18, value: 0x0000000000000000}, {name: x19, value: 0x0000000100003f5c}, + {name: x20, value: 0x000000010000c000}, {name: x21, value: 0x000000010000d910}, + {name: x22, value: 0x000000016fdff250}, {name: x23, value: 0x000000018ce12366}, + {name: x24, value: 0x000000016fdff1d0}, {name: x25, value: 0x0000000000000001}, + {name: x26, value: 0x0000000000000000}, {name: x27, value: 0x0000000000000000}, + {name: x28, value: 0x0000000000000000}, {name: fp, value: 0x000000016fdff3a0}, + {name: lr, value: 0x000000018cd97f28}, {name: sp, value: 0x000000016fdff140}, + {name: pc, value: 0x0000000100003f5c}, {name: cpsr, value: 0x80001000} + ] + - flavor: exc + registers: [ {name: far, value: 0x0000000100003f5c}, + {name: esr, value: 0xf2000000}, + {name: exception, value: 0x00000000} + ] diff --git a/lldb/test/API/macosx/arm-corefile-regctx/armv7m.yaml b/lldb/test/API/macosx/arm-corefile-regctx/armv7m.yaml new file mode 100644 index 000000000000..411c12a7e407 --- /dev/null +++ b/lldb/test/API/macosx/arm-corefile-regctx/armv7m.yaml @@ -0,0 +1,36 @@ +cpu: armv7m +threads: + # (lldb) reg read + # % pbpaste | grep = | sed 's, ,,g' | awk -F= '{print "{name: " $1 ", value: " $2 "},"}' + - regsets: + - flavor: gpr + registers: [ + {name: r0, value: 0x00010000}, {name: r1, value: 0x00020000}, + {name: r2, value: 0x00030000}, {name: r3, value: 0x00040000}, + {name: r4, value: 0x00050000}, {name: r5, value: 0x00060000}, + {name: r6, value: 0x00070000}, {name: r7, value: 0x00080000}, + {name: r8, value: 0x00090000}, {name: r9, value: 0x000a0000}, + {name: r10, value: 0x000b0000}, {name: r11, value: 0x000c0000}, + {name: r12, value: 0x000d0000}, {name: sp, value: 0x000e0000}, + {name: lr, value: 0x000f0000}, {name: pc, value: 0x00100000}, + {name: cpsr, value: 0x00110000} + ] + - flavor: exc + registers: [ {name: far, value: 0x00003f5c}, + {name: esr, value: 0xf2000000}, + {name: exception, value: 0x00000000} + ] + +memory-regions: + # $sp is 0x000e0000, have bytes surrounding that address + - addr: 0x000dffe0 + UInt8: [ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, + 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, + 0x3f + ] diff --git a/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp b/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp deleted file mode 100644 index db39f12ecfb7..000000000000 --- a/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp +++ /dev/null @@ -1,266 +0,0 @@ -#include <mach-o/loader.h> -#include <stdio.h> -#include <stdlib.h> -#include <string> -#include <vector> - - -// Normally these are picked up by including <mach/thread_status.h> -// but that does a compile time check for the build host arch and -// only defines the ARM register context constants when building on -// an arm system. We're creating fake corefiles, and might be -// creating them on an intel system. -#ifndef ARM_THREAD_STATE -#define ARM_THREAD_STATE 1 -#endif -#ifndef ARM_THREAD_STATE_COUNT -#define ARM_THREAD_STATE_COUNT 17 -#endif -#ifndef ARM_EXCEPTION_STATE -#define ARM_EXCEPTION_STATE 3 -#endif -#ifndef ARM_EXCEPTION_STATE_COUNT -#define ARM_EXCEPTION_STATE_COUNT 3 -#endif -#ifndef ARM_THREAD_STATE64 -#define ARM_THREAD_STATE64 6 -#endif -#ifndef ARM_THREAD_STATE64_COUNT -#define ARM_THREAD_STATE64_COUNT 68 -#endif -#ifndef ARM_EXCEPTION_STATE64 -#define ARM_EXCEPTION_STATE64 7 -#endif -#ifndef ARM_EXCEPTION_STATE64_COUNT -#define ARM_EXCEPTION_STATE64_COUNT 4 -#endif - -union uint32_buf { - uint8_t bytebuf[4]; - uint32_t val; -}; - -union uint64_buf { - uint8_t bytebuf[8]; - uint64_t val; -}; - -void add_uint64(std::vector<uint8_t> &buf, uint64_t val) { - uint64_buf conv; - conv.val = val; - for (int i = 0; i < 8; i++) - buf.push_back(conv.bytebuf[i]); -} - -void add_uint32(std::vector<uint8_t> &buf, uint32_t val) { - uint32_buf conv; - conv.val = val; - for (int i = 0; i < 4; i++) - buf.push_back(conv.bytebuf[i]); -} - -std::vector<uint8_t> armv7_lc_thread_load_command() { - std::vector<uint8_t> data; - add_uint32(data, LC_THREAD); // thread_command.cmd - add_uint32(data, 104); // thread_command.cmdsize - add_uint32(data, ARM_THREAD_STATE); // thread_command.flavor - add_uint32(data, ARM_THREAD_STATE_COUNT); // thread_command.count - add_uint32(data, 0x00010000); // r0 - add_uint32(data, 0x00020000); // r1 - add_uint32(data, 0x00030000); // r2 - add_uint32(data, 0x00040000); // r3 - add_uint32(data, 0x00050000); // r4 - add_uint32(data, 0x00060000); // r5 - add_uint32(data, 0x00070000); // r6 - add_uint32(data, 0x00080000); // r7 - add_uint32(data, 0x00090000); // r8 - add_uint32(data, 0x000a0000); // r9 - add_uint32(data, 0x000b0000); // r10 - add_uint32(data, 0x000c0000); // r11 - add_uint32(data, 0x000d0000); // r12 - add_uint32(data, 0x000e0000); // sp - add_uint32(data, 0x000f0000); // lr - add_uint32(data, 0x00100000); // pc - add_uint32(data, 0x00110000); // cpsr - - add_uint32(data, ARM_EXCEPTION_STATE); // thread_command.flavor - add_uint32(data, ARM_EXCEPTION_STATE_COUNT); // thread_command.count - add_uint32(data, 0x00003f5c); // far - add_uint32(data, 0xf2000000); // esr - add_uint32(data, 0x00000000); // exception - - return data; -} - -std::vector<uint8_t> arm64_lc_thread_load_command() { - std::vector<uint8_t> data; - add_uint32(data, LC_THREAD); // thread_command.cmd - add_uint32(data, 312); // thread_command.cmdsize - add_uint32(data, ARM_THREAD_STATE64); // thread_command.flavor - add_uint32(data, ARM_THREAD_STATE64_COUNT); // thread_command.count - add_uint64(data, 0x0000000000000001); // x0 - add_uint64(data, 0x000000016fdff3c0); // x1 - add_uint64(data, 0x000000016fdff3d0); // x2 - add_uint64(data, 0x000000016fdff510); // x3 - add_uint64(data, 0x0000000000000000); // x4 - add_uint64(data, 0x0000000000000000); // x5 - add_uint64(data, 0x0000000000000000); // x6 - add_uint64(data, 0x0000000000000000); // x7 - add_uint64(data, 0x000000010000d910); // x8 - add_uint64(data, 0x0000000000000001); // x9 - add_uint64(data, 0xe1e88de000000000); // x10 - add_uint64(data, 0x0000000000000003); // x11 - add_uint64(data, 0x0000000000000148); // x12 - add_uint64(data, 0x0000000000004000); // x13 - add_uint64(data, 0x0000000000000008); // x14 - add_uint64(data, 0x0000000000000000); // x15 - add_uint64(data, 0x0000000000000000); // x16 - add_uint64(data, 0x0000000100003f5c); // x17 - add_uint64(data, 0x0000000000000000); // x18 - add_uint64(data, 0x0000000100003f5c); // x19 - add_uint64(data, 0x000000010000c000); // x20 - add_uint64(data, 0x000000010000d910); // x21 - add_uint64(data, 0x000000016fdff250); // x22 - add_uint64(data, 0x000000018ce12366); // x23 - add_uint64(data, 0x000000016fdff1d0); // x24 - add_uint64(data, 0x0000000000000001); // x25 - add_uint64(data, 0x0000000000000000); // x26 - add_uint64(data, 0x0000000000000000); // x27 - add_uint64(data, 0x0000000000000000); // x28 - add_uint64(data, 0x000000016fdff3a0); // fp - add_uint64(data, 0x000000018cd97f28); // lr - add_uint64(data, 0x000000016fdff140); // sp - add_uint64(data, 0x0000000100003f5c); // pc - add_uint32(data, 0x80001000); // cpsr - - add_uint32(data, 0x00000000); // padding - - add_uint32(data, ARM_EXCEPTION_STATE64); // thread_command.flavor - add_uint32(data, ARM_EXCEPTION_STATE64_COUNT); // thread_command.count - add_uint64(data, 0x0000000100003f5c); // far - add_uint32(data, 0xf2000000); // esr - add_uint32(data, 0x00000000); // exception - - return data; -} - -std::vector<uint8_t> lc_segment(uint32_t fileoff, - uint32_t lc_segment_data_size) { - std::vector<uint8_t> data; - // 0x000e0000 is the value of $sp in the armv7 LC_THREAD - uint32_t start_vmaddr = 0x000e0000 - (lc_segment_data_size / 2); - add_uint32(data, LC_SEGMENT); // segment_command.cmd - add_uint32(data, sizeof(struct segment_command)); // segment_command.cmdsize - for (int i = 0; i < 16; i++) - data.push_back(0); // segment_command.segname[16] - add_uint32(data, start_vmaddr); // segment_command.vmaddr - add_uint32(data, lc_segment_data_size); // segment_command.vmsize - add_uint32(data, fileoff); // segment_command.fileoff - add_uint32(data, lc_segment_data_size); // segment_command.filesize - add_uint32(data, 3); // segment_command.maxprot - add_uint32(data, 3); // segment_command.initprot - add_uint32(data, 0); // segment_command.nsects - add_uint32(data, 0); // segment_command.flags - - return data; -} - -enum arch { unspecified, armv7, arm64 }; - -int main(int argc, char **argv) { - if (argc != 3) { - fprintf(stderr, - "usage: create-arm-corefiles [armv7|arm64] <output-core-name>\n"); - exit(1); - } - - arch arch = unspecified; - - if (strcmp(argv[1], "armv7") == 0) - arch = armv7; - else if (strcmp(argv[1], "arm64") == 0) - arch = arm64; - else { - fprintf(stderr, "unrecognized architecture %s\n", argv[1]); - exit(1); - } - - // An array of load commands (in the form of byte arrays) - std::vector<std::vector<uint8_t>> load_commands; - - // An array of corefile contents (page data, lc_note data, etc) - std::vector<uint8_t> payload; - - // First add all the load commands / payload so we can figure out how large - // the load commands will actually be. - if (arch == armv7) { - load_commands.push_back(armv7_lc_thread_load_command()); - load_commands.push_back(lc_segment(0, 0)); - } else if (arch == arm64) { - load_commands.push_back(arm64_lc_thread_load_command()); - } - - int size_of_load_commands = 0; - for (const auto &lc : load_commands) - size_of_load_commands += lc.size(); - - int header_and_load_cmd_room = - sizeof(struct mach_header_64) + size_of_load_commands; - - // Erase the load commands / payload now that we know how much space is - // needed, redo it. - load_commands.clear(); - payload.clear(); - - int payload_fileoff = (header_and_load_cmd_room + 4096 - 1) & ~(4096 - 1); - - const int lc_segment_data_size = 64; - if (arch == armv7) { - load_commands.push_back(armv7_lc_thread_load_command()); - load_commands.push_back(lc_segment(payload_fileoff, lc_segment_data_size)); - } else if (arch == arm64) { - load_commands.push_back(arm64_lc_thread_load_command()); - } - - if (arch == armv7) - for (int i = 0; i < lc_segment_data_size; - i++) // from segment_command.filesize - payload.push_back(i); - - struct mach_header_64 mh; - int header_size; - if (arch == armv7) { - mh.magic = MH_MAGIC; - mh.cputype = CPU_TYPE_ARM; - mh.cpusubtype = CPU_SUBTYPE_ARM_V7M; - header_size = sizeof(struct mach_header); - } else if (arch == arm64) { - mh.magic = MH_MAGIC_64; - mh.cputype = CPU_TYPE_ARM64; - mh.cpusubtype = CPU_SUBTYPE_ARM64_ALL; - header_size = sizeof(struct mach_header_64); - } - mh.filetype = MH_CORE; - mh.ncmds = load_commands.size(); - mh.sizeofcmds = size_of_load_commands; - mh.flags = 0; - mh.reserved = 0; - - FILE *f = fopen(argv[2], "w"); - - if (f == nullptr) { - fprintf(stderr, "Unable to open file %s for writing\n", argv[2]); - exit(1); - } - - fwrite(&mh, header_size, 1, f); - - for (const auto &lc : load_commands) - fwrite(lc.data(), lc.size(), 1, f); - - fseek(f, payload_fileoff, SEEK_SET); - - fwrite(payload.data(), payload.size(), 1, f); - - fclose(f); -} diff --git a/lldb/test/API/macosx/arm-pointer-metadata-stripping/Makefile b/lldb/test/API/macosx/arm-pointer-metadata-stripping/Makefile new file mode 100644 index 000000000000..c9319d6e6888 --- /dev/null +++ b/lldb/test/API/macosx/arm-pointer-metadata-stripping/Makefile @@ -0,0 +1,2 @@ +C_SOURCES := main.c +include Makefile.rules diff --git a/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py b/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py new file mode 100644 index 000000000000..f61945b3eb4c --- /dev/null +++ b/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py @@ -0,0 +1,48 @@ +import lldb +import json +import os +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +@skipIf(archs=no_match(["arm64", "arm64e"])) +class TestArmPointerMetadataStripping(TestBase): + # Use extra_symbols.json as a template to add a new symbol whose address + # contains non-zero high order bits set. + def create_symbols_file(self): + template_path = os.path.join(self.getSourceDir(), "extra_symbols.json") + with open(template_path, "r") as f: + symbols_data = json.load(f) + + target = self.dbg.GetSelectedTarget() + symbols_data["triple"] = target.GetTriple() + + module = target.GetModuleAtIndex(0) + symbols_data["uuid"] = module.GetUUIDString() + + json_filename = self.getBuildArtifact("extra_symbols.json") + with open(json_filename, "w") as file: + json.dump(symbols_data, file, indent=4) + + return json_filename + + def test(self): + self.build() + src = lldb.SBFileSpec("main.c") + target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, "break here", src + ) + + symbols_file = self.create_symbols_file() + self.runCmd(f"target module add {symbols_file}") + + # The high order bits should be stripped. + self.expect_expr("get_high_bits(&myglobal_json)", result_value="0") + + # Mark all bits as used for addresses and ensure bits are no longer stripped. + self.runCmd("settings set target.process.virtual-addressable-bits 64") + self.expect_expr( + "get_high_bits(&myglobal_json)", result_value=str(0x1200000000000000) + ) diff --git a/lldb/test/API/macosx/arm-pointer-metadata-stripping/extra_symbols.json b/lldb/test/API/macosx/arm-pointer-metadata-stripping/extra_symbols.json new file mode 100644 index 000000000000..5c2503d508b4 --- /dev/null +++ b/lldb/test/API/macosx/arm-pointer-metadata-stripping/extra_symbols.json @@ -0,0 +1,21 @@ +{ + "triple": "replace me", + "uuid": "replace me", + "type": "executable", + "sections": [ + { + "name": "__DATA", + "type": "data", + "address": 1297224342667202580, + "size": 16 + } + ], + "symbols": [ + { + "name": "myglobal_json", + "size": 8, + "type": "data", + "address": 1297224342667202580 + } + ] +} diff --git a/lldb/test/API/macosx/arm-pointer-metadata-stripping/main.c b/lldb/test/API/macosx/arm-pointer-metadata-stripping/main.c new file mode 100644 index 000000000000..05a85133caf7 --- /dev/null +++ b/lldb/test/API/macosx/arm-pointer-metadata-stripping/main.c @@ -0,0 +1,13 @@ +#include <stdint.h> + +uintptr_t get_high_bits(void *ptr) { + uintptr_t address_bits = 56; + uintptr_t mask = ~((1ULL << address_bits) - 1); + uintptr_t ptrtoint = (uintptr_t)ptr; + uintptr_t high_bits = ptrtoint & mask; + return high_bits; +} + +int main() { + return 0; // break here +} diff --git a/lldb/test/API/macosx/riscv32-corefile/Makefile b/lldb/test/API/macosx/riscv32-corefile/Makefile deleted file mode 100644 index 04f268758d00..000000000000 --- a/lldb/test/API/macosx/riscv32-corefile/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -MAKE_DSYM := NO -CXX_SOURCES := create-empty-riscv-corefile.cpp -EXE := create-empty-riscv-corefile - -all: create-empty-riscv-corefile - -include Makefile.rules diff --git a/lldb/test/API/macosx/riscv32-corefile/TestRV32MachOCorefile.py b/lldb/test/API/macosx/riscv32-corefile/TestRV32MachOCorefile.py index 8d11821d3898..449da70fb08c 100644 --- a/lldb/test/API/macosx/riscv32-corefile/TestRV32MachOCorefile.py +++ b/lldb/test/API/macosx/riscv32-corefile/TestRV32MachOCorefile.py @@ -13,18 +13,16 @@ from lldbsuite.test import lldbutil class TestRV32MachOCorefile(TestBase): NO_DEBUG_INFO_TESTCASE = True - @skipUnlessDarwin + @no_debug_info_test def test_riscv32_gpr_corefile_registers(self): - self.build() - create_corefile = self.getBuildArtifact("create-empty-riscv-corefile") corefile = self.getBuildArtifact("core") - call(create_corefile + " " + corefile, shell=True) + self.yaml2macho_core("riscv32-registers.yaml", corefile) target = self.dbg.CreateTarget("") process = target.LoadCore(corefile) process = target.GetProcess() - self.assertEqual(process.GetNumThreads(), 1) + self.assertEqual(process.GetNumThreads(), 2) thread = process.GetThreadAtIndex(0) self.assertEqual(thread.GetNumFrames(), 1) @@ -80,3 +78,12 @@ class TestRV32MachOCorefile(TestBase): val = idx | (idx << 8) | (idx << 16) | (idx << 24) self.assertEqual(gpr_regs.GetChildAtIndex(idx).GetValueAsUnsigned(), val) idx = idx + 1 + + thread = process.GetThreadAtIndex(1) + self.assertEqual(thread.GetNumFrames(), 1) + + frame = thread.GetFrameAtIndex(0) + gpr_regs = frame.registers.GetValueAtIndex(0) + + self.assertEqual(gpr_regs.GetChildAtIndex(0).GetValueAsUnsigned(), 0x90000000) + self.assertEqual(gpr_regs.GetChildAtIndex(32).GetValueAsUnsigned(), 0x90202020) diff --git a/lldb/test/API/macosx/riscv32-corefile/create-empty-riscv-corefile.cpp b/lldb/test/API/macosx/riscv32-corefile/create-empty-riscv-corefile.cpp deleted file mode 100644 index 907cca3b70b4..000000000000 --- a/lldb/test/API/macosx/riscv32-corefile/create-empty-riscv-corefile.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include <inttypes.h> -#include <mach-o/loader.h> -#include <mach/thread_status.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <string> -#include <sys/errno.h> -#include <uuid/uuid.h> -#include <vector> - -#define CPU_TYPE_RISCV 24 -#define CPU_SUBTYPE_RISCV_ALL 0 -#define RV32_THREAD_STATE 2 -// x0-x31 + pc, all 32-bit -#define RV32_THREAD_STATE_COUNT 33 - -union uint32_buf { - uint8_t bytebuf[4]; - uint32_t val; -}; - -union uint64_buf { - uint8_t bytebuf[8]; - uint64_t val; -}; - -void add_uint64(std::vector<uint8_t> &buf, uint64_t val) { - uint64_buf conv; - conv.val = val; - for (int i = 0; i < 8; i++) - buf.push_back(conv.bytebuf[i]); -} - -void add_uint32(std::vector<uint8_t> &buf, uint32_t val) { - uint32_buf conv; - conv.val = val; - for (int i = 0; i < 4; i++) - buf.push_back(conv.bytebuf[i]); -} - -std::vector<uint8_t> lc_thread_load_command() { - std::vector<uint8_t> data; - add_uint32(data, LC_THREAD); // thread_command.cmd - add_uint32(data, 4 + 4 + 4 + 4 + - (RV32_THREAD_STATE_COUNT * 4)); // thread_command.cmdsize - add_uint32(data, RV32_THREAD_STATE); // thread_command.flavor - add_uint32(data, RV32_THREAD_STATE_COUNT); // thread_command.count - for (int i = 0; i < RV32_THREAD_STATE_COUNT; i++) { - add_uint32(data, i | (i << 8) | (i << 16) | (i << 24)); - } - return data; -} - -int main(int argc, char **argv) { - if (argc != 2) { - fprintf(stderr, - "usage: create-empty-riscv-corefile output-corefile-name\n"); - exit(1); - } - - cpu_type_t cputype = CPU_TYPE_RISCV; - cpu_subtype_t cpusubtype = CPU_SUBTYPE_RISCV_ALL; - - // An array of load commands (in the form of byte arrays) - std::vector<std::vector<uint8_t>> load_commands; - - // An array of corefile contents (page data, lc_note data, etc) - std::vector<uint8_t> payload; - - // First add all the load commands / payload so we can figure out how large - // the load commands will actually be. - load_commands.push_back(lc_thread_load_command()); - - int size_of_load_commands = 0; - for (const auto &lc : load_commands) - size_of_load_commands += lc.size(); - - int header_and_load_cmd_room = - sizeof(struct mach_header_64) + size_of_load_commands; - - // Erase the load commands / payload now that we know how much space is - // needed, redo it. - load_commands.clear(); - payload.clear(); - - load_commands.push_back(lc_thread_load_command()); - - struct mach_header mh; - mh.magic = MH_MAGIC; - mh.cputype = cputype; - - mh.cpusubtype = cpusubtype; - mh.filetype = MH_CORE; - mh.ncmds = load_commands.size(); - mh.sizeofcmds = size_of_load_commands; - mh.flags = 0; - - FILE *f = fopen(argv[1], "w"); - - if (f == nullptr) { - fprintf(stderr, "Unable to open file %s for writing\n", argv[1]); - exit(1); - } - - fwrite(&mh, sizeof(struct mach_header), 1, f); - - for (const auto &lc : load_commands) - fwrite(lc.data(), lc.size(), 1, f); - - fseek(f, header_and_load_cmd_room, SEEK_SET); - - fwrite(payload.data(), payload.size(), 1, f); - - fclose(f); -} diff --git a/lldb/test/API/macosx/riscv32-corefile/riscv32-registers.yaml b/lldb/test/API/macosx/riscv32-corefile/riscv32-registers.yaml new file mode 100644 index 000000000000..81c725f1a4f0 --- /dev/null +++ b/lldb/test/API/macosx/riscv32-corefile/riscv32-registers.yaml @@ -0,0 +1,46 @@ +cpu: riscv +threads: + # (lldb) reg read + # % pbpaste | grep = | sed 's, ,,g' | awk -F= '{print "{name: " $1 ", value: " $2 "},"}' + - regsets: + - flavor: gpr + registers: [ + {name: zero, value: 0x00000000}, {name: ra, value: 0x01010101}, + {name: sp, value: 0x02020202}, {name: gp, value: 0x03030303}, + {name: tp, value: 0x04040404}, {name: t0, value: 0x05050505}, + {name: t1, value: 0x06060606}, {name: t2, value: 0x07070707}, + {name: fp, value: 0x08080808}, {name: s1, value: 0x09090909}, + {name: a0, value: 0x0a0a0a0a}, {name: a1, value: 0x0b0b0b0b}, + {name: a2, value: 0x0c0c0c0c}, {name: a3, value: 0x0d0d0d0d}, + {name: a4, value: 0x0e0e0e0e}, {name: a5, value: 0x0f0f0f0f}, + {name: a6, value: 0x10101010}, {name: a7, value: 0x11111111}, + {name: s2, value: 0x12121212}, {name: s3, value: 0x13131313}, + {name: s4, value: 0x14141414}, {name: s5, value: 0x15151515}, + {name: s6, value: 0x16161616}, {name: s7, value: 0x17171717}, + {name: s8, value: 0x18181818}, {name: s9, value: 0x19191919}, + {name: s10, value: 0x1a1a1a1a}, {name: s11, value: 0x1b1b1b1b}, + {name: t3, value: 0x1c1c1c1c}, {name: t4, value: 0x1d1d1d1d}, + {name: t5, value: 0x1e1e1e1e}, {name: t6, value: 0x1f1f1f1f}, + {name: pc, value: 0x20202020} + ] + - regsets: + - flavor: gpr + registers: [ + {name: zero, value: 0x90000000}, {name: ra, value: 0x91010101}, + {name: sp, value: 0x92020202}, {name: gp, value: 0x93030303}, + {name: tp, value: 0x94040404}, {name: t0, value: 0x95050505}, + {name: t1, value: 0x96060606}, {name: t2, value: 0x97070707}, + {name: fp, value: 0x98080808}, {name: s1, value: 0x99090909}, + {name: a0, value: 0x9a0a0a0a}, {name: a1, value: 0x9b0b0b0b}, + {name: a2, value: 0x9c0c0c0c}, {name: a3, value: 0x9d0d0d0d}, + {name: a4, value: 0x9e0e0e0e}, {name: a5, value: 0x9f0f0f0f}, + {name: a6, value: 0x90101010}, {name: a7, value: 0x91111111}, + {name: s2, value: 0x92121212}, {name: s3, value: 0x93131313}, + {name: s4, value: 0x94141414}, {name: s5, value: 0x95151515}, + {name: s6, value: 0x96161616}, {name: s7, value: 0x97171717}, + {name: s8, value: 0x98181818}, {name: s9, value: 0x19191919}, + {name: s10, value: 0x9a1a1a1a}, {name: s11, value: 0x9b1b1b1b}, + {name: t3, value: 0x9c1c1c1c}, {name: t4, value: 0x9d1d1d1d}, + {name: t5, value: 0x9e1e1e1e}, {name: t6, value: 0x9f1f1f1f}, + {name: pc, value: 0x90202020} + ] diff --git a/lldb/test/API/python_api/basename/Makefile b/lldb/test/API/python_api/basename/Makefile new file mode 100644 index 000000000000..99998b20bcb0 --- /dev/null +++ b/lldb/test/API/python_api/basename/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/python_api/basename/TestGetBaseName.py b/lldb/test/API/python_api/basename/TestGetBaseName.py new file mode 100644 index 000000000000..a3b752e67a35 --- /dev/null +++ b/lldb/test/API/python_api/basename/TestGetBaseName.py @@ -0,0 +1,40 @@ +""" +Test SBFunction::GetBaseName() and SBSymbol::GetBaseName() APIs. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class GetBaseNameTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + TestBase.setUp(self) + self.main_source_file = lldb.SBFileSpec("main.cpp") + + @expectedFailureAll( + oslist=["windows"], + bugnumber="https://github.com/llvm/llvm-project/issues/156861", + ) + def test(self): + """Test SBFunction.GetBaseName() and SBSymbol.GetBaseName()""" + self.build() + _, _, thread, _ = lldbutil.run_to_source_breakpoint( + self, "Set a breakpoint here", self.main_source_file + ) + + frame0 = thread.GetFrameAtIndex(0) + + # Get both function and symbol + function = frame0.GetFunction() + symbol = frame0.GetSymbol() + + # Test consistency between function and symbol basename + function_basename = function.GetBaseName() + symbol_basename = symbol.GetBaseName() + + self.assertEqual(function_basename, "templateFunc") + self.assertEqual(symbol_basename, "templateFunc") diff --git a/lldb/test/API/python_api/basename/main.cpp b/lldb/test/API/python_api/basename/main.cpp new file mode 100644 index 000000000000..9b4140985cf4 --- /dev/null +++ b/lldb/test/API/python_api/basename/main.cpp @@ -0,0 +1,16 @@ +#include <iostream> + +namespace ns { +template <typename T> class MyClass { +public: + void templateFunc() { + std::cout << "In templateFunc" << std::endl; // Set a breakpoint here + } +}; +} // namespace ns + +int main() { + ns::MyClass<int> obj; + obj.templateFunc(); + return 0; +} diff --git a/lldb/test/API/python_api/interpreter/TestRunCommandInterpreterAPI.py b/lldb/test/API/python_api/interpreter/TestRunCommandInterpreterAPI.py index f677b869d137..456598785529 100644 --- a/lldb/test/API/python_api/interpreter/TestRunCommandInterpreterAPI.py +++ b/lldb/test/API/python_api/interpreter/TestRunCommandInterpreterAPI.py @@ -105,7 +105,7 @@ class CommandRunInterpreterAPICase(TestBase): self.assertFalse(has_crashed) self.assertIn("invalid target", result_str) - self.assertIn("No auto repeat", result_str) + self.assertIn("no auto repeat", result_str) class SBCommandInterpreterRunOptionsCase(TestBase): diff --git a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py index 99f88d3da794..b12f4daee0c8 100644 --- a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py +++ b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py @@ -48,10 +48,11 @@ class TestStructuredDataAPI(TestBase): s.Clear() error = example.GetDescription(s) self.assertSuccess(error, "GetDescription works") + # Ensure str() doesn't raise an exception. + self.assertTrue(str(example)) if not "key_float" in s.GetData(): self.fail("FAILED: could not find key_float in description output") - dict_struct = lldb.SBStructuredData() dict_struct = example.GetValueForKey("key_dict") # Tests for dictionary data type @@ -113,18 +114,22 @@ class TestStructuredDataAPI(TestBase): self.assertSuccess(example.SetFromJSON("1")) self.assertEqual(example.GetType(), lldb.eStructuredDataTypeInteger) self.assertEqual(example.GetIntegerValue(), 1) + self.assertEqual(int(example), 1) self.assertSuccess(example.SetFromJSON("4.19")) self.assertEqual(example.GetType(), lldb.eStructuredDataTypeFloat) self.assertEqual(example.GetFloatValue(), 4.19) + self.assertEqual(float(example), 4.19) self.assertSuccess(example.SetFromJSON('"Bonjour, 123!"')) self.assertEqual(example.GetType(), lldb.eStructuredDataTypeString) self.assertEqual(example.GetStringValue(42), "Bonjour, 123!") + self.assertEqual(str(example), "Bonjour, 123!") self.assertSuccess(example.SetFromJSON("true")) self.assertEqual(example.GetType(), lldb.eStructuredDataTypeBoolean) self.assertTrue(example.GetBooleanValue()) + self.assertTrue(example) self.assertSuccess(example.SetFromJSON("null")) self.assertEqual(example.GetType(), lldb.eStructuredDataTypeNull) @@ -187,38 +192,35 @@ class TestStructuredDataAPI(TestBase): self.assertEqual(sb_data, example_arr) def invalid_struct_test(self, example): - invalid_struct = lldb.SBStructuredData() invalid_struct = example.GetValueForKey("invalid_key") if invalid_struct.IsValid(): self.fail("An invalid object should have been returned") # Check Type API - if not invalid_struct.GetType() == lldb.eStructuredDataTypeInvalid: + if invalid_struct.GetType() != lldb.eStructuredDataTypeInvalid: self.fail("Wrong type returned: " + str(invalid_struct.GetType())) def dictionary_struct_test(self, example): # Check API returning a valid SBStructuredData of 'dictionary' type - dict_struct = lldb.SBStructuredData() dict_struct = example.GetValueForKey("key_dict") if not dict_struct.IsValid(): self.fail("A valid object should have been returned") # Check Type API - if not dict_struct.GetType() == lldb.eStructuredDataTypeDictionary: + if dict_struct.GetType() != lldb.eStructuredDataTypeDictionary: self.fail("Wrong type returned: " + str(dict_struct.GetType())) # Check Size API for 'dictionary' type - if not dict_struct.GetSize() == 6: + if dict_struct.GetSize() != 6: self.fail("Wrong no of elements returned: " + str(dict_struct.GetSize())) def string_struct_test(self, dict_struct): - string_struct = lldb.SBStructuredData() string_struct = dict_struct.GetValueForKey("key_string") if not string_struct.IsValid(): self.fail("A valid object should have been returned") # Check Type API - if not string_struct.GetType() == lldb.eStructuredDataTypeString: + if string_struct.GetType() != lldb.eStructuredDataTypeString: self.fail("Wrong type returned: " + str(string_struct.GetType())) # Check API returning 'string' value @@ -238,18 +240,17 @@ class TestStructuredDataAPI(TestBase): # Check a valid SBStructuredData containing an unsigned integer. # We intentionally make this larger than what an int64_t can hold but # still small enough to fit a uint64_t - uint_struct = lldb.SBStructuredData() uint_struct = dict_struct.GetValueForKey("key_uint") if not uint_struct.IsValid(): self.fail("A valid object should have been returned") # Check Type API - if not uint_struct.GetType() == lldb.eStructuredDataTypeInteger: + if uint_struct.GetType() != lldb.eStructuredDataTypeInteger: self.fail("Wrong type returned: " + str(uint_struct.GetType())) # Check API returning unsigned integer value output = uint_struct.GetUnsignedIntegerValue() - if not output == 0xFFFFFFFF00000000: + if output != 0xFFFFFFFF00000000: self.fail("wrong output: " + str(output)) # Calling wrong API on a SBStructuredData @@ -262,18 +263,17 @@ class TestStructuredDataAPI(TestBase): # Check a valid SBStructuredData containing an signed integer. # We intentionally make this smaller than what an uint64_t can hold but # still small enough to fit a int64_t - sint_struct = lldb.SBStructuredData() sint_struct = dict_struct.GetValueForKey("key_sint") if not sint_struct.IsValid(): self.fail("A valid object should have been returned") # Check Type API - if not sint_struct.GetType() == lldb.eStructuredDataTypeSignedInteger: + if sint_struct.GetType() != lldb.eStructuredDataTypeSignedInteger: self.fail("Wrong type returned: " + str(sint_struct.GetType())) # Check API returning signed integer value output = sint_struct.GetSignedIntegerValue() - if not output == -42: + if output != -42: self.fail("wrong output: " + str(output)) # Calling wrong API on a SBStructuredData @@ -283,28 +283,26 @@ class TestStructuredDataAPI(TestBase): self.fail("Valid string " + output + " returned for an integer object") def double_struct_test(self, dict_struct): - floating_point_struct = lldb.SBStructuredData() floating_point_struct = dict_struct.GetValueForKey("key_float") if not floating_point_struct.IsValid(): self.fail("A valid object should have been returned") # Check Type API - if not floating_point_struct.GetType() == lldb.eStructuredDataTypeFloat: + if floating_point_struct.GetType() != lldb.eStructuredDataTypeFloat: self.fail("Wrong type returned: " + str(floating_point_struct.GetType())) # Check API returning 'double' value output = floating_point_struct.GetFloatValue() - if not output == 2.99: + if output != 2.99: self.fail("wrong output: " + str(output)) def bool_struct_test(self, dict_struct): - bool_struct = lldb.SBStructuredData() bool_struct = dict_struct.GetValueForKey("key_bool") if not bool_struct.IsValid(): self.fail("A valid object should have been returned") # Check Type API - if not bool_struct.GetType() == lldb.eStructuredDataTypeBoolean: + if bool_struct.GetType() != lldb.eStructuredDataTypeBoolean: self.fail("Wrong type returned: " + str(bool_struct.GetType())) # Check API returning 'bool' value @@ -314,17 +312,16 @@ class TestStructuredDataAPI(TestBase): def array_struct_test(self, dict_struct): # Check API returning a valid SBStructuredData of 'array' type - array_struct = lldb.SBStructuredData() array_struct = dict_struct.GetValueForKey("key_array") if not array_struct.IsValid(): self.fail("A valid object should have been returned") # Check Type API - if not array_struct.GetType() == lldb.eStructuredDataTypeArray: + if array_struct.GetType() != lldb.eStructuredDataTypeArray: self.fail("Wrong type returned: " + str(array_struct.GetType())) # Check Size API for 'array' type - if not array_struct.GetSize() == 2: + if array_struct.GetSize() != 2: self.fail("Wrong no of elements returned: " + str(array_struct.GetSize())) # Check API returning a valid SBStructuredData for different 'array' @@ -332,17 +329,73 @@ class TestStructuredDataAPI(TestBase): string_struct = array_struct.GetItemAtIndex(0) if not string_struct.IsValid(): self.fail("A valid object should have been returned") - if not string_struct.GetType() == lldb.eStructuredDataTypeString: + if string_struct.GetType() != lldb.eStructuredDataTypeString: self.fail("Wrong type returned: " + str(string_struct.GetType())) output = string_struct.GetStringValue(5) - if not output == "23": + if output != "23": self.fail("wrong output: " + str(output)) string_struct = array_struct.GetItemAtIndex(1) if not string_struct.IsValid(): self.fail("A valid object should have been returned") - if not string_struct.GetType() == lldb.eStructuredDataTypeString: + if string_struct.GetType() != lldb.eStructuredDataTypeString: self.fail("Wrong type returned: " + str(string_struct.GetType())) output = string_struct.GetStringValue(5) - if not output == "arr": + if output != "arr": self.fail("wrong output: " + str(output)) + + def test_round_trip_scalars(self): + for original in (0, 11, -1, 0.0, 4.5, -0.25): + constructor = type(original) + data = lldb.SBStructuredData() + data.SetFromJSON(json.dumps(original)) + round_tripped = constructor(data) + self.assertEqual(round_tripped, original) + + def test_dynamic(self): + for original in (0, 11, -1, 0.0, 4.5, -0.25, "", "dirk", True, False): + data = lldb.SBStructuredData() + data.SetFromJSON(json.dumps(original)) + self.assertEqual(data.dynamic, original) + + def test_round_trip_int(self): + for original in (0, 11, -1): + data = lldb.SBStructuredData() + data.SetFromJSON(json.dumps(original)) + self.assertEqual(int(data), int(original)) + + def test_round_trip_float(self): + for original in (0, 11, -1, 0.0, 4.5, -0.25): + data = lldb.SBStructuredData() + data.SetFromJSON(json.dumps(original)) + self.assertEqual(float(data), float(original)) + + def test_iterate_array(self): + array = [0, 1, 2] + data = lldb.SBStructuredData() + data.SetFromJSON(json.dumps(array)) + for value in data: + self.assertEqual(value, array.pop(0)) + + def test_iterate_dictionary(self): + dictionary = {"0": 0, "1": 1, "2": 2} + keys = set(dictionary.keys()) + data = lldb.SBStructuredData() + data.SetFromJSON(json.dumps(dictionary)) + for key in data: + self.assertIn(key, keys) + keys.remove(key) + + def test_getitem_array(self): + array = [1, 2, 3] + data = lldb.SBStructuredData() + data.SetFromJSON(json.dumps(array)) + for i in range(len(array)): + self.assertEqual(data[i], array[i]) + + def test_getitem_dictionary(self): + dictionary = {"one": 1, "two": 2, "three": 3} + data = lldb.SBStructuredData() + data.SetFromJSON(json.dumps(dictionary)) + for key in dictionary: + self.assertEqual(data[key], dictionary[key]) diff --git a/lldb/test/API/riscv/step/TestSoftwareStep.py b/lldb/test/API/riscv/step/TestSoftwareStep.py index 279c4c1b797e..0544d2102d0f 100644 --- a/lldb/test/API/riscv/step/TestSoftwareStep.py +++ b/lldb/test/API/riscv/step/TestSoftwareStep.py @@ -26,19 +26,26 @@ class TestSoftwareStep(TestBase): substrs=["stopped", "stop reason = instruction step into"], ) - pc = cur_thread.GetFrameAtIndex(0).GetPC() + # Get the instruction we stopped at + pc = cur_thread.GetFrameAtIndex(0).GetPCAddress() + inst = target.ReadInstructions(pc, 1).GetInstructionAtIndex(0) - return pc - entry_pc + inst_mnemonic = inst.GetMnemonic(target) + inst_operands = inst.GetOperands(target) + if not inst_operands: + return inst_mnemonic - @skipIf(archs=no_match("^rv.*")) + return f"{inst_mnemonic} {inst_operands}" + + @skipIf(archs=no_match("^riscv.*")) def test_cas(self): """ This test verifies LLDB instruction step handling of a proper lr/sc pair. """ - difference = self.do_sequence_test("main", "cas") - self.assertEqual(difference, 0x1A) + instruction = self.do_sequence_test("main", "cas") + self.assertEqual(instruction, "nop") - @skipIf(archs=no_match("^rv.*")) + @skipIf(archs=no_match("^riscv.*")) def test_branch_cas(self): """ LLDB cannot predict the actual state of registers within a critical section (i.e., inside an atomic @@ -51,29 +58,29 @@ class TestSoftwareStep(TestBase): test is nearly identical to the previous one, except for the branch condition, which is inverted and will result in a taken jump. """ - difference = self.do_sequence_test("branch", "branch_cas") - self.assertEqual(difference, 0x1A) + instruction = self.do_sequence_test("branch", "branch_cas") + self.assertEqual(instruction, "ret") - @skipIf(archs=no_match("^rv.*")) + @skipIf(archs=no_match("^riscv.*")) def test_incomplete_sequence_without_lr(self): """ This test verifies the behavior of a standalone sc instruction without a preceding lr. Since the sc lacks the required lr pairing, LLDB should treat it as a non-atomic store rather than part of an atomic sequence. """ - difference = self.do_sequence_test( + instruction = self.do_sequence_test( "incomplete_sequence_without_lr", "incomplete_cas" ) - self.assertEqual(difference, 0x4) + self.assertEqual(instruction, "and a5, a2, a4") - @skipIf(archs=no_match("^rv.*")) + @skipIf(archs=no_match("^riscv.*")) def test_incomplete_sequence_without_sc(self): """ This test checks the behavior of a standalone lr instruction without a subsequent sc. Since the lr lacks its required sc counterpart, LLDB should treat it as a non-atomic load rather than part of an atomic sequence. """ - difference = self.do_sequence_test( + instruction = self.do_sequence_test( "incomplete_sequence_without_sc", "incomplete_cas" ) - self.assertEqual(difference, 0x4) + self.assertEqual(instruction, "and a5, a2, a4") diff --git a/lldb/test/API/riscv/step/branch.c b/lldb/test/API/riscv/step/branch.c index 79bf0ca005db..93d6c51ec75e 100644 --- a/lldb/test/API/riscv/step/branch.c +++ b/lldb/test/API/riscv/step/branch.c @@ -11,6 +11,7 @@ void __attribute__((naked)) branch_cas(int *a, int *b) { "xor a5, a2, a5\n\t" "sc.w a5, a1, (a3)\n\t" "beqz a5, 1b\n\t" + "nop\n\t" "2:\n\t" "ret\n\t"); } diff --git a/lldb/test/API/riscv/step/incomplete_sequence_without_lr.c b/lldb/test/API/riscv/step/incomplete_sequence_without_lr.c index eda313c6d69c..ceb906f7f50e 100644 --- a/lldb/test/API/riscv/step/incomplete_sequence_without_lr.c +++ b/lldb/test/API/riscv/step/incomplete_sequence_without_lr.c @@ -1,7 +1,7 @@ void __attribute__((naked)) incomplete_cas(int *a, int *b) { // Stop at the first instruction (an sc without a corresponding lr), then make // a step instruction and ensure that execution stops at the next instruction - // (and). + // (and a5, a2, a4). asm volatile("1:\n\t" "sc.w a5, a1, (a3)\n\t" "and a5, a2, a4\n\t" diff --git a/lldb/test/API/riscv/step/incomplete_sequence_without_sc.c b/lldb/test/API/riscv/step/incomplete_sequence_without_sc.c index 952dc7d2804e..3f1bf64b85c5 100644 --- a/lldb/test/API/riscv/step/incomplete_sequence_without_sc.c +++ b/lldb/test/API/riscv/step/incomplete_sequence_without_sc.c @@ -1,7 +1,7 @@ void __attribute__((naked)) incomplete_cas(int *a, int *b) { // Stop at the first instruction (an lr without a corresponding sc), then make // a step instruction and ensure that execution stops at the next instruction - // (and). + // (and a5, a2, a4). asm volatile("1:\n\t" "lr.w a2, (a0)\n\t" "and a5, a2, a4\n\t" diff --git a/lldb/test/API/riscv/step/main.c b/lldb/test/API/riscv/step/main.c index 35e8aee2cae4..6649034aa0a3 100644 --- a/lldb/test/API/riscv/step/main.c +++ b/lldb/test/API/riscv/step/main.c @@ -1,7 +1,7 @@ void __attribute__((naked)) cas(int *a, int *b) { // This atomic sequence implements a copy-and-swap function. This test should - // at the first instruction, and after step instruction, we should stop at the - // end of the sequence (on the ret instruction). + // stop at the first instruction, and after step instruction, we should stop + // at the end of the sequence (on the ret instruction). asm volatile("1:\n\t" "lr.w a2, (a0)\n\t" "and a5, a2, a4\n\t" @@ -11,6 +11,7 @@ void __attribute__((naked)) cas(int *a, int *b) { "xor a5, a2, a5\n\t" "sc.w a5, a1, (a3)\n\t" "beqz a5, 1b\n\t" + "nop\n\t" "2:\n\t" "ret\n\t"); } diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py index c54e21c1b973..d7d25ca20f85 100644 --- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py +++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py @@ -40,6 +40,7 @@ class TestDAP_attach(lldbdap_testcase.DAPTestCaseBase): self.continue_to_exit() @skipIfNetBSD # Hangs on NetBSD as well + @skipIfWindows # https://github.com/llvm/llvm-project/issues/137660 def test_by_pid(self): """ Tests attaching to a process by process ID. @@ -93,6 +94,7 @@ class TestDAP_attach(lldbdap_testcase.DAPTestCaseBase): self.set_and_hit_breakpoint(continueToExit=True) @skipIfNetBSD # Hangs on NetBSD as well + @skipIfWindows def test_commands(self): """ Tests the "initCommands", "preRunCommands", "stopCommands", diff --git a/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py b/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py index e722fcea9283..109f34ff10a5 100644 --- a/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py +++ b/lldb/test/API/tools/lldb-dap/cancel/TestDAP_cancel.py @@ -37,6 +37,7 @@ class TestDAP_cancel(lldbdap_testcase.DAPTestCaseBase): def async_cancel(self, requestId: int) -> int: return self.send_async_req(command="cancel", arguments={"requestId": requestId}) + @skipIfWindows def test_pending_request(self): """ Tests cancelling a pending request. diff --git a/lldb/test/API/tools/lldb-dap/console/TestDAP_console.py b/lldb/test/API/tools/lldb-dap/console/TestDAP_console.py index ceddaeb50cd3..202b23abc181 100644 --- a/lldb/test/API/tools/lldb-dap/console/TestDAP_console.py +++ b/lldb/test/API/tools/lldb-dap/console/TestDAP_console.py @@ -38,6 +38,7 @@ class TestDAP_console(lldbdap_testcase.DAPTestCaseBase): ), ) + @skipIfWindows def test_scopes_variables_setVariable_evaluate(self): """ Tests that the "scopes" request causes the currently selected diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py index 41112a4f5b9e..22fcd42b3d36 100644 --- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py +++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py @@ -7,6 +7,7 @@ from lldbsuite.test.lldbtest import * import lldbdap_testcase import os import re +import tempfile # Many tests are skipped on Windows because get_stdout() returns None there. # Despite the test program printing correctly. See @@ -94,6 +95,8 @@ class TestDAP_launch(lldbdap_testcase.DAPTestCaseBase): # Check the return code self.assertEqual(self.dap_server.process.poll(), 0) + # Flakey on Windows, https://github.com/llvm/llvm-project/issues/137660. + @skipIfWindows def test_stopOnEntry(self): """ Tests the default launch of a simple program that stops at the @@ -582,3 +585,42 @@ class TestDAP_launch(lldbdap_testcase.DAPTestCaseBase): version_string.splitlines(), "version string does not match", ) + + def test_no_lldbinit_flag(self): + """ + Test that the --no-lldbinit flag prevents sourcing .lldbinit files. + """ + # Create a temporary .lldbinit file in the home directory + with tempfile.TemporaryDirectory() as temp_home: + lldbinit_path = os.path.join(temp_home, ".lldbinit") + + # Write a command to the .lldbinit file that would set a unique setting + with open(lldbinit_path, "w") as f: + f.write("settings set stop-disassembly-display never\n") + f.write("settings set target.x86-disassembly-flavor intel\n") + + # Test with --no-lldbinit flag (should NOT source .lldbinit) + self.build_and_create_debug_adapter( + lldbDAPEnv={"HOME": temp_home}, additional_args=["--no-lldbinit"] + ) + program = self.getBuildArtifact("a.out") + + # Use initCommands to check if .lldbinit was sourced + initCommands = ["settings show stop-disassembly-display"] + + # Launch with initCommands to check the setting + self.launch(program, initCommands=initCommands, stopOnEntry=True) + + # Get console output to verify the setting was NOT set from .lldbinit + output = self.get_console() + self.assertTrue(output and len(output) > 0, "expect console output") + + # Verify the setting has default value, not "never" from .lldbinit + self.assertNotIn( + "never", + output, + "Setting should have default value when --no-lldbinit is used", + ) + + # Verify the initCommands were executed + self.verify_commands("initCommands", output, initCommands) diff --git a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py index e01320c25b15..12b321cf4277 100644 --- a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py +++ b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py @@ -5,6 +5,7 @@ Test lldb-dap server integration. import os import signal import tempfile +import time import dap_server from lldbsuite.test.decorators import * @@ -13,22 +14,28 @@ import lldbdap_testcase class TestDAP_server(lldbdap_testcase.DAPTestCaseBase): - def start_server(self, connection): + def start_server( + self, connection, connection_timeout=None, wait_seconds_for_termination=None + ): log_file_path = self.getBuildArtifact("dap.txt") (process, connection) = dap_server.DebugAdapterServer.launch( executable=self.lldbDAPExec, connection=connection, + connection_timeout=connection_timeout, log_file=log_file_path, ) def cleanup(): - process.terminate() + if wait_seconds_for_termination is not None: + process.wait(wait_seconds_for_termination) + else: + process.terminate() self.addTearDownHook(cleanup) return (process, connection) - def run_debug_session(self, connection, name): + def run_debug_session(self, connection, name, sleep_seconds_in_middle=None): self.dap_server = dap_server.DebugAdapterServer( connection=connection, ) @@ -41,6 +48,8 @@ class TestDAP_server(lldbdap_testcase.DAPTestCaseBase): args=[name], disconnectAutomatically=False, ) + if sleep_seconds_in_middle is not None: + time.sleep(sleep_seconds_in_middle) self.set_source_breakpoints(source, [breakpoint_line]) self.continue_to_next_stop() self.continue_to_exit() @@ -108,3 +117,47 @@ class TestDAP_server(lldbdap_testcase.DAPTestCaseBase): self.dap_server.exit_status, "Process exited before interrupting lldb-dap server", ) + + @skipIfWindows + def test_connection_timeout_at_server_start(self): + """ + Test launching lldb-dap in server mode with connection timeout and waiting for it to terminate automatically when no client connects. + """ + self.build() + self.start_server( + connection="listen://localhost:0", + connection_timeout=1, + wait_seconds_for_termination=5, + ) + + @skipIfWindows + def test_connection_timeout_long_debug_session(self): + """ + Test launching lldb-dap in server mode with connection timeout and terminating the server after the a long debug session. + """ + self.build() + (_, connection) = self.start_server( + connection="listen://localhost:0", + connection_timeout=1, + wait_seconds_for_termination=5, + ) + # The connection timeout should not cut off the debug session + self.run_debug_session(connection, "Alice", 1.5) + + @skipIfWindows + def test_connection_timeout_multiple_sessions(self): + """ + Test launching lldb-dap in server mode with connection timeout and terminating the server after the last debug session. + """ + self.build() + (_, connection) = self.start_server( + connection="listen://localhost:0", + connection_timeout=1, + wait_seconds_for_termination=5, + ) + time.sleep(0.5) + # Should be able to connect to the server. + self.run_debug_session(connection, "Alice") + time.sleep(0.5) + # Should be able to connect to the server, because it's still within the connection timeout. + self.run_debug_session(connection, "Bob") diff --git a/lldb/test/API/tools/lldb-dap/startDebugging/TestDAP_startDebugging.py b/lldb/test/API/tools/lldb-dap/startDebugging/TestDAP_startDebugging.py index b487257b6414..1d13bcdd4837 100644 --- a/lldb/test/API/tools/lldb-dap/startDebugging/TestDAP_startDebugging.py +++ b/lldb/test/API/tools/lldb-dap/startDebugging/TestDAP_startDebugging.py @@ -8,6 +8,7 @@ import lldbdap_testcase class TestDAP_startDebugging(lldbdap_testcase.DAPTestCaseBase): + @skipIfWindows # https://github.com/llvm/llvm-project/issues/137660 def test_startDebugging(self): """ Tests the "startDebugging" reverse request. It makes sure that the IDE can diff --git a/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py b/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py index 5c055f679aed..3a747c399566 100644 --- a/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py +++ b/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py @@ -84,6 +84,7 @@ class TestDAP_step(lldbdap_testcase.DAPTestCaseBase): # only step one thread that is at the breakpoint and stop break + @skipIfWindows def test_step_over_inlined_function(self): """ Test stepping over when the program counter is in another file. diff --git a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py index 03b79a805d34..a386afee21eb 100644 --- a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py +++ b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py @@ -102,6 +102,7 @@ class TestDAP_stepInTargets(lldbdap_testcase.DAPTestCaseBase): self.continue_to_exit() @skipIf(archs=["x86", "x86_64"]) + @skipIfWindows def test_supported_capability_other_archs(self): program = self.getBuildArtifact("a.out") self.build_and_launch(program) diff --git a/lldb/test/API/windows/launch/replace-dll/Makefile b/lldb/test/API/windows/launch/replace-dll/Makefile new file mode 100644 index 000000000000..22f1051530f8 --- /dev/null +++ b/lldb/test/API/windows/launch/replace-dll/Makefile @@ -0,0 +1 @@ +include Makefile.rules diff --git a/lldb/test/API/windows/launch/replace-dll/TestReplaceDLL.py b/lldb/test/API/windows/launch/replace-dll/TestReplaceDLL.py new file mode 100644 index 000000000000..afa97cf4afe5 --- /dev/null +++ b/lldb/test/API/windows/launch/replace-dll/TestReplaceDLL.py @@ -0,0 +1,62 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +import gc +import os + + +class ReplaceDllTestCase(TestBase): + @skipUnlessWindows + def test(self): + """ + Test that LLDB unlocks module files once all references are released. + """ + + exe = self.getBuildArtifact("a.out") + foo = self.getBuildArtifact("foo.dll") + bar = self.getBuildArtifact("bar.dll") + + self.build( + dictionary={ + "DYLIB_NAME": "foo", + "DYLIB_C_SOURCES": "foo.c", + "C_SOURCES": "test.c", + } + ) + self.build( + dictionary={ + "DYLIB_ONLY": "YES", + "DYLIB_NAME": "bar", + "DYLIB_C_SOURCES": "bar.c", + } + ) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + shlib_names = ["foo"] + environment = self.registerSharedLibrariesWithTarget(target, shlib_names) + process = target.LaunchSimple( + None, environment, self.get_process_working_directory() + ) + self.assertEqual(process.GetExitStatus(), 42) + + module = next((m for m in target.modules if "foo" in m.file.basename), None) + self.assertIsNotNone(module) + self.assertEqual(module.file.fullpath, foo) + + target.RemoveModule(module) + del module + gc.collect() + + self.dbg.MemoryPressureDetected() + + os.remove(foo) + os.rename(bar, foo) + + process = target.LaunchSimple( + None, environment, self.get_process_working_directory() + ) + self.assertEqual(process.GetExitStatus(), 43) diff --git a/lldb/test/API/windows/launch/replace-dll/bar.c b/lldb/test/API/windows/launch/replace-dll/bar.c new file mode 100644 index 000000000000..7ddde5123483 --- /dev/null +++ b/lldb/test/API/windows/launch/replace-dll/bar.c @@ -0,0 +1 @@ +__declspec(dllexport) int foo() { return 43; } diff --git a/lldb/test/API/windows/launch/replace-dll/foo.c b/lldb/test/API/windows/launch/replace-dll/foo.c new file mode 100644 index 000000000000..b971fccc6ed9 --- /dev/null +++ b/lldb/test/API/windows/launch/replace-dll/foo.c @@ -0,0 +1 @@ +__declspec(dllexport) int foo() { return 42; } diff --git a/lldb/test/API/windows/launch/replace-dll/test.c b/lldb/test/API/windows/launch/replace-dll/test.c new file mode 100644 index 000000000000..4c29f7852ae0 --- /dev/null +++ b/lldb/test/API/windows/launch/replace-dll/test.c @@ -0,0 +1,3 @@ +int foo(void); + +int main() { return foo(); } diff --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt index b786edc46cd2..39462560c4b9 100644 --- a/lldb/test/CMakeLists.txt +++ b/lldb/test/CMakeLists.txt @@ -224,6 +224,7 @@ add_lldb_test_dependency( llvm-pdbutil llvm-readobj llvm-ar + yaml2macho-core ) if(TARGET lld) diff --git a/lldb/test/Shell/Host/TestCustomShell.test b/lldb/test/Shell/Host/TestCustomShell.test index 0e948a1b1f7f..5d3e90162fb2 100644 --- a/lldb/test/Shell/Host/TestCustomShell.test +++ b/lldb/test/Shell/Host/TestCustomShell.test @@ -6,7 +6,7 @@ # XFAIL: system-openbsd # RUN: %clang_host %S/Inputs/simple.c -g -o %t.out -# RUN: SHELL=bogus not %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s --check-prefix ERROR +# RUN: env SHELL=bogus not %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s --check-prefix ERROR # RUN: env -i ASAN_OPTIONS='detect_container_overflow=0' %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s # ERROR: error: shell expansion failed diff --git a/lldb/test/Shell/Process/Optimization.test b/lldb/test/Shell/Process/Optimization.test index c189d505ef5d..d2d02a74f621 100644 --- a/lldb/test/Shell/Process/Optimization.test +++ b/lldb/test/Shell/Process/Optimization.test @@ -1,5 +1,5 @@ Test warnings. -REQUIRES: shell, system-darwin +REQUIRES: system-darwin RUN: %clang_host -O3 %S/Inputs/true.c -std=c99 -g -o %t.exe RUN: %lldb -o "b main" -o r -o q -b %t.exe 2>&1 | FileCheck %s diff --git a/lldb/test/Shell/Process/UnsupportedLanguage.test b/lldb/test/Shell/Process/UnsupportedLanguage.test index d7e6e5de7751..ec5d1bd9bace 100644 --- a/lldb/test/Shell/Process/UnsupportedLanguage.test +++ b/lldb/test/Shell/Process/UnsupportedLanguage.test @@ -1,6 +1,9 @@ Test unsupported language warning -REQUIRES: shell +TODO: This test does not work on Windows, seemingly because the sed commands +are not actually doing anything. This should be fixed so we can enable this on +Windows. +UNSUPPORTED: system-windows RUN: %clang_host %S/Inputs/true.c -std=c99 -g -c -S -emit-llvm -o - \ RUN: | sed -e 's/DW_LANG_C99/DW_LANG_Mips_Assembler/g' >%t.ll diff --git a/lldb/test/Shell/Recognizer/ubsan_add_overflow.test b/lldb/test/Shell/Recognizer/ubsan_add_overflow.test index a5e95cf5a898..872b5a7a4d58 100644 --- a/lldb/test/Shell/Recognizer/ubsan_add_overflow.test +++ b/lldb/test/Shell/Recognizer/ubsan_add_overflow.test @@ -6,11 +6,11 @@ # RUN: %lldb -b -s %s %t.out | FileCheck %s run -# CHECK: thread #{{.*}} stop reason = Undefined Behavior Sanitizer: Integer addition overflowed +# CHECK: thread #{{.*}} stop reason = Undefined Behavior Sanitizer: signed integer addition overflow in '2147483647 + 1' # CHECK-NEXT: frame #1: {{.*}}`main at ubsan_add_overflow.c bt -# CHECK: frame #0: {{.*}}`__clang_trap_msg$Undefined Behavior Sanitizer$Integer addition overflowed{{.*}} +# CHECK: frame #0: {{.*}}`__clang_trap_msg$Undefined Behavior Sanitizer$signed integer addition overflow in '2147483647 + 1'{{.*}} # CHECK: frame #1: {{.*}}`main at ubsan_add_overflow.c frame info diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test index 9c0510c34cca..f680158fdf73 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test @@ -11,7 +11,7 @@ # CHECK: (lldb) process status --verbose # CHECK-NEXT: Process 96535 stopped # CHECK-NEXT: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0) -# CHECK-NEXT: frame #0: 0x00000001a08c7224{{.*}}[artificial] +# CHECK-NEXT: frame #0: 0x00000001a08c7224{{.*}}[synthetic] # CHECK: Extended Crash Information: # CHECK: Application Specific Information: # CHECK-NEXT: CoreFoundation: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** __boundsFail: index 10 beyond bounds [0 .. 3]' @@ -21,21 +21,21 @@ # CHECK: (lldb) thread backtrace --extended true # CHECK: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0) -# CHECK-NEXT: * frame #0: 0x00000001a08c7224{{.*}}[artificial] -# CHECK-NEXT: frame #1: 0x00000001a08fdceb{{.*}}[artificial] -# CHECK-NEXT: frame #2: 0x00000001a08372c7{{.*}}[artificial] -# CHECK-NEXT: frame #3: 0x00000001a08b7b17{{.*}}[artificial] -# CHECK-NEXT: frame #4: 0x00000001a08a7a0b{{.*}}[artificial] -# CHECK-NEXT: frame #5: 0x00000001a05ab763{{.*}}[artificial] -# CHECK-NEXT: frame #6: 0x00000001a08b6eb3{{.*}}[artificial] -# CHECK-NEXT: frame #7: 0x00000001a08b9c2b{{.*}}[artificial] -# CHECK-NEXT: frame #8: 0x00000001a08b9bd7{{.*}}[artificial] -# CHECK-NEXT: frame #9: 0x00000001a05a3007{{.*}}[artificial] -# CHECK-NEXT: frame #10: 0x00000001a0b3dcc3{{.*}}[artificial] -# CHECK-NEXT: frame #11: 0x00000001a0b46af3{{.*}}[artificial] -# CHECK-NEXT: frame #12: 0x00000001a09a12a3{{.*}}[artificial] -# CHECK-NEXT: frame #13: 0x00000001047e3ecf asi`main{{.*}}[artificial] -# CHECK-NEXT: frame #14: 0x00000001a05d3e4f{{.*}}[artificial] +# CHECK-NEXT: * frame #0: 0x00000001a08c7224{{.*}}[synthetic] +# CHECK-NEXT: frame #1: 0x00000001a08fdceb{{.*}}[synthetic] +# CHECK-NEXT: frame #2: 0x00000001a08372c7{{.*}}[synthetic] +# CHECK-NEXT: frame #3: 0x00000001a08b7b17{{.*}}[synthetic] +# CHECK-NEXT: frame #4: 0x00000001a08a7a0b{{.*}}[synthetic] +# CHECK-NEXT: frame #5: 0x00000001a05ab763{{.*}}[synthetic] +# CHECK-NEXT: frame #6: 0x00000001a08b6eb3{{.*}}[synthetic] +# CHECK-NEXT: frame #7: 0x00000001a08b9c2b{{.*}}[synthetic] +# CHECK-NEXT: frame #8: 0x00000001a08b9bd7{{.*}}[synthetic] +# CHECK-NEXT: frame #9: 0x00000001a05a3007{{.*}}[synthetic] +# CHECK-NEXT: frame #10: 0x00000001a0b3dcc3{{.*}}[synthetic] +# CHECK-NEXT: frame #11: 0x00000001a0b46af3{{.*}}[synthetic] +# CHECK-NEXT: frame #12: 0x00000001a09a12a3{{.*}}[synthetic] +# CHECK-NEXT: frame #13: 0x00000001047e3ecf asi`main{{.*}}[synthetic] +# CHECK-NEXT: frame #14: 0x00000001a05d3e4f{{.*}}[synthetic] # CHECK: thread #4294967295: tid = 0x0001, 0x00000001a0a58418{{.*}}, queue = 'Application Specific Backtrace' # CHECK-NEXT: frame #0: 0x00000001a0a58418{{.*}} diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_arm64_register.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_arm64_register.test index 3f572c3300c0..9da21d9aab78 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_arm64_register.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_arm64_register.test @@ -15,9 +15,9 @@ # CHECK: (lldb) thread backtrace # CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] # CHECK: (lldb) thread list # CHECK-NEXT: Process 22511 stopped @@ -27,20 +27,20 @@ # CHECK: (lldb) bt all # CHECK: thread #1, queue = 'com.apple.main-thread' -# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [artificial] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [synthetic] # CHECK-NEXT: thread #2 -# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK-NEXT:* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK: (lldb) register read # CHECK: General Purpose Registers: diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_json.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_json.test index 684be2846f78..2509f2e88d9b 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_json.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_json.test @@ -15,9 +15,9 @@ # CHECK: (lldb) thread backtrace # CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] # CHECK: (lldb) thread list # CHECK-NEXT: Process 22511 stopped @@ -27,17 +27,17 @@ # CHECK: (lldb) bt all # CHECK: thread #1, queue = 'com.apple.main-thread' -# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [artificial] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [synthetic] # CHECK-NEXT: thread #2 -# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK-NEXT:* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test index 271a4c2aa90f..74ced35fcfae 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/interactive_crashlog_legacy.test @@ -15,9 +15,9 @@ # CHECK: (lldb) thread backtrace # CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] # CHECK: (lldb) thread list # CHECK-NEXT: Process 22511 stopped @@ -27,17 +27,17 @@ # CHECK: (lldb) bt all # CHECK: thread #1 -# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [artificial] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [synthetic] # CHECK-NEXT: thread #2 -# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK-NEXT:* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/last_exception_backtrace_crashlog.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/last_exception_backtrace_crashlog.test index a17b7ac18a62..53c0732deb54 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/last_exception_backtrace_crashlog.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/last_exception_backtrace_crashlog.test @@ -11,7 +11,7 @@ # CHECK: (lldb) process status --verbose # CHECK-NEXT: Process 96535 stopped # CHECK-NEXT: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0) -# CHECK-NEXT: frame #0: 0x00000001a08c7224{{.*}}[artificial] +# CHECK-NEXT: frame #0: 0x00000001a08c7224{{.*}}[synthetic] # CHECK: Extended Crash Information: # CHECK: Application Specific Information: # CHECK-NEXT: CoreFoundation: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** __boundsFail: index 10 beyond bounds [0 .. 3]' @@ -21,21 +21,21 @@ # CHECK: (lldb) thread backtrace --extended true # CHECK: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0) -# CHECK-NEXT: * frame #0: 0x00000001a08c7224{{.*}}[artificial] -# CHECK-NEXT: frame #1: 0x00000001a08fdceb{{.*}}[artificial] -# CHECK-NEXT: frame #2: 0x00000001a08372c7{{.*}}[artificial] -# CHECK-NEXT: frame #3: 0x00000001a08b7b17{{.*}}[artificial] -# CHECK-NEXT: frame #4: 0x00000001a08a7a0b{{.*}}[artificial] -# CHECK-NEXT: frame #5: 0x00000001a05ab763{{.*}}[artificial] -# CHECK-NEXT: frame #6: 0x00000001a08b6eb3{{.*}}[artificial] -# CHECK-NEXT: frame #7: 0x00000001a08b9c2b{{.*}}[artificial] -# CHECK-NEXT: frame #8: 0x00000001a08b9bd7{{.*}}[artificial] -# CHECK-NEXT: frame #9: 0x00000001a05a3007{{.*}}[artificial] -# CHECK-NEXT: frame #10: 0x00000001a0b3dcc3{{.*}}[artificial] -# CHECK-NEXT: frame #11: 0x00000001a0b46af3{{.*}}[artificial] -# CHECK-NEXT: frame #12: 0x00000001a09a12a3{{.*}}[artificial] -# CHECK-NEXT: frame #13: 0x00000001047e3ecf asi`main{{.*}}[artificial] -# CHECK-NEXT: frame #14: 0x00000001a05d3e4f{{.*}}[artificial] +# CHECK-NEXT: * frame #0: 0x00000001a08c7224{{.*}}[synthetic] +# CHECK-NEXT: frame #1: 0x00000001a08fdceb{{.*}}[synthetic] +# CHECK-NEXT: frame #2: 0x00000001a08372c7{{.*}}[synthetic] +# CHECK-NEXT: frame #3: 0x00000001a08b7b17{{.*}}[synthetic] +# CHECK-NEXT: frame #4: 0x00000001a08a7a0b{{.*}}[synthetic] +# CHECK-NEXT: frame #5: 0x00000001a05ab763{{.*}}[synthetic] +# CHECK-NEXT: frame #6: 0x00000001a08b6eb3{{.*}}[synthetic] +# CHECK-NEXT: frame #7: 0x00000001a08b9c2b{{.*}}[synthetic] +# CHECK-NEXT: frame #8: 0x00000001a08b9bd7{{.*}}[synthetic] +# CHECK-NEXT: frame #9: 0x00000001a05a3007{{.*}}[synthetic] +# CHECK-NEXT: frame #10: 0x00000001a0b3dcc3{{.*}}[synthetic] +# CHECK-NEXT: frame #11: 0x00000001a0b46af3{{.*}}[synthetic] +# CHECK-NEXT: frame #12: 0x00000001a09a12a3{{.*}}[synthetic] +# CHECK-NEXT: frame #13: 0x00000001047e3ecf asi`main{{.*}}[synthetic] +# CHECK-NEXT: frame #14: 0x00000001a05d3e4f{{.*}}[synthetic] # CHECK: thread #4294967295: tid = 0x0001, 0x00000001a0a5840c{{.*}}, queue = 'Application Specific Backtrace' # CHECK-NEXT: frame #0: 0x00000001a0a5840c{{.*}} diff --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test index 52a185b8cf76..138cd2bdffc4 100644 --- a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test +++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test @@ -15,9 +15,9 @@ process status thread backtrace # CHECK: * thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] thread list # CHECK: Process 22511 stopped @@ -27,20 +27,20 @@ thread list bt all # CHECK: thread #1, queue = 'com.apple.main-thread' -# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [artificial] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc40b84{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5b3b multithread-test`main{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x00000002230f8da7{{.*}} [synthetic] # CHECK-NEXT: thread #2 -# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: frame #0: 0x000000019cc42c9c{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x0000000100ec5957 multithread-test`call_and_wait{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] # CHECK-NEXT:* thread #3, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) -# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [artificial] -# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [artificial] -# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial] -# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial] +# CHECK-NEXT: * frame #0: 0x0000000100ec58f4 multithread-test`bar{{.*}} [synthetic] +# CHECK-NEXT: frame #1: 0x0000000100ec591b multithread-test`foo{{.*}} [synthetic] +# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [synthetic] +# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [synthetic] image list # CHECK: 11111111-2222-3333-4444-555555555555 {{.*}}bogus.dylib diff --git a/lldb/test/Shell/Settings/TestFrameFormatFunctionReturnObjC.test b/lldb/test/Shell/Settings/TestFrameFormatFunctionReturnObjC.test index 2692c3d9c3e7..55487235ae8c 100644 --- a/lldb/test/Shell/Settings/TestFrameFormatFunctionReturnObjC.test +++ b/lldb/test/Shell/Settings/TestFrameFormatFunctionReturnObjC.test @@ -2,8 +2,11 @@ # ${function.return-right} in languages that don't implement this frame # format variable (in this case Objective-C). # +# link.exe will discard DWARF information. +# REQUIRES: (system-windows && lld) || !system-windows +# # RUN: split-file %s %t -# RUN: %clang_host -g -gdwarf %t/main.m -o %t.objc.out +# RUN: %clang_host -g -gdwarf %t/main.m -o %t.objc.out %if system-windows %{-fuse-ld=lld%} # RUN: %lldb -x -b -s %t/commands.input %t.objc.out -o exit 2>&1 \ # RUN: | FileCheck %s diff --git a/lldb/test/Shell/SymbolFile/DWARF/deterministic-build.cpp b/lldb/test/Shell/SymbolFile/DWARF/deterministic-build.cpp index 9e79f23db2b7..0c86107fc963 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/deterministic-build.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/deterministic-build.cpp @@ -3,9 +3,8 @@ // requires the ld64 linker, which clang invokes by default. // REQUIRES: system-darwin // RUN: %clang_host %s -g -c -o %t.o -// RUN: ZERO_AR_DATE=1 %clang_host %t.o -g -o %t -// RUN: %lldb %t -o "breakpoint set -f %s -l 11" -o run -o exit | FileCheck %s +// RUN: env ZERO_AR_DATE=1 %clang_host %t.o -g -o %t +// RUN: %lldb %t -o "breakpoint set -f %s -l 10" -o run -o exit | FileCheck %s // CHECK: stop reason = breakpoint - int main() { return 0; } diff --git a/lldb/test/Shell/SymbolFile/DWARF/dwo-missing-error.test b/lldb/test/Shell/SymbolFile/DWARF/dwo-missing-error.test index 2805bbb5df7d..72315e828474 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/dwo-missing-error.test +++ b/lldb/test/Shell/SymbolFile/DWARF/dwo-missing-error.test @@ -11,12 +11,12 @@ # "a.out-dwo-missing-error.dwo". # RUN: rm -rf %t.compdir/ # RUN: mkdir -p %t.compdir/a/b/ -# RUN: cd %t.compdir/a/b/ +# RUN: pushd %t.compdir/a/b/ # RUN: %clang_host %S/Inputs/dwo-missing-error.c -glldb -gdwarf-5 \ # RUN: -gsplit-dwarf -fdebug-prefix-map=%t.compdir=. -o a.out # RUN: rm *.dwo # RUN: %lldb a.out -s %s -o exit 2>&1 | FileCheck %s -# RUN: cd - +# RUN: popd # Test the error message with an absolute DW_AT_comp_dir and DW_AT_dwo_name. # RUN: rm -rf %t.compdir/ diff --git a/lldb/test/Shell/SymbolFile/DWARF/dwo-static-data-member-access.test b/lldb/test/Shell/SymbolFile/DWARF/dwo-static-data-member-access.test index 6e4deae7b9a0..40d5e90097eb 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/dwo-static-data-member-access.test +++ b/lldb/test/Shell/SymbolFile/DWARF/dwo-static-data-member-access.test @@ -4,6 +4,9 @@ # a DW_TAG_variable DIE, whose parent DIE is only # a forward declaration. +# UNSUPPORTED: system-darwin +# UNSUPPORTED: system-windows + # RUN: %clangxx_host %S/Inputs/dwo-static-data-member.cpp \ # RUN: -g -gdwarf-5 -gsplit-dwarf -flimit-debug-info -o %t # RUN: %lldb %t -s %s -o exit 2>&1 | FileCheck %s diff --git a/lldb/test/Shell/SymbolFile/DWARF/objcxx-forward-decls.test b/lldb/test/Shell/SymbolFile/DWARF/objcxx-forward-decls.test new file mode 100644 index 000000000000..30109c2943c9 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/objcxx-forward-decls.test @@ -0,0 +1,70 @@ +# REQUIRES: system-darwin + +# In this test we have two CUs with conflicting forward declaration +# depending on the CU language (one is C++ and the other is Objective-C++). +# We are then stopped in the C++ CU and try to print the type, at which +# point LLDB will try to make it into an Clang AST node. If LLDB were to +# interpret the type as C++ instead of Objective-C, we'd violate Clang +# invariants and crash. +# +# RUN: split-file %s %t +# RUN: %clangxx_host -c -g -x objective-c++ %t/request.m -o %t/request_objc.o +# RUN: %clangxx_host -c -g %t/main.cpp -o %t/main.o +# RUN: %clangxx_host %t/main.o %t/request_objc.o -framework Foundation -o %t/a.out +# +# RUN: %lldb %t/a.out \ +# RUN: -o "breakpoint set -p return -X main" \ +# RUN: -o run \ +# RUN: -o "frame variable r" \ +# RUN: -o exit | FileCheck %s +# +# RUN: dsymutil %t/a.out +# +# RUN: %lldb %t/a.out \ +# RUN: -o "breakpoint set -p return -X main" \ +# RUN: -o run \ +# RUN: -o "frame variable r" \ +# RUN: -o exit | FileCheck %s --check-prefix=CHECK-DSYM + +# CHECK: (lldb) frame variable r +# CHECK-NEXT: (Request) ::r = (m_request = "Hello, World!") + +# CHECK-DSYM: (lldb) frame variable r +# CHECK-DSYM-NEXT: (Request) ::r = (m_request = "Hello, World!") + +#--- lib.h +#ifndef LIB_H_IN +#define LIB_H_IN + +#ifdef __OBJC__ +@class NSString; +#else +class NSString; +#endif + +struct Request { + NSString * m_request = nullptr; +}; + +#endif // _H_IN + +#--- main.cpp +#include "lib.h" + +void process(Request *); + +Request r; + +int main() { + process(&r); + return 0; +} + +#--- request.m +#import <Foundation/Foundation.h> + +#include "lib.h" + +void process(Request * r) { + r->m_request = @"Hello, World!"; +} diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp index c93033890544..d08f49d1014b 100644 --- a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp +++ b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp @@ -13,3 +13,8 @@ struct E { E(); }; E::E() = default; + +struct I { + I(); +}; +I::I() = default; diff --git a/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.cpp b/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.cpp deleted file mode 100644 index 7bc7e618667f..000000000000 --- a/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// clang-format off -// REQUIRES: lld, x86 - -// RUN: %clang_cl --target=x86_64-windows-msvc -c /Fo%t1.obj -- %p/Inputs/incomplete-tag-type.cpp -// RUN: %clang_cl --target=x86_64-windows-msvc /O1 /Z7 -c /Fo%t2.obj -- %s -// RUN: lld-link /debug:full /nodefaultlib /entry:main %t1.obj %t2.obj /out:%t.exe /pdb:%t.pdb -// RUN: %lldb -f %t.exe -o \ -// RUN: "settings set interpreter.stop-command-source-on-error false" \ -// RUN: -o "expression b" -o "expression d" -o "expression static_e_ref" -o "exit" 2>&1 | FileCheck %s - -// CHECK: (lldb) expression b -// CHECK: (B) $0 = {} -// CHECK: (lldb) expression d -// CHECK: (D) $1 = {} -// CHECK: (lldb) expression static_e_ref -// CHECK: error:{{.*}}incomplete type 'E' where a complete type is required - -// Complete base class. -struct A { int x; A(); }; -struct B : A {}; -B b; - -// Complete data member. -struct C { - C(); -}; - -struct D { - C c; -}; -D d; - -// Incomplete static data member should return error. -struct E { - E(); -}; - -struct F { - static E static_e; -}; - -E F::static_e = E(); -E& static_e_ref = F::static_e; - -int main(){} diff --git a/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.test b/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.test new file mode 100644 index 000000000000..f30866ccdd6f --- /dev/null +++ b/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.test @@ -0,0 +1,109 @@ +# REQUIRES: lld, x86 + +# RUN: split-file %s %t + +# RUN: %clang_cl --target=x86_64-windows-msvc -c /Fo%t1.obj -- %p/Inputs/incomplete-tag-type.cpp +# RUN: %clang_cl --target=x86_64-windows-msvc /O1 /Z7 -c /Fo%t2.obj -- %t/main.cpp +# RUN: lld-link /debug:full /nodefaultlib /entry:main %t1.obj %t2.obj /out:%t.exe /pdb:%t.pdb + +# RUN: %lldb -f %t.exe -s %t/target-var.input 2>&1 | FileCheck %s --check-prefix=TARGET-VAR +# RUN: %lldb -f %t.exe -s %t/expr.input 2>&1 | FileCheck %s --check-prefix=EXPR + +#--- main.cpp + +// Complete base class. +struct A { int x; A(); }; +struct B : A {}; +B b; + +// Complete data member. +struct C { + C(); +}; + +struct D { + C c; +}; +D d; + +// Incomplete static data member should return error. +struct E { + E(); +}; + +struct F { + static E static_e; +}; + +E F::static_e = E(); +E& static_e_ref = F::static_e; + +struct G { + int foo = 1; +}; +struct H { + G g[2]; +}; +H h; + +struct I { + I(); +}; +struct J { + I i[2]; +}; +J j; + + +int main(){} + +#--- target-var.input + +target variable b +target variable d +target variable h +target variable j +target variable static_e_ref +exit + +#--- expr.input + +settings set interpreter.stop-command-source-on-error false +expression b +expression d +expression h +expression j +expression static_e_ref +exit + +# TARGET-VAR: (lldb) target variable b +# TARGET-VAR-NEXT: (B) b = (A = <incomplete type>) +# TARGET-VAR-NEXT: (lldb) target variable d +# TARGET-VAR-NEXT: (D) d = {} +# TARGET-VAR-NEXT: (lldb) target variable h +# TARGET-VAR-NEXT: (H) h = { +# TARGET-VAR-NEXT: g = { +# TARGET-VAR-NEXT: [0] = (foo = 1) +# TARGET-VAR-NEXT: [1] = (foo = 1) +# TARGET-VAR-NEXT: } +# TARGET-VAR-NEXT: } +# TARGET-VAR-NEXT: (lldb) target variable j +# TARGET-VAR-NEXT: (J) j = {} +# TARGET-VAR-NEXT: (lldb) target variable static_e_ref +# TARGET-VAR-NEXT: (E &) static_e_ref = 0x{{.*}} <incomplete type "E"> + +# EXPR: (lldb) expression b +# EXPR-NEXT: (B) $0 = {} +# EXPR-NEXT: (lldb) expression d +# EXPR-NEXT: (D) $1 = {} +# EXPR-NEXT: (lldb) expression h +# EXPR-NEXT: (H) $2 = { +# EXPR-NEXT: g = { +# EXPR-NEXT: [0] = (foo = 1) +# EXPR-NEXT: [1] = (foo = 1) +# EXPR-NEXT: } +# EXPR-NEXT: } +# EXPR-NEXT: (lldb) expression j +# EXPR-NEXT: (J) $3 = {} +# EXPR-NEXT: (lldb) expression static_e_ref +# EXPR: error:{{.*}}incomplete type 'E' where a complete type is required diff --git a/lldb/test/Shell/SymbolFile/PDB/expressions.test b/lldb/test/Shell/SymbolFile/PDB/expressions.test index 1932be74ca87..33b02e2d6796 100644 --- a/lldb/test/Shell/SymbolFile/PDB/expressions.test +++ b/lldb/test/Shell/SymbolFile/PDB/expressions.test @@ -1,6 +1,7 @@ REQUIRES: target-windows, msvc RUN: %build --compiler=msvc --nodefaultlib --output=%t.exe %S/Inputs/ExpressionsTest.cpp -RUN: not %lldb -b -s %S/Inputs/ExpressionsTest0.script -s %S/Inputs/ExpressionsTest1.script -s %S/Inputs/ExpressionsTest2.script -- %t.exe 2>&1 | FileCheck %s +RUN: env LLDB_USE_NATIVE_PDB_READER=0 not %lldb -b -s %S/Inputs/ExpressionsTest0.script -s %S/Inputs/ExpressionsTest1.script -s %S/Inputs/ExpressionsTest2.script -- %t.exe 2>&1 | FileCheck %s +RUN: env LLDB_USE_NATIVE_PDB_READER=1 not %lldb -b -s %S/Inputs/ExpressionsTest0.script -s %S/Inputs/ExpressionsTest1.script -s %S/Inputs/ExpressionsTest2.script -- %t.exe 2>&1 | FileCheck %s // Check the variable value through `expression` CHECK: (lldb) expression result diff --git a/lldb/test/Shell/SymbolFile/PDB/variables.test b/lldb/test/Shell/SymbolFile/PDB/variables.test index 9ee10f75c7e3..970d714c29c3 100644 --- a/lldb/test/Shell/SymbolFile/PDB/variables.test +++ b/lldb/test/Shell/SymbolFile/PDB/variables.test @@ -2,15 +2,27 @@ REQUIRES: system-windows, msvc RUN: mkdir -p %t.dir RUN: %build --compiler=clang-cl --mode=compile --arch=64 --nodefaultlib --output=%t.dir/VariablesTest.cpp.obj %S/Inputs/VariablesTest.cpp RUN: %build --compiler=msvc --mode=link --arch=64 --nodefaultlib --output=%t.dir/VariablesTest.cpp.exe %t.dir/VariablesTest.cpp.obj -RUN: lldb-test symbols %t.dir/VariablesTest.cpp.exe > %t.dir/VariablesTest.out -RUN: FileCheck --check-prefix=GLOBALS --input-file=%t.dir/VariablesTest.out %s -RUN: FileCheck --check-prefix=FUNC-F --input-file=%t.dir/VariablesTest.out %s -RUN: FileCheck --check-prefix=FUNC-MAIN --input-file=%t.dir/VariablesTest.out %s -RUN: FileCheck --check-prefix=FUNC-CONSTRUCTOR --input-file=%t.dir/VariablesTest.out %s -RUN: FileCheck --check-prefix=FUNC-MEMBER --input-file=%t.dir/VariablesTest.out %s +# Note: The native plugin creates a location list for variables that's only valid for the function. +# The DIA plugin creates a location expression that's always valid. This causes DIA to output +# one line per variable where the native plugin would output two (the second would contain the +# location information). This removes the second line from the output of the native plugin. +# It's done in both cases, because LLDB might not be compiled with the DIA SDK in which case +# the native plugin is always used. +RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symbols %t.dir/VariablesTest.cpp.exe | sed '/^ \+\[0x/d' > %t.dir/VariablesTest.DIA.out +RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols %t.dir/VariablesTest.cpp.exe | sed '/^ \+\[0x/d' > %t.dir/VariablesTest.Native.out +RUN: FileCheck --check-prefix=GLOBALS --input-file=%t.dir/VariablesTest.DIA.out %s +RUN: FileCheck --check-prefix=GLOBALS --input-file=%t.dir/VariablesTest.Native.out %s +RUN: FileCheck --check-prefix=FUNC-F --input-file=%t.dir/VariablesTest.DIA.out %s +RUN: FileCheck --check-prefix=FUNC-F --input-file=%t.dir/VariablesTest.Native.out %s +RUN: FileCheck --check-prefix=FUNC-MAIN --input-file=%t.dir/VariablesTest.DIA.out %s +RUN: FileCheck --check-prefix=FUNC-MAIN --input-file=%t.dir/VariablesTest.Native.out %s +RUN: FileCheck --check-prefix=FUNC-CONSTRUCTOR --input-file=%t.dir/VariablesTest.DIA.out %s +RUN: FileCheck --check-prefix=FUNC-CONSTRUCTOR --input-file=%t.dir/VariablesTest.Native.out %s +RUN: FileCheck --check-prefix=FUNC-MEMBER --input-file=%t.dir/VariablesTest.DIA.out %s +RUN: FileCheck --check-prefix=FUNC-MEMBER --input-file=%t.dir/VariablesTest.Native.out %s GLOBALS: Module [[MOD:.*]] -GLOBALS: SymbolFile pdb ([[MOD]]) +GLOBALS: SymbolFile {{(native-)?}}pdb ([[MOD]]) GLOBALS: CompileUnit{{.*}}, language = "c++", file = '{{.*}}\VariablesTest.cpp' GLOBALS-DAG: Variable{{.*}}, name = "g_IntVar" GLOBALS-SAME: scope = global, location = {{.*}}, external @@ -30,7 +42,7 @@ GLOBALS-DAG: Variable{{.*}}, name = "g_Const" GLOBALS-SAME: scope = ??? (2) GLOBALS: Function -FUNC-F: Function{{.*}}, mangled = ?f@@YAHHH@Z +FUNC-F: Function{{.*}}, {{mangled = \?f@@YAHHH@Z|demangled = f}} FUNC-F-NEXT: Block FUNC-F-NEXT: Variable{{.*}}, name = "var_arg1" FUNC-F-SAME: scope = parameter @@ -39,7 +51,7 @@ FUNC-F-SAME: scope = parameter FUNC-F-NEXT: Variable{{.*}}, name = "same_name_var" FUNC-F-SAME: scope = local -FUNC-MAIN: Function{{.*}}, mangled = main +FUNC-MAIN: Function{{.*}}, {{(de)?}}mangled = main FUNC-MAIN-NEXT: Block FUNC-MAIN-NEXT: Variable{{.*}}, name = "same_name_var" FUNC-MAIN-SAME: scope = local @@ -52,11 +64,10 @@ FUNC-MAIN-SAME: scope = local FUNC-MAIN-NEXT: Variable{{.*}}, name = "a" FUNC-MAIN-SAME: scope = local -FUNC-CONSTRUCTOR: Function{{.*}}, {{(de)?}}mangled = {{.*}}{{(Class::)?}}Class{{.*}} +FUNC-CONSTRUCTOR: Function{{.*}}, {{(de)?}}mangled = {{.*}}Class::Class{{.*}} FUNC-CONSTRUCTOR-NEXT: Block FUNC-CONSTRUCTOR-NEXT: Variable{{.*}}, name = "this" FUNC-CONSTRUCTOR-SAME: scope = parameter -FUNC-CONSTRUCTOR-SAME: artificial FUNC-CONSTRUCTOR-NEXT: Variable{{.*}}, name = "a" FUNC-CONSTRUCTOR-SAME: scope = parameter @@ -64,4 +75,3 @@ FUNC-MEMBER: Function{{.*}}, {{(de)?}}mangled = {{.*}}{{(Class::)?}}Func{{. FUNC-MEMBER-NEXT: Block FUNC-MEMBER-NEXT: Variable{{.*}}, name = "this" FUNC-MEMBER-SAME: scope = parameter -FUNC-MEMBER-SAME: artificial diff --git a/lldb/test/Shell/SymbolFile/add-dsym.test b/lldb/test/Shell/SymbolFile/add-dsym.test index 52d1a1363fee..9695ddc297aa 100644 --- a/lldb/test/Shell/SymbolFile/add-dsym.test +++ b/lldb/test/Shell/SymbolFile/add-dsym.test @@ -4,5 +4,5 @@ # HELP: Syntax: add-dsym <cmd-options> <filename> # RUN: yaml2obj %S/Inputs/a.yaml -o %t.out -# RUN: LLDB_APPLE_DSYMFORUUID_EXECUTABLE=%S/Inputs/dsymforuuid.sh %lldb %t.out -o 'add-dsym -u 41945CA4-5D9D-3CDE-82B4-37E4C09750B5' 2>&1 | FileCheck %s +# RUN: env LLDB_APPLE_DSYMFORUUID_EXECUTABLE=%S/Inputs/dsymforuuid.sh %lldb %t.out -o 'add-dsym -u 41945CA4-5D9D-3CDE-82B4-37E4C09750B5' 2>&1 | FileCheck %s # CHECK: UUID information was not found diff --git a/lldb/test/Shell/Symtab/symtab-wasm.test b/lldb/test/Shell/Symtab/symtab-wasm.test index 4170d9aba9ee..524691b89732 100644 --- a/lldb/test/Shell/Symtab/symtab-wasm.test +++ b/lldb/test/Shell/Symtab/symtab-wasm.test @@ -1,15 +1,16 @@ # RUN: yaml2obj %S/Inputs/simple.wasm.yaml -o %t.wasm -# RUN: %lldb %t.wasm -o 'image dump symtab' -o 'image dump sections' | FileCheck %s -CHECK: Code 0x0000000000000002 0x0000000000000002 0x00000000 __wasm_call_ctors -CHECK: Code 0x0000000000000005 0x0000000000000029 0x00000000 add -CHECK: Code 0x000000000000002f 0x000000000000004c 0x00000000 __original_main -CHECK: Code 0x000000000000007c 0x0000000000000009 0x00000000 main -CHECK: Data 0x0000000000000233 0x0000000000000009 0x00000000 .rodata -CHECK: Data 0x0000000000000242 0x0000000000000004 0x00000000 .data +# RUN: %lldb %t.wasm -o 'image dump symtab' | FileCheck %s --check-prefix SYMTAB +SYMTAB: Code 0x0000000000000002 0x0000000000000002 0x00000000 __wasm_call_ctors +SYMTAB: Code 0x0000000000000005 0x0000000000000029 0x00000000 add +SYMTAB: Code 0x000000000000002f 0x000000000000004c 0x00000000 __original_main +SYMTAB: Code 0x000000000000007c 0x0000000000000009 0x00000000 main -CHECK: 0x0000000000000001 code {{.*}} 0x000001a1 0x00000085 0x00000000 symtab-wasm.test.tmp.wasm.code -CHECK: 0x0000000000000003 data {{.*}} 0x0000022c 0x0000001a 0x00000000 symtab-wasm.test.tmp.wasm.data -CHECK: 0x0000000000000040 wasm-name {{.*}} 0x00000251 0x00000059 0x00000000 symtab-wasm.test.tmp.wasm.name -CHECK: 0x0000000000000100 data {{.*}} 0x00000233 0x00000009 0x00000000 symtab-wasm.test.tmp.wasm.data..rodata -CHECK: 0x0000000000000200 data {{.*}} 0x00000242 0x00000004 0x00000000 symtab-wasm.test.tmp.wasm.data..data +# RUN: %lldb %t.wasm -o 'image dump sections' | FileCheck %s --check-prefix SECTIONS +SECTIONS: 0x0000000000000001 code [0x0000000000000000-0x0000000000000085) --- 0x000001a1 0x00000085 0x00000000 symtab-wasm.test.tmp.wasm.code +SECTIONS: 0x0000000000000040 wasm-name --- 0x00000251 0x00000059 0x00000000 symtab-wasm.test.tmp.wasm.name +SECTIONS: 0x0000000000000100 data [0x0000000000000400-0x0000000000000409) --- 0x00000233 0x00000009 0x00000000 symtab-wasm.test.tmp.wasm..rodata +SECTIONS: 0x0000000000000200 data [0x000000000000040c-0x0000000000000410) --- 0x00000242 0x00000004 0x00000000 symtab-wasm.test.tmp.wasm..data + +# RUN: %lldb %t.wasm -o 'x/s 0x0000000000000400' | FileCheck %s --check-prefix STR +STR: "data str" diff --git a/lldb/test/Shell/lit.cfg.py b/lldb/test/Shell/lit.cfg.py index cfa5506e4864..46e2117cdb8e 100644 --- a/lldb/test/Shell/lit.cfg.py +++ b/lldb/test/Shell/lit.cfg.py @@ -21,7 +21,15 @@ from helper import toolchain config.name = "lldb-shell" # testFormat: The test format to use to interpret tests. -config.test_format = toolchain.ShTestLldb(not llvm_config.use_lit_shell) +# We prefer the lit internal shell which provides a better user experience on +# failures and is faster unless the user explicitly disables it with +# LIT_USE_INTERNAL_SHELL=0 env var. +use_lit_shell = True +lit_shell_env = os.environ.get("LIT_USE_INTERNAL_SHELL") +if lit_shell_env: + use_lit_shell = lit.util.pythonize_bool(lit_shell_env) + +config.test_format = toolchain.ShTestLldb(not use_lit_shell) # suffixes: A list of file extensions to treat as test files. This is overriden # by individual lit.local.cfg files in the test subdirectories. |
