質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
アーキテクチャ

アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

Q&A

解決済

1回答

5597閲覧

GOTとPLTについて確認です。

strike1217

総合スコア651

アーキテクチャ

アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

0グッド

0クリップ

投稿2016/09/15 10:12

GOTとpltについて確認したいことがあるんですが・・・

GOTは共有ライブラリの関数群のポインタ(アドレス)を示している。
→ 共有ライブラリがメモリ上に展開された時のライブラリが持つ仮想メモリのアドレス。

pltはGOTのアドレスと1つのプロセスのアドレスを紐付けるためのテーブル。
GOTを参照してプロセスへそのアドレスを提供している。
個々のプロセスが持つテーブルである。

と理解しているのですが・・・
間違っていますか??

もしかして逆かなぁ・・・と思ったのですが、どうでしょうか?

実験をしてみました。
以下のはgccでコンパイルした実行ファイルを逆アセンブルしたものです。
printf()@pltです

4003e0: ff 25 12 05 20 00 jmpq *0x200512(%rip) # 6008f8 <GLOBAL_OFFSET_TABLE+0x18>
4003e6: 68 00 00 00 00 pushq $0x0
4003eb: e9 e0 ff ff ff jmpq 4003d0 <_init+0x28>

jmpq *0x200512(%rip) のところなのですが、プログラムカウンタを 0x200512にジャンプさせていると思ったのですが、実際には 0x6008f8のアドレスに飛んでいました。
なぜですか??
この0x200512とは何者ですの?

0x6008f8はGOTのアドレスで間違いなさそうなのですが・・・
どなたか教えてください。

またPICとはpltのコードの事ですよね??

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

jmpq *0x200512(%rip) のところなのですが、プログラムカウンタを 0x200512にジャンプさせていると思ったのですが、実際には 0x6008f8のアドレスに飛んでいました。

なぜですか??
この0x200512とは何者ですの?

オフセット(レジスタ名)の記法はアセンブラコードの読み方の基本中の基本です。0x200512(%rip) は %rip レジスタの内容に 0x200512 を足した値という意味です。* がついているので、そのアドレスに入ってる値にジャンプします。
%rip はいわゆる instruction pointer で現在実行中のプログラムの番地を指しています。つまり、 .plt の命令が置かれている番地になります。 %rip を参照するのはそのコードを Position Independent にするためです。

a.out や libxxx.so には命令列は入っていますが、ダイナミックリンクで実行される場合は、その命令がどの番地に配置されても動かなければなりません。考えてみてください。 liba.so が作られたとき、0x100 番地にロードされる前提でコンパイルされたとします。別の場所でコンパイルされた libb.so も 0x100 番地にロードされる前提で作られてしまうと、 a.out から両方を呼び出そうとすると、番地が競合してできません。したがって、ダイナミックリンクされるプログラムはどの番地にロードされてもいいように作られているのです。これを再配置可能(relocatable)といいます。

.plt は .got の中を参照して動きますが、そのときに .plt がメモリ上に配置される番地から .got がメモリ上に配置される番地へのオフセットは常に一定のオフセットとなるように配置されます。そのオフセットがこの場合、0x200512です。%rip を参照することで、 .plt がメモリ上の何番地に配置されていようが、現在の番地を取得することができます。そこからのオフセットで .got を参照するので、このプログラムは何番地に配置されていても正しく動作するわけです。

またPICとはpltのコードの事ですよね??

違います。 PIC は Position Independent Code の略で、 PLT のように相対アドレッシングのみで構成されていていて、再配置可能なコードのことを指しています。ダイナミックリンクに使うオブジェクトでは text セグメントもコンパイラが PIC で出力しています。

投稿2016/09/15 12:50

編集2016/09/16 01:57
mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2016/09/16 01:21

ありがとうございます。
strike1217

2016/09/16 01:37

gotには共有ライブラリの物理アドレスが入っているんですか?? 論理アドレスですか? 物理でないとアクセスできないですよね?
mit0223

2016/09/16 01:47

基本的にユーザ空間のプログラムが扱うのは論理アドレスです。私が回答の中で「番地」と呼んでるのはすべて論理アドレスです。論理アドレスから物理アドレスへの変換はハードウェアで行われます。
strike1217

2016/09/16 02:00

MMUですね。 ありがとうございます。
strike1217

2016/09/16 02:55

共有ライブラリのフォーマットもELFで統一されているのでしょうか?
strike1217

2016/09/16 03:02

あ、すいません。 もう一点 共有ライブラリがメモリ上に展開されるタイミングはいつですか?? 複数のプロセスが同じライブラリを共有するということはシステムが持つプロセスもライブラリにアクセスすることがあるわけですよね? ということはOSが起動した段階で、共有ライブラリもメモリ上に展開しておく必要がありそうなんですが・・・ OSが起動したと同時に展開されるんですかね?
mit0223

2016/09/16 08:54

共有ライブラリのフォーマットもELFです。共有ライブラリはプロセスの起動時にオンデマンドにロードされます。しかし、 init から参照される共有ライブラリは、OSの起動時にロードされて最後までいるでしょうね。ldd /sbin/init とかってやると、init が参照している共有ライブラリの一覧を見ることができます。
strike1217

2016/09/17 01:33

ありがとうございます。 質問が多くてすいません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問