mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge pull request #1082 from masuidrive/add_debug_info
Added debug infomation section into .mrb file
This commit is contained in:
+10
-2
@@ -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;
|
||||
};
|
||||
|
||||
+120
-7
@@ -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;
|
||||
|
||||
*bin_size += sizeof(struct rite_binary_header) + section_irep_size + sizeof(struct rite_binary_footer);
|
||||
/* 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_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) {
|
||||
|
||||
+140
-1
@@ -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);
|
||||
|
||||
+7
-2
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user