2009-12-07 2 views
13

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

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

ответ

21

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

Указанная шестнадцатеричная цифра является адресом рассматриваемого кода в объектном файле относительно начала раздела .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, здесь все происходит. Файл, который у вас есть, - это архив; он содержит несколько объектных файлов, каждый из которых имеет собственный текстовый сегмент. В качестве примера здесь является частью нм против /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 

Вы увидите, что несколько заходы сегмент текста - указывает Т во второй колонке отдыха по адресу 0x0, но каждый отдельный файл имеет только один текстовый сегментный символ в 0x0.

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

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

+0

Если вы скомпилируете свой пример с помощью 'x86_64-w64-mingw32-g ++', вы увидите с помощью 'nm' несколько символов, которые ссылаются на нулевой адрес и имеют знак« A », то есть адрес не будет в будущем. Например. '0000000000000000 A __dll__ 0000000000000000 A __dll_characteristics__'. По сути - [я видел, что были] (http://unix.stackexchange.com/q/158162/59928) отображал фактически полезные функции. Мне интересно, что это могло означать? –

3

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

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

0

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

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

Смежные вопросы