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

              Bastard  BC  (Bastardized C)  Scripting  Manual



================================================================================
 Language Overview


The .bc scripts employed by the bastard are executed by an embedded C-like
interpreter known as EiC. In its native state, EiC is a command shell which
allows C statements to be arbitrarily executed, and can load and execute EiC
scripts. As implemented in libbastard.so, EiC has the ability to process a
line of code, to load and process a script for later execution, and to load
and execute a standard (i.e., including a suitable main()) script. In addition,
the bastard CLI front-end sends all unrecognized commands to EiC for processing;
this allows the Bastard API routines to be invoked directly from the command
line.

In and of itself, EiC is simply an interpreter for C statements. It has no
inherent operating system access, and all memory access is made to and from a
protected area (with the execption of "unsafe pointers", discussed later). As
such, it is useless for all but the most basic arithmetic and logical functions;
however, EiC ships with its own version of the C standard library which can be
accessed as normal by including the appropriate header files with #include 
statements:
   #include <stdio.h>
   #include <string.h>
   #include <unistd.h>
   #include <stdlib.h>
The EiC standard library is contained in the file libstdClib.a, and is linked
into libbastard.so along with the EiC interpreter, libeic.a . All of the
standard library functions act as expected; for details on the contents of the
library, refer to the header files in $BASTARD_HOME/include/eic, or to the 
EiC user manual, Chapter 4.

The EiC interpreter is wrapped in libbastard.so, such that the following
preprocessor statements are included in the EiC environment:
   #pragma push_unsafeptr
   #define PATH_MAX $PATH_MAX 
   #include <bdb.h>
   #include <bastard.h>
   #include <stdlib.h>
   #define exit(x) {int y; y=x;}
As a result, every script or line of C code executed by the bastard has these
definitions and inclusions; scripts need not and should not include any of the
pre-included files. The #pragma directive forces pointers to be unsafe by
default; the #define PATH_MAX is set according to OS defaults, and the #define
exit(x) exists simply to bypass an EiC exit() problem. Including bdb.h and 
bastard.h allows all Bastard API routines and Target DB structures to be 
accessible from within any script or line of code; this built-in deviance
from standard EiC is the reason for the rechristening of the scripting language as BC, or Bastardized C.

                                                
================================================================================
 Language Syntax
 
The syntax of the EiC language is described in detail in Chapter 3 of the
EiC manual; what follows is an overview which should profice a sufficient
working knowledge of EiC.


Whitespace and Comments
EiC ignores whitespace (tabs, newlines, spaces) and comments; both the C style
of comments ( /* comment text */ ) and the C++ style ( // comment text ) are
supported. 

Identifiers and Constants
As with C, an identifier is a letter or an underscore, followed by zero or more
letters, digits, and underscores. A character constant is enclosed in single
quotes (e.g. 'c'), and a string literal is enclosed in double quotes (e.g. 
"string"); integers are prefixed with "0x" or "0X" for hexadecimal, "0" for
octal, and have no prefix for decimal representations.

Keywords
EiC has the usual reserved keywords, as well two special 'jmp' keywords:

   auto break case char const continue default do double else enum extern
   float for goto if int long register return short safe signed sizeof
   static struct switch typedef union unsafe unsigned void volatile while 
   eiclongjmp eicsetjmp

Operators
The operators for EiC likewise encompass the standard C operators:

      fn(...)           function definition of 'fn'
      a[i]              index/offset 'i' of array 'a'
      .                 structure member 
      ->                indirect structure member
      ++ --             increment/decrement 
      ! && ||           logical operations
      ~ & | ^           bitwise operations
      - + * / %         mathematical operations
      ( type-name )     cast to type 'type-name'
      << >>             shift operations
      < <= == != > >=   relational operations
      (expr) ? :        conditional expression
      = += -= *= /= %=  Assignment
      &= ^= |= <<= >>=  Assignment


Types
The types contained in EiC are, once again, standard 32-bit C types:
   Type         Bytes   Asm Equiv           Range                  Declaration
   ---------------------------------------------------------------------------
   char           1     byte            -128 to 127                     char x;
   unsigned char  1     byte               0 to 255            unsigned char x;
   short          2     word          -32768 to 32767                  short x;
   unsigned short 2     word               0 to 65535         unsigned short x;
   int            4     dword    -2147483648 to 2147483647               int x;
   unsigned int   4     dword              0 to 4294967295          unsigned x;
   long           4     dword    -2147483648 to 2147483647              long x; 
   unsigned long  4     dword              0 to 4294967295     unsigned long x;

In addition, floating point variables are supported if float.h is included:
   Type         Bytes   Asm Equiv           Range                  Declaration
   ---------------------------------------------------------------------------
   float          4     dword  1.175494E-38 to 3.402823E+38            float x;
   double         8     qword  2.225074E-308 to 1.797693E+308         double x;
   long double    8     qword  2.225074E-308 to 1.797693E+308    long double x;

Arrays of types use the C bracket notation for declaration and indexing:
   char  string[256];
   float  values[32];
   int      lotto[7];
   lotto[1] = rand();


Pointers
The syntax for pointers is in general the same as C, where * is the indirection
operator, & is the dereference operator, and -> is the structure indirection
operator:
   struct list_node head, *current; /* current is a pointer to a list_node */
   current = &head;                 /* current contains the address of head */
   current->use_count++;            /* increment the value of list_node
                                       member use_count */
In addition, pointers and arrays maintain the same "special" relationship that
they have in C:
   char *string, string2[];
   string2[1] = *(string + 1);      /* string2:index1 = string:index1 */

The declaration of a pointer takes the form
   type * (const | volatile) (safe | unsafe)  name;
e.g.,   
   char * unsafe env_string;           /* unsafe char array */
   int  * const  safe  max_attempts;   /* safe pointer to a constant int */
   void * CallbackFn;                  /* void pointer */
   int (*func)(void);                  /* pointer to function returning int */
...where 'safe' indicates that EiC should apply bounds checking to pointer
usage, and 'unsafe' means that EiC should treat the pointer as pointers are 
normally reated in C. Safe pointers are only allowed to access memory that 
has been allocated from within EiC; since many of the Bastard API routines
will be exchanging data with scripts in EiC, the default pointer type has
been set to 'unsafe' instead of 'safe'.
   
EiC also has the notion of an address specifier; this associates an EiC variable
with a specified address in memory:
   type name @ address
for example:
   long rva @ 0x08041902;
   void compiled_function(int) @ 0x08041400;
This is used for accessing data at known locations in memory; usually, it is
used to share data between a controlling process and EiC:
   int thwack_user( char *user){
      EiC_parseString( "char * unsafe username @", (long) user);
      /* call an EiC script to do the thwacking ... */
      EiC_parseString( "thwack(username);");
   }
Naturally, it is not recommended that .bc scripts employ this except in the
most dire of circumstances (e.g., acquisition of root access).
      

Structures and Unions
EiC structures and unions are the same as C, with the follwogin exceptions:
   * bitfields are not supported
   * 
Structures and unions can be initialized using the C curly-brace notation:
   struct person {
      char *name;
      int rank;
   }  somebody = { "r00t", 1024},  /* name = "r00t", rank = 1024 */
      nobody   = {0};              /* initialize structure to 0 */

   union {
      char c;
      short s;
      int i;
   } dtypes[3] = { {'z'}, {65537}, {512}};


Selection Statements
The usual if and switch statements are supported in EiC; there use should be
known to the reader. Note that EiC employs the same block statements as C:
   /* IF statement */
   if ( expr ) statement ;
   if ( expr ) {
      statement;
      ...
   }
   /* IF-ELSE statement */
   if ( expr ) statement else statement ;
   if ( expr ) statement else if ( expr ) statement else statement ;
   if ( expr ) {
      statement;
   } else if ( expr ) {
      statement;
   } else {
      statement ;
   }
   /* SWITCH statement */
   switch ( expr ) statement ;
   switch ( expr ) {
      case const:
         break;
      case const:
         break;
      default:
   }

Iteration Statements
As with Selection, so with Iteration; the normal C statements apply, including
labels and jumps:
   /* WHILE statement */
   while ( expr ) statement;
   while ( expr ) {
      statement;
   }
   /* DO-WHILE statement */
   do statement while (expr);
   do {
      statement;
   } while (expr );
   /* FOR statement */
   for ( init_expr; cond_expr; step_expr ) statement ;
   for ( init_expr; cond_expr; step_expr ) {
      statement;
   }
   /* redirection */
   name:             /* create code label called 'name' here */
   goto name;        /* jump to code label 'name' */
   continue;         /* jump to next iteration of loop */
   break;            /* break out of loop */
   return(expr);     /* return from function call */


Functions
An EiC function can return any type, including structures, unions, and pointers;
as with C, arrays and functions may not be returned by a fuction. Variable
argument lists can be represented with the usual C ellipses:
   int printf(const char *format, ...) ;
There must be at least one named parameter preceding the ellipses, and EiC will
not allow a structure or union to be passed as part of a variable argument list.

EiC does not provide default return types; all function definitions must specify
their return types:
   int Max( int x, int y) ; /* legal */
   Min( int x, int y);      /* illegal */
Also, EiC does not allow old-style C declarations; all parameter types must be
qualifed in a function definition:
   int Max( int x, int y) ; /* legal */
   int Min( x, y);          /* illegal */

}

