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