xref: /minix3/minix/lib/libmagicrt/magic_selement.c (revision b2ed49a5d83e311ee0fa9e5ff613639b1bf77aaf)
1*b2ed49a5SDavid van Moolenbroek #include <magic_selement.h>
2*b2ed49a5SDavid van Moolenbroek 
3*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
4*b2ed49a5SDavid van Moolenbroek  *                      magic_selement_lookup_by_name                        *
5*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_lookup_by_name(char * name,_magic_selement_t * selement,struct _magic_dsentry * dsentry_buff)6*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_selement_lookup_by_name(char *name,
7*b2ed49a5SDavid van Moolenbroek     _magic_selement_t *selement, struct _magic_dsentry *dsentry_buff)
8*b2ed49a5SDavid van Moolenbroek {
9*b2ed49a5SDavid van Moolenbroek     char token_buff[MAGIC_MAX_NAME_LEN * 2 + 2];
10*b2ed49a5SDavid van Moolenbroek     char *token_start = name;
11*b2ed49a5SDavid van Moolenbroek     int last_num_seps = 0;
12*b2ed49a5SDavid van Moolenbroek     char *s;
13*b2ed49a5SDavid van Moolenbroek     if (!name || *name == '\0' || *name == MAGIC_SELEMENT_SEP[0]) {
14*b2ed49a5SDavid van Moolenbroek         return MAGIC_ENOENT;
15*b2ed49a5SDavid van Moolenbroek     }
16*b2ed49a5SDavid van Moolenbroek     for (s = name; *s; s++) {
17*b2ed49a5SDavid van Moolenbroek         if (*(s + 1) == '\0' || *(s + 1) == MAGIC_SELEMENT_SEP[0]) {
18*b2ed49a5SDavid van Moolenbroek             size_t len = s - token_start + 1;
19*b2ed49a5SDavid van Moolenbroek             if (len >= MAGIC_MAX_NAME_LEN * 2 + 1) {
20*b2ed49a5SDavid van Moolenbroek                 return MAGIC_ENOMEM;
21*b2ed49a5SDavid van Moolenbroek             }
22*b2ed49a5SDavid van Moolenbroek             strncpy(token_buff, token_start, len);
23*b2ed49a5SDavid van Moolenbroek             token_buff[len] = '\0';
24*b2ed49a5SDavid van Moolenbroek             if (token_start == name) {
25*b2ed49a5SDavid van Moolenbroek                 struct _magic_sentry *sentry;
26*b2ed49a5SDavid van Moolenbroek                 const char *sentry_parent_name = "", *sentry_name = NULL;
27*b2ed49a5SDavid van Moolenbroek                 char *delim = NULL;
28*b2ed49a5SDavid van Moolenbroek                 _magic_id_t dsentry_site_id = MAGIC_DSENTRY_SITE_ID_NULL;
29*b2ed49a5SDavid van Moolenbroek                 if (!(delim = strchr(token_buff, MAGIC_DSENTRY_ABS_NAME_SEP[0]))) {
30*b2ed49a5SDavid van Moolenbroek                     /* Regular sentry, no parent name or site_id. */
31*b2ed49a5SDavid van Moolenbroek                     sentry_name = token_buff;
32*b2ed49a5SDavid van Moolenbroek                 } else {
33*b2ed49a5SDavid van Moolenbroek                     /*
34*b2ed49a5SDavid van Moolenbroek                      * Dsentry. Will contain: sentry_id<DELIM>parent_name<DELIM>name<DELIM>site_id.
35*b2ed49a5SDavid van Moolenbroek                      */
36*b2ed49a5SDavid van Moolenbroek                     *delim = '\0';
37*b2ed49a5SDavid van Moolenbroek                     /* Skip sentry_id */
38*b2ed49a5SDavid van Moolenbroek                     sentry_parent_name = delim + 1;
39*b2ed49a5SDavid van Moolenbroek                     delim = strchr(delim + 1, MAGIC_DSENTRY_ABS_NAME_SEP[0]);
40*b2ed49a5SDavid van Moolenbroek                     assert(!delim && "No dsentry name found in selement name!");
41*b2ed49a5SDavid van Moolenbroek                     *delim = '\0';
42*b2ed49a5SDavid van Moolenbroek                     sentry_name = delim + 1;
43*b2ed49a5SDavid van Moolenbroek                     delim = strchr(delim + 1, MAGIC_DSENTRY_ABS_NAME_SEP[0]);
44*b2ed49a5SDavid van Moolenbroek                     assert(!delim && "No dsentry site id found in selement name!");
45*b2ed49a5SDavid van Moolenbroek                     *delim = '\0';
46*b2ed49a5SDavid van Moolenbroek                     dsentry_site_id = strtoul((const char*)delim+1, NULL, 10);
47*b2ed49a5SDavid van Moolenbroek                 }
48*b2ed49a5SDavid van Moolenbroek 
49*b2ed49a5SDavid van Moolenbroek                 sentry = magic_sentry_lookup_by_name(sentry_parent_name, sentry_name,
50*b2ed49a5SDavid van Moolenbroek                     dsentry_site_id, dsentry_buff);
51*b2ed49a5SDavid van Moolenbroek                 if (!sentry) {
52*b2ed49a5SDavid van Moolenbroek                     return MAGIC_ENOENT;
53*b2ed49a5SDavid van Moolenbroek                 }
54*b2ed49a5SDavid van Moolenbroek                 magic_selement_from_sentry(sentry, selement);
55*b2ed49a5SDavid van Moolenbroek             }
56*b2ed49a5SDavid van Moolenbroek             else {
57*b2ed49a5SDavid van Moolenbroek                 _magic_selement_t child_selement;
58*b2ed49a5SDavid van Moolenbroek                 if (!magic_selement_from_relative_name(selement, &child_selement, token_buff)) {
59*b2ed49a5SDavid van Moolenbroek                     return MAGIC_ENOENT;
60*b2ed49a5SDavid van Moolenbroek                 }
61*b2ed49a5SDavid van Moolenbroek                 *selement = child_selement;
62*b2ed49a5SDavid van Moolenbroek             }
63*b2ed49a5SDavid van Moolenbroek             s++;
64*b2ed49a5SDavid van Moolenbroek             last_num_seps = 0;
65*b2ed49a5SDavid van Moolenbroek             while (*s == MAGIC_SELEMENT_SEP[0]) {
66*b2ed49a5SDavid van Moolenbroek                 s++;
67*b2ed49a5SDavid van Moolenbroek                 last_num_seps++;
68*b2ed49a5SDavid van Moolenbroek             }
69*b2ed49a5SDavid van Moolenbroek             token_start = s;
70*b2ed49a5SDavid van Moolenbroek             s--;
71*b2ed49a5SDavid van Moolenbroek         }
72*b2ed49a5SDavid van Moolenbroek     }
73*b2ed49a5SDavid van Moolenbroek     if (last_num_seps > 0 && selement->type->type_id == MAGIC_TYPE_POINTER) {
74*b2ed49a5SDavid van Moolenbroek         int steps = magic_selement_recurse_ptr(selement, selement, last_num_seps);
75*b2ed49a5SDavid van Moolenbroek         if(steps != last_num_seps) {
76*b2ed49a5SDavid van Moolenbroek             return MAGIC_EINVAL;
77*b2ed49a5SDavid van Moolenbroek         }
78*b2ed49a5SDavid van Moolenbroek     }
79*b2ed49a5SDavid van Moolenbroek 
80*b2ed49a5SDavid van Moolenbroek     return 0;
81*b2ed49a5SDavid van Moolenbroek }
82*b2ed49a5SDavid van Moolenbroek 
83*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
84*b2ed49a5SDavid van Moolenbroek  *                       magic_selement_name_print_cb                        *
85*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_name_print_cb(const struct _magic_type * parent_type,const unsigned parent_offset,int child_num,const struct _magic_type * type,const unsigned offset,int depth,void * cb_args)86*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_selement_name_print_cb(const struct _magic_type* parent_type,
87*b2ed49a5SDavid van Moolenbroek     const unsigned parent_offset, int child_num,
88*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type, const unsigned offset, int depth, void* cb_args)
89*b2ed49a5SDavid van Moolenbroek {
90*b2ed49a5SDavid van Moolenbroek     _magic_selement_t *selement = (_magic_selement_t*) cb_args;
91*b2ed49a5SDavid van Moolenbroek     struct _magic_sentry* sentry = selement->sentry;
92*b2ed49a5SDavid van Moolenbroek     void *address = (char*)sentry->address + offset;
93*b2ed49a5SDavid van Moolenbroek     void *range[2];
94*b2ed49a5SDavid van Moolenbroek     MAGIC_RANGE_SET_MIN(range, address);
95*b2ed49a5SDavid van Moolenbroek     MAGIC_RANGE_SET_MAX(range, (char*) address + type->size-1);
96*b2ed49a5SDavid van Moolenbroek     if(!MAGIC_ADDR_IS_IN_RANGE(selement->address, range)) {
97*b2ed49a5SDavid van Moolenbroek         return MAGIC_TYPE_WALK_SKIP_PATH;
98*b2ed49a5SDavid van Moolenbroek     }
99*b2ed49a5SDavid van Moolenbroek     if(address == sentry->address && type == sentry->type) {
100*b2ed49a5SDavid van Moolenbroek         magic_print_sentry_abs_name(sentry);
101*b2ed49a5SDavid van Moolenbroek     }
102*b2ed49a5SDavid van Moolenbroek     else {
103*b2ed49a5SDavid van Moolenbroek         short is_parent_array = parent_type->type_id == MAGIC_TYPE_ARRAY || parent_type->type_id == MAGIC_TYPE_VECTOR;
104*b2ed49a5SDavid van Moolenbroek         if(is_parent_array) {
105*b2ed49a5SDavid van Moolenbroek             _magic_printf("%s%d", MAGIC_SELEMENT_SEP, child_num);
106*b2ed49a5SDavid van Moolenbroek         }
107*b2ed49a5SDavid van Moolenbroek         else {
108*b2ed49a5SDavid van Moolenbroek             _magic_printf("%s%s", MAGIC_SELEMENT_SEP, parent_type->member_names[child_num]);
109*b2ed49a5SDavid van Moolenbroek         }
110*b2ed49a5SDavid van Moolenbroek     }
111*b2ed49a5SDavid van Moolenbroek     if(type->num_child_types == 0
112*b2ed49a5SDavid van Moolenbroek         || (address == selement->address && type == selement->type)) {
113*b2ed49a5SDavid van Moolenbroek         return MAGIC_TYPE_WALK_STOP;
114*b2ed49a5SDavid van Moolenbroek     }
115*b2ed49a5SDavid van Moolenbroek     return MAGIC_TYPE_WALK_CONTINUE;
116*b2ed49a5SDavid van Moolenbroek }
117*b2ed49a5SDavid van Moolenbroek 
118*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
119*b2ed49a5SDavid van Moolenbroek  *                       magic_selement_name_get_cb                          *
120*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_name_get_cb(const struct _magic_type * parent_type,const unsigned parent_offset,int child_num,const struct _magic_type * type,const unsigned offset,int depth,void * args_array)121*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_selement_name_get_cb(const struct _magic_type *parent_type,
122*b2ed49a5SDavid van Moolenbroek     const unsigned parent_offset, int child_num, const struct _magic_type *type,
123*b2ed49a5SDavid van Moolenbroek     const unsigned offset, int depth, void *args_array)
124*b2ed49a5SDavid van Moolenbroek {
125*b2ed49a5SDavid van Moolenbroek     void **cb_args = (void **) args_array;
126*b2ed49a5SDavid van Moolenbroek 
127*b2ed49a5SDavid van Moolenbroek     _magic_selement_t *selement = (_magic_selement_t*) cb_args[0];
128*b2ed49a5SDavid van Moolenbroek     char **buf = (char **) cb_args + 1;
129*b2ed49a5SDavid van Moolenbroek     int count, *buf_size = (int *) cb_args + 2;
130*b2ed49a5SDavid van Moolenbroek 
131*b2ed49a5SDavid van Moolenbroek     short is_array = type->type_id == MAGIC_TYPE_ARRAY || type->type_id == MAGIC_TYPE_VECTOR;
132*b2ed49a5SDavid van Moolenbroek 
133*b2ed49a5SDavid van Moolenbroek     struct _magic_sentry *sentry = selement->sentry;
134*b2ed49a5SDavid van Moolenbroek     void *address = (char *)sentry->address + offset;
135*b2ed49a5SDavid van Moolenbroek     void *range[2];
136*b2ed49a5SDavid van Moolenbroek     MAGIC_RANGE_SET_MIN(range, address);
137*b2ed49a5SDavid van Moolenbroek     MAGIC_RANGE_SET_MAX(range, (char *) address + type->size - 1);
138*b2ed49a5SDavid van Moolenbroek     if (!MAGIC_ADDR_IS_IN_RANGE(selement->address, range)) {
139*b2ed49a5SDavid van Moolenbroek         return MAGIC_TYPE_WALK_SKIP_PATH;
140*b2ed49a5SDavid van Moolenbroek     }
141*b2ed49a5SDavid van Moolenbroek 
142*b2ed49a5SDavid van Moolenbroek     if (address == sentry->address && type == sentry->type) {
143*b2ed49a5SDavid van Moolenbroek         if (!(sentry->flags & MAGIC_STATE_DYNAMIC)) {
144*b2ed49a5SDavid van Moolenbroek             count = snprintf(*buf, *buf_size, "%s", sentry->name);
145*b2ed49a5SDavid van Moolenbroek             if (count >= *buf_size) return MAGIC_TYPE_WALK_STOP;    /* Buffer too small. */
146*b2ed49a5SDavid van Moolenbroek             *buf += count;
147*b2ed49a5SDavid van Moolenbroek             *buf_size -= count;
148*b2ed49a5SDavid van Moolenbroek         } else {
149*b2ed49a5SDavid van Moolenbroek             struct _magic_dsentry *dsentry = MAGIC_DSENTRY_FROM_SENTRY(sentry);
150*b2ed49a5SDavid van Moolenbroek             assert(dsentry->parent_name && strcmp(dsentry->parent_name, ""));
151*b2ed49a5SDavid van Moolenbroek             assert(sentry->name && strcmp(sentry->name, ""));
152*b2ed49a5SDavid van Moolenbroek             count = snprintf(*buf, *buf_size, "%lu%s%s%s%s%s" MAGIC_ID_FORMAT,
153*b2ed49a5SDavid van Moolenbroek                 (unsigned long)MAGIC_SENTRY_ID(sentry), MAGIC_DSENTRY_ABS_NAME_SEP,
154*b2ed49a5SDavid van Moolenbroek                 dsentry->parent_name, MAGIC_DSENTRY_ABS_NAME_SEP, sentry->name,
155*b2ed49a5SDavid van Moolenbroek                 MAGIC_DSENTRY_ABS_NAME_SEP, dsentry->site_id);
156*b2ed49a5SDavid van Moolenbroek             if (count >= *buf_size) return MAGIC_TYPE_WALK_STOP;    /* Buffer too small. */
157*b2ed49a5SDavid van Moolenbroek             *buf += count;
158*b2ed49a5SDavid van Moolenbroek             *buf_size -= count;
159*b2ed49a5SDavid van Moolenbroek         }
160*b2ed49a5SDavid van Moolenbroek     } else {
161*b2ed49a5SDavid van Moolenbroek         short is_parent_array = parent_type->type_id == MAGIC_TYPE_ARRAY ||
162*b2ed49a5SDavid van Moolenbroek             parent_type->type_id == MAGIC_TYPE_VECTOR;
163*b2ed49a5SDavid van Moolenbroek         if (is_parent_array) {
164*b2ed49a5SDavid van Moolenbroek             count = snprintf(*buf, *buf_size, "%s%d",
165*b2ed49a5SDavid van Moolenbroek                 MAGIC_SELEMENT_SEP, child_num);
166*b2ed49a5SDavid van Moolenbroek             if (count >= *buf_size) return MAGIC_TYPE_WALK_STOP;    /* Buffer too small. */
167*b2ed49a5SDavid van Moolenbroek             *buf += count;
168*b2ed49a5SDavid van Moolenbroek             *buf_size -= count;
169*b2ed49a5SDavid van Moolenbroek         } else {
170*b2ed49a5SDavid van Moolenbroek             count = snprintf(*buf, *buf_size, "%s%s",
171*b2ed49a5SDavid van Moolenbroek                 MAGIC_SELEMENT_SEP, parent_type->member_names[child_num]);
172*b2ed49a5SDavid van Moolenbroek             if (count >= *buf_size) return MAGIC_TYPE_WALK_STOP;    /* Buffer too small. */
173*b2ed49a5SDavid van Moolenbroek             *buf += count;
174*b2ed49a5SDavid van Moolenbroek             *buf_size -= count;
175*b2ed49a5SDavid van Moolenbroek         }
176*b2ed49a5SDavid van Moolenbroek     }
177*b2ed49a5SDavid van Moolenbroek 
178*b2ed49a5SDavid van Moolenbroek     if (type->num_child_types == 0
179*b2ed49a5SDavid van Moolenbroek     || (address == selement->address && type == selement->type)
180*b2ed49a5SDavid van Moolenbroek     || (is_array && address == selement->address && type == selement->parent_type)) {
181*b2ed49a5SDavid van Moolenbroek         return MAGIC_TYPE_WALK_STOP;
182*b2ed49a5SDavid van Moolenbroek     }
183*b2ed49a5SDavid van Moolenbroek 
184*b2ed49a5SDavid van Moolenbroek     return MAGIC_TYPE_WALK_CONTINUE;
185*b2ed49a5SDavid van Moolenbroek }
186*b2ed49a5SDavid van Moolenbroek 
187*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
188*b2ed49a5SDavid van Moolenbroek  *                        magic_selement_print_value                         *
189*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_print_value(const _magic_selement_t * selement)190*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_selement_print_value(const _magic_selement_t *selement)
191*b2ed49a5SDavid van Moolenbroek {
192*b2ed49a5SDavid van Moolenbroek     int type_id = selement->type->type_id;
193*b2ed49a5SDavid van Moolenbroek     unsigned size = selement->type->size;
194*b2ed49a5SDavid van Moolenbroek     double dvalue;
195*b2ed49a5SDavid van Moolenbroek     void *pvalue;
196*b2ed49a5SDavid van Moolenbroek     unsigned long uvalue;
197*b2ed49a5SDavid van Moolenbroek     long ivalue;
198*b2ed49a5SDavid van Moolenbroek     char vvalue;
199*b2ed49a5SDavid van Moolenbroek     switch(type_id) {
200*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_FLOAT:
201*b2ed49a5SDavid van Moolenbroek             dvalue = magic_selement_to_float(selement);
202*b2ed49a5SDavid van Moolenbroek             _magic_printf("float(%d):%g", size, dvalue);
203*b2ed49a5SDavid van Moolenbroek             _magic_printf("/%d", (long) dvalue);
204*b2ed49a5SDavid van Moolenbroek         break;
205*b2ed49a5SDavid van Moolenbroek 
206*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_POINTER:
207*b2ed49a5SDavid van Moolenbroek             pvalue = magic_selement_to_ptr(selement);
208*b2ed49a5SDavid van Moolenbroek             _magic_printf("ptr:%08x", pvalue);
209*b2ed49a5SDavid van Moolenbroek         break;
210*b2ed49a5SDavid van Moolenbroek 
211*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_INTEGER:
212*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_ENUM:
213*b2ed49a5SDavid van Moolenbroek             if(MAGIC_TYPE_FLAG(selement->type, MAGIC_TYPE_UNSIGNED)) {
214*b2ed49a5SDavid van Moolenbroek                 uvalue = magic_selement_to_unsigned(selement);
215*b2ed49a5SDavid van Moolenbroek                 _magic_printf("unsigned %s(%d):%u", type_id == MAGIC_TYPE_INTEGER ? "int" : "enum", size, uvalue);
216*b2ed49a5SDavid van Moolenbroek             }
217*b2ed49a5SDavid van Moolenbroek             else {
218*b2ed49a5SDavid van Moolenbroek                 ivalue = magic_selement_to_int(selement);
219*b2ed49a5SDavid van Moolenbroek                 _magic_printf("%s(%d):%d", type_id == MAGIC_TYPE_INTEGER ? "int" : "enum", size, ivalue);
220*b2ed49a5SDavid van Moolenbroek             }
221*b2ed49a5SDavid van Moolenbroek         break;
222*b2ed49a5SDavid van Moolenbroek 
223*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_VOID:
224*b2ed49a5SDavid van Moolenbroek             vvalue = *((char*) selement->address);
225*b2ed49a5SDavid van Moolenbroek             _magic_printf("void(%d):%d", size, vvalue);
226*b2ed49a5SDavid van Moolenbroek         break;
227*b2ed49a5SDavid van Moolenbroek 
228*b2ed49a5SDavid van Moolenbroek         default:
229*b2ed49a5SDavid van Moolenbroek             _magic_printf("???");
230*b2ed49a5SDavid van Moolenbroek         break;
231*b2ed49a5SDavid van Moolenbroek     }
232*b2ed49a5SDavid van Moolenbroek }
233*b2ed49a5SDavid van Moolenbroek 
234*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
235*b2ed49a5SDavid van Moolenbroek  *                         magic_selement_to_unsigned                        *
236*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_to_unsigned(const _magic_selement_t * selement)237*b2ed49a5SDavid van Moolenbroek PUBLIC unsigned long magic_selement_to_unsigned(const _magic_selement_t *selement)
238*b2ed49a5SDavid van Moolenbroek {
239*b2ed49a5SDavid van Moolenbroek     void *address = selement->address;
240*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type = selement->type;
241*b2ed49a5SDavid van Moolenbroek     unsigned long value = 0;
242*b2ed49a5SDavid van Moolenbroek     unsigned size = type->size;
243*b2ed49a5SDavid van Moolenbroek     assert(size > 0);
244*b2ed49a5SDavid van Moolenbroek     assert(type->type_id == MAGIC_TYPE_INTEGER
245*b2ed49a5SDavid van Moolenbroek         || type->type_id == MAGIC_TYPE_ENUM);
246*b2ed49a5SDavid van Moolenbroek 
247*b2ed49a5SDavid van Moolenbroek     if(address == NULL)
248*b2ed49a5SDavid van Moolenbroek 	return 0;
249*b2ed49a5SDavid van Moolenbroek 
250*b2ed49a5SDavid van Moolenbroek     if(size == sizeof(unsigned char)) {
251*b2ed49a5SDavid van Moolenbroek         value = (unsigned long) *((unsigned char*) address);
252*b2ed49a5SDavid van Moolenbroek     }
253*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(unsigned short)) {
254*b2ed49a5SDavid van Moolenbroek         value = (unsigned long) *((unsigned short*) address);
255*b2ed49a5SDavid van Moolenbroek     }
256*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_LONG_SUPPORTED
257*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(unsigned long long)) {
258*b2ed49a5SDavid van Moolenbroek         value = (unsigned long) *((unsigned long long*) address);
259*b2ed49a5SDavid van Moolenbroek     }
260*b2ed49a5SDavid van Moolenbroek #endif
261*b2ed49a5SDavid van Moolenbroek     else {
262*b2ed49a5SDavid van Moolenbroek         assert(size == sizeof(unsigned long));
263*b2ed49a5SDavid van Moolenbroek         value = *((unsigned long*) address);
264*b2ed49a5SDavid van Moolenbroek     }
265*b2ed49a5SDavid van Moolenbroek 
266*b2ed49a5SDavid van Moolenbroek     return value;
267*b2ed49a5SDavid van Moolenbroek }
268*b2ed49a5SDavid van Moolenbroek 
269*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
270*b2ed49a5SDavid van Moolenbroek  *                           magic_selement_to_int                           *
271*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_to_int(const _magic_selement_t * selement)272*b2ed49a5SDavid van Moolenbroek PUBLIC long magic_selement_to_int(const _magic_selement_t *selement)
273*b2ed49a5SDavid van Moolenbroek {
274*b2ed49a5SDavid van Moolenbroek     void *address = selement->address;
275*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type = selement->type;
276*b2ed49a5SDavid van Moolenbroek     long value = 0;
277*b2ed49a5SDavid van Moolenbroek     unsigned size = type->size;
278*b2ed49a5SDavid van Moolenbroek     assert(size > 0);
279*b2ed49a5SDavid van Moolenbroek     assert(type->type_id == MAGIC_TYPE_INTEGER
280*b2ed49a5SDavid van Moolenbroek         || type->type_id == MAGIC_TYPE_ENUM);
281*b2ed49a5SDavid van Moolenbroek 
282*b2ed49a5SDavid van Moolenbroek     if(address == NULL)
283*b2ed49a5SDavid van Moolenbroek 	return 0;
284*b2ed49a5SDavid van Moolenbroek 
285*b2ed49a5SDavid van Moolenbroek     if(size == sizeof(char)) {
286*b2ed49a5SDavid van Moolenbroek         value = (long) *((char*) address);
287*b2ed49a5SDavid van Moolenbroek     }
288*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(short)) {
289*b2ed49a5SDavid van Moolenbroek         value = (long) *((short*) address);
290*b2ed49a5SDavid van Moolenbroek     }
291*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_LONG_SUPPORTED
292*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(long long)) {
293*b2ed49a5SDavid van Moolenbroek         value = (long) *((long long*) address);
294*b2ed49a5SDavid van Moolenbroek     }
295*b2ed49a5SDavid van Moolenbroek #endif
296*b2ed49a5SDavid van Moolenbroek     else {
297*b2ed49a5SDavid van Moolenbroek         assert(size == sizeof(long));
298*b2ed49a5SDavid van Moolenbroek         value = *((long*) address);
299*b2ed49a5SDavid van Moolenbroek     }
300*b2ed49a5SDavid van Moolenbroek 
301*b2ed49a5SDavid van Moolenbroek     return value;
302*b2ed49a5SDavid van Moolenbroek }
303*b2ed49a5SDavid van Moolenbroek 
304*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_LONG_SUPPORTED
305*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
306*b2ed49a5SDavid van Moolenbroek  *                            magic_selement_to_llu                          *
307*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_to_llu(const _magic_selement_t * selement)308*b2ed49a5SDavid van Moolenbroek PUBLIC unsigned long long magic_selement_to_llu(const _magic_selement_t *selement)
309*b2ed49a5SDavid van Moolenbroek {
310*b2ed49a5SDavid van Moolenbroek     void *address = selement->address;
311*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type = selement->type;
312*b2ed49a5SDavid van Moolenbroek     unsigned long long value;
313*b2ed49a5SDavid van Moolenbroek     unsigned size = type->size;
314*b2ed49a5SDavid van Moolenbroek 
315*b2ed49a5SDavid van Moolenbroek     if(address == NULL)
316*b2ed49a5SDavid van Moolenbroek 	return 0;
317*b2ed49a5SDavid van Moolenbroek 
318*b2ed49a5SDavid van Moolenbroek     if (size == sizeof(unsigned long long))
319*b2ed49a5SDavid van Moolenbroek         value = *((unsigned long long*) address);
320*b2ed49a5SDavid van Moolenbroek     else
321*b2ed49a5SDavid van Moolenbroek         value = (unsigned long long) magic_selement_to_unsigned(selement);
322*b2ed49a5SDavid van Moolenbroek     return value;
323*b2ed49a5SDavid van Moolenbroek }
324*b2ed49a5SDavid van Moolenbroek 
325*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
326*b2ed49a5SDavid van Moolenbroek  *                            magic_selement_to_ll                           *
327*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_to_ll(const _magic_selement_t * selement)328*b2ed49a5SDavid van Moolenbroek PUBLIC long long magic_selement_to_ll(const _magic_selement_t *selement)
329*b2ed49a5SDavid van Moolenbroek {
330*b2ed49a5SDavid van Moolenbroek     void *address = selement->address;
331*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type = selement->type;
332*b2ed49a5SDavid van Moolenbroek     long long value;
333*b2ed49a5SDavid van Moolenbroek     unsigned size = type->size;
334*b2ed49a5SDavid van Moolenbroek 
335*b2ed49a5SDavid van Moolenbroek     if(address == NULL)
336*b2ed49a5SDavid van Moolenbroek 	return 0;
337*b2ed49a5SDavid van Moolenbroek 
338*b2ed49a5SDavid van Moolenbroek     if (size == sizeof(long long))
339*b2ed49a5SDavid van Moolenbroek         value = *((long long*) address);
340*b2ed49a5SDavid van Moolenbroek     else
341*b2ed49a5SDavid van Moolenbroek         value = (long long) magic_selement_to_int(selement);
342*b2ed49a5SDavid van Moolenbroek     return value;
343*b2ed49a5SDavid van Moolenbroek }
344*b2ed49a5SDavid van Moolenbroek #endif
345*b2ed49a5SDavid van Moolenbroek 
346*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
347*b2ed49a5SDavid van Moolenbroek  *                          magic_selement_to_float                          *
348*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_to_float(const _magic_selement_t * selement)349*b2ed49a5SDavid van Moolenbroek PUBLIC double magic_selement_to_float(const _magic_selement_t *selement)
350*b2ed49a5SDavid van Moolenbroek {
351*b2ed49a5SDavid van Moolenbroek     void *address = selement->address;
352*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type = selement->type;
353*b2ed49a5SDavid van Moolenbroek     double value = 0.0;
354*b2ed49a5SDavid van Moolenbroek     unsigned size = type->size;
355*b2ed49a5SDavid van Moolenbroek     assert(size > 0);
356*b2ed49a5SDavid van Moolenbroek     assert(type->type_id == MAGIC_TYPE_FLOAT);
357*b2ed49a5SDavid van Moolenbroek 
358*b2ed49a5SDavid van Moolenbroek     if(address == NULL)
359*b2ed49a5SDavid van Moolenbroek 	return 0;
360*b2ed49a5SDavid van Moolenbroek 
361*b2ed49a5SDavid van Moolenbroek     if(size == sizeof(float)) {
362*b2ed49a5SDavid van Moolenbroek         value = (double) *((float*) address);
363*b2ed49a5SDavid van Moolenbroek     }
364*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_DOUBLE_SUPPORTED
365*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(long double)) {
366*b2ed49a5SDavid van Moolenbroek         value = (double) *((long double*) address);
367*b2ed49a5SDavid van Moolenbroek     }
368*b2ed49a5SDavid van Moolenbroek #endif
369*b2ed49a5SDavid van Moolenbroek     else {
370*b2ed49a5SDavid van Moolenbroek         assert(size == sizeof(double));
371*b2ed49a5SDavid van Moolenbroek         value = *((double*) address);
372*b2ed49a5SDavid van Moolenbroek     }
373*b2ed49a5SDavid van Moolenbroek 
374*b2ed49a5SDavid van Moolenbroek     return value;
375*b2ed49a5SDavid van Moolenbroek }
376*b2ed49a5SDavid van Moolenbroek 
377*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
378*b2ed49a5SDavid van Moolenbroek  *                           magic_selement_to_ptr                           *
379*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_to_ptr(const _magic_selement_t * selement)380*b2ed49a5SDavid van Moolenbroek PUBLIC void* magic_selement_to_ptr(const _magic_selement_t *selement)
381*b2ed49a5SDavid van Moolenbroek {
382*b2ed49a5SDavid van Moolenbroek     void *address = selement->address;
383*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type = selement->type;
384*b2ed49a5SDavid van Moolenbroek     void* value = NULL;
385*b2ed49a5SDavid van Moolenbroek     assert(type->type_id == MAGIC_TYPE_POINTER);
386*b2ed49a5SDavid van Moolenbroek 
387*b2ed49a5SDavid van Moolenbroek     if (!address)
388*b2ed49a5SDavid van Moolenbroek         return NULL;
389*b2ed49a5SDavid van Moolenbroek     value = *((void**) address);
390*b2ed49a5SDavid van Moolenbroek     return value;
391*b2ed49a5SDavid van Moolenbroek }
392*b2ed49a5SDavid van Moolenbroek 
393*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
394*b2ed49a5SDavid van Moolenbroek  *                         magic_selement_from_unsigned                      *
395*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_from_unsigned(const _magic_selement_t * selement,unsigned long value)396*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_selement_from_unsigned(const _magic_selement_t *selement, unsigned long value)
397*b2ed49a5SDavid van Moolenbroek {
398*b2ed49a5SDavid van Moolenbroek     void *address = selement->address;
399*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type = selement->type;
400*b2ed49a5SDavid van Moolenbroek     unsigned size = type->size;
401*b2ed49a5SDavid van Moolenbroek     assert(size > 0);
402*b2ed49a5SDavid van Moolenbroek     assert(type->type_id == MAGIC_TYPE_INTEGER
403*b2ed49a5SDavid van Moolenbroek         || type->type_id == MAGIC_TYPE_ENUM);
404*b2ed49a5SDavid van Moolenbroek 
405*b2ed49a5SDavid van Moolenbroek     /* Prevent a store to NULL. */
406*b2ed49a5SDavid van Moolenbroek     if(address == NULL)
407*b2ed49a5SDavid van Moolenbroek 	return;
408*b2ed49a5SDavid van Moolenbroek 
409*b2ed49a5SDavid van Moolenbroek     if(size == sizeof(unsigned char)) {
410*b2ed49a5SDavid van Moolenbroek         *((unsigned char*) address) = (unsigned char) value;
411*b2ed49a5SDavid van Moolenbroek     }
412*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(unsigned short)) {
413*b2ed49a5SDavid van Moolenbroek         *((unsigned short*) address) = (unsigned short) value;
414*b2ed49a5SDavid van Moolenbroek     }
415*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_LONG_SUPPORTED
416*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(unsigned long long)) {
417*b2ed49a5SDavid van Moolenbroek         *((unsigned long long*) address) = (unsigned long long) value;
418*b2ed49a5SDavid van Moolenbroek     }
419*b2ed49a5SDavid van Moolenbroek #endif
420*b2ed49a5SDavid van Moolenbroek     else {
421*b2ed49a5SDavid van Moolenbroek         assert(size == sizeof(unsigned long));
422*b2ed49a5SDavid van Moolenbroek         *((unsigned long*) address) = (unsigned long) value;
423*b2ed49a5SDavid van Moolenbroek     }
424*b2ed49a5SDavid van Moolenbroek }
425*b2ed49a5SDavid van Moolenbroek 
426*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
427*b2ed49a5SDavid van Moolenbroek  *                           magic_selement_from_int                         *
428*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_from_int(const _magic_selement_t * selement,long value)429*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_selement_from_int(const _magic_selement_t *selement, long value)
430*b2ed49a5SDavid van Moolenbroek {
431*b2ed49a5SDavid van Moolenbroek     void *address = selement->address;
432*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type = selement->type;
433*b2ed49a5SDavid van Moolenbroek     unsigned size = type->size;
434*b2ed49a5SDavid van Moolenbroek     assert(size > 0);
435*b2ed49a5SDavid van Moolenbroek     assert(type->type_id == MAGIC_TYPE_INTEGER
436*b2ed49a5SDavid van Moolenbroek         || type->type_id == MAGIC_TYPE_ENUM);
437*b2ed49a5SDavid van Moolenbroek 
438*b2ed49a5SDavid van Moolenbroek     /* Prevent a store to NULL. */
439*b2ed49a5SDavid van Moolenbroek     if(address == NULL)
440*b2ed49a5SDavid van Moolenbroek 	return;
441*b2ed49a5SDavid van Moolenbroek 
442*b2ed49a5SDavid van Moolenbroek     if(size == sizeof(char)) {
443*b2ed49a5SDavid van Moolenbroek         *((char*) address) = (char) value;
444*b2ed49a5SDavid van Moolenbroek     }
445*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(short)) {
446*b2ed49a5SDavid van Moolenbroek         *((short*) address) = (short) value;
447*b2ed49a5SDavid van Moolenbroek     }
448*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_LONG_SUPPORTED
449*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(long long)) {
450*b2ed49a5SDavid van Moolenbroek         *((long long*) address) = (long long) value;
451*b2ed49a5SDavid van Moolenbroek     }
452*b2ed49a5SDavid van Moolenbroek #endif
453*b2ed49a5SDavid van Moolenbroek     else {
454*b2ed49a5SDavid van Moolenbroek         assert(size == sizeof(long));
455*b2ed49a5SDavid van Moolenbroek         *((long*) address) = (long) value;
456*b2ed49a5SDavid van Moolenbroek     }
457*b2ed49a5SDavid van Moolenbroek }
458*b2ed49a5SDavid van Moolenbroek 
459*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
460*b2ed49a5SDavid van Moolenbroek  *                          magic_selement_from_float                        *
461*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_from_float(const _magic_selement_t * selement,double value)462*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_selement_from_float(const _magic_selement_t *selement, double value)
463*b2ed49a5SDavid van Moolenbroek {
464*b2ed49a5SDavid van Moolenbroek     void *address = selement->address;
465*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* type = selement->type;
466*b2ed49a5SDavid van Moolenbroek     unsigned size = type->size;
467*b2ed49a5SDavid van Moolenbroek     assert(size > 0);
468*b2ed49a5SDavid van Moolenbroek     assert(type->type_id == MAGIC_TYPE_FLOAT);
469*b2ed49a5SDavid van Moolenbroek 
470*b2ed49a5SDavid van Moolenbroek     /* Prevent a store to NULL. */
471*b2ed49a5SDavid van Moolenbroek     if(address == NULL)
472*b2ed49a5SDavid van Moolenbroek 	return;
473*b2ed49a5SDavid van Moolenbroek 
474*b2ed49a5SDavid van Moolenbroek     if(size == sizeof(float)) {
475*b2ed49a5SDavid van Moolenbroek         *((float*) address) = (float) value;
476*b2ed49a5SDavid van Moolenbroek     }
477*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_DOUBLE_SUPPORTED
478*b2ed49a5SDavid van Moolenbroek     else if(size == sizeof(long double)) {
479*b2ed49a5SDavid van Moolenbroek         *((long double*) address) = (long double) value;
480*b2ed49a5SDavid van Moolenbroek     }
481*b2ed49a5SDavid van Moolenbroek #endif
482*b2ed49a5SDavid van Moolenbroek     else {
483*b2ed49a5SDavid van Moolenbroek         assert(size == sizeof(double));
484*b2ed49a5SDavid van Moolenbroek         *((double*) address) = (double) value;
485*b2ed49a5SDavid van Moolenbroek     }
486*b2ed49a5SDavid van Moolenbroek }
487*b2ed49a5SDavid van Moolenbroek 
488*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
489*b2ed49a5SDavid van Moolenbroek  *                      magic_selement_ptr_value_cast                        *
490*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_ptr_value_cast(const _magic_selement_t * src_selement,const _magic_selement_t * dst_selement,void * value_buffer)491*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_selement_ptr_value_cast(const _magic_selement_t *src_selement, const _magic_selement_t *dst_selement, void* value_buffer)
492*b2ed49a5SDavid van Moolenbroek {
493*b2ed49a5SDavid van Moolenbroek     int src_type_id = src_selement->type->type_id;
494*b2ed49a5SDavid van Moolenbroek     int dst_type_id = dst_selement->type->type_id;
495*b2ed49a5SDavid van Moolenbroek     unsigned src_size = src_selement->type->size;
496*b2ed49a5SDavid van Moolenbroek     unsigned dst_size = dst_selement->type->size;
497*b2ed49a5SDavid van Moolenbroek     void* src_value;
498*b2ed49a5SDavid van Moolenbroek     int r = 0;
499*b2ed49a5SDavid van Moolenbroek     assert(dst_size > 0);
500*b2ed49a5SDavid van Moolenbroek 
501*b2ed49a5SDavid van Moolenbroek     if(dst_type_id != MAGIC_TYPE_POINTER) {
502*b2ed49a5SDavid van Moolenbroek         return EINVAL;
503*b2ed49a5SDavid van Moolenbroek     }
504*b2ed49a5SDavid van Moolenbroek     assert(dst_size == sizeof(void*));
505*b2ed49a5SDavid van Moolenbroek     if(src_size != sizeof(void*)) {
506*b2ed49a5SDavid van Moolenbroek         return EINVAL;
507*b2ed49a5SDavid van Moolenbroek     }
508*b2ed49a5SDavid van Moolenbroek     switch(src_type_id) {
509*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_POINTER:
510*b2ed49a5SDavid van Moolenbroek             return 0;
511*b2ed49a5SDavid van Moolenbroek         break;
512*b2ed49a5SDavid van Moolenbroek 
513*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_INTEGER:
514*b2ed49a5SDavid van Moolenbroek             if(MAGIC_TYPE_FLAG(src_selement->type, MAGIC_TYPE_UNSIGNED)) {
515*b2ed49a5SDavid van Moolenbroek                 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_unsigned(src_selement), unsigned long, src_value, void*, &r, 0);
516*b2ed49a5SDavid van Moolenbroek                 assert(r == 0);
517*b2ed49a5SDavid van Moolenbroek             }
518*b2ed49a5SDavid van Moolenbroek             else {
519*b2ed49a5SDavid van Moolenbroek                 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_int(src_selement), long, src_value, void*, &r, 0);
520*b2ed49a5SDavid van Moolenbroek                 assert(r == 0);
521*b2ed49a5SDavid van Moolenbroek             }
522*b2ed49a5SDavid van Moolenbroek         break;
523*b2ed49a5SDavid van Moolenbroek 
524*b2ed49a5SDavid van Moolenbroek         default:
525*b2ed49a5SDavid van Moolenbroek             return EINVAL;
526*b2ed49a5SDavid van Moolenbroek         break;
527*b2ed49a5SDavid van Moolenbroek     }
528*b2ed49a5SDavid van Moolenbroek 
529*b2ed49a5SDavid van Moolenbroek     MAGIC_CHECKED_VALUE_DST_CAST(src_value, void*, value_buffer, void*, &r);
530*b2ed49a5SDavid van Moolenbroek     assert(r == 0);
531*b2ed49a5SDavid van Moolenbroek 
532*b2ed49a5SDavid van Moolenbroek     return dst_size;
533*b2ed49a5SDavid van Moolenbroek }
534*b2ed49a5SDavid van Moolenbroek 
535*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
536*b2ed49a5SDavid van Moolenbroek  *                    magic_selement_unsigned_value_cast                     *
537*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_unsigned_value_cast(const _magic_selement_t * src_selement,const _magic_selement_t * dst_selement,void * value_buffer)538*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_selement_unsigned_value_cast(const _magic_selement_t *src_selement, const _magic_selement_t *dst_selement, void* value_buffer)
539*b2ed49a5SDavid van Moolenbroek {
540*b2ed49a5SDavid van Moolenbroek     int src_type_id = src_selement->type->type_id;
541*b2ed49a5SDavid van Moolenbroek     int dst_type_id = dst_selement->type->type_id;
542*b2ed49a5SDavid van Moolenbroek     int r = 0;
543*b2ed49a5SDavid van Moolenbroek     unsigned src_size = src_selement->type->size;
544*b2ed49a5SDavid van Moolenbroek     unsigned dst_size = dst_selement->type->size;
545*b2ed49a5SDavid van Moolenbroek     unsigned long src_value;
546*b2ed49a5SDavid van Moolenbroek     assert(dst_size > 0);
547*b2ed49a5SDavid van Moolenbroek 
548*b2ed49a5SDavid van Moolenbroek     if(dst_type_id != MAGIC_TYPE_INTEGER && dst_type_id != MAGIC_TYPE_ENUM) {
549*b2ed49a5SDavid van Moolenbroek         return EINVAL;
550*b2ed49a5SDavid van Moolenbroek     }
551*b2ed49a5SDavid van Moolenbroek     switch(src_type_id) {
552*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_FLOAT:
553*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_float(src_selement), double, src_value, unsigned long, &r, 1);
554*b2ed49a5SDavid van Moolenbroek         break;
555*b2ed49a5SDavid van Moolenbroek 
556*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_POINTER:
557*b2ed49a5SDavid van Moolenbroek             if(dst_size != sizeof(void*)) {
558*b2ed49a5SDavid van Moolenbroek                 return EINVAL;
559*b2ed49a5SDavid van Moolenbroek             }
560*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_ptr(src_selement), void*, src_value, unsigned long, &r, 0);
561*b2ed49a5SDavid van Moolenbroek             assert(r == 0);
562*b2ed49a5SDavid van Moolenbroek         break;
563*b2ed49a5SDavid van Moolenbroek 
564*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_INTEGER:
565*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_ENUM:
566*b2ed49a5SDavid van Moolenbroek             if(src_size == dst_size && MAGIC_TYPE_FLAG(src_selement->type, MAGIC_TYPE_UNSIGNED) == MAGIC_TYPE_FLAG(dst_selement->type, MAGIC_TYPE_UNSIGNED)) {
567*b2ed49a5SDavid van Moolenbroek                 return 0;
568*b2ed49a5SDavid van Moolenbroek             }
569*b2ed49a5SDavid van Moolenbroek             if(MAGIC_TYPE_FLAG(src_selement->type, MAGIC_TYPE_UNSIGNED)) {
570*b2ed49a5SDavid van Moolenbroek                 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_unsigned(src_selement), unsigned long, src_value, unsigned long, &r, 0);
571*b2ed49a5SDavid van Moolenbroek                 assert(r == 0);
572*b2ed49a5SDavid van Moolenbroek             }
573*b2ed49a5SDavid van Moolenbroek             else {
574*b2ed49a5SDavid van Moolenbroek                 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_int(src_selement), long, src_value, unsigned long, &r, 1);
575*b2ed49a5SDavid van Moolenbroek             }
576*b2ed49a5SDavid van Moolenbroek         break;
577*b2ed49a5SDavid van Moolenbroek 
578*b2ed49a5SDavid van Moolenbroek         default:
579*b2ed49a5SDavid van Moolenbroek             return EINVAL;
580*b2ed49a5SDavid van Moolenbroek         break;
581*b2ed49a5SDavid van Moolenbroek     }
582*b2ed49a5SDavid van Moolenbroek 
583*b2ed49a5SDavid van Moolenbroek     switch(dst_size) {
584*b2ed49a5SDavid van Moolenbroek         case sizeof(unsigned char):
585*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, unsigned long, value_buffer, unsigned char, &r);
586*b2ed49a5SDavid van Moolenbroek         break;
587*b2ed49a5SDavid van Moolenbroek 
588*b2ed49a5SDavid van Moolenbroek         case sizeof(unsigned short):
589*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, unsigned long, value_buffer, unsigned short, &r);
590*b2ed49a5SDavid van Moolenbroek         break;
591*b2ed49a5SDavid van Moolenbroek 
592*b2ed49a5SDavid van Moolenbroek         case sizeof(unsigned int):
593*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, unsigned long, value_buffer, unsigned int, &r);
594*b2ed49a5SDavid van Moolenbroek         break;
595*b2ed49a5SDavid van Moolenbroek 
596*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_LONG_SUPPORTED
597*b2ed49a5SDavid van Moolenbroek         case sizeof(unsigned long long):
598*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, unsigned long, value_buffer, unsigned long long, &r);
599*b2ed49a5SDavid van Moolenbroek         break;
600*b2ed49a5SDavid van Moolenbroek #endif
601*b2ed49a5SDavid van Moolenbroek 
602*b2ed49a5SDavid van Moolenbroek         default:
603*b2ed49a5SDavid van Moolenbroek             return EINVAL;
604*b2ed49a5SDavid van Moolenbroek         break;
605*b2ed49a5SDavid van Moolenbroek     }
606*b2ed49a5SDavid van Moolenbroek 
607*b2ed49a5SDavid van Moolenbroek     if(r == 0) {
608*b2ed49a5SDavid van Moolenbroek         r = dst_size;
609*b2ed49a5SDavid van Moolenbroek     }
610*b2ed49a5SDavid van Moolenbroek 
611*b2ed49a5SDavid van Moolenbroek     return r;
612*b2ed49a5SDavid van Moolenbroek }
613*b2ed49a5SDavid van Moolenbroek 
614*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
615*b2ed49a5SDavid van Moolenbroek  *                      magic_selement_int_value_cast                        *
616*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_int_value_cast(const _magic_selement_t * src_selement,const _magic_selement_t * dst_selement,void * value_buffer)617*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_selement_int_value_cast(const _magic_selement_t *src_selement, const _magic_selement_t *dst_selement, void* value_buffer)
618*b2ed49a5SDavid van Moolenbroek {
619*b2ed49a5SDavid van Moolenbroek     int src_type_id = src_selement->type->type_id;
620*b2ed49a5SDavid van Moolenbroek     int dst_type_id = dst_selement->type->type_id;
621*b2ed49a5SDavid van Moolenbroek     int r = 0;
622*b2ed49a5SDavid van Moolenbroek     unsigned src_size = src_selement->type->size;
623*b2ed49a5SDavid van Moolenbroek     unsigned dst_size = dst_selement->type->size;
624*b2ed49a5SDavid van Moolenbroek     long src_value;
625*b2ed49a5SDavid van Moolenbroek     assert(dst_size > 0);
626*b2ed49a5SDavid van Moolenbroek 
627*b2ed49a5SDavid van Moolenbroek     if(dst_type_id != MAGIC_TYPE_INTEGER && dst_type_id != MAGIC_TYPE_ENUM) {
628*b2ed49a5SDavid van Moolenbroek         return EINVAL;
629*b2ed49a5SDavid van Moolenbroek     }
630*b2ed49a5SDavid van Moolenbroek 
631*b2ed49a5SDavid van Moolenbroek     switch(src_type_id) {
632*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_FLOAT:
633*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_float(src_selement), double, src_value, long, &r, 1);
634*b2ed49a5SDavid van Moolenbroek         break;
635*b2ed49a5SDavid van Moolenbroek 
636*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_POINTER:
637*b2ed49a5SDavid van Moolenbroek             if(dst_size != sizeof(void*)) {
638*b2ed49a5SDavid van Moolenbroek                 return EINVAL;
639*b2ed49a5SDavid van Moolenbroek             }
640*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_ptr(src_selement), void*, src_value, long, &r, 0);
641*b2ed49a5SDavid van Moolenbroek             assert(r == 0);
642*b2ed49a5SDavid van Moolenbroek         break;
643*b2ed49a5SDavid van Moolenbroek 
644*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_INTEGER:
645*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_ENUM:
646*b2ed49a5SDavid van Moolenbroek             if(src_size == dst_size && MAGIC_TYPE_FLAG(src_selement->type, MAGIC_TYPE_UNSIGNED) == MAGIC_TYPE_FLAG(dst_selement->type, MAGIC_TYPE_UNSIGNED)) {
647*b2ed49a5SDavid van Moolenbroek                 return 0;
648*b2ed49a5SDavid van Moolenbroek             }
649*b2ed49a5SDavid van Moolenbroek             if(MAGIC_TYPE_FLAG(src_selement->type, MAGIC_TYPE_UNSIGNED)) {
650*b2ed49a5SDavid van Moolenbroek                 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_unsigned(src_selement), unsigned long, src_value, long, &r, 1);
651*b2ed49a5SDavid van Moolenbroek             }
652*b2ed49a5SDavid van Moolenbroek             else {
653*b2ed49a5SDavid van Moolenbroek                 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_int(src_selement), long, src_value, long, &r, 0);
654*b2ed49a5SDavid van Moolenbroek                 assert(r == 0);
655*b2ed49a5SDavid van Moolenbroek             }
656*b2ed49a5SDavid van Moolenbroek         break;
657*b2ed49a5SDavid van Moolenbroek 
658*b2ed49a5SDavid van Moolenbroek         default:
659*b2ed49a5SDavid van Moolenbroek             return EINVAL;
660*b2ed49a5SDavid van Moolenbroek         break;
661*b2ed49a5SDavid van Moolenbroek     }
662*b2ed49a5SDavid van Moolenbroek 
663*b2ed49a5SDavid van Moolenbroek     switch(dst_size) {
664*b2ed49a5SDavid van Moolenbroek         case sizeof(char):
665*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, long, value_buffer, char, &r);
666*b2ed49a5SDavid van Moolenbroek         break;
667*b2ed49a5SDavid van Moolenbroek 
668*b2ed49a5SDavid van Moolenbroek         case sizeof(short):
669*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, long, value_buffer, short, &r);
670*b2ed49a5SDavid van Moolenbroek         break;
671*b2ed49a5SDavid van Moolenbroek 
672*b2ed49a5SDavid van Moolenbroek         case sizeof(int):
673*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, long, value_buffer, int, &r);
674*b2ed49a5SDavid van Moolenbroek         break;
675*b2ed49a5SDavid van Moolenbroek 
676*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_LONG_SUPPORTED
677*b2ed49a5SDavid van Moolenbroek         case sizeof(long long):
678*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, long, value_buffer, long long, &r);
679*b2ed49a5SDavid van Moolenbroek         break;
680*b2ed49a5SDavid van Moolenbroek #endif
681*b2ed49a5SDavid van Moolenbroek 
682*b2ed49a5SDavid van Moolenbroek         default:
683*b2ed49a5SDavid van Moolenbroek             return EINVAL;
684*b2ed49a5SDavid van Moolenbroek         break;
685*b2ed49a5SDavid van Moolenbroek     }
686*b2ed49a5SDavid van Moolenbroek 
687*b2ed49a5SDavid van Moolenbroek     if(r == 0) {
688*b2ed49a5SDavid van Moolenbroek         r = dst_size;
689*b2ed49a5SDavid van Moolenbroek     }
690*b2ed49a5SDavid van Moolenbroek 
691*b2ed49a5SDavid van Moolenbroek     return r;
692*b2ed49a5SDavid van Moolenbroek }
693*b2ed49a5SDavid van Moolenbroek 
694*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
695*b2ed49a5SDavid van Moolenbroek  *                      magic_selement_float_value_cast                      *
696*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_float_value_cast(const _magic_selement_t * src_selement,const _magic_selement_t * dst_selement,void * value_buffer)697*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_selement_float_value_cast(const _magic_selement_t *src_selement, const _magic_selement_t *dst_selement, void* value_buffer)
698*b2ed49a5SDavid van Moolenbroek {
699*b2ed49a5SDavid van Moolenbroek     int src_type_id = src_selement->type->type_id;
700*b2ed49a5SDavid van Moolenbroek     int dst_type_id = dst_selement->type->type_id;
701*b2ed49a5SDavid van Moolenbroek     int r = 0;
702*b2ed49a5SDavid van Moolenbroek     unsigned src_size = src_selement->type->size;
703*b2ed49a5SDavid van Moolenbroek     unsigned dst_size = dst_selement->type->size;
704*b2ed49a5SDavid van Moolenbroek     double src_value;
705*b2ed49a5SDavid van Moolenbroek     assert(dst_size > 0);
706*b2ed49a5SDavid van Moolenbroek 
707*b2ed49a5SDavid van Moolenbroek     if(dst_type_id != MAGIC_TYPE_FLOAT) {
708*b2ed49a5SDavid van Moolenbroek         return EINVAL;
709*b2ed49a5SDavid van Moolenbroek     }
710*b2ed49a5SDavid van Moolenbroek     switch(src_type_id) {
711*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_FLOAT:
712*b2ed49a5SDavid van Moolenbroek             if(src_size == dst_size) {
713*b2ed49a5SDavid van Moolenbroek                 return 0;
714*b2ed49a5SDavid van Moolenbroek             }
715*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_float(src_selement), double, src_value, double, &r, 0);
716*b2ed49a5SDavid van Moolenbroek             assert(r == 0);
717*b2ed49a5SDavid van Moolenbroek         break;
718*b2ed49a5SDavid van Moolenbroek 
719*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_INTEGER:
720*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_ENUM:
721*b2ed49a5SDavid van Moolenbroek             if(MAGIC_TYPE_FLAG(src_selement->type, MAGIC_TYPE_UNSIGNED)) {
722*b2ed49a5SDavid van Moolenbroek                 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_unsigned(src_selement), unsigned long, src_value, double, &r, 1);
723*b2ed49a5SDavid van Moolenbroek             }
724*b2ed49a5SDavid van Moolenbroek             else {
725*b2ed49a5SDavid van Moolenbroek                 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_int(src_selement), long, src_value, double, &r, 1);
726*b2ed49a5SDavid van Moolenbroek             }
727*b2ed49a5SDavid van Moolenbroek         break;
728*b2ed49a5SDavid van Moolenbroek 
729*b2ed49a5SDavid van Moolenbroek         default:
730*b2ed49a5SDavid van Moolenbroek             return EINVAL;
731*b2ed49a5SDavid van Moolenbroek         break;
732*b2ed49a5SDavid van Moolenbroek     }
733*b2ed49a5SDavid van Moolenbroek 
734*b2ed49a5SDavid van Moolenbroek 
735*b2ed49a5SDavid van Moolenbroek     switch(dst_size) {
736*b2ed49a5SDavid van Moolenbroek         case sizeof(float):
737*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, double, value_buffer, float, &r);
738*b2ed49a5SDavid van Moolenbroek         break;
739*b2ed49a5SDavid van Moolenbroek 
740*b2ed49a5SDavid van Moolenbroek         case sizeof(double):
741*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, double, value_buffer, double, &r);
742*b2ed49a5SDavid van Moolenbroek         break;
743*b2ed49a5SDavid van Moolenbroek 
744*b2ed49a5SDavid van Moolenbroek #ifdef MAGIC_LONG_DOUBLE_SUPPORTED
745*b2ed49a5SDavid van Moolenbroek         case sizeof(long double):
746*b2ed49a5SDavid van Moolenbroek             MAGIC_CHECKED_VALUE_DST_CAST(src_value, double, value_buffer, long double, &r);
747*b2ed49a5SDavid van Moolenbroek         break;
748*b2ed49a5SDavid van Moolenbroek #endif
749*b2ed49a5SDavid van Moolenbroek 
750*b2ed49a5SDavid van Moolenbroek         default:
751*b2ed49a5SDavid van Moolenbroek             return EINVAL;
752*b2ed49a5SDavid van Moolenbroek         break;
753*b2ed49a5SDavid van Moolenbroek     }
754*b2ed49a5SDavid van Moolenbroek 
755*b2ed49a5SDavid van Moolenbroek     if(r == 0) {
756*b2ed49a5SDavid van Moolenbroek         r = dst_size;
757*b2ed49a5SDavid van Moolenbroek     }
758*b2ed49a5SDavid van Moolenbroek 
759*b2ed49a5SDavid van Moolenbroek     return r;
760*b2ed49a5SDavid van Moolenbroek }
761*b2ed49a5SDavid van Moolenbroek 
762*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
763*b2ed49a5SDavid van Moolenbroek  *                         magic_selement_value_cast                         *
764*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_value_cast(const _magic_selement_t * src_selement,const _magic_selement_t * dst_selement,void * value_buffer)765*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_selement_value_cast(const _magic_selement_t *src_selement, const _magic_selement_t *dst_selement, void* value_buffer)
766*b2ed49a5SDavid van Moolenbroek {
767*b2ed49a5SDavid van Moolenbroek     int r, src_type_id, dst_type_id;
768*b2ed49a5SDavid van Moolenbroek     size_t src_size, dst_size;
769*b2ed49a5SDavid van Moolenbroek     src_type_id = src_selement->type->type_id;
770*b2ed49a5SDavid van Moolenbroek     dst_type_id = dst_selement->type->type_id;
771*b2ed49a5SDavid van Moolenbroek     src_size = src_selement->type->size;
772*b2ed49a5SDavid van Moolenbroek     dst_size = dst_selement->type->size;
773*b2ed49a5SDavid van Moolenbroek     if(src_type_id == dst_type_id && src_size == dst_size && MAGIC_TYPE_FLAG(src_selement->type, MAGIC_TYPE_UNSIGNED) == MAGIC_TYPE_FLAG(dst_selement->type, MAGIC_TYPE_UNSIGNED)) {
774*b2ed49a5SDavid van Moolenbroek         return 0;
775*b2ed49a5SDavid van Moolenbroek     }
776*b2ed49a5SDavid van Moolenbroek 
777*b2ed49a5SDavid van Moolenbroek     /* No size change allowed in opaque value casts. */
778*b2ed49a5SDavid van Moolenbroek     if(src_type_id == MAGIC_TYPE_OPAQUE || dst_type_id == MAGIC_TYPE_OPAQUE) {
779*b2ed49a5SDavid van Moolenbroek         return src_size == dst_size ? 0 : EINVAL;
780*b2ed49a5SDavid van Moolenbroek     }
781*b2ed49a5SDavid van Moolenbroek 
782*b2ed49a5SDavid van Moolenbroek     /* No size change allowed in void value casts. */
783*b2ed49a5SDavid van Moolenbroek     if(src_type_id == MAGIC_TYPE_VOID || dst_type_id == MAGIC_TYPE_VOID) {
784*b2ed49a5SDavid van Moolenbroek         return src_size == dst_size ? 0 : EINVAL;
785*b2ed49a5SDavid van Moolenbroek     }
786*b2ed49a5SDavid van Moolenbroek 
787*b2ed49a5SDavid van Moolenbroek     switch(dst_type_id) {
788*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_POINTER:
789*b2ed49a5SDavid van Moolenbroek             /* Cast to pointer values. */
790*b2ed49a5SDavid van Moolenbroek             r = magic_selement_ptr_value_cast(src_selement, dst_selement, value_buffer);
791*b2ed49a5SDavid van Moolenbroek         break;
792*b2ed49a5SDavid van Moolenbroek 
793*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_FLOAT:
794*b2ed49a5SDavid van Moolenbroek             /* Cast to float values. */
795*b2ed49a5SDavid van Moolenbroek             r = magic_selement_float_value_cast(src_selement, dst_selement, value_buffer);
796*b2ed49a5SDavid van Moolenbroek         break;
797*b2ed49a5SDavid van Moolenbroek 
798*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_INTEGER:
799*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_ENUM:
800*b2ed49a5SDavid van Moolenbroek             if(MAGIC_TYPE_FLAG(dst_selement->type, MAGIC_TYPE_UNSIGNED)) {
801*b2ed49a5SDavid van Moolenbroek                 /* Cast to unsigned values. */
802*b2ed49a5SDavid van Moolenbroek                 r = magic_selement_unsigned_value_cast(src_selement, dst_selement, value_buffer);
803*b2ed49a5SDavid van Moolenbroek             }
804*b2ed49a5SDavid van Moolenbroek             else {
805*b2ed49a5SDavid van Moolenbroek                 /* Cast to integer values. */
806*b2ed49a5SDavid van Moolenbroek                 r = magic_selement_int_value_cast(src_selement, dst_selement, value_buffer);
807*b2ed49a5SDavid van Moolenbroek             }
808*b2ed49a5SDavid van Moolenbroek         break;
809*b2ed49a5SDavid van Moolenbroek 
810*b2ed49a5SDavid van Moolenbroek         default:
811*b2ed49a5SDavid van Moolenbroek             r = EINVAL;
812*b2ed49a5SDavid van Moolenbroek         break;
813*b2ed49a5SDavid van Moolenbroek     }
814*b2ed49a5SDavid van Moolenbroek     return r;
815*b2ed49a5SDavid van Moolenbroek }
816*b2ed49a5SDavid van Moolenbroek 
817*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
818*b2ed49a5SDavid van Moolenbroek  *                         magic_selement_get_parent                         *
819*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_get_parent(const _magic_selement_t * selement,_magic_selement_t * parent_selement)820*b2ed49a5SDavid van Moolenbroek PUBLIC _magic_selement_t* magic_selement_get_parent(
821*b2ed49a5SDavid van Moolenbroek     const _magic_selement_t *selement, _magic_selement_t *parent_selement)
822*b2ed49a5SDavid van Moolenbroek {
823*b2ed49a5SDavid van Moolenbroek     if(!selement->parent_type) {
824*b2ed49a5SDavid van Moolenbroek         return NULL;
825*b2ed49a5SDavid van Moolenbroek     }
826*b2ed49a5SDavid van Moolenbroek 
827*b2ed49a5SDavid van Moolenbroek     parent_selement->sentry = selement->sentry;
828*b2ed49a5SDavid van Moolenbroek     parent_selement->parent_type = NULL;
829*b2ed49a5SDavid van Moolenbroek     parent_selement->child_num = 0;
830*b2ed49a5SDavid van Moolenbroek     parent_selement->type = selement->parent_type;
831*b2ed49a5SDavid van Moolenbroek     parent_selement->address = selement->parent_address;
832*b2ed49a5SDavid van Moolenbroek     parent_selement->num = 0;
833*b2ed49a5SDavid van Moolenbroek     assert(parent_selement->address >= parent_selement->sentry->address);
834*b2ed49a5SDavid van Moolenbroek 
835*b2ed49a5SDavid van Moolenbroek     return parent_selement;
836*b2ed49a5SDavid van Moolenbroek }
837*b2ed49a5SDavid van Moolenbroek 
838*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
839*b2ed49a5SDavid van Moolenbroek  *                    magic_selement_fill_from_parent_info                   *
840*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_fill_from_parent_info(_magic_selement_t * selement,int walk_flags)841*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_selement_fill_from_parent_info(_magic_selement_t *selement,
842*b2ed49a5SDavid van Moolenbroek     int walk_flags)
843*b2ed49a5SDavid van Moolenbroek {
844*b2ed49a5SDavid van Moolenbroek     unsigned offset;
845*b2ed49a5SDavid van Moolenbroek     magic_type_walk_step(selement->parent_type,
846*b2ed49a5SDavid van Moolenbroek         selement->child_num, &selement->type, &offset, walk_flags);
847*b2ed49a5SDavid van Moolenbroek     selement->address = (char*) selement->parent_address + offset;
848*b2ed49a5SDavid van Moolenbroek }
849*b2ed49a5SDavid van Moolenbroek 
850*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
851*b2ed49a5SDavid van Moolenbroek  *                         magic_selement_from_sentry                        *
852*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_from_sentry(struct _magic_sentry * sentry,_magic_selement_t * selement)853*b2ed49a5SDavid van Moolenbroek PUBLIC _magic_selement_t* magic_selement_from_sentry(struct _magic_sentry *sentry,
854*b2ed49a5SDavid van Moolenbroek     _magic_selement_t *selement)
855*b2ed49a5SDavid van Moolenbroek {
856*b2ed49a5SDavid van Moolenbroek     selement->sentry = sentry;
857*b2ed49a5SDavid van Moolenbroek     selement->parent_type = NULL;
858*b2ed49a5SDavid van Moolenbroek     selement->child_num = 0;
859*b2ed49a5SDavid van Moolenbroek     selement->type = sentry->type;
860*b2ed49a5SDavid van Moolenbroek     selement->address = sentry->address;
861*b2ed49a5SDavid van Moolenbroek     selement->num = 1;
862*b2ed49a5SDavid van Moolenbroek 
863*b2ed49a5SDavid van Moolenbroek     return selement;
864*b2ed49a5SDavid van Moolenbroek }
865*b2ed49a5SDavid van Moolenbroek 
866*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
867*b2ed49a5SDavid van Moolenbroek  *                      magic_selement_from_relative_name                    *
868*b2ed49a5SDavid van Moolenbroek  *===========================================================================*/
magic_selement_from_relative_name(_magic_selement_t * parent_selement,_magic_selement_t * selement,char * name)869*b2ed49a5SDavid van Moolenbroek PUBLIC _magic_selement_t* magic_selement_from_relative_name(
870*b2ed49a5SDavid van Moolenbroek     _magic_selement_t *parent_selement, _magic_selement_t *selement, char* name)
871*b2ed49a5SDavid van Moolenbroek {
872*b2ed49a5SDavid van Moolenbroek     _magic_selement_t new_parent_selement;
873*b2ed49a5SDavid van Moolenbroek     const struct _magic_type* parent_type = parent_selement->type;
874*b2ed49a5SDavid van Moolenbroek     int parent_type_id = parent_type->type_id;
875*b2ed49a5SDavid van Moolenbroek     int walk_flags = 0;
876*b2ed49a5SDavid van Moolenbroek     int i, child_num = -1;
877*b2ed49a5SDavid van Moolenbroek     char *end;
878*b2ed49a5SDavid van Moolenbroek 
879*b2ed49a5SDavid van Moolenbroek     if(!name || *name == '\0') {
880*b2ed49a5SDavid van Moolenbroek         return NULL;
881*b2ed49a5SDavid van Moolenbroek     }
882*b2ed49a5SDavid van Moolenbroek 
883*b2ed49a5SDavid van Moolenbroek     if(parent_type_id == MAGIC_TYPE_UNION && (*name >= '0' && *name <= '9')) {
884*b2ed49a5SDavid van Moolenbroek         parent_type_id = MAGIC_TYPE_ARRAY;
885*b2ed49a5SDavid van Moolenbroek         walk_flags = MAGIC_TYPE_WALK_UNIONS_AS_VOID;
886*b2ed49a5SDavid van Moolenbroek     }
887*b2ed49a5SDavid van Moolenbroek 
888*b2ed49a5SDavid van Moolenbroek     switch(parent_type_id) {
889*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_ARRAY:
890*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_VECTOR:
891*b2ed49a5SDavid van Moolenbroek             child_num = (int) strtol(name, &end, 10);
892*b2ed49a5SDavid van Moolenbroek             if(end == name || *end != '\0' || errno == ERANGE) {
893*b2ed49a5SDavid van Moolenbroek                 return NULL;
894*b2ed49a5SDavid van Moolenbroek             }
895*b2ed49a5SDavid van Moolenbroek         break;
896*b2ed49a5SDavid van Moolenbroek 
897*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_STRUCT:
898*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_UNION:
899*b2ed49a5SDavid van Moolenbroek             for(i=0; (unsigned int)i<parent_type->num_child_types;i++) {
900*b2ed49a5SDavid van Moolenbroek                 if(!strcmp(parent_type->member_names[i], name)) {
901*b2ed49a5SDavid van Moolenbroek                     child_num = i;
902*b2ed49a5SDavid van Moolenbroek                     break;
903*b2ed49a5SDavid van Moolenbroek                 }
904*b2ed49a5SDavid van Moolenbroek             }
905*b2ed49a5SDavid van Moolenbroek             if((unsigned int)i == parent_type->num_child_types) {
906*b2ed49a5SDavid van Moolenbroek                 return NULL;
907*b2ed49a5SDavid van Moolenbroek             }
908*b2ed49a5SDavid van Moolenbroek         break;
909*b2ed49a5SDavid van Moolenbroek 
910*b2ed49a5SDavid van Moolenbroek         case MAGIC_TYPE_POINTER:
911*b2ed49a5SDavid van Moolenbroek             i = magic_selement_recurse_ptr(parent_selement, selement, MAGIC_SELEMENT_MAX_PTR_RECURSIONS);
912*b2ed49a5SDavid van Moolenbroek             if(i <= 0 || i >= MAGIC_SELEMENT_MAX_PTR_RECURSIONS) {
913*b2ed49a5SDavid van Moolenbroek                 return NULL;
914*b2ed49a5SDavid van Moolenbroek             }
915*b2ed49a5SDavid van Moolenbroek             new_parent_selement = *selement;
916*b2ed49a5SDavid van Moolenbroek             return magic_selement_from_relative_name(&new_parent_selement, selement, name);
917*b2ed49a5SDavid van Moolenbroek         break;
918*b2ed49a5SDavid van Moolenbroek 
919*b2ed49a5SDavid van Moolenbroek         default:
920*b2ed49a5SDavid van Moolenbroek             return NULL;
921*b2ed49a5SDavid van Moolenbroek         break;
922*b2ed49a5SDavid van Moolenbroek     }
923*b2ed49a5SDavid van Moolenbroek 
924*b2ed49a5SDavid van Moolenbroek     if(child_num != -1) {
925*b2ed49a5SDavid van Moolenbroek         selement->sentry = parent_selement->sentry;
926*b2ed49a5SDavid van Moolenbroek         selement->parent_type = parent_type;
927*b2ed49a5SDavid van Moolenbroek         selement->parent_address = parent_selement->address;
928*b2ed49a5SDavid van Moolenbroek         selement->child_num = child_num;
929*b2ed49a5SDavid van Moolenbroek         selement->num = parent_selement->num+1;
930*b2ed49a5SDavid van Moolenbroek         magic_selement_fill_from_parent_info(selement, walk_flags);
931*b2ed49a5SDavid van Moolenbroek     }
932*b2ed49a5SDavid van Moolenbroek 
933*b2ed49a5SDavid van Moolenbroek     return selement;
934*b2ed49a5SDavid van Moolenbroek }
935*b2ed49a5SDavid van Moolenbroek 
936