|
|
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 d
Length: 3904 (0xf40)
Types: TextFile
Names: »decomp.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦3f75c1919⟧ »EurOpenD3/utils/decomp.tar.Z«
└─⟦510c4d5ee⟧
└─⟦this⟧ »decomp/decomp.c«
/*
* 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
}
}