Просмотр исходного кода

Implements a small breakpoint lib

Allows to store & efficient lookup
Yann Weber 1 год назад
Родитель
Сommit
e3d0baa414
4 измененных файлов: 354 добавлений и 1 удалений
  1. 1
    1
      Makefile.am
  2. 175
    0
      breakpoints.c
  3. 70
    0
      breakpoints.h
  4. 108
    0
      tests/tests_breakpoints.c

+ 1
- 1
Makefile.am Просмотреть файл

@@ -1,6 +1,6 @@
1 1
 bin_PROGRAMS = asmsh child
2 2
 
3
-libcheck_asmsh_a_SOURCES = mmap_parse.c asm_env.c compile.c logger.c \
3
+libcheck_asmsh_a_SOURCES = mmap_parse.c asm_env.c breakpoints.c compile.c logger.c \
4 4
 			   completion.c shell.c shell_cmds.c shell_sym.c \
5 5
 			   history.c
6 6
 

+ 175
- 0
breakpoints.c Просмотреть файл

@@ -0,0 +1,175 @@
1
+/* Copyright Yann Weber <asmsh@yannweb.net>
2
+   This file is part of asmsh.
3
+
4
+   asmsh is free software: you can redistribute it and/or modify it under the
5
+   terms of the GNU General Public License as published by the Free Software
6
+   Foundation, either version 3 of the License, or any later version.
7
+   
8
+   asmsh is distributed in the hope that it will be useful, but WITHOUT ANY
9
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+   FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11
+   details.
12
+   
13
+   You should have received a copy of the GNU General Public License along
14
+   with asmsh. If not, see <https://www.gnu.org/licenses/>.
15
+*/
16
+#include "breakpoints.h"
17
+
18
+/** Efficient search of a breakpoint address
19
+ *
20
+ * @param brks pointer on the breakpoint list
21
+ * @param addr the address to search
22
+ * @param idx a pointer on the breakpoint index
23
+ * @return -1 if not found else 0
24
+ *
25
+ * @note idx is set to a value suitable for insertion if value is not found
26
+ */
27
+static int asmsh_brk_index(asmsh_brk_t *brks, unsigned long addr, size_t *idx);
28
+
29
+
30
+int asmsh_brk_init(asmsh_brk_t *brks)
31
+{
32
+	brks->addrs = NULL;
33
+	brks->sz = 0;
34
+
35
+	return 0;
36
+}
37
+
38
+
39
+void asmsh_brk_free(asmsh_brk_t *brks)
40
+{
41
+	free(brks->addrs);
42
+}
43
+
44
+
45
+int asmsh_brk_add(asmsh_brk_t *brks, unsigned long addr)
46
+{
47
+	size_t idx;
48
+	int ret;
49
+
50
+	void *tmp;
51
+
52
+	ret = asmsh_brk_index(brks, addr, &idx);
53
+
54
+	if(ret == 0)
55
+	{
56
+		return 1;
57
+	}
58
+	if(brks->sz > 0)
59
+	{
60
+		tmp = realloc(brks->addrs, sizeof(*brks->addrs)*(brks->sz + 1));
61
+		if(tmp == NULL)
62
+		{
63
+			int err = errno;
64
+			asmsh_log_perror("Unable to reallocate breakpoint list");
65
+			errno = err;
66
+			return -1;
67
+		}
68
+		brks->addrs=tmp;
69
+	}
70
+	else
71
+	{
72
+		if(!(brks->addrs = malloc(sizeof(*brks->addrs))))
73
+		{
74
+			int err = errno;
75
+			asmsh_log_perror("Unable to allocate breakpoint list");
76
+			errno = err;
77
+			return -1;
78
+		}
79
+	}
80
+	if(idx == brks->sz)
81
+	{
82
+		brks->addrs[brks->sz] = addr;
83
+	}
84
+	else
85
+	{
86
+		memmove(&(brks->addrs[idx+1]),&(brks->addrs[idx]),
87
+				(brks->sz - idx)*sizeof(*brks->addrs));
88
+		brks->addrs[idx] = addr;
89
+	}
90
+	brks->sz++;
91
+	return 0;
92
+}
93
+
94
+int asmsh_brk_del(asmsh_brk_t *brks, unsigned long addr)
95
+{
96
+	size_t idx;
97
+	int ret;
98
+
99
+	void *tmp;
100
+
101
+	ret = asmsh_brk_index(brks, addr, &idx);
102
+
103
+	if(ret < 0)
104
+	{
105
+		return 1;
106
+	}
107
+	brks->sz--;
108
+	if(idx < brks->sz)
109
+	{
110
+		memmove(&(brks->addrs[idx]), &(brks->addrs[idx+1]),
111
+				sizeof(*brks->addrs)*brks->sz);
112
+	}
113
+	if(brks->sz)
114
+	{
115
+		tmp = realloc(brks->addrs, brks->sz);
116
+		if(tmp == NULL)
117
+		{
118
+			int err = errno;
119
+			asmsh_log_perror("Unable to reallocate breakpoint list when removing");
120
+			errno = err;
121
+			return -1;
122
+		}
123
+		brks->addrs=tmp;
124
+	}
125
+	else
126
+	{
127
+		free(brks->addrs);
128
+		brks->addrs = NULL;
129
+	}
130
+	return 0;
131
+}
132
+
133
+int asmsh_brk_isset(asmsh_brk_t *brks, unsigned long addr)
134
+{
135
+	size_t idx;
136
+	return asmsh_brk_index(brks, addr, &idx) == 0;
137
+}
138
+
139
+static int asmsh_brk_index(asmsh_brk_t *brks, unsigned long addr, size_t *idx)
140
+{
141
+	size_t beg, end, mid;
142
+
143
+	if(brks->sz == 0)
144
+	{
145
+		*idx = 0;
146
+		return -1;
147
+	}
148
+
149
+	beg = 0;
150
+	end = brks->sz;
151
+	
152
+	while(end >= beg)
153
+	{
154
+		mid = (beg + end)  / 2;
155
+		if(brks->addrs[mid] == addr)
156
+		{
157
+			*idx = mid;
158
+			return 0;
159
+		}
160
+		else if(brks->addrs[mid] > addr)
161
+		{
162
+			if(mid == 0) { break; }
163
+			end = mid - 1;
164
+		}
165
+		else
166
+		{
167
+			beg = mid + 1;
168
+			if(beg >= brks->sz) { break; }
169
+		}
170
+	}
171
+	*idx = beg;
172
+	return -1;
173
+
174
+}
175
+

