Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Dynamic creation and update of ELF files, or: an allocator for JIT compilers
|Type||Name||Latest commit message||Commit time|
|Failed to load latest commit information.|
This is libdlbind, an extension to System V-style dynamic loaders to allow dynamic allocation of objects and dynamic binding of symbols. Its main use-case is in JIT compilers, or other run-time code generators. Rather than allocating code memory yourself, allocating it with dlbind keeps the dynamic loader informed -- along with any debugger that might be attached. This means that your JITted code and data are automatically debuggable just like any other dynamically loaded content. It also means that the usual dlsym() and dladdr() interfaces will work against your JITted output. Currently, the implementation is very minimal and naive. It does work, with some caveats: - you must have a writable /run/shm directory; - no deallocation or unbinding yet; - when defining a new symbol, the dlreload() call, necessary for symbol binding, doesn't quite work without some modifications to the dynamic loader or debugger. In particular, since we need in-memory changes to persist across a close-open sequence, we have two options. (1) don't really close the file, hence keeping the mappings in memory, but make the debugger re-read the symbols anyway; (2) close and reopen the file. To make (1) work, we need to make the debugger think that the link map has changed. We can do this by temporarily removing our object from the doubly-linked list, but that requires changing the loader (since RTLD_NODELETE leaves the object in the link map even when the refcount is zero). Or we can do it by changing the debugger to be more conservative and (correctly) avoid assuming that an unchanged link map means unchanged symbol tables. The loader modifications are less invasive, and probably justify a new dlopen() flag, say RTLD_RELOADABLE, that removes and re-inserts across a 1-0-1 refcount transition (and that fakes the same remove-reinsert on an explicit dlreload(), even if the refcount does not go down). To make (2) work, we need to hope that we get the same mapping addresses when we re-map, and we need changes to the memory mappings to persist. We can do this by trapping the mmap() calls made by the loader and clearing the MAP_PRIVATE flag. This is what our gdb-script <test/elfproto-simple/gdb-script> does, and shows correct operation.