プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

スポンサーサイト このエントリーをはてなブックマークに追加

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


スポンサー広告 | 【--------(--) --:--:--】 | Trackback(-) | Comments(-)

IA64アセンブラ Tips その1 - @gprel と @ltoff このエントリーをはてなブックマークに追加

またしても自分用備忘録。
IA64用gasのディレクティブ

@gprel
gpレジスタと足すことにより、引数var変数へのアドレスが得られるようなオフセット値

addl r2 = @gprel(var), gp;;  // r2にvar変数のアドレスを入れる
ld4 r3 = [r2] ;; // r3にvarをload


のように使う
しかし、IA64のadd命令で即値を取るものは

add r1 = imm_14, r3
add r1 = imm_22, r3



の二種類しかなく最大4M(±2M)

なので、このgp relative dataは小さいサイズのデータだけに
使う。という紳士協定をつくりデカいデータは以下のltoffを使う

@ltoff
引数big_var変数のアドレスが格納されたテーブルへのオフセットを得る

 addl r2 = @ltoff(big_var), gp;;  // r2にvar変数のアドレスが格納されたテーブルへのポインタを得る
ld8 r3 = [r2];; // r3にvarのアドレスをload
ld4 r8 = [r3];; // r8にvarをload


これはELF用語でいうところのGOT(global offset table)そのもの。

両方ともPIC(position independent code)に必要


イメージ図



high address

+---------------+
| |
| var | ←+
| | | @gprel
| | |
gp ⇒ | | -+
| | |
| | |
| | | @ltoff
+---------------+ |
| linkage table | |
+- | 0x47f8 | ←+
| | |
| +---------------+
| | |
| | |
0x47f8 +→ | big_var |
| |
+---------------+


low address




テーブル
グローバルなテーブル! ランキング!



関連記事
スポンサーサイト
linux | 【2006-04-28(Fri) 14:36:54】 | Trackback:(0) | Comments:(3)

品川から渋谷まで行くにはどうすりゃいいべ このエントリーをはてなブックマークに追加

参考: 線路変形 JR山手線全線ストップ 復旧は夕方か (Yahoo!ニュース)

500 番組の途中ですが名無しです 2006/04/24(月) 13:09:21.49 ID:rQ4GIc2G0
品川から渋谷まで行くにはどうすりゃいいべ


524 番組の途中ですが名無しです 2006/04/24(月) 13:12:52.89 ID:jd62PBxZ0
>>500
品川
↓京急
羽田空港
↓航空機
福岡空港
↓地下鉄
博多
↓新幹線
東京(大手町)
↓半蔵門線
渋谷



関連記事
ねた | 【2006-04-26(Wed) 13:17:44】 | Trackback:(0) | Comments:(3)

チェルノブイリが野生生物の楽園になっている件について このエントリーをはてなブックマークに追加

Rauru Blog様のエントリより


コメントがイカス!

さらにこの記事の終り近くでは、ガイア仮説で知られる James Lovelock が、興味深いことを語っている。曰く、「若干の核廃棄物を熱帯雨林の中に置いておけば、人が近付かなくなるので、熱帯雨林の自然も復活するのではないか」だそうだ。




そりゃーそーかも知れんがのww


------------

このブログの情報はまりおんのらんだむと~く様からいただきました



関連記事
ねた | 【2006-04-26(Wed) 11:36:21】 | Trackback:(0) | Comments:(5)

RPMパッケージからファイルを取り出す方法 このエントリーをはてなブックマークに追加

何回やっても忘れるシリーズ

@ITの記事
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/522rpmcpio.html

をみるとよい。

rpm2cpio rpmfile | cpio -id



関連記事
linux | 【2006-04-24(Mon) 10:40:08】 | Trackback:(0) | Comments:(5)

mixiの知り合いにおしえてもらった凄いスレ このエントリーをはてなブックマークに追加


クワガタがいっぱいいるって有名な森で

1 :以下、名無しにかわりましてVIPがお送りします :2006/04/03(月) 18:23:25.55 ID:kUdo3mTN0

バルサンを炊いたらどうなるかなぁ・・・



で始まるスレ
感動した!


http://blog.livedoor.jp/michaelsan/archives/50407311.html

関連記事
ねた | 【2006-04-23(Sun) 21:05:43】 | Trackback:(0) | Comments:(6)

ソースを貼れといわれたときのうまい切り返し このエントリーをはてなブックマークに追加


そのソースじゃないだろうww

661 名前:名無しさん@ピンキー[sage] 投稿日:05/03/12 14:17:33 ID:???
>>659
ソース貼れ。

662 名前:名無しさん@ピンキー[sage] 投稿日:05/03/12 16:43:48 ID:???
http://www.bulldog.co.jp/ ブルドックソース株式会社 東京都
http://www.kagome.co.jp/ カゴメ株式会社 愛知県
http://www.otafuku.co.jp/ オタフクソース株式会社 広島県
http://www.ikari-s.co.jp/ イカリソース株式会社 大阪府
http://www.kikkoman.co.jp/ キッコーマン株式会社 千葉県
http://www.oliversauce.com/オリバーソース株式会社 兵庫県
http://www.sky-net.or.jp/toshi/ カープソース 広島県
http://www.maruki-su.com/ 株式会社 川上酢店 愛知県
http://www.kozima.co.jp/ 小島食品製造株式会社 愛知県
http://www.komi.co.jp/ コーミ株式会社 愛知県
http://www.sankyohikari.co.jp/ サンキョーヒカリ 愛知県
http://www.junmaru.co.jp/ 株式会社 純正食品マルシマ 広島県
http://www.papaya-sauce.co.jp/ パパヤソース本舗 大洋産業株式会社 京都府
http://www.takahashisauce.com/ 高橋ソース株式会社 埼玉県


663 名前:名無しさん@ピンキー[sage] 投稿日:05/03/12 17:39:59 ID:???
>>662
尊敬のまなざし・・凄いよ!素敵だよ!



関連記事
ねた | 【2006-04-23(Sun) 15:00:37】 | Trackback:(0) | Comments:(4)

俺ってなんてイタリアンな漢なんだろう このエントリーをはてなブックマークに追加

のっけからアホタイトルをつけてみたが、今回のおもろリファラをご紹介。

てか、ふつーのぐぐる様からのお客さんなんだけどね。

こんなの
http://www.google.it/search?q=centos%20vmx&start=0&ie=utf-8&hl=it&oe=utf-8&client=firefox-a&rls=org.mozilla:it:official

ってイタリアですかい。
しかも、このリンク辿るとなぜかググる検索結果1位!


で、さらに履歴を丹念に調べると案の定日本語が分からなかったらしくgoogle translationで翻訳した形跡が・・・

http://translate.google.com/translate?hl=en&sl=ja&u=http://mkosaki.blog46.fc2.com/&prev=/search%3Fq%3D%25E9%259D%25A9%25E5%2591%25BD%25E3%2581%25AE%25E6%2597%25A5%2B%26hl%3Den%26lr%3D%26sa%3DG