At this point, an excerpt from the EiC manual should serve to clarify the
relationship between compiled and scripted EiC functions:

   "In EiC, there are basically two types of functions: 
      1) interpreter functions, such as those supplied by the user, and 
      2) builtin functions, which get linked into EiC at compile time.
   Naturally, builtin functions run a lot faster than interpreter 
   functions. All builtin functions must be prototyped, via including 
   the appropriate header file, before they are used, and as discussed 
   with respect to the EiC show command on page 18."

The Bastard API routines defined in eic_wrappers.c are considered "builtin"
functions by EiC; everything which is parsed by the interpreter --either
scripts or lines of C code-- is an interpreter function.


================================================================================
 The Bastard API


/* Contents:_________________________________________________________________
 1.  Low-Level DB Interface
 2.  Generic Object Access
 3.  Low-Level Disassembler Access
 4.  Loading
 5.  Saving
 6.  Sections
 7.  Disassembly
 8.  Addresses
 9.  Names & Comments
 10. Structures & Constants
 11. Code
 12. Strings
 13. Imports
 14. Exports
 15. XRefs
 16. Functions
 17. Macros
 18. Search
 19. System Interaction                                                  */

/* Notes:_________________________________________________________________
 * + The following naming conventions are used:
 *       rva       Relative Virtual Address -- the address of a location of
 *                   code or data once the program has been loaded by the OS
 *       pa        Physical Address -- the offset of a location of code or
 *                   data within the executable file/image.
 *
 * + Most routines return 0 on error or failure; the reason for the error can
 *   be found by calling sys_get_lasterr();
 *   
 * + Routines that take character arrays as arguments generally do not require
 *   the length of the array. This because the strings in the DB are of
 *   fixed length [see bdb.h], and thus it simple enough for the caller to
 *   know the size of array they should use. Naturally this goes against all
 *   sane security practice; however anyone incorporating a program such as
 *   the bastard into their firewalling policy is pretty much beyond saving.
 *   Be warned: you are expected to know what you are doing.
 */

/* DB Interface -- db.c
   ======================================================================== */
/* These are located in db.c, but are included here for the convenience of
 * the script writers who shouldn't really be using them, but probably will
 * regardless */

/* DB State -- a way to keep the DB from changing the current record inside
 *             a subroutine. Wrap all calls to the DB as follows:
 *                int *state;
 *                state = db_save_state();
 *                 ...
 *                db_restore_state(state);
 *             and you should be alright. */
void* db_save_state();
int db_restore_state(void *state);
/* ---- Low-level DB access ---- */
/*   These expect *dest to be pre-allocated */
int db_index_first(int index, void *dest);
int db_index_next(int index, void *dest);
int db_index_prev(int index, void *dest);
int db_index_last(int index, void *dest);
int db_index_find(int index, void *value, void *dest);
int db_table_first(int table, void *dest);
int db_table_next(int table, void *dest);
int db_table_prev(int table, void *dest);
int db_table_last(int table, void *dest);
int db_record_insert(int table, void *src);
int db_record_update(int index, void *value, void *src);
int db_record_delete(int index, void *value);
int db_find_closest_prev(int index, void *value, void *dest);
int db_find_closest_next(int index, void *value, void *dest);
/* ---- generic 'object' access ---- */
/*   These calloc a struct and fill it; it is up to the caller to free */
struct address * GetAddressObject(long rva);
struct code * GetCodeObject(long rva);
struct addr_exp * GetAddrExpObject(int id);
struct section * GetSectionObject(char *name);
struct xref * GetXrefObject(int id);
struct int_code * GetIntCodeObject(int id);
struct fin_code * GetFinCodeObject(int id);
struct export_addr * GetExportObject(long rva);
struct import_addr * GetImportObject(long rva);
struct string * GetStringObject(long rva);
struct name * GetNameObject(long rva);
struct comment * GetCommentObject(int id);
struct function * GetFunctionObject(int id);
struct func_param * GetFuncParamObject(int id);
struct func_local * GetFuncLocalObject(int id);
struct f_inline * GetFInlineObject(int id);
struct inline_type * GetInlineTypeObject(int id);
struct structure * struct_getureTypeObject(int id);
struct struct_member * GetStructMemberObject(int id);
struct data_type * GetDataTypeObject(int id);
struct constant * GetConstantObject(int id);
struct bc_macro * GetBCMacroObject(int id);

/* ---- Low level Disassembler access ---- */
/* These all call functions internal to the processor modules */
int disasm_prologue(struct code **c);
int disasm_epilogue(struct code **c);
int disasm_byte_order();
int disasm_addr_size();
int disasm_byte_size();
int disasm_word_size();
int disasm_dword_size();
int disasm_get_sp();
int disasm_get_ip();



/* Loading -- api_loadsave.c
   ======================================================================== */
/*  target_load : Open target file for disassenbly
 *    Return Value:   1 -- Success       0 -- Failure
 *     Arguments:      char *target -- full name/path of file to open */
int target_load( char *target );
/* target_load_bdb : Open previously disassembled file 
 *    Return Value:   1 -- Success       0 -- Failure
 *    Arguments:      char *dbname -- full name/path of .bdb file */
int target_load_bdb( char *dbname );
/* SetFileFormat : Specify Format of Target [e.g. "ELF"]
 *    Return Value:   1 -- Success       0 -- Failure
 *    Arguments:      char *file_format -- name of format
 *    Notes:      Valid formats can be listed with GetValidFormats(); */
int SetFileFormat( char *file_format );
/* SetFileArch : Specify Processor Target was compiled for [e.g. "i386"]
 *    Return Value:   1 -- Success       0 -- Failure
 *    Arguments:      char *file_arch -- name of architecture
 *    Notes:      Valid architectures are listed with GetValidArchs(); */
int SetFileArch( char *file_arch );
/* SetOutputAssembler : Set the assembly language output format -- these are
 *                      .so's in $BASTARD_HOME/asm . The output assembler
 *                      determines the [default] formatting for screen and
 *                      .asm file output [e.g. AT&T vs Intel syntax]
 *    Return Value:   1 -- Success       0 -- Failure
 *    Arguments:      char *asm_output -- name of target assembler */
int SetOutputAssembler( char *asm_output );
/* target_set_lang : Specify the language the target was written in [e.g.
 *                     C, FORTRAN] ... this determines defaults for string
 *                     style, calling convention, etc. Language modules are
 *                     .so's in $BASTARD_HOME/lang
 *    Return Value:   1 -- Success       0 -- Failure
 *    Arguments:      char *language -- name of language */
int target_set_lang( char *language );

/* Saving -- api_loadsave.c 
   ======================================================================== */
/* target_save_db : Save current DB as .bdb file
 *    Notes : Uses ./$target.bdb for filename */
void target_save_db( );
/* target_save_bak : Save current DB to a unique 'temp' filename
 *    Notes: Uses ./$target.$timestamp.bdb as filename */
void target_save_bak( );
/* target_close_db : Close the current DB and target [i.e. before loading a new one] */
void target_close_db( );
/* target_save_db_as : Save DB as the specified filename
 *    Arguments:      char *filename -- name of file to save DB as */
void target_save_db_as( char *filename );
/* target_save_asm : Save a disassembled listing of the file
 *    Return Value :   0 -- Success       -1 -- Failure
 *    Arguments :      char *filename -- name of file to save listing as 
 *    Notes :       Will change to target_save_lst and make new routine for 
 *                GAS and NASM asm files */
int target_save_asm( char *filename );
/* target_save_hex : Save a  hex dump of the target
 *    Return Value :   1 -- Success       0 -- Failure
 *    Arguments :      char *filename -- name of file to save dump as  */
int target_save_hex( char *filename );
/* target_save_diff : Create a binary diff [patch] between the original target and
 *              the current DB image of the target. Useless if you have not
 *              patched the target inside the disassembler.
 *    Return Value :   1 -- Success       0 -- Failure
 *    Arguments :      char *filename -- name of file to save diff as  */
int target_save_diff( char *filename );
/* target_save_binary : Create a new binary image of the target, using the DB image
 *                of the target. Used to 'recreate' a missing or patched 
 *                target.
 *    Return Value :   1 -- Success       0 -- Failure
 *    Arguments :      char *filename -- name of file to save target as  */
int target_save_binary( char *filename );

/* Sections -- api_section.c
   ======================================================================== */
 /* SECTION types and permissions */
#define SECTION_HDR      0x1000
#define SECTION_CODE   0x1100
#define SECTION_DATA   0x1200
#define SECTION_RSRC   0x1300
#define SECTION_IMPORT   0x1400
#define SECTION_EXPORT   0x1500
#define SECTION_DEBUG   0x1600
#define SECTION_CMT      0x1700
#define SECTION_RELOC   0x1800
#define SECTION_EXECUTE   0x01
#define SECTION_WRITE   0x02
#define SECTION_READ   0x04
/*  sec_new :  Create a program section or segment
 *    Return Value:   1 = success, 0 = error
 *     Arguments:      char *name -- name of section [must be unique]
 *                    long start -- starting rva of section 
 *                    long pa    -- starting physical addr of section
 *                    int  size  -- size of section, in bytes
 *                    int  type  -- section type ORed with permissions : 
   types : SECTION_HDR   SECTION_CODE SECTION_DATA SECTION_RSRC SECTION_RELOC
           SECTION_IMPORT SECTION_EXPORT SECTION_DEBUG SECTION_CMT   
   perms : SECTION_EXECUTE SECTION_WRITE   SECTION_READ           */
int sec_new( char *name, long start, int size, long pa, int type );
/*  sec_del : Delete a program section [be careful!]
 *    Return Value:   1 = success, 0 = error
 *     Arguments:      char *name -- name of section to delete  */
int sec_del( char *name );
/*  sec_get : Finds the Section that contains a given addr
 *    Return Value: 1 if found, 0 if not
 *    Arguments:    long rva   -- known address
 *                  section *s -- empty structure to fill w/ found section */
int sec_get( long rva, struct section *s);
/*  sec_get_start : Get starting address of a given section
 *    Return Value: rva of start of section, 0 if not found   
 *     Arguments:     char *name -- name of section to get the start of    */
    /* FIX: should increase the end addr of the prev section thru curr->end */
long sec_get_start( char *name );
/*  sec_get_end : Get address of the last byte in a given section
 *    Return Value: rva of end of section [not last ADDRESS in section!] or 0   
 *     Arguments:     char *name -- name of section to get the end of    */
long sec_get_end( char *name );
/*  sec_get_by_rva : Get name of section
 *    Return Value:   1 if found, 0 if not
 *     Arguments:      long rva     -- address within section 
 *                    char buf[32] -- buffer to fill with section name */
int  sec_get_by_rva( long rva, char* buf );
/*  sec_flags : Get section type/permissions 
 *    Return Value:   Type and permissions OR'ed together
 *     Arguments:      char *name -- name of section to get the flags of */
int  sec_flags( char *name );
/*  sec_set_start :  Set the starting address of a section
 *    Return Value:     1 if success, 0 if error
 *     Arguments:        char *name -- name of section
 *                      long start -- new starting rva of section */
int  sec_set_start( char *name, long start );
/*  sec_get_end : Set the ending address of a section
 *    Return Value:   1 if success, 0 if error
 *     Arguments:      char *name -- name of section
 *                    long end   -- rva of the "new" last byte in the section */
int  sec_get_end( char *name, long end );
/*  sec_rename : Set the name of a section
 *    Return Value:   1 if success, 0 if error
 *     Arguments:      char *name == old name, char *new_name = new name */
