lua-users home
lua-l archive

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


>>>>> "William" == William Ahern <william@25thandclement.com> writes:

 William> There are at least two (maybe three) ways to hide the symbols:

This is an issue we've had to deal with in PostgreSQL, so we have
working examples of methods to deal with it on a fairly wide range of
platforms. (In our case, we have some functions that have "frontend" and
"backend" versions with the same name, where the "backend" version is
linked into the postgres server binary, but that binary sometimes needs
to load dynamic modules that contain frontend code and which have been
linked against the frontend version.)

We actually went so far as to include an explicit "link canary" file
that we can test to ensure that functions have not been mis-linked to
the wrong versions.

You can see the compiler options PostgreSQL uses for building shared
libraries (including dynamically loaded modules) for all our platforms
except Windows here:
https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/Makefile.shlib

(for Windows there's a bunch of scripts under src/tools/msvc)

 William> 1.a) #include the Lua source into the same C (or C++) source
 William> file as the extension module and set LUA_API to "static". This
 William> is the obvious, standard's compliant approach. However, this
 William> can be unwieldy (especially for C++) and not great for
 William> incremental builds.

This would have been impractical for us.

 William> 1.b) Use GCC's or clang's -fvisibility=hidden flag when
 William> building Lua. (Or try setting LUA_API to
 William> '__attribute__((visibility ("hudden")))'). This has the same
 William> effect as 1.a (truly "static" linking) but you can still build
 William> and cross-link separate .o object files.

A better variation on this is to link your dynamic libraries with an
explicit exports / version-script file that defines an exported symbol
API (optionally with a version) and hides all other symbols.

We currently use export files on AIX , MacOS, *BSD, Linux, and Windows.
(On Windows, and I believe also on AIX, the export file is required.) We
would likely use it on Solaris(-derivatives) and other ELF platforms if
anyone cared enough about them to contribute a tested makefile patch.

For Linux and *BSD the version script can just look something like:

{ global:
    func1;
    func2;
    func3;
  local: *;
};

and link with -Wl,--version-script=filename

For MacOS it's a plain list of symbols with _ prepended, and the compile
option is -exported_symbols_list filename

 William> 1.c) I think Mach-O has the ability to tweak symbol precedence
 William> to favor symbols defined in same shared object. I haven't
 William> explored this, though.

I don't know about MacOS, but a fair range of platforms support the
-Bsymbolic linker option, which means (when linking a shared library)
"resolve symbols within the library to their definitions now, rather
than at runtime". This is the option we use on HP-UX and Solaris.

 William> I'm not very familiar with Visual Studio so don't know how to
 William> do things there. If Visual Studio doesn't support something
 William> like -fvisibility=hidden you could try clang.

Windows DLL symbol resolution is not like ELF; one of the big
differences is that DLLs export only the symbols you explicitly tell
them to export (in the .DEF file) and nothing else.

-- 
Andrew.