- PVSM.RU - https://www.pvsm.ru -

Blink: супербыстрый эмулятор x86_64 размером 119 КБ

Blink: супербыстрый эмулятор x86_64 размером 119 КБ - 1

На Хабре когда-то писали про талантливую программистку Джастин Танни [1], автора маленьких и очень быстрых приложений. Приятно знать, что она не останавливает свою неординарную деятельность. Например, одна из её последних разработок — крошечный эмулятор под названием Blink [2] размером всего 116 КБ, который очень быстро компилирует WASM и выполняет Linux-программы x86_64 под разными платформами и даже в браузере [3].

Как уже рассказывалось, Джастин известна не только своей программистской, но и общественной деятельностью. В 2011 году она приняла участие в движении «Оккупируй Уолл-стрит», и чуть ли не сама его начала [4]. По крайней мере, пост с таким названием (OCCUPYWALLSTREET) был опубликован в блоге alt-media Adbusters. Он содержал призыв к мирному протесту на Уолл-Стрит. Джастин же зарегистрировала домен occupywallst [5].

Blink: супербыстрый эмулятор x86_64 размером 119 КБ - 2

Широкой общественности Танни стала известна в 2014 году, когда обратилась к правительству США с предложением ввести должность гендиректора США, на которую назначить тогдашнего исполнительного директора Google Эрика Шмидта.

RedBean и APE

Одна из наиболее известных её программ — веб-сервер Redbean [6], который представляет собой кросс-платформенный бинарный файл с сайтом. Точнее, внутри бинарного файла внедрены статические файлы. На выходе мы имеем файл .com, который можно запустить на любом компьютере под Linux, Mac, Windows, FreeBSD, OpenBSD, NetBSD, BIOS. Джастин — автор и кросс-платформенного формата APE [7] (αcτµαlly pδrταblε εxεcµταblε).

Именно благодаря этому формату и появился Redbean. Джастин выяснила, что совмещение в файле заголовков Windows и UNIX позволяет выполнить Windows Portable Executable в качестве скрипта для Thompson shell. Таким образом, бинарный файл запускается на Windows, Linux и Mac OS. Вот шаблон такого кода:

                    MZqFpD='
                    BIOS BOOT SECTOR'
                    exec 7<> $(command -v $0)
                    printf '177ELF...LINKER-ENCODED-FREEBSD-HEADER' >&7
                    exec "$0" "$@"
                    exec qemu-x86_64 "$0" "$@"
                    exit 1
                    REAL MODE...
                    ELF SEGMENTS...
                    OPENBSD NOTE...
                    NETBSD NOTE...
                    MACHO HEADERS...
                     CODE AND DATA...
                     ZIP DIRECTORY...

Библиотека Cosmopolitan

Библиотека Cosmopolitan, реализует формат APE и даёт возможность компилировать кросс-платформенные бинарные файлы с помощью компилятора GCC.

Цель разработки состояла в том, чтобы сделать С языком однократной сборки, разработки «с нуля» и запуска в любой системе, избегая ограничений, которые препятствуют обмену программным обеспечением.

gcc -g -O -static -fno-pie -no-pie -mno-red-zone -nostdlib -nostdinc -o hello.com hello.c 
 -Wl,--oformat=binary -Wl,--gc-sections -Wl,-z,max-page-size=0x1000 -fuse-ld=bfd -gdwarf-4 
 -Wl,-T,ape.lds -include cosmopolitan.h crt.o ape.o cosmopolitan.a

В приведённом выше фрагменте кода компилятор Linux перенастроен так, что он будет выводить бинарные файлы, которые будут запускаться в macOS, Windows, FreeBSD, OpenBSD и NetBSD и BIOS.

Braille Dump и Blinkenlights

У Джастин много проектов. Среди них Braille Dump [8] — замена для hexdump -C, которая использует символы брайля [9] в Юникоде для отображения шестнадцатеричных кодов 0x81… 0xff, тем самым улучшая читаемость двоичного кода.

