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