xref: /illumos-gate/usr/src/tools/smatch/src/ptrmap.c (revision c85f09cc)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Stupid implementation of pointer -> pointer map.
4  *
5  * Copyright (c) 2017 Luc Van Oostenryck.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 
26 #include "ptrmap.h"
27 #include "allocate.h"
28 #include <stddef.h>
29 
30 #define	MAP_NR	7
31 
32 struct ptrpair {
33 	void *key;
34 	void *val;
35 };
36 struct ptrmap {
37 	struct ptrmap *next;
38 	int nr;
39 	struct ptrpair pairs[MAP_NR];
40 };
41 
42 DECLARE_ALLOCATOR(ptrmap);
43 ALLOCATOR(ptrmap, "ptrmap");
44 
__ptrmap_add(struct ptrmap ** mapp,void * key,void * val)45 void __ptrmap_add(struct ptrmap **mapp, void *key, void *val)
46 {
47 	struct ptrmap *head = *mapp;
48 	struct ptrmap *newmap;
49 	struct ptrmap *map;
50 	struct ptrpair *pair;
51 	int nr;
52 
53 	if ((map = head)) {
54 		struct ptrmap *next = map->next;
55 		if (next)		// head is full
56 			map = next;
57 		if ((nr = map->nr) < MAP_NR)
58 			goto oldmap;
59 	}
60 
61 	// need a new block
62 	newmap = __alloc_ptrmap(0);
63 	if (!head) {
64 		*mapp = newmap;
65 	} else {
66 		newmap->next = head->next;
67 		head->next = newmap;
68 	}
69 	map = newmap;
70 	nr = 0;
71 
72 oldmap:
73 	pair = &map->pairs[nr];
74 	pair->key = key;
75 	pair->val = val;
76 	map->nr = ++nr;
77 }
78 
__ptrmap_lookup(struct ptrmap * map,void * key)79 void *__ptrmap_lookup(struct ptrmap *map, void *key)
80 {
81 	for (; map; map = map->next) {
82 		int i, n = map->nr;
83 		for (i = 0; i < n; i++) {
84 			struct ptrpair *pair = &map->pairs[i];
85 			if (pair->key == key)
86 				return pair->val;
87 		}
88 	}
89 	return NULL;
90 }
91 
__ptrmap_update(struct ptrmap ** mapp,void * key,void * val)92 void __ptrmap_update(struct ptrmap **mapp, void *key, void *val)
93 {
94 	struct ptrmap *map = *mapp;
95 
96 	for (; map; map = map->next) {
97 		int i, n = map->nr;
98 		for (i = 0; i < n; i++) {
99 			struct ptrpair *pair = &map->pairs[i];
100 			if (pair->key == key) {
101 				if (pair->val != val)
102 					pair->val = val;
103 				return;
104 			}
105 		}
106 	}
107 
108 	__ptrmap_add(mapp, key, val);
109 }
110