blob: 0542bf9dd55ca43949f6fc7e776ddb29f9d3ce85 (
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#include "dbmalloc.h"
#include "dbutil.h"
#define LIST_SIZE 1000
struct dbmalloc_header {
unsigned int index;
unsigned int epoch;
};
static struct dbmalloc_header* dbmalloc_list[LIST_SIZE];
unsigned int current_epoch = 0;
void m_malloc_set_epoch(unsigned int epoch) {
current_epoch = epoch;
}
void m_malloc_free_epoch(unsigned int epoch) {
unsigned int i;
unsigned int freed = 0;
for (i = 0; i < LIST_SIZE; i++) {
if (dbmalloc_list[i] != NULL) {
assert(dbmalloc_list[i]->index == i);
if (dbmalloc_list[i]->epoch == epoch) {
free(dbmalloc_list[i]);
dbmalloc_list[i] = NULL;
freed++;
}
}
}
TRACE(("free_epoch freed %d", freed))
}
static void put_alloc(struct dbmalloc_header *header) {
unsigned int i;
for (i = 0; i < LIST_SIZE; i++) {
if (dbmalloc_list[i] == NULL) {
dbmalloc_list[i] = header;
header->index = i;
return;
}
}
dropbear_exit("ran out of dbmalloc entries");
}
static void remove_alloc(struct dbmalloc_header *header) {
assert(header->index < LIST_SIZE);
assert(dbmalloc_list[header->index] == header);
assert(header->epoch == current_epoch);
dbmalloc_list[header->index] = NULL;
}
static struct dbmalloc_header* get_header(void* ptr) {
char* bptr = ptr;
return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)];
}
void * m_malloc(size_t size) {
char* mem = NULL;
struct dbmalloc_header* header = NULL;
if (size == 0 || size > 1e9) {
dropbear_exit("m_malloc failed");
}
size = size + sizeof(struct dbmalloc_header);
mem = calloc(1, size);
if (mem == NULL) {
dropbear_exit("m_malloc failed");
}
header = (struct dbmalloc_header*)mem;
put_alloc(header);
header->epoch = current_epoch;
return &mem[sizeof(struct dbmalloc_header)];
}
void * m_calloc(size_t nmemb, size_t size) {
if (SIZE_T_MAX / nmemb < size) {
dropbear_exit("m_calloc failed");
}
return m_malloc(nmemb*size);
}
void * m_realloc(void* ptr, size_t size) {
char* mem = NULL;
struct dbmalloc_header* header = NULL;
if (size == 0 || size > 1e9) {
dropbear_exit("m_realloc failed");
}
header = get_header(ptr);
remove_alloc(header);
size = size + sizeof(struct dbmalloc_header);
mem = realloc(header, size);
if (mem == NULL) {
dropbear_exit("m_realloc failed");
}
header = (struct dbmalloc_header*)mem;
put_alloc(header);
return &mem[sizeof(struct dbmalloc_header)];
}
void m_free_direct(void* ptr) {
struct dbmalloc_header* header = NULL;
if (!ptr) {
return;
}
header = get_header(ptr);
remove_alloc(header);
free(header);
}
void * m_strdup(const char * str) {
char* ret;
unsigned int len;
len = strlen(str);
ret = m_malloc(len+1);
if (ret == NULL) {
dropbear_exit("m_strdup failed");
}
memcpy(ret, str, len+1);
return ret;
}
|