僕のサイトのページランクって0なんだけどな。
ぐぐる様のランキングの基準ってわからんわぁぁ(n'ω'`)


てか、イタリア人に日本語サイト1位でみせちゃダメだろうwww



P.S
なにげに、ぐぐる様は翻訳センスも最高。グッジョブ
革命の日々! が Everyday life of revolution! なのはカッチョイイのでまじ感動したが、
次までに考えておくよ が You think to as described below なのは明らかに誤訳だろう。と
ブログ検索 にいたっては Bu log searching デスヨ!
そこで区切るか!?




ポカーン
ぐぐる様へ一言いいたい、こんなこと! ランキング!



関連記事
ねた | 【2006-04-22(Sat) 22:37:58】 | Trackback:(0) | Comments:(2)

/proc/[pid]/maps ファイルの見方 このエントリーをはてなブックマークに追加

何回もソース読んだはずなのにすぐ忘れてしまう。

08048000-08049000 r-xp 00000000 16:44 66267    /home/foo/a.out
08049000-0804a000 rw-p 00000000 16:44 66267 /home/foo/a.out
40000000-40016000 r-xp 00000000 16:42 442401 /lib/ld-2.2.4.so
40016000-40017000 rw-p 00015000 16:42 442401 /lib/ld-2.2.4.so
40017000-40019000 rw-p 00000000 00:00 0
40033000-40166000 r-xp 00000000 16:42 327696 /lib/i686/libc-2.2.4.so
40166000-4016b000 rw-p 00132000 16:42 327696 /lib/i686/libc-2.2.4.so
4016b000-4016f000 rw-p 00000000 00:00 0
bfffe000-c0000000 rwxp fffff000 00:00 0
-------- -------- -- - -------- ----- ----- --------------
start end | | file device inode file name
addr addr | | offset major/ no
| | minor
rwxアクセス権 -+ |
mmapの引数ね |
|
s: 共有 ---+
p: プライベート




ソースの位置は linux/fs/proc/task_mmu.c より
80 static int show_map(struct seq_file *m, void *v)
81 {
82 struct vm_area_struct *map = v;
83 struct file *file = map->vm_file;
84 int flags = map->vm_flags;
85 unsigned long ino = 0;
86 dev_t dev = 0;
87 int len;
88
89 if (file) {
90 struct inode *inode = map->vm_file->f_dentry->d_inode;
91 dev = inode->i_sb->s_dev;
92 ino = inode->i_ino;
93 }
94
95 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
96 map->vm_start,
97 map->vm_end,
98 flags & VM_READ ? 'r' : '-',
99 flags & VM_WRITE ? 'w' : '-',
100 flags & VM_EXEC ? 'x' : '-',
101 flags & VM_MAYSHARE ? 's' : 'p',
102 map->vm_pgoff << PAGE_SHIFT,
103 MAJOR(dev), MINOR(dev), ino, &len);
104
105 if (map->vm_file) {
106 len = 25 + sizeof(void*) * 6 - len;
107 if (len < 1)
108 len = 1;
109 seq_printf(m, "%*c", len, ' ');
110 seq_path(m, file->f_vfsmnt, file->f_dentry, "");
111 }
112 seq_putc(m, '\n');
113 return 0;
114 }






関連記事
linux | 【2006-04-22(Sat) 17:49:03】 | Trackback:(0) | Comments:(4)

NintendoDS Liteの先行取材が最高すぎる件 このエントリーをはてなブックマークに追加

まあ、これを見ろ

ニュー速クオリティ: NintendoDSLiteを独占先行入手

NintendoDS



関連記事
ねた | 【2006-04-22(Sat) 16:52:03】 | Trackback:(0) | Comments:(3)

PIE(位置独立実行ファイル)で遊んでみる このエントリーをはてなブックマークに追加

いやなブログさんのPIE (位置独立実行形式) を作成する を読んで。

PIEという形式についてまるで聞いたことがなかったので色々と遊んでみた(いやなブログさんはこういう情報をどこから入手しているのかしら?)

まず、readelfコマンドで実行ファイルのヘッダを読んでみると

$readelf -h pie_hello

ELF ヘッダ:
マジック: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
クラス: ELF32
データ: 2 の補数、リトルエンディアン
バージョン: 1 (current)
OS/ABI: UNIX - System V
ABI バージョン: 0
タイプ: DYN (共有オブジェクトファイル)
マシン: Intel 80386
バージョン: 0x1
エントリポイントアドレス: 0x4dc
プログラムの開始ヘッダ: 52 (バイト)
セクションヘッダ始点: 2564 (バイト)
フラグ: 0x0
このヘッダのサイズ: 52 (バイト)
プログラムヘッダサイズ: 32 (バイト)
プログラムヘッダ数: 7
セクションヘッダ: 40 (バイト)
Number of section headers: 28
Section header string table index: 25


タイプの所に注目。
通常のET_EXE(実行可能ファイル)ではなくET_DYN(共有オブジェクトファイル)になっている。
共有オブジェクトファイルってのは要するに共有ライブらりと同じタイプだ。

つまりカーネルからは共有ライブラリとして見えていて、ランタイムリンカー(ld.so)で細工をしているということを意味する。


実はLinuxにおいて、実行ファイルと共有ライブラリの違いは恐ろしく少ない。
共有ライブラリはELFでいうところの動的オブジェクトという仕組みを使うのだが、
動的オブジェクトと実行可能ファイルの違いは再配置情報があるか否かが本質的な違いであり、
共有ライブラリが通常エントリポイントをもたず実行可能でないのは、あくまで使い方の習慣に
過ぎない。

たとえば、libcなぞは実は実行可能であって

[mkosaki@centos pie]$ /lib/libc-2.3.4.so
GNU C Library stable release version 2.3.4, by Roland McGrath et al.
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 3.4.4 20050721 (Red Hat 3.4.4-2).
Compiled on a Linux 2.4.20 system on 2005-10-08.
Available extensions:
GNU libio by Per Bothner
crypt add-on version 2.1 by Michael Glad and others
linuxthreads-0.10 by Xavier Leroy
The C stubs add-on version 2.1.2.
BIND-8.2.3-T5B
NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
Glibc-2.0 compatibility add-on by Cristian Gafton
GNU Libidn by Simon Josefsson
libthread_db work sponsored by Alpha Processor Inc
Thread-local storage support included.
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.


などというメッセージを出力してくれる。

カーネル的には、ET_EXEとET_DYNの違いってのはET_EXEは再配置可能でないので
実行ファイルをメモリに貼り付けるときにdo_mmap()をMAP_FIXED flagをONにするぐらいしか
配慮の違いをしていない。

#おいら、今回の件について調べるまでなんでET_EXEかどうかをチェックするのか
#思いつかなかったよ。
#ちょっと反省


というわけで、あんまり調べてないがPIEとは

・PICと違い、自分の再配置に必要な情報だけが入っている(とinfoには書いてあるな)
・エントリポイントを持った共有ライブラリ

がその正体であると結論付けることができました。
メデタシメデタシ




・・・・と終わると綺麗なのだが、このブログっぽいアホさが足りないので蛇足っぽく続けてみる。








ためしに、リンク時に
gcc hello_pie.o -o hello_pie -pie -static


などとスタティックリンクしてみると

./pie_hello
bash: ./pie_hello: /usr/lib/libc.so.1: bad ELF interpreter: そのようなファイルやディレクトリはありません


というつれないお返事をいただき、実行できません。よよよ

もう一度readelfしてinterpを見ると、/usr/lib/libc.so.1 が埋め込まれていました。
むむ、-staticは本来interpセクションを生成しないはずだけど、ここでは-pieが勝ってしまって
生成されてしまった。
しかしながら、gccのinterpセクションのデフォルトがlibc.so.1なのに、最近のディストリじゃ
んなファイルは存在しない。という事になっているのが原因かと思います。

とゆーか、こんなアホなリンクオプションの組み合わせはテストしてないに違いない(決め付け)

そこで無理やりランタイムリンカーにld-2.3.4.so(普段使っているシステムデフォルトのランタイムリンカー)を明示的に埋め込んでみる

  gcc hello_pie.o -o hello_pie -statc -pie -Wl,--dynamic-linker,/lib/ld-2.3.4.so 


[mkosaki@centos pie]$ catchsegv ./pie
*** Segmentation fault
Register dump:

EAX: 00970000 EBX: bfea0a37 ECX: 00000004 EDX: 00970114
ESI: 00000000 EDI: 00554670 EBP: bfea0988 ESP: bfea097c

EIP: 0097c9cd EFLAGS: 00210206

CS: 0073 DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 007b

Trap: 0000000d Error: 00000000 OldMask: 00000000
ESP/signal: bfea097c CR2: 00000000

Backtrace:
/lib/libSegFault.so[0x4b839f]
/lib/libc.so.6[0xab58d8]
??:0(??)[0x97c1da]
??:0(??)[0x97bf81]

Memory map:

0041d000-0041e000 r-xp 00000000 fd:00 65555 /lib/libNoVersion-2.3.4.so
0041e000-00420000 rwxp 00000000 fd:00 65555 /lib/libNoVersion-2.3.4.so
004b7000-004ba000 r-xp 00000000 fd:00 65557 /lib/libSegFault.so
004ba000-004bc000 rwxp 00002000 fd:00 65557 /lib/libSegFault.so
00548000-0055d000 r-xp 00000000 fd:00 65538 /lib/ld-2.3.4.so
0055d000-0055e000 r-xp 00015000 fd:00 65538 /lib/ld-2.3.4.so
0055e000-0055f000 rwxp 00016000 fd:00 65538 /lib/ld-2.3.4.so
00970000-009d9000 r-xp 00000000 fd:00 1922710 /home/mkosaki/projects/pie/pie
009d9000-009db000 rwxp 00068000 fd:00 1922710 /home/mkosaki/projects/pie/pie
009db000-009dc000 rwxp 009db000 00:00 0
00a8d000-00bb2000 r-xp 00000000 fd:00 65560 /lib/libc-2.3.4.so
00bb2000-00bb3000 r-xp 00125000 fd:00 65560 /lib/libc-2.3.4.so
00bb3000-00bb6000 rwxp 00126000 fd:00 65560 /lib/libc-2.3.4.so
00bb6000-00bb8000 rwxp 00bb6000 00:00 0
00ff1000-00ff8000 r-xp 00000000 fd:00 65598 /lib/libgcc_s-3.4.4-20050721.so.1
00ff8000-00ff9000 rwxp 00006000 fd:00 65598 /lib/libgcc_s-3.4.4-20050721.so.1
08fb8000-08fd9000 rw-p 08fb8000 00:00 0
b7f02000-b7f03000 rw-p b7f02000 00:00 0
bfe9f000-c0000000 rw-p bfe9f000 00:00 0
ffffe000-fffff000 ---p 00000000 00:00 0
[mkosaki@centos pie]$ catchsegv ./pie
*** Segmentation fault
Register dump:

EAX: 00554000 EBX: bfef2977 ECX: 00000004 EDX: 00554114
ESI: 00000000 EDI: 00606670 EBP: bfef28c8 ESP: bfef28b8

EIP: 00aa8000 EFLAGS: 00210206

CS: 0073 DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 007b

Trap: 0000000e Error: 00000004 OldMask: 00000000
ESP/signal: bfef28b8 CR2: 00aa8000

Backtrace:
/lib/libSegFault.so[0x25739f]
/lib/libc.so.6[0x3fc8d8]
??:0(??)[0x5601da]
??:0(??)[0x55ff81]

Memory map:

00256000-00259000 r-xp 00000000 fd:00 65557 /lib/libSegFault.so
00259000-0025b000 rwxp 00002000 fd:00 65557 /lib/libSegFault.so
003d4000-004f9000 r-xp 00000000 fd:00 65560 /lib/libc-2.3.4.so
004f9000-004fa000 r-xp 00125000 fd:00 65560 /lib/libc-2.3.4.so
004fa000-004fd000 rwxp 00126000 fd:00 65560 /lib/libc-2.3.4.so
004fd000-004ff000 rwxp 004fd000 00:00 0
00554000-005bd000 r-xp 00000000 fd:00 1922710 /home/mkosaki/projects/pie/pie
005bd000-005bf000 rwxp 00068000 fd:00 1922710 /home/mkosaki/projects/pie/pie
005bf000-005c0000 rwxp 005bf000 00:00 0
005fa000-0060f000 r-xp 00000000 fd:00 65538 /lib/ld-2.3.4.so
0060f000-00610000 r-xp 00015000 fd:00 65538 /lib/ld-2.3.4.so
00610000-00611000 rwxp 00016000 fd:00 65538 /lib/ld-2.3.4.so
00997000-0099e000 r-xp 00000000 fd:00 65598 /lib/libgcc_s-3.4.4-20050721.so.1
0099e000-0099f000 rwxp 00006000 fd:00 65598 /lib/libgcc_s-3.4.4-20050721.so.1
00f30000-00f31000 r-xp 00000000 fd:00 65555 /lib/libNoVersion-2.3.4.so
00f31000-00f33000 rwxp 00000000 fd:00 65555 /lib/libNoVersion-2.3.4.so
0917f000-091a0000 rw-p 0917f000 00:00 0
b7ef8000-b7ef9000 rw-p b7ef8000 00:00 0
bfef1000-c0000000 rw-p bfef1000 00:00 0
ffffe000-fffff000 ---p 00000000 00:00 0



これでメデタク(?)毎回違うアドレスで死んでくれる実行ファイルができました。

ああ、死ぬのはええんよ。
毎回違うアドレスにマップされるのに、再配置不可能なんだから、そら死ぬやろ。

catchsegvでメッセージが出るという事は.ctorの初期化は走っているということで
.ctorが動いたという事はランタイムリンカーの仕事は無事完了して
実行ファイルのスタートアップコードに到達したという事だからOKOKですよ。


P.S.
恒例の今回見つけたバグまたはuglyな仕様コーナー
と、いうわけで、普通やらないコーナーケースに備えて
execシステムコールで実行ファイルがET_DYNでもノーチェックで
ランタイムリンカーへ処理が移っちゃうのですが(この時点で親プロセスからはexec成功に見える)
これはエントリポイントが見つからないときは、exec成功させずに
ENOEXECぐらいを返すべきだと思いますね。
再配置はできるけど、ラインタイムリンカー抜けた瞬間にSIGSEGVって意味わからんし
どうでしょ?



あぶないよ!!とびだしみえるきみのにく
中身がみえちゃった! ランキング!


関連記事
linux | 【2006-04-22(Sat) 14:16:27】 | Trackback:(0) | Comments:(3)

変態祭り このエントリーをはてなブックマークに追加

「alternative マクロと自己修正コード」エントリのはてなブックマークのコメントが変態に満ち溢れている件について。

誰だ、犯人は!(笑い


エライメにあいます
この変態が!! ランキング!



関連記事
ねた | 【2006-04-19(Wed) 01:17:48】 | Trackback:(1) | Comments:(5)

そういえば このエントリーをはてなブックマークに追加

Pentium4登場時にWindows XPの起動がPentium4だとPentiumIIIよりもものすごく速い。
というキャンペーンがあって、みんなで「なんでやねん!」と連呼していたのだが、もしかしてWindowsもLinuxのalternativeマクロみたいな仕組みを入れてるんかね?
Linuxとは逆に、デフォルトがPentium4で。

それだとすると納得するんだけどな。

関連記事
雑談 | 【2006-04-18(Tue) 23:52:27】 | Trackback:(0) | Comments:(3)

alternative マクロと自己修正コード このエントリーをはてなブックマークに追加

alternativeマクロについて

シーケンスロック その3 において

> alternativeマクロは興味深い動作をするので、回を改めて詳しく説明しますが、

などと書いておいて すっかり忘れていた alternativeマクロですがいい機会なので解説しましょう。
いつものように lxr.linux.no あたりからソースを引っ張ってきている。

linux/include/asm-i386/system.h より
288 /* 
289 * Alternative instructions for different CPU types or capabilities.
290 *
291 * This allows to use optimized instructions even on generic binary
292 * kernels.
293 *
294 * length of oldinstr must be longer or equal the length of newinstr
295 * It can be padded with nops as needed.
296 *
297 * For non barrier like inlines please define new variants
298 * without volatile and memory clobber.
299 */
300 #define alternative(oldinstr, newinstr, feature) \
301 asm volatile ("661:\n\t" oldinstr "\n662:\n" \
302 ".section .altinstructions,\"a\"\n" \
303 " .align 4\n" \
304 " .long 661b\n" /* label */ \
305 " .long 663f\n" /* new instruction */ \
306 " .byte %c0\n" /* feature bit */ \
307 " .byte 662b-661b\n" /* sourcelen */ \
308 " .byte 664f-663f\n" /* replacementlen */ \
309 ".previous\n" \
310 ".section .altinstr_replacement,\"ax\"\n" \
311 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
312 ".previous" :: "i" (feature) : "memory")


これがalternativeマクロの定義ね。
はっはっは、これを見せると確実に引かれるので省いたのだよ。

見やすくするために、このマクロを展開してみる。

まず、こんなファイルをカット&ペーストを駆使して作る

main.c
#define alternative(oldinstr, newinstr, feature) 	\
asm volatile ("661:\n\t" oldinstr "\n662:\n" \
".section .altinstructions,\"a\"\n" \
" .align 4\n" \
" .long 661b\n" /* label */ \
" .long 663f\n" /* new instruction */ \
" .byte %c0\n" /* feature bit */ \
" .byte 662b-661b\n" /* sourcelen */ \
" .byte 664f-663f\n" /* replacementlen */ \
".previous\n" \
".section .altinstr_replacement,\"ax\"\n" \
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
".previous" :: "i" (feature) : "memory")

#define X86_FEATURE_XMM2 57 /* dummy */
#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)


main(){
mb();
mb();
}


X86_FEATURE_XMM2 の定義は適当にでっちあげたが、何、かまやしない。

これを -S 付きでコンパイル

 $ gcc -S main.c -o main.s 


出来上がったファイルがこちら

main.s
	.file	"main.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
#APP
661:
lock; addl $0,0(%esp)
662:
.section .altinstructions,"a"
.align 4
.long 661b
.long 663f
.byte 57
.byte 662b-661b
.byte 664f-663f
.previous
.section .altinstr_replacement,"ax"
663:
mfence
664:
.previous
661:
lock; addl $0,0(%esp)
662:
.section .altinstructions,"a"
.align 4
.long 661b
.long 663f
.byte 57
.byte 662b-661b
.byte 664f-663f
.previous
.section .altinstr_replacement,"ax"
663:
mfence
664:
.previous
#NO_APP
leave
ret
.size main, .-main
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.4.4 20050721 (Red Hat 3.4.4-2)"


gccは親切なことに、asm文の範囲を#APPと#NO_APPで教えてくれています。
あとasm文が volatile修飾されているので素直にマクロが2つとも展開されています。

まず文法的な説明から
詳しくは

 $info gas 


で調べて欲しいが簡単に。

セクション切り替え
.section [section_name], "[FLAGS]"

FLAGS:
'a' allocatable, 実行時にメモリにロードされる。これがOFFなセクションってほとんど見ない
'x' executable, 実行可能

セクション名は任意のASCII名がつけれるが、"."(ドット) で初めておくのが
スカートのプリーツを乱さないと同じくらい、ここでのたしなみ。

.previous 1つ前の.section命令をキャンセルする。
つまり
.section .foo
.previous

.scction .foo
.text
と同じなのだけれど、最初が.text じゃなかったときもうまく動くのが利点。


ローカルなラベル
[positive_number]:

普通のラベルと違い、複数あられてもOKなラベル。
このラベルを参照するときは末尾に"f"か"b"をつける。
"f"は参照より後ろ(forward)で一番近いラベル、"b"は参照より前(backword)で一番近いラベルをあらわす。

.byte
.long
即値埋め込み命令。
.byte 57
とやればそのまんまバイナリに57という数字が埋め込まれる。
普通はC言語的な意味での「定数」をバイナリに埋め込むために使うが
たまに変態的な使い方として
x86プロテクトモードアセンブラの一部に16bitモードのアセンブラを埋め込みたいとか
ARMのアセンブラの一部にTHUMBコードを埋め込みたいとかいうバカ(褒め言葉)が
.byteを駆使して、実行コードを記述する例も見られる。

あ、話がそれた。

.align [argument]
後続のデータをargument byteにアライメントさせる。

また、この引数ではラベルへの参照と簡単な四則演算が使える。つまり

.long 661b
と書けばラベル661を前方参照してそのアドレスを埋め込む

.byte 662b-661b
と書けばラベル662のアドレス引く661のアドレス、つまりその範囲のコードの長さが埋め込まれる。
ここで、661bとかってのはローカルラベルだから、最初のmbと2番目のmbで661bの展開先が異なることには
注意していただきたい。
ここを理解しないと、何を埋め込んでいるのかサッパリ分からなくなってしまう。

つまり661bは引数oldinstrのアドレスになっていて、663fは引数newinstrのアドレスになる。


これを確かめるために、先ほどのmain.c をコンパイルして出来た実行ファイルをobjdumpしてみる

セクション:
索引名 サイズ VMA LMA File off Algn
(中略)
12 .altinstr_replacement 00000006 0804841c 0804841c 0000041c 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .fini 0000001a 08048424 08048424 00000424 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .rodata 00000008 08048440 08048440 00000440 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
15 .altinstructions 00000017 08048448 08048448 00000448 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA


よしよし、.altinstr_replacement と .altinstructions がちゃんとあるな。

あっと、寄り道になるけど補足しておこう。
なぜか .altinstr_replacement と .altinstructions の順番が逆になっているけど
これはセクションフラグに"x"を入れたかどうかの違いが現れている。
gccは特に指定しないと"x"がONになっているコード部分を実行ファイルの前のほうに
寄せるんです。


次に .altinstructions セクションをダンプしてみる。
ファイル位置は0x448でサイズが0x17とobjdump君はいっているので

[mkosaki@centos alternative_macro]$ od -A x -t x1  -j 0x448 -N 0x17 a.out
000448 50 83 04 08 1c 84 04 08 39 06 03 00 56 83 04 08
000458 1f 84 04 08 39 06 03


ほれ、でてきた。これを「じーーー」っと見ると

50 83 04 08 1c 84 04 08 39 06 03 00 
56 83 04 08 1f 84 04 08 39 06 03
----------- ----------- - - - -
oldinstr newinstr | | | |
| | | +-- pad (4byte alignにするため)
| | |
| | +------ mfence命令のopcodeは 0F AE /6 の3バイト
| |
| +--------- add mem imm8で5バイトlock prefixで+1
|
+ ----------- feature(0x39=57ダミーで入れたよね)


と、なんとなくソレらしい値になっていることが分かる。
特に661bとかのラベル参照がちゃんと、違うアドレスになっていることを確認していただきたい。


つまり、これは

linux/include/asm-i386/system.h の
278 struct alt_instr { 
279 __u8 *instr; /* original instruction */
280 __u8 *replacement;
281 __u8 cpuid; /* cpuid bit set for replacement */
282 __u8 instrlen; /* length of original instruction */
283 __u8 replacementlen; /* length of new instruction, <= instrlen */
284 __u8 pad;
285 };


というデータ構造をメンドクサイ方法で作っているだけだという事。
なんでわざわざ面倒な方法を採用するかというと、C言語で普通に書くと変数には
名前をつけなくてはいけない。
でも、そこらじゅうで使われるマクロだと名前のバッティングを避けるのがえらい面倒なので
アセンブラで無理やり無名データを作っているわけ。


さて、ここらで今までに分かったことを一端まとめると

alternativeマクロは、oldinstr引数だけを実行コードとして生成して、
newinstr引数、feature引数をつかって、.altinstr_replacement と .altinstructions
というなんだかよく分からないデータ構造を作る。

という事が分かった。


エェェ(´д`)ェェエ
newinstr が実行コードに入らないんじゃ意味ないじゃーーん。

と思うかもしれないが、信じて欲しい、最終的にはnewinstrが実行されるように
別の場所で細工しているのだ。

それをこれから解説していく。


まず、 .sectionがマクロ内で使っていた時点で「きっとリンカスクリプト」で何か
細工をしているに違いない。
と、ピンとこなければならない。

だって、他にセクションなんか使う場所ないんだもの。

で、リンカスクリプトを見てみると・・・

linux/arch/i386/kernel/vmlinux.lds.S
86   . = ALIGN(4);
87 __alt_instructions = .;
88 .altinstructions : { *(.altinstructions) }
89 __alt_instructions_end = .;
90 .altinstr_replacement : { *(.altinstr_replacement) }


ありました。
複数のファイルの、色々な場所に散らばっている.altinstructions と.altinstr_replacementを一箇所に集めています。
見方は
出力先のセクション名: { 入力ファイル名(入力ファイル内のセクション)}
で入力ファイルが*(ワイルドカード)だから全てのファイルのセクションを集めるって意味。

そして、.altinstructions セクションの直前と直後に__alt_instructions, __alt_instructions_endという
シンボル(C言語で言うところの変数)をつくり、カレントマーカを代入しています。

これも定石処理(どこの世界の常識だよ!)で、無名のデータを作ったまま何もしないと、
本当に使いようがなくなってしまうので、
リンク時に先頭にシンボルを作って、C言語の別の場所から extern __alt_instructions とかやって
参照できるようにするんですな。

あとは、__alt_instructions を作った以上はどこかでつかっているに違いないと、grepすると

linux/arch/i386/kernel/setup.c
1285 /* Replace instructions with better alternatives for this CPU type.
1286
1287 This runs before SMP is initialized to avoid SMP problems with
1288 self modifying code. This implies that assymetric systems where
1289 APs have less capabilities than the boot processor are not handled.
1290 In this case boot with "noreplacement". */
1291 void apply_alternatives(void *start, void *end)
1292 {
1293 struct alt_instr *a;
1294 int diff, i, k;
1295 unsigned char **noptable = intel_nops;
1296 for (i = 0; noptypes[i].cpuid >= 0; i++) {
1297 if (boot_cpu_has(noptypes[i].cpuid)) {
1298 noptable = noptypes[i].noptable;
1299 break;
1300 }
1301 }
1302 for (a = start; (void *)a < end; a++) {
1303 if (!boot_cpu_has(a->cpuid))
1304 continue;
1305 BUG_ON(a->replacementlen > a->instrlen);
1306 memcpy(a->instr, a->replacement, a->replacementlen);
1307 diff = a->instrlen - a->replacementlen;
1308 /* Pad the rest with nops */
1309 for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
1310 k = diff;
1311 if (k > ASM_NOP_MAX)
1312 k = ASM_NOP_MAX;
1313 memcpy(a->instr + i, noptable[k], k);
1314 }
1315 }
1316 }
1317
1318 static int no_replacement __initdata = 0;
1319
1320 void __init alternative_instructions(void)
1321 {
1322 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
1323 if (no_replacement)
1324 return;
1325 apply_alternatives(__alt_instructions, __alt_instructions_end);
1326 }
1327
1328 static int __init noreplacement_setup(char *s)
1329 {
1330 no_replacement = 1;
1331 return 0;
1332 }
1333
1334 __setup("noreplacement", noreplacement_setup);


という処理をしているのがわかります。

__initはLinuxカーネル内における __attribute__((constructor)) 指定であり、
カーネル起動時に自動的に呼ばれます。
なんでgcc標準の__attribute__((constructor)) を使わないのかってはなしは面白いので別の機会にでも。

__setup()ってのはカーネル起動時のコマンドライン引数(lilo.confとかgrub.confとかに書くヤツ)
で第一引数の文字列が指定されたら第二引数の関数を呼べというある種のコールバック登録。

話がそれた。


で、見てみると
__alt_instructions をそのまま alt_instr構造体の配列とみなして
(そうできるように、.longやら.byteを駆使してデータ構造を作ったんだよね)

cpuid命令の結果からfeature bitがONになっていれば boot_cpu_has(a->cpuid)
newinstr をoldinstrの位置にmemcpy()して実行コードを直接書き換えてしまう(!)
という荒業を行っています。

これで実行時にif文を使わずにCPUにあわせた最適な処理が実行できるわけ。
alternativeマクロのコメントに記述してあるnewinstr引数はoldinstr引数よりも
生成コードが短くないといけないって制限もこれで納得していただけると思う。

1クロックでも無駄にしないカーネル魂。感じていただけただろうか。

あっと、書き忘れ
memcpy(a->instr + i, noptable[k], k); ってのは残りのバイトをNOPで埋めるんだけども
x86はNOPがいくつか種類があって、たとえば4バイトあまったときに
1バイトのNOP x4 よりも4バイトNOP x1 のほうがCPU にやさしい
(バファリンとカーネルハッカーの半分はやさしさで出来ています)
ので、こういうメンドクさいループを実行している。


どうだろう?
思ったよりも、ややこしかったのではないだろうか?
元を正せばマルチプロセッサ同期命令などという基本的な命令を
P6, Pentium4などという超最近に追加するIntelが悪いのだが、
素直にコンパイルオプションなぞにしてしまったら、ディストリビュータはきっと
Pentium4をOFFにしたGenericカーネルを配布しだして遅くなるし
条件分岐命令なんぞいれた日にゃあ、目も当てられない速度になるのは請け合い。
ってことで、かなり強引な手法がとられている。

普通のLinuxでは実行コードは書き換え不可なので、自己修正コードをつくるのはかなり難儀なのだが、そこはカーネル、なにものにも邪魔されずにハックされてる様は逆にすがすがしくもある
(なにが?)

当然、というか、x86以外ではここまでエエカげんな命令セット拡張はしてないので、
alternativeマクロ自体が存在しない。

どうだまいったか!(だからなにが?)



P.S.
ところで、これを書いている中で些細なバグをまた見つけてしまった。
Intelが発行している
「IA-32 インテル アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル 下巻: システムプログラミングガイド」の10.6節 自己修正コード の項にはコードを書き換えたらcpuid命令(など)を発行してシリアルか操作を実行してね。
と書いてあるけど、してないよね。
まあ、書き換え直後に実行しない限りprefechは考えなくて良いし、起動時に書き換えてるのでキャッシュにすでに
乗っている可能性は0なので、実害はないんだろうけど、うがが・・


P.S.2
今回は余興もかねて、よく分からないときの調べ方も含めて書こうとしたのだが、幾分中途半端だったかも。
次からは普通に、結論だけ書く記事に戻るかもしれん。
そのほうがこっちもラクだし。


P.S.3
早く発売してくれ



修正してやる
修正してやる! ランキング!
(そして返り討ち)



関連記事
linux | 【2006-04-18(Tue) 20:16:47】 | Trackback:(1) | Comments:(11)

マイクロソフトのパッケージグループが最高すぎる件について このエントリーをはてなブックマークに追加

すこし旧聞になってしまうが、すごくおもしろい動画をみつけたのでご紹介。

Ad Innovator様のマイクロソフト版iPodパッケージ開発パロディビデオ、マイクロソフト社内の仕業と認める というエントリを参照していただきたい。

これ、実はマイクロソフトのパッケージ部門直々に作成したMSのパッケージデザインを揶揄する作品なんですねー
ものすごく的確にiPodのデザインが無茶苦茶にされていくさまはいっそ感動を覚えます。

あちこちのBlogでスタッフがキレたと大絶賛!
そら絶賛もするわー

まあ見てくだされ。



そろそろ成仏、する?
逆ギレ! ランキング!


関連記事
ねた | 【2006-04-16(Sun) 21:02:56】 | Trackback:(0) | Comments:(3)

Google Gmail のスパムフィルター超便利 このエントリーをはてなブックマークに追加

最近、SPAM がものすごく多くて閉口していた。
よく考えたらもう10年以上同じメアド。
しかも技術系のMLとかで過去ログをWebに公開されちゃうパターンでがんがん流出してるから、もうトンでもない

で、見つけた記事がこれ「Gmailをスパムフィルタとして活用してみる」

携帯に転送とか考えずに、パソコンで読むだけなら単にGmailアカウントに転送するだけ。
勝手にSpamを振り分けてPOPでダウンロードされないようにしてくれます。
しかも振り分け精度はものすごくGoodです。

しかもしかも
Gmailを経由させることにより、メールのバックアップが自動的に取れてしまいます。
(GmailはPOPでメール取得してもメールを消さない仕様)

SPAM、本当に減りました。
オススメです。

Gmailアカウント持ってない人は言ってくれれば招待いたしますので一声くださいまし




BlackPepperCan
SPAMなんかに負けない! ランキング!


関連記事
テクノロジー | 【2006-04-15(Sat) 22:53:17】 | Trackback:(0) | Comments:(7)

pfmonの使い方 このエントリーをはてなブックマークに追加

今回は小ネタ。
IA64なLinuxで簡単にItanium2のPerformance Monitor機能を使う方法

$ pfmon -eL2_MISSES,L3_MISSES ls
lpgserial projects
9210 L2_MISSES
2397 L3_MISSES


-e オプションの後にモニタしたいイベント名を入れるだけ

イベント名はCPUのマニュアルを見る必要があるが
大体分かっているときは

$ pfmon -lL3_
L2_BYPASS_L3_DATA1
L2_BYPASS_L3_INST1
L2_L3ACCESS_CANCEL_INV_L3_BYP
L2_L3ACCESS_CANCEL_SPEC_L3_BYP
L3_LINES_REPLACED
L3_MISSES
L3_READS_ALL_ALL
L3_READS_ALL_HIT
L3_READS_ALL_MISS
L3_READS_DATA_READ_ALL
L3_READS_DATA_READ_HIT
L3_READS_DATA_READ_MISS
L3_READS_DINST_FETCH_ALL
L3_READS_DINST_FETCH_HIT
L3_READS_DINST_FETCH_MISS
L3_READS_INST_FETCH_ALL
L3_READS_INST_FETCH_HIT
L3_READS_INST_FETCH_MISS
L3_REFERENCES
L3_WRITES_ALL_ALL
L3_WRITES_ALL_HIT
L3_WRITES_ALL_MISS
L3_WRITES_DATA_WRITE_ALL
L3_WRITES_DATA_WRITE_HIT
L3_WRITES_DATA_WRITE_MISS
L3_WRITES_L2_WB_ALL
L3_WRITES_L2_WB_HIT
L3_WRITES_L2_WB_MISS


-l 文字列 でその文字列を含むイベントをリストアップできる。
イベントを度忘れしたときに便利


また、

$ pfmon -iL2_IFET_CANCELS_ANY
Name : L2_IFET_CANCELS_ANY
VCode : 0xa1
Code : 0xa1
PMD/PMC: [ ]
Umask : 0000
EAR : No (N/A)
BTB : No
MaxIncr: 1 (Threshold 0)
Qual : [Instruction Address Range] [OpCode Match] [Data Address Range]
Group : L2 Cache
Set : 0
Desc : Instruction Fetch Cancels by the L2 -- total instruction fetch cancels by L2


-i オプションでそのイベント説明を表示できる
ただし、元のインテルのマニュアルの説明がかなり説明不足なのでDescを読んでも意味不明になることしばしば




追記:
ここまで書いて、はからずもこの記事が
higeponさんの「プログラマの皆さんホームディレクトリで ls してみようよ」エントリに応募資格があることに気づいてしまった。
早速応募。

って、ぜんぜん面白くないlsだこと。。。orz





関連記事
linux | 【2006-04-12(Wed) 14:47:35】 | Trackback:(0) | Comments:(2)

赤松ナントカ このエントリーをはてなブックマークに追加

「誰も読まないOSのソース・コード」というエントリのツッコミで極めて面白いものを見つけた

孤高さんのブログより

■ 小飼氏のエントリに細かいツッコミをしてみる。。
(中略)
「赤松ナントカ」と読んで「健?」とか思ってしまった私はラブひなとネギま!ぐらい本質的に同じだ(意味不明)



それ、もはやツッコミでもなんでもないw

というか、こんなに引用してもらえるんだったらバナナはおやつに含まない! ぐらいのネタ条項を仕込んでおくんだった。
反省


追記: 引用元にちゃんとリンク貼れていませんでした。今度はうまくいってるかな


しりにいれない
そんな所にツッコマないで! ランキング!


関連記事
ねた | 【2006-04-11(Tue) 10:11:51】 | Trackback:(1) | Comments:(0)

誰も読まないOSのソース・コード このエントリーをはてなブックマークに追加

日経BPのサイトに、誰も読まないOSのソース・コードという記事がアップされている。

わりと衝撃的な見出しから始まるのでさくっと引用

 まず,結論から言おう。 「エンジニアがOSのソース・コードを読めるようになると,活躍の場が一気に広がる」。そして,「コツさえ分かれば,OSのソース・コードはびっくりするほど簡単に読める」。



 赤松氏が「ソースを読んでいる人がほとんどいない」と感じる理由はもう1つある。それは,誰もがよく使うソフトでさえバグが大量にある,ということだ。少しでもソースをのぞけば,誰にでもすぐに見つけられるほど簡単なバグなのに,ネットにも情報が上がらず放置されているという。例えば,赤松氏が見つけたバグの具体例を一つだけお見せしよう。




まあ、寝言は寝てから言ってくれといった感じだが、カーネル読めるぐらいで生活は楽にならんっちゅーの。
だいたい、アンタprocfsとネットワークしか読んでないならカーネル屋としては全然駆け出しやんけ。

最近のLinuxでごろごろ変わっているエンタープライズ向けのスケーラビリティー向上パッチに追従できてナンボやで。


閑話休題

ところで、しょーもない不具合が長年放置され続けるってケースはオイラも結構実体験があったりする。
しょーもなさすぎるから、みんなが「ま、いっか」モードになってしまうわけだな。

具体例を一つ。

えーと、UNIXなタイマーってのはとっても貧弱な機能しかAPIとして提供してないので
大規模開発になるとすぐにSIGALRMの取り合いになってしまうという根本的に間違って仕様になっています。

んで、普通はタイマーを管理するサブシステムやらスレッドやらを作るのだが、当時オイラが関わっていた
プロジェクトでは10msの精度が必要だったのでタイマー担当者が以下のようなスレッドを作ったのだな

	while(1){
usleep(10 * 1000);
for(elem=list_head(); elem; elem=elem->next){
elem->remain -= (10 * 1000);
if( elem->remain == 0 ){
/* timer fired */
elem->func( elem->arg );
}
}
}


ま、エラー処理とか大幅に省略してあるけど、雰囲気は伝わると思う。

で、動かしてみるとなぜかタイマーがかっきり2倍近く狂ってしまう。
多少の誤差は覚悟していたが、なんで2倍やねんと。まあ、そういう話になってだな。

ソースを見てみたんよ。


で、出てきたのは以下(当時のソースはもうないから、lxr.linux.no の2.4.28のソースより引用してる)

linux/kernel/timer.c より
836 asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
837 {
838 struct timespec t;
839 unsigned long expire;
840
(中略)
860
861 expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
862



linux/include/linux/time.h より
32 timespec_to_jiffies(struct timespec *value)
33 {
34 unsigned long sec = value->tv_sec;
35 long nsec = value->tv_nsec;
36
37 if (sec >= (MAX_JIFFY_OFFSET / HZ))
38 return MAX_JIFFY_OFFSET;
39 nsec += 1000000000L / HZ - 1;
40 nsec /= 1000000000L / HZ;
41 return HZ * sec + nsec;
42 }


見て分かるように、時間をjiffiesに変換する処理で端数切り上げ
(当時はカーネルタイマが100Hzなので10ms単位)
してるのに、呼び出し側でさらに1足している。

つまり、usleep(0)は本当に0と解釈するけど、usleep(10 * 1000)は内部でusleep(20 * 1000)にされてしまっていたわけ。

うーん、ugly


一瞬パッチを作ろうかとも思ったが、いつものように「それが仕様だ」「usleepは引数以上の時間寝ることを禁止していない」
「今あるアプリが誤動作するかもしれない」etc.. と返ってくる返答が容易に想像できたのでやめた。

んで結局、タイマーサブシステムを書き直して対処しましたとさ。


ま、この程度の「うがーーー、なんだこのuglyな仕様はーーーー!!!」と叫んで初めて一人前って気もする。
Linuxの場合。昔からすんげぇ癖が強いから。



で、ここでさらに話を変えて
この話に言及していたブログでこんなのを見つけました。

でいずおぶぱーがとりー

「LinuxのOSコードを読めるようになれば、イロイロわかるよ~。コツさえ掴めばなんとかなるよ。」
ッて話。
にしても、Cを知らない俺には敷居高いと思う。だから、とりあえず関連有る連載が始まった日経Linuxでも立ち読みしてみるかな。




おほほほ。
C言語なんてカーネルを読んで勉強するものですわよ。

実際オイラは、情報系の学校とか出てないのでC言語はK&R本と、日本橋で買ってきたFreeBSD2.2 のCDのソースコードで
覚えましたわよ。

といっても、カーネルをいきなり理解できるはずもなく、半分以上理解できなかったが、データ構造の作り方の定石とかが
いきなり学べたのは本当にうれしかった。
たぶん、僕はカーネルを読んでC言語を覚えた最後の世代だと思う。同年代でそういう話あんまり聞かないし。

さらに言うとUNIXカーネルの動きがちゃんと理解できたと確信できたのは、

Haskellを勉強するためにPugsのソースを読むというのは、Cの勉強をするためにUnixのカーネルの読むようなものだ。いいねいいね、この主客転倒ぶり。*1

*1:Lionsの本(Lions’ Commentary on UNIX)はCのいい教科書でもある。 Cでどのように表現するかという勉強になるしね。



と、未来のいつかの日記でもオススメされている
Lions本を読破した後だったりする。
まじでいい本です。

僕はLinux 0.9 とかを読むより、こっちをすすめるな。
x86はカーネルの本筋じゃないところでやたら複雑だから、途中で心が折れる気がする。
はじめの一歩にぶん殴られたかのような衝撃が襲うものな。 > Linuxのブートまわり



どうも、話が脱線してしまった。
結局いいたかったのは

・Linuxはそんなにバグバグじゃないよ。コードの質たかいよ
・でもuglyな仕様は、すごいたくさんあるよ。そこはuglyさ加減を楽しもうよ
・C言語できなくても気にすることないよ。カーネル読んでいけばそのうち覚わるから
・赤松ナントカはシッタカ・うそつき

って事ぐらいか


そして、まとまらないままに、了


追記:
上であげたusleepの問題は2.6系列では問題ない。
なぜならjiffiesが1024になったときに問題自体が自然消滅してるから。
1ms単位の精度だと、どうせ元から全然保障できてないので
(精度が細かすぎてちょっと割り込み入っただけで崩れまくる)
1msずれるぐらい、気にならない。というか気にしてられない

関連記事
linux | 【2006-04-08(Sat) 19:05:44】 | Trackback:(2) | Comments:(8)

友達が漫画を出しました その2 このエントリーをはてなブックマークに追加

前回紹介した友達漫画だが、ひとつ面白い特徴がある。
どうもゲームの原作者が この漫画家のファンだったらしく 原作者によるやたら大量の解説文がついている。

量が多すぎて巻末に収まりきらなくなったらしく、各話が終わるたびに濃ゆいヲタ解説文が始まるので漫画を楽しむ本か解説を楽しむ本か微妙な位置づけになっている有様。



さすがご自身が日記

 3月25日発売予定の磨伸映一郎作品集「月の彼方、永遠の眼鏡」にバカみたいな量の寄稿文を送りつけました。でもあれぐらいやらないと磨伸映一郎の波に呑まれちゃうんだよ! 磨伸氏のアンソロ漫画は、ほら、アレだ、ニトロ(薬)みたいなもんだから。我こそ重度のオタクなり、なんて自覚のある方は是非読んでみてほしい……!



と豪語するだけの事はありますな。



友人のmixi日記を読むと

ちなみにもう
http://www.typemoon.org/bbb/diary/
で御本人が語ってるのでバレるも何もないんですが、
解説は奈須きのこさんが立候補して下さいました!
ありがたい事ですヨ!!
何気に「月姫」「メルブラ」の製作裏話も満載で
読んでるこっちが嬉しくなりますヨ!



つーかメルブラのシナリオが●●●シナリオノーマルED後という
設定だとか「次のメルブラの追加ヒロインが凄い」とか
極秘情報満載気味なので読んでるコッチが『いいのか!?』って
感じですよ?




どうも原作者が自分から立候補してきたらしい。ほほー





で、これを見ていてふと思い出したのが結城ブログのこの文章

長男「本を読む楽しさっていうのは、別の世界に行くおもしろさだね」
私「なになに、何だかすごいね。まさにその通りだと思う。別世界に行くことがファンタジーの本質だからね」
長男「たとえばナルニアを読む人はナルニアという世界に行く」
私「そうだね。ところで、そこに多重構造があるのは知っている?」
長男「どゆこと?」
私「登場人物と読んでいる私たちのことを考えてみると…」
長男「わかった! こうだね。中に入って、さらに中に入る」




パロディ漫画ってのは、原作への言及とあたらしい表現がキモなわけで、
  原作ゲームを言及するパロディ漫画
⇒パロディ漫画を言及する原作者による解説文
⇒原作者の解説文に言及する漫画家の日記
⇒漫画家の日記に言及するただの友達(おれ)
⇒ただの友達のブログを読んでいる読者(あなた)


と、かなり何十にも多重構造のテクストを構成している。うーん文学的に構造を理解しようとすると極めて興味深い。




それはさておき、こんだけ大量のヲタ解説文がありながらも、まだ半分以上のネタが未解説ってどういう事ですか?!
てか、漫画でほぼ全ての台詞にネタが仕込んであるって正気か?!
ちょ。。それどこのパズルゲーム(ry


あー、映画とかアニメとかゲームとかのネタに素養がある人はぜひドウゾ(天使のような邪悪な笑みをうかべつつ)


まったく近頃の右翼は!
右翼だってヲタクに走る時代なんですから! ランキング!



関連記事
書評(まんが) | 【2006-04-08(Sat) 04:15:26】 | Trackback:(0) | Comments:(0)

友達が漫画を出しました このエントリーをはてなブックマークに追加

私事になりますが、わたくし最近、「汝は人狼なりや?」と小一時間問い詰めたい。というチャットベースの人間vs人間で楽しむ推理ゲームを毎週遊んでいます。

山奥の山荘で連続殺人犯をくびり殺さないと村人は死ぬ。しかし証拠は0なので、基本的に相手の揚げ足をとるしか推理のしようがない。いきおい無罪の人が次々死んでいく。
村人は全滅するまえに犯人を見つけることができるか!

まあそんなゲームです。

新規参加者はいつでも大募集中ですので興味のあるかたはぜひどうぞ。

ルールがよく分からない方への解説はこちら↓

①「接触編」<参加する為に知る事>
http://mixi.jp/view_diary.pl?id=47488594&owner_id=104959
②「発動編」<実際に遊ぶ為に知る事>
http://mixi.jp/view_diary.pl?id=47497682&owner_id=104959
③「鳳凰編」<知ってて得する応用編>
http://mixi.jp/view_diary.pl?id=47508081&owner_id=104959


mixi IDを持ってない人は管理人のみが見えるモードコメントでメアド教えてくれれば招待いたしますよん。
注: 招待にはメールアドレスが必要です。プライバシーとか気になる人は、どこかでフリーメールアドレスか何かを作ってくださいませ

ま、それはさておき。


それでですね。その参加者の一人がどうも漫画家さんであることが最近発覚いたしましてですね。
初単行本を出したというので買ってみたわけですよ。友達として




マイミク登録を拒否られるぐらい薄い友情ですが!
友達として!


これが予想外(失礼)にめちゃくちゃ面白い!

ゲームのパロディ漫画になっていて、そういう系統の漫画をあつめたアンソロジー作品集から一人の作品だけをピックアップした総集編という体裁なのだが。

なんというか、超えちゃってるね。
原作をあまり理解していない僕がいうのもなんだが、これ、パロディである必要ないよ。

主人公がコタツにずーーーと籠もっているまま話終了。完。とか
ヒロインがずーーと公衆TOTOに籠もっているまま話終了。完。とか

とくに2つ目は原作付きマンガとしてはどうなのよ?(゚Д゚;≡;゚Д゚)



さすが、本人が表紙にて

あふれ出す眼鏡愛が止まらない、超問題作品集、ここに



と豪語するだけのことはあるわ。


負けるときになぜか3人乗り自転車で逃げていくヒロイン
(背景に「おしおきだべー」の掛け声付き)

とか

最終的にはPTAと全面戦争する気か、このハレンチな学園めー!!

とか

やばいネタ満載。
てか一番笑ったのは後書きのこの文章

「お、おおお・・・」
ご本人からのメールに添付された文章を読了し、思わず心からの声が漏れた (中略)
し、「しみるぅ」に対して「ホルヘ・バカ」を返せる人なんて何年ぶりだろう・・・




何年もの間、誰にも通じなかったネタを商業誌で炸裂させないでいただきたい


アナタに複線ドリフトーーーー!!! と叫んでしまった某執事漫画 in サンデーを笑う資格はない。


ps 最終的には666の数字とともに復活した第六天魔王信長を自らの命とひきかえに聖剣エクスカリバーで封印して王子の涙で命を取り戻す映画とくしゃみで主人公が爆死する映画の正体をだれか教えて!


ps2 いまぐぐった所、作品のまっとうなレビューとしては以下のURLがオススメのようです。

レビログ::月の彼方、永遠の眼鏡 TYPE-MOON作品集 奈須きのこ解説付き




複線ドリフト
ドリフトしないと曲がれない線路ってどうなのよ?! ランキング!



関連記事
書評(まんが) | 【2006-04-08(Sat) 03:22:30】 | Trackback:(0) | Comments:(7)

悲しい このエントリーをはてなブックマークに追加

Life is beautiful様より

 典型的な例が、日本の衛星放送のデータ配信に使われているマークアップ言語 BML (Broadcast Markup Lanugage)。家電業界が、パソコン業界の進出を阻むためにあえてHTMLとは異なるものにしたことは、知る人は知る事実である。



当時の事情の一端なりとも知るものとして、この決め付け記事は悲しい。
当時から事情を知らない人間がシッタカで広めたこの類のデマはたくさんあったので、まあしかたない面もあるのだが、こうも断定口調で書かれると。。。

今から振り返ってみると色々と問題のある規格ではあるのだが、囲い込みだけを目的とするのであれば当初の予定通りMHEG(って知ってる?MPEGグループが策定していたハイパーテキスト記述方式だよ。コンテンツが目玉が飛び出るぐらいとんでもなく作りにくいが家電を作るのは楽な仕様だった)でデジタル放送すればよかったんだよ。

なにも、規格がふらふらと揺れ動いていたXHTMLやらCSSやらを取り込む必要もDOMとか仕様に入れ込んで端末側の実装を超複雑にさせる必要もなかった。

結局、現実と折り合いをつける過程で、かなり色々とあったのだが、だからと言って、データ放送開始を5年遅らせればもっといいものが出来た。みたいな議論は意味がない。

すくなくとも規格の策定は参入障壁を作ろう。という雰囲気では進まなかったし(むしろWeb連携は重要課題だったと記憶している)
関係者は限られた時間内で、いいものにすべく最善(いや120%の)努力をしたと思う。


・・・・


・・・・・・・・・



誰が悪いかと言われたら、試験放送開始1年まえに、いきなり方式をXMLにしたいから規格を今から作ろう。とか寝言を言い出した郵政省なんだろうな。やっぱり

対応LSIを作るのも、規格を作るのも普通そんな短期間で出来ませんから!
まったく役人は。まったく


-----------
と全然証拠資料をあげない感情論をぶちまけてみる



関連記事
テクノロジー | 【2006-04-07(Fri) 14:29:08】 | Trackback:(1) | Comments:(3)

read で読み出すのと mmap で叩いていくのとどちらが速いか このエントリーをはてなブックマークに追加

g新部さんのブログより

ユーザ空間のアドレスにアクセスするところ、例えば read(2) から copy_to_user で書かれますが、これって copy が起こるから遅いような気がします?

mmap したアドレスを deref して page fault から page cache にあるのを張り付けて TLB に load してもらうほうが速そうな感じもしますか。

でも、素直に copy の方が速いかもしれないです。同一のバッファでアドレスを使いまわして TLB miss を起こさないようにして回すとすると。

mmap でやっていくとページごとに起こる TLB miss の処理のオーバヘッドが馬鹿にならなくなるでしょう。



むーん、これはちょっと違うのでは。
readでユーザ空間では同一バッファを使いまわしても、カーネルの読み先のページキャッシュはどんどんTLB missするわけで、そこに優劣は生じない。

だからコピーの分だけ mmapが勝つはず。

とゆーか、オイラの知ってるシステムでは組み込みでもサーバーでもmmapが勝つ。
mmapが負けるケースを教えてほしいっす(と、結論を人まかせにする為にトラックバックしてみる)




関連記事
linux | 【2006-04-07(Fri) 13:26:23】 | Trackback:(0) | Comments:(6)

ユダ裏切ってない?1700年前の「福音書」写本解読 このエントリーをはてなブックマークに追加

ネタ元は読売新聞の記事

なんというか。。。

偏向とはいわんまでも情報の取捨選択がずるいな。

Wikipedeaの福音書の項をまず読んで欲しいのだが、

福音書ってのは正典と外典があって、ユダの書は外典。
キリスト神学的にはもともと正統とは認めていない文書。

とか

それを言ったら福音書ってのは、基本的にキリストの直接の弟子が死に絶えたぐらいの時期に、そのへんの神学者が使徒の名前使って自分が聞いた口伝を正当化するために適当書いたもの。
本人が書いたものでも、誰かが編集チェックをしてから発表されたものでもない。
なので、正典も文章に間違い多数。

とか

ユダを裏切り者じゃないとする異端は昔からあったけど、一般的にはぜんぜん相手にされていない

とか、そういうが全然書いてないから、すごい大ニュースのように見えるけど、これってその道の研究者以外にはあんまり凄いニュースでもないようなぁ。。
とかとか


関連記事
雑談 | 【2006-04-07(Fri) 11:25:46】 | Trackback:(0) | Comments:(0)

Dell のアフィリエイト承認通知がいまさら来た このエントリーをはてなブックマークに追加

一ヶ月以上前に申し込んでいたデルのアフィリエイトの申請について、承認通知がいまさら来た。
相変わらず仕事が遅いのう。

てっきり却下をくらったと思ってすでに忘れていたよ。


ま、せっかくなのでうちのInspiron1300のレビューに宣伝貼っておく。
どうも人気機種らしく今もしょっちゅうGoogle様経由でレビューを見にお客が訪れるので。

なにか反響あったら、またレポートするつもり。
ではでは

関連記事
blog | 【2006-04-07(Fri) 09:40:48】 | Trackback:(0) | Comments:(0)

linuxの記事はつかれる このエントリーをはてなブックマークに追加

いやー、いつもの事ながら、Linuxの記事はものすごく間隔が空いてしまった。
申し訳ない。

理由はいくつかあるのだが、やっぱり書いていると色々調べたいことが出てきてしまうのが1つ(これ自体は自分への復習になるので悪いことではない)

とくに今回の記事は、本来ならgccのソースコードを調査のうえ事実を書くか、現在売っている数種類のコンパイラで生成されるコードを比較して、それを元に語るってのがあるべき態度だと思った。

でも、それは大変すぎるので、最終的には手抜きをすることを選択させていただいたが。

あと、もう一個壁があって、これが最大のものなんだけど、
Linuxの記事を書いていると、どうも頭が無意識のうちにマジメモードに切り替わってしまうらしく、ぜんぜんギャグが浮かんでこなくなる。
これは報酬をもらっていないネタBlogerとしては致命的だ。

ギャグもなしに、こんな長文かけるか!

↑ かなり間違ったイケン


実は技術的な知識はけっこうあったので、このブログを書き始めたころは、すらすらと文章が続くようならどっかの雑誌に売り込んでいっちょ記事でも書くかぁ
とか野心を持っていたのだが、おかげですっぱりさっぱり諦めた。

こんな締め切り守れない男に、商業誌は無理だよ。無理無理。





関連記事
雑談 | 【2006-04-06(Thu) 11:17:12】 | Trackback:(0) | Comments:(0)

シーケンスロック その5 volatileがダメな理由 このエントリーをはてなブックマークに追加

どもども。またまた間隔があいてしまいましたがシーケンスロックな話しの続きです。
前回の記事で坩堝さんから面白い指摘をうけたので今回は予定を変更してvolatileの話をしたいと思います。


retをvolatileにするだけではうまくいかないんですよね?
どういう風になるんだろ.




なるほど、たしかに世のC言語の参考書を見るとvolatileはある種の最適化を妨げる効果を持つと
されています。
これだけ見ると、volatileとつけるだけすべての最適化が無効になってうまく動きそうですね。
しかし、その理屈は微妙におかしいのである


多くの人が「ある種の」という言葉を拡大解釈しているがvolatileは本来スレッド同期に使えるようなシロモノではないのである。

つづきは、続きを読むからご覧ください。


あと、お願い。
今回の話は前提知識がいろいろとあるので、末尾のご参考にあげたURLを読んでから
読んでいただけるとうれしいっす。



そのりくつはおかしい
その理屈はおかしい! ランキング


“シーケンスロック その5 volatileがダメな理由”の続きを読む>>
関連記事
linux | 【2006-04-06(Thu) 11:06:13】 | Trackback:(0) | Comments:(3)

Linux: Documenting Memory Barriers このエントリーをはてなブックマークに追加

kerneltrapの記事より

カーネルのメモリバリアモデルについて、超力作ドキュメントが投稿されている。
とりたてて新しい情報はなさそうだが、Linuxのドキュメントとは思えないぐらい網羅的。

後でちゃんと読もう ← まだ読んでないのかよ

関連記事
linux | 【2006-04-06(Thu) 09:28:58】 | Trackback:(0) | Comments:(1)

Google AdSenseの精度を向上させる このエントリーをはてなブックマークに追加

このへんより抜粋


セクション ターゲットとは何ですか。また、実装方法を教えてください。

セクション ターゲットを使用すると、サイトのコンテンツと広告を照合する場合に、強調または無視すべきテキストや HTML コンテンツのセクションを Google に知らせて、 広告表示の関連性における精度をより向上させることができます。 セクション ターゲットの実装は、HTML を熟知したお客様にのみお勧めしています。

セクション ターゲットを実装するには、1 組の HTML コメント タグをコードに追加する必要があります。 これらのタグは、広告表示で強調または無視するセクションの前後に挿入します。

ページ内のセクションを強調するための HTML タグは次の形式となります。

<!-- google_ad_section_start -->

<!-- google_ad_section_end -->

開始タグに (weight=ignore) を追加して、無視したいセクションを指定することもできます。

<!-- google_ad_section_start(weight=ignore) -->



というわけで、サイドバーやらなんやらは軒並み ignore にしてやった。
これで余分な情報はすっきり無視されるわけですね。


でも、体感的にはあんまり差がないような・・・



そこじゃねーだろ!
無視ですか! ランキング!


関連記事
blog | 【2006-04-03(Mon) 19:53:39】 | Trackback:(0) | Comments:(0)

glibcを一部分だけビルド このエントリーをはてなブックマークに追加

鮎田屋ドットコムというサイトこのへんから


GLIBC で、ld.so だけコンパイルする(Sun Sep 22 2002)
備忘録として。これができんと、オチオチとデバッグコードもはさめない。

1.まず、普通にビルド(configure & make)する
2."cd elf" で ELF ディレクトリへ
3."OBJDIR=../build-i386-linux" で、オブジェクトの入るディレクトリを指定
4."make objdir=$OBJDIR $OBJDIR/elf/ld.so" でビルド
難解ホークス。



いちいち全ビルドなんてやってられないっす


追記: さっきやってみたらRHEL4では出来なかった。元々の記事が2002年のものなので、glibcのバージョンがだいぶ変わっているのでそのせいかも


関連記事
プログラミング | 【2006-04-03(Mon) 06:16:35】 | Trackback:(0) | Comments:(0)

dlmallocとglibc mallocで性能が大幅に異なることがあるらしい このエントリーをはてなブックマークに追加

いやなブログさんのDoug Lea の malloc (dlmalloc)というエントリから

くだんの new しまくるプログラムを LD_PRELOAD=./libdlmalloc.so で実行したところ、4.5秒かかっていた処理時間が 3.6秒になりました。20% の高速化です。ltrace -e malloc で調べたところ malloc の呼び出し回数は 1,376,066 回でした。今回の実験では、 dlmalloc は GLIBC の malloc よりもかなり高速という結果が出ました。手元の環境は GLIBC 2.3.2 です。



うーむ、信じられない結果(疑っているのではなく驚異的ということね)
glibc mallocはDoug Lea mallocほぼそのままなんで、20%も性能が異なるなんて普通ありえないんですよ。

そのつかったテストプログラム見たいかも。。

glibcで追加された最適化って少ないから、
たぶん、Arenaまわりの排他がごにょごにょとか、
malloc - free - malloc - free - malloc
と繰り返すプログラム用に追加されたキャッシュ機構が裏目にでているとかそんなんなのかな



そんなの計らないでぇぇ
そんなモノを測定するなんて! ランキング!


関連記事
プログラミング | 【2006-04-03(Mon) 05:37:42】 | Trackback:(1) | Comments:(3)
次のページ
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。