2009年04月21日

[Debug Hacks] #66.手元のx86マシンが64bitモード対応かどうかを調べる

本日オライリージャパン様より「Debug Hacks――デバッグを極めるテクニック&ツール」の献本をいただきました。著者の皆様、出版社の皆様ありがとうございます。

とりあえず、ざっくりと気になる章だけをかいつまんで読んでみたのですが、最後の章「#66.手元のx86マシンが64bitモード対応かどうかを調べる」では、/proc/cpuinfo で lm の文字列を探す方法と、以下のような CPUID 命令を発行して今自分が使っているマシンのCPUが64bitに対応しているかどうかを調べるハックが紹介されていました。

#include <stdio.h>

void cpuid(int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
  __asm__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "0" (op));
}


int main() {
  unsigned int eax, ebx, ecx, edx;
  cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
  if (eax < 0x80000001) return 0;
  cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
  if (!((1<<29) & edx)) return 0;
  printf("64bit Long mode is supported.\n");
  return 1;
}

ただし、このハックの問題点は、CPUが64bitをサポートしているかどうかだけをチェックしていて、実際に64bitロングモードか32bitのx86互換モードで動いているかどうかを検出できないことにあります。

そこで、現在のCPUが64bitロングモードで動作しているかどうかをチェックする簡単なPerlスクリプトを書いてみました。

#!/usr/bin/perl

use DynaLoader;

sub x86_sub {
	my ($func, $x86) = @_;
	if ($^O eq "linux") {
		require 'syscall.ph';
		syscall(&SYS_mprotect,(unpack"L",pack"P",$x86)&~4095,4096*2,7);
	}
	DynaLoader::dl_install_xsub(caller(0)."::$func",unpack"L",pack"P",$x86);
}

x86_sub check64bit => do {
	our $LM64bit = "?";

	"\xb8\x31\x00\x00\x00".    # mov eax, 0x31

	"\x48".                    # dec eax // 64bit REX PREFIX
	"\xa2".pack("P",$LM64bit). # mov [$LM64bit], al
	"\xc3";                    # ret

};

&check64bit();

warn $LM64bit; # "0" => 32bit, "1" => 64bit

これは、DynaLoader::dl_install_xsubでx86の機械語を直接実行させるサブルーチンを定義して、64bitロングモード特有のREX PREFIXを解釈するかどうかで判別している方法になります。32bitのx86互換モードでは dec eax が実行され $LM64bit='0' となりますが、64bitロングモードではこのような1byte decは解釈されず、直後のmov命令のREX PREFIXを指定することになるので、$LM64bit='1' となります。

したがって、x86_64対応の「Intel(R) Xeon(R) CPU E5430 @ 2.66GHz」が搭載されているマシンでもCentOS 5.2(i386)のような64bitに対応していないOSで動かしてしまっている場合は、32bitと判定されます。

本Hackはデバッグには関係ありませんが、普段スクリプト言語を書いておられる方にも興味を持っていただければ幸いです。

2009年03月27日

4/22(水)Shibuya.pm#11開催します

Shibuya.pmテクニカルトーク#11を2009年4月22日(水)に開催します。

とりあえず、仮のプログラムですが、告知&申し込みフォームを公開しました。

  • テーマ - "no Perl; use x86;"
  • 日時 - 2009年4月22日(水) 18:30-21:00 (18:00 開場)
  • 会場 - グラントウキョウサウスタワー23F リクルート本社サウスホール
  • 住所 - 東京都千代田区丸の内1-9-2 (JR東京駅 八重洲南口すぐ)
  • 料金 - 無料
  • 事前登録 - 申し込みフォームより受付開始しています(定員200名)
    http://shibuya.pm.org/blosxom/techtalks/200904.html

会場はリクルートMTLの川崎さんにお世話になりまして、机付きの200人規模の大きな会場を使わさせていただくことになりました。ありがとうございます。

ちなみに今回のプログラムは XS Nite のときよりも低レベルになる予定です。正規表現やPerlに詳しくない方でも安心して聞ける内容になると思います。現在お使いのプログラミング言語を問わず、ふるってご参加ください。

2009年03月24日

Pure Perl で Acme::x86::CPUID を作りました

Perlでアセンブリプログラミングしているとき、実行マシンのCPUを判別してプログラムの処理を分岐したいときがでてくると思います。

