forked from flang-compiler/classic-flang-llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[lldb][AArch64] Annotate synchronous tag faults
In the latest Linux kernels synchronous tag faults include the tag bits in their address. This change adds logical and allocation tags to the description of synchronous tag faults. (asynchronous faults have no address) Process 1626 stopped * thread flang-compiler#1, name = 'a.out', stop reason = signal SIGSEGV: sync tag check fault (fault address: 0x900fffff7ff9010 logical tag: 0x9 allocation tag: 0x0) This extends the existing description and will show as much as it can on the rare occasion something fails. This change supports AArch64 MTE only but other architectures could be added by extending the switch at the start of AnnotateSyncTagCheckFault. The rest of the function is generic code. Tests have been added for synchronous and asynchronous MTE faults. Reviewed By: omjavaid Differential Revision: https://reviews.llvm.org/D105178 (cherry picked from commit d510b5f)
- Loading branch information
1 parent
dc00e19
commit bc0cc10
Showing
5 changed files
with
189 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
C_SOURCES := main.c | ||
CFLAGS_EXTRAS := -march=armv8.5-a+memtag | ||
|
||
include Makefile.rules |
62 changes: 62 additions & 0 deletions
62
lldb/test/API/linux/aarch64/mte_tag_faults/TestAArch64LinuxMTEMemoryTagFaults.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
""" | ||
Test reporting of MTE tag access faults. | ||
""" | ||
|
||
|
||
import lldb | ||
from lldbsuite.test.decorators import * | ||
from lldbsuite.test.lldbtest import * | ||
from lldbsuite.test import lldbutil | ||
|
||
|
||
class AArch64LinuxMTEMemoryTagFaultsTestCase(TestBase): | ||
|
||
mydir = TestBase.compute_mydir(__file__) | ||
|
||
NO_DEBUG_INFO_TESTCASE = True | ||
|
||
def setup_mte_test(self, fault_type): | ||
if not self.isAArch64MTE(): | ||
self.skipTest('Target must support MTE.') | ||
|
||
self.build() | ||
self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) | ||
|
||
lldbutil.run_break_set_by_file_and_line(self, "main.c", | ||
line_number('main.c', '// Breakpoint here'), | ||
num_expected_locations=1) | ||
|
||
self.runCmd("run {}".format(fault_type), RUN_SUCCEEDED) | ||
|
||
if self.process().GetState() == lldb.eStateExited: | ||
self.fail("Test program failed to run.") | ||
|
||
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, | ||
substrs=['stopped', | ||
'stop reason = breakpoint']) | ||
|
||
@skipUnlessArch("aarch64") | ||
@skipUnlessPlatform(["linux"]) | ||
@skipUnlessAArch64MTELinuxCompiler | ||
def test_mte_tag_fault_sync(self): | ||
self.setup_mte_test("sync") | ||
# The logical tag should be included in the fault address | ||
# and we know what the bottom byte should be. | ||
# It will be 0x10 (to be in the 2nd granule), +1 to be 0x11. | ||
# Which tests that lldb-server handles fault addresses that | ||
# are not granule aligned. | ||
self.expect("continue", | ||
patterns=[ | ||
"\* thread #1, name = 'a.out', stop reason = signal SIGSEGV: " | ||
"sync tag check fault \(fault address: 0x9[0-9A-Fa-f]+11\ " | ||
"logical tag: 0x9 allocation tag: 0xa\)"]) | ||
|
||
@skipUnlessArch("aarch64") | ||
@skipUnlessPlatform(["linux"]) | ||
@skipUnlessAArch64MTELinuxCompiler | ||
def test_mte_tag_fault_async(self): | ||
self.setup_mte_test("async") | ||
self.expect("continue", | ||
substrs=[ | ||
"* thread #1, name = 'a.out', stop reason = " | ||
"signal SIGSEGV: async tag check fault"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#include <arm_acle.h> | ||
#include <asm/hwcap.h> | ||
#include <asm/mman.h> | ||
#include <stdbool.h> | ||
#include <string.h> | ||
#include <sys/auxv.h> | ||
#include <sys/mman.h> | ||
#include <sys/prctl.h> | ||
#include <unistd.h> | ||
|
||
// Set bits 59-56 to tag, removing any existing tag | ||
static char *set_tag(char *ptr, size_t tag) { | ||
return (char *)(((size_t)ptr & ~((size_t)0xf << 56)) | (tag << 56)); | ||
} | ||
|
||
int main(int argc, char const *argv[]) { | ||
// We assume that the test runner has checked we're on an MTE system | ||
|
||
// Only expect to get the fault type | ||
if (argc != 2) | ||
return 1; | ||
|
||
unsigned long prctl_arg2 = 0; | ||
if (!strcmp(argv[1], "sync")) | ||
prctl_arg2 = PR_MTE_TCF_SYNC; | ||
else if (!strcmp(argv[1], "async")) | ||
prctl_arg2 = PR_MTE_TCF_ASYNC; | ||
else | ||
return 1; | ||
|
||
// Set fault type | ||
if (prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg2, 0, 0, 0)) | ||
return 1; | ||
|
||
// Allocate some memory with tagging enabled that we | ||
// can read/write if we use correct tags. | ||
char *buf = mmap(0, sysconf(_SC_PAGESIZE), PROT_MTE | PROT_READ | PROT_WRITE, | ||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||
if (buf == MAP_FAILED) | ||
return 1; | ||
|
||
// Our pointer will have tag 9 | ||
char *tagged_buf = set_tag(buf, 9); | ||
// Set allocation tags for the first 2 granules | ||
__arm_mte_set_tag(set_tag(tagged_buf, 9)); | ||
__arm_mte_set_tag(set_tag(tagged_buf + 16, 10)); | ||
|
||
// Confirm that we can write when tags match | ||
*tagged_buf = ' '; | ||
|
||
// Breakpoint here | ||
// Faults because tag 9 in the ptr != allocation tag of 10. | ||
// + 16 puts us in the second granule and +1 makes the fault address | ||
// misaligned relative to the granule size. This misalignment must | ||
// be accounted for by lldb-server. | ||
*(tagged_buf + 16 + 1) = '?'; | ||
|
||
return 0; | ||
} |