
Փորձնական ձևաչափը գործարկվող ֆայլը դարձնում է SQLite տվյալների բազա
Ծրագրավորող Ֆարիդ Զաքարիան ստեղծել է SELF-ը՝ փորձնական ձևաչափ, որը ծրագիրն ու նրա գրադարանները պահում է մեկ SQLite բազայում՝ readelf-ն ու ldd-ն փոխարինելով SQL հարցումներով։
Ծրագրավորող Ֆարիդ Զաքարիան հրապարակել է փորձնական նախագիծ, որը բինար ELF ձևաչափը փոխարինում է SQLite-ով։ Նախագիծը կոչվում է SELF. արդյունքը սովորական SQLite ֆայլ է, որը ստանում է գործարկման իրավունք և իսկապես աշխատում է, իսկ binutils գործիքների փոխարեն օգտագործվում են SQL հարցումներ։ Կոդը GitHub-ի selfdb պահոցում է։
ELF-ն արդեն տվյալների բազա է
Զաքարիայի փաստարկն այն է, որ ELF-ն ինքնին տվյալների բազա է՝ ուղղակի ձեռքով իրականացված. տողերի աղյուսակները տողերի ինտերնինգ են, .gnu.hash-ը՝ ձեռքով կառուցված ինդեքս, բաժինների վերնագրերի աղյուսակը՝ աղյուսակների աղյուսակ, իսկ տողերի աղյուսակի հատվածները կատարում են արտաքին բանալիների դեր։ Ձևաչափը խիտ է, ինքնանկարագրող սխեմա չունի, և այն կարդացող ամեն գործիք կրկին գրում է նույն վերլուծիչը։ Նրա նախորդ գործիքը՝ sqlelf-ը, ELF ֆայլերը ներկայացնում էր որպես SQL վիրտուալ աղյուսակներ, որպեսզի ծրագրավորողները readelf-ի ու grep-ի փոխարեն SELECT գրեին։
Ինչ է պարունակում SELF ֆայլը
Գործարկելու համար երկու աղյուսակ բավական է. self_meta-ն պահում է ELF-ի վերնագիրը որպես բանալի-արժեք զույգեր, իսկ segments-ը՝ մեկ տող յուրաքանչյուր ծրագրային վերնագրի համար՝ սեգմենտի բայթերով BLOB սյունակում։ Մեկ symbols աղյուսակը մեկ b-tree ինդեքսով փոխարինում է ELF-ի մի քանի բաժիններին և ձեռքով կառուցված .gnu.hash կառույցին, իսկ սիմվոլների տարբերակները դառնում են սովորական սյունակ։ sections, notes և dynamic_entries աղյուսակները միայն գործիքների համար են. դրանք ջնջելուց հետո ծրագիրը դեռ աշխատում է, այսինքն՝ strip-ը DELETE-ն ու VACUUM-ն է, patchelf-ը՝ UPDATE, իսկ ldd-ն՝ JOIN-ի վրայի տեսք։
Ինչպես է այն գործարկում միջուկը
SQLite-ը իր վերնագրի 68-րդ բայթի վրա չորս բայթանոց application_id դաշտ է պահում. SELF-ը այնտեղ գրում է SELF տառերը, այնպես որ սովորական բազան երբեք չի համընկնի։ Linux-ի binfmt_misc-ի գրանցումը միջուկին հանձնարարում է ֆայլը փոխանցել փոքր ինտերպրետատորի՝ self-exec-ի, որը բեռնվող սեգմենտները տեղադրում է հիշողության մեջ, կատարում տեղափոխումները և անցնում մուտքի կետին։ Ինտերպրետատորն ինքը պետք է մնա ELF ֆայլ, քանի որ նա, որ նույնպես կհամընկներ մոգական բայթերի հետ, կկանչվեր ռեկուրսիվ՝ մինչև միջուկը կվերադարձներ ELOOP։
Արժեքը և ամբողջ userland-ը մեկ ֆայլում
Դինամիկ կապակցումը փորձարկվել է երկու ձևով. սկզբում ld.so-ն մնաց տեղում, և գրադարանների որոնումը կատարվեց SQL-ով՝ glibc-ի rtld-audit ինտերֆեյսի միջոցով, ապա ստեղծվեց փորձնական կապող, որն ամբողջ կապակցումը կատարում է SQL-ում։ Ծավալով SELF ֆայլը մոտ երկու անգամ մեծ է համարժեք ELF-ից, սակայն դրա մեծ մասը ոչ պարտադիր գործիքային տվյալներ են. մաքրելուց հետո coreutils-ի բինարը չափվել է 1 794 048 բայթ՝ ELF տարբերակի 1 768 632-ի դիմաց։ Գործարկումը ավելացնում է մոտ 5 մվ ֆիքսված ծախս և պատկերի չափին համահունչ պատճենում. քանի որ բայթերը պատճենվում են b-tree-ից և ոչ թե քարտեզագրվում, նույն ծրագրի երկու գործընթաց չեն կիսում տեքստի էջերը։
Ամբողջ userland-ը մեկ բազայում փաթեթավորելը տվեց ամենատպավորիչ արդյունքը. 723 գործարկվող ֆայլ, որոնք օգտագործում են 400 տարբեր գրադարան, դարձան 1123 օբյեկտ և 346 386 սիմվոլ մեկ 611,9 ՄԲ ֆայլում՝ ավելի փոքր, քան այն 644,4 ՄԲ ELF ֆայլերը, որոնցից ստեղծվել է։ LD_PRELOAD-ը դառնում է աղյուսակի տող, ուստի նրա միացումն ու անջատումը գործարք է։
SiTech — AI-ով հզորացված վեբ մշակում
Ստեղծում ենք արագ ու ժամանակակից կայքեր և AI-ը ներդնում իրական բիզնես գործընթացներում։ Ունե՞ք նախագիծ կամ հարց։ Ուրախ կլինենք օգնել։