pstrace

Форк
0
/
common.c 
138 строк · 3.2 Кб
1
/*
2
 * common.cpp
3
 *
4
 *  Created on: Jan 8, 2020
5
 *      Author: nnosov
6
 */
7

8
#include <inttypes.h>
9
#include <stdbool.h>
10
#include <sys/mman.h>
11
#include <unistd.h>
12
#include <errno.h>
13

14
#include "context.h"
15

16
int32_t decode_sleb128(uint8_t *sleb128)
17
{
18
	int32_t num = 0, shift = 0, size = 0;
19
	do {
20
		num |= ((*sleb128 & 0x7f) << shift);
21
		shift += 7;
22
		size += 8;
23
	} while(*sleb128++ & 0x80);
24
	if((shift < size) && (*(--sleb128) & 0x40)) {
25
		num |= - (1 << shift);
26
	}
27
	return num;
28
}
29

30
uint32_t decode_uleb128(uint8_t *uleb128)
31
{
32
	uint32_t num = 0, shift = 0;
33
	do {
34
		num |= ((*uleb128 & 0x7f) << shift);
35
		shift += 7;
36
	} while(*uleb128++ & 0x80);
37
	return num;
38
}
39

40
// Utility function to encode a ULEB128 value to a buffer. Returns
41
// the length in bytes of the encoded value. by default PadTo = 0
42
inline unsigned encode_uleb128(uint64_t value, uint8_t *p, unsigned PadTo)
43
{
44
	uint8_t *orig_p = p;
45
	unsigned count = 0;
46
	do {
47
		uint8_t Byte = value & 0x7f;
48
		value >>= 7;
49
		count++;
50
		if (value != 0 || count < PadTo)
51
			Byte |= 0x80; // Mark this byte to show that more bytes will follow.
52
		*p++ = Byte;
53
	} while (value != 0);
54

55
	// Pad with 0x80 and emit a null byte at the end.
56
	if (count < PadTo) {
57
		for (; count < PadTo - 1; ++count)
58
			*p++ = '\x80';
59
		*p++ = '\x00';
60
	}
61

62
	return (unsigned)(p - orig_p);
63
}
64

65
// Utility function to encode a SLEB128 value to a buffer. Returns
66
// the length in bytes of the encoded value. by default PadTo = 0
67
inline unsigned encode_sleb128(int64_t value, uint8_t *p, unsigned PadTo)
68
{
69
	uint8_t *orig_p = p;
70
	unsigned count = 0;
71
	bool More;
72
	do {
73
		uint8_t Byte = value & 0x7f;
74
		// NOTE: this assumes that this signed shift is an arithmetic right shift.
75
		value >>= 7;
76
		More = !((((value == 0 ) && ((Byte & 0x40) == 0)) ||
77
				((value == -1) && ((Byte & 0x40) != 0))));
78
		count++;
79
		if (More || count < PadTo)
80
			Byte |= 0x80; // Mark this byte to show that more bytes will follow.
81
		*p++ = Byte;
82
	} while (More);
83

84
	// Pad with 0x80 and emit a terminating byte at the end.
85
	if (count < PadTo) {
86
		uint8_t PadValue = value < 0 ? 0x7f : 0x00;
87
		for (; count < PadTo - 1; ++count)
88
			*p++ = (PadValue | 0x80);
89
		*p++ = PadValue;
90
	}
91
	return (unsigned)(p - orig_p);
92
}
93

94
// Utility function to get the size of the ULEB128-encoded value.
95
unsigned getULEB128Size(uint64_t Value)
96
{
97
	unsigned Size = 0;
98
	do {
99
		Value >>= 7;
100
		Size += sizeof(int8_t);
101
	} while (Value);
102

103
	return Size;
104
}
105

106
// Utility function to get the size of the SLEB128-encoded value.
107
unsigned getSLEB128Size(int64_t Value)
108
{
109
	unsigned Size = 0;
110
	int Sign = Value >> (8 * sizeof(Value) - 1);
111
	bool IsMore;
112

113
	do {
114
		unsigned Byte = Value & 0x7f;
115
		Value >>= 7;
116
		IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
117
		Size += sizeof(int8_t);
118
	} while (IsMore);
119

120
	return Size;
121
}
122

123
int pst_pointer_valid(void *p, uint32_t size)
124
{
125
    long page_size = sysconf(_SC_PAGESIZE);
126
    if(page_size < 0) {
127
        pst_log(SEVERITY_ERROR, "%s: Failed to determine page size");
128
        return EFAULT;
129
    }
130

131
    void *aligned = (void *)((((long)p) / page_size) * page_size);
132
    //void *aligned = (void *)((uintptr_t)p & ~(page_size - 1));
133
    if(msync(aligned, size, MS_ASYNC) == 0) {
134
        return 0;
135
    }
136

137
    return (errno == ENOMEM ? EINVAL : EFAULT);
138
}
139

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

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

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

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