Symbol in ld

リンカで定義したシンボルの値をC言語から使う場合、

extern int SYMBOL;
int x = (int)&SYMBOL;

のように、シンボルのアドレスとして取得する。これは少し分かりにくい。

C言語でグローバル変数int foo = 1000を定義したとき、シンボルテーブルに"foo"が追加され、シンボルはとあるメモリ番地のアドレスに紐づけられる。プログラムが実行されるとき、値1000がその番地に展開される。コンパイルした時点でシンボル"foo"のメモリ番地は決まっていない。これを決めるのはリンカの仕事である。

int *p = &fooはシンボルテーブルから"foo"を探し、リンカが決めたメモリ番地を取得する。int a = fooと書いた場合はシンボルテーブルから"foo"を探し、リンカが決めたメモリ番地を参照し、さらにそのメモリの値を読みだす。

リンカでシンボルbar = 1000を定義したとき、シンボルテーブルに"bar"が追加される。ただしメモリは確保されない。値1000はシンボルに対応する値として固定される。シンボルの値は例外なく全てアドレスである、と思っておくくらいでもいいのかもしれない。

ということで、リンカで定義した値は、C言語からはアドレスとして見える。シンボルテーブルを参照するためにextern int SYMBOLと書いて、その値を&SYMBOLで取り出す。あたかも変数があるかのようだが、この変数は存在しない。当然、この変数を読み書きしてはいけない。