Braille Dump будет работать в Linux 2.6.16 +, Windows Vista +, macOS XNU 15.6 +, FreeBSD 12 +, OpenBSD 6.4 + или NetBSD 9.1 +.

$ curl https://justine.lol/braille/bd.com >bd.com
$ chmod +x bd.com
$ echo 'hello→world→' | ./bd.com
00000000 68 65 6c 6c 6f e2 86 92 77 6f 72 6c 64 e2 86 92 │hello⢚⢠⢁world⢚⢠⢁│
00000010 0a │◙│
00000011

Отладчик командной строки Blinkenlights [10], который визуализирует изменения памяти программами. Он может эмулировать статически связанные программы i8086 и x86_64-pc-linux-gnu на платформах Linux, Mac, Windows, FreeBSD, NetBSD и OpenBSD.

Blink: супербыстрый эмулятор x86_64 размером 119 КБ - 3

Последняя упомянутая утилита отладки имеет отношение к разработке Джастин, которая вызвала достаточно большой интерес. Это Blink [2], эмулятор x86-64, работающий вдвое быстрее QEMU [11].

Скучная теория

Прежде чем рассказать о Blink, вспомним о виртуализации и эмуляции. И о QEMU, конечно.

Виртуализация имитирует вычислительную среду (например, операционную систему) для программ, которые в ней работать не могут. Благодаря виртуализации на одном компьютере или сервере может быть создано несколько виртуальных машин (программ, имитирующих работу целого компьютера) с индивидуальным набором программ и выделенным объёмом ресурсов (процессорных, оперативной памяти, накопителей), распределяемых гипервизором основной (хостовой) ОС.

Blink: супербыстрый эмулятор x86_64 размером 119 КБ - 4

Эмуляция в простейшем варианте — это имитация программ или аппаратного комплекса с помощью созданного специально для этого программного обеспечения. Воспроизвести цифровую модель не так просто, но иногда необходимо, если требуется, например, подключить библиотеку, работавшую ещё на Intel 80486 или игру с приставки Sega.

Программы, эмулирующие среду (рабочее окружение) для различных программных комплексов, ОС и т.д называются виртуальными машинами. С их помощью можно поднять Windows на машине с Linux и наоборот. Виртуальных машин на одном компьютере может работать несколько — лишь бы ресурсов хватало.

Приложение с открытым кодом QEMU, предназначено для эмуляции аппаратного обеспечения различных платформ. Программа способна воспроизводить работу процессоров Intel x86 и устройств их ввода-вывода. Она может эмулировать x86 (32 и 64 бит), PowerPC (32 и 64 бит), ARM, MIPS (32 бит), Sprac (32 и 64 бит), Alpha, ColdFire(m68k), CRISv2, MicroBlaze.

QEMU работает на Syllable, FreeBSD, OpenBSD, FreeDOS, Linux, Windows 9x, Windows 2000, Mac OS X, QNX, Android.

Эмулятор использует аппаратную виртуализацию и может работать в режиме полной эмуляции (full-system emulation). В этом случае программа полностью воспроизводит работу компьютера, и в режиме пользовательской эмуляции (user-mode emulation), когда приложения, разработанные для одной среды, запускаются в другой (только в хостовой системе Linux). Во втором случае QEMU превращает инструкции или бинарный код на входе (например, от ARM) в платформонезависимый бинарный код, который далее преобразуется в код или инструкции (к примеру, для x86). В общем, QEMU — отличная программа виртуализации с большими возможностями.

Blink: супербыстрый эмулятор x86_64 размером 119 КБ - 5

Blink

Исполняемый файл эмулятора Blink [2] весит всего 221 килобайт, а после отключения дефолтных функций вовсе 115 КБ (вместо 4 мегабайт у QEMU) и работает вдвое быстрее, чем QEMU.

Blink: супербыстрый эмулятор x86_64 размером 119 КБ - 6

