|
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 } }