5254
Комментарий: Больше, чем для ВМШ статья :)
|
6173
|
Удаления помечены так. | Добавления помечены так. |
Строка 2: | Строка 2: |
= Математическая библиотека = * ''Повторение'': создание исполняемой программы из исходного кода на Си: 1. Трансляция: файл на Си → объектный файл (все операторы Си переведены на машинный язык) 1. Компоновка: объектный файл → исполняемый файл (к объектному файлу добавлена исполняющая подсистема Си и другие подпрограммы, непосредственно либо в виде указания библиотеки, откуда эти подпрограммы может загрузить операционная система) |
= О компоновке программ = Компоновка: объектный файл → исполняемый файл (к объектному файлу добавлена исполняющая подсистема Си и другие подпрограммы, непосредственно либо в виде указания библиотеки, откуда эти подпрограммы может загрузить операционная система) |
Строка 30: | Строка 27: |
-rw-r--r-- 1 george george 94 янв 27 21:32 simple.c -rw-r--r-- 1 george george 3488 янв 27 21:42 simple.o |
-rw-r--r-- 1 george george 99 янв 29 10:43 simple.c -rw-r--r-- 1 george george 1680 янв 29 10:47 simple.o |
Строка 46: | Строка 43: |
-rw-r--r-- 1 george george 94 янв 27 21:32 simple.c -rw-r--r-- 1 george george 3488 янв 27 22:17 simple.o -rwxr-xr-x 1 george george 3487080 янв 27 22:17 simple.static |
-rw-r--r-- 1 george george 99 янв 29 10:43 simple.c -rw-r--r-- 1 george george 1680 янв 29 10:47 simple.o -rwxr-xr-x 1 george george 3486600 янв 29 10:50 simple.static |
Строка 50: | Строка 47: |
Статическая компоновка добавляет в объектный файл ''всю'' исполняющую систему Си и всю отладочную информацию к ней, так что получается программа в 1000 (!) раз больше. С помощью `egrep` из отладочной информации добудем сведения о четфрёх именах. Они уже определены, и даже адреса есть. | Статическая компоновка добавляет в объектный файл ''всю'' исполняющую систему Си и всю отладочную информацию к ней, так что получается программа в 1000 (!) раз больше. С помощью [[https://www.opennet.ru/man.shtml?topic=egrep|egrep]] из отладочной информации добудем сведения о четырёх именах. Они уже определены, и даже адреса есть. |
Строка 54: | Строка 51: |
$ strip simple.o simple.static | $ strip simple.static -o simple.static.stripped |
Строка 56: | Строка 53: |
-rw-r--r-- 1 george george 94 янв 27 21:32 simple.c -rw-r--r-- 1 george george 880 янв 27 22:21 simple.o -rwxr-xr-x 1 george george 730112 янв 27 22:21 simple.static |
-rw-r--r-- 1 george george 99 янв 29 10:43 simple.c -rw-r--r-- 1 george george 1680 янв 29 10:47 simple.o -rwxr-xr-x 1 george george 3486600 янв 29 10:50 simple.static -rwxr-xr-x 1 george george 730112 янв 29 10:56 simple.static.stripped |
Строка 64: | Строка 62: |
$ cc -std=c89 simple.c -o simple.dynamic | $ cc simple.o -o simple.dynamic |
Строка 76: | Строка 74: |
== Домашнее задание == 1.#0 {i} Прочитать что-нибудь из [[http://cpp.com.ru/kr_cbook/|учебника]] 1. Сделать что-нибудь из [[http://narhoz-chita.ru/zadachnik|задачника]] 1. …или из другого [[http://kufas.ru/programming179.htm|задачника]] 1. <!> Задание повышенной хитрости ---- CategoryClasses |
В этой программе используется единственная библиотека — `libc` — исполняющая система Си. В ней-то и находятся `printf` и `scanf`. Функции будут подгружены системой из библиотеки во время запуска программы. {{{ $ objdump -T /lib64/libc.so.6 | egrep ' (main|var|printf|scanf)$' 000000000004eb00 g DF .text 00000000000000a1 GLIBC_2.2.5 printf 0000000000062fa0 g DF .text 00000000000000a3 GLIBC_2.2.5 scanf $ strip simple.dynamic -o simple.dynamic.stripped $ ls -l итого 4156 -rw-r--r-- 1 george george 99 янв 29 10:43 simple.c -rwxr-xr-x 1 george george 12528 янв 29 10:57 simple.dynamic -rwxr-xr-x 1 george george 6312 янв 29 11:10 simple.dynamic.stripped -rw-r--r-- 1 george george 1680 янв 29 10:47 simple.o -rwxr-xr-x 1 george george 3486600 янв 29 10:50 simple.static -rwxr-xr-x 1 george george 730112 янв 29 10:56 simple.static.stripped }}} По этой причине файлы получаются меньше (и с отладочной информации, и без неё). Утилита [[https://www.opennet.ru/man.shtml?topic=objdump|objdump]] предназначена для исследования динамических библиотек, с ключом `-T` она выдаёт список видимых в ней символов (преимущественно функций). |
О компоновке программ
Компоновка: объектный файл → исполняемый файл (к объектному файлу добавлена исполняющая подсистема Си и другие подпрограммы, непосредственно либо в виде указания библиотеки, откуда эти подпрограммы может загрузить операционная система) Пример: файл simple.c
Здесь мы определяем переменную var и функцию main, а функции printf и scanf становятся доступны только в процессе компоновки. С помощью ключа -c остановим процесс трансляции на объектном файле (файл этот будет называться simple.o):
$ cc -std=c89 simple.c -c -o simple.o $ hexdump -C simple.o <содержмое объектного файла в шестнадцатеричном виде> ... $ nm simple.o 0000000000000000 T main U printf U scanf 0000000000000004 C var $ ls -l simple.* -rw-r--r-- 1 george george 99 янв 29 10:43 simple.c -rw-r--r-- 1 george george 1680 янв 29 10:47 simple.o
Утилита hexdump покажет нам внутренности simple.o (среди трёхкилобайтного шестнадцатеричного месива можно отыскать все четыре названия). Утилита nm — выдаст информацию о том, какие идентификаторы используются в программе, при этом те, что не определены, помечены как U (undefined). При компиляции использовался старый стандарт c89, чтобы функции назывались более наглядно.
Компоновка:
$ cc -static simple.o -o simple.static $ nm simple.static <множество имён, среди которых есть уже `main, printf, scanf и var> $ nm simple.static | egrep ' (main|var|printf|scanf)$' 000000000040096e T main 0000000000407440 T printf 0000000000407570 T scanf 00000000006b2d58 B var $ ls -l simple.* -rw-r--r-- 1 george george 99 янв 29 10:43 simple.c -rw-r--r-- 1 george george 1680 янв 29 10:47 simple.o -rwxr-xr-x 1 george george 3486600 янв 29 10:50 simple.static
Статическая компоновка добавляет в объектный файл всю исполняющую систему Си и всю отладочную информацию к ней, так что получается программа в 1000 раз больше. С помощью egrep из отладочной информации добудем сведения о четырёх именах. Они уже определены, и даже адреса есть.
Отладочную информацию можно удалить:
$ strip simple.static -o simple.static.stripped $ ls -l simple.* -rw-r--r-- 1 george george 99 янв 29 10:43 simple.c -rw-r--r-- 1 george george 1680 янв 29 10:47 simple.o -rwxr-xr-x 1 george george 3486600 янв 29 10:50 simple.static -rwxr-xr-x 1 george george 730112 янв 29 10:56 simple.static.stripped
Размер раз в 5 меньше.
Вместо статической компоновки обычно используется динамическая, при которой нужные функции в исполняемый файл не записываются, а вместо этого там лежит информация, из какой библиотеки их брать при запуске.
$ cc simple.o -o simple.dynamic $ nm simple.dynamic | egrep ' (main|var|printf|scanf)' 0000000000400566 T main U printf@@GLIBC_2.2.5 U scanf@@GLIBC_2.2.5 0000000000601038 B var $ ldd simple.dynamic linux-vdso.so.1 (0x00007ffe939de000) libc.so.6 => /lib64/libc.so.6 (0x00007fefe7726000) /lib64/ld-linux-x86-64.so.2 (0x000055e6bc426000)
В этой программе используется единственная библиотека — libc — исполняющая система Си. В ней-то и находятся printf и scanf. Функции будут подгружены системой из библиотеки во время запуска программы.
$ objdump -T /lib64/libc.so.6 | egrep ' (main|var|printf|scanf)$' 000000000004eb00 g DF .text 00000000000000a1 GLIBC_2.2.5 printf 0000000000062fa0 g DF .text 00000000000000a3 GLIBC_2.2.5 scanf $ strip simple.dynamic -o simple.dynamic.stripped $ ls -l итого 4156 -rw-r--r-- 1 george george 99 янв 29 10:43 simple.c -rwxr-xr-x 1 george george 12528 янв 29 10:57 simple.dynamic -rwxr-xr-x 1 george george 6312 янв 29 11:10 simple.dynamic.stripped -rw-r--r-- 1 george george 1680 янв 29 10:47 simple.o -rwxr-xr-x 1 george george 3486600 янв 29 10:50 simple.static -rwxr-xr-x 1 george george 730112 янв 29 10:56 simple.static.stripped
По этой причине файлы получаются меньше (и с отладочной информации, и без неё). Утилита objdump предназначена для исследования динамических библиотек, с ключом -T она выдаёт список видимых в ней символов (преимущественно функций).