int  sec_rename( char *name, char *new_name );
/*  sec_set_flags : Change the type/permissions of a section
 *    Return Value:   1 id success, 0 if failure
 *     Arguments:      char *name -- name of section
 *                    int  flags -- new type and permissions ORed together */
int  sec_set_flags( char *name, int flags );

/* Disassembly -- api_disasm.c
   ======================================================================== */
#define BIG_ENDIAN_ORD       0
#define LITTLE_ENDIAN_ORD    1
/*  target_set_header : Create ASCII representation of the file/program header
 *    Return Value:   1 id success , 0 if failure
 *     Arguments:      char *header = ASCII representation of header    */
int target_set_header( char *header );
char * target_header( );
/*  sys_initDisassembler : Load and initialize disassembler module
 *                     This sets the processor type for subsequent disassembly.
 *                     Note that the disasm_eng structure will be passed to
 *                     the processor module in order to perform any cpu-
 *                     specific init [like default address size] -- so do all
 *                     mods to that structure before making this call.
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      char *disasm -- name of processor module to load. This is
 *                                    the part of the name between "lib" and 
 *                                    ".so", e.g. libi386.so would be loaded as
 *                                    "i386" */
int sys_initDisassembler( char *disasm );
/*  DisassembleFull : Perform a full-featured deluxe-o-rama disassembly:
 *                     1. disasm_forward() from each known function
 *                     2. disasm_forward() from the entry point
 *                     3. Perform all passes under $BASTARD_HOME/engines
 *    Return Value:   1 if success, 0 if error
 *     Arguments:      none  */
int DisassembleFull( );
/*  DisassembleDumb : Perform a simple, brain-dead disassembly:
 *                     1. Do a disasm_section() of each section of type
 *                        SECTION_CODE or with SECTION_EXECUTE permissions
 *                     2. That's it.
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      none  */
int DisassembleDumb( );
/*  disasm_section : Perform a linear disassembly of a section. This does
 *                       no flow-of execution; rather it calls disasm_range
 *                       for the starting rva & size of the section
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      char *name -- name of section to disassemble */
int disasm_section( char *name );
/*  disasm_range :   Perform a linear disassembly on a range of addresses;
 *                       this blindly disassembles instruction after instruction
 *                       with no branch following/etc, until the end of the
 *                       range is reached.
 *    Return Value:    1 if success, 0 if failure
 *     Arguments:       long rva  -- address to start disassembly at
 *                     int  size -- size of range to disassemble [in bytes] */
int disasm_range( long rva, int size );
/*  disasm_forward : Perform a flow-of-execution disassembly starting at
 *                       the given address. The disassembly attempts to 
 *                       follow branches and will not overwrite existing CODE
 *                       objects [they will be skipped -- as with the other
 *                       disassembly routines. this behavior is determined in
 *                       disasm_addr(), the backend to all of these api routines].
 *    Return Value:   
 *     Arguments:       */
int disasm_forward( long rva );
/*  disasm_pass :    Performa a single post-disassembly pass on the target.
 *                       Passes are in the pass#.sc files in the engines/
 *                       directory; the # in the file name is the number used
 *                       to specify which pass to perform.
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      int pass -- the number of the pass to perform */
int disasm_pass( int pass );
/*  disasm_all_passes : Performs all passes on the target 
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      none */
int disasm_all_passes();

/* Addresses -- api_address.c
   ======================================================================== */
 /* ADDRESS types and permissions */
#define ADDR_CODE      0x01
#define ADDR_DATA      0x02
#define ADDR_IMPORT      0x10
#define ADDR_EXPORT      0x20
#define ADDR_SECTION   0x40
#define ADDR_STRUCT      0x100
#define ADDR_STRING      0x200
#define ADDR_FUNCTION   0x300
#define ADDR_INLINE      0x400
#define ADDR_NAME      0x1000
#define ADDR_COMMENT   0x2000
#define ADDR_SYMBOL   0x4000
/* these are really just guesses based on target size and base rva */
/*  addr_is_valid :  Determine if given address is valid [ this is interpreted
 *                 to mean 'the given rva exists in some section', not 'the
 *                 given rva belongs to an ADDRESS object]. This is a bit
 *                 redundant with sec_get(), but makes code more clear.
 *    Return Value:   1 if valid, 0 if invalid
 *     Arguments:      long rva -- address to be checked */
int addr_is_valid( long rva );
/*  addr_is_valid_code : Determine if given address is a valid code address 
 *                    [i.e., does it exist in a section of type SECTION_CODE]
 *    Return Value:   1 if valid, 0 if invalid
 *     Arguments:      long rva -- address to be checked */
int addr_is_valid_code( long rva );
/*  addr_exists : Determine if the given address is an ADDRESS object
 *    Return Value:   1 if it exists, 0 if it does not
 *     Arguments:      long rva -- address to be checked */
int addr_exists( long rva );
/*  addr_find_closest : Find ADDRESS object containing given address --
 *                    this searches if 'rva' exists and, if it doesn't,
 *                    searches backwards looking for the ADDRESS object
 *                    that begins before rva.
 *    Return Value:    the rva closest to the given address
 *     Arguments:       long rva -- address to be located */
long addr_find_closest( long rva );
/*  addr_new :      Create an ADDRESS object at the given address, of the
 *                    specified size. This will resize existing addresses if
 *                    need be.
 *    Return Value:    1 if success, 0 if failure
 *     Arguments:       long rva   -- address to be created
 *                     int  size  -- size of address in bytes
 *                     long  pa   -- physical address of 'rva'
 *                     int  flags -- Flags for ADDRESS object, e.g. : 
 *                                   ADDR_CODE ADDR_DATA */
int addr_new( long rva, int size, long pa, int flags );
/*  addr_del :  Remove ADDRESS object for given address
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      long rva -- address to delete */
int addr_del( long rva );
/*  asmsprintf : print formatted line of assembly to buffer. This is like
 *                 sprintf(), only with custom format specificers:
 *                  %a - rva            %p - pa               %n - name  
 *                  %m - mnemonic       %b - hex bytes        %S - section name
 *                  %d - dest operand   %s - source operand   %t - aux operand
 *                  %c - comment        %x - xrefs
 *                 These specifiers allow a length byte, which for string
 *                 specifiers [%a %pa %n %m %s %d %x %S %c] limits the length
 *                 of the string, for xrefs or hex bytes [%x %b] soecifies 
 *                 how many to display. Examples:
 *                     %4x  - show up to 4 xrefs
 *                     %8b  - show up to 8 hexadecimal bytes
 *                     %64c - show up to 64 characters of comment
 *                 There are conditional punctuation specifiers:
 *                  %, - insert a comma if the next specifier is non-null
 *                  %; - insert a semicolon if any text follows
 *                  %: - append a colon if any text precedes it
 *                  %^ - append a newline if any text precedes it
 *                 The default format string for the Intel architecture is:
 *                     "%n%:%^%a %8b\t%m\t%d%, %s %;%c %x"
 *                 Note that as with sprintf(), a '%' can be printed by using
 *                 "%%".
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      char *buf    -- buffer to fill. It better e big enough.
 *                    char *format -- format string 
 *                    struct address *addr -- address to be printed */
