glibcをデバッグしてみよう2

前回glibcを取ってきてそれをコンパイルしてみました。

そしてそのあと簡単なテストを作ってそのライブラリーをリンクしました。

今回はglibcの中に簡単な関数を作ってそれをgdbでデバッグしてみます。

mallocにhelloworldという関数を作ってみましょう。

glibcに関数を作るにはまずVersionsというファイルにその名前を書きます。

mallocフォルダーの中のVersionsにhelloworldを入れましょう。

malloc/Versions

    ....
    # f*
    free;
    free2;
    # h*
    helloworld;

    # m*
    mallinfo; malloc;
    ....


次にmalloc.cの中にhelloworldを書いていきます。

malloc/malloc.c

int __libc_helloworld (void)
{
 return 1;
}

これだけではダメでhidden_protoとhidden_defに登録します。

malloc/malloc.c

int     __libc_helloworld(void);
libc_hidden_proto (__libc_helloworld)

.....

libc_hidden_def (__libc_helloworld)

そして最後にこの関数にaliasを作ります。

malloc/malloc.c

strong_alias (__libc_helloworld, __helloworld) strong_alias (__helloworld, helloworld)

これでhelloworldがmallocの中に追加されました。 コンパイルしてみましょう。 今回はデバッグのオプションをつけてコンパイルします。

~/download/glibc-2.21/configure --prefix=/usr --enable-debug CFLAGS='-g -O2'

makeしてできたlibc.aにhelloworldが入っているか確かめてみましょう。

nm libc.a | grep helloworld
00000000000048c0 T __helloworld
00000000000048c0 T __libc_helloworld
00000000000048c0 T helloworld

入っています。ではこのhelloworldを呼び出してみましょう。

extern int helloworld (void);
void * __gcc_personality_v0=0;
void * _Unwind_GetIP=0;
void * _Unwind_GetGR=0;
void * _Unwind_GetCFA=0;
void * _Unwind_Backtrace=0;
void * _Unwind_Resume =0; 
void * __divdi3=0;
void * __moddi3=0;
int main(){
  int res;
  res = helloworld();
  return 0;
}

前回のtest.cをちょっと変更しました。 helloworldを呼んでいるだけです。このtest.cを今コンパイルしたlibc.aとリンクしてコンパイルしてみましょう。 簡単にするためbuildディレクトリにあるlibc.aをtest.cのあるディレクトリにコピーしておきます。

cc -g -o test test.c -L./ -lc

コンパイルできたらgdbで実行してみましょう。

gdb test

ブレークポイントをhelloworldにおいてrunします。

b helloworld
r

helloworldが1を返すのが確認できました。 いよいよglibcデバッグのお膳が整いました。では次回まで