« 2007年9月9日 - 2007年9月15日 | トップページ | 2007年11月4日 - 2007年11月10日 »

2007年10月 5日 (金)

シンボルテーブルのFUNCについて

naoyaさんのところで見かけて気になったので調べてみた。

などをみてみると、シンボルテーブルのTypeのFUNCはリンクの辺りで必要そう。

そこで、

int add(int x, int y)
{
    return x + y;
}

int sub(int x, int y)
{
    return x - y;
}

をfunc.cとして作成して、

$ gcc -S func.c

としてアセンブリコードを作成。

.globl add
    .type   add, @function

となっているところを

,globl add
    .type    add, @notype

と変更する。それから共有ライブラリを作成する。共有ライブラリを参考に

$ gcc -fPIC -g -c -Wall func.s
$ gcc -shared -Wl,-soname,libfunc.so.1 -o libfunc.so.1.0.1 func.o -lc
$ ln -s libfunc.so.1.0.1 libfunc.so.1
$ ln -s libfunc.so.1.0.1 libfunc.so

一応共有ライブラリのaddの属性の確認をする。

$ readelf -s libfunc.so | grep add
     6: 000003cc    11 NOTYPE  GLOBAL DEFAULT   10 add
    49: 000003cc    11 NOTYPE  GLOBAL DEFAULT   10 add

確かにNOTYPEとなっています。
次にこの共有ライブラリを使用するプログラムをmain.cとして作成します。

     1  #include <stdio.h>
     2
     3  int add(int, int);
     4  int sub(int, int);
     5
     6  int main()
     7  {
     8      int x, y;
     9
    10      x = 8;
    11      y = 4;
    12
    13      printf("%d\n", add(x, y));
    14      printf("%d\n", sub(x, y));
    15
    16      return 0;
    17  }

さて、ここからが本番です。

$ export LD_LIBRARY_PATH=.
$ gcc main.c -L. -lfunc
$ ./a.out
セグメンテーション違反です

となりました。main.cのaddをしている行を消して、

$ gcc main.c -L. -lfunc
$ ./a.out
4

となりsubの実行結果が表示されます。なので、シンボルテーブルのTypeのFUNCは動的リンクに必要にであることが分かりました。mainにFUNCをつける必要はないみたいですね。FUNCじゃなくてEXPO(export)とかの方が分かりやすかったりするのかなとか思ったりしました。

| | コメント (0) | トラックバック (1)

« 2007年9月9日 - 2007年9月15日 | トップページ | 2007年11月4日 - 2007年11月10日 »