int asmsprintf(char *buf, char *format, struct address *addr);
/*  : 
 *    Return Value:   
 *     Arguments:       */
int addr_print( long rva );
/*  addr_make_code : 
 *    Return Value:   
 *     Arguments:       */
int addr_make_code( long addr );
/*  addr_make_data : 
 *    Return Value:   
 *     Arguments:       */
int addr_make_data( long addr );
/*  addr_pa : 
 *    Return Value:   
 *     Arguments:       */
long addr_pa( long rva );
/*  addr_rva : 
 *    Return Value:   
 *     Arguments:       */
long addr_rva( long pa );
/*  addr_type : 
 *    Return Value:   
 *     Arguments:       */
int addr_type( long rva );
/*  addr_size : 
 *    Return Value:   
 *     Arguments:       */
int addr_size( long rva );
/*  addr_flags : 
 *    Return Value:   
 *     Arguments:       */
int addr_flags( long addr );
/*  addr_bytes : 
 *    Return Value:   
 *     Arguments:       */
int addr_bytes( long rva, char *buf );
/*  addr_next : 
 *    Return Value:   
 *     Arguments:       */
long addr_next( long rva );
/*  addr_prev : 
 *    Return Value:   
 *     Arguments:       */
long addr_prev( long rva );
/*  addr_set_flags : 
 *    Return Value:   
 *     Arguments:       */
int addr_set_flags( long rva, int flags );
 /*
  addr_make_data( addr, size );
    Note that addr_make_data provides a size attr -- it is up to the front-end to
   display this as a byte, word, dword, or array
 name_get( addr, char* );
    returns size, 0 [no name], or -1 [no addr]
 JumpTo( addr );
    use this to follow xrefs
 GetBranchCode( addr );
    Gets next code item from a JMP/JCC
 GetPrevData( addr );
 GetPrevCode( addr );
*/


/* Names & Comments -- api_namecmt.c
   ======================================================================== */
   /* Name Types */
#define NAME_AUTO      0x01
#define NAME_SUB      0x02
#define NAME_USER      0x10
#define NAME_SYMBOL   0x20
   /* Comment Types */
#define CMT_AUTO      0x01
#define CMT_USER      0x02
/*  name_new : 
 *    Return Value:   
 *     Arguments:       */
int name_new( long rva, char* name, int type );
/*  name_get : 
 *    Return Value:   
 *     Arguments:       */
int name_get( long rva, char* buffer );
/*  name_get_type: 
 *    Return Value:   
 *     Arguments:       */
int name_get_type(long addr);
/*  addr_get_by_name: 
 *    Return Value:   
 *     Arguments:       */
long addr_get_by_name( char *name );
/*  addr_add_comment : 
 *    Return Value:   
 *     Arguments:       */
int addr_add_comment( long rva, char *buf );
/*  addr_comment : 
 *    Return Value:   
 *     Arguments:       */
int addr_comment( long rva );
/*  addr_set_comment : 
 *    Return Value:   
 *     Arguments:       */
int addr_set_comment( long rva, int id );
/*  comment_get: 
 *    Return Value:   
 *     Arguments:       */
int comment_get( int id, char *buf );
/*  comment_new: 
 *    Return Value:   
 *     Arguments:       */
int comment_new( char *buf, int type );
/*  comment_change: 
 *    Return Value:   
 *     Arguments:       */
int comment_change( int id, char *buf );
/*  comment_del: 
 *    Return Value:   
 *     Arguments:       */
int comment_del( int id ) ;



/* Structures & Constants -- api_structconst.c
   ======================================================================== */
/*  addr_constant : 
 *    Return Value:   
 *     Arguments:       */
int addr_constant( long rva );
/*  addr_struct : 
 *    Return Value:   
 *     Arguments:       */
int addr_struct( long rva );
/*  addr_set_constant : 
 *    Return Value:   
 *     Arguments:       */
int addr_set_constant( long rva, int id );
/*  addr_set_struct : 
 *    Return Value:   
 *     Arguments:       */
int addr_set_struct( long rva, int id );
// *buf is buf[32]
/*  const_new: 
 *    Return Value:   
 *     Arguments:       */
int const_new( char *name, int value);
/*  const_get_by_val: 
 *    Return Value:   
 *     Arguments:       */
int const_get_by_val(int value, char buf[32]);
/*  const_get_by_valNext: 
 *    Return Value:   
 *     Arguments:       */
int const_get_by_valNext( char buf[32]);
/*  const_get_name: 
 *    Return Value:   
 *     Arguments:       */
int const_get_name( unsigned long id, char buf[32]);
/*  const_get_by_name: 
 *    Return Value:   
 *     Arguments:       */
unsigned long const_get_by_name( char *name);
/*  const_del: 
 *    Return Value:   
 *     Arguments:       */
int const_del( unsigned long id);
   /*CreateStructure( char*, name);
      Prob isn't necessary -- can be provided by the UI
   struct_apply( name, addr );*/


/* Code -- api_code.c
   ======================================================================== */
 /* Operand and instruction types */
/*                   Permissions: */
#define OP_R         0x001      /* operand is READ */
#define OP_W         0x002      /* operand is WRITTEN */
#define OP_X         0x004      /* operand is EXECUTED */
/*                   Types: */
#define OP_REG       0x100      /* register */
#define OP_IMM       0x200      /* immediate value */
#define OP_REL       0x300      /* relative Address [offset] */
#define OP_PTR       0x400      /* Pointer */
#define OP_EXPR      0x500      /* Address Expression [e.g. SIB byte] */
#define OP_UNK       0xE00      /* unknown operand */     
/*                   Modifiers: */
#define OP_IND       0x001000   /* indirect memory reference */
#define OP_STRING    0x002000   /* operand a string */
#define OP_SIGNED    0x003000   /* operand is signed */
#define OP_CONST     0x004000   /* operans is a constant */
/*                   Size: */
#define OP_BYTE      0x100000   /* operand is  8 bits/1 byte  */
#define OP_WORD      0x200000   /* operand is 16 bits/2 bytes */
#define OP_DWORD     0x300000   /* operand is 32 bits/4 bytes */
#define OP_QWORD     0x400000   /* operand is 64 bits/8 bytes */
/* operand masks */
#define OP_PERM_MASK 0x0000007  /* perms are NOT mutually exclusive */
#define OP_TYPE_MASK 0x0000F00  /* types are mututally exclusive */
#define OP_MOD_MASK  0x00FF000  /* mods are NOT mutual;y exclusive */
#define OP_SIZE_MASK 0x0F00000  /* sizes are mutually exclusive */

#define OP_REG_MASK    0x0000FFFF /* lower WORD is register ID */
#define OP_REGTBL_MASK 0xFFFF0000 /* higher word is register type [gen/dbg] */

#define INS_BRANCH   0x01        /* Unconditional branch */
#define INS_COND     0x02     /* Conditional branch */
#define INS_SUB      0x04     /* Jump to subroutine */
#define INS_RET      0x08     /* Return from subroutine */
    /* modify ( 'w' ) instructions */
#define INS_ARITH    0x10       /* Arithmetic inst */
#define INS_LOGIC    0x20       /* logical inst */
#define INS_FPU      0x40       /* Floating Point inst */
#define INS_FLAG     0x80       /* Modify flags */
    /* misc Instruction Types */
#define INS_MOVE     0x0100
#define INS_ARRAY    0x0200   /* String and XLAT ops */
#define INS_PTR      0x0400   /* Load EA/pointer */
#define INS_STACK    0x1000   /* PUSH, POP, etc */
#define INS_FRAME    0x2000   /* ENTER, LEAVE, etc */
#define INS_SYSTEM   0x4000   /* CPUID, WBINVD, etc */
   /* instruction size */
#define INS_BYTE      0x10000   /* operand is  8 bits/1 byte  */
#define INS_WORD      0x20000   /* operand is 16 bits/2 bytes */
#define INS_DWORD      0x40000   /* operand is 32 bits/4 bytes */
#define INS_QWORD      0x80000   /* operand is 64 bits/8 bytes */
/*  code_new: 
 *    Return Value:   
 *     Arguments:       */
int code_new(long rva, struct code *c);
/*  code_del: 
 *    Return Value:   
 *     Arguments:       */
int code_del(long rva);
/*  addr_next_code: 
 *    Return Value:   
 *     Arguments:       */
long addr_next_code( long rva );
/*  addr_next_data: 
 *    Return Value:   
 *     Arguments:       */
long addr_next_data( long rva );
/*  code_sprint: 
 *    Return Value:   
 *     Arguments:       */
int code_sprint( char *buf, char *fmt, long rva ) ;
/*  GetMnemonic: 
 *    Return Value:   
 *     Arguments:       */
int GetMnemonic( long rva, char *buf );
/*  GetSrc: 
 *    Return Value:   
 *     Arguments:       */
int GetSrc( long rva );
/*  GetDest: 
 *    Return Value:   
 *     Arguments:       */
int GetDest( long rva );
/*  GetAux: 
 *    Return Value:   
 *     Arguments:       */
int GetAux( long rva );
/*  GetMnemType: 
 *    Return Value:   
 *     Arguments:       */
int GetMnemType( long rva );
/*  GetSrcType: 
 *    Return Value:   
 *     Arguments:       */
int GetSrcType( long rva );
/*  GetDestType: 
 *    Return Value:   
 *     Arguments:       */
int GetDestType( long rva );
/*  GetAuxType: 
 *    Return Value:   
 *     Arguments:       */
int GetAuxType( long rva );
   /* 
   code_sprint( addr );
      Returns a basic [INTEL fmt] representation of the line of code
   addr_flags( code );
*/
/*   Address Expressions -- api_code.c
   ======================================================================== */
/* these could reuse OP types, but those types are too general... */
#define ADDEXP_SCALE_MASK  0x000000FF
#define ADDEXP_INDEX_MASK  0x0000FF00
#define ADDEXP_BASE_MASK   0x00FF0000
#define ADDEXP_DISP_MASK   0xFF000000
#define ADDEXP_SCALE_OFFSET 0
#define ADDEXP_INDEX_OFFSET 8
#define ADDEXP_BASE_OFFSET  16
#define ADDEXP_DISP_OFFSET  24
#define ADDREXP_BYTE    0x01
#define ADDREXP_WORD    0x02
#define ADDREXP_DWORD   0x03     
#define ADDREXP_QWORD   0x04
#define ADDREXP_REG     0x10 /*0x00 implies non-register */

#define AddrExp_ScaleType(x) x & ADDEXP_SCALE_MASK
#define AddrExp_IndexType(x) (x & ADDEXP_INDEX_MASK) >> 8
#define AddrExp_BaseType(x) (x & ADDEXP_BASE_MASK) >> 16
#define AddrExp_DispType(x) (x & ADDEXP_DISP_MASK) >> 24

int addrexp_new(int scale, int index, int base, int disp, int flags);
int addrexp_get( int id, struct addr_exp *exp );
int addrexp_get_str( int id, char *string, int len);

/*   Strings -- api_strings.c
   ======================================================================== */
#define STR_STD  1
#define STR_WIDE 2
/*  str_get: 
 *    Return Value:   
 *     Arguments:       */
int str_get( long rva, char *buf, int len );
/* gets entire string from binary file, puts it in buf, returns length */
int str_get_raw(long rva, char **buf);
/*  str_new: 
 *    Return Value:   
 *     Arguments:       */
int str_new( long rva );
/*  str_print: 
 *    Return Value:   */   
int str_print( ); /* print all strings/addresses to stdout */
/* rva : start of range   size: extent of range  type: string type */
int str_find_in_range(long rva, int size, int type);


/* Imports -- api_importexport.c
   ======================================================================== */
/*  imp_new: 
 *    Return Value:   
 *     Arguments:       */
int imp_new( long rva, char *lib, char* name, int type );
/*  imp_get_name: 
 *    Return Value:   
 *     Arguments:       */
int imp_get_name( long rva, char *buf );
/*  imp_get_lib: 
 *    Return Value:   
 *     Arguments:       */
int imp_get_lib( long rva, char *buf );
/*  imp_type: 
 *    Return Value:   
 *     Arguments:       */
int imp_type( long rva );
/*  imp_print: 
 *    Return Value:   
 *     Arguments:       */
int imp_print( );
/*  lib_new: 
 *    Return Value:   
 *     Arguments:       */
int lib_new( char *name, int v_hi, int v_lo );
/*  lib_print: 
 *    Return Value:   
 *     Arguments:       */
int lib_print( );   /* print all libraries to stdout */


/* Exports -- api_importexport.c
   ======================================================================== */
/*  exp_new: 
 *    Return Value:   
 *     Arguments:       */
int exp_new( long rva, char *name );
/*  exp_get: 
 *    Return Value:   
 *     Arguments:       */
int exp_get( char *name );
/*  exp_print: 
 *    Return Value:   
 *     Arguments:       */
int exp_print( ); /* list all entry points */


/* XRefs -- api_xref.c
   ======================================================================== */
    /* Xref Types */
#define XREF_READ      0x01
#define XREF_WRITE   0x02
#define XREF_EXEC      0x04
/*  xref_to: 
 *    Return Value: from_rva or 0 if no matches   
 *     Arguments:     rva  -- address to find references to
 *                    type -- type of xref to match [OP_R | OP_W | OP_X] or 0 */
long xref_to( long rva, int type ) ;       //get first
/*  xref_to_next: 
 *    Return Value:   from_rva or 0 if no more matches   
 *     Arguments:     type -- type of xref to match [OP_R | OP_W | OP_X] or 0 */
long xref_to_next( int type ) ; //get array of structs; return num
/*  xref_from: 
 *    Return Value: to_rva or 0 if no matches   
 *     Arguments:     rva  -- address to find references from
 *                    type -- type of xref to match [OP_R | OP_W | OP_X] or 0 */
long xref_from( long rva, int type ) ;
/*  xref_from_next: 
 *    Return Value: to_rva or 0 if no more matches   
 *     Arguments:     type -- type of xref to match [OP_R | OP_W | OP_X] or 0 */
long xref_from_next( int type ) ;
/*  xref_new: 
 *    Return Value: 1 on success, 0 on error 
 *     Arguments:       */
int xref_new( long from, long to, int type );


/* Functions -- api_functions.c
   ======================================================================== */
/*  func_new: 
 *    Return Value:   
 *     Arguments:       */
int func_new( long rva, char * name, int size );
/*  func_get_name: 
 *    Return Value:   
 *     Arguments:       */
int func_get_name( long rva, char *buf );
/*  func_get_start: 
 *    Return Value:   
 *     Arguments:       */
int func_get_start( long rva );
/*  func_get_end: 
 *    Return Value:   
 *     Arguments:       */
int func_get_end( long rva );
/*  func_get_by_name: 
 *    Return Value:   
 *     Arguments:       */
int func_get_by_name( char *name );
/*  func_set_name: 
 *    Return Value:   
 *     Arguments:       */
int func_set_name( long rva, char *name );
/*  func_set_size: 
 *    Return Value:   
 *     Arguments:       */
int func_set_size( long rva, int size );
 /*
 MakeFunction();
 SetFunctionComment();
 GetFunctionComment();
 GetFunctionPrototype();
    A type of comment
 SetFunctionPrototype();
 MakeInlineFunction( addr, name );
 ApplyInlineFunction( name );
    consider these to be 'structs' for code...*/


/* Macros -- api_macros.c
   ======================================================================== */
   /* Macro Types */
#define SEERC_CODE   0x01
#define SEERC_FILE   0x02
/*  script_file_exec: Run a script contained in a file 
 *    Return Value:   Exit status of script
 *     Arguments:      char *name -- name of file to compile and execute */
int script_file_exec( char *name );
/*  script_text_exec: Compile and run the provided code
 *    Return Value:   Exit status of script
 *     Arguments:      char *script -- code to compile and execute */
int script_text_exec( char *script );
/*  script_compiled_exec: Run a precompiled script
 *    Return Value:     Exit status of script
 *     Arguments:        char *name -- name of file to load and run */
int script_compiled_exec(char *name);
/*  script_compile: Compile a script file
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      char *name -- name of file to compile */
int script_compile(char *name);
/*  macro_new: 
 *    Return Value:   
 *     Arguments:       */
int macro_new( char *name, char *macro );
/*  macro_del: 
 *    Return Value:   
 *     Arguments:       */
int macro_del( char *name );
/*  macro_exec: 
 *    Return Value:   
 *     Arguments:       */
int macro_exec( char *name );
/*  macro_record: 
 *    Return Value:   
 *     Arguments:       */
int macro_record( char *name );

/* Search -- api_search.c
   ======================================================================== */
/* Each of these 'Find' functions initiates a search if *search is NULL --
 * the Find becomes a FindFirst, and *search is filled with a search handle.
 * Subsequent calls to the Find function act as a FindNext, until the search
 * returns 0 hits [and the handle is automatically freed]. If you are finished
 * with the search before it returns 0 --for example if you only want the first
 * ten matches -- then you must call find_free_handle to dealloc the memory
 * used for *search. */

/*  find_bytes: Find a sequence of bytes in the target image
 *    Return Value:   Rva of found location or 0 if not found
 *     Arguments:      char * bytes -- sequence of bytes to search for
 *                    int    len   -- length of the sequence 
 *                    int **search -- void pointer to store search handle in */
int find_bytes( unsigned char *bytes, int len, int **search);
/*  find_operand:     Find an operand in all the code objects
 *    Return Value:   rva of match or 0 if no match
 *     Arguments:      char *str    -- operand to search for 
 *                    int **search -- void pointer to store search handle in */
int find_operand( char *str, int **search);
/*  find_mnemonic:    Find a mnemonic in all the code objects
 *    Return Value:   rva of match or 0 if no match
 *     Arguments:      char *str    -- mnemonic to search for
 *                    int **search -- void pointer to store search handle in */
int find_mnemonic( char *str, int **search);
/*  find_constant:    Find an Imeediate Value/Constant in all the CODE objects
 *    Return Value:   rva of match or 0 if no match
 *     Arguments:      long value   -- value to search for 
 *                    int **search -- void pointer to store search handle in */
int find_constant( long value, int **search);
/*  find_free_handle: Use this if you terminate a search before viewing all
 *                    the hits.
 *    Return Value:    Returns a count of the matches examined
 *     Arguments:       int **search -- void pointer to a search handle */
int find_free_handle( int **search );

/* The following searches are one-offs and do not use a search handle.
 * These take a given operand [assumed to be a regiser or address] and
 * search backwards or forwards for up to 'ttl' instructions looking for
 * an instruction where that operand is accessed with OP_R, OP_W, or OP_X
 * permissions. 
 *    Return Value:   rva where the match occurs or 0 if ttl expired
 *    Arguments:      char *operand -- operand to search for
 *                    long rva      -- address to start searching after/before
 *                    int ttl       -- max # of addresses to search */
long find_next_op_r( char *operand, long rva, int ttl );
long find_prev_op_r( char *operand, long rva, int ttl );
long find_next_op_w( char *operand, long rva, int ttl );
long find_prev_op_w( char *operand, long rva, int ttl );
long find_next_opsys_x( char *operand, long rva, int ttl );
long find_prev_opsys_x( char *operand, long rva, int ttl );

/* System Interaction -- api_system.c
   ======================================================================== */
/* bastard environment :  flags */
/*      Current state of target */
#define DB_LOADED       0x00000001        /* .bdb loaded */
#define TGT_MAPPED      0x00000002        /* target bin image mmap'ed */
#define DB_MOD          0x00000004        /* .bdb has been modified */
#define TGT MOD         0x00000008        /* target bin image modified */
/*      Current state of disassembly */
#define PASS_1          0x00000010        /* main disassembly pass */
#define PASS_2          0x00000020        /* subsequent passes */
#define CODE_INT        0x00000040        /* intermediate code rep is done */
#define CODE_FIN        0x00000080        /* final code rep is done */
/*      Safety stuff */
#define DISABLE_EXEC    0x00010000  /* do not allow shell escapes */
#define QUIT_NOW        0x00080000  /* Easier this way */
/*     *Bastard Prefs: OPTIONS *        */
/*      User convenience */
#define PAGINATE        0x00000100
#define COLOR_TTY       0x00000200
/*      User inconvenience ;) */
#define QUIET           0x00001000  /* print std msgs to STDOUT */
#define ANNOY_USER      0x00002000  /* bug user with save prompts, etc */
#define DEBUG_TIME      0x00008000  /* horrendous debug output */
/*      Auto-Disasm controls */
#define DISASM_REDO     0x00100000  /* redo existing code [default: skip it] */

#define ASM_OUTPUT_TTY       0x00
#define ASM_OUTPUT_FILE      0x01
#define ASM_OUTPUT_PRINTER   0x02
#define ASM_OUTPUT_TTY_COLOR 0x03
/* bastard environment :  structs */
struct DISASM_ENV {
      char   home[256]; /* bastard dir info */
      char   p1[16];    /* main prompt */
      char   p2[16];    /* multiline prompt */
      char   p3[16];    /* 'other' prompt */
      char   p4[16];    /* help system prompt */
      /* eventually this will just be asmFmt and datFmt */
      /* .asm file format and lpr format will be in assembler struct */
      char   dbpath[256];
      int    targetDB;
      int    configDB;
      void   *db_open;  /* linked list of open DBs (TODO) */
      void   *db_current;  
      int    output;   /* defualt output type */
      int    flags;
};

struct DISASM_PREFS {
      char pager[PATH_MAX]; /* default pager to use */
      char editor[PATH_MAX]; /* default editor to use */
      char debugger[PATH_MAX]; /* default editor to use */
      int options;
      int override;
};

struct DISASM_TGT {   /* target information */
      int    FD;               // fd to .bdb image of target
      //caddr_t   image;         // memory mapped image of target
      //size_t   size;            // size of target
      char *   image;         // memory mapped image of target
      int   size;               // size of target
      long   entry;            // entrypoint
      char    cpu[32];            // CPU type [./arch/lib*.so]
      char   format[32];         // file format [./formats/ *.sc]
      char  lang[32];         // high-level language
      char  assembler[32];    // assembler
      char   *header;            // string containing formatted file header
      char   name[64];         // name of target
      char   path[PATH_MAX];   // location of target
      char   dbname[PATH_MAX];   // path+name of .bdb for target
};


/* TODO : add some semblence or order to these: */
int env_set_pager(char *name);
int env_set_editor(char *name);
int env_set_debugger(char *name); 
char * GetDisasmHome();
int target_fd();
char * target_image();
int target_size();
char * env_get_pager();
char * env_get_editor();
char * env_get_debugger(); 
struct DISASM_ENV   * GetDisasmEnv();
struct DISASM_PREFS * GetDisasmPrefs();
struct DISASM_TGT   * GetDisasmTgt();
struct DISASM_ENG   * GetDisasmEng();
struct DISASM_ASM   * GetDisasmAsm();
struct DISASM_LANG  * GetDisasmLang();
int env_clear();
int env_clear_target();
int env_defaults();
int env_target_defaults();
int env_pref_defaults();
/*  env_get_flag: Test whether environment flag is true. Flags:
 *                     DB_LOADED TGT_MAPPED DB_MOD TGT MOD PASS_1 PASS_2
 *                     CODE_INT CODE_FIN PAGINATE COLOR_TTY QUIET ANNOY_USER
 *                     DISABLE_EXEC DEBUG_LIB
 *    Return Value:   1 (set) or 0 (not set)
 *     Arguments:      int flag -- one of the above flags  */
int env_get_flag( int flag );
/*  env_set_flag: Set an environment flag 
 *    Return Value:   Returns 0 always
 *     Arguments:      int flag -- flag to set */
int env_set_flag( int flag );
/*  env_clear_flag: Un-set an environment flag 
 *    Return Value:   Returns 0 always
 *     Arguments:      int flag -- flag to clear */
int env_clear_flag( int flag );
int env_get_option( int flag );
int env_set_option( int flag );
int env_clear_option( int flag );
/*  env_tty_asm: Set asmsprintf format string for CODE on a tty
 *     Arguments:   char *fmt -- new default format string */
void env_tty_asm( char *fmt );
/*  env_tty_data: asmsprintf format string for DATA on a tty 
 *     Arguments:   char *fmt -- new default format string */
void env_tty_data( char *fmt );
/*  env_file_asm: asmsprintf format string for CODE to a file
 *     Arguments:   char *fmt -- new default format string */
void env_file_asm( char *fmt );
/*  env_file_data: asmsprintf format string for DATA to a file
 *     Arguments:   char *fmt -- new default format string */
void env_file_data( char *fmt );
/*  env_lpr_asm: asmsprintf format string for CODE on a printer
 *     Arguments:   char *fmt -- new default format string */
void env_lpr_asm( char *fmt );
/*  env_lpr_data: asmsprintf format string for DATA on a printer
 *     Arguments:   char *fmt -- new default format string */
void env_lpr_data( char *fmt );

/* System Interaction -- api_system.c
   ======================================================================== */
/* sys_init : Starts the DB and the interpreter, calls sys_re_init();
void sys_init( char *home);
/* sys_re_init : Clears bastard internal structs and sets $HOME to home */
void sys_re_init(char *home);
/*  sys_msg : Print a message to STDOUT unless QUIET flags is set 
 *     Arguments:   char *str -- sys_msg to print    */
void sys_msg( const char *str ) ;
/*  sys_errmsg: Print Error Code & sys_msg w/newline, regardless of QUIET flag
 *     Arguments:   int num -- Error Code    char *str -- sys_msg to print    */
void sys_errmsg( int num, const char *str ) ;
/*  sys_quit: Exit the bastard */
void sys_quit( ) ;
/*  sys_exec : sys_execute the target via system() 
 *    Return Value:   exit status of process
 *     Arguments:      char *args -- arguments to append to command line */
int sys_exec( char *args );
/*  sys_debug: sys_execute target in gdb via system()
 *    Return Value:   exit status of process */
int sys_debug( );
/*  sys_core: sys_execute target with core_dumps enabled; allow user to coredump the
 *        target with a hotkey combination
 *    Return Value:   1 = success   0 = failure */
int sys_core( ); 
/*  sys_panic: Get a snapshot of the kernel as the target is running -- basically
 *         dump system state as you would in a kernel panic
 *    Return Value:   1 = success   0 = failure */
int sys_panic( ); 
/*  GetValidArchs: Dump a list of all supported processors to STDOUT 
 *    Return Value:   0 */
int GetValidArchs( );
/*  GetValidFormats: Dump a list of all supported file formtas to STDOUT 
 *    Return Value:   0 */
int GetValidFormats( );
/*  sys_set_lasterr:  Sets the 'last error' internal variable 
 *    Return Value:   Returns 0 always
 *     Arguments:      int errnum -- error code for last error */
int sys_set_lasterr( int errnum );
/*  sys_get_lasterr: Returns error code of last error
 *    Return Value:   Error Code or 0 if failure
 *     Arguments:      none */
int sys_get_lasterr( );
/*  sys_lasterr_str: Returns pointer to string representing the last error
 *    Return Value:      const char * -- pointer to string or NULL if failure
 *     Arguments:         none */
char* sys_lasterr_str( );
/*  sys_print_errmsg:  Print string for error code to STDOUT
 *     Arguments:     int errnum -- error code to print    */
void sys_print_errmsg(int errnum);
/*  sys_sprint_errmsg:  Fills buffer with string for error code
 *     Arguments:      char buf[80] -- buffer for string
 *                    int  errnum  -- error code to look up */
void sys_sprint_errmsg(char *buf, int errnum);

