@c -----------------------------------------------------------------------------
@node dxegen, dxe3gen, , Top
@chapter @command{dxegen}
@pindex dxegen

Usage: @kbd{dxegen outfile.dxe _symbol infile.o [infile2.o @dots{} -lgcc -lc]}

@command{dxegen} is a utility which allows you to create files which contain
dynamically loadable code (@acronym{DXE}).  This command is retained for
compatibility purposes and is a symlink to @command{dxe3gen} (@pxref{dxe3gen}).

The image must be self-contained, and it cannot reference symbols from the
main image.  As a consequence, you cannot do I/O and some other functions
directly from a @acronym{DXE} loaded image.

Constructors, destructors, and C@t{++} exceptions do not work.

There is a single entry point (procedure or data block) returned.  This
can be a vector of routines you have created.

@file{outfile.dxe} is the name you want to contain your dynamic load code.

@code{_symbol} is the procedure name (or data structure) you want a pointer to.
You must add an initial underscore for most symbols created from C.

@file{input.o} is created with GCC from your source.  Additional arguments
on the command line (.o and .a files; or other ld options) are passed to
ld to resolve references to build your code.

The floating point emulator code provided by DJGPP is stored in a
@acronym{DXE}.

See the documentation for @code{_dxe_load} (@pxref{_dxe_load, , _dxe_load, libc})
for details on how to load the dynamic code.


@c -----------------------------------------------------------------------------
@node dxe3gen, dxe3res, dxegen, Top
@chapter @command{dxe3gen}
@pindex dxe3gen

Usage: @kbd{dxe3gen [-o output.dxe] [options] [object-files] [ld-options]}

@example
-o output.dxe	Define the name of output DXE file
-P module.dxe	Specify dependency module (cumulative)
-I import.a	Create an import library for given DXE file
-Y import.a	Create autoresolved import library for given DXE file
-D description	Set module description string
-E prefix	Export only symbols that start with <prefix> (cumulative)
-X prefix	Exclude symbols that start with <prefix> (cumulative)
-U		Allow unresolved symbols in DXE file
-V		Verbose output (minimal output by default)
--show-dep	Show dependencies for specified module
--show-exp	Show symbols exported by the DXE module
--show-unres	Show unresolved symbols in the DXE module
[ld-options]	Any other options are passed unchanged to ld


dxe3gen responds to the following environment variables:

DXE_CC: C compiler name. If not set, defaults to gcc for native build
environments, and i586-pc-msdosdjgpp-gcc for cross-build environmlents.
DXE_AS: Assembler name. If not set, defaults to as for native build
environments, and i586-pc-msdosdjgpp-as for cross-build environmlents.
DXE_AR: Archiver name. If not set, defaults to ar for native build
environments, and i586-pc-msdosdjgpp-ar for cross-build environmlents.
DXE_LD: Linker name. If not set, defaults to ld for native build
environments, and i586-pc-msdosdjgpp-ld for cross-build environmlents.
DXE_SC: Path to linker script name. If not set, defaults to dxe.ld.
Passed internally to ld, like 'ld -T dxe.ld'
@end example

@command{dxe3gen} is a utility which allows you to create files which contain
dynamically loadable code (@acronym{DXE}).  @acronym{DXE} is used as a synonym
for `dynamically loadable executable module', also called sometimes `dynamic
modules' or simply `modules' in this document.  File names provided as 
arguments should not contain special characters that require quoting 
or they may not be passed properly to @command{ld}.

