================================================================================
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 GetLastError();
 *   
 * + 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 = DBSaveState();
 *                 ...
 *                DBRestoreState(state);
 *             and you should be alright. */
void* DBSaveState();
int DBRestoreState(void *state);
/* ---- Low-level DB access ---- */
/*   These expect *dest to be pre-allocated */
int DBIndexFirst(int index, void *dest);
int DBIndexNext(int index, void *dest);
int DBIndexPrev(int index, void *dest);
int DBIndexLast(int index, void *dest);
int DBIndexFind(int index, void *value, void *dest);
int DBTableFirst(int table, void *dest);
int DBTableNext(int table, void *dest);
int DBTablePrev(int table, void *dest);
int DBTableLast(int table, void *dest);
int DBRecordInsert(int table, void *src);
int DBRecordUpdate(int index, void *value, void *src);
int DBRecordDelete(int index, void *value);
int DBFindClosestPrev(int index, void *value, void *dest);
int DBFindClosestNext(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 * GetStructureTypeObject(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 DisPrologue(struct code **c);
int DisEpilogue(struct code **c);
int DisByteOrder();
int DisAddrSize();
int DisByteSize();
int DisWordSize();
int DisDwordSize();
int DisGetSP();
int DisGetIP();



/* Loading -- api_loadsave.c
   ======================================================================== */
/*  LoadTarget : Open target file for disassenbly
 *    Return Value:   1 -- Success       0 -- Failure
 *     Arguments:      char *target -- full name/path of file to open */
int LoadTarget( char *target );
/* LoadBDB : Open previously disassembled file 
 *    Return Value:   1 -- Success       0 -- Failure
 *    Arguments:      char *dbname -- full name/path of .bdb file */
int LoadBDB( 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 );
/* SetTargetLanguage : 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 SetTargetLanguage( char *language );

/* Saving -- api_loadsave.c 
   ======================================================================== */
/* SaveDB : Save current DB as .bdb file
 *    Notes : Uses ./$target.bdb for filename */
void SaveDB( );
/* SaveDBBak : Save current DB to a unique 'temp' filename
 *    Notes: Uses ./$target.$timestamp.bdb as filename */
void SaveDBBak( );
/* CloseDB : Close the current DB and target [i.e. before loading a new one] */
void CloseDB( );
/* SaveDBAs : Save DB as the specified filename
 *    Arguments:      char *filename -- name of file to save DB as */
void SaveDBAs( char *filename );
/* SaveAsASM : 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 SaveAsLST and make new routine for 
 *                GAS and NASM asm files */
int SaveAsASM( char *filename );
/* SaveAsDump : Save a  hex dump of the target
 *    Return Value :   1 -- Success       0 -- Failure
 *    Arguments :      char *filename -- name of file to save dump as  */
int SaveAsDump( char *filename );
/* SaveAsDiff : 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 SaveAsDiff( char *filename );
/* SaveAsBinary : 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 SaveAsBinary( 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
/*  CreateSection :  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 CreateSection( char *name, long start, int size, long pa, int type );
/*  DeleteSection : Delete a program section [be careful!]
 *    Return Value:   1 = success, 0 = error
 *     Arguments:      char *name -- name of section to delete  */
int DeleteSection( char *name );
/*  GetSection : 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 GetSection( long rva, struct section *s);
/*  GetSectionStart : 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 GetSectionStart( char *name );
/*  GetSectionEnd : 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 GetSectionEnd( char *name );
/*  GetSectionName : 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  GetSectionName( long rva, char* buf );
/*  GetSectionFlags : Get section type/permissions 
 *    Return Value:   Type and permissions OR'ed together
 *     Arguments:      char *name -- name of section to get the flags of */
int  GetSectionFlags( char *name );
/*  SetSectionStart :  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  SetSectionStart( char *name, long start );
/*  SetSectionEnd : 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  SetSectionEnd( char *name, long end );
/*  SetSectionName : 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  SetSectionName( char *name, char *new_name );
/*  SetSectionFlags : 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  SetSectionFlags( char *name, int flags );

/* Disassembly -- api_disasm.c
   ======================================================================== */
#define BIG_ENDIAN_ORD       0
#define LITTLE_ENDIAN_ORD    1
/*  CreateHeader : Create ASCII representation of the file/program header
 *    Return Value:   1 id success , 0 if failure
 *     Arguments:      char *header = ASCII representation of header    */
int CreateHeader( char *header );
/*  PrintHeader : Print ASCII representation of header to stdout
 *    Return Value: none   
 *     Arguments:     none [uses header in target.header]    */
void PrintHeader( );
/*  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 InitDisassembler( char *disasm );
/*  DisassembleFull : Perform a full-featured deluxe-o-rama disassembly:
 *                     1. DisassembleForward() from each known function
 *                     2. DisassembleForward() 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 DisassembleSection() 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( );
/*  DisassembleSection : Perform a linear disassembly of a section. This does
 *                       no flow-of execution; rather it calls DisassembleRange
 *                       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 DisassembleSection( char *name );
/*  DisassembleRange :   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 DisassembleRange( long rva, int size );
/*  DisassembleForward : 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
 *                       DisAddr(), the backend to all of these api routines].
 *    Return Value:   
 *     Arguments:       */
int DisassembleForward( long rva );
/*  DisassemblePass :    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 DisassemblePass( int pass );
/*  DisassembleAllPasses : Performs all passes on the target 
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      none */
int DisassembleAllPasses();

/* 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 */
/*  IsValidAddr :  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 GetSection(), but makes code more clear.
 *    Return Value:   1 if valid, 0 if invalid
 *     Arguments:      long rva -- address to be checked */
int IsValidAddr( long rva );
/*  IsValidCodeAddr : 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 IsValidCodeAddr( long rva );
/*  AddrExists : 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 AddrExists( long rva );
/*  FindClosestAddr : 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 FindClosestAddr( long rva );
/*  DefineAddr :      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 DefineAddr( long rva, int size, long pa, int flags );
/*  UndefineAddr :  Remove ADDRESS object for given address
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      long rva -- address to delete */
int UndefineAddr( 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 PrintAddress( long rva );
/*  MakeCode : 
 *    Return Value:   
 *     Arguments:       */
int MakeCode( long addr );
/*  MakeData : 
 *    Return Value:   
 *     Arguments:       */
int MakeData( long addr );
/*  GetPA : 
 *    Return Value:   
 *     Arguments:       */
long GetPA( long rva );
/*  GetRVA : 
 *    Return Value:   
 *     Arguments:       */
long GetRVA( long pa );
/*  GetAddrType : 
 *    Return Value:   
 *     Arguments:       */
int GetAddrType( long rva );
/*  GetAddrSize : 
 *    Return Value:   
 *     Arguments:       */
int GetAddrSize( long rva );
/*  GetFlags : 
 *    Return Value:   
 *     Arguments:       */
int GetFlags( long addr );
/*  GetAddrBytes : 
 *    Return Value:   
 *     Arguments:       */
int GetAddrBytes( long rva, char *buf );
/*  GetNextAddr : 
 *    Return Value:   
 *     Arguments:       */
long GetNextAddr( long rva );
/*  GetPrevAddr : 
 *    Return Value:   
 *     Arguments:       */
long GetPrevAddr( long rva );
/*  SetFlags : 
 *    Return Value:   
 *     Arguments:       */
int SetFlags( long rva, int flags );
 /*
  MakeData( addr, size );
    Note that MakeData provides a size attr -- it is up to the front-end to
   display this as a byte, word, dword, or array
 GetName( 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
/*  SetName : 
 *    Return Value:   
 *     Arguments:       */
int SetName( long rva, char* name, int type );
/*  GetName : 
 *    Return Value:   
 *     Arguments:       */
int GetName( long rva, char* buffer );
/*  GetNameType: 
 *    Return Value:   
 *     Arguments:       */
int GetNameType(long addr);
/*  GetAddrByName: 
 *    Return Value:   
 *     Arguments:       */
long GetAddrByName( char *name );
/*  DefineAddrComment : 
 *    Return Value:   
 *     Arguments:       */
int DefineAddrComment( long rva, char *buf );
/*  GetAddrComment : 
 *    Return Value:   
 *     Arguments:       */
int GetAddrComment( long rva );
/*  SetAddrComment : 
 *    Return Value:   
 *     Arguments:       */
int SetAddrComment( long rva, int id );
/*  GetComment: 
 *    Return Value:   
 *     Arguments:       */
int GetComment( int id, char *buf );
/*  DefineComment: 
 *    Return Value:   
 *     Arguments:       */
int DefineComment( char *buf, int type );
/*  SetComment: 
 *    Return Value:   
 *     Arguments:       */
int SetComment( int id, char *buf );
/*  DelComment: 
 *    Return Value:   
 *     Arguments:       */
int DelComment( int id ) ;



/* Structures & Constants -- api_structconst.c
   ======================================================================== */
/*  GetAddrConstant : 
 *    Return Value:   
 *     Arguments:       */
int GetAddrConstant( long rva );
/*  GetAddrStruct : 
 *    Return Value:   
 *     Arguments:       */
int GetAddrStruct( long rva );
/*  SetAddrConstant : 
 *    Return Value:   
 *     Arguments:       */
int SetAddrConstant( long rva, int id );
/*  SetAddrStruct : 
 *    Return Value:   
 *     Arguments:       */
int SetAddrStruct( long rva, int id );
// *buf is buf[32]
/*  DefineConstant: 
 *    Return Value:   
 *     Arguments:       */
int DefineConstant( char *name, int value);
/*  GetConstant: 
 *    Return Value:   
 *     Arguments:       */
int GetConstant(int value, char buf[32]);
/*  GetConstantNext: 
 *    Return Value:   
 *     Arguments:       */
int GetConstantNext( char buf[32]);
/*  GetConstantName: 
 *    Return Value:   
 *     Arguments:       */
int GetConstantName( unsigned long id, char buf[32]);
/*  GetConstantID: 
 *    Return Value:   
 *     Arguments:       */
unsigned long GetConstantID( char *name);
/*  DelConstant: 
 *    Return Value:   
 *     Arguments:       */
int DelConstant( unsigned long id);
   /*CreateStructure( char*, name);
      Prob isn't necessary -- can be provided by the UI
   ApplyStructure( 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 */
/*  DefineCode: 
 *    Return Value:   
 *     Arguments:       */
int DefineCode(long rva, struct code *c);
/*  UndefineCode: 
 *    Return Value:   
 *     Arguments:       */
int UndefineCode(long rva);
/*  GetNextCode: 
 *    Return Value:   
 *     Arguments:       */
long GetNextCode( long rva );
/*  GetNextData: 
 *    Return Value:   
 *     Arguments:       */
long GetNextData( long rva );
/*  GetCodeRep: 
 *    Return Value:   
 *     Arguments:       */
int GetCodeRep( 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 );
   /* 
   GetCodeRep( addr );
      Returns a basic [INTEL fmt] representation of the line of code
   GetFlags( 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 DefineAddrExp(int scale, int index, int base, int disp, int flags);
int GetAddrExpr( int id, struct addr_exp *exp );
int GetAddrExprString( int id, char *string, int len);

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


/* Imports -- api_importexport.c
   ======================================================================== */
/*  DefineImport: 
 *    Return Value:   
 *     Arguments:       */
int DefineImport( long rva, char *lib, char* name, int type );
/*  GetImportName: 
 *    Return Value:   
 *     Arguments:       */
int GetImportName( long rva, char *buf );
/*  GetImportLib: 
 *    Return Value:   
 *     Arguments:       */
int GetImportLib( long rva, char *buf );
/*  GetImportType: 
 *    Return Value:   
 *     Arguments:       */
int GetImportType( long rva );
/*  DumpImports: 
 *    Return Value:   
 *     Arguments:       */
int DumpImports( );
/*  DefineLibrary: 
 *    Return Value:   
 *     Arguments:       */
int DefineLibrary( char *name, int v_hi, int v_lo );
/*  DumpLibs: 
 *    Return Value:   
 *     Arguments:       */
int DumpLibs( );   /* print all libraries to stdout */


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


/* XRefs -- api_xref.c
   ======================================================================== */
    /* Xref Types */
#define XREF_READ      0x01
#define XREF_WRITE   0x02
#define XREF_EXEC      0x04
/*  GetRefTo: 
 *    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 GetRefTo( long rva, int type ) ;       //get first
/*  GetNextRefTo: 
 *    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 GetNextRefTo( int type ) ; //get array of structs; return num
/*  GetRefFrom: 
 *    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 GetRefFrom( long rva, int type ) ;
/*  GetNextRefFrom: 
 *    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 GetNextRefFrom( int type ) ;
/*  DefineRef: 
 *    Return Value: 1 on success, 0 on error 
 *     Arguments:       */
int DefineRef( long from, long to, int type );


/* Functions -- api_functions.c
   ======================================================================== */
/*  DefineFunc: 
 *    Return Value:   
 *     Arguments:       */
int DefineFunc( long rva, char * name, int size );
/*  GetFuncName: 
 *    Return Value:   
 *     Arguments:       */
int GetFuncName( long rva, char *buf );
/*  GetFuncStart: 
 *    Return Value:   
 *     Arguments:       */
int GetFuncStart( long rva );
/*  GetFuncEnd: 
 *    Return Value:   
 *     Arguments:       */
int GetFuncEnd( long rva );
/*  GetFuncByName: 
 *    Return Value:   
 *     Arguments:       */
int GetFuncByName( char *name );
/*  SetFuncName: 
 *    Return Value:   
 *     Arguments:       */
int SetFuncName( long rva, char *name );
/*  SetFuncSize: 
 *    Return Value:   
 *     Arguments:       */
int SetFuncSize( 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
/*  RunScript: Run a script contained in a file 
 *    Return Value:   Exit status of script
 *     Arguments:      char *name -- name of file to compile and execute */
int RunScript( char *name );
/*  RunScriptText: Compile and run the provided code
 *    Return Value:   Exit status of script
 *     Arguments:      char *script -- code to compile and execute */
int RunScriptText( char *script );
/*  RunCompiledScript: Run a precompiled script
 *    Return Value:     Exit status of script
 *     Arguments:        char *name -- name of file to load and run */
int RunCompiledScript(char *name);
/*  CompileScript: Compile a script file
 *    Return Value:   1 if success, 0 if failure
 *     Arguments:      char *name -- name of file to compile */
int CompileScript(char *name);
/*  DefineMacro: 
 *    Return Value:   
 *     Arguments:       */
int DefineMacro( char *name, char *macro );
/*  UndefineMacro: 
 *    Return Value:   
 *     Arguments:       */
int UndefineMacro( char *name );
/*  RunMacro: 
 *    Return Value:   
 *     Arguments:       */
int RunMacro( char *name );
/*  RecordMacro: 
 *    Return Value:   
 *     Arguments:       */
int RecordMacro( 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 FreeSearchHandle to dealloc the memory
 * used for *search. */

/*  FindBytes: 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 FindBytes( unsigned char *bytes, int len, int **search);
/*  FindOperand:     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 FindOperand( char *str, int **search);
/*  FindMnemonic:    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 FindMnemonic( char *str, int **search);
/*  FindConstant:    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 FindConstant( long value, int **search);
/*  FreeSearchHandle: 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 FreeSearchHandle( 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 FindNextOpRead( char *operand, long rva, int ttl );
long FindPrevOpRead( char *operand, long rva, int ttl );
long FindNextOpWrite( char *operand, long rva, int ttl );
long FindPrevOpWrite( char *operand, long rva, int ttl );
long FindNextOpExec( char *operand, long rva, int ttl );
long FindPrevOpExec( 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 SetPager(char *name);
int SetEditor(char *name);
int SetDebugger(char *name); 
char * GetDisasmHome();
int GetTargetFD();
char * GetTargetImage();
int GetTargetSize();
char * GetPager();
char * GetEditor();
char * GetDebugger(); 
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 ClearEnv();
int ClearTarget();
int SetEnvDefaults();
int SetTargetDefaults();
int SetPrefDefaults();
/*  GetEnvFlag: 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 GetEnvFlag( int flag );
/*  SetEnvFlag: Set an environment flag 
 *    Return Value:   Returns 0 always
 *     Arguments:      int flag -- flag to set */
int SetEnvFlag( int flag );
/*  ClearEnvFlag: Un-set an environment flag 
 *    Return Value:   Returns 0 always
 *     Arguments:      int flag -- flag to clear */
int ClearEnvFlag( int flag );
int GetOption( int flag );
int SetOption( int flag );
int ClearOption( int flag );
/*  SetTtyAsmFmt: Set asmsprintf format string for CODE on a tty
 *     Arguments:   char *fmt -- new default format string */
void SetTtyAsmFmt( char *fmt );
/*  SetTtyDataFmt: asmsprintf format string for DATA on a tty 
 *     Arguments:   char *fmt -- new default format string */
void SetTtyDataFmt( char *fmt );
/*  SetFileAsmFmt: asmsprintf format string for CODE to a file
 *     Arguments:   char *fmt -- new default format string */
void SetFileAsmFmt( char *fmt );
/*  SetFileDataFmt: asmsprintf format string for DATA to a file
 *     Arguments:   char *fmt -- new default format string */
void SetFileDataFmt( char *fmt );
/*  SetLprAsmFmt: asmsprintf format string for CODE on a printer
 *     Arguments:   char *fmt -- new default format string */
void SetLprAsmFmt( char *fmt );
/*  SetLprDataFmt: asmsprintf format string for DATA on a printer
 *     Arguments:   char *fmt -- new default format string */
void SetLprDataFmt( char *fmt );

/* System Interaction -- api_system.c
   ======================================================================== */
/* Init : Starts the DB and the interpreter, calls ReInit();
void Init( char *home);
/* ReInit : Clears bastard internal structs and sets $HOME to home */
void ReInit(char *home);
/*  Message : Print a message to STDOUT unless QUIET flags is set 
 *     Arguments:   char *str -- Message to print    */
void Message( const char *str ) ;
/*  ErrorMsg: Print Error Code & Message w/newline, regardless of QUIET flag
 *     Arguments:   int num -- Error Code    char *str -- Message to print    */
void ErrorMsg( int num, const char *str ) ;
/*  Quit: Exit the bastard */
void Quit( ) ;
/*  Exec : Execute the target via system() 
 *    Return Value:   exit status of process
 *     Arguments:      char *args -- arguments to append to command line */
int Exec( char *args );
/*  Debug: Execute target in gdb via system()
 *    Return Value:   exit status of process */
int Debug( );
/*  Core: Execute target with core_dumps enabled; allow user to coredump the
 *        target with a hotkey combination
 *    Return Value:   1 = success   0 = failure */
int Core( ); 
/*  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 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( );
/*  SetLastError:  Sets the 'last error' internal variable 
 *    Return Value:   Returns 0 always
 *     Arguments:      int errnum -- error code for last error */
int SetLastError( int errnum );
/*  GetLastError: Returns error code of last error
 *    Return Value:   Error Code or 0 if failure
 *     Arguments:      none */
int GetLastError( );
/*  GetLastErrorString: Returns pointer to string representing the last error
 *    Return Value:      const char * -- pointer to string or NULL if failure
 *     Arguments:         none */
char* GetLastErrorString( );
/*  PrintErrorMsg:  Print string for error code to STDOUT
 *     Arguments:     int errnum -- error code to print    */
void PrintErrorMsg(int errnum);
/*  SprintErrorMsg:  Fills buffer with string for error code
 *     Arguments:      char buf[80] -- buffer for string
 *                    int  errnum  -- error code to look up */
void SprintErrorMsg(char *buf, int errnum);

