static int read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len) { const uint8_t *bin = start; ptrdiff_t diff; size_t record_size; uint16_t f_idx; int i; if (irep->debug_info) { return MRB_DUMP_INVALID_IREP; } irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info)); irep->debug_info->pc_count = (uint32_t)irep->ilen; record_size = (size_t)bin_to_uint32(bin); bin += sizeof(uint32_t); irep->debug_info->flen = bin_to_uint16(bin); irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_malloc(mrb, sizeof(mrb_irep_debug_info*) * irep->debug_info->flen); bin += sizeof(uint16_t); for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { mrb_irep_debug_info_file *file; uint16_t filename_idx; mrb_int len; file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file)); irep->debug_info->files[f_idx] = file; file->start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); /* filename */ filename_idx = bin_to_uint16(bin); bin += sizeof(uint16_t); mrb_assert(filename_idx < filenames_len); file->filename_sym = filenames[filename_idx]; len = 0; file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len); file->line_entry_count = bin_to_uint32(bin); bin += sizeof(uint32_t); file->line_type = (mrb_debug_line_type)bin_to_uint8(bin); bin += sizeof(uint8_t); switch (file->line_type) { case mrb_debug_line_ary: { uint32_t l; file->lines.ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * (size_t)(file->line_entry_count)); for (l = 0; l < file->line_entry_count; ++l) { file->lines.ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t); } } break; case mrb_debug_line_flat_map: { uint32_t l; file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc( mrb, sizeof(mrb_irep_debug_info_line) * (size_t)(file->line_entry_count)); for (l = 0; l < file->line_entry_count; ++l) { file->lines.flat_map[l].start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); file->lines.flat_map[l].line = bin_to_uint16(bin); bin += sizeof(uint16_t); } } break; default: return MRB_DUMP_GENERAL_FAILURE; } } diff = bin - start; mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); if (record_size != (size_t)diff) { return MRB_DUMP_GENERAL_FAILURE; } for (i = 0; i < irep->rlen; i++) { size_t len; int ret; ret = read_debug_record(mrb, bin, irep->reps[i], &len, filenames, filenames_len); if (ret != MRB_DUMP_OK) return ret; bin += len; } diff = bin - start; mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); *record_len = (size_t)diff; return MRB_DUMP_OK; }
static int read_rite_debug_record(mrb_state *mrb, const uint8_t *start, size_t irepno, uint32_t *len, const mrb_sym *filenames, size_t filenames_len) { const uint8_t *bin = start; mrb_irep *irep = mrb->irep[irepno]; size_t record_size; uint16_t f_idx; if(irep->debug_info) { return MRB_DUMP_INVALID_IREP; } irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info)); irep->debug_info->pc_count = irep->ilen; record_size = bin_to_uint32(bin); bin += sizeof(uint32_t); irep->debug_info->flen = bin_to_uint16(bin); irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_malloc(mrb, sizeof(mrb_irep_debug_info*) * irep->debug_info->flen); bin += sizeof(uint16_t); for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { mrb_irep_debug_info_file *file; uint16_t filename_idx; size_t len; file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file)); irep->debug_info->files[f_idx] = file; file->start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); // filename filename_idx = bin_to_uint16(bin); bin += sizeof(uint16_t); mrb_assert(filename_idx < filenames_len); file->filename_sym = filenames[filename_idx]; len = 0; file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len); file->line_entry_count = bin_to_uint32(bin); bin += sizeof(uint32_t); file->line_type = bin_to_uint8(bin); bin += sizeof(uint8_t); switch(file->line_type) { case mrb_debug_line_ary: { size_t l; file->line_ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * file->line_entry_count); for(l = 0; l < file->line_entry_count; ++l) { file->line_ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t); } } break; case mrb_debug_line_flat_map: { size_t l; file->line_flat_map = mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * file->line_entry_count); for(l = 0; l < file->line_entry_count; ++l) { file->line_flat_map[l].start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); file->line_flat_map[l].line = bin_to_uint16(bin); bin += sizeof(uint16_t); } } break; default: return MRB_DUMP_GENERAL_FAILURE; } } if((long)record_size != (bin - start)) { return MRB_DUMP_GENERAL_FAILURE; } *len = bin - start; return MRB_DUMP_OK; }