Reputation: 903
First Lua code:
local ffi = require "ffi"
ffi.cdef[[
void printc(const char *fmt, ...);
]]
ffi.C.printc("Hello world")
Does not work. Error:
boot.lua:6: /usr/lib64/libluajit-5.1.so.2: undefined symbol: printc
However, the symbol is in fact defined inside the executable that LuaJIT is running from (and the function declaration is copy-pasted from C):
$ nm --defined-only build/a.out | grep printc
00000000000650c1 T printc
My first idea for a solution was to build a shared library with the same symbols as the executable and load it in LuaJIT:
$ cc -fPIC -shared $LDFLAGS $OFILES -o build/a.so
New Lua code:
local ffi = require "ffi"
lib = ffi.load("./build/a.so")
ffi.cdef[[
void printc(const char *fmt, ...);
]]
lib.printc("Hello world")
This allows me to call the printc
function. However, there's a very big issue: the loaded library uses a separate memory space from the running program. The buffer that lib.printc("Hello world")
is writing to is not the same buffer as the program that LuaJIT is running in uses. It acts as if it's interacting an entirely different process.
printc
is supposed to print to the console subsystem of the executable that LuaJIT is running inside of. The console buffer is stored as a global (extern
) array of strings, which printc
writes to. The global console buffer that LuaJIT gets by loading a.so
points to some other memory address than global console buffer of the running a.out
program.
So that is not a viable solution. I don't know what I'm supposed to do now. The symbols are being exported as part of my executable but LuaJIT not loading them. I can't ffi.load
my executable either:
lib = ffi.load("./build/a.out")
boot.lua:2: ./build/a.out: cannot dynamically load position-independent executable
How can I get the LuaJIT FFI to load symbols from my running executable?
Upvotes: 3
Views: 1436
Reputation: 903
Passing the -rdynamic
flag to cc
fixes the issue, allowing LuaJIT to run ffi.C.*
functions from the program.
Upvotes: 1