lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




On 2018-02-26 07:04 PM, Sean Conner wrote:
It was thus said that the Great Soni They/Them L. once stated:
dlopen(NULL, ...) is a thing. Read about it.
   What you said is ambiguous.  It could mean

	dlopen(NULL), ...) is a thing.  I have read about it.

or

	dlopen(NULL), ...) is a thing.  You should read about it.

   With that said, yes, I am aware of dlopen(NULL,...).

It means the symbols need
to be exported during linking, even if the linking is static. It just
means you have dynamic lookup of "static"-ish symbols. It's complicated.
   Yes.  But the presence of dlopen(NULL) in the code does *NOT*
automatically cause the symbol information to be included in the final
executable.

If you're turning them straight into a statically linked library, you
can still do it but I'm not sure how. (I mean the linker has to find the
symbols somewhere, right?)
   Yes.  In the object file itself:

	% cat c1.c
	extern int printf(char const *,...);
	
	int A(int x)
	{
	  printf("%d\n",x);
	  return x;
	}
	% gcc -c c1.c
	% readelf -a c1.o
	  [ output snipped ]

	Symbol table '.symtab' contains 10 entries:
	   Num:    Value  Size Type    Bind   Vis      Ndx Name
	     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
	     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS c1.c
	     2: 00000000     0 SECTION LOCAL  DEFAULT    1
	     3: 00000000     0 SECTION LOCAL  DEFAULT    3
	     4: 00000000     0 SECTION LOCAL  DEFAULT    4
	     5: 00000000     0 SECTION LOCAL  DEFAULT    5
	     6: 00000000     0 SECTION LOCAL  DEFAULT    6
	     7: 00000000     0 SECTION LOCAL  DEFAULT    7
	     8: 00000000    30 FUNC    GLOBAL DEFAULT    1 A
	     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf

	...
	%

which involves adding some new entries to the package.searchers array (I
update package.loaders but that's because I'm using Lua 5.1 in that
particular project).  Another way when statically linking in C based Lua
modules is to populate the luaopen_() calls in the package.preload array.
Assuming you're turning pre-built shared objects into statically linked
libraries, this is still trivial.
   I'm not sure how you think this is done, or where.  Yes, it's easy, but it
involves writing C code, not linker magic.

Interesting. So C modules could be renameable if they supported what I
proposed.
   Again, how?
Because they can rely on the passed-in names rather than relying on
hardcoded names.
   Again, I think you have a misunderstanding about how this works.  You have
this in Lua:

	local foo = require "foo"

require() will first look in package.loaded for a "foo" entry.  Not finding
it there, it will then call the functions in the package.searchers array.
The first will attempt to find the "foo" entry in package.preload.  If that
one fails, the next will attempt to look for "foo.lua" (or "foo/init.lua")
using the paths in package.path.  So now we get to the searcher for C based
Lua modules.  It attempts to locate "foo.so" (or "foo.dll" on Windows).

   Okay, it finds a "foo.so".  It loads it via dlopen().  It then needs the
address of the entry point of the module, and it's here were the problem
manifests itself---what is the symbol name?

   It can't be "luaopen".  While what will work on Linux (and probably Mac
OS-X and maybe even Windows, I don't know) there apparently *are* systems
out there with dynamic library support that can't handle the same symbol
from multiple dynamic objects (per an email from Roberto).  It will also
have problems when compiling the modules statically (it will require a
source change).

   The solution Roberto came up with is, look for "luaopen_foo"---in other
words, append the module name to the end of "luaopen_" (and change any "."
in the module name to "_") and look for *that* symbol.  If I simply change
the name of "foo.so" to "bar.so" and try to do:

	local bar = require "bar"

it will fail, because "bar.so" does not contain the symbol "luaopen_bar".
Renaming the dynamic object does *NOT* change any of the symbols defined
inside the dynamic object, which is why I keep asking you "how".  If the
entry point isn't found, Lua can't even pass in the module name and file to
it.

   Now, Lua 5.3 *DOES* contain package.loadlib(), which is a wrapper around
dlopen()/dlsym().  So keeping in mind the limitations (there must be a
unique symbol identifying the entry point of a C module), if you can come up
with a way to rename a C-based Lua module and still find that unique symbol
*WITHOUT RECOMPILING THE MODULE*, then by all means, go ahead.  I'd love to
see the solution.

   -spc



Since I can access the symbol table (by reading the module with io.open and looking at all of its symbols), I can probably write something that finds the common prefix for all luaopen_* and omits it when doing requires. This should solve the problem?

Luckily I don't need my package manager to support non-POSIX systems with dlopen functions.

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.