Влияние статической и динамической привязки на начальный адрес

У меня простая программа на C. Я бегу:

$ gcc Q1.c -Wall -save-temps -o Q1 

Затем я проверяю созданный исполняемый файл:

 $ objdump -f Q1 Q1: file format elf32-i386 architecture: i386, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x080483b0 

Затем я скомпилирую его со статической связью:

 $ gcc Q1.c -Wall -save-temps -static -o Q1 

и снова проверьте файл:

 $ objdump -f Q1 Q1: file format elf32-i386 architecture: i386, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x08048e08 

Какое влияние оказывает статическая и динамическая связь на начальный адрес программы? Стартовый адрес – адрес main() , правильно?

One Solution collect form web for “Влияние статической и динамической привязки на начальный адрес”

Стартовый адрес – адрес main() , правильно?

Не совсем: начало программы не является main() . По умолчанию GCC будет создавать исполняемые файлы, начальный адрес которых соответствует _start . Вы можете видеть, что, выполняя objdump --disassemble Q1 . Вот результат на моей простой программе, которая return 0; в main() :

 0000000000400e30 <_start>: 400e30: 31 ed xor %ebp,%ebp 400e32: 49 89 d1 mov %rdx,%r9 400e35: 5e pop %rsi 400e36: 48 89 e2 mov %rsp,%rdx 400e39: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 400e3d: 50 push %rax 400e3e: 54 push %rsp 400e3f: 49 c7 c0 a0 15 40 00 mov $0x4015a0,%r8 400e46: 48 c7 c1 10 15 40 00 mov $0x401510,%rcx 400e4d: 48 c7 c7 40 0f 40 00 mov $0x400f40,%rdi 400e54: e8 f7 00 00 00 callq 400f50 <__libc_start_main> 400e59: f4 hlt 400e5a: 66 90 xchg %ax,%ax 400e5c: 0f 1f 40 00 nopl 0x0(%rax) 

Как вы можете видеть по адресу 400e54 , _start() в свою очередь вызывает __libc_start_main , который инициализирует необходимый материал (pthreads, atexit, …) и, наконец, вызывает main() с соответствующими аргументами (argc, argv и env).

Хорошо, но что это связано с изменением начального адреса?

Когда вы запрашиваете gcc для связывания статически, это означает, что вся инициализация, о которой я упоминал выше, должна выполняться с использованием функций, которые находятся в исполняемом файле. И действительно, если вы посмотрите на размеры обоих исполняемых файлов, вы обнаружите, что статическая версия намного больше. В моем тесте статическая версия составляет 800K, а общая версия – всего 6K.

Дополнительные функции выполняются перед _start() , следовательно, изменение начального адреса. Вот макет статического исполняемого файла вокруг start() :

 000000000049e960 r translit_from_tbl 0000000000400a76 t _i18n_number_rewrite 0000000000400bc0 t fini 0000000000400bd0 t init_cacheinfo 0000000000400e30 T _start 0000000000400e60 t deregister_tm_clones 0000000000400e90 t register_tm_clones 0000000000400ed0 t __do_global_dtors_aux 

И вот макет общего исполняемого файла:

 00000000004003c0 T _start 00000000004003f0 t deregister_tm_clones 00000000004004b0 T main 00000000004004c0 T __libc_csu_init 00000000006008a0 B _end 0000000000400370 T _init 

В результате я получаю несколько разные стартовые адреса: 0x400e30 в статическом случае и 0x4003c0 в общем случае.

  • Компиляция GCC - откуда берется символ __stack_chk_fail@GLIBC_2.4?
  • Обновление GCC на Debian Wheezy для поддержки возможностей C ++ 11
  • Как изменить версию GCC, которую я использую? Почему GCC по-прежнему работает, несмотря на то, что bash говорит мне, что команда gcc не найдена?
  • Как я могу получить обычный gcc и т. Д. Под HomeBrew под Mac OSX Mountain Lion?
  • как установить gcc4.8 в netbsd 6.1.3?
  • Как установить GCC 4.7.2 на CentOS 5.2?
  • Неустранимая ошибка: удаленные sys-devel / binutils - emerge больше не работают
  • Неустранимая ошибка: нет компиляции в поддержку x86_64
  • защита от разбиения стека на Debian?
  • Используя * Autotools *, как мне сохранить список компиляторов в файле по файлу?
  • Как этот Makefile делает программу C даже без указания компилятора?
  • Interesting Posts

    Как узнать, запущен ли httpd или нет через командную строку?

    Как отслеживать пакеты с MAC-адреса

    Debian Wheezy vs Logitech Quickcam E2500

    Что такое ошибка проверки транзакции? (обновление yum)

    как перечислить пользователей в группе и их пароли

    Удалить n минут старый файл в solaris

    В HP-UX, как я могу записывать сообщения системных событий Information Only Only в syslog.log?

    Почему добавление тестового репозитория Debian создало так много зависимостей пакетов?

    Сценарий Bash не будет работать в текущем каталоге

    Конфигурация unixODBC после компиляции из источника

    Linux-ОС как единая групповая версия

    Какой процесс создал это окно без привязки PID?

    Exynos 5 DVFS или выключение ядра в Ubuntu – Частота масштабирования только для одного из ядер (двухъядерный) (cpufreq)

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

    Как включить механизм объединения в пакет Debian MySQL?

    Linux и Unix - лучшая ОС в мире.