dvander@2320: #include dvander@2320: #include dvander@2320: #include dvander@2320: #include dvander@2325: #include dvander@2320: #include "decompiler.h" dvander@2320: #include "platform_util.h" dvander@2320: dvander@2320: sp_decomp_t *Sp_InitDecomp(const char *file, int *err) dvander@2320: { dvander@2320: sp_decomp_t *dc; dvander@2320: sp_file_t *plugin; dvander@2320: dvander@2320: if ((plugin = Sp_ReadPlugin(file, err)) == NULL) dvander@2320: { dvander@2320: return NULL; dvander@2320: } dvander@2320: dvander@2320: dc = new sp_decomp_t; dvander@2320: memset(dc, 0, sizeof(sp_decomp_t)); dvander@2320: dc->plugin = plugin; dvander@2320: dc->pcode_map = (cell_t *)malloc(dc->plugin->pcode_size); dvander@2320: memset(dc->pcode_map, 0, dc->plugin->pcode_size); dvander@2320: dvander@2320: #define OPDEF(num,enm,str,prms) \ dvander@2320: dc->opdef[num].name = str; \ dvander@2320: dc->opdef[num].params = prms; dvander@2320: #include "opcodes.tbl" dvander@2320: #undef OPDEF dvander@2320: dvander@2325: if (plugin->debug.ntv != NULL) dvander@2325: { dvander@2325: assert(plugin->debug.ntv->num_entries == plugin->num_natives); dvander@2325: dc->natives = new FunctionInfo[plugin->num_natives]; dvander@2325: memset(dc->natives, 0, sizeof(FunctionInfo) * plugin->num_natives); dvander@2325: dvander@2325: /* Unfurl this mess. */ dvander@2325: uint8_t *cursor = (uint8_t *)plugin->debug.ntv; dvander@2325: dvander@2325: cursor += sizeof(sp_fdbg_ntvtab_t); dvander@2325: for (uint32_t i = 0; i < plugin->num_natives; i++) dvander@2325: { dvander@2325: sp_fdbg_native_t *native = (sp_fdbg_native_t *)cursor; dvander@2325: dvander@2325: uint32_t idx = native->index; dvander@2325: dvander@2325: assert(dc->natives[idx].name[0] == '\0'); dvander@2325: dvander@2325: Sp_Format(dc->natives[idx].name, dvander@2325: sizeof(dc->natives[idx].name), dvander@2325: "%s", dvander@2325: plugin->debug.stringbase + native->name); dvander@2325: dc->natives[idx].tag = Sp_FindTag(plugin, native->tagid); dvander@2325: dc->natives[idx].num_known_args = native->nargs; dvander@2325: dvander@2325: cursor += sizeof(sp_fdbg_native_t); dvander@2325: dvander@2325: for (uint32_t j = 0; j < dc->natives[idx].num_known_args; j++) dvander@2325: { dvander@2325: sp_fdbg_ntvarg_t *arg = (sp_fdbg_ntvarg_t *)cursor; dvander@2325: dc->natives[idx].known_args[j].name = dvander@2325: plugin->debug.stringbase + arg->name; dvander@2325: dc->natives[idx].known_args[j].tag = dvander@2325: Sp_FindTag(plugin, arg->tagid); dvander@2325: dc->natives[idx].known_args[j].dimcount = arg->dimcount; dvander@2325: dvander@2325: cursor += sizeof(sp_fdbg_ntvarg_t); dvander@2325: if (arg->dimcount != 0) dvander@2325: { dvander@2325: dc->natives[idx].known_args[j].dims = (sp_fdbg_arraydim_t *)cursor; dvander@2325: cursor += sizeof(sp_fdbg_arraydim_t) * arg->dimcount; dvander@2325: } dvander@2325: } dvander@2325: } dvander@2325: } dvander@2325: dvander@2320: return dc; dvander@2320: } dvander@2320: dvander@2320: void Sp_FreeDecomp(sp_decomp_t *decomp) dvander@2320: { dvander@2320: FunctionInfo *info, *info_temp; dvander@2320: dvander@2320: info = decomp->funcs; dvander@2320: while (info != NULL) dvander@2320: { dvander@2320: info_temp = info->next; dvander@2320: delete info; dvander@2320: info = info_temp; dvander@2320: } dvander@2320: dvander@2320: Sp_FreePlugin(decomp->plugin); dvander@2320: free(decomp->pcode_map); dvander@2325: delete [] decomp->natives; dvander@2320: delete decomp; dvander@2320: } dvander@2320: dvander@2320: PrintBuffer::PrintBuffer() : printbuf(NULL), printbuf_alloc(0), printbuf_pos(0) dvander@2320: { dvander@2320: } dvander@2320: dvander@2320: PrintBuffer::~PrintBuffer() dvander@2320: { dvander@2320: free(printbuf); dvander@2320: } dvander@2320: dvander@2320: void PrintBuffer::Grow(size_t len) dvander@2320: { dvander@2320: if (printbuf_pos + len > printbuf_alloc) dvander@2320: { dvander@2320: if (printbuf_alloc == 0) dvander@2320: { dvander@2320: printbuf_alloc = len * 8; dvander@2320: } dvander@2320: else dvander@2320: { dvander@2320: printbuf_alloc += len; dvander@2320: printbuf_alloc *= 2; dvander@2320: } dvander@2320: dvander@2320: printbuf = (char *)realloc(printbuf, printbuf_alloc); dvander@2320: } dvander@2320: } dvander@2320: dvander@2320: void PrintBuffer::Append(const char *fmt, ...) dvander@2320: { dvander@2320: size_t len; dvander@2320: va_list ap; dvander@2320: char buffer[2048]; dvander@2320: dvander@2320: va_start(ap, fmt); dvander@2320: len = Sp_FormatArgs(buffer, sizeof(buffer), fmt, ap); dvander@2320: va_end(ap); dvander@2320: dvander@2325: Grow(len + 1); dvander@2320: dvander@2320: strcpy(&printbuf[printbuf_pos], buffer); dvander@2320: printbuf_pos += len; dvander@2320: } dvander@2320: dvander@2320: void PrintBuffer::Set(const char *fmt, ...) dvander@2320: { dvander@2320: size_t len; dvander@2320: va_list ap; dvander@2320: char buffer[2048]; dvander@2320: dvander@2320: va_start(ap, fmt); dvander@2320: len = Sp_FormatArgs(buffer, sizeof(buffer), fmt, ap); dvander@2320: va_end(ap); dvander@2320: dvander@2320: Reset(); dvander@2325: Grow(len + 1); dvander@2320: dvander@2320: printbuf = (char *)realloc(printbuf, printbuf_alloc); dvander@2320: strcpy(&printbuf[printbuf_pos], buffer); dvander@2320: printbuf_pos += len; dvander@2320: } dvander@2320: dvander@2320: void PrintBuffer::Prepend(const char *fmt, ...) dvander@2320: { dvander@2320: size_t len; dvander@2320: va_list ap; dvander@2320: char buffer[2048]; dvander@2320: dvander@2320: va_start(ap, fmt); dvander@2320: len = Sp_FormatArgs(buffer, sizeof(buffer), fmt, ap); dvander@2320: va_end(ap); dvander@2320: dvander@2320: Grow(len + 1); dvander@2320: dvander@2320: /* Move old data forward. Move one extra byte for the null terminator. */ dvander@2320: memmove(&printbuf[len], printbuf, printbuf_pos + 1); dvander@2320: printbuf_pos += len; dvander@2320: /* Move the new data in. */ dvander@2320: memcpy(printbuf, buffer, len); dvander@2320: } dvander@2320: dvander@2320: void PrintBuffer::Reset() dvander@2320: { dvander@2320: printbuf_pos = 0; dvander@2320: } dvander@2320: dvander@2320: void PrintBuffer::Dump(FILE *fp) dvander@2320: { dvander@2320: fprintf(fp, "%s", printbuf); dvander@2320: }