From d6d8b5b49d95ac91adc5accadf3066e4a45bbae4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 4 Mar 2011 18:44:02 +0900 Subject: [PATCH] Generate the debug symbol file. --- tools/qfcc/include/obj_file.h | 1 + tools/qfcc/source/obj_file.c | 72 +++++++++++++++++++++++ tools/qfcc/source/qfcc.c | 106 +++++++++++++++++----------------- 3 files changed, 127 insertions(+), 52 deletions(-) diff --git a/tools/qfcc/include/obj_file.h b/tools/qfcc/include/obj_file.h index 13cd40fb9..57192ae78 100644 --- a/tools/qfcc/include/obj_file.h +++ b/tools/qfcc/include/obj_file.h @@ -462,6 +462,7 @@ qfo_t *qfo_read (QFile *file); qfo_t *qfo_open (const char *filename); dprograms_t *qfo_to_progs (qfo_t *qfo, int *size); +pr_debug_header_t *qfo_to_sym (qfo_t *qfo, int *size); /** Create a new ::qfo_t struct \return pointer to new ::qfo_t struct, or 0 on error. diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index fccd27b42..740e11e9c 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -798,3 +798,75 @@ qfo_to_progs (qfo_t *qfo, int *size) // FIXME do relocs return progs; } + +pr_debug_header_t * +qfo_to_sym (qfo_t *qfo, int *size) +{ + pr_debug_header_t *sym; + int i, j; + pr_auxfunction_t *auxfuncs; + pr_lineno_t *linenos; + ddef_t *locals, *ld; + + *size = sizeof (pr_debug_header_t); + sym = calloc (1, *size); + + sym->version = PROG_DEBUG_VERSION; + for (i = 0; i < qfo->num_funcs; i++) { + qfo_func_t *func = qfo->funcs + i; + int num_locals = 0; + + if (func->locals_space) + num_locals = qfo->spaces[func->locals_space].num_defs; + if (!func->line_info && !num_locals) + continue; + sym->num_auxfunctions++; + sym->num_locals += num_locals; + } + sym->num_linenos = qfo->num_lines; + + *size += sym->num_auxfunctions * sizeof (pr_auxfunction_t); + *size += sym->num_linenos * sizeof (pr_lineno_t); + *size += sym->num_locals * sizeof (ddef_t); + sym = realloc (sym, *size); + + auxfuncs = (pr_auxfunction_t *)(sym + 1); + linenos = (pr_lineno_t *)(auxfuncs + sym->num_auxfunctions); + locals = (ddef_t *)(linenos + sym->num_linenos); + + sym->auxfunctions = (char *) auxfuncs - (char *) sym; + sym->linenos = (char *) linenos - (char *) sym; + sym->locals = (char *) locals - (char *) sym; + + ld = locals; + + for (i = 0; i < qfo->num_funcs; i++) { + qfo_func_t *func = qfo->funcs + i; + qfo_def_t *def = 0; + int num_locals = 0; + qfot_type_t *type; + + if (func->locals_space) { + num_locals = qfo->spaces[func->locals_space].num_defs; + def = qfo->spaces[func->locals_space].defs; + } + if (!func->line_info && !num_locals) + continue; + memset (auxfuncs, 0, sizeof (*auxfuncs)); + auxfuncs->function = i; + auxfuncs->source_line = func->line; + auxfuncs->line_info = func->line_info; + if (num_locals) { + auxfuncs->local_defs = ld - locals; + for (j = 0; j < num_locals; j++) + convert_def (qfo, def++, ld++); + } + auxfuncs->num_locals = num_locals; + //FIXME check type + type = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, func->type); + auxfuncs->return_type = type->t.func.return_type; + auxfuncs++; + } + memcpy (linenos, qfo->lines, qfo->num_lines * sizeof (pr_lineno_t)); + return sym; +} diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index d4bbe843b..5a7680dd0 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -158,7 +158,7 @@ InitData (void) } static int -WriteData (dprograms_t *progs, int size) +WriteProgs (dprograms_t *progs, int size) { //pr_debug_header_t debug; QFile *h; @@ -233,59 +233,52 @@ WriteData (dprograms_t *progs, int size) Qclose (h); - if (!options.code.debug) { - return 0; - } -#if 0 //FIXME - if (!(h = Qopen (options.output_file, "rb"))) - Sys_Error ("%s: %s\n", options.output_file, strerror(errno)); + return 0; +} - memset (&debug, 0, sizeof (debug)); - debug.version = LittleLong (PROG_DEBUG_VERSION); - CRC_Init (&debug.crc); - while ((i = Qgetc (h)) != EOF) - CRC_ProcessByte (&debug.crc, i); - Qclose (h); - debug.crc = LittleShort (debug.crc); - debug.you_tell_me_and_we_will_both_know = 0; +static int +WriteSym (pr_debug_header_t *sym, int size) +{ + //pr_debug_header_t debug; + QFile *h; + unsigned i; + + pr_auxfunction_t *auxfunctions; + pr_lineno_t *linenos; + ddef_t *locals; + +#define P(t,o) ((t *)((char *)sym + sym->o)) + auxfunctions = P (pr_auxfunction_t, auxfunctions); + linenos = P (pr_lineno_t, linenos); + locals = P (ddef_t, locals); +#undef P + + for (i = 0; i < sym->num_auxfunctions; i++) { + pr_auxfunction_t *af = auxfunctions++; + af->function = LittleLong (af->function); + af->source_line = LittleLong (af->source_line); + af->line_info = LittleLong (af->line_info); + af->local_defs = LittleLong (af->local_defs); + af->num_locals = LittleLong (af->num_locals); + af->return_type = LittleShort (af->return_type); + } + for (i = 0; i < sym->num_linenos; i++) { + pr_lineno_t *ln = linenos++; + ln->fa.addr = LittleLong (ln->fa.addr); + ln->line = LittleLong (ln->line); + } + for (i = 0; i < sym->num_locals; i++) { + locals[i].type = LittleShort (locals[i].type); + locals[i].ofs = LittleShort (locals[i].ofs); + locals[i].s_name = LittleLong (locals[i].s_name); + } if (!(h = Qopen (debugfile, "wb"))) - Sys_Error ("%s: %s\n", options.output_file, strerror(errno)); - Qwrite (h, &debug, sizeof (debug)); + Sys_Error ("%s: %s\n", debugfile, strerror(errno)); + Qwrite (h, sym, size); - debug.auxfunctions = LittleLong (Qtell (h)); - debug.num_auxfunctions = LittleLong (pr.num_auxfunctions); - for (i = 0; i < pr.num_auxfunctions; i++) { - pr.auxfunctions[i].function = LittleLong (pr.auxfunctions[i].function); - pr.auxfunctions[i].source_line = LittleLong (pr.auxfunctions[i].source_line); - pr.auxfunctions[i].line_info = LittleLong (pr.auxfunctions[i].line_info); - pr.auxfunctions[i].local_defs = LittleLong (pr.auxfunctions[i].local_defs); - pr.auxfunctions[i].num_locals = LittleLong (pr.auxfunctions[i].num_locals); - } - Qwrite (h, pr.auxfunctions, - pr.num_auxfunctions * sizeof (pr_auxfunction_t)); - - debug.linenos = LittleLong (Qtell (h)); - debug.num_linenos = LittleLong (pr.num_linenos); - for (i = 0; i < pr.num_linenos; i++) { - pr.linenos[i].fa.addr = LittleLong (pr.linenos[i].fa.addr); - pr.linenos[i].line = LittleLong (pr.linenos[i].line); - } - Qwrite (h, pr.linenos, pr.num_linenos * sizeof (pr_lineno_t)); - - debug.locals = LittleLong (Qtell (h)); - debug.num_locals = LittleLong (pr.num_locals); - for (i = 0; i < pr.num_locals; i++) { - pr.locals[i].type = LittleShort (pr.locals[i].type); - pr.locals[i].ofs = LittleShort (pr.locals[i].ofs); - pr.locals[i].s_name = LittleLong (pr.locals[i].s_name); - } - Qwrite (h, pr.locals, pr.num_locals * sizeof (ddef_t)); - - Qseek (h, 0, SEEK_SET); - Qwrite (h, &debug, sizeof (debug)); Qclose (h); -#endif + return 0; } @@ -385,7 +378,10 @@ finish_link (void) } if (options.code.debug) { - int str = linker_add_string (debugfile); + int str; + + setup_sym_file (options.output_file); + str = linker_add_string (debugfile); linker_add_def (".debug_file", &type_string, flags, str); } @@ -401,14 +397,20 @@ finish_link (void) dprograms_t *progs; progs = qfo_to_progs (qfo, &size); - setup_sym_file (options.output_file); //finish_compilation (); // write progdefs.h if (options.progdefs_h) progs->crc = WriteProgdefs (progs, "progdefs.h"); - WriteData (progs, size); + WriteProgs (progs, size); + if (options.code.debug) { + pr_debug_header_t *sym; + int sym_size = 0; + sym = qfo_to_sym (qfo, &sym_size); + sym->crc = CRC_Block ((byte *) progs, size); + WriteSym (sym, sym_size); + } } return 0; }