static int avr_tenc_walk_to_element (const prog_char *data, UWORD *length, const char *id, avr_tenc_element_t *element) { while (*length > 0) { int ret = avr_tenc_decode_element (data, length, element); if (ret < 0) { return ret; } if (ids_match (element->id, id)) { return 0; } data = element->next; } return -1; }
int tenc_walk_to_element (BYTE *data, unsigned int *length, const char *id, tenc_element_t *element) { while (*length > 0) { int ret = tenc_decode_element (data, length, element); if (ret < 0) { return ret; } if (ids_match (element->id, id)) { return 0; } data = element->next; } return -1; }
static int avr_tbc_decode (const prog_char *data, UWORD length, ECTX context, WORDPTR memory, UWORD memory_size) { UWORD ws_size, vs_size; const prog_char *bytecode; WORDPTR ws, vs; avr_tenc_element_t element; int ret, memory_used; /* Decode the required elements */ if ((ret = load_uint (&data, &length, "ws U", &ws_size)) < 0) return ret; if ((ret = load_uint (&data, &length, "vs U", &vs_size)) < 0) return ret; if ((ret = avr_tenc_walk_to_element (data, &length, "bc B", &element)) < 0) return ret; bytecode = element.data.bytes; data = element.next; /* FIXME: check TLP is empty */ #if 0 /* Decode optional elements */ tbc->tlp = NULL; while (length > 0) { if (tenc_decode_element (data, &length, &element) < 0) return 0; /* ignore errors */ if (ids_match (element.id, "tlpL")) { tbc->tlp = decode_tlp (data, tbc->tlp, &element); } data = element.next; } #endif memory_used = tvm_ectx_layout ( context, memory, "", 0, ws_size, vs_size, &ws, &vs ); #ifdef DEBUG printf ("loaded program with ws_size=%d, vs_size=%d, memory_size=%d, used=%d\n", ws_size, vs_size, memory_size, memory_used); #endif /* Check we haven't exhausted memory. */ if (memory_used > memory_size) { terminate ("not enough RAM for program", NULL); } ret = tvm_ectx_install_tlp ( context, tvm_addr_from_progmem ((prog_void *) bytecode), ws, vs, "", 0, NULL ); return ret; }
/* tbc_decode: * If ptr is NULL then this uses in place decoding, * otherwise fills out the structure pointered to. * When not using in place decoding the structure should be * initialised with zeros. tlp elements will be decoded if * tbc->tlp is not NULL. */ int tbc_decode (BYTE *data, unsigned int length, tbc_t **ptr) { tenc_element_t element; tbc_t *tbc; int in_place; int ret; if (*ptr != NULL) { tbc = *ptr; in_place = 0; } else { tbc = (tbc_t *) data; in_place = 1; } /* Decode the required elements */ if ((ret = load_uint (&data, &length, "endU", &(tbc->endian))) < 0) return ret; if ((ret = load_uint (&data, &length, "ws U", &(tbc->ws))) < 0) return ret; if ((ret = load_uint (&data, &length, "vs U", &(tbc->vs))) < 0) return ret; if ((ret = tenc_walk_to_element (data, &length, "bc B", &element)) < 0) return ret; tbc->bytecode_len = element.length; tbc->bytecode = element.data.bytes; data = element.next; /* Decode optional elements */ if (in_place) { tbc->tlp = NULL; tbc->symbols = NULL; tbc->ffi = NULL; tbc->debug = NULL; } else { if (tbc->tlp != NULL) { tbc->tlp->fmt = NULL; tbc->tlp->symbol = NULL; } } /* Copy pointer */ *ptr = tbc; while (length > 0) { if (tenc_decode_element (data, &length, &element) < 0) return 0; /* ignore errors */ if (ids_match (element.id, "tlpL")) { tbc->tlp = decode_tlp (data, tbc->tlp, &element); } else if (in_place && ids_match (element.id, "ffiL")) { tbc->ffi = decode_ffi (data, &element); } else if (in_place && ids_match (element.id, "stbL")) { tbc->symbols = decode_symbols (&element); } else if (in_place && ids_match (element.id, "dbgL")) { tbc->debug = decode_debug (data, &element); } data = element.next; } return 0; }