2021-06-23
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
で取り出す。あたかも変数があるかのようだが、この変数は存在しない。当然、この変数を読み書きしてはいけない。