Эмулятор предназначается для запуска x86-64 Linux-программ в других операционных системах (macOS, FreeBSD, NetBSD, OpenBSD) и на оборудовании с различной аппаратной архитектурой (x86, ARM, RISC-V, MIPS, PowerPC, s390x). Код проекта написан на языке Си (ANSI C11) и распространяется под лицензией ISC (требуется libc (POSIX.1-2017)).

За счёт чего он такой быстрый? В первую очередь, за счёт использования вышеупомянутого портативного формата и множества оптимизаций. В документации указано, что Blink использует JIT-компилятор (just-in-time), который на лету преобразует исходные инструкции в код на предметно-ориентированном языке в стиле printf (поддерживаются x86_64 и aarch64). Компилятор во время выполнения генерирует функции, которые в свою очередь вызывают микрооперации (micro-op) в машинном коде. Чтобы ускорить выполнение микроопераций, Blink определяет длину байта скомпилированной функции, сканируя её на наличие RET-инструкции (инструкция возврата из ближней процедуры на ассемблере). Затем копирует скомпилированную функцию в JIT.

Кроме того, Blink виртуализирует память, используя тот же подход PML4T, что и аппаратное обеспечение, которое осуществляет поиск по четырёхуровневому основному дереву. Поскольку выполнение четырёх отдельных поисков в таблице страниц при каждом обращении к памяти может быть медленным, Blink проверяет буфер просмотра перевода, который содержит шестнадцать самых последних использованных записей таблицы страниц.

И это далеко не полный список оригинальных оптимизаций, которые сделала Джастин.

Blink проходит 194 тестовых набора из проекта Cosmopolitan Libc [12], 350 тестовых наборов из проекта Linux Test Project [13], 108 тестов из набора модульных тестов Musl Libc [14].

Из интересного, эмулятор способен эмулировать самого себя:

Blink: супербыстрый эмулятор x86_64 размером 119 КБ - 7

Поддерживаются форматы ELF, PE (Portable Executables) и bin (Flat executable), собранные с С-библиотеками Cosmopolitan, Glibc и Musl. Встроена поддержка системных вызовов Linux (в том числе fork() и clone()). Эмулируются наборы инструкций i8086, i386, SSE2, x86_64, SSE3, SSSE3, CLMUL, POPCNT, ADX, BMI2 (MULX, PDEP, PEXT), X87, RDRND, RDSEED, RDTSCP.

Главная директива Blink — поддерживать бинарные файлы, созданные с помощью Cosmopolitan Libc. Собственно, переносимые исполняемые файлы составляют большую часть набора модульных тестов Blink.

Набор инструкций x86_64 в Blink покрыт полностью. Однако ABI системных вызовов Linux намного больше и поэтому не может быть полностью поддержан, если только Blink не эмулирует образ ядра Linux. Но такое чувство, что до этого осталось недолго… 😏

Автор: Александр

Источник [15]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/linux/384690

Ссылки в тексте:

[1] Джастин Танни: https://dev.abcdef.wiki/wiki/Justine_Tunney

[2] Blink: https://github.com/jart/blink

[3] даже в браузере: https://twitter.com/justinetunney/status/1613895681038770182

[4] сама его начала: https://www.businessinsider.com/google-engineer-who-organized-occupy-movement-2014-4

[5] occupywallst: http://occupywallst.org/

[6] Redbean: https://redbean.dev/

[7] APE: https://justine.lol/ape.html

[8] Braille Dump: https://justine.lol/braille/

[9] символы брайля: https://github.com/angea/corkami/blob/master/src/HexII/braille/braille-ange

[10] Blinkenlights: https://justine.lol/blinkenlights/

[11] вдвое быстрее QEMU: https://twitter.com/JustineTunney/status/1610276286269722629

[12] Cosmopolitan Libc: https://github.com/jart/blink/tree/master/third_party/cosmo

[13] Linux Test Project: https://github.com/linux-test-project/ltp

[14] Musl Libc: https://github.com/jart/libc-test

[15] Источник: https://habr.com/ru/companies/timeweb/articles/734652/?utm_source=habrahabr&utm_medium=rss&utm_campaign=734652