diff options
| author | Yuichiro MASUI <[email protected]> | 2013-03-27 18:02:48 +0900 |
|---|---|---|
| committer | Yuichiro MASUI <[email protected]> | 2013-03-27 18:21:04 +0900 |
| commit | f3ebb89392163afba18f0f05634255adaf527294 (patch) | |
| tree | 81de5eb967d20d17ba67cdbdfa1aa2cff4b21cde | |
| parent | f1e6a4a3b564ac07f0b283af05bc2d7be5a31414 (diff) | |
| download | mruby-f3ebb89392163afba18f0f05634255adaf527294.tar.gz mruby-f3ebb89392163afba18f0f05634255adaf527294.zip | |
Added debug infomation section into .mrb file
| -rw-r--r-- | include/mruby/dump.h | 12 | ||||
| -rw-r--r-- | src/dump.c | 127 | ||||
| -rw-r--r-- | src/load.c | 141 | ||||
| -rw-r--r-- | tools/mrbc/mrbc.c | 9 |
4 files changed, 277 insertions, 12 deletions
diff --git a/include/mruby/dump.h b/include/mruby/dump.h index a9cc93fdc..42427de68 100644 --- a/include/mruby/dump.h +++ b/include/mruby/dump.h @@ -14,8 +14,8 @@ extern "C" { #include "mruby.h" #ifdef ENABLE_STDIO -int mrb_dump_irep_binary(mrb_state*, size_t, FILE*); -int mrb_dump_irep_cfunc(mrb_state *mrb, size_t n, FILE *f, const char *initname); +int mrb_dump_irep_binary(mrb_state*, size_t, int, FILE*); +int mrb_dump_irep_cfunc(mrb_state *mrb, size_t n, int, FILE *f, const char *initname); int32_t mrb_read_irep_file(mrb_state*, FILE*); #endif int mrb_read_irep(mrb_state*, const uint8_t*); @@ -51,6 +51,7 @@ mrb_value mrb_load_irep_file(mrb_state*,FILE*); #define RITE_BINARY_EOF "END\0" #define RITE_SECTION_IREP_IDENTIFIER "IREP" +#define RITE_SECTION_LIENO_IDENTIFIER "LINE" #define MRB_DUMP_DEFAULT_STR_LEN 128 @@ -81,6 +82,13 @@ struct rite_section_irep_header { uint8_t sirep[2]; // Start index }; +struct rite_section_lineno_header { + RITE_SECTION_HEADER; + + uint8_t nirep[2]; // Number of ireps + uint8_t sirep[2]; // Start index +}; + struct rite_binary_footer { RITE_SECTION_HEADER; }; diff --git a/src/dump.c b/src/dump.c index fdb20f68a..d3f6ee62b 100644 --- a/src/dump.c +++ b/src/dump.c @@ -334,6 +334,97 @@ mrb_write_section_irep(mrb_state *mrb, size_t start_index, uint8_t *bin) } static int +mrb_write_section_lineno_header(mrb_state *mrb, uint32_t section_size, uint16_t nirep, uint16_t sirep, uint8_t *bin) +{ + struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin; + + // TODO + memcpy(header->section_identify, RITE_SECTION_LIENO_IDENTIFIER, sizeof(header->section_identify)); + uint32_to_bin(section_size, header->section_size); + uint16_to_bin(nirep, header->nirep); + uint16_to_bin(sirep, header->sirep); + + return MRB_DUMP_OK; +} + +static size_t +get_debug_record_size(mrb_state *mrb, mrb_irep *irep) +{ + size_t size = 0; + + size += sizeof(uint32_t); // record size + size += sizeof(uint16_t); // filename size + if(irep->filename) { + size += strlen(irep->filename); // filename + } + size += sizeof(uint32_t); // niseq + if(irep->lines) { + size += sizeof(uint16_t) * irep->ilen; // lineno + } + + return size; +} + +static int +write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) +{ + uint8_t *cur = bin; + size_t filename_len = 0; + int iseq_no; + + cur += sizeof(uint32_t); /* record size */ + + if(irep->filename) { + filename_len = strlen(irep->filename); + } + cur += uint16_to_bin(filename_len, cur); /* filename size */ + + if(filename_len) { + memcpy(cur, irep->filename, filename_len); + cur += filename_len; /* filename */ + } + + if(irep->lines) { + cur += uint32_to_bin(irep->ilen, cur); /* niseq */ + for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { + cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */ + } + } + else { + cur += uint32_to_bin(0, cur); /* niseq */ + } + + uint32_to_bin(cur - bin, bin); /* record size */ + + return (cur - bin); +} + +static int +mrb_write_section_lineno(mrb_state *mrb, int start_index, uint8_t *bin) +{ + int irep_no; + uint32_t section_size = 0, rlen = 0; /* size of irep record */ + uint8_t *cur = bin; + + if (mrb == NULL || start_index < 0 || start_index >= mrb->irep_len || bin == NULL) { + return MRB_DUMP_INVALID_ARGUMENT; + } + + cur += sizeof(struct rite_section_lineno_header); + section_size += sizeof(struct rite_section_lineno_header); + + for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { + rlen = write_lineno_record(mrb, mrb->irep[irep_no], cur); + cur += rlen; + section_size += rlen; + } + + mrb_write_section_lineno_header(mrb, section_size, mrb->irep_len - start_index, start_index, bin); + + return MRB_DUMP_OK; +} + +static int write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t* bin) { struct rite_binary_header *header = (struct rite_binary_header*)bin; @@ -354,10 +445,12 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t* bin) } static int -mrb_dump_irep(mrb_state *mrb, size_t start_index, uint8_t **bin, size_t *bin_size) +mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin, size_t *bin_size) { int result = MRB_DUMP_GENERAL_FAILURE; + size_t section_size = 0; size_t section_irep_size; + size_t section_lineno_size = 0; size_t irep_no; uint8_t *cur = NULL; @@ -370,8 +463,18 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, uint8_t **bin, size_t *bin_siz for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { section_irep_size += get_irep_record_size(mrb, mrb->irep[irep_no]); } + section_size += section_irep_size; + + /* DEBUG section size */ + if(debug_info) { + section_lineno_size += sizeof(struct rite_section_lineno_header); + for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { + section_lineno_size += get_debug_record_size(mrb, mrb->irep[irep_no]); + } + section_size += section_lineno_size; + } - *bin_size += sizeof(struct rite_binary_header) + section_irep_size + sizeof(struct rite_binary_footer); + *bin_size += sizeof(struct rite_binary_header) + section_size + sizeof(struct rite_binary_footer); cur = *bin = (uint8_t *)mrb_malloc(mrb, *bin_size); if(cur == NULL) { goto error_exit; @@ -383,8 +486,18 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, uint8_t **bin, size_t *bin_siz if (result != MRB_DUMP_OK) { goto error_exit; } - + cur += section_irep_size; + + /* write DEBUG section */ + if(debug_info) { + result = mrb_write_section_lineno(mrb, start_index, cur); + if (result != MRB_DUMP_OK) { + goto error_exit; + } + cur += section_lineno_size; + } + mrb_write_eof(mrb, cur); result = write_rite_binary_header(mrb, *bin_size, *bin); @@ -401,7 +514,7 @@ error_exit: #ifdef ENABLE_STDIO int -mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, FILE* fp) +mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, int debug_info, FILE* fp) { uint8_t *bin = NULL; size_t bin_size = 0; @@ -411,7 +524,7 @@ mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, FILE* fp) return MRB_DUMP_INVALID_ARGUMENT; } - result = mrb_dump_irep(mrb, start_index, &bin, &bin_size); + result = mrb_dump_irep(mrb, start_index, debug_info, &bin, &bin_size); if (result == MRB_DUMP_OK) { fwrite(bin, bin_size, 1, fp); } @@ -421,7 +534,7 @@ mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, FILE* fp) } int -mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, FILE *fp, const char *initname) +mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, int debug_info, FILE *fp, const char *initname) { uint8_t *bin = NULL; size_t bin_size = 0, bin_idx = 0; @@ -431,7 +544,7 @@ mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, FILE *fp, const char *in return MRB_DUMP_INVALID_ARGUMENT; } - result = mrb_dump_irep(mrb, start_index, &bin, &bin_size); + result = mrb_dump_irep(mrb, start_index, debug_info, &bin, &bin_size); if (result == MRB_DUMP_OK) { fprintf(fp, "const uint8_t %s[] = {", initname); while (bin_idx < bin_size) { diff --git a/src/load.c b/src/load.c index d0859df27..23b23af5c 100644 --- a/src/load.c +++ b/src/load.c @@ -32,7 +32,7 @@ static size_t offset_crc_body() { struct rite_binary_header header; - return ((char *)header.binary_crc - (char *)&header) + sizeof(header.binary_crc); + return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc); } static int @@ -226,6 +226,74 @@ error_exit: } static int +read_rite_lineno_record(mrb_state *mrb, const uint8_t *bin, size_t irepno, uint32_t *len) +{ + int ret; + size_t i, fname_len, niseq; + char *fname; + short *lines; + + bin += sizeof(uint32_t); // record size + fname_len = bin_to_uint16(bin); + bin += sizeof(uint16_t); + fname = (char *)mrb_malloc(mrb, fname_len + 1); + if (fname == NULL) { + ret = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } + memcpy(fname, bin, fname_len); + fname[fname_len] = '\0'; + bin += fname_len; + + niseq = bin_to_uint32(bin); + bin += sizeof(uint32_t); // niseq + + lines = (short *)mrb_malloc(mrb, niseq * sizeof(short)); + for (i = 0; i < niseq; i++) { + lines[i] = bin_to_uint16(bin); + bin += sizeof(short); // niseq + } + + mrb->irep[irepno]->filename = fname; + mrb->irep[irepno]->lines = lines; + +error_exit: + return MRB_DUMP_OK; +} + +static int +read_rite_section_lineno(mrb_state *mrb, const uint8_t *bin, size_t sirep) +{ + int result; + size_t i; + uint32_t len; + uint16_t nirep; + uint16_t n; + const struct rite_section_lineno_header *header; + + header = (const struct rite_section_lineno_header*)bin; + bin += sizeof(struct rite_section_lineno_header); + + nirep = bin_to_uint16(header->nirep); + + //Read Binary Data Section + for (n = 0, i = sirep; n < nirep; n++, i++) { + result = read_rite_lineno_record(mrb, bin, i, &len); + if (result != MRB_DUMP_OK) + goto error_exit; + bin += len; + } + + result = MRB_DUMP_OK; +error_exit: + if (result != MRB_DUMP_OK) { + return result; + } + return sirep + bin_to_uint16(header->sirep); +} + + +static int read_rite_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc) { const struct rite_binary_header *header = (const struct rite_binary_header *)bin; @@ -255,6 +323,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) uint16_t crc; size_t bin_size = 0; size_t n; + size_t sirep; if ((mrb == NULL) || (bin == NULL)) { return MRB_DUMP_INVALID_ARGUMENT; @@ -271,6 +340,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) } bin += sizeof(struct rite_binary_header); + sirep = mrb->irep_len; do { section_header = (const struct rite_section_header *)bin; @@ -281,6 +351,12 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) } total_nirep += result; } + else if(memcmp(section_header->section_identify, RITE_SECTION_LIENO_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { + result = read_rite_section_lineno(mrb, bin, sirep); + if(result < MRB_DUMP_OK) { + return result; + } + } bin += bin_to_uint32(section_header->section_size); } while(memcmp(section_header->section_identify, RITE_BINARY_EOF, sizeof(section_header->section_identify)) != 0); @@ -310,6 +386,60 @@ mrb_load_irep(mrb_state *mrb, const uint8_t *bin) #ifdef ENABLE_STDIO static int32_t +read_rite_section_lineno_file(mrb_state *mrb, FILE *fp, size_t sirep) +{ + int32_t result; + size_t i; + uint16_t nirep; + uint16_t n; + uint32_t len, buf_size; + uint8_t *buf = NULL; + const size_t record_header_size = 4; + + struct rite_section_lineno_header header; + fread(&header, sizeof(struct rite_section_lineno_header), 1, fp); + + nirep = bin_to_uint16(header.nirep); + + buf_size = record_header_size; + buf = (uint8_t *)mrb_malloc(mrb, buf_size); + + //Read Binary Data Section + for (n = 0, i = sirep; n < nirep; n++, i++) { + fread(buf, record_header_size, 1, fp); + buf_size = bin_to_uint32(&buf[0]); + buf = (uint8_t *)mrb_realloc(mrb, buf, buf_size); + + fread(&buf[record_header_size], buf_size - record_header_size, 1, fp); + result = read_rite_lineno_record(mrb, buf, i, &len); + if (result != MRB_DUMP_OK) + goto error_exit; + } + + result = MRB_DUMP_OK; +error_exit: + mrb_free(mrb, buf); + if (result != MRB_DUMP_OK) { + for (i = sirep; i < mrb->irep_len; i++) { + if (mrb->irep[i]) { + if (mrb->irep[i]->iseq) + mrb_free(mrb, mrb->irep[i]->iseq); + + if (mrb->irep[i]->pool) + mrb_free(mrb, mrb->irep[i]->pool); + + if (mrb->irep[i]->syms) + mrb_free(mrb, mrb->irep[i]->syms); + + mrb_free(mrb, mrb->irep[i]); + } + } + return result; + } + return sirep + bin_to_uint16(header.sirep); +} + +static int32_t read_rite_section_irep_file(mrb_state *mrb, FILE *fp) { int32_t result; @@ -381,6 +511,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) uint16_t crc, crcwk = 0; uint32_t section_size = 0; size_t nbytes; + size_t sirep; struct rite_section_header section_header; long fpos; const size_t block_size = 1 << 14; @@ -416,6 +547,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) return MRB_DUMP_INVALID_FILE_HEADER; } fseek(fp, fpos + section_size, SEEK_SET); + sirep = mrb->irep_len; // read sections do { @@ -433,6 +565,13 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) } total_nirep += result; } + else if(memcmp(section_header.section_identify, RITE_SECTION_LIENO_IDENTIFIER, sizeof(section_header.section_identify)) == 0) { + fseek(fp, fpos, SEEK_SET); + result = read_rite_section_lineno_file(mrb, fp, sirep); + if(result < MRB_DUMP_OK) { + return result; + } + } fseek(fp, fpos + section_size, SEEK_SET); } while(memcmp(section_header.section_identify, RITE_BINARY_EOF, sizeof(section_header.section_identify)) != 0); diff --git a/tools/mrbc/mrbc.c b/tools/mrbc/mrbc.c index 6535d5636..e217ef30f 100644 --- a/tools/mrbc/mrbc.c +++ b/tools/mrbc/mrbc.c @@ -21,6 +21,7 @@ struct _args { char *ext; mrb_bool check_syntax : 1; mrb_bool verbose : 1; + mrb_bool debug_info : 1; }; static void @@ -31,6 +32,7 @@ usage(const char *name) "-c check syntax only", "-o<outfile> place the output into <outfile>", "-v print version number, then trun on verbose mode", + "-g produce debugging information", "-B<symbol> binary <symbol> output in C language format", "--verbose run at verbose mode", "--version print the version", @@ -107,6 +109,9 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) mrb_show_version(mrb); args->verbose = 1; break; + case 'g': + args->debug_info = 1; + break; case '-': if (strcmp((*argv) + 2, "version") == 0) { mrb_show_version(mrb); @@ -209,10 +214,10 @@ main(int argc, char **argv) return EXIT_SUCCESS; } if (args.initname) { - n = mrb_dump_irep_cfunc(mrb, n, args.wfp, args.initname); + n = mrb_dump_irep_cfunc(mrb, n, args.debug_info, args.wfp, args.initname); } else { - n = mrb_dump_irep_binary(mrb, n, args.wfp); + n = mrb_dump_irep_binary(mrb, n, args.debug_info, args.wfp); } cleanup(mrb, &args); |