そういうときに困ってしまわないように Acme::x86::CPUID を作ってみました。

package Acme::x86::CPUID;

use DynaLoader;

sub ProcessorBrandString {
	my $cpu = "\0" x 48;
	my $x86 = ""
	. "S\xbf" . pack("P", $cpu)
	. "\xb8\x02\x00\x00\x80"
	. ("P\x0f\xa2\x89\x07\x89_\x04\x89O\x08\x89W\x0c\x8d\x7f\x10X\x8d\@\x01" x 3)
	. "[\xc3"
	;
	DynaLoader::dl_install_xsub("X",unpack"L",pack"P",$x86);&X;
	$cpu =~ s/\0+//g;
	$cpu =~ s/^ +//;
	$cpu;
}

### print Acme::x86::CPUID::ProcessorBrandString, "\n";

1;

DynaLoaderはPerlコアに標準でバンドルされているとっても便利なモジュールです。

※ Acme::x86::CPUID は 100% Pure Perl で書かれているため、別途CコンパイラやXSモジュールなどをインストールする必要がありません。

■ 実行結果

以下、手元にある複数の環境で Acme::x86::CPUID::ProcessorBrandString の値を調べてみました。

※ Linux/Windows/FreeBSDのx86環境でそれぞれ動作確認しましたが、それ以外の環境ではシステムがクラッシュする可能性がありますので実行はお勧めしません。

1. WindowsXP(32bit) - ブログを書いているDELLデスクトップ

Intel(R) Pentium(R) 4 CPU 3.40GHz

2. CentOS5.2(i386) - wafful.org で使用しているVPSレンタルサーバ

Intel(R) Xeon(R) CPU           E5430  @ 2.66GHz

3. CentOS4.4(x86_64) - Linux/AMD64 の開発環境

AMD Opteron(tm) Processor 240 EE

4. FreeBSD(i386) - 奥さんから借りている jail 環境

Intel(R) Pentium(R) 4 CPU 3.20GHz

うまく CPU の情報を取ってこれているみたいですね!

■ まとめ

次回Shibuya.pmで発表の機会があれば、この辺の DynaLoader を活用した基礎的なテクニックを簡単にお話ししようと思います。

XS Niteよりも低レベルな内容ですので、Perlや正規表現に詳しくない人でも安心して聞けると思います。どうぞご安心ください。

2009年03月23日

Shibuya.pmリーダーとしてインタビュー取材を受けました

Shibuya.pmリーダーとしてインタビューを受けた記事が公開されましたので、ご報告です。

参加者の成長を見守る、Shibuya.pm 2代目リーダー − @IT自分戦略研究所

参加者の成長を見守る、Shibuya.pm 2代目リーダー − @IT自分戦略研究所

記事トップの写真は、プロカメラマンの大星直輝さんによる撮影です。 自分でもびっくりするほどかっこよく撮っていただきありがとうございます。

インタビューを受けたのは 「@IT自分戦略研究所 今週のリーダー」という面白い企画で、 技術者経験があり、現在はリーダーもしくはマネージャ的な役割を果たされている「若手リーダー」にインタビューし、その経験、リーダーシップに対する考え方を紹介し、それを通して読者に「リーダーシップとは何か、どうすれば身に付けられるのか」を伝える企画だそうです。

次はどんなリーダーの方の記事が掲載されるのか楽しみですね。

アイティメディアの長谷川さん、素晴らしい記事をありがとうございました。

ちなみに、次回Shibuya.pmは4月にテクニカルトークを開催する方向で準備を進めていますので、どうぞご期待ください。

■ 参考文献
  1. TAKESAKO @ Yet another Cybozu Labs: Shibuya.pmリーダ交代式@バソキヤオフ
  2. Shibuya.pm と私 - にぽたん研究所

2009年02月12日

デブサミ2009に行くべき、たった一つの理由

デブサミ会場内で「モダンPerl入門」が1割引の2,640円(税込)で販売中。

2009年02月07日

キャラバン京都に来ています

セキュリティ&プログラミングキャンプ・キャラバン2008 京都に来ています。

caravan2008kyoto-1.jpg caravan2008kyoto-2.jpg caravan2008kyoto-3.jpg

これからフリーディスカッションです。