Ответ 1
Вот фрагмент кода, который я написал в 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
В этом примере я запускаю 64-разрядную версию Ubuntu Linux; поэтому 8-значный гекс, который вы видите, здесь 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.
Что касается отдельных файлов, содержащих несколько символов, расположенных на одном и том же адресе, похоже, возможно, это возможно. В конце концов, это всего лишь запись в таблице, используемой для определения местоположения и размера части данных. Но я точно не знаю. Я никогда не видел несколько символов, ссылающихся на одну и ту же часть раздела. Любой, кто имеет больше знаний об этом, чем я, может перезвонить.: -)
Надеюсь, это поможет некоторым.