+ 70
- 0
breakpoints.h Просмотреть файл

@@ -0,0 +1,70 @@
1
+/* Copyright Yann Weber <asmsh@yannweb.net>
2
+   This file is part of asmsh.
3
+
4
+   asmsh is free software: you can redistribute it and/or modify it under the
5
+   terms of the GNU General Public License as published by the Free Software
6
+   Foundation, either version 3 of the License, or any later version.
7
+   
8
+   asmsh is distributed in the hope that it will be useful, but WITHOUT ANY
9
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
+   FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11
+   details.
12
+   
13
+   You should have received a copy of the GNU General Public License along
14
+   with asmsh. If not, see <https://www.gnu.org/licenses/>.
15
+*/
16
+#ifndef ASMSH_BREAKPOINTS_H
17
+#define ASMSH_BREAKPOINTS_H
18
+#include "config.h"
19
+
20
+#include <errno.h>
21
+#include <stdlib.h>
22
+
23
+#include "logger.h"
24
+
25
+typedef struct asmsh_brk_s asmsh_brk_t;
26
+
27
+
28
+/** Stores breakpoints informations */
29
+struct asmsh_brk_s
30
+{
31
+	/** Breakpoint addresses sorted ascending */
32
+	unsigned long *addrs;
33
+	/** Number of breakpoints */
34
+	size_t sz;
35
+};
36
+
37
+/** Initialize the breakpoint list
38
+ * @param brks Pointer on the list to initialize
39
+ * @return 0 if no error else -1
40
+ */
41
+int asmsh_brk_init(asmsh_brk_t *brks);
42
+
43
+/** Cleanup a breakpoint list struct
44
+ * @param brks Pointer on the list to clean
45
+ */
46
+void asmsh_brk_free(asmsh_brk_t *brks);
47
+
48
+/** Add a breakpoint
49
+ * @param brks Pointer on the list
50
+ * @param addr The breakpoint's address
51
+ * @return 0 if no error 1 if allready present else -1 and set errno
52
+ */
53
+int asmsh_brk_add(asmsh_brk_t *brks, unsigned long addr);
54
+
55
+/** Del a breakpoint
56
+ * @param brks Pointer on the list
57
+ * @param addr The breakpoint's address
58
+ * @return 0 if no error 1 if not present else -1 and set errno
59
+ */
60
+int asmsh_brk_del(asmsh_brk_t *brks, unsigned long addr);
61
+
62
+/** Check if a breakpoint exists
63
+ * @param brks Pointer on the list
64
+ * @param addr The address to check
65
+ * @return 0 if no breakpoint at given address
66
+ */
67
+int asmsh_brk_isset(asmsh_brk_t *brks, unsigned long addr);
68
+
69
+#endif
70
+

+ 108
- 0
tests/tests_breakpoints.c Просмотреть файл

