|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T v
Length: 11019 (0x2b0b)
Types: TextFile
Names: »vartab.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦3f75c1919⟧ »EurOpenD3/utils/decomp.tar.Z«
└─⟦510c4d5ee⟧
└─⟦this⟧ »decomp/vartab.c«
/*
* Module: vartab.c
*
* Author: J. Reuter
*
* This module contains the functions that manipulate and print
* the register, local variable, argument, internal, and external
* symbol tables.
*/
#include <stdio.h>
#include "defs.h"
#include "machine.h"
#include "vartab.h"
#include "objfile.h"
/* type declaration strings */
char *typedecl[] = {
"char",
"unsigned char",
"short",
"unsigned short",
"long",
"unsigned long",
"ERR",
"ERR",
"float",
"ERR",
"double",
"ERR",
"quad",
"ERR",
"func",
"ERR",
"char *",
"unsigned char *",
"short *",
"unsigned short *",
"long *",
"unsigned long *",
"ERR",
"ERR",
"float *",
"ERR",
"double *",
"ERR",
"quad *",
"ERR",
"func *",
"ERR",
};
/* type name suffixes for automatically generated names */
char *typesuf[] = {
"c",
"uc",
"s",
"us",
"l",
"ul",
"p",
"ERR",
"f",
"ERR",
"d",
"ERR",
"q",
"ERR",
"z",
"ERR",
"pc",
"puc",
"ps",
"pus",
"pl",
"pul",
"ERR",
"ERR",
"pf",
"ERR",
"pd",
"ERR",
"pq",
"ERR",
"pz",
"ERR",
};
/* list heads */
/*
* Note: all the lists are stored in order of increasing "address"
* (usually an offset). Type is used as a secondary sort key for
* entries that have the same address.
*
* Some of the lists are then accessed in this order. Others are
* not, but I'm too lazy to design a faster access method, and
* performance is not an issue with this software.
*/
static struct regtype reg_head = { -1, 0, 0 };
static struct regtype loc_head = { -1, 0, 0 };
static struct regtype arg_head = { -1, 0, 0 };
static struct inttype int_head = { -1, 0, 0, 0, 0, 0 };
static struct exttype ext_head = { -1, 0, 0 };
static
regadd( addr, type, flag, p )
register int addr;
register int type;
register struct regtype *p;
{
register struct regtype *m, *op;
do {
op = p;
p = p->next;
} while ( p != NULL && ( p->v_address < addr
|| ( p->v_address == addr && p->type <= type ) ) );
if ( op->v_address != addr || op->type != type ) {
m = (struct regtype *) malloc( sizeof( struct regtype ) );
if ( m == NULL ) {
fprintf( stderr, "Out of memory\n" );
exit( 1 );
}
m->v_address = addr;
m->type = type;
m->flag = flag;
op->next = m;
m->next = p;
} else {
op->flag |= flag;
}
}
reg_add( regno, type, flag )
int regno, type, flag;
{
if ( regno < AP )
regadd( regno, type, flag, ®_head );
}
loc_add( offset, type, flag )
int offset, type, flag;
{
regadd( offset, type, flag, &loc_head );
}
arg_add( offset, type, flag )
int offset, type, flag;
{
regadd( offset, type, flag, &arg_head );
}
reg_print()
{
register struct regtype *p;
p = reg_head.next;
while ( p != NULL ) {
printf( " %s r%02d%s;\n",typedecl[p->type | (p->flag & T_UNSIGNED)],
p->v_address, typesuf[p->type | (p->flag & T_UNSIGNED)] );
p = p->next;
}
}
loc_print()
{
register struct regtype *p;
p = loc_head.next;
while ( p != NULL ) {
printf( " %s L%04d%s;\n",typedecl[p->type | (p->flag & T_UNSIGNED)],
p->v_address, typesuf[p->type | (p->flag & T_UNSIGNED)] );
p = p->next;
}
}
arg_print()
{
register struct regtype *p;
p = arg_head.next;
while ( p != NULL ) {
printf( "%s A%03d%s;\n", typedecl[p->type | (p->flag & T_UNSIGNED)],
p->v_address, typesuf[p->type | (p->flag & T_UNSIGNED)] );
p = p->next;
}
}
arg_names()
{
register struct regtype *p;
p = arg_head.next;
while ( p != NULL ) {
printf( "A%03d%s", p->v_address,
typesuf[p->type | (p->flag & T_UNSIGNED)] );
p = p->next;
if ( p != NULL )
printf( ", " );
}
}
static
regpurge( p )
register struct regtype *p;
{
register struct regtype *np, *q;
q = p->next;
while ( q != NULL ) {
np = q->next;
free( q );
q = np;
}
p->next = NULL;
}
reg_purge()
{
regpurge( ®_head );
}
loc_purge()
{
regpurge( &loc_head );
}
arg_purge()
{
regpurge( &arg_head );
}
static char *
reggetsuf( addr, type, p )
register int addr;
register int type;
register struct regtype *p;
{
p = p->next;
while ( p != NULL ) {
if ( p->v_address == addr && p->type == type )
return typesuf[p->type | (p->flag & T_UNSIGNED)];
p = p->next;
}
return "ERR";
}
char symbuf[40];
char *
reg_sym( regno, type )
register int regno, type;
{
if ( regno == SP )
sprintf( symbuf, "sp" );
else if ( regno == AP )
sprintf( symbuf, "ap" );
else if ( regno == FP )
sprintf( symbuf, "fp" );
else
sprintf( symbuf, "r%02d%s", regno,
reggetsuf( regno, type, ®_head ) );
return symbuf;
}
char *
loc_sym( offset, type )
int offset, type;
{
sprintf( symbuf, "L%04d%s", offset, reggetsuf( offset, type, &loc_head ) );
return symbuf;
}
char *
arg_sym( offset, type )
int offset, type;
{
sprintf( symbuf, "A%03d%s", offset, reggetsuf( offset, type, &arg_head ) );
return symbuf;
}
int_add( addr, type, flag, class )
register int addr, type, flag, class;
{
register struct inttype *m, *p, *op;
p = &int_head;
do {
op = p;
p = p->next;
} while ( p != NULL &&
(p->v_address < addr || ( p->v_address == addr &&
(p->type < type || (p->type == type && p->class <= class) ) ) ) );
if ( op->v_address != addr || op->type != type || op->class != class ) {
m = (struct inttype *)malloc( sizeof( struct inttype ) );
if ( m == NULL ) {
fprintf( stderr, "Out of memory\n" );
exit( 1 );
}
m->v_address = addr;
m->type = type;
m->class = class;
m->flag = flag;
m->symbolnum = sym_find( addr );
if ( class == C_DATA )
m->value_ptr = (char *)(addr - datoff + (int)datatab);
op->next = m;
m->next = p;
} else {
op->flag |= flag;
}
}
int_print()
{
register struct inttype *p;
register char *st, *name;
p = int_head.next;
while ( p != NULL ) {
st = (p->flag & C_STATIC) ? "static " : "";
if ( p->symbolnum == -1 ) {
if ( p->class == C_TEXT ) {
printf( "%sG%04d%s();\n", st, p->v_address,
typesuf[p->type | (p->flag & T_UNSIGNED)] );
} else if ( p->class == C_DATA ) {
if ( (p->flag & C_WRITTEN) == 0 )
printf( "/* const */ " );
printf( "%s%s D%04d%s = ", st,
typedecl[p->type | (p->flag & T_UNSIGNED)],
p->v_address,
typesuf[p->type | (p->flag & T_UNSIGNED)] );
switch ( p->type & ~T_POINTER ) {
case T_CHAR:
case T_CHAR+T_UNSIGNED:
printf( "%d;\n", *(char *)p->value_ptr );
break;
case T_SHORT:
case T_SHORT+T_UNSIGNED:
printf( "%d;\n", *(short *)p->value_ptr );
break;
case T_LONG:
case T_LONG+T_UNSIGNED:
if ( p->type == T_LONG && ( p->next == NULL
|| p->next->v_address != p->v_address+4 ) &&
strlen( p->value_ptr ) < 200 )
c_string( p->value_ptr );
else
printf( "%d;\n", *(long *)p->value_ptr );
break;
case T_FLOAT:
printf( "%g;\n", *(float *)p->value_ptr );
break;
case T_DOUBLE:
printf( "%g;\n", *(double *)p->value_ptr );
break;
default:
printf( "funny type;\n" );
break;
}
} else {
printf( "%s%s B%04d%s;\n", st,
typedecl[p->type | (p->flag & T_UNSIGNED)],
p->v_address, typesuf[p->type | (p->flag & T_UNSIGNED)] );
}
} else {
name = prname( &strtab[ symtab[p->symbolnum].n_un.n_strx ] );
if ( p->class == C_TEXT ) {
printf( "%s%s();\n", st, name );
} else {
printf( "%s%s %s;\n", st,
typedecl[p->type | (p->flag & T_UNSIGNED)], name );
}
}
p = p->next;
}
}
char *
int_sym( addr, type, class )
register int addr, type, class;
{
register struct inttype *p;
p = int_head.next;
while ( p != NULL ) {
if ( p->v_address == addr && p->type == type && p->class == class )
break;
else
p = p->next;
}
if ( p == NULL ) {
fprintf( stderr,
"Can't find internal symbol addr %d type %d class %d\n",
addr, type, class );
return "ERR";
} else {
if ( p->symbolnum == -1 ) {
if ( p->class == C_TEXT )
sprintf( symbuf, "G%04d%s", addr,
typesuf[type | (p->flag & T_UNSIGNED)] );
else if ( p->class == C_DATA )
sprintf( symbuf, "D%04d%s", addr,
typesuf[type | (p->flag & T_UNSIGNED)] );
else
sprintf( symbuf, "B%04d%s", addr,
typesuf[type | (p->flag & T_UNSIGNED)] );
return symbuf;
} else {
return prname( &strtab[ symtab[p->symbolnum].n_un.n_strx ] );
}
}
}
ext_add( symnum, type, offset, flag )
register unsigned int symnum;
register int type, offset, flag;
{
register struct exttype *m, *p, *op;
p = &ext_head;
do {
op = p;
p = p->next;
} while ( p != NULL &&
( p->symnum < symnum ||
( p->symnum == symnum &&
( p->type < type || ( p->type == type &&
p->offset <= offset ) ) ) ) );
if ( op->symnum != symnum || op->type != type || op->offset != offset ) {
m = (struct exttype *) malloc( sizeof ( struct exttype ) );
if ( m == NULL ) {
fprintf( stderr, "Out of memory\n" );
exit( 1 );
}
m->symnum = symnum;
m->type = type;
m->offset = offset;
m->flag = flag;
op->next = m;
m->next = p;
} else {
op->flag |= flag;
}
}
ext_print()
{
register struct exttype *p;
p = ext_head.next;
while ( p != NULL ) {
if ( p->offset == 0 )
printf( "extern %s %s;\n",
typedecl[p->type | (p->flag & T_UNSIGNED)],
prname( &strtab[ symtab[p->symnum].n_un.n_strx] ) );
else
printf( "extern %s %s.O%03d%s;\n",
typedecl[p->type | (p->flag & T_UNSIGNED)],
prname( &strtab[ symtab[p->symnum].n_un.n_strx] ),
p->offset, typesuf[p->type | (p->flag & T_UNSIGNED)] );
p = p->next;
}
}
char *
ext_sym( symnum, type, offset )
register unsigned int symnum;
register int type, offset;
{
register struct exttype *p;
p = ext_head.next;
while ( p != NULL ) {
if ( p->symnum == symnum && p->type == type && p->offset == offset )
break;
p = p->next;
}
if ( p == NULL ) {
fprintf( stderr, "Can't find external symbol\n" );
return "ERR";
} else {
if ( p->offset == 0 ) {
return prname( &strtab[ symtab[p->symnum].n_un.n_strx] );
} else {
sprintf( symbuf, "%s.O%03d%s",
prname( &strtab[ symtab[p->symnum].n_un.n_strx ] ),
p->offset, typesuf[ p->type | (p->flag & T_UNSIGNED) ] );
return symbuf;
}
}
}
/* format a C initializer string */
static
c_string( s )
register char *s;
{
register int c;
putchar( '"' );
while ( (c = *s++) != 0 ) {
switch( c ) {
case '\n':
printf( "\\n" );
break;
case '\t':
printf( "\\t" );
break;
case '"':
printf( "\\\"" );
break;
case '\b':
printf( "\\b" );
break;
case '\r':
printf( "\\r" );
break;
case '\f':
printf( "\\f" );
break;
default:
putchar( c );
break;
}
}
printf( "\";\n" );
}