36 lines · python
1import lldb2from lldbsuite.test.decorators import *3from lldbsuite.test.lldbtest import *4from lldbsuite.test import lldbutil5 6 7@skipUnlessDarwin8@skipIf(archs=no_match(["arm64"]))9class TestArmPointerMetadataStripping(TestBase):10 def test(self):11 self.build()12 target, process, thread, bkpt = lldbutil.run_to_name_breakpoint(self, "foo")13 14 # Step over the first two instructions of foo in order to15 # toggle the bit of fp and save it on the stack:16 # orr x29, x29, #0x100000000000000017 # stp x29, x30, [sp, #-16]!18 # This is effectively adding metadata to the CFA of the caller frame (main).19 thread.StepInstruction(False)20 thread.StepInstruction(False)21 22 # The location of `argv` has been artificially made equal to the CFA of the frame.23 # As such, it should have the metadata artificially set previously.24 argv_addr = thread.frames[1].GetValueForVariablePath("&argv")25 self.assertTrue(argv_addr.IsValid())26 argv_addr_uint = argv_addr.GetValueAsUnsigned()27 self.assertNotEqual((argv_addr_uint & (1 << 60)), 0)28 29 # GetCFA strips metadata.30 cfa = thread.frames[1].GetCFA()31 self.assertEqual((cfa & (1 << 60)), 0)32 33 # If the test worked correctly, the cfa and the location should be identical,34 # modulo the metadata.35 self.assertEqual(cfa | (1 << 60), argv_addr_uint)36