Здесь вы видите, как динамический загрузчик открывает и читает заголовок нужных библиотек.Почти любая strace
программа ELF (это стандартный исполняемый формат в Linux) начинается с набора open
/ read
/ mmap
/ close
по этой причине: динамический загрузчик загружает необходимыйбиблиотеки.
То, что вы видите здесь:
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\273\0\0\0\0\0\0"..., 832) = 832
Это то, что загрузчик читает из файла:
3
: это fd
, который был назначен открытому файлу open()
. "\177ELF\2\1\1\0..."
: это содержимое файла, который читается.Числа существуют потому, что это восьмеричные escape-последовательности, например, \1
означает байт 1. Они печатаются так, потому что в противном случае вы бы не смогли их увидеть и создали бы беспорядок на вашем терминале, так как большинство из нихспециальные непечатаемые символы. 832
: это количество байтов, которое загрузчик хочет прочитать из файла. = 832
: это результат read()
,Это означает, что все запрошенные байты были прочитаны.
Другими словами, эти escape-последовательности - просто способ сделать непечатные байты удобочитаемыми для человека .Вы можете протестировать этот запуск od -bc
для файла, который пытается открыть загрузчик, вы можете увидеть его содержимое в восьмеричной форме, а также с печатными символами и символами обратной косой черты:
$ od -bc /lib/x86_64-linux-gnu/libc.so.6 | head -n4
0000000 177 105 114 106 002 001 001 003 000 000 000 000 000 000 000 000
177 E L F 002 001 001 003 \0 \0 \0 \0 \0 \0 \0 \0
0000020 003 000 076 000 001 000 000 000 260 034 002 000 000 000 000 000
003 \0 > \0 001 \0 \0 \0 260 034 002 \0 \0 \0 \0 \0
Более полныйНапример, из strace /bin/true
:
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 4
read(4, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\4\2\0\0\0\0\0"..., 832) = 832
fstat(4, {st_mode=S_IFREG|0755, st_size=1689360, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0d3d877000
mmap(NULL, 3795296, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x7f0d3d2dd000
mprotect(0x7f0d3d472000, 2097152, PROT_NONE) = 0
mmap(0x7f0d3d672000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x195000) = 0x7f0d3d672000
mmap(0x7f0d3d678000, 14688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f0d3d678000
close(4)
Вы можете видеть, что загрузчик открывает «libc», который является ELF-файлом для стандартной библиотеки C.Он читает свой заголовок, чтобы определить, какие разделы должны быть загружены, а затем mmap
все необходимые разделы в памяти, назначая необходимые разрешения.