Commit e265d7c7 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #1082 from masuidrive/add_debug_info

Added debug infomation section into .mrb file
parents 82991049 f3ebb893
......@@ -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;
};
......
......@@ -333,6 +333,97 @@ mrb_write_section_irep(mrb_state *mrb, size_t start_index, uint8_t *bin)
return MRB_DUMP_OK;
}
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)
{
......@@ -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) {
......
......@@ -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
......@@ -225,6 +225,74 @@ error_exit:
return sirep + bin_to_uint16(header->sirep);
}
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)
{
......@@ -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);
......@@ -309,6 +385,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)
{
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment