Что означает «значение символа» из команды nm? - PullRequest
15 голосов
/ 08 декабря 2009

Когда вы перечисляете таблицу символов статической библиотеки, например nm mylib.a, что означает восьмизначный гекс, который отображается рядом с каждым символом? Это относительное расположение каждого символа в коде?

Кроме того, могут ли несколько символов иметь одинаковое значение символа? Что-то не так с кучей разных символов со значением символа 00000000?

Ответы [ 3 ]

23 голосов
/ 08 декабря 2009

Вот фрагмент кода, который я написал на 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.

Что касается отдельных файлов с несколькими символами, расположенными по одному и тому же адресу, то кажется, что возможно возможно. В конце концов, это просто запись в таблице, используемая для определения местоположения и размера фрагмента данных. Но я не знаю наверняка. Я никогда раньше не видел нескольких символов, ссылающихся на одну и ту же часть раздела. Любой, кто знает больше, чем я, может принять участие.: -)

Надеюсь, это поможет некоторым.

3 голосов
/ 08 декабря 2009

Шестнадцатеричное число - это смещение памяти в объектных файлах, где можно найти символ. Это буквально количество байтов в объектном коде.

Это значение используется компоновщиком, чтобы найти и скопировать значение символа. В общем, вы можете увидеть, как это выглядит, добавив параметр -S к nm, который покажет вам размер значения для каждого символа.

1 голос
/ 08 декабря 2009

нм показывает значения символов. Некоторые символы в библиотеке или объектном файле могут отображаться как ноль просто потому, что им еще не присвоено значение. Они получат свое реальное значение во время ссылки.

Некоторые символы являются символами кода, некоторые являются данными и т. Д. Перед связыванием значения символа часто смещение в разделе, в котором оно находится,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...