/* bastard api -- these should be called from the macro language and the prog */
#ifndef BASTARD_API_INCLUDE /* prevent redeclaration errors in scripts */
#define BASTARD_API_INCLUDE

#ifndef PATH_MAX
#include <dirent.h>
#endif

/* 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 code_effect * GetCodeEffectObject(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 func_effect * GetFuncEffectObject(int id);
struct f_inline * GetFInlineObject(int id);
struct structure * GetStructureObject(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 */
/* note: these should probably be in extension.h instead */
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 );
/* SetTargetFormat : 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 SetTargetFormat( char *file_format );
int ApplyTargetFormat( void );
/* SetTargetArch : 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 SetTargetArch( char *file_arch );
/* SetTargetAssembler : 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 SetTargetAssembler( 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 );
/* yeah, stupid place for this, it'll be moved somewhere else */
int LoadPlugin( char *name );
int RunPlugin( void *param );
int UnloadPlugin( );


/* 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 );
int SaveAsHLL( char *filename );
int SaveAsLST( 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
#define SECTION_TYPE_MASK 0xFF00
#define SECTION_PERM_MASK 0x000F
/*  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( );
int DisassembleTarget(char *disasm, void *param);
/*  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, int options );
/*  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   0x400
#define ADDR_INLINE      0x800
#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 /* name generator */
#define NAME_USER      0x02
#define NAME_SUB      0x10 /* name type */
#define NAME_SYMBOL   0x20
#define NAME_STRUCT   0x40
   /* 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
   ======================================================================== */
#define DT_SIGNED    0x01
#define DT_UNSIGNED  0x02
#define DT_POINTER   0x04
int DefineDataType(char *name, int size, int flags) ;
int DeleteDataType(char *name);
int GetDataType(char *name);
int DefineStruct( char *name, short size );
int DefineStructMember( int struct_id, long type, int size, int order, char *name );
int GetStruct( unsigned long id, struct structure *s);
unsigned long GetStructID(char *name);
int GetStructMember( int struct_id, int order, struct struct_member *m) ;
int ApplyStructure(long rva, unsigned long id);
int DelStruct( unsigned long id);
int DelStructMember( unsigned long id);

/*  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_UNK       0x000      /* unknown operand */     
#define OP_REG       0x100      /* register */
#define OP_IMM       0x200      /* immediate value */
#define OP_REL       0x300      /* relative Address [offset from IP] */
#define OP_ADDR      0x400      /* Absolute Address */
#define OP_EXPR      0x500      /* Address Expression [e.g. SIB byte] */
#define OP_PTR       0x600      /* Operand is an Address containing a Pointer */
#define OP_OFF       0x700      /* Operand is an offset from a seg/selector */
/*                   Modifiers: */
#define OP_SIGNED    0x001000   /* operand is signed */
#define OP_STRING    0x002000   /* operand a string */
#define OP_CONST     0x004000   /* operand is a constant */
#define OP_EXTRASEG  0x010000   /* seg overrides */
#define OP_CODESEG   0x020000
#define OP_STACKSEG  0x030000
#define OP_DATASEG   0x040000
#define OP_DATA1SEG  0x050000
#define OP_DATA2SEG  0x060000
/*                   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_SEG_MASK  0x00F0000  /* segs are NOT mutually 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 */
   /* instruction modifiers */
#define INS_REPZ     0x0100000
#define INS_REPNZ    0x0200000  
#define INS_LOCK     0x0400000 /* lock bus */
#define INS_DELAY    0x0800000 /* branch delay slot */
/*  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 ) ;
/* compare 2 operands */
int opcmp(long op1, int flag1, long op2, int flag2);

int DefineCodeEffect(long rva, int reg, int change);

/*   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
   ======================================================================== */
#define IMPORT_UNKNOWN  0x00
#define IMPORT_FUNCTION 0x01
#define IMPORT_DATA     0x02
/*  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, int flags );
/*  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 BC_CODE   0x01
#define BC_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 IN_EIC          0x00020000  /* 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    output;   /* defualt output type */
      int    flags;
      int    endian;    /* big or little endian? 1= little */
};

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;
      int num_hist;           /* number of cmd history to remember */
};

#define DISASM_TGT_LOADED        0x01
#define DISASM_TGT_FORMAT_SET    0x02
#define DISASM_TGT_ARCH_SET      0x03
#define DISASM_TGT_ASM_SET       0x04
#define DISASM_TGT_LANG_SET      0x05
#define DISASM_TGT_PREDISASM     0x06
#define DISASM_TGT_DISASM        0x07
#define DISASM_TGT_POSTDISASM    0x08
#define DISASM_TGT_INTCODE       0x09
#define DISASM_TGT_FINCODE       0x0A
struct DISASM_TGT {   /* target information */
      int status;              // how far the disassembly got 
      int endian;             // 0 = big, 1 = little
      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    arch[32];            // CPU type [./arch/lib*.so]
      char  assembler[32];    // assembler
      char   format[32];         // file format [./formats/ *.sc]
      char  lang[32];         // high-level language
      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: */
char * GetBastardHome();
/* These are the best way to set things : */
int SetBastardSetting(char *group, char *name, char *val);
int SetBastardOption(char *option);
int GetBastardOption(char *option);
/* Other 'Set' cmds may be removed in the future */
int SetPager(char *name);
int SetEditor(char *name);
int SetDebugger(char *name); 
int GetTargetFD();
char * GetTargetImage();
int GetTargetSize();
char * GetPager();
char * GetEditor();
char * GetDebugger(); 
struct DISASM_ENV   * GetBastardEnv();
struct DISASM_PREFS * GetBastardPrefs();
struct DISASM_TGT   * GetBastardTgt();
struct DISASM_ENG   * GetBastardEng();
struct DISASM_ASM   * GetBastardAsm();
struct DISASM_LANG  * GetBastardLang();
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( );
/*  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);

#endif /* prevent redeclaration errors in scripts */
