xref: /minix/minix/lib/libmagicrt/include/magic_mem.h (revision d2532d3d)
1 #ifndef _MAGIC_MEM_H
2 #define _MAGIC_MEM_H
3 
4 #include <magic.h>
5 
6 #define __MA_ARGS__             struct _magic_type *type, const char *name, const char *parent_name,
7 #define __MA_VALUES__           type, name, parent_name,
8 #define __MA_VALUES_EXT__       MAGIC_VOID_TYPE, MAGIC_ALLOC_EXT_NAME, MAGIC_ALLOC_EXT_PARENT_NAME,
9 
10 #define __MD_ARGS__
11 #define __MD_VALUES__
12 #define __MD_VALUES_EXT__
13 #define __MD_VALUES_DEFAULT__
14 
15 /* External callbacks. */
16 typedef void *(*magic_mem_heap_alloc_cb_t)(size_t size, const char *name, const char *parent_name);
17 typedef void (*magic_mem_create_dsentry_cb_t)(struct _magic_dsentry *dsentry);
18 typedef int (*magic_mem_heap_free_cb_t)(struct _magic_dsentry *dsentry);
19 extern magic_mem_heap_alloc_cb_t magic_mem_heap_alloc_cb;
20 extern magic_mem_create_dsentry_cb_t magic_mem_create_dsentry_cb;
21 extern magic_mem_heap_free_cb_t magic_mem_heap_free_cb;
22 
23 /* Public dsentry functions. */
24 typedef void (*magic_dsentry_cb_t)(struct _magic_dsentry*);
25 PUBLIC int magic_create_dsentry(struct _magic_dsentry *dsentry,
26     void *data_ptr, struct _magic_type *type, size_t size, int flags,
27     const char *name, const char *parent_name);
28 PUBLIC struct _magic_obdsentry* magic_create_obdsentry(void *data_ptr,
29     struct _magic_type *type, size_t size, int flags,
30     const char *name, const char *parent_name);
31 PUBLIC int magic_update_dsentry_state(struct _magic_dsentry *dsentry,
32     unsigned long mstate);
33 PUBLIC void magic_free_dead_dsentries(void);
34 PUBLIC void magic_destroy_dsentry(struct _magic_dsentry *dsentry,
35     struct _magic_dsentry *prev_dsentry);
36 PUBLIC void magic_destroy_dsentry_set_ext_cb(const magic_dsentry_cb_t cb);
37 PUBLIC int magic_destroy_obdsentry_by_addr(void *data_ptr);
38 PUBLIC int magic_update_dsentry(void* addr, struct _magic_type *type);
39 PUBLIC void magic_stack_dsentries_create(
40     struct _magic_dsentry **prev_last_stack_dsentry, int num_dsentries,
41     /* struct _magic_dsentry *dsentry, struct _magic_type *type, void* data_ptr, const char* function_name, const char* name, */ ...);
42 PUBLIC void magic_stack_dsentries_destroy(
43     struct _magic_dsentry **prev_last_stack_dsentry, int num_dsentries,
44     /* struct _magic_dsentry *dsentry, */ ...);
45 
46 /* Public dfunction functions. */
47 PUBLIC int magic_create_dfunction(struct _magic_dfunction *dfunction,
48     void *data_ptr, struct _magic_type *type, int flags,
49     const char *name, const char *parent_name);
50 PUBLIC void magic_destroy_dfunction(struct _magic_dfunction *dfunction);
51 
52 /* Public sodesc functions. */
53 PUBLIC int magic_create_sodesc(struct _magic_sodesc *sodesc);
54 PUBLIC int magic_destroy_sodesc(struct _magic_sodesc *sodesc);
55 
56 /* Public dsodesc functions. */
57 PUBLIC int magic_create_dsodesc(struct _magic_dsodesc *dsodesc);
58 PUBLIC int magic_destroy_dsodesc(struct _magic_dsodesc *dsodesc);
59 
60 /* Memory usage logging support. */
61 #if MAGIC_MEM_USAGE_OUTPUT_CTL
62 /* CPU frequency (used for timestamp generation) */
63 EXTERN double magic_cycles_per_ns;
64 #endif
65 
66 /* Magic malloc wrappers. */
67 #include <stdlib.h>
68 #ifndef __MINIX
69 #include <malloc.h>
70 #endif
71 
72 PUBLIC void *magic_alloc(__MA_ARGS__ void *ptr, size_t size, int flags);
73 PUBLIC void *magic_malloc( __MA_ARGS__ size_t size);
74 PUBLIC void *magic_calloc( __MA_ARGS__ size_t nmemb, size_t size);
75 PUBLIC void  magic_free(   __MD_ARGS__ void *ptr);
76 PUBLIC void *magic_realloc(__MA_ARGS__ void *ptr, size_t size);
77 
78 PUBLIC void *(*magic_real_malloc)(size_t size);
79 PUBLIC void *(*magic_real_calloc)(size_t nmemb, size_t size);
80 PUBLIC void  (*magic_real_free)(void *ptr);
81 PUBLIC void *(*magic_real_realloc)(void *ptr, size_t size);
82 
83 PUBLIC int magic_posix_memalign(__MA_ARGS__ void **memptr, size_t alignment, size_t size);
84 PUBLIC int (*magic_real_posix_memalign)(void **memptr, size_t alignment, size_t size);
85 
86 #ifndef __MINIX
87 PUBLIC void *magic_valloc(      __MA_ARGS__ size_t size);
88 PUBLIC void *magic_memalign(    __MA_ARGS__ size_t boundary, size_t size);
89 
90 PUBLIC void *(*magic_real_valloc)(size_t size);
91 PUBLIC void *(*magic_real_memalign)(size_t boundary, size_t size);
92 #endif
93 
94 /* Magic mmap wrappers. */
95 #include <sys/mman.h>
96 
97 #ifdef __MINIX
98 #ifndef MAP_ANONYMOUS
99 #define MAP_ANONYMOUS MAP_ANON
100 #endif
101 #endif
102 
103 #ifndef _GNU_SOURCE
104 void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off_t pgoffset);
105 #endif
106 
107 PUBLIC void *magic_mmap(__MA_ARGS__ void *start, size_t length, int prot, int flags,
108     int fd, off_t offset);
109 PUBLIC int magic_munmap(__MD_ARGS__ void *start, size_t length);
110 
111 PUBLIC void *(*magic_real_mmap)(void *start, size_t length, int prot, int flags,
112     int fd, off_t offset);
113 PUBLIC int (*magic_real_munmap)(void *start, size_t length);
114 
115 /* Magic brk wrappers. */
116 #include <unistd.h>
117 
118 PUBLIC int magic_brk(   __MA_ARGS__ void *addr);
119 PUBLIC void *magic_sbrk(__MA_ARGS__ intptr_t increment);
120 
121 PUBLIC int (*magic_real_brk)(void *addr);
122 PUBLIC void *(*magic_real_sbrk)(intptr_t increment);
123 
124 #ifndef __MINIX
125 /* Magic shm wrappers. */
126 #include <sys/types.h>
127 #include <sys/shm.h>
128 
129 PUBLIC void *magic_shmat(__MA_ARGS__ int shmid, const void *shmaddr, int shmflg);
130 PUBLIC int magic_shmdt(  __MD_ARGS__ const void *shmaddr);
131 
132 PUBLIC void *(*magic_real_shmat)(int shmid, const void *shmaddr, int shmflg);
133 PUBLIC int (*magic_real_shmdt)(const void *shmaddr);
134 
135 /* Magic other wrappers. */
136 PUBLIC void *magic_mmap64(__MA_ARGS__ void *start, size_t length, int prot, int flags,
137     int fd, off_t pgoffset);
138 
139 PUBLIC void *(*magic_real_mmap64)(void *start, size_t length, int prot, int flags,
140     int fd, off_t pgoffset);
141 #else
142 #include <minix/vm.h>
143 
144 PUBLIC void *magic_vm_map_cacheblock(__MA_ARGS__ dev_t dev, off_t dev_offset,
145     ino_t ino, off_t ino_offset, u32_t *flags, int blocksize);
146 PUBLIC void *(*magic_real_vm_map_cacheblock)(dev_t dev, off_t dev_offset,
147     ino_t ino, off_t ino_offset, u32_t *flags, int blocksize);
148 #endif
149 
150 /* wrappers to skip alloction */
151 PUBLIC void *magic_malloc_positioned( __MA_ARGS__ size_t size, void *ptr);
152 PUBLIC void *magic_mmap_positioned(__MA_ARGS__ void *start, size_t length, int prot, int flags,
153     int fd, off_t offset, struct _magic_dsentry *cached_dsentry);
154 
155 /* Macros. */
156 #define MAGIC_ALLOC_SIZE                    (sizeof(struct _magic_dsentry))
157 
158 #define MAGIC_SIZE_TO_REAL(S)               (S + MAGIC_ALLOC_SIZE)
159 #define MAGIC_SIZE_TO_SOURCE(S)             (S - MAGIC_ALLOC_SIZE)
160 #define MAGIC_PTR_TO_DSENTRY(P)                                                \
161     ((struct _magic_dsentry *) (((char *)P)))
162 #define MAGIC_PTR_FROM_DSENTRY(P)           ((void *) P)
163 #define MAGIC_PTR_TO_DATA(P)                                                   \
164     ((void *) (((char *)P) + MAGIC_ALLOC_SIZE))
165 #define MAGIC_PTR_FROM_DATA(P)                                                 \
166     ((void *) (((char *)P) - MAGIC_ALLOC_SIZE))
167 
168 /* Variables to keep track of magic mem wrappers. */
169 EXTERN THREAD_LOCAL short magic_mem_wrapper_active;
170 EXTERN short magic_mem_create_dsentry_site_id;
171 
172 /* Variables to indicate if dsentry site_ids should be created. */
173 
174 #if MAGIC_ALLOW_DYN_MEM_WRAPPER_NESTING
175 #define MAGIC_MEM_WRAPPER_IS_ACTIVE()   (magic_mem_wrapper_active > 0)
176 #define MAGIC_MEM_WRAPPER_BEGIN()       do {                                   \
177         magic_mem_wrapper_active++;                                            \
178     } while(0)
179 #define MAGIC_MEM_WRAPPER_END()         do {                                   \
180         assert(MAGIC_MEM_WRAPPER_IS_ACTIVE());                                 \
181         magic_mem_wrapper_active--;                                            \
182     } while(0)
183 #else
184 #define MAGIC_MEM_WRAPPER_IS_ACTIVE()   (magic_mem_wrapper_active == 1)
185 #define MAGIC_MEM_WRAPPER_BEGIN()       do {                                   \
186         assert(!MAGIC_MEM_WRAPPER_IS_ACTIVE());                                \
187         magic_mem_wrapper_active = 1;                                          \
188     } while(0)
189 #define MAGIC_MEM_WRAPPER_END()         do {                                   \
190         assert(MAGIC_MEM_WRAPPER_IS_ACTIVE());                                 \
191         magic_mem_wrapper_active = 0;                                          \
192     } while(0)
193 #endif
194 
195 #define MAGIC_MEM_WRAPPER_LBEGIN()       do {                                  \
196         MAGIC_MEM_WRAPPER_BEGIN();                                             \
197         MAGIC_DSENTRY_LOCK();                                                  \
198     } while(0)
199 #define MAGIC_MEM_WRAPPER_LEND()         do {                                  \
200         MAGIC_MEM_WRAPPER_END();                                               \
201         MAGIC_DSENTRY_UNLOCK();                                                \
202     } while(0)
203 #define MAGIC_MEM_WRAPPER_BLOCK(BLOCK)   do {                                  \
204         MAGIC_MEM_WRAPPER_BEGIN();                                             \
205         BLOCK                                                                  \
206         MAGIC_MEM_WRAPPER_END();                                               \
207     } while(0)
208 #define MAGIC_MEM_WRAPPER_LBLOCK(BLOCK)  do {                                  \
209         MAGIC_MEM_WRAPPER_LBEGIN();                                            \
210         BLOCK                                                                  \
211         MAGIC_MEM_WRAPPER_LEND();                                              \
212     } while(0)
213 
214 /* Variables to keep track of memory pool management functions. */
215 #define MAGIC_MEMPOOL_ID_UNKNOWN            -1
216 #define MAGIC_MEMPOOL_ID_DETACHED           -2
217 #define MAGIC_MEMPOOL_MAX_FUNC_RECURSIONS   100
218 EXTERN THREAD_LOCAL short magic_mempool_mgmt_active_level;
219 EXTERN THREAD_LOCAL short magic_mempool_ids[MAGIC_MEMPOOL_MAX_FUNC_RECURSIONS];
220 EXTERN int magic_mempool_allow_reset;
221 EXTERN int magic_mempool_allow_reuse;
222 
223 /* TLS flags to be set when pool management functions are active. */
224 #define MAGIC_MEMPOOL_MGMT_SET_ACTIVE()                                        \
225     assert((++magic_mempool_mgmt_active_level <= MAGIC_MEMPOOL_MAX_FUNC_RECURSIONS) \
226             && "Reached the maximum number of nested pool function calls!")
227 #define MAGIC_MEMPOOL_MGMT_IS_ACTIVE()                                         \
228     (magic_mempool_mgmt_active_level > 0)
229 #define MAGIC_MEMPOOL_MGMT_UNSET_ACTIVE()                                      \
230     assert((--magic_mempool_mgmt_active_level >= 0) && "Invalid nested pool call level!")
231 #define MAGIC_MEMPOOL_SET_ID(ID)                                               \
232     (magic_mempool_ids[magic_mempool_mgmt_active_level - 1] = ID)
233 #define MAGIC_MEMPOOL_GET_ID()                                                 \
234     (magic_mempool_ids[magic_mempool_mgmt_active_level - 1])
235 #define MAGIC_MEMPOOL_ID_IS_SET()                                              \
236     (magic_mempool_ids[magic_mempool_mgmt_active_level - 1] > 0)
237 #define MAGIC_MEMPOOL_GET_NAME()                                               \
238     (MAGIC_MEMPOOL_ID_IS_SET() ?                                               \
239         _magic_mpdescs[MAGIC_MEMPOOL_GET_ID() - 1].name :                      \
240         ((MAGIC_MEMPOOL_GET_ID() == MAGIC_MEMPOOL_ID_UNKNOWN) ?                \
241             MAGIC_MEMPOOL_NAME_UNKNOWN : MAGIC_MEMPOOL_NAME_DETACHED))
242 /*  Store dynamic type in TLS if memory usage logging is enabled */
243 #if MAGIC_MEM_USAGE_OUTPUT_CTL
244 #define	MAGIC_MEMPOOL_SET_DTYPE(TYPE)                                          \
245     do {                                                                       \
246         if (MAGIC_MEMPOOL_ID_IS_SET())  {                                      \
247             _magic_mpdescs[MAGIC_MEMPOOL_GET_ID() - 1].dtype_id = TYPE;        \
248         }                                                                      \
249     } while(0)
250 #define	MAGIC_MEMPOOL_GET_DTYPE()                                              \
251     (MAGIC_MEMPOOL_ID_IS_SET() ?                                               \
252             _magic_mpdescs[MAGIC_MEMPOOL_GET_ID() - 1].dtype_id : 0)
253 #else
254 #define	MAGIC_MEMPOOL_SET_DTYPE(TYPE)
255 #define	MAGIC_MEMPOOL_GET_DTYPE()   0
256 #endif
257 
258 /* Pass call site information when logging is activated. */
259 #if (MAGIC_MEM_USAGE_OUTPUT_CTL == 1)
260 #define __MDEBUG_ARGS__             const char* name
261 #else
262 #define __MDEBUG_ARGS__
263 #endif
264 /* Specific wrapper for the memory pool creation. */
265 MAGIC_HOOK void magic_mempool_create_begin(__MDEBUG_ARGS__);
266 MAGIC_HOOK void magic_mempool_create_end(void* addr, int indirection);
267 
268 /* Specific wrappers for the memory pool destruction. */
269 MAGIC_HOOK void magic_mempool_destroy_begin(void* addr, int memory_reuse);
270 MAGIC_HOOK void magic_mempool_destroy_end(void);
271 
272 /* Specific wrappers for the memory pool resetting */
273 MAGIC_HOOK void magic_mempool_reset_begin(void* addr);
274 
275 /* Generic wrappers for the rest of the memory pool management functions. */
276 MAGIC_HOOK void magic_mempool_mgmt_begin(void* addr);
277 MAGIC_HOOK void magic_mempool_mgmt_end(void);
278 
279 /* Pool block allocation template function and magic wrapper. */
280 MAGIC_FUNC void *mempool_block_alloc_template(void* addr, size_t size);
281 PUBLIC void *magic_mempool_block_alloc_template(__MA_ARGS__ void* addr, size_t size);
282 
283 #endif
284 
285