Назад
Експериментальний формат робить виконуваний файл базою даних SQLite
SiTech AI Team3 წთ. საკითხავი

Експериментальний формат робить виконуваний файл базою даних SQLite

Розробник Фарід Закарія створив SELF — прототип формату, який зберігає програму та її бібліотеки в одній базі SQLite, а такі утиліти, як readelf, ldd і strip, замінює SQL-запитами.

Розробник Фарід Закарія опублікував прототип, який замінює бінарний формат ELF на SQLite. Проєкт має назву SELF — Structured Executable & Linkable Format: на виході звичайний файл SQLite, якому надають право на виконання і який справді запускається, а замість утиліт binutils використовуються SQL-запити. Код доступний на GitHub у репозиторії selfdb.

ELF уже є базою даних

Аргумент Закарії полягає в тому, що ELF і без того є базою даних, лише реалізованою вручну: таблиці рядків — це інтернування рядків, .gnu.hash — саморобний індекс, таблиця заголовків секцій — таблиця таблиць, а зсуви в таблицю рядків виконують роль зовнішніх ключів. Формат щільний, не має самодостатньої схеми, і кожен інструмент, що його читає, заново пише той самий парсер. Його попередній інструмент sqlelf подавав файли ELF як віртуальні таблиці SQL, тож розробники могли писати SELECT замість комбінації readelf і grep.

Що містить файл SELF

Для виконання достатньо двох таблиць: self_meta зберігає заголовок ELF як пари ключ-значення, а segments містить по одному рядку на програмний заголовок із байтами сегмента в стовпці BLOB. Одна таблиця symbols з одним b-tree індексом замінює кілька секцій ELF і саморобну структуру .gnu.hash, а версії символів стають звичайним стовпцем. Таблиці sections, notes і dynamic_entries існують лише для інструментів: після їх видалення програма все одно запускається, тобто strip — це DELETE і VACUUM, patchelf — UPDATE, а ldd — подання над JOIN.

Як його запускає ядро

SQLite резервує чотирибайтове поле application_id за зсувом 68 у своєму заголовку; SELF записує туди символи SELF, тож звичайна база ніколи не збігається. Реєстрація через binfmt_misc у Linux доручає ядру передати файл невеликому інтерпретатору self-exec, який відображає завантажувані сегменти, виконує переміщення й переходить на точку входу. Сам інтерпретатор мусить залишатися файлом ELF, бо той, що теж збігався б із магічними байтами, рекурсивно викликав би себе, аж поки ядро не поверне ELOOP.

Ціна та весь userland в одному файлі

Динамічне зв'язування випробували двічі: спершу залишили ld.so, а пошук бібліотек виконували SQL-запитами через інтерфейс rtld-audit із glibc, потім створили прототип компонувальника, який виконує все зв'язування в SQL. За розміром файл SELF приблизно вдвічі більший за відповідний ELF, але більшість цього — необов'язкові службові дані: після очищення бінарник coreutils мав 1 794 048 байтів проти 1 768 632 у версії ELF, тобто в межах одного відсотка. Запуск додає фіксовані ~5 мс і копіювання, пропорційне розміру образу; оскільки байти копіюються з b-tree, а не відображаються, два процеси однієї програми не спільно використовують сторінки коду.

Пакування цілого userland в одну базу дало найяскравіший результат: 723 виконувані файли, що залучають 400 різних бібліотек, стали 1123 об'єктами та 346 386 символами в одному файлі на 611,9 МіБ — меншому за 644,4 МіБ файлів ELF, з яких його зібрали. LD_PRELOAD стає рядком у таблиці, тож його вмикання й вимикання є транзакцією.

SSiTech

SiTech — веброзробка з підтримкою AI

Створюємо швидкі та сучасні сайти й інтегруємо AI у бізнес-процеси. Маєте проєкт чи запитання? Із задоволенням допоможемо.