2010-10-10 6 views
4

Я пытаюсь понять следующее поведение разделяемых библиотек в Cпонимание общих библиотек с использованием GCC

Machine One

$ cat one.c 
#include<stdio.h> 

int main() { 
    printf ("%d", 45); 
} 
$ gcc one.c -o one -O3 
$ ldd one 
    linux-gate.so.1 => (0x00331000) 
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00bc2000) 
    /lib/ld-linux.so.2 (0x006dc000) 
$ cat two.c 
int main() { 
    int i = 0; 
} 
$ gcc two.c -o two -O3 
$ ldd two 
    linux-gate.so.1 => (0x006f7000) 
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000) 
    /lib/ld-linux.so.2 (0x00eb0000) 
$ 

машина Два

$ cat three.c 
#include<stdio.h> 

int main() { 
    printf ("%d", 45); 
} 
$ gcc three.c -o three -O3 
$ ldd three 
    /usr/lib/libcwait.so (0xb7ffd000) 
    libc.so.6 => /lib/tls/i686/nosegneg/libc.so.6 (0x002de000) 
    /lib/ld-linux.so.2 (0x002bf000) 
$ 

Несколько вещей, которые я не до конца понимаю, в настоящее время:

  • Что адрес в скобках (например, (0x002de000)) означает?

    Эти адреса различны даже для одной и той же библиотеки на той же машине, что предполагает, что это адреса мест в памяти, где загружаются эти библиотеки. Но, если это так, почему эти библиотеки загружены в память вообще (я еще не выполнял программы, разве они не должны загружаться только во время выполнения?).

  • Почему two нужны библиотеки вообще? Я использовал -O3, а выход ассемблер

    $ gcc two.c -S -O3 
    $ cat two.s 
        .file "two.c" 
        .text 
        .p2align 4,,15 
    .globl main 
        .type main, @function 
    main: 
        pushl %ebp 
        movl %esp, %ebp 
        popl %ebp 
        ret 
        .size main, .-main 
        .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" 
        .section .note.GNU-stack,"",@progbits 
    $ 
    

    Какова потребность в каких-либо библиотек вообще?

  • На машине два, почему используется /usr/lib/libcwait.so вместо linux-gate.so.1?

    Я думаю, это связано с тем, что ядро ​​на Machine Two очень старое (2.6.9), а библиотека linux-gate.so.1 недоступна. Это причина?

ответ

5

Что означает адрес, указанный в скобках (например, (0x002de000))?

Это (виртуальный) адрес памяти, в который загружается библиотека. Недавняя система может обеспечить рандомизацию того, где загружаются библиотеки, поэтому этот адрес может различаться между вызовами.

Следует ли их загружать только во время выполнения?

Да, они есть. ldd проходит большую часть той же процедуры, что и , выполненный во время выполнения, чтобы иметь возможность выяснить различные вещи.

Почему две библиотеки нужны вообще?

libc.so.6 - стандартная библиотека C (и другие материалы, такие как интерфейс для ядра) и всегда связаны по умолчанию. gcc имеет опции для управления этим, например, -nostdlib flag

ld-linux.so - это динамический загрузчик, и он отвечает за загрузку и перемещение других разделяемых библиотек и запуск вашего приложения. Страница man для ld-linux.so дает вам подробную информацию.

linux-gate.so.1 - это виртуальная библиотека, она существует только в памяти в ядре. Он используется для выполнения системных вызовов ядра и определяет наиболее эффективный способ сделать это на основе вашего процессора. Вероятно, это было добавлено в linux позже, чем ваша другая версия ядра 2.6.9.

Я не знаю, что /usr/lib/libcwait.so есть, но скорее всего, вы можете получить некоторую информацию о нем, делая обороты -qif /usr/lib/libcwait.so

1

Номер является адресом памяти, в котором библиотека загружается при запуске исполняемого файла. Он определяется во время соединения и обычно рандомизирован для того, чтобы сделать ошибки в библиотечных функциях непредсказуемыми и, следовательно, более трудными для использования в эксплоитах. Стандартная библиотека C по умолчанию связана GCC. libcwait, вероятно, является другой библиотекой по умолчанию, возможно, используемой более старыми версиями GCC.

2

Адреса являются в основном случайными числами. Перед тем, как были разработаны безопасные реализации, ldd будет последовательно указывать адреса памяти, в которых загружены разделы программы. Так как около пяти лет назад, многие ароматы Linux в настоящее время намеренно рандомизации адресов нагрузки расстроить потенциальных вирусов и т.д. Я составил one.c (как дц) и выполняется повторно LDD:

[[email protected] .bin]$ cat t.c 
#include <stdio.h> 
int main() 
{ 
    printf ("%d", 45); 
} 
[[email protected] .bin]$ gcc -o t t.c -O3 
[[email protected] .bin]$ ldd t 
    linux-gate.so.1 => (0x009e5000) 
    libc.so.6 => /lib/libc.so.6 (0x002e4000) 
    /lib/ld-linux.so.2 (0x002c2000) 
[[email protected] .bin]$ ldd t 
    linux-gate.so.1 => (0x00b8d000) 
    libc.so.6 => /lib/libc.so.6 (0x002e4000) 
    /lib/ld-linux.so.2 (0x002c2000) 
[[email protected] .bin]$ ldd t 
    linux-gate.so.1 => (0x00238000) 
    libc.so.6 => /lib/libc.so.6 (0x002e4000) 
    /lib/ld-linux.so.2 (0x002c2000) 
[[email protected] .bin]$ ldd t 
    linux-gate.so.1 => (0x002a0000) 
    libc.so.6 => /lib/libc.so.6 (0x002e4000) 
    /lib/ld-linux.so.2 (0x002c2000) 
[[email protected] .bin]$ ldd t 
    linux-gate.so.1 => (0x00f93000) 
    libc.so.6 => /lib/libc.so.6 (0x002e4000) 
    /lib/ld-linux.so.2 (0x002c2000) 
[[email protected] .bin]$ ldd t 
    linux-gate.so.1 => (0x00c7a000) 
    libc.so.6 => /lib/libc.so.6 (0x002e4000) 
    /lib/ld-linux.so.2 (0x002c2000) 
[[email protected] .bin]$ ldd t 
    linux-gate.so.1 => (0x00d1a000) 
    libc.so.6 => /lib/libc.so.6 (0x002e4000) 
    /lib/ld-linux.so.2 (0x002c2000) 
[[email protected] .bin]$ ldd t 
    linux-gate.so.1 => (0x00d12000) 
    libc.so.6 => /lib/libc.so.6 (0x002e4000) 
    /lib/ld-linux.so.2 (0x002c2000) 

Crtl и ЛД-линукс адреса загрузки согласованы, но linux-gate рандомизирован.

Библиотеки необходимы, поскольку необходимо запустить инициализацию и завершение выполнения C. Конечно, они могут быть в значительной степени оптимизированы с stdin, stdout, stderr и т. Д. И т. Д. Не нужно инициализировать. Тем не менее, crtl - это то, как вызывается main().

Различные варианты и версии Linux имеют отличия. Эволюция glib имела много поворотов.Некоторые вещи были перенесены в другие библиотеки. Это почти то же самое, что и ваш местный продуктовый магазин перемещает вещи вокруг. Это не имеет большого значения.

+0

'two.c 'можно было бы оптимизировать в 0-байтную (или почти 0-байтовую) программу. Но ни один производитель не собирается создавать компиляторы, которые оптимизируют для тривиальных программ. –