Skip to content

Instantly share code, notes, and snippets.

@EmacsUser
Created March 3, 2013 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EmacsUser/5078185 to your computer and use it in GitHub Desktop.
Save EmacsUser/5078185 to your computer and use it in GitHub Desktop.
Extract of debug_load_symbols from zoom/src/debug.c in http://code.logicalshift.co.uk/zoom/zoom.git.
void debug_load_symbols(char* filename,
char* pathname)
{
ZFile* file;
ZByte* db_file;
int size;
int pos;
int done;
int x;
debug_routine* this_routine = NULL;
debug_symbol* sym;
#ifdef REMOTE_BREAKPOINT
/* SIGUSR1 indicates that we should break ASAP */
struct sigaction oldact;
sigaction(SIGUSR1, NULL, &oldact);
oldact.sa_flags |= SA_RESTART;
oldact.sa_flags &= ~(SA_NODEFER|SA_SIGINFO);
oldact.sa_handler = debug_sigusr1;
sigaction(SIGUSR1, &oldact, NULL);
#endif
size = get_file_size(filename);
file = open_file(filename);
if (file == NULL)
{
display_printf("=! unable to open file '%s'\n", filename);
return;
}
db_file = read_block(file, 0, size);
close_file(file);
if (db_file == NULL)
return;
display_printf("= loading symbols from '%s'...\n", filename);
if (db_file[0] != 0xde || db_file[1] != 0xbf)
{
display_printf("=! Bad debug file\n");
free(db_file);
return;
}
debug_syms.largest_object = 0;
pos = 6;
done = 0;
if (debug_syms.symbol == NULL)
debug_syms.symbol = hash_create();
if (debug_syms.file == NULL)
debug_syms.file = hash_create();
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_global;
sym->data.global.name = "self";
sym->data.global.number = 251-16;
debug_add_symbol(sym->data.global.name, sym);
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_global;
sym->data.global.name = "sender";
sym->data.global.number = 250-16;
debug_add_symbol(sym->data.global.name, sym);
while (pos < size && !done)
{
switch (db_file[pos])
{
case DEBUG_EOF_DBR:
done = 1;
break;
case DEBUG_FILE_DBR:
{
debug_file* fl;
ZFile* fl_load;
ZDWord fl_len;
char* fn;
fl = malloc(sizeof(debug_file));
fl->number = db_file[pos+1];
fl->name = malloc(sizeof(char)*(strlen((char*)(db_file + pos + 2)) + 1));
strcpy(fl->name, (char*)(db_file + pos + 2));
pos += 3 + strlen(fl->name);
fl->realname = malloc(sizeof(char)*(strlen((char*)(db_file + pos)) + 1));
strcpy(fl->realname, (char*)(db_file + pos));
pos += strlen(fl->realname) + 1;
fl->data = NULL;
fl->nlines = 0;
fl->line = NULL;
fn = malloc(sizeof(char)*(strlen(fl->realname)+strlen(pathname)+1));
strcpy(fn, fl->realname);
fl_len = get_file_size(fn);
if (fl_len == -1)
{
strcpy(fn, pathname);
strcat(fn, fl->realname);
fl_len = get_file_size(fn);
}
if (fl_len >= 0)
{
fl_load = open_file(fn);
if (fl_load != NULL)
{
int x;
fl->data = (char*)read_block(fl_load, 0, fl_len);
close_file(fl_load);
fl->data = realloc(fl->data, sizeof(char)*(fl_len+2));
fl->data[fl_len] = 0;
fl->nlines++;
fl->line = realloc(fl->line, sizeof(char*)*(fl->nlines));
fl->line[0] = fl->data;
for (x=0; x<fl_len; x++)
{
if (fl->data[x] == 13 || fl->data[x] == 10)
{
int p;
p = x;
if (((fl->data[x+1] == 10 || fl->data[x+1] == 13) &&
fl->data[x+1] != fl->data[x]))
x++;
fl->data[p] = 0;
if (x < fl_len)
{
fl->nlines++;
fl->line = realloc(fl->line,
sizeof(char*)*fl->nlines);
fl->line[fl->nlines-1] = fl->data + x+1;
}
}
}
}
}
else
{
display_printf("=? unable to load source file '%s'\n", fl->realname);
}
free(fn);
debug_syms.nfiles++;
if (debug_syms.nfiles != fl->number)
{
display_printf("=! file '%s' doesn't appear in order\n",
fl->name);
goto failed;
}
debug_syms.files = realloc(debug_syms.files,
sizeof(debug_file)*(debug_syms.nfiles+1));
debug_syms.files[fl->number] = *fl;
hash_store_happy(debug_syms.file,
(unsigned char*)fl->name,
strlen(fl->name),
fl);
}
break;
case DEBUG_CLASS_DBR:
{
debug_class c;
pos++;
c.name = malloc(sizeof(char)*(strlen(db_file + pos)+1));
strcpy(c.name, db_file + pos);
pos += strlen(db_file+pos) + 1;
c.st_fl = db_file[pos++];
c.st_ln = db_file[pos++]<<8;
c.st_ln |= db_file[pos++];
c.st_ch = db_file[pos++];
c.end_fl = db_file[pos++];
c.end_ln = db_file[pos++]<<8;
c.end_ln |= db_file[pos++];
c.end_ch = db_file[pos++];
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_class;
sym->data.class = c;
debug_add_symbol(c.name,
sym);
}
break;
case DEBUG_OBJECT_DBR:
{
debug_object o;
pos++;
o.number = db_file[pos++]<<8;
o.number |= db_file[pos++];
o.name = malloc(sizeof(char)*(strlen(db_file + pos)+1));
strcpy(o.name, db_file + pos);
pos += strlen(db_file+pos) + 1;
o.st_fl = db_file[pos++];
o.st_ln = db_file[pos++]<<8;
o.st_ln |= db_file[pos++];
o.st_ch = db_file[pos++];
o.end_fl = db_file[pos++];
o.end_ln = db_file[pos++]<<8;
o.end_ln |= db_file[pos++];
o.end_ch = db_file[pos++];
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_object;
sym->data.object = o;
debug_add_symbol(o.name,
sym);
if (o.number > debug_syms.largest_object) debug_syms.largest_object = o.number;
}
break;
case DEBUG_GLOBAL_DBR:
{
debug_global g;
pos++;
g.number = db_file[pos++];
g.name = malloc(sizeof(char)*(strlen(db_file + pos) + 1));
strcpy(g.name, db_file + pos);
pos += strlen(db_file + pos) + 1;
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_global;
sym->data.global = g;
debug_add_symbol(g.name,
sym);
}
break;
case DEBUG_ATTR_DBR:
{
debug_attr a;
pos++;
a.number = db_file[pos++]<<8;
a.number |= db_file[pos++];
a.name = malloc(sizeof(char)*(strlen(db_file + pos) + 1));
strcpy(a.name, db_file + pos);
pos += strlen(a.name)+1;
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_attr;
sym->data.attr = a;
debug_add_symbol(a.name,
sym);
}
break;
case DEBUG_PROP_DBR:
{
debug_prop p;
pos++;
p.number = db_file[pos++]<<8;
p.number |= db_file[pos++];
p.name = malloc(sizeof(char)*(strlen(db_file + pos) + 1));
strcpy(p.name, db_file + pos);
pos += strlen(p.name)+1;
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_prop;
sym->data.prop = p;
debug_add_symbol(p.name,
sym);
}
break;
case DEBUG_ACTION_DBR:
{
debug_action a;
pos++;
a.number = db_file[pos++]<<8;
a.number |= db_file[pos++];
a.name = malloc(sizeof(char)*(strlen(db_file + pos) + 1));
strcpy(a.name, db_file + pos);
pos += strlen(db_file + pos) + 1;
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_action;
sym->data.action = a;
/* debug_add_symbol(a.name,
sym); */
}
break;
case DEBUG_FAKEACT_DBR:
{
debug_fakeact a;
pos++;
a.number = db_file[pos++]<<8;
a.number |= db_file[pos++];
a.name = malloc(sizeof(char)*(strlen(db_file + pos) + 1));
strcpy(a.name, db_file + pos);
pos += strlen(db_file + pos) + 1;
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_fakeact;
sym->data.fakeact = a;
/* debug_add_symbol(a.name,
sym); */
}
break;
case DEBUG_ARRAY_DBR:
{
debug_array a;
pos++;
a.offset = db_file[pos++]<<8;
a.offset |= db_file[pos++];
a.name = malloc(sizeof(char)*(strlen(db_file + pos) + 1));
strcpy(a.name, db_file + pos);
pos += strlen(db_file + pos) + 1;
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_array;
sym->data.array = a;
debug_add_symbol(a.name,
sym);
}
break;
case DEBUG_HEADER_DBR:
pos++;
pos += 64;
break;
case DEBUG_LINEREF_DBR:
{
debug_line l;
int rno;
int nseq;
int x;
pos++;
rno = db_file[pos++]<<8;
rno |= db_file[pos++];
nseq = db_file[pos++]<<8;
nseq |= db_file[pos++];
if (rno != this_routine->number)
{
display_printf("=! routine number of line does not match current routine\n");
goto failed;
}
for (x=0; x<nseq; x++)
{
l.fl = db_file[pos++];
l.ln = db_file[pos++]<<8;
l.ln |= db_file[pos++];
l.ch = db_file[pos++];
l.address = db_file[pos++]<<8;
l.address |= db_file[pos++];
l.address += this_routine->start;
this_routine->line = realloc(this_routine->line,
sizeof(debug_line)*(this_routine->nlines+1));
this_routine->line[this_routine->nlines] = l;
this_routine->nlines++;
}
}
break;
case DEBUG_ROUTINE_DBR:
{
debug_routine r;
pos++;
r.number = db_file[pos++]<<8;
r.number |= db_file[pos++];
r.defn_fl = db_file[pos++];
r.defn_ln = db_file[pos++]<<8;
r.defn_ln |= db_file[pos++];
r.defn_ch = db_file[pos++];
r.start = db_file[pos++]<<16;
r.start |= db_file[pos++]<<8;
r.start |= db_file[pos++];
r.name = malloc(sizeof(char)*(strlen(db_file+pos) + 1));
strcpy(r.name, db_file + pos);
pos += strlen(r.name)+1;
r.nvars = 0;
r.var = NULL;
while (db_file[pos] != 0)
{
r.var = realloc(r.var, sizeof(char*)*(r.nvars+1));
r.var[r.nvars] = malloc(sizeof(char)*(strlen(db_file+pos) + 1));
strcpy(r.var[r.nvars], db_file+pos);
pos += strlen(r.var[r.nvars]) + 1;
r.nvars++;
}
pos++;
r.nlines = 0;
r.line = NULL;
if (this_routine != NULL &&
this_routine->start >= r.start)
{
display_printf("=! Out of order routines\n");
}
debug_syms.routine = realloc(debug_syms.routine,
sizeof(debug_routine)*
(debug_syms.nroutines+1));
debug_syms.routine[debug_syms.nroutines] = r;
this_routine = debug_syms.routine + debug_syms.nroutines;
debug_syms.nroutines++;
sym = malloc(sizeof(debug_symbol));
sym->type = dbg_routine;
sym->data.routine = debug_syms.nroutines-1;
debug_add_symbol(this_routine->name,
sym);
}
break;
case DEBUG_ROUTINE_END_DBR:
{
int rno;
pos++;
rno = db_file[pos++]<<8;
rno |= db_file[pos++];
if (rno != this_routine->number)
{
display_printf("=! routine number of EOR does not match current routine\n");
goto failed;
}
this_routine->end_fl = db_file[pos++];
this_routine->end_ln = db_file[pos++]<<8;
this_routine->end_ln |= db_file[pos++];
this_routine->end_ch = db_file[pos++];
this_routine->end = db_file[pos++]<<16;
this_routine->end |= db_file[pos++]<<8;
this_routine->end |= db_file[pos++];
}
break;
case DEBUG_MAP_DBR:
{
pos++;
while (db_file[pos] != 0)
{
char* name;
ZDWord address;
name = db_file + pos;
pos += strlen(db_file + pos) + 1;
address = db_file[pos++]<<16;
address |= db_file[pos++]<<8;
address |= db_file[pos++];
/* Fill in various fields according to what we get... */
if (strcmp(name, "code area") == 0)
{
debug_syms.codearea = address;
} else if (strcmp(name, "strings area") == 0) {
debug_syms.stringarea = address;
}
}
pos++;
}
break;
default:
display_printf("=! unknown record type %i\n", db_file[pos]);
goto failed;
return;
}
}
/* Update addresses of routines/lines */
for (x=0; x<debug_syms.nroutines; x++)
{
int y;
debug_syms.routine[x].start += debug_syms.codearea;
debug_syms.routine[x].end += debug_syms.codearea;
for (y=0; y<debug_syms.routine[x].nlines; y++)
{
debug_syms.routine[x].line[y].address += debug_syms.codearea;
}
}
free(db_file);
return;
failed:
free(db_file);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment