April 2006

またしても自分用備忘録。
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




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

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

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


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


Rauru Blog様のエントリより


コメントがイカス!

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




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


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

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

そのソースじゃないだろう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
尊敬のまなざし・・凄いよ!素敵だよ!


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

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

こんなの
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 デスヨ!
そこで区切るか!?




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

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

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 }

いやなブログさんの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って意味わからんし
どうでしょ?



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

↑このページのトップヘ