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 d

⟦93d08a97a⟧ TextFile

    Length: 3904 (0xf40)
    Types: TextFile
    Names: »decomp.c«

Derivation

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

TextFile

/*
 * Module: decomp.c
 *
 * Author: J. Reuter
 *
 * This module contains the code that finds each function entry
 * point in an object module and calls the decompiler proper for
 * each of the functions.
 */

#include "defs.h"
#include "main.h"
#include "labeltab.h"
#include "objfile.h"
#include "setjmp.h"

jmp_buf badbranch;

/*
 * This function sets up global symbol information and then procedes
 * to decompile the module one function at a time.  It finds each
 * functions entry point using the symbol table.
 */
decomp( tsize )
unsigned long tsize;		/* amount of code to decompile */
{
    register address start_addr, end_addr;
    register int i;
    register struct glb *g;

    /* process global, extern data */

    for ( i = 0; i < nsym/sizeof(struct nlist); i++ ) {
	if ( ((symtab+i)->n_type & ~1) == 4 )
	    glb_add( (symtab+i)->n_value, i, 1 - ((symtab+i)->n_type & 1) );
    }

    /* if there is code here to decompile... */

    if ( tsize > 0 ) {

	start_addr = 0;

	/*
	 * Get the first (by address order) global symbol.  This is
	 * the first function entry point.
	 */
	g = glb_first();

	/* for each function ... */

	do {
	    /* skip entry mask */
	    start_addr += 2;

	    /* clear the local label table */
	    llb_purge();

	    /* print g's name as the function name */
	    printf( "\n%s( ",
		   prname( &strtab[(symtab+g->sym_num)->n_un.n_strx] ) );

	    /*
	     * Get the next function entry point.  This is also, by
	     * definition, the end address of the previous function.
	     * (A fancy optimizer could screw this assumption.)
	     */
	    g = glb_next();

	    if ( g == NULL )
		end_addr = tsize;
	    else
		end_addr = g->l_address;

	    /*
	     * Make the first pass over the code.  This pass builds
	     * the tables for local register and stack variable usage.
	     */
	    tables( start_addr, end_addr );

	    /* print the argument names in the function declaration */
	    arg_names();
	    printf( " )\n" );

	    /* print the argument type declarations */
	    arg_print();
	    printf( "{\n" );

	    /* print the declarations for register variables */
	    reg_print();

	    /* print the declarations for local stack variables */
	    loc_print();
	    printf( "\n" );

	    /*
	     * The following code attempts to analyze the branch structure
	     * of the code and turn branches into C language control
	     * structures.  If something goes wrong, such as a branch
	     * outside the expected code space of the current function,
	     * a longjmp( badbranch ) will occur and the decompiler
	     * will punt and switch to disassembler mode.
	     */

	    if ( setjmp( badbranch ) == 0 ) {

		/* break up the code into a directed graph of basic blocks */
		blocks( start_addr, end_addr );

		/* turn the directed graph into a tree of control constructs */
		hier();

		/* map this tree into C specific constructs */
		hll();

		/* and print all of it */
		format();

	    } else {
		/* punt--just "disassemble" the code */
		disasm( start_addr, end_addr );
	    }

	    /* end of function */
	    printf( "}\n" );

	    /* clean up function-local tables for next function */
	    free_nodes();
	    reg_purge();
	    arg_purge();
	    loc_purge();

	    /* previous end address is next function's start address */
	    start_addr = end_addr;

#ifdef debug
	    {
		struct llb *l;
		printf( "\nlocal labels\n" );
		l = llb_first();
		while ( l != NULL ) {
		    printf( "%6d\n", l->l_address );
		    l = llb_next();
		}
	    }
#endif debug

	} while ( end_addr < tsize );

	/* print globals */

	printf( "\nglobals -- move to top\n" );
	int_print();
	ext_print();

#ifdef debug
	{
	    struct glb *g;
	    printf( "\nglobal labels\n" );
	    g = glb_first();
	    while ( g != NULL ) {
		printf( "%6d %-15s\n", g->l_address,
		       &strtab[(symtab+g->sym_num)->n_un.n_strx] );
		g = glb_next();
	    }
	}
#endif debug
    }
}