DavidSpickett created this revision. Herald added a subscriber: kristof.beyls. Herald added a project: All. DavidSpickett requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
Previously if you read a code/data mask before there was a valid thread you would get the top byte mask. This meant the value was "valid" as in, don't read it again. When using a corefile we ask for the data mask very early on and this meant that later once you did have a thread it wouldn't read the register to get the rest of the mask. This fixes that and adds a corefile test generated from the same program as in my previous change on this theme. Depends on D118794 <https://reviews.llvm.org/D118794> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D122411 Files: lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py lldb/test/API/linux/aarch64/non_address_bit_memory_access/a.out.corefile lldb/test/API/linux/aarch64/non_address_bit_memory_access/corefile lldb/test/API/linux/aarch64/non_address_bit_memory_access/main.c Index: lldb/test/API/linux/aarch64/non_address_bit_memory_access/main.c =================================================================== --- lldb/test/API/linux/aarch64/non_address_bit_memory_access/main.c +++ lldb/test/API/linux/aarch64/non_address_bit_memory_access/main.c @@ -13,6 +13,13 @@ if (buf == MAP_FAILED) return 1; + // Some known values to go in the corefile, since we cannot + // write to corefile memory. + buf[0] = 'L'; + buf[1] = 'L'; + buf[2] = 'D'; + buf[3] = 'B'; + #define sign_ptr(ptr) __asm__ __volatile__("pacdza %0" : "=r"(ptr) : "r"(ptr)) // Set top byte to something. @@ -21,5 +28,8 @@ // Address is now: // <8 bit top byte tag><pointer signature><virtual address> + // Uncomment this line to crash and generate a corefile. + //*(char*)0 = 0; + return 0; // Set break point at this line. } Index: lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py =================================================================== --- lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py +++ lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py @@ -175,3 +175,21 @@ if not found_read_buf: self.fail("Did not find any reads of buf.") + + @skipIfLLVMTargetMissing("AArch64") + def test_non_address_bit_memory_corefile(self): + if not self.isAArch64PAuth(): + self.skipTest('Target must support pointer authentication.') + + self.runCmd("target create a.out.corefile --core corefile") + + self.expect("thread list", substrs=['stopped', + 'stop reason = signal SIGSEGV']) + + # No caching (the program/corefile are the cache) and no writing + # to memory. So just check that tagged/untagged addresses read + # the same location. + + expected = ["4c 4c 44 42", "LLDB"] + self.expect("memory read buf", substrs=expected) + self.expect("memory read buf_with_non_address", substrs=expected) Index: lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp +++ lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp @@ -794,14 +794,20 @@ // Reads code or data address mask for the current Linux process. static lldb::addr_t ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp, llvm::StringRef reg_name) { - // Linux configures user-space virtual addresses with top byte ignored. - // We set default value of mask such that top byte is masked out. - uint64_t address_mask = ~((1ULL << 56) - 1); - // If Pointer Authentication feature is enabled then Linux exposes - // PAC data and code mask register. Try reading relevant register - // below and merge it with default address mask calculated above. + // 0 means there isn't a mask or it has not been read yet. + // We do not return the top byte mask unless thread_sp is valid. + // This prevents calls to this function before the thread is setup locking + // in the value to just the top byte mask, in cases where pointer authentication + // might also be active. + uint64_t address_mask = 0; lldb::ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread(); if (thread_sp) { + // Linux configures user-space virtual addresses with top byte ignored. + // We set default value of mask such that top byte is masked out. + address_mask = ~((1ULL << 56) - 1); + // If Pointer Authentication feature is enabled then Linux exposes + // PAC data and code mask register. Try reading relevant register + // below and merge it with default address mask calculated above. lldb::RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); if (reg_ctx_sp) { const RegisterInfo *reg_info =
Index: lldb/test/API/linux/aarch64/non_address_bit_memory_access/main.c =================================================================== --- lldb/test/API/linux/aarch64/non_address_bit_memory_access/main.c +++ lldb/test/API/linux/aarch64/non_address_bit_memory_access/main.c @@ -13,6 +13,13 @@ if (buf == MAP_FAILED) return 1; + // Some known values to go in the corefile, since we cannot + // write to corefile memory. + buf[0] = 'L'; + buf[1] = 'L'; + buf[2] = 'D'; + buf[3] = 'B'; + #define sign_ptr(ptr) __asm__ __volatile__("pacdza %0" : "=r"(ptr) : "r"(ptr)) // Set top byte to something. @@ -21,5 +28,8 @@ // Address is now: // <8 bit top byte tag><pointer signature><virtual address> + // Uncomment this line to crash and generate a corefile. + //*(char*)0 = 0; + return 0; // Set break point at this line. } Index: lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py =================================================================== --- lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py +++ lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py @@ -175,3 +175,21 @@ if not found_read_buf: self.fail("Did not find any reads of buf.") + + @skipIfLLVMTargetMissing("AArch64") + def test_non_address_bit_memory_corefile(self): + if not self.isAArch64PAuth(): + self.skipTest('Target must support pointer authentication.') + + self.runCmd("target create a.out.corefile --core corefile") + + self.expect("thread list", substrs=['stopped', + 'stop reason = signal SIGSEGV']) + + # No caching (the program/corefile are the cache) and no writing + # to memory. So just check that tagged/untagged addresses read + # the same location. + + expected = ["4c 4c 44 42", "LLDB"] + self.expect("memory read buf", substrs=expected) + self.expect("memory read buf_with_non_address", substrs=expected) Index: lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp +++ lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp @@ -794,14 +794,20 @@ // Reads code or data address mask for the current Linux process. static lldb::addr_t ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp, llvm::StringRef reg_name) { - // Linux configures user-space virtual addresses with top byte ignored. - // We set default value of mask such that top byte is masked out. - uint64_t address_mask = ~((1ULL << 56) - 1); - // If Pointer Authentication feature is enabled then Linux exposes - // PAC data and code mask register. Try reading relevant register - // below and merge it with default address mask calculated above. + // 0 means there isn't a mask or it has not been read yet. + // We do not return the top byte mask unless thread_sp is valid. + // This prevents calls to this function before the thread is setup locking + // in the value to just the top byte mask, in cases where pointer authentication + // might also be active. + uint64_t address_mask = 0; lldb::ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread(); if (thread_sp) { + // Linux configures user-space virtual addresses with top byte ignored. + // We set default value of mask such that top byte is masked out. + address_mask = ~((1ULL << 56) - 1); + // If Pointer Authentication feature is enabled then Linux exposes + // PAC data and code mask register. Try reading relevant register + // below and merge it with default address mask calculated above. lldb::RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); if (reg_ctx_sp) { const RegisterInfo *reg_info =
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits