DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T v

⟦34b1001ba⟧ TextFile

    Length: 11019 (0x2b0b)
    Types: TextFile
    Names: »vartab.c«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦3f75c1919⟧ »EurOpenD3/utils/decomp.tar.Z« 
        └─⟦510c4d5ee⟧ 
            └─⟦this⟧ »decomp/vartab.c« 

TextFile

/*
 * 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, &reg_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( &reg_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, &reg_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" );
}