There are several ways to use @acronym{DXE} modules.  You may either
load/unload modules at runtime or to link with them (or rather with so-called
`import libraries') at link time (e.g. statically link with dynamic libraries).

@command{dxe3gen} allows you to build either dynamic modules that don't have
unresolved symbols as well as dynamic modules that DO have unresolved symbols
(and allows you to resolve them at runtime).  If your @acronym{DXE} references
symbols in your main image, you must provide it the locations for those symbols
or use the @command{dxe3res} command.

Statically linking against dynamic libraries allows for a easy way to
introduce dynamic modules into any program.  `Static linking' means that during
linking stage of your program you link against certain library, called a
`import library' in the following, which provides all the functions present in
certain @acronym{DXE} module.  The symbols points to some very small wrappers,
and when you call any of those functions, the library is automatically loaded
and the call is redirected further.  Also you may load/unload the library manually
by calling some special functions called @code{dlload_MODNAME} and @code{dlunload_MODNAME}
functions (where @code{MODNAME} stands for the name of your dynamic module).

The @command{dxe3gen} tool can build these import libraries, so basically you
just take a existing @acronym{DXE} module and generate the corresponding import
library for this module (see the `Import libraries' section).  Then you link
against it... and voila! it works.

Static linkage against dynamic libraries has a drawback: you @emph{CANNOT} have
exported data inside the library (at least you can't use it).  This happens
because the symbols are resolved to the wrappers and not to the actual symbols
inside the module.  That is, if you have a variable called @code{i} in a dynamic
module, and you assign @code{i = 1} from your program which is statically linked
against that module, you will actually write over the wrapper and not into the
actual location where the contents of @code{i} are.  If you really need to
set/get values of some variables inside a dynamic module, write a couple of
set_i and get_i *functions*.

Some modules require other modules to be already loaded when they are hit
(either via @code{dlopen()} or a call into their corresponding import library).
Don't worry about that: just use the @kbd{-P} (dependency) option of the generator.

Another way to use @acronym{DXE} modules is implemented through the
@code{dlopen()} API (@pxref{dlopen, , dlopen, libc}).  This API closely
mimics the one found on many Unix-like systems, thus you may even build
some Unix applications that use dynamic libraries without a single change.

The dynamic loader supports initialization and finalization functions
inside dynamic libraries.  You may use the standard C/C@t{++} way of doing
initialization/finalization, for example (C@t{++}):

@example
	class __init
	@{
	  __init ()
	  @{
	    @dots{} initialization stuff
	  @}
	  ~__init ()
	  @{
	    @dots{} finalization stuff
	  @}
	@} __dummy_object;
@end example

The above approach will work on any platform with a C@t{++} compiler.  During
program (or shared library) startup the constructor for the
@code{__dummy_object} is called, and during program (or shared library)
shutdown the destructor is invoked.  For plain C you will have to use the GNU C
extensions:

@example
	void __attribute__((constructor)) __init_func ()
	@{
	  @dots{} initialization stuff
	@}

	void __attribute__((destructor)) __finit_func ()
	@{
	  @dots{} finalization stuff
	@}
@end example


@section Building a DXE

To build a @acronym{DXE} module you will use the @command{dxe3gen} tool.

Now suppose you have some library which you want to turn into a @acronym{DXE}
module.  To do this inside the makefile for your library add a rule like this:

@example
mylib.dxe: one.o two.o three.o four.o
	dxe3gen -o $@ $^
@end example

That is, the @kbd{dxe3gen -o mylib.dxe one.o two.o three.o four.o} will build
the @file{mylib.dxe} dynamically-loadable module.  All public (e.g. non-static)
symbols will be exported, and you may query the address for any of them with
the @code{dlsym} API function.

Now suppose you use some functions from the C library, like @code{strcpy},
@code{strlen} and so on.  In this case @command{dxe3gen} will list all those
symbols and will tell you that they are `unresolved', because these functions
are not present in any of the object files you have specified on the command
line.  From now on you have several ways to go:

-*- You can link the @acronym{DXE} module with the C library by specifying
@kbd{-lc} on the @command{dxe3gen} command line.  This effectively will add all
the unresolved symbols to your @acronym{DXE} module, taking them from the C
library.  Drawbacks:

@itemize @bullet

@item
If your program and/or other modules use same functions, this will
duplicate the code through all of them.

@item
Many functions won't work this way because they refer to other symbols in
other libraries such as @kbd{-lgcc}, the later usually refers some symbols
from @file{crt0.o} and you can't link with @file{crt0.o} (well, you can but
you cannot launch crt0.o's initialization routine because it will screw many
things up).  For example, you can't link against @kbd{-lc} to get the
@code{printf} routine.  Most file functions and memory allocation functions
are a no-no as well.

@item
Sometimes it could lead to a deadly-embrace situation: suppose you
resolve against LIBC, build an import library and then link with it.  If
the functions you extracted from LIBC are made visible (exported) in the
module, the corresponding import library will contain references to them.
Then, the linker might consider the symbols from your library, instead of
LIBC.  Here comes the nastiness: until the module is loaded, all those
symbols are nothing but wrappers to @code{dlopen}.  The worst case is when
@code{dlopen} fires but calls such a function, which again will try to load
the module and so on.  As a workaround, keep such names unexported by
filtering exported names through @kbd{-E} option.

@end itemize

-*- The best way is to leave the symbols unresolved and resolve them at
runtime. To tell @command{dxe3gen} to not fail on unresolved symbols, add the
option @kbd{-U}.  This will build a @acronym{DXE} module with unresolved
symbols.

Before loading such a module you should provide somehow the missing symbols
to the @acronym{DXE} loader so that it can fix up all the references to those
missing functions.  If it doesn't succeed, the loader will fail.
The easiest way to provide symbol references is using @command{dxe3res}.

There are several ways to provide symbol references to loader.  The first
one is to provide a explicit pointer to every function you are going to
export into dynamically-loadable modules.  You can do it with a couple of
handy macros:

@example
	#include <sys/dxe.h>

	DXE_EXPORT_TABLE (exported_symbols)
	  DXE_EXPORT (printf)
	  DXE_EXPORT (strcpy)
	  DXE_EXPORT (strcat)
	  @dots{}
	DXE_EXPORT_END

    or:

	#include <sys/dxe.h>

	extern_asm(_printf);
	extern_asm(_strcpy);
	extern_asm(_strcat);
	@dots{}
	DXE_EXPORT_TABLE (exported_symbols)
	  DXE_EXPORT_ASM (_printf)
	  DXE_EXPORT_ASM (_strcpy)
	  DXE_EXPORT_ASM (_strcat)
	  @dots{}
	DXE_EXPORT_END
@end example

Both the above sequences are equivalent.  As you can see, @code{DXE_EXPORT_ASM}
macro requires its parameter to be previously declared with "extern_asm".
Now you should pass this export table to the dynamic linker:

@example
	dlregsym (exported_symbols);
@end example

The loader now knows these symbols so if any loaded module has
references to them, it knows how to resolve them.  You may call @code{dlregsym}
as much as you want, the symbols are accumulating in a internal table
of the dynamic loader.  Also you may unregister symbols with @code{dlunregsym}
function.

Another way to resolve symbols is to make all exported symbols in one
module global, thus they get added to the global symbol table and when
a new module with unresolved symbols is loaded, these shared libraries
are searched for the corresponding exported symbol. This allows you to
use symbols from one module as regular `extern's in another module.
A simple example:

@example
	---------- module A
	void something ()
	@{
	  @dots{}
	@}
	---------- module B
	extern void something ()
	void something_else ()
	@{
	  something ();
	@}
@end example

When you link module B, you use the @kbd{-U} switch to suppress the warning
about symbol `something' being unresolved.  Now from your program you
first load the module A:

@example
	dlopen ("moduleA.dxe", RTLD_GLOBAL);
@end example

then load the module B:

@example
	dlopen ("moduleB.dxe", 0);
@end example

The references are now resolved.  Note that during first @code{dlopen} call
the @code{RTLD_GLOBAL} flag is specifed so that all exported symbols become
visible to other modules.

The third and most powerful way is to use the @command{dxe3res} tool
(@pxref{dxe3res}).  It combines the previous methods and requires minimal
interaction from the user, as the table is built automatically.  To be more
specific, dxe3res outputs a valid C source file, which must be compiled and
linked with your application:

@example
	dxe3res -o table.c moduleA.dxe moduleB.dxe
@end example

Also sometimes you may want to build a @acronym{DXE} module from a ready
library. For example, you can build @acronym{DXE} modules of @file{libjpeg.a},
@file{libpng.a} and @file{libz.a} without recompiling the libraries.  For
this you should specify a special option to the linker: @kbd{--whole-archive}
(this is a GNU @command{ld} option, it is just passed to @command{ld} by
@command{dxe3gen}):

@example
	dxe3gen -o z.dxe -Y libz_i.a --whole-archive -U libz.a \
	  -D "Zlib compression library"

	dxe3gen -o png.dxe -Y libpng_i.a --whole-archive -U libpng.a \
	  -D "Portable Network Graphics (PNG) Reference Library"

	dxe3gen -o jpeg.dxe -Y libjpeg_i.a --whole-archive -U libjpeg.a \
	  -D "The Independent JPEG Group's JPEG software"
@end example

You should call all import libraries @file{libsomething_i.a}, to avoid
confusion.

@section Import libraries

Import libraries are a special kind of libraries (@file{.a}) which contains
a number of very small wrappers (just long jumps to the actual functions
inside the dynamic module and two functions: @code{dlload_MODNAME} and
@code{dlunload_MODNAME}.

Initially all jumps are directed to @code{dlload_MODNAME}, thus when you call any
function from a dynamic module it initially arrives to @code{dlload_MODNAME} function.
Then the module is loaded, all jumps are directed to the respective locations
inside the dynamic module, and the last call is restarted.

As you may understand (and mentioned above), this approach does not
work with variables.  This is one of the drawbacks of this method.

To build a import library you should use the @kbd{-Y} switch on the @command{dxe3gen}
command line.  The import library can be built from a ready @acronym{DXE} module as well
as `on-the-fly' during @acronym{DXE} generation process.  For example, you can do:

@example
	dxe3gen -Y libmy.a -o my.dxe one.o two.o three.o
@end example

as well as

@example
	dxe3gen -o my.dxe one.o two.o three.o
	dxe3gen -Y libmy.a my.dxe
@end example

Both above sequences are equivalent.  The @kbd{-I} switch does the same 
thing as the @kbd{-Y} option and is used if you do not want to have symbols
automatically resolved (when they are provided by another @acronym{DXE}, 
for example).  

@section Contacts

This library was designed specifically for the Crystal Space project
(see @uref{http://crystal.sourceforge.net}), but it is very general and 
useful in other environments as well.

Daniel Borca, <dborca@@yahoo.com>
Andrew Zabolotny, <bit@@eltech.ru>

@c -----------------------------------------------------------------------------
@node dxe3res, , dxe3gen, Top
@chapter @command{dxe3res}
@pindex dxe3res

Usage: @kbd{dxe3res -o linkage.c moduleA.dxe moduleB.dxe @dots{}}

The @command{dxe3res} tool takes one or more @acronym{DXE} modules and
creates a C source file which will transparently load the @acronym{DXE} as if
it were linked into your image.  The C source file must be compiled and
linked with your application.

@example
	dxe3res -o table.c moduleA.dxe moduleB.dxe
	gcc -c -O2 table.c
	gcc mymain.o table.o
@end example
