1 /*
2 $Id: memblocksobj.c 2523 2021-03-14 20:58:12Z soci $
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 */
19 #include "memblocksobj.h"
20 #include <string.h>
21 #include "values.h"
22 #include "error.h"
23
24 #include "typeobj.h"
25
26 static Type obj;
27
28 Type *const MEMBLOCKS_OBJ = &obj;
29
destroy(Obj * o1)30 static FAST_CALL void destroy(Obj *o1) {
31 size_t i;
32 Memblocks *v1 = Memblocks(o1);
33 free(v1->mem.data);
34 for (i = 0; i < v1->p; i++) {
35 const struct memblock_s *b = &v1->data[i];
36 if (b->ref != NULL) val_destroy(Obj(b->ref));
37 }
38 free(v1->data);
39 }
40
same(const Obj * o1,const Obj * o2)41 static FAST_CALL bool same(const Obj *o1, const Obj *o2) {
42 size_t i;
43 const Memblocks *v1 = Memblocks(o1), *v2 = Memblocks(o2);
44 if (o1->obj != o2->obj || v1->p != v2->p) return false;
45 for (i = 0; i < v1->p; i++) {
46 struct memblock_s *b1 = &v1->data[i];
47 struct memblock_s *b2 = &v2->data[i];
48 if (b1->p != b2->p || b1->addr != b2->addr || b1->len != b2->len) return false;
49 if (b1->ref == b2->ref) continue;
50 if (b1->ref == NULL || b2->ref == NULL) return false;
51 if (!same(Obj(b1->ref), Obj(b2->ref))) return false;
52 }
53 return v1->mem.p == v2->mem.p && !memcmp(v1->mem.data, v2->mem.data, v1->mem.p);
54 }
55
new_memblocks(address_t ln,size_t ln2)56 MALLOC Memblocks *new_memblocks(address_t ln, size_t ln2) {
57 Memblocks *val = Memblocks(val_alloc(MEMBLOCKS_OBJ));
58 val->mem.p = 0;
59 val->mem.len = ln;
60 val->mem.data = (ln == 0) ? NULL : (uint8_t*)mallocx(ln);
61 val->p = 0;
62 val->len = ln2;
63 val->lastp = 0;
64 val->lastaddr = 0;
65 val->data = (ln2 == 0) ? NULL : (struct memblock_s *)mallocx(ln2 * sizeof *val->data);
66 val->flattened = false;
67 val->merged = false;
68 val->enumeration = false;
69 return val;
70 }
71
copy_memblocks(Memblocks * m)72 MALLOC Memblocks *copy_memblocks(Memblocks *m) {
73 Memblocks *val = Memblocks(val_alloc(MEMBLOCKS_OBJ));
74 size_t i;
75 val->mem.p = m->mem.p;
76 val->mem.len = m->mem.len;
77 val->mem.data = (m->mem.len == 0) ? NULL : (uint8_t*)mallocx(m->mem.len);
78 if (m->mem.len != 0) memcpy(val->mem.data, m->mem.data, m->mem.len);
79 val->p = m->p;
80 val->len = m->len;
81 val->lastp = m->lastp;
82 val->lastaddr = m->lastaddr;
83 val->data = (m->len == 0) ? NULL : (struct memblock_s *)mallocx(m->len * sizeof *val->data);
84 val->flattened = m->flattened;
85 val->merged = m->merged;
86 for (i = 0; i < m->len; i++) {
87 const struct memblock_s *b = &m->data[i];
88 val->data[i] = m->data[i];
89 if (b->ref != NULL) val->data[i].ref = copy_memblocks(b->ref);
90 }
91 return val;
92 }
93
memblocksobj_init(void)94 void memblocksobj_init(void) {
95 new_type(&obj, T_MEMBLOCKS, "memblocks", sizeof(Memblocks));
96 obj.destroy = destroy;
97 obj.same = same;
98 }
99