Archives
Recent Entries
Search


Links
Powered by
Movable Type 2.64

2010年03月25日

OpenCOBOLを拡張

03 FILLER PIC X(12) VALUES 'HELLO WORLD!'
     CHARACTER TYPE KM-12P
みたいなのを文法的に通るようにしてみたり。
コレで色々な移植の手間がかなり減ったヽ(´ー`)ノ
CHARACTER TYPE KM-12 部分が拡張ですね。 見覚えがあって、なおかつ同様に困ってるトコには配ったり出来るかも。
Posted by minemaz at 16:41 | Comments (0) | TrackBack

2010年03月15日

自己書換コードとか

先々必要になるのがわかってるので、自己書換コードとか書いてみたりヽ(´ー`)ノ
あるサブルーチンを引数付きで呼び出すコードを関数へのポインタ1個だけで管理
OpenCOBOL中でサブルーチン呼び出してる箇所で色々とやるために必要だっ
たり、同様に他言語からCで書いたコード呼び出すときに色々便利なので。

#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

void enable_code(void *addr) {
    long pagesize = sysconf(_SC_PAGESIZE);
    char* p = (void*)(((int) addr ) & ~(pagesize-1));
    if(mprotect(p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC)) {
        fprintf(stderr, "mprotect(2) failed. errno = %d?n", errno);
        exit(1);
    }
}

void prt1(char *str) {
   printf("1:%s\n",str);
}

void prt2(char *str) {
   printf("2:%s\n",str);
}

void*
make_caller_with_void_ptr(void* prog, void *strp) {
    unsigned char opcodes[] = {
        0x55,              /* push   %ebp        */
        0x89,0xe5,         /* mov    %esp,%ebp   */
        0x53,              /* push   %ebx        */
        0x83,0xec,0x04,    /* sub    $0x4,%esp   */
        0xb8,0,0,0,0,      /* movl   $0x0,%eax   */
        0x89,0x04,0x24,    /* mov    %eax,(%esp) */
        0xb8,0,0,0,0,      /* movl   $0x0,%eax   */
        0xff,0xd0,         /* call   *%eax       */
        0x83,0xc4,0x04,    /* add    $0x4,%esp   */
        0x5b,              /* pop    %ebx        */
        0x5d,              /* pop    %ebp        */
        0xc3               /* ret                */
    };

    static const int offset_string = 8;
    static const int offset_callee = 16;

    void(*code)(void);
    code = malloc(sizeof(opcodes));
    memcpy(code, opcodes, sizeof(opcodes));
    memcpy(code+offset_string, &strp, sizeof(&strp));
    memcpy(code+offset_callee, &prog, sizeof(&prog));
    enable_code(code);
    return code;
}

int main(int argc, char* argv[]) {
   void(*code1)(void);
   void(*code2)(void);
   code1 = make_caller_with_void_ptr(prt1, "this is code1");
   code2 = make_caller_with_void_ptr(prt2, "this is code2");


    printf("code1:");
    code1();

    printf("code2:");
    code2();

    exit(0);
}
Posted by minemaz at 01:53 | Comments (2) | TrackBack