Dear All:
I'm having the dreaded BINFMT_FLAT: reloc outside program error while
extending lua. Normally, lua likes to load code as a shared library
and I'm building this code into the executable instead, so as to get
around the lack of shared libraries on M68000 hardware.
BINFMT_FLAT: reloc outside program 0x61723a74 (0 -
0xffe83214/0x2f720), killing lua!
BINFMT_FLAT: reloc outside program 0x61723a74 (0 -
0xffe83214/0x2f720), killing lua!
I've searched through the list archives trying to track this down.
I've compiled with -fno-common, increased the stack size all to no
avail. There was a post earlier about having to rename variables and
avoiding that with -fno-common etc but that didn't work for me either.
I managed to track down the bug to the code that causes it (a SIGSEGV
accompanied by the above BINFMT_FLAT error) and hope that I could get
some help or insight as to what is actually going wrong. I've built
the same executable on Mac OS X and I've verified that it works there,
so the problem is isolated to uclinux.
In lua code, we have a luaL_Reg struct which associates a 'library'
name to a startup function. The startup function is normally supposed
to be called when the library is dynamically loaded, but once we place
it in the lualibs struct, then it gets called (preloaded) when lua
starts up. So far so good.
In the code below LUALIB_API gets defined to extern or
__declspec(dllimport) or __declspec(dllexport) (for Windows), so for
our purposes, we can just assume it's extern, since we aren't on
Windows. Lines marked 0 are part of lua-out-of-the-box and they work
fine (there are several others like it before that also work ok).
Lines marked 1 and 2 are my additions, which call the library
initialization functions.
#define LUA_LOADLIBNAME "package" // 0
LUALIB_API int (luaopen_package) (lua_State *L); // 0
#define LUA_SOCKLIBNAME "socket.core" // 1
LUALIB_API int (luaopen_socket_core) (lua_State *L); // 1
#define LUA_MIMELIBNAME "mime.core" // 2
LUALIB_API int (luaopen_mime_core) (lua_State *L); // 2
Now here is an array of these structs that lua walks through, calling
each initialization function as it finds it. I have added the lines
marked 3 to have the library initialization function called. If I
comment out the lines marked 3, then my executable runs fine. If I
include those lines, I get the SIGSEGV/BINFMT_FLAT error.
static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{LUA_SOCKLIBNAME, luaopen_socket_core}, // 3
{LUA_MIMELIBNAME, luaopen_mime_core}, // 3
{NULL, NULL}
};
m68k-elf-objdump -t lua.gdb > lua.dump gives me the following symbol
information ...
0003123c l O .data 00000058 lualibs
00010cee g F .text 00000028 luaopen_base
000164a2 g F .text 00000170 luaopen_package
000166c0 g F .text 0000005a luaopen_socket_core
0001671c g F .text 00000064 luaopen_mime_core
And running elf2flt with the -v flag gives me the following relocation
information. Strangely, here the fixups are zero for these symbols and
we're adding an awfully large offset to the symbol base, aren't we? I
noticed the BINFMT_FLAT error above had a huge offset (0x61723a74)
which is very likely much larger than my entire problem. Is this
normal? Or is that how we are getting to the data segment (where
lualibs contains the function pointer needing relocation) from the
text segment (where we are relocating to) in the flat binary?
So I guess my question is why does this work for luaopen_package, but
not for luaopen_socket_core? ie. How come lua will start fine with
luaopen_package active but crashes as soon as I introduce *any* of the
lines marked 3? Am I blowing my stack? I tried increasing stack size
via an export FLTFLAGS="-v -s 159999" and I still got the same
problem. Making the stack absurdly large got me a slightly different
error - "Illegal instruction" ... Adding debug printf's at the entry
points of the function pointers doesn't result in any output, so
something is happening as soon as these functions are called, but they
never actually get called.
RELOC[68]: offset=1b20 symbol=luaopen_base+0xfffef312 section=.text
size=4 fixup=0 (reloc=0x31240)
reloc[68] = 0x31240
RELOC[69]: offset=1b24 symbol=.text+0x2c555 section=.text size=4
fixup=2c555 (reloc=0x31244)
reloc[69] = 0x31244
RELOC[70]: offset=1b28 symbol=luaopen_package+0xfffe9b5e
section=.text size=4 fixup=0 (reloc=0x31248)
reloc[70] = 0x31248
RELOC[71]: offset=1b2c symbol=.text+0x2c54f section=.text size=4
fixup=2c54f (reloc=0x3124c)
reloc[71] = 0x3124c
RELOC[84]: offset=1b60 symbol=luaopen_socket_core+0xfffe9940
section=.text size=4 fixup=0 (reloc=0x31280)
reloc[84] = 0x31280
RELOC[85]: offset=1b64 symbol=.text+0x2c521 section=.text size=4
fixup=2c521 (reloc=0x31284)
reloc[85] = 0x31284
RELOC[86]: offset=1b68 symbol=luaopen_mime_core+0xfffe98e4
section=.text size=4 fixup=0 (reloc=0x31288)
reloc[86] = 0x31288
RELOC[87]: offset=1b74 symbol=.text+0x2c660 section=.text size=4
fixup=2c660 (reloc=0x31294)
reloc[87] = 0x31294
I don't really understand what is going wrong here and I'm learning a
lot more about the lua interpreter and elf2flt than I really need to
know just to include socket code into my application, so any help
would greatly appreciated :-) If I'm talking nonsense, then please let
me know ASAP too! :-)
-- G.