forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
1.8 KiB
79 lines
1.8 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
#include <string.h> |
|
#include "perf_regs.h" |
|
#include "thread.h" |
|
#include "map.h" |
|
#include "maps.h" |
|
#include "event.h" |
|
#include "debug.h" |
|
#include "tests/tests.h" |
|
#include "arch-tests.h" |
|
|
|
#define STACK_SIZE 8192 |
|
|
|
static int sample_ustack(struct perf_sample *sample, |
|
struct thread *thread, u64 *regs) |
|
{ |
|
struct stack_dump *stack = &sample->user_stack; |
|
struct map *map; |
|
unsigned long sp; |
|
u64 stack_size, *buf; |
|
|
|
buf = malloc(STACK_SIZE); |
|
if (!buf) { |
|
pr_debug("failed to allocate sample uregs data\n"); |
|
return -1; |
|
} |
|
|
|
sp = (unsigned long) regs[PERF_REG_X86_SP]; |
|
|
|
map = maps__find(thread->maps, (u64)sp); |
|
if (!map) { |
|
pr_debug("failed to get stack map\n"); |
|
free(buf); |
|
return -1; |
|
} |
|
|
|
stack_size = map->end - sp; |
|
stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; |
|
|
|
memcpy(buf, (void *) sp, stack_size); |
|
#ifdef MEMORY_SANITIZER |
|
/* |
|
* Copying the stack may copy msan poison, avoid false positives in the |
|
* unwinder by removing the poison here. |
|
*/ |
|
__msan_unpoison(buf, stack_size); |
|
#endif |
|
stack->data = (char *) buf; |
|
stack->size = stack_size; |
|
return 0; |
|
} |
|
|
|
int test__arch_unwind_sample(struct perf_sample *sample, |
|
struct thread *thread) |
|
{ |
|
struct regs_dump *regs = &sample->user_regs; |
|
u64 *buf; |
|
|
|
buf = malloc(sizeof(u64) * PERF_REGS_MAX); |
|
if (!buf) { |
|
pr_debug("failed to allocate sample uregs data\n"); |
|
return -1; |
|
} |
|
|
|
#ifdef MEMORY_SANITIZER |
|
/* |
|
* Assignments to buf in the assembly function perf_regs_load aren't |
|
* seen by memory sanitizer. Zero the memory to convince memory |
|
* sanitizer the memory is initialized. |
|
*/ |
|
memset(buf, 0, sizeof(u64) * PERF_REGS_MAX); |
|
#endif |
|
perf_regs_load(buf); |
|
regs->abi = PERF_SAMPLE_REGS_ABI; |
|
regs->regs = buf; |
|
regs->mask = PERF_REGS_MASK; |
|
|
|
return sample_ustack(sample, thread, buf); |
|
}
|
|
|