![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Подрихтовал ещё немного тулзу, и таки добился своего. Можем теперь наблюдать интимные подробности работы динамического загрузчика.
Пример состоит из двух частей, обе написаны на ассемблере.

Компилируем, запускаем. Работу динамического загрузчика я сократил для ясности. Инструкции главной программы выделены зелёным, инструкции библиотечной функции сиреневым. Видно, как при первом вызове функции say() её адрес ещё не готов. Активируется динамический загрузчик, находит адрес функции и уходит в неё. При втором вызове say() переход происходит напрямую. Вставка-переходник say@plt занимает три машинных команды.
Пример состоит из двух частей, обе написаны на ассемблере.
- Главная программа foobar.S выдаёт пару текстовых сообщений, вызывая функцию say() из динамической библиотеки. Затем завершается системным вызовом _exit().
- Бибилиотека lib.S реализует функцию say(), которая выполняет системный вызов write().

Компилируем, запускаем. Работу динамического загрузчика я сократил для ясности. Инструкции главной программы выделены зелёным, инструкции библиотечной функции сиреневым. Видно, как при первом вызове функции say() её адрес ещё не готов. Активируется динамический загрузчик, находит адрес функции и уходит в неё. При втором вызове say() переход происходит напрямую. Вставка-переходник say@plt занимает три машинных команды.
$ cpp foobar.S | as -o foobar.o - $ cpp lib.S | as -o lib.o - $ ld -shared -o lib.so lib.o $ ld -o foobar foobar.o lib.so $ export LD_LIBRARY_PATH=. $ bintrace ./foobar Starting program: ./foobar sp = 0xbfbfeb50 lr = 0x20025538 cpsr = 0x10 ----------------------------------------------------------- dynamic loader 0x20025538: e1a0600d mov r6, sp r6 = 0xbfbfeb50 ... (initialize dynamic loader) ... 0x20025590: e1a0f003 mov pc, r3 ----------------------------------------------------------- 00010158 <_start>: 0x00010158: e300017c movw r0, #0x17c r0 = 0x17c 0x0001015c: e3400001 movt r0, #1 r0 = 0x1017c 0x00010160: ebfffff9 bl #0x1014c lr = 0x10164 ----------------------------------------------------------- 0001014c <say@plt>: 0x0001014c: e28fc600 add ip, pc, #0, #12 r12 = 0x10154 0x00010150: e28cca01 add ip, ip, #0x1000 r12 = 0x11154 0x00010154: e5bcf0c4 ldr pc, [ip, #0xc4]! r12 = 0x11218 ----------------------------------------------------------- 00010138 <.plt>: 0x00010138: e52de004 str lr, [sp, #-4]! sp = 0xbfbfeb4c 0x0001013c: e59fe004 ldr lr, [pc, #4] lr = 0x10c4 0x00010140: e08fe00e add lr, pc, lr lr = 0x1120c 0x00010144: e5bef008 ldr pc, [lr, #8]! lr = 0x11214 ----------------------------------------------------------- into dynamic loader 0x200255a0: e92d0c3f push {r0, r1, r2, r3, r4, r5, sl, fp} sp = 0xbfbfeb2c ... (find symbol 'say' in lib.so) ... 0x200255d4: e1a0f00c mov pc, ip ----------------------------------------------------------- 000000d4 <say>: 0x200170d4: e92d4080 push {r7, lr} sp = 0xbfbfeb48 0x200170d8: e1a01000 mov r1, r0 r1 = 0x1017c 0x200170dc: e3a00001 mov r0, #1 r0 = 0x1 0x200170e0: e3a02004 mov r2, #4 r2 = 0x4 0x200170e4: e3a07004 mov r7, #4 r7 = 0x4 0x200170e8: ef000000 svc #0 foo r0 = 0x4 r1 = 0 0x200170ec: e8bd8080 pop {r7, pc} r7 = 0 sp = 0xbfbfeb50 ----------------------------------------------------------- back to _start 0x00010164: e3000180 movw r0, #0x180 r0 = 0x180 0x00010168: e3400001 movt r0, #1 r0 = 0x10180 0x0001016c: ebfffff6 bl #0x1014c lr = 0x10170 ----------------------------------------------------------- 0001014c <say@plt>: 0x0001014c: e28fc600 add ip, pc, #0, #12 r12 = 0x10154 0x00010150: e28cca01 add ip, ip, #0x1000 r12 = 0x11154 0x00010154: e5bcf0c4 ldr pc, [ip, #0xc4]! r12 = 0x11218 ----------------------------------------------------------- 000000d4 <say>: 0x200170d4: e92d4080 push {r7, lr} sp = 0xbfbfeb48 0x200170d8: e1a01000 mov r1, r0 r1 = 0x10180 0x200170dc: e3a00001 mov r0, #1 r0 = 0x1 0x200170e0: e3a02004 mov r2, #4 0x200170e4: e3a07004 mov r7, #4 r7 = 0x4 0x200170e8: ef000000 svc #0 bar r0 = 0x4 r1 = 0 0x200170ec: e8bd8080 pop {r7, pc} r7 = 0 sp = 0xbfbfeb50 ----------------------------------------------------------- back to _start 0x00010170: e3a07001 mov r7, #1 r7 = 0x1 0x00010174: e3a00000 mov r0, #0 r0 = 0 0x00010178: ef000000 svc #0 Process exited normally.