@@ -0,0 +1,108 @@
1
+#include "config.h"
2
+
3
+#include <check.h>
4
+#include <errno.h>
5
+#include <stdio.h>
6
+#include <string.h>
7
+#include <unistd.h>
8
+
9
+#include "asmsh_check.h"
10
+#include "breakpoints.h"
11
+
12
+START_TEST(brk_add)
13
+{
14
+	asmsh_brk_t brks;
15
+	asmsh_brk_init(&brks);
16
+	ck_assert_int_eq(brks.sz, 0);
17
+
18
+	ck_assert_int_eq(asmsh_brk_add(&brks, 0x42), 0);
19
+	ck_assert_int_eq(brks.sz, 1);
20
+	ck_assert_int_eq(brks.addrs[0], 0x42);
21
+	ck_assert_int_eq(asmsh_brk_add(&brks, 0x42), 1);
22
+	ck_assert_int_eq(asmsh_brk_add(&brks, 0x1312), 0);
23
+	ck_assert_int_eq(brks.sz, 2);
24
+	ck_assert_int_eq(brks.addrs[0], 0x42);
25
+	ck_assert_int_eq(brks.addrs[1], 0x1312);
26
+}
27
+END_TEST
28
+
29
+START_TEST(brk_add_order)
30
+{
31
+	asmsh_brk_t brks;
32
+	asmsh_brk_init(&brks);
33
+
34
+	for(int s=0;s<2;s++)
35
+	{
36
+		for(int i=s;i<10; i+=2)
37
+		{
38
+			ck_assert_int_eq(asmsh_brk_add(&brks, i), 0);
39
+		}
40
+	}
41
+	for(int i=0;i<10;i++)
42
+	{
43
+		ck_assert_int_eq(brks.addrs[i], i);
44
+	}
45
+}
46
+
47
+START_TEST(brk_isset)
48
+{
49
+	asmsh_brk_t brks;
50
+	asmsh_brk_init(&brks);
51
+	ck_assert_int_eq(brks.sz, 0);
52
+
53
+	ck_assert_int_eq(asmsh_brk_isset(&brks, 0x42), 0);
54
+	ck_assert_int_eq(asmsh_brk_isset(&brks, 0x1312), 0);
55
+	ck_assert_int_eq(asmsh_brk_add(&brks, 0x42), 0);
56
+	ck_assert_int_ne(asmsh_brk_isset(&brks, 0x42), 0);
57
+
58
+	ck_assert_int_eq(asmsh_brk_add(&brks, 0x1312), 0);
59
+dprintf(2,"test isset\n");
60
+	ck_assert_int_ne(asmsh_brk_isset(&brks, 0x1312), 0);
61
+dprintf(2,"test isset2\n");
62
+	ck_assert_int_ne(asmsh_brk_isset(&brks, 0x42), 0);
63
+}
64
+END_TEST
65
+
66
+
67
+START_TEST(brk_del)
68
+{
69
+	asmsh_brk_t brks;
70
+	asmsh_brk_init(&brks);
71
+	ck_assert_int_eq(brks.sz, 0);
72
+
73
+	ck_assert_int_eq(asmsh_brk_add(&brks, 0x42), 0);
74
+	ck_assert_int_eq(asmsh_brk_add(&brks, 0x1312), 0);
75
+	ck_assert_int_ne(asmsh_brk_isset(&brks, 0x42), 0);
76
+	ck_assert_int_ne(asmsh_brk_isset(&brks, 0x1312), 0);
77
+
78
+	ck_assert_int_eq(asmsh_brk_del(&brks, 0x42), 0);
79
+	ck_assert_int_eq(asmsh_brk_isset(&brks, 0x42), 0);
80
+	ck_assert_int_ne(asmsh_brk_isset(&brks, 0x1312), 0);
81
+
82
+	ck_assert_int_eq(asmsh_brk_del(&brks, 0x42), 1);
83
+	ck_assert_int_eq(asmsh_brk_isset(&brks, 0x42), 0);
84
+	ck_assert_int_ne(asmsh_brk_isset(&brks, 0x1312), 0);
85
+
86
+	ck_assert_int_eq(asmsh_brk_del(&brks, 0x1312), 0);
87
+	ck_assert_int_eq(asmsh_brk_isset(&brks, 0x42), 0);
88
+	ck_assert_int_eq(asmsh_brk_isset(&brks, 0x1312), 0);
89
+}
90
+END_TEST
91
+
92
+
93
+
94
+/*
95
+START_TEST(brk_)
96
+{
97
+	asmsh_brk_t brks;
98
+	asmsh_brk_init(&brks);
99
+}
100
+END_TEST
101
+*/
102
+
103
+ASMSH_CHECK_START("Testing breakpoints lib", "Testing breakpoints manipulation")
104
+	ASMSH_ADD_TEST(brk_add);
105
+	ASMSH_ADD_TEST(brk_add_order);
106
+	ASMSH_ADD_TEST(brk_isset);
107
+	ASMSH_ADD_TEST(brk_del);
108
+ASMSH_CHECK_END

Загрузка…
Отмена
Сохранить