summaryrefslogtreecommitdiff
path: root/source/ucli/unwind.h
blob: d7ad366a19a43a807b534e19e07b59ae4587798c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#ifndef __UNWIND_H
#define __UNWIND_H

#include <libunwind-ptrace.h>
#include <libunwind.h>
#include <linux/ptrace.h>

#include "symbol.h"

#define DIAG_USER_STACK_SIZE (16 * 1024)

typedef unsigned long u64;
typedef unsigned char u8;
typedef unsigned int u32;
typedef long s64;
typedef char s8;
typedef int s32;

// typedef struct {
//   struct pt_regs regs;
//   unsigned long ip;
//   unsigned long bp;
//   unsigned long sp;
//   unsigned long stack_size;
//   unsigned long stack[DIAG_USER_STACK_SIZE / sizeof(unsigned long)];
// } raw_stack_detail;

struct regs_dump {
  u64 *regs;
};

struct ip_callchain {
  u64 nr;
  u64 ips[0];
};

struct branch_flags {
  u64 mispred : 1;
  u64 predicted : 1;
  u64 reserved : 62;
};

struct branch_entry {
  u64 from;
  u64 to;
  struct branch_flags flags;
};

struct branch_stack {
  u64 nr;
  struct branch_entry entries[0];
};

struct stack_dump {
  unsigned short offset;
  u64 size;
  char *data;
};

struct perf_sample {
  u64 ip;
  u32 pid, tid;
  u64 time;
  u64 addr;
  u64 id;
  u64 stream_id;
  u64 period;
  u32 cpu;
  u32 raw_size;
  void *raw_data;
  struct ip_callchain *callchain;
  struct branch_stack *branch_stack;
  struct regs_dump user_regs;
  struct stack_dump user_stack;
};

#define PERF_REG_IP 0
#define PERF_REG_SP 1
#define PERF_REG_BP 2

struct unwind_entry {
  int pid;
  int pid_ns;
  u64 ip;
  struct vma *map;
};

typedef struct {
  struct perf_sample *stack_sample;
  void *arg;
} entry_cb_arg_t;

typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);

// unw_create_addr_space need
extern unw_accessors_t accessors;

struct unwind_info {
  struct perf_sample *sample;
  int pid;
  int pid_ns;
  symbol_parser *sp;
};

// extern "C" void diag_printf_raw_stack(int pid, int ns_pid, const char *comm,
//                                       raw_stack_detail *raw_stack, int
//                                       attach);
int unwind__get_entries(unwind_entry_cb_t cb, void *arg, symbol_parser *sp,
                        int pid, int pid_ns, struct perf_sample *data);
#endif /* __UNWIND_H */