1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2aa16b81fSJiri Olsa #include <string.h> 3aa16b81fSJiri Olsa #include "perf_regs.h" 4aa16b81fSJiri Olsa #include "thread.h" 5aa16b81fSJiri Olsa #include "map.h" 6c54d241bSArnaldo Carvalho de Melo #include "maps.h" 7aa16b81fSJiri Olsa #include "event.h" 884f5d36fSJiri Olsa #include "debug.h" 9aa16b81fSJiri Olsa #include "tests/tests.h" 10aa16b81fSJiri Olsa 11aa16b81fSJiri Olsa #define STACK_SIZE 8192 12aa16b81fSJiri Olsa 13aa16b81fSJiri Olsa static int sample_ustack(struct perf_sample *sample, 14aa16b81fSJiri Olsa struct thread *thread, u64 *regs) 15aa16b81fSJiri Olsa { 16aa16b81fSJiri Olsa struct stack_dump *stack = &sample->user_stack; 17aa16b81fSJiri Olsa struct map *map; 18aa16b81fSJiri Olsa unsigned long sp; 19aa16b81fSJiri Olsa u64 stack_size, *buf; 20aa16b81fSJiri Olsa 21aa16b81fSJiri Olsa buf = malloc(STACK_SIZE); 22aa16b81fSJiri Olsa if (!buf) { 23aa16b81fSJiri Olsa pr_debug("failed to allocate sample uregs data\n"); 24aa16b81fSJiri Olsa return -1; 25aa16b81fSJiri Olsa } 26aa16b81fSJiri Olsa 27aa16b81fSJiri Olsa sp = (unsigned long) regs[PERF_REG_X86_SP]; 28aa16b81fSJiri Olsa 29fe87797dSArnaldo Carvalho de Melo map = maps__find(thread->maps, (u64)sp); 30aa16b81fSJiri Olsa if (!map) { 31aa16b81fSJiri Olsa pr_debug("failed to get stack map\n"); 32763d7f5fSMasanari Iida free(buf); 33aa16b81fSJiri Olsa return -1; 34aa16b81fSJiri Olsa } 35aa16b81fSJiri Olsa 36*e5116f46SIan Rogers stack_size = map__end(map) - sp; 37aa16b81fSJiri Olsa stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; 38aa16b81fSJiri Olsa 39aa16b81fSJiri Olsa memcpy(buf, (void *) sp, stack_size); 40568beb27SIan Rogers #ifdef MEMORY_SANITIZER 41568beb27SIan Rogers /* 42568beb27SIan Rogers * Copying the stack may copy msan poison, avoid false positives in the 43568beb27SIan Rogers * unwinder by removing the poison here. 44568beb27SIan Rogers */ 45568beb27SIan Rogers __msan_unpoison(buf, stack_size); 46568beb27SIan Rogers #endif 47aa16b81fSJiri Olsa stack->data = (char *) buf; 48aa16b81fSJiri Olsa stack->size = stack_size; 49aa16b81fSJiri Olsa return 0; 50aa16b81fSJiri Olsa } 51aa16b81fSJiri Olsa 52aa16b81fSJiri Olsa int test__arch_unwind_sample(struct perf_sample *sample, 53aa16b81fSJiri Olsa struct thread *thread) 54aa16b81fSJiri Olsa { 55aa16b81fSJiri Olsa struct regs_dump *regs = &sample->user_regs; 56aa16b81fSJiri Olsa u64 *buf; 57aa16b81fSJiri Olsa 58aa16b81fSJiri Olsa buf = malloc(sizeof(u64) * PERF_REGS_MAX); 59aa16b81fSJiri Olsa if (!buf) { 60aa16b81fSJiri Olsa pr_debug("failed to allocate sample uregs data\n"); 61aa16b81fSJiri Olsa return -1; 62aa16b81fSJiri Olsa } 63aa16b81fSJiri Olsa 640fb0d615SIan Rogers #ifdef MEMORY_SANITIZER 650fb0d615SIan Rogers /* 660fb0d615SIan Rogers * Assignments to buf in the assembly function perf_regs_load aren't 670fb0d615SIan Rogers * seen by memory sanitizer. Zero the memory to convince memory 680fb0d615SIan Rogers * sanitizer the memory is initialized. 690fb0d615SIan Rogers */ 700fb0d615SIan Rogers memset(buf, 0, sizeof(u64) * PERF_REGS_MAX); 710fb0d615SIan Rogers #endif 72aa16b81fSJiri Olsa perf_regs_load(buf); 73aa16b81fSJiri Olsa regs->abi = PERF_SAMPLE_REGS_ABI; 74aa16b81fSJiri Olsa regs->regs = buf; 75352ea45aSJiri Olsa regs->mask = PERF_REGS_MASK; 76aa16b81fSJiri Olsa 77aa16b81fSJiri Olsa return sample_ustack(sample, thread, buf); 78aa16b81fSJiri Olsa } 79