【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

2012-06-01から1ヶ月間の記事一覧

Genieのサンプルコード

Genieは絶望的にサンプルコードがありません。仕方ないので、手始めにチュートリアルからコードを抜粋しました。せめてValaからトランスレートできれば良いのですが、逆(Genie→Vala)しかできないようです。 Is there any way to compile between Vala and …

MSYSでValaをビルド

MSYSでValaという言語をビルドしてみました。C言語へのトランスレータで、C#風の構文からGObjectの定型的なコードを出力します。 Vala - Compiler for the GObject type system 先にglibとpkg-configをビルドします。詳細は以下を参照してください。 MSYSでG…

MinGWでwaitpid()とkill()

MinGWでUNIXのプログラムをビルドしていると、waitpid()やkill()でよく引っ掛かります。とりあえずコンパイルを通すため、代わりの関数を実装してみました。※ サポートできない引数は無視しています。 #include <windows.h> #include <process.h> int waitpid(pid_t pid, int *stat</process.h></windows.h>…

classファイルの注釈付きバイナリダンプ

前回の記事で解析したclassファイルのバイナリダンプに注釈を付けました。

classファイルの解析

Javaでハローワールドをコンパイルしてclassファイルを解析してみました。※ 仕様書を参照したため、リバースエンジニアリングではありません。 Hello.java class Hello { public static void main(String[] args) { System.out.println("hello"); } } 実行結…

void *とintptr_t

今まで何度かvoid *の説明を求められましたが、なかなか納得してもらえませんでした。説明を工夫するだけでは限界があると感じたので、別の方法でどうにかならないかを考えてみました。前回の記事の延長線上で説明します。サンプルコードを再掲します。 mov …

メモリ書き込み構文

対象環境を限定できる場合、バイト配列にリトルエンディアンで32bit値を書き込むときに、私は以下のように書いていました。 char buf[32]; *(int *)&buf[6] = 0x12345678; 非常に分かりにくいとご指摘を受けて色々と変形しましたが、どれもしっくり来ません…

odcctoolsの修正 (3)

Mac OS XのasはIntel記法で同じラベルが2度出るとエラーになります。 $ cat intel.s .intel_syntax noprefix call foo call foo $ i386-darwin-as intel.s intel.s:3:suffix or operands invalid for `call'この問題を修正するパッチを作成しました。 --- od…

odcctoolsの修正 (2)

前回、ようやくodcctoolsのアセンブラが動くようになりましたが、odcctoolsに手を出すようになった経緯を書きます。 Mach-O遊びを調査中。Mac OS Xではbinutilsではなくcctoolsを使う。cctoolsは他のOSで使うことは考慮されていないので、クロスでやるときは…

odcctoolsの修正 (1)

前回まででNetBSDとMSYSでodcctoolsをビルドしました。どちらも同じ問題でi386用のアセンブラが起動しませんでした。 http://7shi.hateblo.jp/entry/2012/06/13/005958 (NetBSD) http://7shi.hateblo.jp/entry/2012/06/13/013702 (MSYS) 問題を修正するパッ…

MSYSでodcctools(一部)

前回、NetBSDでodcctoolsをビルドしました。 http://7shi.hateblo.jp/entry/2012/06/13/005958 そこで問題になったのはi386のアセンブラです。問題の切り分けのため、MSYSでもビルドを試みました。ただしすべてのビルドを通すのはかなり大変なので、i386のア…

NetBSDでodcctools

Mac OS Xではバイナリ処理にGNU binutilsではなくcctoolsという独自のものを用いています(asはbinutils派生)。Appleはソースを以下で公開しています。 http://www.opensource.apple.com/ (Developer Tools) Appleが公開しているものはMac OS Xでビルドする…

文字列配列を作る (1)

数回に分けて文字列配列を作ってみます。手始めに検証用サブルーチンをJITで作ってみます。 strarray.c #include <stdio.h> #include <string.h> #include <windows.h> // for (i = 0; i < argc; i++) { // printf(argv[i]); // putchar(' '); // } char buf[] = { 0x56, // push esi 0x8b,</windows.h></string.h></stdio.h>…

C#でJITからコールバック

C#でJITからコールバックさせてみました。PythonのコードをC#に移植したものです。 using System; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr lpA…

C#でJIT

PythonでやったJITをC#に移植しました。32bit専用です。 using System; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr lpAddress, int dwSize, int f…

void*とオフセット

C++

第6回 コンパイラ実装会で出た話題です。以下のコードがエラーになります。なぜ? test.cpp #include <stdlib.h> int main(void) { void *p = malloc(100); *(void **)&p[10] = reinterpret_cast<void *>(free); return 0; } コンパイル結果 $ g++ test.cpp test.cpp: In funct</void></stdlib.h>…

関数のサイズ

第6回 コンパイラ実装会で出た話題です。関数のサイズを取ろうとしたら1になりました。なぜ? test.c #include <stdio.h> int main(void) { printf("%d\n", sizeof(putchar)); return 0; } 実行結果 $ gcc test.c $ ./a.exe 1int aへのポインタが&aであるように、putc</stdio.h>…

jeとjz

x86

第6回 コンパイラ実装会で出た話題です。jzをアセンブルして逆アセンブルしたらjeになると指摘されました。なぜ変わるのか?jeとjzは別名(エイリアス)でまったく同じため、どちらを使っても同じマシン語が出力されます。理由としては、cmp命令による比較は…

第7回 コンパイラ実装会

みんなでコンパイラの実装に挑戦する勉強会です。バイナリいじりの基礎から始めて、実行ファイルを自前のコンパイラで作って動かすことを目標にします。コンパイラをきっかけにして、各種マシンコードやOSのメモリ管理について理解を深めるのが狙いです。 20…

Brainf*ckの分岐をJIT

x86の分岐命令は相対アドレス指定のため、分岐元と分岐先のアドレスが決まらなければ相対アドレスを求められません。Brainf*ckではループの先頭と末尾で分岐が出てきます。相互に分岐しているので少し複雑です。 ループの先頭 loop_begin: cmp byte ptr[esi]…

PythonによるJITで関数呼び出し

前回、Pythonでポインタアクセスする方法が分かりました。 Pythonでポインタ経由のメモリアクセス これを使ってC言語で書いたJITをPythonに移植してみます。コードの詳細は以下を参照してください。 JITで関数呼び出し 共通部 (jit.py) import sys, struct f…

Pythonでポインタ経由のメモリアクセス

Pythonでmalloc()したメモリへのアクセスを試しました。戻り値を POINTER(c_ubyte) へキャストするとアクセスできます。※ 例は32bit Windows限定のコードです。UNIX系ではlibcのロード方法が少し違います。 from ctypes import * malloc = cdll.msvcrt.mallo…