/** * add data to table for given symbol * @param symbol_name * @param type * @param value * @param tag */ void add_data_initials (char *symbol_name, int type, int value, TAG_SYMBOL *tag) { int position; if (find_symbol_initials(symbol_name) == 0) add_symbol_initials(symbol_name, tag == 0 ? type : CSTRUCT); if (tag != 0) { // find number of members, dim is total number of values added int index = initials_table[initials_idx].dim % tag->number_of_members; int member_type = member_table[tag->member_idx + index].type; // add it recursively add_data_initials(symbol_name, member_type, value, 0); } else { position = initials_table[initials_idx].data_len; if (type == CCHAR || type == CUCHAR) { initials_data_table[initials_data_idx + position] = 0xff & value; initials_table[initials_idx].data_len += 1; } else { initials_data_table[initials_data_idx + position] = (0xff00 & value) >> 8; initials_data_table[initials_data_idx + position + 1] = 0xff & value; initials_table[initials_idx].data_len += INTSIZE; } initials_table[initials_idx].dim += 1; } }
/** * dump all static variables */ void dumpglbs(void) { int dim, i, list_size, line_count, value; if (!glbflag) return; current_symbol_table_idx = rglobal_table_index; while (current_symbol_table_idx < global_table_index) { SYMBOL *symbol = &symbol_table[current_symbol_table_idx]; if (symbol->identity != FUNCTION) { ppubext(symbol); if (symbol->storage != EXTERN) { output_string(symbol->name); output_label_terminator(); dim = symbol->offset; list_size = 0; line_count = 0; if (find_symbol_initials(symbol->name)) { // has initials list_size = get_size(symbol->name); if (dim == -1) { dim = list_size; } } for (i=0; i<dim; i++) { if (symbol->type == STRUCT) { dump_struct(symbol, i); } else { if (line_count % 10 == 0) { newline(); if ((symbol->type & CINT) || (symbol->identity == POINTER)) { gen_def_word(); } else { gen_def_byte(); } } if (i < list_size) { // dump data value = get_item_at(symbol->name, i, &tag_table[symbol->tagidx]); output_number(value); } else { // dump zero, no more data available output_number(0); } line_count++; if (line_count % 10 == 0) { line_count = 0; } else { if (i < dim-1) { output_byte( ',' ); } } } } newline(); } } else { fpubext(symbol); } current_symbol_table_idx++; } }
/** * get number of data items for given symbol * @param symbol_name * @return */ int get_size (char *symbol_name) { int result = 0; if (find_symbol_initials(symbol_name) != 0) result = initials_table[initials_idx].dim; return (result); }
/** * get item at position * @param symbol_name * @param position * @param itag index of tag in tag table * @return */ int get_item_at (char *symbol_name, int position, TAG_SYMBOL *tag) { int result = 0, i, type; if (find_symbol_initials(symbol_name) != 0) { if ((initials_table[initials_idx].type & ~CUNSIGNED) == CCHAR) result = initials_data_table[initials_data_idx + position]; else if ((initials_table[initials_idx].type & ~CUNSIGNED) == CINT) { position *= INTSIZE; result = (initials_data_table[initials_data_idx + position] << 8) + (unsigned char)initials_data_table[initials_data_idx + position + 1]; } else if (initials_table[initials_idx].type == CSTRUCT) { // find number of members int number_of_members = tag->number_of_members; // point behind the last full struct int index = (position / number_of_members) * tag->size; // move to required member for (i = 0; i < (position % number_of_members); i++) { type = member_table[tag->member_idx + i].type; if (type == CCHAR || type == CUCHAR) index += 1; else index += INTSIZE; } // get value type = member_table[tag->member_idx + i].type; if (type == CCHAR || type == CUCHAR) result = initials_data_table[initials_data_idx + index]; else { result = (initials_data_table[initials_data_idx + index] << 8) + (unsigned char)initials_data_table[initials_data_idx + index + 1]; } } } return (result); }
/* * dump all static variables */ void dumpglbs (void) { long i = 1; int dim, list_size, line_count; int j; FILE *save = output; if (!data) data = fmemopen(data_buf, DATABUFSIZE, "w"); if (!rodata) rodata = fmemopen(rodata_buf, DATABUFSIZE, "w"); /* This is done in several passes: Pass 0: Dump initialization data into const bank. Pass 1: Define space for uninitialized data. Pass 2: Define space for initialized data. */ if (glbflag) { int pass = 0; next: i = 1; for (cptr = rglbptr; cptr < glbptr; cptr++) { if (cptr->ident != FUNCTION) { // ppubext(cptr); if ((cptr->storage & WRITTEN) == 0 && /* Not yet written to file */ cptr->storage != EXTERN) { dim = cptr->offset; if (find_symbol_initials(cptr->name)) { // has initials /* dump initialization data */ if (pass == 1) /* initialized data not handled in pass 1 */ continue; else if (pass == 2) { /* define space for initialized data */ output = data; if (cptr->storage != LSTATIC) prefix(); outstr(cptr->name); outstr(":\t"); defstorage(); outdec(cptr->size); nl(); cptr->storage |= WRITTEN; output = save; continue; } /* output initialization data into const bank */ output = rodata; have_init_data = 1; list_size = 0; line_count = 0; list_size = get_size(cptr->name); if (cptr->type == CSTRUCT) list_size /= tag_table[cptr->tagidx].number_of_members; if (dim == -1) dim = list_size; int item; /* dim is an item count for non-compound types and a byte size for compound types; dump_struct() wants an item number, so we have to count both to get the right members out. */ for (j = item = 0; j < dim; j++, item++) { if (cptr->type == CSTRUCT) j += dump_struct(cptr, item) - 1; else { if (line_count % 10 == 0) { nl(); if (cptr->type == CCHAR || cptr->type == CUCHAR) defbyte(); else defword(); } if (j < list_size) { // dump data int value = get_item_at(cptr->name, j, &tag_table[cptr->tagidx]); outdec(value); } else { // dump zero, no more data available outdec(0); } line_count++; if (line_count % 10 == 0) line_count = 0; else { if (j < dim - 1) outbyte(','); } } } nl(); output = save; } else { if (pass == 0) continue; /* define space in bss */ if (i) { i = 0; nl(); gdata(); } if (cptr->storage != LSTATIC) prefix(); outstr(cptr->name); outstr(":\t"); defstorage(); outdec(cptr->size); nl(); cptr->storage |= WRITTEN; } } } else { // fpubext(cptr); } } if (++pass < 3) goto next; } if (i) { nl(); gdata(); } output = save; }