Generate the debug symbol file.

This commit is contained in:
Bill Currie 2011-03-04 18:44:02 +09:00
parent 9a96febdf5
commit d6d8b5b49d
3 changed files with 127 additions and 52 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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));
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;
}