[ create a new paste ] login | about

Link: http://codepad.org/HoWmAY49    [ raw code | fork ]

C, pasted on Aug 22:
/*
**-------------------------------------------------------------------
**
** A Mini Language:
**   C-like/Script type, compiled ( x86 ) 32 bits.
**
** FILE:
**   mini.c
**
** MAIN FUNCTION:
**   int Parse (ASM *a, char *text);
**
** RESERVED WORDS:
**   int, char *, struct *,
**   if, for, break.
**
** COMPILE:
**   gcc mini.c -o mini -Wall
**
** BUILD/VERSION:
**   0001 - 22/08/2015 - 18:50
**
** BY: Francisco G. A. - "gokernel" ( gokernel@hotmail.com )
**
**-------------------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifdef _WIN32
    #include <windows.h>
#endif
#ifdef __linux__
    #include <unistd.h>
    #include <sys/mman.h> // to: mprotect()
#endif

//-------------------------------------------------------------------
//########################  DEFINE/ENUM  ############################
//-------------------------------------------------------------------
//
#define ASM_DEFAULT_SIZE  50000
#define PROG_SIZE         50000
#define UCHAR             unsigned char

enum {
    TOK_INT = 255, TOK_CHAR, TOK_STRUCT, TOK_IF, TOK_FOR, TOK_BREAK,
    //----------------------------
    TOK_ID,         // identifier
    TOK_NUMBER,
    TOK_STRING,
    TOK_PLUS_PLUS,  // ++
    TOK_MINUS_MINUS // --
};

//-------------------------------------------------------------------
//###########################  STRUCT  ##############################
//-------------------------------------------------------------------
//
typedef struct ASM        ASM;
typedef struct ASM_label  ASM_label;
typedef struct ASM_jump   ASM_jump;

struct ASM {
    UCHAR     *p;         // to increment ...
    UCHAR     *code;      // code_len=: p - code
    ASM_label *label;
    ASM_jump  *jump;
    int       label_len;  // len of ( label ) array to realloc
    int       jump_len;   // len of ( jump  ) array to realloc
};
struct ASM_label {
    char  *text;
    int   pos;
};
struct ASM_jump {
    char  *text;
    int   pos;
    int   type;
};

//-------------------------------------------------------------------
//###########################  PROTOTYPE  ###########################
//-------------------------------------------------------------------
//
void expression (ASM *a);

//-------------------------------------------------------------------
//###########################  VARIABLE  ############################
//-------------------------------------------------------------------
//
static char
    *str,
    prog[PROG_SIZE], token[1024]
    ;

static int
    tok, erro, line
    ;

static int lex (void)
{
    switch (*str) {

    case 0: return 0;

    default:
        return *str++;
    }
    return 0;
}
static int stmt (ASM *a)
{
    tok = lex();

    switch (tok) {
    case TOK_INT: break;
    default:
        expression(a);
    }
    return tok;
}
void expression (ASM *a)
{
    // ...
}

//-------------------------------------------------------------------
//###########################  ASM API  #############################
//-------------------------------------------------------------------
//
ASM *asm_new (unsigned int size)
{
    ASM *a = (ASM*)malloc(sizeof(ASM));

    if (a && (a->code=(UCHAR*)malloc(size)) != NULL) {

        a->p = a->code;
        a->label = NULL;  // this use realloc
        a->jump  = NULL;  // this use realloc
        a->label_len = 0;
        a->jump_len  = 0;

        return a;
    }

    return NULL;
}
//-------------------------------------------------------------------
// This function use the code of Fabrice Bellard:
//
//   LIB:  tcc-0.9.25
//   FILE: libtcc.c
//   FUNC: void set_pages_executable (void *ptr, unsigned long length);
//   LINE: 400
//
// Set executable: a->code
//
//-------------------------------------------------------------------
void asm_set_executable (void *ptr, unsigned long len)
{
#ifdef _WIN32
    unsigned long old_protect;

    if (!VirtualProtect(ptr, len, PAGE_EXECUTE_READWRITE, &old_protect))
    {
        printf ("ERROR: asm_set_executable() ... NOT FOUND - VirtualProtect()\n");
        exit (-1);
    }
#endif

#ifdef __linux__
    unsigned long start, end, PageSize;

    PageSize = sysconf (_SC_PAGESIZE);
    start = (unsigned long)ptr & ~(PageSize - 1);
    end = (unsigned long)ptr + len;
    end = (end + PageSize - 1) & ~(PageSize - 1);
    if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
    {
        printf ("ERROR: asm_set_executable() ... NOT FOUND - mprotec()\n");
        exit (-1);
    }
#endif
}
void asm_begin (ASM *a) {
    a->p[0] = 0x55;                 //: 55      push  %ebp
    a->p[1] = 0x89; a->p[2] = 0xe5; //: 89 e5   mov   %esp,%ebp
    a->p += 3;
}
void asm_end (ASM *a) {
    a->p[0] = 0xc9;  // leave
    a->p[1] = 0xc3;  // ret
    a->p += 2;

//    if (a->jump_len)
//        asm_change_label (a);
}

int Parse (ASM *a, char *text)
{
    str = text;
    line = 1;
    erro = 0;

    asm_begin(a);
    while (!erro && stmt(a)) { }
    asm_end(a);

    if (erro) printf("<<<<<<<  ERRO  >>>>>>>\n");

    return erro;
}

int main (int argc, char *argv[])
{
    ASM *a;
    FILE *fp;

    if (argc >= 2 && (a=asm_new(ASM_DEFAULT_SIZE))!=NULL && (fp=fopen(argv[1], "rb"))!=NULL) {
        int c, i = 0;

        while ((c=getc(fp))!=EOF) prog[i++] = c; // store prog[];
        prog[i] = 0;
        fclose(fp);

        if ( !Parse(a,prog) ) {

            asm_set_executable (a->code, (int)(a->p - a->code)+5);

            ( (void(*)()) a->code ) (); // <<<<<<< execute here >>>>>>>

        }
        //--------------------------------
        //##########  Free ASM  ##########
        //--------------------------------
        if (a->label) {
            for(i=0;i<a->label_len;i++)
                if (a->label[i].text) free(a->label[i].text);

            free (a->label);
        }
        if (a->jump) {
            for(i=0;i<a->jump_len;i++)
                if (a->jump[i].text) free(a->jump[i].text);

            free(a->jump);
        }
        free(a->code);
        free(a);

        printf ("\nExiting With Sucess !!!\n");
    }
    else printf ("USAGE: mini <file.cs>\n");

    return 0;
}


Create a new paste based on this one


Comments: