1 #include <stdbool.h> 2 #include <stdint.h> 3 get_tpidr(void)4uint64_t get_tpidr(void) { 5 uint64_t tpidr = 0; 6 __asm__ volatile("mrs %0, tpidr_el0" : "=r"(tpidr)); 7 return tpidr; 8 } 9 get_tpidr2(void)10uint64_t get_tpidr2(void) { 11 uint64_t tpidr2 = 0; 12 // S3_3_C13_C0_5 means tpidr2, and will work with older tools. 13 __asm__ volatile("mrs %0, S3_3_C13_C0_5" : "=r"(tpidr2)); 14 return tpidr2; 15 } 16 set_tpidr(uint64_t value)17void set_tpidr(uint64_t value) { 18 __asm__ volatile("msr tpidr_el0, %0" ::"r"(value)); 19 } 20 set_tpidr2(uint64_t value)21void set_tpidr2(uint64_t value) { 22 __asm__ volatile("msr S3_3_C13_C0_5, %0" ::"r"(value)); 23 } 24 25 bool use_tpidr2 = false; 26 const uint64_t tpidr_pattern = 0x1122334455667788; 27 const uint64_t tpidr2_pattern = 0x8877665544332211; 28 expr_func()29void expr_func() { 30 set_tpidr(~tpidr_pattern); 31 if (use_tpidr2) 32 set_tpidr2(~tpidr2_pattern); 33 } 34 main(int argc,char * argv[])35int main(int argc, char *argv[]) { 36 use_tpidr2 = argc > 1; 37 38 uint64_t original_tpidr = get_tpidr(); 39 // Accessing this on a core without it produces SIGILL. Only do this if 40 // requested. 41 uint64_t original_tpidr2 = 0; 42 if (use_tpidr2) 43 original_tpidr2 = get_tpidr2(); 44 45 set_tpidr(tpidr_pattern); 46 47 if (use_tpidr2) 48 set_tpidr2(tpidr2_pattern); 49 50 // Set break point at this line. 51 // lldb will now set its own pattern(s) for us to find. 52 53 uint64_t new_tpidr = get_tpidr(); 54 volatile bool tpidr_was_set = new_tpidr == 0x1111222233334444; 55 56 uint64_t new_tpidr2 = 0; 57 volatile bool tpidr2_was_set = false; 58 if (use_tpidr2) { 59 new_tpidr2 = get_tpidr2(); 60 tpidr2_was_set = new_tpidr2 == 0x4444333322221111; 61 } 62 63 set_tpidr(original_tpidr); 64 if (use_tpidr2) 65 set_tpidr2(original_tpidr2); 66 67 return 0; // Set break point 2 at this line. 68 } 69