nm はシンボルの値を示します。ライブラリまたはオブジェクト ファイル内の一部のシンボルは、まだ値が与えられていないという理由だけでゼロとして表示される場合があります。リンク時に実際の値を取得します。
一部のシンボルはコード シンボルであり、一部はデータなどです。シンボル値をリンクする前は、多くの場合、それが存在するセクション内のオフセットです。
16 進数は、シンボルが見つかるオブジェクト ファイルへのメモリ オフセットです。文字通り、オブジェクト コードのバイト数です。
その値は、リンカーがシンボルの値を見つけてコピーを作成するために使用されます。 -S
を追加すると、一般的にどのようにレイアウトされているかを確認できます nm
へのオプション 、各シンボルの値のサイズが表示されます。
これは私が C で書いたコードのスニペットです:
#include
#include
void foo();
int main(int argc, char* argv[]) {
foo();
}
void foo() {
printf("Foo bar baz!");
}
gcc -c foo.c
を実行しました そのコードで。これが nm foo.o
です 表示:
000000000000001b T foo 0000000000000000 T main U printf
この例では、Ubuntu Linux 64 ビットを実行しています。そのため、ここでは 8 桁の 16 進数が 16 桁になっています。 :-)
表示される 16 進数は、.text.
の先頭を基準とした、オブジェクト ファイル内の問題のコードのアドレスです。 セクション。 (0x0 で始まるオブジェクト ファイルのセクションをアドレス指定すると仮定します)。 objdump -td foo.o
を実行した場合 、出力に次のように表示されます:
Disassembly of section .text: 0000000000000000 : 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 83 ec 10 sub $0x10,%rsp 8: 89 7d fc mov %edi,-0x4(%rbp) b: 48 89 75 f0 mov %rsi,-0x10(%rbp) f: b8 00 00 00 00 mov $0x0,%eax 14: e8 00 00 00 00 callq 19 19: c9 leaveq 1a: c3 retq 000000000000001b : 1b: 55 push %rbp 1c: 48 89 e5 mov %rsp,%rbp 1f: b8 00 00 00 00 mov $0x0,%eax 24: 48 89 c7 mov %rax,%rdi 27: b8 00 00 00 00 mov $0x0,%eax 2c: e8 00 00 00 00 callq 31 31: c9 leaveq 32: c3 retq
これらの 2 つのシンボルは、nm
のシンボル テーブルで見たエントリと一致していることに注意してください。 .このオブジェクト ファイルを他のオブジェクト ファイルにリンクすると、これらのアドレスが変更される可能性があることに注意してください。また、callq
ということを念頭に置いてください。 at 0x2c は、このファイルをシステムが提供する libc にリンクすると変更されます。これは現在、printf への不完全な呼び出しであるためです (現時点ではどこにあるのかわかりません)。
あなたの mylib.a
について 、ここでさらに進んでいます。あなたが持っているファイルはアーカイブです。 複数含まれています オブジェクト ファイルで、それぞれに独自のテキスト セグメントがあります。例として、これは私のボックスの /usr/lib/libm.a に対する nm の一部です。
e_sinh.o: 0000000000000000 r .LC0 0000000000000008 r .LC1 0000000000000010 r .LC2 0000000000000018 r .LC3 0000000000000000 r .LC4 U __expm1 U __ieee754_exp 0000000000000000 T __ieee754_sinh e_sqrt.o: 0000000000000000 T __ieee754_sqrt e_gamma_r.o: 0000000000000000 r .LC0 U __ieee754_exp 0000000000000000 T __ieee754_gamma_r U __ieee754_lgamma_r U __rint
複数のテキスト セグメント エントリが表示されます -- 2 列目の T で示されますが、アドレス 0x0 にありますが、個々のファイルには のみ があります。 0x0 に 1 つのテキスト セグメント シンボル。
複数のシンボルが同じアドレスにある個々のファイルについては、そう おそらく可能です。結局のところ、データのチャンクの場所とサイズを決定するために使用されるテーブルのエントリにすぎません。しかし、私は確かに知りません。セクションの同じ部分を参照する複数のシンボルを見たことがありません。これについて私よりも多くの知識を持っている人なら誰でも参加できます. :-)
これが少しでも役に立てば幸いです。