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