Вот фрагмент кода, который я написал на 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-bit; Вот почему вы видите 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
Обратите внимание, что эти два символа совпадают с записями, которые мы видели в таблице символов из nm
. Не забывайте, что эти адреса могут измениться, если вы связываете этот объектный файл с другими объектными файлами. Кроме того, помните, что callq
в 0x2c изменится, когда вы свяжете этот файл с любой библиотекой libc, которую предоставляет ваша система, поскольку в настоящее время это неполный вызов printf (он не знает, где он находится сейчас).
Что касается вашего mylib.a
, здесь происходит больше. У вас есть файл архива; он содержит несколько объектных файлов, каждый из которых имеет свой собственный текстовый сегмент. В качестве примера, вот часть nm для /usr/lib/libm.a на моем поле здесь
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
Вы увидите, что несколько текстовых сегментов входят - обозначенные буквой T во втором столбце, покоятся по адресу 0x0, но в каждом отдельном файле есть только один символ текстового сегмента в 0x0.
Что касается отдельных файлов с несколькими символами, расположенными по одному и тому же адресу, то кажется, что возможно возможно. В конце концов, это просто запись в таблице, используемая для определения местоположения и размера фрагмента данных. Но я не знаю наверняка. Я никогда раньше не видел нескольких символов, ссылающихся на одну и ту же часть раздела. Любой, кто знает больше, чем я, может принять участие.: -)
Надеюсь, это поможет некоторым.