================================================================================
B A S T A R D                                            disassembly environment


                         Bastard  Function  HOWTO



================================================================================
 Contents

 1. The Representation of Target Functions
 2. Creating Functions
 3. Assigning Parameters to a Function
 4. Assigning Local Variables to a Function
 5. Printing a Function in the Target Assembly Language
 6. Printing a Function in the Target High-Level Language
 7. Inline Functions
 8. Function Effects


================================================================================
 1. The Representation of Target Functions

In order to correctly use FUNCTION objects in the bastard, it is important
to understand the DB representation of functions, and the reason behind it.

Each function in the target is represented in the DB as follows:

struct function {  
      unsigned long    id;
      unsigned long    rva;
      unsigned short   size;
      unsigned long    ret_type;
      unsigned long    comment;
   };

The 'id' field represents a unique number identifying the structure; rva
refers to the starting address of the function --and is an implied reference
to an ADDRESS object-- while size is the size of the function in bytes. If 
the return type is know, ret_type contains the ID of the associated DATA_TYPE
object; if the function has an associated comment --separate from the comment
of the ADDRESS object-- then the ID of the COMMENT is in the comment field.


Functions may have any number of parameters; therefore parameters are stored in
their own table:

struct func_param { 
      unsigned long    id;
      unsigned long    func;
      unsigned long    type;
      int     size;
      int     addr_exp;
      int     flags;
      char    name[32];
   };

Each parameter is associated with a FUNCTION object via the func field, which
contains the ID of the associated function. The order in which FUNC_PARAM 
objects are added to the DB implies their calling order; however, the addr_exp
field contains the ID of an ADDR_EXP object which expresses the address of the
parameter as an offset from the frame pointer, and this may override the 
implied order. The type field contains the ID or a DATA_TYPE object associated
with the parameter, and size gives the size relative to the data type --e.g. a
size of 1 indicates a single occurrence of the data type, while a size > 1
indicates an array of that data type. Finally, the name field allows function
parameters to have their own namespace, though conflicts within this namespace
are not detected.

A similar situation exists for function local variables, which also have their
own table in the DB:
   struct func_local {  
      unsigned long    id;
      unsigned long    func;
      unsigned long    type;
      int     size;
      int     addr_exp;
      int     flags;
      char    name[32];
   };
The structure for a local variable is identical to that of a parameter, and all
comments for the latter apply to the former.


================================================================================
 2. Creating Functions

   DefineFunc(long rva, char * name, int size, int flags );

   Where 'rva' is FUNCTION.rva, size is FUNCTION.size, name is the name both
   of the FUNCTION and ADDRESS objects, and flags is the flags which the name
   will have in addition to NAME_SUB.

   Thus, to create a function called "_start" at rva 0x08048AA0 which is
   automatically generated and a symbol, of unknown total size:

   DefineFunc(0x8048AA0, "_start", 0, NAME_AUTO | NAME_SYMBOL);


================================================================================
 3. Assigning Parameters to a Function

   For now, this must be done through the DB.


================================================================================
 4. Assigning Local Variables to a Function

   For now, this must be done through the DB.


================================================================================
 5. Printing a Function in the Target Assembly Language

   #include <extension.h>

   asmprint_function( struct function *func) {
      int cont;
      char *line;
      struct address a;

      line = calloc(LINE_SIZE, 1);
      ext_sprint_asm_func_start(line, LINE_SIZE, func->id);
      fprintf(f, "%s\n", line);

      cont = DBIndexFind(ADDRESS_RVA, &func->rva, &a);
      while (cont && a.rva < func->rva + func->size ) {
         if (ext_sprint_code(a.rva, line, LINE_SIZE, ASM_OUTPUT_FILE))
            printf(f, "%s\n", line);;
         cont = DBIndexNext(ADDRESS_RVA, &a);
      }

      ext_sprint_asm_func_end(line, 512, func->id);


================================================================================
 6. Printing a Function in the Target High-Level Language

   #include <extension.h>
   ext_sprint_hll_proto(buf, len, int func_id);

   #include <extension.h>
   ext_sprint_hll_func(buf, len, int func_id);


================================================================================
 7. Inline Functions

   struct f_inline {  
      unsigned long    id;
      unsigned long    type;
   };

   struct inline_type {  
      unsigned long    id;
      char    name[64];
      unsigned long    rva;
      unsigned short   size;
   };


================================================================================
 8. Function Effects

   struct func_effect {  
      unsigned long    id;
      unsigned long    func;
      int     reg;
      int     change;
   };


