pstrace

Форк
0
/
registers.c 
152 строки · 4.7 Кб
1
/*
2
 * registers.cpp
3
 *
4
 *  Created on: Jan 27, 2020
5
 *      Author: nnosov
6
 */
7

8
#include <dwarf.h>
9
#include <elfutils/libdwfl.h>
10

11
#include "common.h"
12
#include "registers.h"
13

14
dwarf_reg_map   reg_map[] = {
15
    // GP Registers
16
    {0x0,  "RAX",   DW_OP_reg0},
17
    {0x1,  "RDX",   DW_OP_reg1},
18
    {0x2,  "RCX",   DW_OP_reg2},
19
    {0x3,  "RBX",   DW_OP_reg3},
20
    {0x4,  "RSI",   DW_OP_reg4},
21
    {0x5,  "RDI",   DW_OP_reg5},
22
    {0x6,  "RBP",   DW_OP_reg6},
23
    {0x7,  "RSP",   DW_OP_reg7}, // Stack pointer address (SP) mapped to RSP
24
    // Extended GP Registers
25
    {0x8,  "R8",    DW_OP_reg8},
26
    {0x9,  "R9",    DW_OP_reg9},
27
    {0xA,  "R10",   DW_OP_reg10},
28
    {0xB,  "R11",   DW_OP_reg11},
29
    {0xC,  "R12",   DW_OP_reg12},
30
    {0xD,  "R13",   DW_OP_reg13},
31
    {0xE,  "R14",   DW_OP_reg14},
32
    {0xF,  "R15",   DW_OP_reg15},
33
    {0x10, "RIP",   DW_OP_reg16}, // Return Address (RA) mapped to RIP
34
    // SSE Vector Registers
35
    {0x11, "XMM0",  DW_OP_reg17},
36
    {0x12, "XMM1",  DW_OP_reg18},
37
    {0x13, "XMM2",  DW_OP_reg19},
38
    {0x14, "XMM3",  DW_OP_reg20},
39
    {0x15, "XMM4",  DW_OP_reg21},
40
    {0x16, "XMM5",  DW_OP_reg22},
41
    {0x17, "XMM6",  DW_OP_reg23},
42
    {0x18, "XMM7",  DW_OP_reg24},
43
    {0x19, "XMM8",  DW_OP_reg25},
44
    {0x1a, "XMM9",  DW_OP_reg26},
45
    {0x1b, "XMM10", DW_OP_reg27},
46
    {0x1c, "XMM11", DW_OP_reg28},
47
    {0x1d, "XMM12", DW_OP_reg29},
48
    {0x1e, "XMM13", DW_OP_reg30},
49
    {0x1f, "XMM14", DW_OP_reg31},
50

51
    // GP Registers
52
    {0x0,  "RAX",   DW_OP_breg0},
53
    {0x1,  "RDX",   DW_OP_breg1},
54
    {0x2,  "RCX",   DW_OP_breg2},
55
    {0x3,  "RBX",   DW_OP_breg3},
56
    {0x4,  "RSI",   DW_OP_breg4},
57
    {0x5,  "RDI",   DW_OP_breg5},
58
    {0x6,  "RBP",   DW_OP_breg6},
59
    {0x7,  "RSP",   DW_OP_breg7},
60
    // Extended GP Registers
61
    {0x8,  "R8",    DW_OP_breg8},
62
    {0x9,  "R9",    DW_OP_breg9},
63
    {0xA,  "R10",   DW_OP_breg10},
64
    {0xB,  "R11",   DW_OP_breg11},
65
    {0xC,  "R12",   DW_OP_breg12},
66
    {0xD,  "R13",   DW_OP_breg13},
67
    {0xE,  "R14",   DW_OP_breg14},
68
    {0xF,  "R15",   DW_OP_breg15},
69
    {0x10, "RIP",   DW_OP_breg16}, // Return Address (RA) mapped to RIP
70
    // SSE Vector Registers
71
    {0x11, "XMM0",  DW_OP_breg17},
72
    {0x12, "XMM1",  DW_OP_breg18},
73
    {0x13, "XMM2",  DW_OP_breg19},
74
    {0x14, "XMM3",  DW_OP_breg20},
75
    {0x15, "XMM4",  DW_OP_breg21},
76
    {0x16, "XMM5",  DW_OP_breg22},
77
    {0x17, "XMM6",  DW_OP_breg23},
78
    {0x18, "XMM7",  DW_OP_breg24},
79
    {0x19, "XMM8",  DW_OP_breg25},
80
    {0x1a, "XMM9",  DW_OP_breg26},
81
    {0x1b, "XMM10", DW_OP_breg27},
82
    {0x1c, "XMM11", DW_OP_breg28},
83
    {0x1d, "XMM12", DW_OP_breg29},
84
    {0x1e, "XMM13", DW_OP_breg30},
85
    {0x1f, "XMM14", DW_OP_breg31},
86
    {0x20, "XMM15", 0xff}, // no mapping to dwarf registers
87
};
88

89
int regnum = sizeof(reg_map) / sizeof(dwarf_reg_map);
90

91
int find_regnum(uint32_t op)
92
{
93
    for(int i = 0; i < regnum; ++i) {
94
        if(reg_map[i].op_num == op) {
95
            return reg_map[i].regno;
96
        }
97
    }
98

99
    return -1;
100
}
101

102
pst_reg_error pst_get_reg(pst_context* ctx, int regno, uint64_t* regval)
103
{
104
#ifdef USE_LIBUNWIND
105
    int ret = unw_get_reg(ctx->curr_frame, regno, regval);
106
    switch (ret) {
107
        case UNW_EUNSPEC:
108
            return REG_CFI_ERROR;
109
            break;
110
        case UNW_EBADREG:
111
            return REG_UNDEFINED;
112
            break;
113
        default:
114
            return REG_UNDEFINED;
115
            break;
116
    }
117

118
    return REG_OK;
119
#else
120
    Dwarf_Op ops_mem[3];
121
    Dwarf_Op* ops;
122
    size_t nops;
123
    char str[512];
124
    if(dwarf_frame_register(ctx->frame, regno, ops_mem, &ops, &nops) != -1) {
125
        if(nops != 0 || ops != ops_mem) {
126
            if(nops != 0 || ops != NULL) {
127
                str[0] = 0;
128
                ctx->print_expr_block(ops, nops, str, sizeof(str));
129
                dwarf_stack st(ctx);
130
                if(st.calc_expression(ops, nops, NULL) && st.get_value(regval)) {
131
                    pst_log(SEVERITY_DEBUG, "CFI register 0x%X(%s) expression: %s ==> %#lX", regno, reg_map[regno].regname, str, regval);
132
                    return REG_OK;
133
                } else {
134
                    pst_log(SEVERITY_ERROR, "Failed to calculate register 0x%X(%s) CFI expression %s", regno, reg_map[regno].regname, str);
135
                    return REG_EXPR_ERROR;
136
                }
137
            } else {
138
                pst_log(SEVERITY_DEBUG, "CFI expression for register 0x%X(%s) is SAME VALUE", regno, reg_map[regno].regname);
139
                return REG_SAME;
140
            }
141
        } else {
142
            pst_log(SEVERITY_DEBUG, "CFI expression for register 0x%X(%s) is UNDEFINED", regno, reg_map[regno].regname);
143
            return REG_UNDEFINED;
144
        }
145

146
    } else {
147
        pst_log(SEVERITY_ERROR, "Failed to get CFI expression for register 0x%X", regno);
148
    }
149

150
    return REG_CFI_ERROR;
151
#endif
152
}
153

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.