自作OS
gcc -c -O0 -fPIE -m32 -mgeneral-regs-only プログラム名.c
objcopy --only-section=.text --output-target binary プログラム名.o filebin
これでRAWバイナリにして実行しています。
gccのコンパイル時に-fpieオプションを付ければ"位置独立コード"を生成できるようです。
どこのアドレスから展開しても問題なく動かせるってことですね
では、・・・
sample_function(){} main(){ int * p = 0x00000000; void (*func_p)() = sample_function; //32bit環境を想定 int dummy = func_p; *p = dummy; }
(コード正しいかわからないけど・・・)
メモリアドレス0x00000000にsample_function関数のアドレスを格納するプログラムです。
で、質問なのですが
どこのアドレスにマップされた場合でも
0x0000000に正しくsample_function関数のアドレスが格納されるのでしょうか?
仮に正しく格納されないとして
正しく格納させる方法とかはないでしょうか?
質問内容おかしかったらすみません
わからないのでお願いします。
> gccのコンパイル時に-fpieオプションを付ければ"位置独立コード"を生成できるようです。
-fpic または -fPIC のことでしょうか? (position independent code)
-fpie があるのなら、その説明のある URL を示してください。
調べたところ fpieは位置独立実行形式 fpicが位置独立コードみたいですね。
http://0xcc.net/blog/archives/000109.html
0. 自作OS上でのことだというなら、その条件を問題に含めてください。
自作OSとなると、それがどの程度動いているか、そっちの問題じゃないのかと思ってしまうので、
1. 「0番地に、関数アドレスを書く」プログラムですが、そのような制約が無いプログラムなら動作するのですか。とにかくなんでも良いので、コンパイルしたコードが動作することを確認できているのか、ということです。
2.0番地に(アドレスではなく)普通の整数値なら書けてますか。
3.よりによって0番地に書く理由・目的は何ですか。
4.-fpie 位置独立実行形式でなければならない理由・目的は何ですか。
割込みベクタをセットするためであれば位置独立コードは必須条件ではないです。それとも割込みハンドラが何番地に配置されるか、リンク時に決まらない=実行時でないとアドレスが決まらない、という事情がありますか。
以上に対する答えも問題文に追加すれば結構。
[0]
追記いたします
[1]
動いているのかさえ不明です。
[2]
そのままの意味ですか?
それなら書けています。(なので、関数の配置アドレスを固定すれば
任意のアドレスにその関数のアドレスを格納するってのはできるが
柔軟性がないからやりたくない。)
[3]
特に理由はありません。
X86プロテクトモードなら0x0000番地は勝手に使ってもいい(・・・はず)
[4]
前提として
ブートローダーをアセンブリ(NASM)で、
カーネルをcで書いています。
両者のリンクのさせかたがわからないので苦肉の策として、
cで書かれたカーネルをオブジェクトファイルに変更したあとOBJCOPYで
RAWバイナリにし、
それをブートローダーにくっつけることで
ブートローダーとカーネルを繋いでいます。
-fpie指定しないで上記の手順でRAWバイナリを生成した場合コードがうまく動きません。
https://teratail.com/questions/302484
>リンク時に決まらない=実行時でないとアドレスが決まらない、という事情がありますか。
リンクしていません。(ライブラリは使っていない)
ただ、どこのメモリアドレスからこのプログラムを配置するかは決まっています。
(-FPIEオプションをつけずにオブジェクトファイルを生成し
そこからRAWバイナリ形式に変換した場合
そのプログラムはどこのアドレスから動くことを前提に作られているのか全くわからない。
だから、とりあえずどこでも動くように-FPIEオプションをつけています。)
以上の状況を整理して、このスレッドに書くのではなく、質問文に追加してください。
> 動いているのかさえ不明です
これは質問の意図を誤解されたかな。だってyoutubeにアップした動画は「ともかく何かは動いている」んでしょ。
すみません まず、"そのような制約"とは何のことですか?
そのような制約とは「0番地に、関数アドレスを書く事」という意味でかきました。
ともかく動いているか?という問いです。
割り込み設定の中で
IDTに割り込みハンドラのアドレスを格納する必要があります。
で、そのIDTの開始アドレスが0番地です。
”0番地に、関数アドレスを書く事”をしないと割り込み設定ができないです。
(フォーマット的に正確にはそのまま0番地に書き込むわけではないけど)