Remove building with NOCRYPTO option
[minix.git] / minix / lib / libmagicrt / magic_range.c
blob266816f7fbdfeca5c8d3e66205d76b58f8166abb
1 #define MAGIC_RANGE_DEBUG MAGIC_DEBUG_SET(0)
3 #include <magic_range.h>
5 /*===========================================================================*
6 * magic_range_is_shlib *
7 *===========================================================================*/
8 PRIVATE int magic_range_is_shlib(void *addr, void **container)
11 * NB!: This function requires the calling thread to already
12 * hold the DSODESC lock.
14 int ret = 0;
15 struct _magic_sodesc *sodesc;
16 struct _magic_dsodesc *dsodesc;
18 /* First iterate through the SO descriptors. */
19 MAGIC_SODESC_ITER(_magic_first_sodesc, sodesc,
20 /* First check the text range. */
21 MAGIC_RANGE_DEBUG_ADDR(addr, sodesc->lib.text_range);
22 if (MAGIC_ADDR_IS_IN_RANGE(addr, sodesc->lib.text_range)) {
23 ret |= MAGIC_STATE_TEXT;
24 goto found_so;
26 /* Next check the data range. */
27 MAGIC_RANGE_DEBUG_ADDR(addr, sodesc->lib.data_range);
28 if (MAGIC_ADDR_IS_IN_RANGE(addr, sodesc->lib.data_range)) {
29 ret |= MAGIC_STATE_DATA;
30 goto found_so;
34 /* Next iterate through the DSO descriptors. */
35 MAGIC_SODESC_ITER(_magic_first_dsodesc, dsodesc,
36 /* First check the text range. */
37 MAGIC_RANGE_DEBUG_ADDR(addr, dsodesc->lib.text_range);
38 if (MAGIC_ADDR_IS_IN_RANGE(addr, dsodesc->lib.text_range)) {
39 ret |= MAGIC_STATE_TEXT;
40 goto found_dso;
42 /* Next check the data range. */
43 MAGIC_RANGE_DEBUG_ADDR(addr, dsodesc->lib.data_range);
44 if (MAGIC_ADDR_IS_IN_RANGE(addr, dsodesc->lib.data_range)) {
45 ret |= MAGIC_STATE_DATA;
46 goto found_dso;
51 out:
52 return ret;
53 found_so:
54 ret |= MAGIC_STATE_LIB | MAGIC_STATE_LIB_SO;
55 if (container != NULL)
56 *container = (void *)(sodesc);
57 goto out;
58 found_dso:
59 ret |= MAGIC_STATE_LIB | MAGIC_STATE_LIB_DSO;
60 if (container != NULL) {
61 *container = (void *)(dsodesc);
63 goto out;
67 /*===========================================================================*
68 * magic_range_is_data *
69 *===========================================================================*/
70 PRIVATE INLINE int magic_range_is_data(void *addr)
72 MAGIC_RANGE_DEBUG_ADDR(addr, magic_data_range);
73 return MAGIC_ADDR_IS_IN_RANGE(addr, magic_data_range) ? MAGIC_STATE_DATA : 0;
76 /*===========================================================================*
77 * magic_range_is_text *
78 *===========================================================================*/
79 PRIVATE INLINE int magic_range_is_text(void *addr)
81 MAGIC_RANGE_DEBUG_ADDR(addr, magic_text_range);
82 return MAGIC_ADDR_IS_IN_RANGE(addr, magic_text_range) ? MAGIC_STATE_TEXT : 0;
85 /*===========================================================================*
86 * magic_range_is_heap *
87 *===========================================================================*/
88 PRIVATE INLINE int magic_range_is_heap(void *addr)
90 void* heap_range[2];
91 MAGIC_RANGE_SET_MIN(heap_range, magic_heap_start);
92 MAGIC_RANGE_SET_MAX(heap_range, (char *)magic_heap_end + MAGIC_HEAP_GAP);
93 MAGIC_RANGE_DEBUG_ADDR(addr, heap_range);
94 return MAGIC_ADDR_IS_IN_RANGE(addr, heap_range) ? MAGIC_STATE_HEAP : 0;
97 /*===========================================================================*
98 * magic_range_is_stack *
99 *===========================================================================*/
100 PUBLIC int magic_range_is_stack(void *addr)
103 * NB!: This function requires the calling thread to already
104 * hold the DSENTRY lock.
106 struct _magic_sentry *sentry;
107 int ret;
108 void *stack_range[2];
110 MAGIC_RANGE_INIT(stack_range);
111 assert(_magic_first_stack_dsentry && _magic_last_stack_dsentry);
112 sentry = MAGIC_DSENTRY_TO_SENTRY(_magic_first_stack_dsentry);
113 MAGIC_RANGE_SET_MIN(stack_range,
114 (char *) MAGIC_DSENTRY_TO_SENTRY(_magic_last_stack_dsentry)->address -
115 MAGIC_STACK_GAP);
116 MAGIC_RANGE_SET_MAX(stack_range,
117 ((char *) sentry->address) + sentry->type->size - 1);
118 #if MAGIC_RANGE_ROUND_STACK
119 MAGIC_RANGE_PAGE_ROUND(stack_range);
120 #endif
121 MAGIC_RANGE_DEBUG_ADDR(addr, stack_range);
122 ret = MAGIC_ADDR_IS_IN_RANGE(addr, stack_range) ? MAGIC_STATE_STACK : 0;
124 return ret;
127 /*===========================================================================*
128 * magic_range_is_dsentry *
129 *===========================================================================*/
130 PUBLIC int magic_range_is_dsentry(void *addr)
133 * NB!: This function requires the calling thread to already
134 * hold the DSENTRY lock.
136 int ret = 0;
137 void *start_address, *end_address;
138 struct _magic_dsentry *prev_dsentry, *dsentry;
139 struct _magic_sentry *sentry;
140 int region;
142 if(magic_update_dsentry_ranges) {
143 MAGIC_RANGE_INIT(magic_heap_range);
144 MAGIC_RANGE_INIT(magic_map_range);
145 MAGIC_RANGE_INIT(magic_shm_range);
146 MAGIC_RANGE_INIT(magic_stack_range);
147 MAGIC_DSENTRY_ALIVE_ITER(_magic_first_dsentry, prev_dsentry, dsentry, sentry,
148 start_address = sentry->address;
149 end_address = (void *) (((char *)sentry->address) +
150 sentry->type->size - 1);
151 region = MAGIC_STATE_REGION(sentry);
152 if(region & MAGIC_STATE_HEAP) {
153 MAGIC_RANGE_UPDATE(magic_heap_range, start_address, end_address);
155 else if(region & MAGIC_STATE_MAP) {
156 MAGIC_RANGE_UPDATE(magic_map_range, start_address, end_address);
158 else if(region & MAGIC_STATE_SHM) {
159 MAGIC_RANGE_UPDATE(magic_shm_range, start_address, end_address);
161 else if(region & MAGIC_STATE_STACK) {
162 MAGIC_RANGE_UPDATE(magic_stack_range, start_address, end_address);
165 magic_update_dsentry_ranges = 0;
167 MAGIC_RANGE_DEBUG_ADDR(addr, magic_heap_range);
168 if(MAGIC_ADDR_IS_IN_RANGE(addr, magic_heap_range)) {
169 ret |= MAGIC_STATE_HEAP;
171 MAGIC_RANGE_DEBUG_ADDR(addr, magic_map_range);
172 if(MAGIC_ADDR_IS_IN_RANGE(addr, magic_map_range)) {
173 ret |= MAGIC_STATE_MAP;
175 MAGIC_RANGE_DEBUG_ADDR(addr, magic_shm_range);
176 if(MAGIC_ADDR_IS_IN_RANGE(addr, magic_shm_range)) {
177 ret |= MAGIC_STATE_SHM;
179 MAGIC_RANGE_DEBUG_ADDR(addr, magic_stack_range);
180 if(MAGIC_ADDR_IS_IN_RANGE(addr, magic_stack_range)) {
181 ret |= MAGIC_STATE_STACK;
184 return ret;
187 /*===========================================================================*
188 * magic_range_is_dfunction *
189 *===========================================================================*/
190 PUBLIC int magic_range_is_dfunction(void *addr)
193 * NB!: This function requires the calling thread to already
194 * hold the DFUNCTION lock.
196 int ret = 0;
197 void *start_address;
198 struct _magic_dfunction* dfunction;
199 struct _magic_function* function;
200 int region;
202 if(magic_update_dfunction_ranges) {
203 MAGIC_RANGE_INIT(magic_dfunction_range);
204 MAGIC_DFUNCTION_FUNC_ITER(_magic_first_dfunction, dfunction, function,
205 start_address = function->address;
206 region = MAGIC_STATE_REGION(function);
207 assert(region & MAGIC_STATE_TEXT);
208 MAGIC_RANGE_UPDATE(magic_dfunction_range, start_address, start_address);
210 magic_update_dfunction_ranges = 0;
212 MAGIC_RANGE_DEBUG_ADDR(addr, magic_dfunction_range);
213 if(MAGIC_ADDR_IS_IN_RANGE(addr, magic_dfunction_range)) {
214 ret |= MAGIC_STATE_TEXT;
217 return ret;
220 /*===========================================================================*
221 * magic_ranges_init *
222 *===========================================================================*/
223 PUBLIC void magic_ranges_init(void)
225 int i,j;
226 void *start_address, *end_address;
227 const char* linker_vars[] = { MAGIC_LINKER_VAR_NAMES };
229 /* Init sentry and data range. */
230 MAGIC_RANGE_INIT(magic_data_range);
231 MAGIC_RANGE_INIT(magic_sentry_range);
232 for (i = 0 ; i < _magic_sentries_num ; i++) {
233 start_address = _magic_sentries[i].address;
234 end_address = (void *) (((char *)_magic_sentries[i].address)+_magic_sentries[i].type->size-1);
235 MAGIC_RANGE_UPDATE(magic_sentry_range, start_address, end_address);
236 j = 0;
237 while (linker_vars[j] && strcmp(linker_vars[j], _magic_sentries[i].name)) j++;
238 if (linker_vars[j] || MAGIC_STATE_FLAG(&_magic_sentries[i], MAGIC_STATE_THREAD_LOCAL)
239 || MAGIC_STATE_FLAG(&_magic_sentries[i], MAGIC_STATE_EXTERNAL)) {
240 continue;
242 MAGIC_RANGE_UPDATE(magic_data_range, start_address, end_address);
244 #if MAGIC_RANGE_ROUND_DATA
245 MAGIC_RANGE_PAGE_ROUND(magic_data_range);
246 #endif
248 /* Init function range. */
249 MAGIC_RANGE_INIT(magic_function_range);
250 for (i = 0 ; i < _magic_functions_num ; i++) {
251 start_address = _magic_functions[i].address;
252 MAGIC_RANGE_UPDATE(magic_function_range, start_address, start_address);
255 /* Init text range. */
256 #ifdef __MINIX
257 MAGIC_RANGE_SET(magic_text_range, MAGIC_TEXT_START,
258 MAGIC_TEXT_END ? MAGIC_TEXT_END : ((char *)magic_function_range[1]));
259 #else
260 MAGIC_RANGE_SET(magic_text_range, MAGIC_TEXT_START,
261 MAGIC_TEXT_END ? MAGIC_TEXT_END : ((char *)magic_data_range[0] - 1));
262 #endif
263 #if MAGIC_RANGE_ROUND_TEXT
264 MAGIC_RANGE_PAGE_ROUND(magic_text_range);
265 #endif
267 /* Init heap start. */
268 magic_heap_start = MAGIC_HEAP_START ? MAGIC_HEAP_START : ((char *)magic_data_range[1] + 1);
269 magic_heap_end = ((char *)sbrk(0)) - 1;
271 /* Defaults for other ranges. */
272 MAGIC_RANGE_INIT(magic_heap_range);
273 MAGIC_RANGE_INIT(magic_map_range);
274 MAGIC_RANGE_INIT(magic_shm_range);
275 MAGIC_RANGE_INIT(magic_stack_range);
276 MAGIC_RANGE_INIT(magic_dfunction_range);
279 /*===========================================================================*
280 * magic_range_lookup_by_addr *
281 *===========================================================================*/
282 PUBLIC int magic_range_lookup_by_addr(void *addr, void **container)
285 * NB!: This function requires the calling thread to already
286 * hold the DSENTRY, DFUNCTION and DSODESC locks.
288 int ret;
289 /* Constant ranges first. */
290 if (magic_range_is_data(addr)) {
291 return MAGIC_STATE_DATA;
293 if (magic_range_is_text(addr)) {
294 return MAGIC_STATE_TEXT;
297 /* Non-dsentry ranges next. */
298 if (magic_range_is_heap(addr)) {
299 return MAGIC_STATE_HEAP;
301 if (magic_range_is_stack(addr)) {
302 return MAGIC_STATE_STACK;
305 /* Shared library ranges. */
306 #if 0
307 /* XXX: This kind of range isn't very accurate. */
308 if (magic_range_is_dfunction(addr)) {
309 return MAGIC_STATE_LIB | MAGIC_STATE_TEXT;
311 #endif
313 if ((ret = magic_range_is_shlib(addr, container))) {
314 return ret;
317 /* Dsentry ranges last. */
318 return magic_range_is_dsentry(addr);