SELF Framework Replaces Executable Linkable Format Binary Headers with Queryable SQLite Databases
An open-source prototype called SELF turns Linux ELF executables into standard SQLite3 database files. Developers can inspect binary headers, strip notes within SQL transactions, and customize dynamic linking using standard relational queries.

Impact: Medium
Why it matters
Replacing rigid binary formats with relational schemas turns static ELF analysis, patching, and auditing into declarative SQL statements.
TL;DR
- 01Executable binaries can be fully represented as self-describing relational databases.
- 02Binary stripping and dependency patching reduce to standard SQL updates and vacuum commands.
- 03Linux binfmt_misc allows custom executable database formats to run transparently.
Key facts
- SQLite Application ID
- 0x53454c46 ('SELF')
- Strip Equivalent
- DELETE FROM sections; DELETE FROM notes; VACUUM;
- Kernel Integration
- binfmt_misc + self-exec loader
- Dynamic Audit Interface
- glibc rtld-audit (libself-audit.so)
Binary Layout as Relational Tables
ELF files manually re-implement basic database primitives like string interning, section offset lookup, and bloom filters (.gnu.hash). The SELF prototype replaces this complexity with a self-describing SQLite 3 schema. Two core tables are required to execute a binary: self_meta (storing execution key-value headers) and segments (storing binary memory bytes per program header).
Queryable Dynamic Linking and Stripping
Metadata transformation becomes transactional SQL rather than risky binary offset manipulation:
- Inspecting imports:
SELECT name, version FROM imports; - Listing dynamic dependencies:
SELECT ord, soname FROM ldd; - Stripping binaries:
DELETE FROM sections; DELETE FROM notes; VACUUM;
Linux Kernel Integration
Execution is enabled through Linux binfmt_misc. By registering the SQLite magic string offset with the application tag SELF, the kernel transparently passes execution to self-exec. A custom C loader reads program headers from the SQLite file, maps memory segments via mmap, and jumps directly to the entry point.
Try it in 2 minutes
sqlite3 hello 'SELECT name, version FROM imports LIMIT 3;'bash
✓ When to use
- Exploring declarative binary symbol inspection and dynamic linking experiments on Linux.
- Building custom low-level devtools and NixOS package post-fixup hooks.
✕ When NOT to use
- Deploying production binaries requiring minimal runtime memory overhead.
- Cross-compiling for systems lacking binfmt_misc or libsqlite3 dependency.
What to do today
- Clone the SELF repository to experiment with elf2self conversion on NixOS or Linux.
- Test querying executable binary symbols directly with sqlite3 CLI.
Sources