home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
emxtutor.zip
/
emxdevj.zip
/
emxdev.doc
< prev
next >
Wrap
Text File
|
1996-03-03
|
154KB
|
3,878 lines
===============================================================================
emxdev.doc emx 0.9a APPLICATION DEVELOPER'S GUIDE 05-Dec-1994
===============================================================================
Copyright (c) 1990-1994 by Eberhard Mattes
1 Table of Contents
===================
1 Table of Contents
2 Introduction to the emx Application Developer's Guide
3 Managing bound .exe files with emxbind
3.1 Creating an .exe file
3.2 Changing the type of an .exe file
3.3 Extracting the a.out file from a bound .exe file
3.4 Displaying and changing the emx options of a bound .exe file
3.5 Updating emx.exe in a bound .exe file
3.6 Stripping the symbol table from a bound .exe file
3.7 Module definition files
3.7.1 Module definition statements
3.7.2 Reserved words
4 Using emx options
5 More emx utilities
5.1 updt
5.2 emximp
5.2.1 What is an emx import list file?
5.2.2 Creating an emx import list file from an OMF import library
5.2.3 Creating an emx import list file from a module definition file
5.2.4 Creating an emx import library for method (I1)
5.2.5 Creating an a.out import library for method (I2)
5.2.6 Creating an OMF import library for method (I3)
5.2.7 Creating a module definition file for method (I3)
5.3 emxomf
5.4 emxomfld
5.5 emxomfar
5.6 emxexp
5.7 emxaout
5.8 emxcat
5.9 emxload
5.10 emxrev
5.11 listomf
6 Hints for porting Unix programs to emx
7 Creating OS/2 programs
7.1 Calling OS/2 API functions
7.2 Importing from OS/2 DLLs
7.3 Creating Presentation Manager applications using ld and emxbind
7.4 Creating Presentation Manager applications using emxomf and LINK386
7.5 Creating Workplace Shell applications
7.6 Creating dynamic link libraries
7.6.1 Creating dynamic link libraries that use a C library DLL
7.6.2 Creating custom C runtime DLLs
7.6.3 Creating C runtime forwarder DLLs
7.6.4 Creating stand-alone dynamic link libraries
7.6.5 Creating dynamic link libraries without C runtime environment
7.6.6 Creating resource DLLs
7.6.7 Creating dynamic link libraries using C++
7.7 Using the DLL version of the C library
7.8 Creating multithread programs
7.9 Calling 16-bit functions
8 Customizing
8.1 Increasing the heap size
8.2 Increasing the stack size
8.3 Increasing the number of files
9 Debugger (DOS)
10 Executable file format
11 Known problems
2 Introduction to the emx Application Developer's Guide
=======================================================
This document describes how to use emx utilities to create programs
running under emx and how to create OS/2 programs with the emx
utilities. In this document, OS/2 stands for OS/2 2.x and OS/2 3.x.
The GNU utilities are described in /emx/doc/gnudev.doc and
/emx/book/gnudev.inf.
There are three methods for creating executable files:
(E1) using ld and emxbind
(E2) using emxomf, emxomfld and LINK386, the program will use the
emx.dll dynamic link library for performing system calls
(E3) using emxomf, emxomfld and LINK386, the program will be linked
with a system call library (creating a stand-alone application
or DLL)
The assembler creates a Unix-style a.out object file (.o file). When
using method (E1), .o files created by the assembler are linked by a
Unix-style linker with Unix-style libraries (.a files) to create a
Unix-style a.out file. Then, emxbind is used to turn this file into
an .exe file that can be executed under both OS/2 and DOS. Using
method (E1) enables core dumps and fork(). Moreover, programs created
with method (E1) can be debugged using GDB, the GNU debugger.
Programs created using method (E1) use emx (emx.dll under OS/2,
emx.exe under DOS) for system calls.
When using method (E2), the .o files created by the assembler are
converted to Object Module Format files (.obj files). These files are
linked with the OS/2 linker LINK386. The libraries are .lib files.
emxomfld is a front end to LINK386 which converts the ld command line
to a LINK386 command line. Programs created with method (E2) cannot
create core dumps, cannot call fork() and cannot be debugged with GDB.
Method (E2) works only under OS/2 and creates programs that work only
under OS/2. You can use IBM's IPMD debugger to debug programs created
with methods (E2) and (E3). Files created with method (E2) are
usually smaller. The emx.dll dynamic link library is used for system
calls. The -Zomf option of GCC selects method (E2).
When using method (E3), the program won't call the emx.dll dynamic
link library. A system call library (emx emulator) is linked to the
program. The system call library maps system calls to OS/2 API calls.
Only a subset of the emx system calls is available with method (E3).
For instance, the general terminal interface is not available.
Functions which are not available or are limited with method (E3) are
marked [*] in the library reference. Use a module definition file and
the STACKSIZE statement to set the stack size. Alternatively, you can
use the -Zstack option of GCC. The default stack size is 0x8000
bytes. Note that the command line arguments and environment pointers
are copied to the stack on startup.
The following table summarizes the methods for creating executable
files.
Method │ (E1) │ (E2) │ (E3)
───────────────────────────────┼──────────────┼─────────────┼──────────────
GCC options │ │ -Zomf │ -Zomf -Zsys
Object file format │ a.out │ OMF │ OMF
Object file name extension │ .o │ .obj │ .obj
Library file name extension │ .a │ .lib │ .lib
Executable file format │ LX & a.out │ LX │ LX
Object files converted by │ N/A │ emxomf │ emxomf
Executable files converted by │ emxbind │ N/A │ N/A
Linker │ ld │ LINK386 │ LINK386
Librarian │ ar │ emxomfar │ emxomfar
Minimal set of libraries │ c gcc │ c gcc │ c gcc
│ │ emx emx2 │ sys os2
Methods for importing │ (I1) (I2) │ (I3) │ (I3)
Can link with OMF libraries │ NO (note 1) │ NO (note 1) │ YES
Debugger │ GDB │ IPMD │ IPMD
emx.dll required at run time │ YES │ YES │ NO
Library support │ +++ │ ++ │ +
Core dumps │ YES │ NO │ NO
Size overhead │ big │ none │ (note 2)
Programs run under DOS │ YES │ NO │ NO
Can create DLLs │ YES (note 3) │ YES │ YES
EMXOPT environment variable │ YES │ YES │ NO
-Zmt supported │ YES │ YES │ YES
-Zcrtdll supported │ YES │ YES │ NO
Note 1:
import libraries can be used after conversion with emximp
Note 2:
depends on the set of syscalls used by the program
Note 3:
not recommended
See also section `Startup modules and libraries' of gnudev.doc.
Programs created with method (E1) or (E2) can use emxlibcm.dll or
emxlibcs.dll, dynamic link libraries containing the C library. Use
the -Zcrtdll option to make a program that uses emxlibcm.dll
(multithread library) or emxlibcs.dll (single-thread library).
Programs which use emxlibcm.dll or emxlibcs.dll don't run under DOS.
For running the application, either emxlibcm.dll or emlibcs.dll
(depending on whether the application is a single-thread or
multithread program) and emx.dll are required. There are three
advantages of using emxlibcm.dll and emxlibcs.dll:
- reduced executable size
- reduced memory requirements
- programs don't have to be re-linked when the C library is changed.
Use -Zomf -Zcrtdll -lwrap -s to minimize the size of the executable
file.
Please note that you should change the name of emxlibcm.dll or
emxlibcs.dll if you want to distribute your program with modified
versions of those dynamic link libraries.
For using floating point arithmetic, a coprocessor is required (80387
or i486). All exceptions are masked, that is, computation continues
with +#INF, -#INF, +#NAN or -#NAN after an error.
A 387 coprocessor is not required for doing floating point arithmetic
under OS/2. Under DOS, a 387 coprocessor (or i486) is required for
doing floating point arithmetic.
A core dump file will be written if a program is terminated by signal
SIGSEGV (protection violation), SIGILL (illegal instruction), SIGABRT
(abort()), SIGFPE (floating point exception), SIGTRAP (breakpoint),
SIGBUS, SIGEMT, SIGQUIT, or SIGSYS. You can later debug the program
using the .exe file and the core dump file. The name of the core dump
file is core, and it is put into the current working directory. Use
the -c emx option to suppress writing a core dump file. When linking
a program using method (E2) or (E3), core dump files are not written
by that program.
OS/2 and DOS support both the forward slash and the backslash for
separating directories. Unix utilities usually treat the backslash
character specially, therefore you should use the forward slash. This
document uses forward slash unless an OS/2 or DOS command is shown
(cmd.exe and command.com use backslashes).
File name extensions (the list is incomplete):
a Unix-style library (archive)
bat DOS batch file
c C source file
cc C++ source file
cmd OS/2 batch file
cpp C++ source file
cxx C++ source file
def Module definition file
doc Documentation file
dll Dynamic link library
dvi Device independent file, created by TeX
exe Executable file
h C include file (header file)
i<digits> Split GNU info file
imp emx import list file
inf GNU info file (use `info' for reading) or
OS/2 on-line book (use `VIEW' for reading)
lib OMF library
m Objective C source file
map Map file, created by LINK386 or emxbind
o Object file (Unix style, a.out)
obj Object file (OMF)
rc Resource script file
res Binary resource file
s Assembler source file
tex TeX (or texinfo) source file
Directories:
/emx Main directory, contains no files
/emx/bin Executable files and batch files
/emx/dll OS/2 DLL files
/emx/doc Documentation
/emx/include Header files (C language)
/emx/lib Libraries
/emx/lib/mt Multithread libraries
/emx/lib/st Single-thread libraries
/emx/new New .exe files created by the makebin batch file
/emx/samples Sample programs
/emx/src Source code
/emx/test Test programs
3 Managing bound .exe files with emxbind
========================================
The emxbind utility is used to create and modify bound .exe files
using method (E1). The action to be performed is specified by a
command letter which looks like a command line option.
3.1 Creating an .exe file
-------------------------
emxbind binds emx.exe and an emx executable file into one executable
file which runs both under OS/2 (6.167 or later) and DOS.
Usage:
emxbind [-b] [<emxbind_options>]
<emx>[.exe] <input_file> [<output_file>[.exe]] [<emx_options>]
emxbind [-b] [<emxbind_options>] <input_file> [<emx_options>]
<emxbind_options>
The following options can be given to emxbind. They must appear
at the beginning of the emxbind arguments.
-b (optional)
this emxbind command means `bind' and is the default. If
you want to use the -s option (strip symbol table), -b
cannot be omitted, that is, you should type -bs
(otherwise, emxbind would perform the -s command described
below)
-c[<core_file>]
combine an a.out file and a core dump file created for
that a.out file into one program. This can be used to
create a a program with preloaded data. Note that the
.exe file will waste a lot of disk space. If you don't
enter <core_file>, core is used
-d[<def_file>]
read the module definition file <def_file>. The default
extension is .def. If <def_file> is omitted, <input_file>
with .def extension is used instead. See section 3.7 for
details on module definition files
-E<dll>
use <dll>.dll instead of emx.dll. This option is used for
referencing an alternate, renamed emx.dll. If -E<dll> is
not used, emxbind takes the name of the DLL from the
EMXBIND_DLL environment variable. For instance, to use
myx.dll instead of emx.dll, use the following command:
set emxbind_dll=myx
If both -E<dll> and EMXBIND_DLL are not set, emxbind uses
emx.dll
-f set application type to `full screen'. See also the -e
command
-h<heap_size>
set heap size for OS/2. This is the space available for
allocation by malloc() and _tmalloc(). The number is
given in decimal, octal or hexadecimal, using C notation.
The heap size is specified in megabytes (1 through 512).
The default value is 32. For DOS, the heap size is
controlled by the -s# emx option (see section 4)
-k<stack_size>
set the size of the stack object of the executable file.
The number is given in decimal, octal or hexadecimal,
using C notation. The stack size set by this option is
used under OS/2. The stack size is given in KByte, the
default is 8192 (8 MByte). The stack size must be between
20 and 524288 (512 MByte). The stack size should not be
less than 32 KByte. You should not use -k without -b, as
a -k command is planned for a future version of emxbind
-m<map_file>
write the map file <map_file>. The format is simular to
that of map files written by LINK386. The default
extension is `map'.
-p set application type to `Presentation Manager'. See also
the -e command
-q don't display emxbind banner line
-r<res_file>
put resources from binary resource file <res_file> (no
default extension) into the .exe file. Use rc -r to
create the binary resource file. Do not use rc to put the
resources into the .exe file
-s strip symbols (requires -b). You can also strip the
symbol table before creating the .exe file by calling
strip.exe or after creating the .exe file by using the -s
command of emxbind
-v display more information: list resources, display path
name of emxl.exe unless given on command line, display the
statements in the module definition file that are ignored
-w set application type to `windowed' (default). See also
the -e command
Only one of the options -f, -p and -w can be used. If none of
these options is used, the application type is taken from the NAME
statement of the module definition file (-d option). If no module
definition file is used, -w is the default.
<emx> (optional if no output file is given)
path name of emx (default extension: .exe), that is emx.exe,
emxd.exe or emxl.exe. Using emxl.exe is recommended. If this
argument is omitted (in this case the <output_file> argument must
be omitted as well), the filename from the STUB statement of the
module definition file is used. emxbind searches the directories
listed in the EMXPATH and PATH environment variables for that
file. If no module definition file is used or if the STUB
statement isn't used, the file /emx/bin/emxl.exe will be used. If
that file doesn't exist, emxbind searches the directories listed
in the EMXPATH and PATH environment variables for emxl.exe. If
that fails, emxl.exe is taken from the current working directory.
If the -v option is given, the path name of emxl.exe will be
displayed unless a STUB statement is present
<input_file>
path name of the a.out file to be read
<output_file> (optional)
path name of the bound executable file. The default extension is
.exe unless the LIBRARY statement is used in the module definition
file. If LIBRARY is used in the module definition file (that is,
when you are creating a dynamic link library), the default
extension is .dll. If the <output_file> parameter is omitted, the
<input_file> parameter will be used instead (do not specify an
extension for the input file to avoid overwriting the input
file!). Moreover, the output file name (or <input_file>, if
<output_file> is omitted) sans directory part and extension is
used as module name for the .exe file unless a module name is
defined with a NAME or LIBRARY statement in the module definition
file
<emx_options> (optional)
emx options to be used when running the bound program. These
options will be examined before those given in EMXOPT. emxbind
does not completely check the validity of the options. See
section 4 for details.
-a* [DOS] Enable dangerous features
-c Disable core dumps caused by signals and exceptions
-d [DOS] Don't use extended memory
-e [DOS] Redirect standard error to standard output
-h# Set file handle limit
-n [OS/2] Suppress exception popups
-o [DOS] Send the register dump of an exception to stdout
instead of the CON device
-p [DOS] Don't use low memory (lower Megabyte)
-q Quote all arguments passed to child processes
-s# [DOS] Set stack size (KByte)
-t Truncate file names to 8.3
-x [OS/2] Don't suppress wildcard expansion and response
files if the `MKS Korn shell' method of passing command
line arguments is used
-C# [DOS] Commit memory
-E Run debuggee in same session
-K Avoid using DosKillThread
-L [DOS] Disable preloading of pages from the executable file
-Z [DOS] TODO
Example:
emxbind \emx\bin\emxl myprog -s16384 -p
This example will bind myprog and emxl.exe into myprog.exe. The stack
size will be set to 16384 KByte (under DOS) if this value is not
overridden by EMXOPT when myprog.exe is run. The program will be able
to run DOS programs. This example can be abbreviated to
emxbind myprog -s16384 -p
The bound program does not run under DOS versions prior to 3.0. emx
options cannot be put onto the command line; use EMXOPT instead.
Do not compress the bound executable with a program like TINYPROG,
PKLITE, or LZEXE, which makes the program uncompress itself when
started.
emx can be used for running bound .exe files created using the same
version of emx. spawn*() and exec*() also work on bound .exe files.
The GNU programs GDB, nm, objdump and size (but not strip) have been
modified to work with bound .exe files.
You can use the emx loader emxl.exe to save disk space. When the
bound executable is run, emxl.exe will load emx.exe to run the
program. There is a small speed penalty due to locating and loading
emx.exe.
If the EMX environment variable is set, emxl.exe first tries to load
the file specified by that variable. Use
SET EMX=c:\emx\bin\emx.exe
to speed up locating emx.exe. You can also use emxd.exe this way.
If the EMX environment variable is not set or the emx.exe file
specified by EMX could not be loaded, emxl.exe will try emx.exe in the
current working directory, then emx.exe in all directories listed in
the PATH environment variable.
3.2 Changing the type of an .exe file
-------------------------------------
You can change the application type after creating an .exe file with
emxbind. For instance, this can be used after creating an .exe file
with GCC. Exactly one of the options -f, -p and -w must be given.
Note that you can set the application type while creating an .exe file
with the -b command.
Usage:
emxbind -e <emxbind_options> <program_file>[.exe]
<emxbind_options>
The following options can be given to emxbind. They must appear
at the beginning of the emxbind arguments.
-e change the type of an .exe file
-f set application type to `full screen'
-p set application type to `Presentation Manager'
-q don't display emxbind banner line
-w set application type to `windowed'
Exactly one of the options -f, -p and -w must be given.
<program_file>
path name of the bound .exe file to be changed. The default
extension is .exe
Example:
gcc -o myprog.exe myprog.c
emxbind -ep myprog
Alternatively, you can create a file named myprog.def containing
NAME WINDOWAPI
and invoke GCC with the following command line:
gcc -o myprog.exe myprog.def
3.3 Extracting the a.out file from a bound .exe file
----------------------------------------------------
Usage:
emxbind -x [<emxbind_options>] <input_file>[.exe] <output_file>
<emxbind_options>
The following options can be given to emxbind. They must appear
at the beginning of the emxbind arguments.
-q don't display emxbind banner line
-x extract a.out file
<input_file>
path name of a bound .exe file to be read. The default extension
is .exe
<output_file>
path name of the a.out file to be created
After extracting the a.out file from an .exe file which was created
using a core dump file, you should not use that file for creating an
.exe file. Use the -u command if you want to replace emx.exe,
emxl.exe or emxd.exe contained in a bound .exe file.
The relocation information is removed by emxbind while binding an .exe
file. Therefore, the a.out file extracted from a bound .exe file does
not include relocation information. This applies to dynamic link
libraries and a.out files linked with the -R option of ld. Import
information will be lost.
3.4 Displaying and changing the emx options of a bound .exe file
----------------------------------------------------------------
emxbind also can display or change the emx options of a bound .exe
file. Note that the -i option was called -s in previous versions of
emxbind.
Usage (showing options):
emxbind -i [<emxbind_options>] <program_file>[.exe]
Usage (altering options):
emxbind -a [<emxbind_options>] <program_file>[.exe] [<emx_options>]
<emxbind_options>
The following options can be given to emxbind. They must appear
at the beginning of the emxbind arguments.
-a change emx options
-q don't display emxbind banner line
<program_file>
path name of a bound .exe file to be read or changed,
respectively. The default extension is .exe
<emx_options>
remove the options if empty, otherwise put these options into the
.exe file (see also the -b command)
3.5 Updating emx.exe in a bound .exe file
-----------------------------------------
emxbind also can replace the DOS loader in an existing bound .exe
file. You should use this only if you can't rebuild the .exe file
because you don't have the a.out file. Note that you usually have to
re-link your program when using a new release of emx due to
differences in the system interface.
Usage:
emxbind -u [<emxbind_options>] <emx>[.exe] <program_file>[.exe]
<emxbind_options>
The following options can be given to emxbind. They must appear
at the beginning of the emxbind arguments.
-q don't display emxbind banner line
-u replace DOS loader
<emx>
path name of emxd.exe, emx.exe or emxl.exe. This DOS loader is
copied to the <program_file>. The default extension is .exe.
<program_file>
path name of the bound .exe file to be changed. The default
extension is .exe. Better make a backup copy of the file before
using emxbind -u.
3.6 Stripping the symbol table from a bound .exe file
-----------------------------------------------------
emxbind can also be used to remove the symbol table from a bound .exe
file strip.exe cannot be used on .exe files). You can also strip the
symbol table while creating the .exe file by using the -s option with
the -b command.
Usage:
emxbind -s [<emxbind_options>] <program_file>[.exe]
<emxbind_options>
The following options can be given to emxbind. They must appear
at the beginning of the emxbind arguments.
-q don't display emxbind banner line
-s strip symbol table
<program_file>
path name of the bound .exe file to be changed. The default
extension is .exe. If you cannot recreate the .exe file, make a
backup copy of the file before using emxbind -s.
3.7 Module definition files
---------------------------
emxbind reads LINK386 compatible module definition files. In the
following list of available module definition statements, optional
parts are enclosed in brackets. Case is ignored for keywords (though
IBM says you should use upper case for keywords). See below a list of
reserved words. You cannot use keywords for function names, module
names etc. In case of a conflict, enclose the offending name in
single or double quotes. Quotes are also required if a name contains
a special character such as blank, tab, `@', `=', `.' or `;'. Lines
starting with a semicolon are treated as comment lines and are
completely ignored. Numbers can be given in decimal, octal or
hexadecimal, using C syntax.
3.7.1 Module definition statements
----------------------------------
CODE ...
Define default attributes for code segments. Ignored by emxbind.
DATA ...
Define default attributes for data segments. Ignored by emxbind.
DESCRIPTION '<text>'
Put a text into the .exe or .dll file. The text must be enclosed
in single or double quotes. To include a single quote in single
quotes or a double quote in double quotes, simply enter the quote
twice. The text will be put at the start of the nonresident name
table, which is put at the end of the .exe or .dll file.
Typically, DESCRIPTION is used to insert a copyright message.
Example:
DESCRIPTION 'HAL9000 -- Copyright (c) 2001 by Space Odyssey Inc.'
EXETYPE ...
Identifies the operating system. Ignored by emxbind (the
operating system is always OS/2).
EXPORTS <entryname> [=<internalname>] [@<ordinal> [RESIDENTNAME|NONAME]]
Make functions and variables visible outside the .exe or .dll
file. All entry points of a dynamic link library must be exported
using EXPORTS. Exporting entry points of .exe files is less
common.
Following the EXPORTS keyword, you can enter any number of
<entryname> [=<internalname>] [@<ordinal> [RESIDENTNAME|NONAME]]
lines, one for each entrypoint. <entryname> is the name of the
function as made visible outside of the .exe or .dll file.
<entryname> is always converted to upper case. <internalname> is
the name of the function as defined in your program. If
=<internalname> is omitted, it is assumed to be identical to
<entryname>. <internalname> is case sensitive. Exported
functions not only have a name (<entryname>), they also have an
ordinal number, the position within the name table. Using ordinal
numbers when importing saves space and is supposed to be faster.
You can assign a specific ordinal number to an exported function
by entering @<ordinal>. <ordinal> is the ordinal number to be
used (1 through 65535). If @<ordinal> is not given, emxbind
chooses an unused ordinal number, but you won't know the ordinal
number and therefore cannot use it for importing. If @<ordinal>
is specified, <entryname> is by default put into the nonresident
name table, which is not kept in memory while the .exe or .dll
file is running or loaded, respectively. This saves space. To
put <entryname> into the resident name table, enter RESIDENTNAME.
Then, OS/2 will keep <entryname> in memory while the .exe or .dll
file is running or loaded, respectively. This saves time.
Example:
EXPORTS my_qsort=qsort1 @1 RESIDENTNAME
my_hsort
Use NONAME to avoid putting <entryname> into the name tables.
This may be required for dynamic link libraries which export many
functions and variables.
HEAPSIZE <number>
Set the size of the local heap. <number> can be MAXVAL as well.
Ignored by emxbind.
IMPORTS [<internalname>=]<modulename>.<entry>
Define imported symbols. Ignored by emxbind. Use emximp instead.
LIBRARY [<libraryname>] [<initialization>] [<termination>]
Create dynamic link library (.dll file). If LIBRARY is used, it
must be the first statement of the module definition file.
<libraryname> is the name of the module. The name is the first
entry of the resident name table and must match the base name of
the .dll file. If <libraryname> is not specified, the name of the
output file sans directory and extension is used.
<initialization> can be either INITGLOBAL or INITINSTANCE.
INITGLOBAL causes the library initialization function to be called
when the DLL is initially loaded into memory. INITINSTANCE causes
the library initialization function to be called each time a
process loads the DLL and each time a process referencing the DLL
is started. <termination> can be either TERMGLOBAL or
TERMINSTANCE. TERMGLOBAL causes the library termination function
to be called when the DLL is no longer used by any process.
TERMINSTANCE causes the library termination function to be called
each time a process frees the DLL and each time a process
referencing the DLL terminates.
Currently, TERMGLOBAL seems to cause the termination function not
to be called at all.
See _DLL_InitTerm() for details about the library initialization
function and the library termination function.
If <initialization> and <termination> are omitted, INITGLOBAL and
TERMGLOBAL are used. If one of <initialization> and <termination>
is specified, the other one defaults to an appropriate value, as
shown by the following table:
│ (no termination) │ TERMGLOBAL │ TERMINSTANCE
──────────────────────┼──────────────────┼──────────────┼─────────────
(no initialization) │ INITGLOBAL │ INITGLOBAL │ INITINSTANCE
│ TERMGLOBAL │ TERMGLOBAL │ TERMINSTANCE
──────────────────────┼──────────────────┼──────────────┼─────────────
INITGLOBAL │ INITGLOBAL │ INITGLOBAL │ INITGLOBAL
│ TERMGLOBAL │ TERMGLOBAL │ TERMINSTANCE
──────────────────────┼──────────────────┼──────────────┼─────────────
INITINSTANCE │ INITINSTANCE │ INITINSTANCE │ INITINSTANCE
│ TERMINSTANCE │ TERMGLOBAL │ TERMINSTANCE
Examples:
LIBRARY
LIBRARY INITINSTANCE
LIBRARY mylib
LIBRARY mylib INITINSTANCE TERMGLOBAL
NAME [<appname>] [<apptype>] [NEWFILES]
Create an .exe file. If NAME is used, it must be the first
statement. <appname> is the name of the module. The name is the
first entry of the resident name table. If <appname> is not
specified, the name of the output file sans directory and
extension is used. <apptype> can be one of the following
keywords:
NOTWINDOWCOMPAT
the program will run full-screen
WINDOWAPI
the program is a Presentation Manager application
WINDOWCOMPAT
the program will run in a text window
The default is WINDOWCOMPAT. <apptype> can be overridden on the
emxbind command line with the -f, -p and -w options.
The NEWFILES keyword (LONGNAMES is an alias) is ignored, emx
applications always use long file names. Examples:
NAME WINDOWAPI
NAME myprog
NAME myprog NOTWINDOWCOMPAT
OLD '<library>'
Preserve import information. Ignored by emxbind.
PROTMODE
Executable runs only in protected mode. Ignored by emxbind.
SEGMENTS ...
Set segment attributes. Ignored by emxbind.
STACKSIZE <number>
Set the stack size for OS/2 programs. Always use this statement
as the default is too small. The stack size should be 32768 or
more. The stack size for DOS programs is controlled by the -s#
emx option.
STUB '<program>'
Use <program> as DOS executable file. This program is run if the
.exe or .dll file is started under DOS. <program> is sought in
the directories listed in the EMXPATH and PATH environment
variables unless the filename includes a directory. If the <emx>
argument is given on the emxbind command line, the STUB statement
is ignored. If <emx> is not given and the STUB statement is not
present, \emx\bin\emxl.exe is used. If that file does not exist,
emxbind searches the directories listed in the EMXPATH and PATH
environment variables and the current working directory for
emxl.exe. Example:
STUB 'emx.exe'
3.7.2 Reserved words
--------------------
The following words are reserved. You cannot use them as function
names, module names, etc. unless enclosed in quotes.
ALIAS INVALID PHYSICAL
BASE IOPL PRELOAD
CLASS LIBRARY PRIVATE
CODE LOADONCALL PRIVATELIB
CONFORMING LONGNAMES PROTECT
CONTIGUOUS MAXVAL PROTMODE
DATA MIXED1632 PURE
DESCRIPTION MOVABLE READONLY
DEV386 MOVEABLE READWRITE
DEVICE MULTIPLE REALMODE
DISCARDABLE NAME RESIDENT
DOS4 NEWFILES RESIDENTNAME
DYNAMIC NODATA SEGMENTS
EXECUTEONLY NOEXPANDDOWN SHARED
EXECUTE-ONLY NOIOPL SINGLE
EXECUTEREAD NONAME STACKSIZE
EXETYPE NONCONFORMING STUB
EXPANDDOWN NONDISCARDABLE SWAPPABLE
EXPORTS NONE TERMGLOBAL
FIXED NONPERMANENT TERMINSTANCE
HEAPSIZE NONSHARED UNKNOWN
HUGE NOTWINDOWCOMPAT VIRTUAL
IMPORTS OBJECTS WINDOWAPI
IMPURE OLD WINDOWCOMPAT
INCLUDE ORDER WINDOWS
INITGLOBAL OS2
INITINSTANCE PERMANENT
4 Using emx options
===================
Under DOS, emx options can be given on the emx command line:
emx [<options>] <program> [<arguments>]
where <program> is either a bound .exe file or an a.out file. Options
marked [*] for DOS below affect only the emx program given on the
command line. All other options are `sticky' and apply to all
processes started by that instance of emx. Options of this type put
by emxbind into the executable file are ignored when running an emx
program by running emx. If you need one of these options, put them on
the emx command line.
Under OS/2 and DOS, emx options can also be given in the EMXOPT
environment variable. These options apply to all processes.
Moreover, you can use emxbind to put emx options into the executable
file (see above for restrictions). In this case, options marked [*]
below apply only to the program for which they have been set. All
other options are `sticky' and apply to all processes started by the
current instance of emx (unless you are running emx manually as shown
above).
Options given on the emx command line override options given in
EMXOPT. Options given in EMXOPT override options stored in the
executable file.
The following emx options are available:
-a* [DOS*] Enable dangerous features: -ac makes data and the stack
executable, -am enables _memaccess(), -aw enables write access
to all memory areas, -ai enables _portaccess(). By default,
only the .text section is executable, _memaccess() and
_portaccess() are disabled. You can combine letters: for
instance, -aim enables both _memaccess() and _portaccess(),
-aciw enables all dangerous features. Note: -ac is
automatically set in programs run with P_DEBUG mode of
spawn*(). This is used to be able to call functions of the
debuggee by putting code into the stack.
-c [*] Disable core dumps caused by signals. Core dumps created
by _core() are not disabled by -c.
-d [DOS] Don't use extended memory. Only low memory (below 1
MByte) will be used. Use this if you suspect a bug in the
extended memory management of emx or a bug in an extended
memory manager.
-e [DOS*] Redirect the standard error handle (2) to standard
output (1)
-h# [DOS, OS/2*] Set file handle limit. Under DOS, the DOS file
handle limit for the emx process is set to #. The number #
must be between 10 and 255. This option is ignored for DOS
versions earlier than 3.30. This option does not change the
emx limit for the number of files per process -- that limit is
always 40. Under OS/2, the file handle limit for the current
process is set to #. The number # must be between 10 and 255.
-m# [DOS] Select machine. -m1 selects Fujitsu FMR70 (not
implemented yet), -m2 selects NEC PC-98 (not implemented yet),
-m3 selects Inboard 386/PC.
-o [DOS] Send the register dump of an exception to stdout.
Without -o, the register dump is sent to the CON device. You
need -o for redirecting the register dump to a file.
-p [DOS] Don't use low memory (lower Megabyte); use this if the
program runs a DOS program; not required for running emx
programs (either a.out and bound .exe) unless command.com is
called to run the programs (as done by the system() library
function). If -p is not given, low memory will be used and
there won't be enough low memory for running DOS programs.
-q [*] All command line arguments passed to child processes will
be quoted unconditionally, that is, wildcard expansion and
response files won't work in child processes of processes for
which the -q option is in effect.
-r* [*] Prepend drive letter * to absolute path names. If a path
name starts with / but does not start with //, /dev/ or
/pipe/, * followed by a colon will be prepended. If -rd has
been given, the filename \mydir\abc will be translated to
d:\mydir\abc. Note: this option can cause unexpected effects.
-s# [DOS*] Set stack size (KByte), minimum: -s8, maximum:
-s524288, default: -s8192. Note that under DOS, the heap and
the stack share the same memory area. The pages not used by
the stack are available for the heap. Therefore, you should
use -s# if you need more than 8 MByte of heap and stack.
-t [*] Truncate file names to 8.3 format. Each part of a
pathname is truncated to 8.3 format by taking the first 8
characters before the dot and the first 3 characters after the
dot. This is useful to compile programs on a FAT filesystem
with minimal changes.
-x [OS/2] Don't suppress wildcard expansion and response files if
the `MKS Korn shell' method of passing command line arguments
is used.
-C# [DOS*] Commit memory. By default, memory is allocated as soon
as a page is accessed. If there isn't enough memory (and swap
space), the process is terminated. With -C#, memory is
allocated when creating the process and when enlarging the
data segment with brk() and sbrk(). If there isn't enough
memory (and swap space), the process brk(), sbrk(), malloc()
etc. return an error. The number # specifies how many KByte
should be allocated for the stack. If # is omitted, 0 is
used. The -C# option is not yet completely implemented -- if
an allocation request succeeds partly, the allocated pages are
not freed.
-E [OS/2*] Run debuggee in same session. By default, a debugger
for emx (such as GDB) runs the child process in a separate
session. The P_NOSESSION flag of spawn*() has the same effect
as -E.
[DOS] Don't check for 387 coprocessor. Assume no coprocessor
is present. This option is used for testing.
-F [DOS] Use fast A20 switching. By default, the standard method
for switching A20 is used. A faster method is available on
some machines. That method will be used if the -F option is
present.
-K [OS/2*] Don't use DosKillThread. Due to bugs in OS/2,
DosKillThread may cause problems. emx.dll automatically
avoids using DosKillThread for OS/2 2.1 and older. For OS/2
2.11 and later, you can use the -K option to disable usage of
DosKillThread. Currently, DosKillThread is used only if
select() is applied to socket handles
-L [DOS*] Disable preloading of pages from the executable file.
By default, the complete code and data areas are read into
memory before a program is started. If there is not enough
memory, no pages are preloaded. With -L (or if not enough
memory is available), pages are loaded as soon as they are
accessed.
-O [DOS] Override XMS version check. By default, emx checks for
XMS version number 2.00 or later and for XMS driver revision
2.06 or later, as older himem.sys drivers don't work
correctly. You can override this check by giving the -O
option (for drivers using a different revision numbering
scheme), but emx may not work with your XMS driver, anyway.
Actually, emx has not been tested with himem.sys 2.05; 2.04
fails, 2.06 works.
-P [DOS] Use patched code for A20 switching. There is a patch
area in emx.exe where you can put alternate code for switching
A20. The -P option enables the code in the patch area.
-S# [DOS] Enable the emx kernel debugger. Use the -S option to
operate the debugger through the keyboard and display. If you
want to debug using a terminal, enter -S1 to use COM1, -S2 to
use COM2.
-V Display emx version. On program start, the emx version will
be displayed.
-Z [DOS*] Don't zero-fill pages. This option is used for
testing.
5 More emx utilities
====================
5.1 updt
--------
- Copy file if contents have changed:
updt [-v] <source_file> <target_file>
updt copies the source file to the target file if the target file
does not exist or if the source and target files differ in contents.
This is used by the makefile for GCC.
- Copy file if source file is newer:
updt [-v] -t <source_file> <target_file>
updt copies the source file to the target file if the target file
does not exist or if the source file is newer than the target file.
This is used for configuring GCC.
The -v option turns on information messages.
5.2 emximp
----------
emximp manages files required for importing functions from dynamic
link libraries.
Three different methods for importing are used for the two methods of
creating executable files. When using ld and emxbind, there are two
methods for importing:
(I1) The import library contains a small piece of code for each
function which loads the AL register with the number of
argument words and jumps to the imported function.
Information on imported functions is stored in tables in the
text segment of the program. emxbind reads these tables to
create appropriate fixups in the .exe file. When an imported
function is called while running the resulting program under
DOS, an error message will be displayed and the program will
be terminated. Data cannot be imported with method (I1). You
have to use the -R option of ld.
(I2) The import library does not contain code for import
definitions. Instead, it contains special symbol table
entries, which are copied to the a.out file. One of these
entries makes ld create a relocatable output file. emxbind
reads the symbol table and creates appropriate fixups in the
.exe file. The AL register isn't loaded with the number of
argument words. The program will be aborted (protection
violation) when an imported function is called under DOS. The
-R option of ld is automatically turned on when referencing an
import definition of type (I2).
When using emxomf and LINK386, the standard OS/2 method is used:
(I3) LINK386 reads a .lib import library or a module definition
file to create appropriate fixups. The AL register isn't
loaded with the number of argument words. The program won't
run under DOS.
Methods (I2) and (I3) are recommended unless the dynamic link library
requires the AL register to be loaded with the number of argument
words. os2.a uses method (I2).
emximp is used to create appropriate files for all these methods.
Information on functions exported by dynamic link libraries is
provided in emx import list files.
The following table summarizes the features of the three methods:
Method │ (I1) │ (I2) │ (I3)
─────────────────────┼────────┼─────────┼──────────
Linker │ ld │ ld │ LINK386
Import by name │ YES │ NO │ YES
Load AL register │ YES │ NO │ NO
Code overhead │ YES │ NO │ NO
Catch call under DOS │ YES │ NO │ NO
Import library type │ .o .a │ .a │ .lib .def
Can import functions │ YES │ YES │ YES
Can import data │ NO │ YES │ YES
Additive fixups │ NO │ YES │ YES
Linker options │ -R │ │
5.2.1 What is an emx import list file?
--------------------------------------
An emx import list file defines how functions can be imported from
dynamic link libraries. For each function, the import list file
defines the name of the function, the module name (that's the name of
the dynamic link library exporting the function), either the ordinal
number or the name of the function as exported by the dynamic link
library, and the number of argument 32-bit words expected by the
function (this is the number of arguments unless structures are passed
by value).
For method (I1), emximp is used to turn an import list file into an .a
import library which can be linked to a program using the ld linker.
emximp either creates assembler source files (.s) or automatically
calls the assembler to create object files (.o). The object files can
be packed into a library with the ar program.
For method (I2), emximp is used to turn an import list file or an OMF
import library (.lib file) directly into an .a import library which
can be linked to a program using the ld linker.
For method (I3), emximp can convert an import list file into a module
definition file or an OMF import library. emximp can also convert a
module definition file into an OMF import library.
Comments in an import list file are started with a semicolon. Empty
lines are ignored.
For each function you have to put one line into the import list file.
Here's an example of an import list file:
; myimport.imp
DosStartTimer doscalls 351 3
DosStopTimer doscalls 290 1
Such a line consists of four components which are separated by one or
more blanks. The first word is the name of the function, as used in C
programs. The second word is the name of the DLL. The third word is
either the ordinal number of the DLL entry or the name of the DLL
entry. You have to use ordinal numbers for OS/2 API functions. The
fourth word is the number of 32-bit words of arguments expected by the
function. This is the number of arguments unless structures are
passed by value.
A question mark used as forth word is equivalent to using the number
0. A question mark should be used if the number of arguments is
unknown or if the entry point is not a function (data can also be
exported). Using a question mark causes a warning when creating files
for method (I1).
An R used as forth word causes the AL register not to be loaded with
method (I1) -- this is used for functions which expect an argument in
the EAX register.
An F used as forth word specifies a 16-bit function. emximp adds _16_
in front of the function name to notify emxbind and emxomf of the
16-bitness of the function. References to symbols starting with _16_
are fixed up by 16:16 far pointers.
5.2.2 Creating an emx import list file from an OMF import library
-----------------------------------------------------------------
To create an emx import list file from an OMF import library, type
emximp -o <output_file>.imp <input_file>.lib ...
<output_file> is the name of the emx import list file to be created.
The name must end with .imp. <input_file> is the name of an existing
import library file. The name must end with .lib. You can give one
or more input filenames on the command line.
As the number of argument words of the functions cannot be derived
from the import library, a question mark instead of a number for the
number of argument words is written to the import list file.
When encountering a module with static code or data, emximp displays a
warning message.
5.2.3 Creating an emx import list file from a module definition file
--------------------------------------------------------------------
To create an emx import list file from a module definition file, type
emximp -o <output_file>.imp <input_file>.def ...
<output_file> is the name of the emx import list file to be created.
The name must end with .imp. <input_file> is the name of an existing
module definition file. The name must end with .def. You can give
one or more input filenames on the command line.
As the number of argument words of the functions cannot be derived
from the module definition file, a question mark instead of a number
for the number of argument words is written to the import list file.
5.2.4 Creating an emx import library for method (I1)
----------------------------------------------------
To create an emx import library for method (I1), type
emximp [-a<assembler>] [-b<base_name>|<prefix_length>] [-p<module>]...
[-s] <input_file>.imp ...
<input_file> is the name of the import list file. The name must end
with .imp. You can give one or more input filenames on the command
line.
The names of the output files are either taken from the import list
file or automatically generated by emximp. A line in starting with
`+' starts a new assembly language file or object file (module). The
name of the output file is given after the `+':
+os2mem1.s ; start a new output file
This feature is used only for method (I1). All the functions defined
in one module are linked if at least one of the functions is
referenced.
It's possible to let emximp automatically write one file per function.
The output filenames are constructed by appending the ordinal number
or a sequential number to a fixed prefix or to a prefix of the DLL
name. To let emximp automatically choose output filenames, use the -b
command line option. If -b is given, the import list file must not
contain lines starting with `+'. The argument of the -b option is
either a number or a string. If the argument is a string, that string
is used as base name of the output files. If the argument is a
number, that many characters are taken from the start of each DLL name
to create the base name of the output file. A number is appended to
the base name. If -s is given, a sequential number is appended,
starting with the number 1. The number is incremented for each output
file. If -s is not given, the ordinal number of the function is
appended; giving entry names instead of ordinal numbers in the import
list file is not allowed for that reason. Note that appending ordinal
numbers to the names may cause problems (output for different
functions written to the same file) if multiple DLLs are used in the
import list file and the argument of the -b option is a string (or too
small a number to make the prefixes unique). These problems also
occur if the import list file defines multiple functions to refer to
the same entry point. The extension of the output files is .o if the
-a option is used, .s otherwise.
By default, emximp creates assembler source files. emximp can
automatically call an assembler to assemble the output files. This
feature is turned on by the -a command line option. The argument of
the -a option is the name of the assembler (there must be no blanks
between -a and the argument). If the argument is omitted, as.exe is
used. The default extension is .exe, the program will be sought in
the directories listed in the PATH environment variable.
The object files will have the same name as the assembler source
files, with the .s extension replaced by .o.
Under OS/2, the assembly language files are not actually written, a
pipe is used instead. Under DOS, the assembly language files created
by emximp will be deleted automatically after running the assembler.
To save space in the executable file, DLL names which are often used
should be put into separate files, see above for an example. Use the
-p option of emximp to use separate files for the DLL names. The
argument of the -p option is the name of the DLL. emximp prepends
__os2_ to the DLL name for making the label used for referencing the
DLL name. You can use multiple -p options. Here's how to write a
separate file which defines a DLL name:
.globl __os2_pmgpi
.text
__os2_pmgpi:
.asciz "PMGPI"
This file declares the DLL name PMGPI. Use the -p pmgpi option of
emximp to tell emximp to create code that references this file.
Technical details:
Let's examine the .s file created by emximp for the DosSelectSession
function.
1) .globl _DosSelectSession
2) .align 2, 144
3) _DosSelectSession:
4) movb $1, %al
5) 1: jmp __os2_bad
6) 2: .long 1, 1b+1, L1, 38
7) L1: .asciz "sesmgr"
8) .stabs "__os2dll", 23, 0, 0, 2b
Line 1 is obvious: it exports _DosSelectSession from os2.a so that ld
will link this module when _DosSelectSession is referenced.
Line 2 is a speed hack: the 386 performs much better when jumping to
an address which is an integral multiple of 4.
Line 3 declares _DosSelectSession. Your program calls this code when
calling DosSelectSession.
Line 4 stores the number of arguments in the AL register (or rather,
the number of argument 32-bit words).
Line 5 jumps to __os2_bad which displays an error message and stops
execution. This is what happens if you run the program on DOS.
Line 6 creates a small table which is read by emxbind: It consists of
four words:
- a word of flag bits. Currently, only bit 0 is defined: it's 0 for
import by name, 1 for import by ordinal.
- the address of the word to be fixed up for referencing the DLL.
`1b+1' means `local label 1, looking backwards, add one to address'.
Therefore, the address used by the JMP instruction is used.
- a pointer to the name of the module (null-terminated ASCII string).
For often used names the pointer should point to a string in a
separate, common module to save space, see the -p option.
- the ordinal number or a pointer to the name of the entry point
(null-terminated ASCII string), respectively, depending on bit 0 of
the flags word.
Line 7 defines the module name pointed to by the table.
Line 8 is the tricky part: it contains a special symbol table entry to
make ld build a table named __os2dll which contains pointers to all
the small tables (2b is the address of the small table). See also
crt0.s, where the table is initialized. crt0 contains a pointer to
the table in a fixed location so that emxbind can find the table of
pointers, read all the small tables (as described above) and create
the necessary OS/2 fixups.
5.2.5 Creating an a.out import library for method (I2)
------------------------------------------------------
To create an a.out import library for method (I2), type
emximp -o <output_file>.a <input_file>.imp ...
emximp -o <output_file>.a <input_file>.lib ...
<output_file>.a is the name of the archive file to be created. The
name must end with .a.
<input_file>.imp is the name of an emx import list file. The name
must end with .imp.
<input_file>.lib is the name of an import library (OMF). The name
must end with .lib. Modules in the input files which are not import
definitions are ignored.
You can give one or more input filenames on the command line; all
input file must be of the same type, either .imp or .lib.
All import records of the input files are converted to import modules
for method (I2). After creating the output file, you should run ar s
on the output file to increase linking efficiency.
When encountering a module with static code or data in a .lib file,
emximp displays a warning message. You may have to use extract those
modules from the library, convert them with emxaout, and add them to
the target library with emxomfar.
Technical details:
A member named __.IMPORT is added to the archive. GNU ld (the one
ported to emx) has been patched to turn on relocatable output if it
finds a member named __.IMPORT in a library. As only the __.SYMDEF
member is scanned if present, __.IMPORT defines the special symbol
__IMPORT!. When patched GNU ld finds the definition of a symbol named
__IMPORT! in the __.SYMDEF member, relocatable output is turned on.
(Relocatable output can also be turned on by using the -R option of
ld.)
For each function in the input files, emximp adds an a.out-type module
to the output file. Such a module defines two symbols. One symbol
defines the entry point, the other symbol gives information on the DLL
name and the ordinal number or procedure name. For instance, for
LIBRARY doscalls
EXPORTS DosBeep @286
the two symbols `_DosBeep' and `_DosBeep=doscalls.286' are defined.
The symbol types 0x69 and 0x6b are used, respectively. GNU ld has
been patched to keep references to symbols of type 0x69 in the
relocation table.
emxbind scans the relocation table for references to symbols of type
0x69 and scans the symbol table for a matching symbol of type 0x6b
which defines the entry point.
5.2.6 Creating an OMF import library for method (I3)
----------------------------------------------------
To create an OMF import library for method (I3), use one of the
following invokations of emximp, depending on the input format:
emximp -o <output_file>.lib <input_file>.def ...
emximp -o <output_file>.lib <input_file>.imp ...
<output_file>.lib is the name of the import library file to be
created. The name must end with .lib.
<input_file>.def is the name of a module definition file containing
one or more EXPORTS statements.
<input_file>.imp is the name of an emx import list file.
You can give one or more input filenames on the command line.
All the import list files must define functions that are in the same
dynamic link library. Lines start with `+' are ignored.
The number of argument words is lost after that conversion, that is,
you cannot recreated the import list file using emximp.
5.2.7 Creating a module definition file for method (I3)
-------------------------------------------------------
To create a module definition file for method (I3), type
emximp -o <output_file>.def <input_file>.imp ...
<output_file> is the name of the module definition file to be created.
The name must end with .def.
<input_file> is the name of an emx import list file. The name must
end with .imp. You can give one or more input filenames on the
command line.
All the import list files must define functions that are in the same
dynamic link library. Lines start with `+' are ignored.
The number of argument words is lost after that conversion, that is,
you cannot recreated the import list file using emximp.
5.3 emxomf
----------
The emxomf tool converts a.out object files (.o files) to Object
Module Formats (.obj files). The converted files can be used with the
OS/2 linker link386.exe.
emxomf keeps itself in memory for N minutes if the environment
variable GCCLOAD is set to N.
emxomf [-d] [-l[<symbol>]] [-g] [-s] [-p <page_size>] [-m <symbol>]
[-i <default_lib>] [-I <idmdll>] [-D <dataseg>]
-o <output_file> <input_file>
Convert a single .o or .a file (<input_file>) to an .obj or .lib file
(<output_file>). There are no default extensions. If the -d option
is given, the input file is deleted after successful conversion. If
the input file is an archive, it is not deleted.
emxomf [-d] [-l[<symbol>]] [-g] [-s] [-x] [-p <page_size>]
[-m <symbol>]
[-O <directory>] [-r|R<response_file>] [-i <default_lib>]
[-I <idmdll>] [-D <dataseg>] <input_file>...
Convert multiple .o and .a files to .obj and .lib files (more than one
<input_file> can be given on the command line). The names of the
output files are constructed by replacing the extension of the
<input_file>s with .obj or .lib, respectively. If the -x option is
given, all members (which must be a.out modules) of archives (.a
files) are converted to .obj files. The names of the output files are
constructed by replacing the extension of the member names with .obj.
If the -x option is not given, archives (.a files) are converted to
libraries (.lib files). If the -O option is given, the output files
are written to the directory <directory>. A LIB response file
<response_file> is created if you use the -r or -R option. When using
-r, the response file will contain commands to add the modules to a
library file, when using -R, it will contain commands to replace the
modules in a library file. If the -d option is given, all the input
files except for archives are deleted after successful conversion. If
the -s option is given, debugging information is omitted.
You can put emxomf options into the environment variable EMXOMFOPT.
These options will be read before the options given on the command
line.
Options common to both calling sequences:
-D <dataseg>
Change the name of the data segment. By default, all initialized
variables are put into the DATA32 segment which is a member of the
DGROUP group. By using the -D option, the segment used for
initialized variables can be changed. That segment won't be a
member of the DGROUP. This can be used for creating dynamic link
libraries with both instance data and shared data. Define all
variables which should be private to the instances of the DLL in a
separate source file, initialize all the variables, use the -D
option of emxomf to put these variables into a separate segment
and set the attributes of that segment in the module definition
file to NONSHARED. All other variables will go into the default
data segment, which is shared by all instances of the DLL.
Alternatively, you can make variables private by default and put
the shared variables into a separate segment. You have to list
all the segments of class DATA in the module definition file.
Example:
SEGMENTS
PRIV CLASS 'DATA' NONSHARED
DATA32 CLASS 'DATA' SHARED
BSS32 CLASS 'BSS' SHARED
In this example, variables are shared by default. The segment
PRIV contains private variables.
-g
Create groups for sets, as did previous versions of emxomf. This
causes an extra object to be created for each set (such as
__CTOR__LIST__). By default, all sets are merged into the text
object.
-i <default_lib>
Add default library request. LINK386 is informed that the .obj
file should be linked with the library <default_lib>. If
<default_lib> doesn't include a file name extension, LINK386 uses
the default extension .lib. You can specify multiple libraries by
using multiple -i options.
-I <idmdll>
Change the name of the identifier manipulation DLL. That DLL is
used by LINK386 to demangle C++ symbol names in error messages. A
special record (IDMDLL) is inserted into the .obj file by emxomf
to tell LINK386 about the name of the DLL. emxomf inserts that
record only if it recognizes the input file as being compiled by
G++. The default for the identifier manipulation DLL is gppdemid.
Use -I- to suppress the insertion of the IDMDLL record.
-l[<symbol>]
The module (all the modules of an archive when converting an
archive) is supposed to be a library modules. A library module
doesn't define a stack segment and doesn't request libraries. If
<symbol> is given (following directly -l, without space), it is
used as name of the entry point, that is, the function that should
be called when the DLL is started. If <symbol> is not specified,
no entry point will be defined. If -l and -m are missing, the
module is supposed to be part of a program but not the main
module. Such a module doesn't define a stack segment and doesn't
have an entry point.
-m <symbol>
The module is supposed to be the main module of a program. A main
module defines a default stack segment (0x8000 bytes) and has an
entry point. <symbol> is the name of the entry point, that is,
the function that should be called when the program is started.
-m is used for the startup code module crt0 and should not be used
for user modules. If -l and -m are missing, the module is
supposed to be part of a program but not the main module. Such a
module doesn't define a stack segment and doesn't have an entry
point.
-p <page_size>
Set the page size of .lib files to <page_size> bytes (16, 32, 64,
..., 32768). If -p is not given, a page size of 16 bytes will be
used. Increase the page size if emxomf complains about too big a
library. If emxomf doesn't complain, you shouldn't increase the
page size to save disk space.
-s
If the -s option is given, debugging information is omitted. By
default, debugging information is converted from a.out DBX-style
(with GNU extensions) to HLL version 3 format (as used by IBM's
IPMD debugger of the C/C++ Tools 2.0 package). If emxomf cannot
translate debugging information, a warning message is displayed.
Types not recognized by emxomf are treated as `int' to be able to
continue conversion. Restrictions:
- The Objective C language is not supported yet.
- Structures (or unions) without declarator within another
structure (or union) are ignored as GCC doesn't emit suitable
debugging information.
- Variable-length automatic arrays are not supported.
- `long long' and `unsigned long long' types are translated to the
following structure, as HLL version 3 debugging information
doesn't support 64-bit integers:
struct _long_long
{
unsigned long lo;
unsigned long hi;
}
- Pointer to member (C++) is not yet supported.
5.4 emxomfld
------------
emxomfld is a front end to LINK386, providing an ld-like command line
syntax for LINK386. After parsing the command line, LINK386 is called
with equivalent command line arguments.
emxomfld -o <file> [-l <lib>] [-L <libdir>] [-T <base>] [-sS]
[-Zexe] [-Zdll] [-Zstack <stack_size>] [-Zmap[=<map_file>]]
[-O <option>] <file>...
The files given on the emxomfld command line are assumed to be .obj
files to be linked unless the extension is .def, .lib or .res. A file
having a .def extension is used as module definition file. There may
be at most one module definition file. A file having a .lib extension
is used as library file. A file having a .res extension is used as
binary resource file; rc is called to attach the resources to the
output file.
Example:
emxomfld -o test -lc -Lc:/mylibs test1 test2 test.def test.res
Create file test.exe (or test.dll, depending on the contents of
test.def), by linking test1.obj and obj2.obj with c.lib. c.lib is
sought in c:/mylibs. Use the module definition file test.def. Call
rc to copy the resources from test.res to test.exe (or test.dll).
The following options are available:
-i
Pass the /INFORMATION option to LINK386, causing filenames to be
displayed while linking. This is used for debugging emxomfld.
-l <lib>
Link with the library <lib>.lib. For instance, -lc causes c.lib
to be used.
-L <libdir>
Add the directory <libdir> to the library search path. Libraries
are sought in the directories given by -L options. emxomfld
prepends the directories to the LIB environment variable.
-o <file>
<file> is the output file. The default extension (.exe or .dll)
is provided by LINK386. If -o is omitted, $$$ will be used.
-O <option>
Pass the option <option> to LINK386. For each option to be passed
to LINK386, one -O has to be used. <option> should start with a
slash. Example:
-O/runfromvdm
See also the -Zlinker option of GCC.
-s
Strip all symbols, including debugging information. If -s and -S
are not used, emxomfld passes the /DEBUG option to LINK386.
-S
Strip debugging symbols (emxomfld strips all symbols, including
debugging information, if -S is used). If -s and -S are not used,
emxomfld passes the /DEBUG option to LINK386.
-T <base>
Set the base address of the text segment. This option is
translated to the /BASE option of LINK386. emxomfld automatically
passes /BASE:0x10000 to LINK386 unless -T is used or a DLL is
built. If neither -T nor -Zdll is used, the module definition
file is read to learn whether a DLL is being built or not.
-x
Discard all local symbols (this option is ignored by emxomfld).
-X
Discard local symbols starting with L (this option is ignored by
emxomfld).
-Zdll
Build a DLL. If the -Zdll option is present, emxomfld does not
automatically pass /BASE:0x10000 to LINK386. The -Zdll option
isn't necesary as a module definition file is required when
building a DLL and emxomfld reads the module definition file to
learn whether a DLL is to be built or not.
-Zexe
If the -Zexe option is present, emxomfld deletes the output file
(whose name is given on the command line) and adds .exe to the
output filename. After calling LINK386, emxomfld creates an empty
output file (without .exe). This feature is used for minimizing
changes to Unixoid makefiles. See also the -Zexe option of GCC
and ld.
-Zmap[=<map_file>]
Let LINK386 write the map file <map_file>. LINK386 adds the
default extension `map'. If =<map_file> is not specified, the
name of the map file will be derived from the output file name.
-Zstack <stack_size>
Set the stack size of the executable, in Kbyte. The argument of
the -Zstack option is multiplied by 1024 and turned into a /STACK
LINK386 option. The number can be given in decimal, octal or
hexadecimal, using C notation.
5.5 emxomfar
------------
emxomfar is a librarian for OMF .lib files with a command line
interface similar to ar to simplify makefiles.
emxomfar [-p#] <command> <library_file> [<module>]...
The default extension for <library_file> is .lib. When modifying a
library file, a backup file with .bak extension is created.
Here's a description of ar commands:
d Delete modules from library. The module name __.SYMDEF is
ignored.
m Move members to the end of the archive. Not implemented in
emxomfar.
p Copy members to standard output. Not implemented in emxomfar.
q Quick append. This command is equivalent to the r command in
emxomfar.
r Replace modules in library. Modules which are not in the
library are added to the library. The default extension for
modules is .obj.
s Build the __.SYMDEF symbol table member. This command is
ignored by emxomfar.
t List table of contents. Use the v option to also list public
symbols.
x Extract modules from library. The default extension for
modules is .obj.
You can additionally use the following modifiers in the <command>
argument:
a Position after specified member. Not implemented in emxomfar
b Position before specified member. Not implemented in emxomfar
c Don't display warning when creating new library.
i Position before specified member. Not implemented in emomfar
l Create temporary file in current directory. Ignored by
emxomfar
o Preserve dates. Ignored by emxomfar
u Don't replace members with older files (update). Ignored by
emxomfar
v Verbose output.
The following option must precede <command> if used:
-p# Set page size to # bytes (16, 32, 64, ..., 32768). If -p is
not given, a page size of 16 bytes will be used. Increase the
page size if emxomfar complains about too big a library. If
emxomfar doesn't complain, you shouldn't increase the page
size to save disk space.
Example:
emxomfar -p32 rc newlib *.obj
5.6 emxexp
----------
The emxexp tool creates an export list for a module definition file
from object files and libraries. This is used for building dynamic
link libraries written in C++.
emxexp [-n] [-o[<ordinal>]] <input_file>...
For each public symbol (except for uninitialized variables) of the
input files (which can be .o, .a, .obj or .lib files), emxexp prints
to the standard output an export definition for the EXPORTS statement
of a module definition file. For mangled names, a comment is
generated which shows the demangled name. The following options are
available:
-n
Add the NONAME keyword to each export definition to keep LINK386
from putting the name into the name tables. This is required for
dynamic link libraries which export too many names.
-o[<ordinal>]
Add ordinal numbers to the export definitions. If <ordinal> is
given, ordinal numbers will start with that number. Otherwise,
ordinal numbers will start with 1.
5.7 emxaout
-----------
The emxaout tool converts OMF object files (.obj files) to a.out
object files (.o files). The converted files can be used with the
Unix-style linker ld. By using emxaout, you can create .o files with
MASM 6.0.
emxaout [-u] [-o <output_file>] <input_file>
Convert the OMF file <input_file> to a.out format. The default
extension for <input_file> is .obj. If the -o option is used, the
a.out file is written to <output_file>. Otherwise, the name of the
output file is constructed by replacing the extension of <input_file>
with .o.
The following option is available:
-u
Don't add leading underscores to symbol names. By default,
emxaout prepends an underscore to every symbol name.
When using the PROC C, PROTO C and EXTERNDEF C directives of MASM
6.0, you should use the -u option of emxaout because MASM prepends
an underscore to symbols defined with those directives.
The OMF file must have 32-bit OS/2 format, that is, you should use the
following MASM directives:
.386
.MODEL FLAT
emxaout discards debugging information.
5.8 emxcat
----------
The emxcat tool concatenates assembler or C source files. This is
used for building emxwrap.dll.
emxcat [-D<symbol>]... -o <output_file> <input_file>...
All the <input_file>s are concatenated and written to <output_file>.
If the output file is included in the input files, it is not copied;
emxcat simply compares the filenames, therefore it's possible to fool
emxcat and make it copying until the disk is full.
Your code should not depend on the order in which the files are copied
to the output file. A different version of emxcat may copy the files
files in a different order.
At the very beginning of the output file, the symbols given on the
command line are defined. Note that there must not be a space between
-D and the name of the symbol.
#include statements are collected at the start of the output file.
The (partial) order of the include files is maintained. If there is
an inconsistency in the order of include files in different input
files, emxomf prints a warning message. For instance, this happens
for the following three input files:
/* file1.c */
#include "a.h"
#include "b.h"
/* file2.c */
#include "b.h"
#include "c.h"
/* file3.c */
#include "c.h"
#include "a.h"
The statement
#include <sys/emx.h>
is treated specially: it always precedes all other #include statements
if present in one of the input files.
When concatenating .s files, lines starting with CONST_ are omitted if
already copied to the output file -- only the first instance is
retained.
All macros #defined by an input file are #undefined after copying the
input file. Constants starting with INCL_ are an exception and are
collected at the start of the output file, before the #include
statements.
emxcat leaves alone #define and #include statements which do not start
at the first column of the line. If you put blanks before #define and
#include, emxcat copies these statements to the output file without
treating them specially.
5.9 emxload
-----------
The emxload tool preloads OS/2 programs. Preloading programs speeds
up loading these programs if you have enough memory. If you have too
little memory, preloading may degrade performance. Preloading is
especially useful with a compiler such as GCC which runs many
processes to complete its task.
emxload starts the emxload server process (emxload.exe contains both
the client program described here and the server program). The server
process runs until stopped with the -q option of emxload.
When using emxload to load a program which is already preloaded by
emxload, the expiry time of that program will be reset to the new
value.
There are library functions for using the emxload server in your
programs. See _emxload_prog() etc. for details.
The GNU C compiler keeps itself in memory for N minutes if the
environment variable GCCLOAD is set to N. For example, to keep the
passes of GCC in memory for 5 minutes, type
SET GCCLOAD=5
The following programs use GCCLOAD: gcc.exe, cpp.exe, cc1.exe,
cc1plus.exe, cc1obj.exe, as.exe and emxomf.exe.
emxload [-m<limit>] [-s<limit>] [-e] [-u[w]]
[-gcc] [-g++] [-gobjc] [-omf] <program>...
All the <program>s are preloaded. The default extension is .exe.
There are shortcuts for preloading the GNU C compiler:
-gcc
This option preloads the complete GNU C compiler for compiling C
programs and generating a.out-style output. The following
programs will be preloaded: gcc.exe, cpp.exe, cc1.exe, ld.exe,
as.exe and emxbind.exe.
-g++
This option preloads the complete GNU C compiler for compiling C++
programs and generating a.out-style output. The following
programs will be preloaded: gcc.exe, cpp.exe, cc1plus.exe, ld.exe,
as.exe and emxbind.exe.
-gobjc
This option preloads the complete GNU C compiler for compiling
programs written in the Objective C programming language and
generating a.out-style output. The following programs will be
preloaded: gcc.exe, cpp.exe, cc1obj.exe, ld.exe, as.exe and
emxbind.exe.
-omf
Use this option in addition to one of the options for preloading
GCC to preload the programs used for generating OMF-style output.
The following programs will be preloaded: emxomf.exe, emxomfld.exe
and link386.exe.
You can use one or more of the above options. For instance, if you
want to compile C and C++ programs, use
emxload -gcc -g++
This will preload gcc.exe, cpp.exe, cc1.exe, cc1plus.exe, ld.exe,
as.exe and emxbind.exe.
There are additional options for controlling the operation of emxload:
-m<limit>
Automatically unload the specified programs after <limit> minutes.
This option overrides the -s<limit> option. By default, programs
are unloaded after 10 minutes.
-s<limit>
Automatically unload the specified programs after <limit> seconds.
This option overrides the -m<limit> option. By default, programs
are unloaded after 600 seconds.
-e
Don't unload the specified programs automatically. This option
overrides the -m<limit> and -s<limit> options. By default,
emxload unloads a program after 10 minutes.
-u
Unload the specified programs. By default, emxload preloads the
specified programs. With the -u option, all specified programs
will be unloaded. Don't wait until the server has unloaded the
programs.
-uw
Like -u, but wait until the server has unloaded the programs.
Two special calling sequences are available:
emxload -l
List the preloaded programs with the number of minutes and seconds
left until automatic unloading.
emxload -q[w]
Stop the emxload server process. All preloaded programs will be
unloaded. Use -qw to wait until the server is stopped. -q doesn't
wait.
5.10 emxrev
-----------
emxrev displays the revision number of emx DLLs (emx.dll, emxio.dll,
emxlibc.dll, emxlibcm.dll, emxlibcs.dll, and emxwrap.dll). The
revision number is incremented every time a changed version of a DLL
is released. By looking at the revision numbers of the DLLs, you can
tell which one is the newest one.
To display the revision number of the default emx DLLs, type
emxrev
The default DLLs are those used by the operating system when starting
a program.
To display the revision number of a specific file, type
emxrev -f <file>
If a directory is included in <file>, append .dll to the name. If no
directory is included in <file>, don't append .dll to the name.
To display the revision numbers of the emx DLLs in directory <dir>,
type
emxrev -d <dir>
To display the revision numbers of the emx DLLs in all directories of
drive <drive> (c:, for instance), type
emxrev -c <drive>
To display the revision numbers of the emx DLLs in all directories of
all hard disks, type
emxrev -a
To display the revision numbers of the emx DLLs in the directories
listed in the LIBPATH statement of a config.sys file, type
emxrev -p <file>
where <file> is the name of the config.sys file.
5.11 listomf
------------
listomf lists an .obj file in (more or less) human-readable form.
Give the name of the object file on the command line. There is no
default extension.
Warning: listomf is a quick and dirty program which was used for
developing emxomf.
6 Hints for porting Unix programs to emx
========================================
- If you want Unix-like wildcard expansion built into the program, use
int main (int argc, char *argv[])
{
_wildcard (&argc, &argv);
/* ... the program ... */
}
This should be done at the very beginning of main(), before ARGC and
ARGV are used. See _wildcard() and _response().
- Change all open(), fopen(), fdopen() and freopen() calls to use
O_BINARY or "b", respectively, for binary files. If a file contains
both binary and textual data, read the file in binary mode and do
the conversion yourself.
- Though fseek() and ftell() now work on text files, the offsets are
different from what Unix programs expect. You may have to open the
files in binary mode and ignore carriage returns (this has been done
in GDB).
- Replace fork() and exec*() with spawn*(). Under OS/2, fork() is
inefficient. Under DOS, fork() is not implemented.
- Replace exec*() with spawn*() and exit() if the parent process waits
for the termination of the new process (by calling wait() or by
waiting for SIGCLD). This is required to keep the process ID of the
child process. In a forked process, however, you don't have to do
this because emx.dll does it for you.
- Programs reading a.out files should be changed to call _seek_hdr()
or _fseek_hdr() before reading the header to support .exe files.
More changes are usually required.
- Watch out for Unix file system hacks: Unix allows deleting and
renaming an open file (the file will be deleted after being closed).
- Watch out for Unix file names (Unix is case sensitive, long file
names and multiple dots are allowed). On OS/2's HPFS multiple dots
are also allowed; however, trailing dots are not significant (except
for the special file names `.' and `..').
- The null device is called /dev/null under Unix. The __open() system
call translates the filenames "/dev/null" and "/dev/tty" (lower
case, with slashes) to "nul" and "con", respectively. However,
system ("whatever >/dev/null");
won't work as the standard OS/2 and DOS command interpreters don't
recognize /dev/null.
- Programs using stdin, stdout or stderr for binary data should call
_fsetmode() to switch the stream to binary mode.
- If you want to use \ for separating directories, changes may be
necessary. These changes are optional because / also works.
- Implement support for drive names. This can be done by using
#define getcwd _getcwd2
#define chdir _chdir2
In addition, some changes will be necessary. For instance, you have
to change code which checks whether a filename is an absolute path
name. _fullpath() and _abspath() can also be useful.
- Note that ///abc is a valid Unix filename. It's equivalent to /abc.
- Note that chdir ("..") is a no-op under Unix if the current working
directory is the root directory. Under emx, chdir ("..") fails in
the root directory.
- Use termio or termios or read the keyboard with _read_kbd() if you
don't want to get input line by line.
- Under Unix, directories in environment variables (PATH, for
instance) are separated by colons; use semicolons instead.
- Do not use the PTRACE_TRACEME request of ptrace(): use P_DEBUG
instead when starting the process with spawn*().
- By default, signal processing is different when using signal():
SIG_ACK should be used instead of the signal handler address to
re-enable a signal by calling signal() when the signal handler has
been called. This behavior can be changed with the -Zbsd-signals
and -Zsysv-signals options of GCC. If you use POSIX.1 functions for
signal handling, SIG_ACK is not required.
- The shell isn't called /bin/sh. Use system(). system() and popen()
don't expand wildcards (unless COMSPEC points to a shell which
expands wildcards).
- Printing single characters is inefficient. A solution is to use
setvbuf (stdout, NULL, _IOLBF, BUFSIZ)
and to use fflush (stdout) if you need the output immediately
(flushing is required only after displaying prompting texts before
reading input or displaying progress reports that don't end with a
newline character). GDB output has been made much faster by using
line buffering.
- Note that VEOF != VMIN and VEOL != VTIME. Programs which use VEOF
and VEOL to access VMIN and VTIME, respectively, should be changed
to use VMIN and VTIME. emx uses separate fields for VEOF, VEOL,
VMIN and VTIME.
- To use termio, you have to reset the IDEFAULT bit of c_lflag. This
does not apply to termios.
7 Creating OS/2 programs
========================
This section describes additional features available when devoloping
OS/2 programs.
7.1 Calling OS/2 API functions
------------------------------
Use
#include <os2.h>
in your C files to call OS/2 API functions. GCC automatically links
your program with os2.a (or os2.lib) by passing the -los2 option to
the linker. If you call the linker manually, you have to tell the
linker to link with library os2. Note that your program will crash if
it calls an OS/2 API function when run under DOS.
You can use either the header file that comes with emx (os2emx.h) or
the header files that come with the Developer's Toolkit for OS/2 (an
IBM product). By default, os2emx.h is used when doing
#include <os2.h>. To use the header files of the Developer's Toolkit
for OS/2, edit /emx/include/os2.h to #include os2tk.h instead of
os2emx.h, and add the toolkit include file directory to the
C_INCLUDE_PATH, CPLUS_INCLUDE_PATH and OBJC_INCLUDE_PATH environment
variables. Instead of editing os2.h, you can #define
USE_OS2_TOOLKIT_HEADERS before doing #include <os2.h>.
Note that you should define INCL_WHATEVER constants when using
os2emx.h as you would with the IBM Developer's Toolkit for OS/2 --
though not all constants are tested by the current version of
os2emx.h.
When compiling C++ programs, you may have to define the preprocessor
symbol OS2EMX_PLAIN_CHAR.
When passing a pointer to a structure to a 16-bit function, the
structure must not cross a 64 KByte boundary. This (currently) cannot
be automatically assured for structures allocated in the stack (auto
variables and function arguments).
To pass the address of an auto variable to a 16-bit function, you
should define the variable twice and use _THUNK_PTR_STRUCT_OK or
_THUNK_PTR_SIZE_OK to check which one is properly aligned.
To ensure that all structures passed to 16-bit functions are properly
aligned, define all those variables in a module of their own which
must be the first module linked. This doesn't work if the combined
size of all those variables exceeds 64 KByte. Use _tmalloc() to
allocate memory for structures passed to 16-bit functions.
The 32-bit wrappers for 16-bit OS/2 API functions are provided for
both static linking (library os2) and dynamic linking (library wrap,
emxwrap.dll).
os2emx.h contains declarations for the following OS/2 API functions:
Device I/O
----------
DosDevConfig DosPhysicalDisk
DosDevIOCtl
Dynamic linking
---------------
DosFreeModule DosQueryModuleName
DosLoadModule DosQueryProcAddr
DosQueryModuleHandle DosQueryProcType
Errors
------
DosErrClass DosError
Exceptions
----------
DosAcknowledgeSignalException DosSetExceptionHandler
DosEnterMustComplete DosSetSignalExceptionFocus
DosExitMustComplete DosUnsetExceptionHandler
DosRaiseException DosUnwindException
DosSendSignalException
File system
-----------
DosCancelLockRequest DosProtectSetFileSize
DosClose DosProtectWrite
DosCopy DosQueryCurrentDir
DosCreateDir DosQueryCurrentDisk
DosCreatePipe DosQueryFHState
DosDelete DosQueryFileInfo
DosDeleteDir DosQueryFSAttach
DosDupHandle DosQueryFSInfo
DosEditName DosQueryHType
DosEnumAttribute DosQueryPathInfo
DosFindClose DosQueryVerify
DosFindFirst DosRead
DosFindNext DosSetCurrentDir
DosForceDelete DosSetDefaultDisk
DosFSAttach DosSetFHState
DosFSCtl DosSetFileInfo
DosMove DosSetFileLocks
DosOpen DosSetFilePtr
DosProtectClose DosSetFileSize
DosProtectEnumAttribute DosSetFSInfo
DosProtectOpen DosSetMaxFH
DosProtectQueryFHState DosSetPathInfo
DosProtectQueryFileInfo DosSetRelMaxFH
DosProtectRead DosSetVerify
DosProtectSetFHState DosShutdown
DosProtectSetFileInfo DosResetBuffer
DosProtectSetFileLocks DosWrite
DosProtectSetFilePtr
Help Manager
------------
DdfBeginList DdfSetFontStyle
DdfBitmap DdfSetFormat
DdfEndList DdfSetTextAlign
DdfHyperText DdfText
DdfInform WinAssociateHelpInstance
DdfInitialize WinCreateHelpInstance
DdfListItem WinCreateHelpTable
DdfMetafile WinDestroyHelpInstance
DdfPara WinLoadHelpTable
DdfSetColor WinQueryHelpInstance
DdfSetFont
Memory management
-----------------
DosAllocMem DosQueryMem
DosAllocSharedMem DosSetMem
DosFreeMem DosSubAllocMem
DosGetNamedSharedMem DosSubFreeMem
DosGetSharedMem DosSubSetMem
DosGiveSharedMem DosSubUnsetMem
Messages
--------
DosGetMessage DosPutMessage
DosInsertMessage DosQueryMessageCP
Miscellanea
-----------
DosQuerySysInfo DosSearchPath
DosScanEnv
Named pipes
-----------
DosCallNPipe DosQueryNPipeInfo
DosConnectNPipe DosQueryNPipeSemState
DosCreateNPipe DosSetNPHState
DosDisConnectNPipe DosSetNPipeSem
DosPeekNPipe DosTransactNPipe
DosQueryNPHState DosWaitNPipe
National language support
-------------------------
DosMapCase DosQueryCtryInfo
DosQueryCollate DosQueryDBCSEnv
DosQueryCp DosSetProcessCp
Queues
------
DosCloseQueue DosPurgeQueue
DosCreateQueue DosQueryQueue
DosOpenQueue DosReadQueue
DosPeekQueue DosWriteQueue
Resources
---------
DosFreeResource DosQueryResourceSize
DosGetResource
Semaphores
----------
DosAddMuxWaitSem DosOpenMuxWaitSem
DosCloseEventSem DosPostEventSem
DosCloseMutexSem DosQueryEventSem
DosCloseMuxWaitSem DosQueryMutexSem
DosCreateEventSem DosQueryMuxWaitSem
DosCreateMutexSem DosReleaseMutexSem
DosCreateMuxWaitSem DosRequestMutexSem
DosDeleteMuxWaitSem DosResetEventSem
DosOpenEventSem DosWaitEventSem
DosOpenMutexSem DosWaitMuxWaitSem
Sessions
--------
DosQueryAppType DosStartSession
DosSelectSession DosStopSession
DosSetSession
Tasking
-------
DosBeep DosKillProcess
DosCreateThread DosKillThread
DosDebug DosResumeThread
DosEnterCritSect DosSetPriority
DosExecPgm DosSleep
DosExit DosSuspendThread
DosExitCritSect DosWaitChild
DosExitList DosWaitThread
DosGetInfoBlocks
Timers
------
DosAsyncTimer DosStopTimer
DosGetDateTime DosTmrQueryFreq
DosStartTimer DosTmrQueryTime
Virtual DOS machines
--------------------
DosCloseVDD DosRequestVDD
DosOpenVDD DosSetDOSProperty
DosQueryDOSProperty
Graphics Programming Interface
------------------------------
GpiAnimatePalette GpiQueryFaceString
GpiAssociate GpiQueryFontAction
GpiBeginArea GpiQueryFontFileDescriptions
GpiBeginElement GpiQueryFontMetrics
GpiBeginPath GpiQueryFonts
GpiBitBlt GpiQueryFullFontFileDescs
GpiBox GpiQueryGraphicsField
GpiCallSegmentMatrix GpiQueryInitialSegmentAttrs
GpiCharString GpiQueryKerningPairs
GpiCharStringAt GpiQueryLineEnd
GpiCharStringPos GpiQueryLineJoin
GpiCharStringPosAt GpiQueryLineType
GpiCloseFigure GpiQueryLineWidth
GpiCloseSegment GpiQueryLineWidthGeom
GpiCombineRegion GpiQueryLogColorTable
GpiComment GpiQueryLogicalFont
GpiConvert GpiQueryMarker
GpiConvertWithMatrix GpiQueryMarkerBox
GpiCopyMetaFile GpiQueryMarkerSet
GpiCorrelateChain GpiQueryMetaFileBits
GpiCorrelateFrom GpiQueryMetaFileLength
GpiCorrelateSegment GpiQueryMix
GpiCreateBitmap GpiQueryModelTransformMatrix
GpiCreateLogColorTable GpiQueryNearestColor
GpiCreateLogFont GpiQueryNumberSetIds
GpiCreatePalette GpiQueryPS
GpiCreateRegion GpiQueryPageViewport
GpiCreatePS GpiQueryPalette
GpiDeleteBitmap GpiQueryPaletteInfo
GpiDeleteElement GpiQueryPattern
GpiDeleteElementRange GpiQueryPatternRefPoint
GpiDeleteElementsBetweenLabels GpiQueryPatternSet
GpiDeleteMetaFile GpiQueryPel
GpiDeletePalette GpiQueryPickAperturePosition
GpiDeleteSegment GpiQueryPickApertureSize
GpiDeleteSegments GpiQueryRealColors
GpiDeleteSetId GpiQueryRegionBox
GpiDestroyPS GpiQueryRegionRects
GpiDestroyRegion GpiQueryRGBColor
GpiDrawBits GpiQuerySegmentAttrs
GpiDrawChain GpiQuerySegmentNames
GpiDrawDynamics GpiQuerySegmentPriority
GpiDrawFrom GpiQuerySegmentTransformMatrix
GpiDrawSegment GpiQuerySetIds
GpiElement GpiQueryStopDraw
GpiEndArea GpiQueryTag
GpiEndElement GpiQueryTextAlignment
GpiEndPath GpiQueryTextBox
GpiEqualRegion GpiQueryViewingLimits
GpiErase GpiQueryViewingTransformMatrix
GpiErrorSegmentData GpiQueryWidthTable
GpiExcludeClipRectangle GpiRectInRegion
GpiFillPath GpiRectVisible
GpiFloodFill GpiRemoveDynamics
GpiFrameRegion GpiResetBoundaryData
GpiFullArc GpiResetPS
GpiGetData GpiRestorePS
GpiImage GpiRotate
GpiIntersectClipRectangle GpiSaveMetaFile
GpiLabel GpiSavePS
GpiLine GpiScale
GpiLoadBitmap GpiSelectPalette
GpiLoadFonts GpiSetArcParams
GpiLoadMetaFile GpiSetAttrMode
GpiLoadPublicFonts GpiSetAttrs
GpiMarker GpiSetBackColor
GpiModifyPath GpiSetBackMix
GpiMove GpiSetBitmap
GpiOffsetClipRegion GpiSetBitmapBits
GpiOffsetElementPointer GpiSetBitmapDimension
GpiOffsetRegion GpiSetBitmapId
GpiOpenSegment GpiSetCharAngle
GpiOutlinePath GpiSetCharBox
GpiPaintRegion GpiSetCharBreakExtra
GpiPartialArc GpiSetCharDirection
GpiPathToRegion GpiSetCharExtra
GpiPlayMetaFile GpiSetCharMode
GpiPointArc GpiSetCharSet
GpiPolyFillet GpiSetCharShear
GpiPolyFilletSharp GpiSetClipPath
GpiPolygons GpiSetClipRegion
GpiPolyLine GpiSetColor
GpiPolyLineDisjoint GpiSetCp
GpiPolyMarker GpiSetCurrentPosition
GpiPolySpline GpiSetDefArcParams
GpiPop GpiSetDefAttrs
GpiPtInRegion GpiSetDefaultViewMatrix
GpiPtVisible GpiSetDefTag
GpiPutData GpiSetDefViewingLimits
GpiQueryArcParams GpiSetDrawControl
GpiQueryAttrMode GpiSetDrawingMode
GpiQueryAttrs GpiSetEditMode
GpiQueryBackColor GpiSetElementPointer
GpiQueryBackMix GpiSetElementPointerAtLabel
GpiQueryBitmapBits GpiSetGraphicsField
GpiQueryBitmapDimension GpiSetInitialSegmentAttrs
GpiQueryBitmapHandle GpiSetLineEnd
GpiQueryBitmapInfoHeader GpiSetLineJoin
GpiQueryBitmapParameters GpiSetLineType
GpiQueryBoundaryData GpiSetLineWidth
GpiQueryCharAngle GpiSetLineWidthGeom
GpiQueryCharBox GpiSetMarker
GpiQueryCharBreakExtra GpiSetMarkerBox
GpiQueryCharDirection GpiSetMarkerSet
GpiQueryCharExtra GpiSetMetaFileBits
GpiQueryCharMode GpiSetMix
GpiQueryCharSet GpiSetModelTransformMatrix
GpiQueryCharShear GpiSetPageViewport
GpiQueryCharStringPos GpiSetPaletteEntries
GpiQueryCharStringPosAt GpiSetPattern
GpiQueryClipBox GpiSetPatternRefPoint
GpiQueryClipRegion GpiSetPatternSet
GpiQueryColor GpiSetPel
GpiQueryColorData GpiSetPickAperturePosition
GpiQueryColorIndex GpiSetPickApertureSize
GpiQueryCp GpiSetPS
GpiQueryCurrentPosition GpiSetRegion
GpiQueryDefArcParams GpiSetSegmentAttrs
GpiQueryDefAttrs GpiSetSegmentPriority
GpiQueryDefCharBox GpiSetSegmentTransformMatrix
GpiQueryDefTag GpiSetStopDraw
GpiQueryDefViewingLimits GpiSetTag
GpiQueryDefaultViewMatrix GpiSetTextAlignment
GpiQueryDevice GpiSetViewingLimits
GpiQueryDeviceBitmapFormats GpiSetViewingTransformMatrix
GpiQueryDrawControl GpiStrokePath
GpiQueryDrawingMode GpiTranslate
GpiQueryEditMode GpiUnloadFonts
GpiQueryElement GpiUnloadPublicFonts
GpiQueryElementPointer GpiWCBitBlt
GpiQueryElementType
Device Contexts
---------------
DevCloseDC DevQueryCaps
DevEscape DevQueryDeviceNames
DevOpenDC DevQueryHardcopyCaps
DevPostDeviceModes
Presentation Manager
--------------------
WinAddAtom WinQueryAtomUsage
WinAlarm WinQueryCapture
WinBeginEnumWindows WinQueryClassInfo
WinBeginPaint WinQueryClassName
WinBroadcastMsg WinQueryClassThunkProc
WinCalcFrameRect WinQueryClipbrdData
WinCallMsgFilter WinQueryClipbrdFmtInfo
WinCancelShutdown WinQueryClipbrdOwner
WinCheckInput WinQueryClipbrdViewer
WinCloseClipbrd WinQueryCp
WinCompareStrings WinQueryCpList
WinCopyAccelTable WinQueryCursorInfo
WinCopyRect WinQueryDesktopBkgnd
WinCpTranslateChar WinQueryDesktopWindow
WinCpTranslateString WinQueryDlgItemShort
WinCreateAccelTable WinQueryDlgItemText
WinCreateAtomTable WinQueryDlgItemTextLength
WinCreateCursor WinQueryFocus
WinCreateDlg WinQueryMsgPos
WinCreateFrameControls WinQueryMsgTime
WinCreateMenu WinQueryObjectWindow
WinCreateMsgQueue WinQueryPointer
WinCreatePointer WinQueryPointerInfo
WinCreatePointerIndirect WinQueryPointerPos
WinCreateStdWindow WinQueryPresParam
WinCreateWindow WinQueryQueueInfo
WinDdeInitiate WinQueryQueueStatus
WinDdePostMsg WinQuerySysColor
WinDdeRespond WinQuerySysModalWindow
WinDefWindowProc WinQuerySysPointer
WinDefDlgProc WinQuerySysPointerData
WinDeleteAtom WinQuerySystemAtomTable
WinDeleteLibrary WinQuerySysValue
WinDeleteProcedure WinQueryUpdateRect
WinDestroyAccelTable WinQueryUpdateRegion
WinDestroyAtomTable WinQueryVersion
WinDestroyCursor WinQueryVisibleRegion
WinDestroyMsgQueue WinQueryWindow
WinDestroyPointer WinQueryWindowDC
WinDestroyWindow WinQueryWindowModel
WinDismissDlg WinQueryWindowPos
WinDispatchMsg WinQueryWindowProcess
WinDlgBox WinQueryWindowPtr
WinDrawBitmap WinQueryWindowRect
WinDrawBorder WinQueryWindowText
WinDrawPointer WinQueryWindowTextLength
WinDrawText WinQueryWindowThunkProc
WinEmptyClipbrd WinQueryWindowULong
WinEnablePhysInput WinQueryWindowUShort
WinEnableWindow WinRealizePalette
WinEnableWindowUpdate WinRegisterClass
WinEndEnumWindows WinRegisterUserDatatype
WinEndPaint WinRegisterUserMsg
WinEnumClipbrdFmts WinReleaseHook
WinEnumDlgItem WinReleasePS
WinEqualRect WinRemovePresParam
WinExcludeUpdateRegion WinRequestMutexSem
WinFillRect WinSaveWindowPos
WinFindAtom WinScrollWindow
WinFlashWindow WinSendMsg
WinFocusChange WinSendDlgItemMsg
WinFreeErrorInfo WinSetAccelTable
WinGetClipPS WinSetActiveWindow
WinGetCurrentTime WinSetCapture
WinGetDlgMsg WinSetClassMsgInterest
WinGetErrorInfo WinSetClassThunkProc
WinGetKeyState WinSetClipbrdData
WinGetLastError WinSetClipbrdOwner
WinGetMaxPosition WinSetClipbrdViewer
WinGetMinPosition WinSetCp
WinGetMsg WinSetDesktopBkgnd
WinGetNextWindow WinSetDlgItemShort
WinGetPhysKeyState WinSetDlgItemText
WinGetPS WinSetFocus
WinGetScreenPS WinSetHook
WinGetSysBitmap WinSetKeyboardStateTable
WinInflateRect WinSetMsgInterest
WinInitialize WinSetMsgMode
WinInSendMsg WinSetMultWindowPos
WinIntersectRect WinSetOwner
WinInvalidateRect WinSetParent
WinInvalidateRegion WinSetPointer
WinInvertRect WinSetPointerOwner
WinIsChild WinSetPointerPos
WinIsPhysInputEnabled WinSetPresParam
WinIsRectEmpty WinSetRect
WinIsThreadActive WinSetRectEmpty
WinIsWindow WinSetSynchroMode
WinIsWindowEnabled WinSetSysColors
WinIsWindowShowing WinSetSysModalWindow
WinIsWindowVisible WinSetSysPointerData
WinLoadAccelTable WinSetSysValue
WinLoadDlg WinSetVisibleRegionNotify
WinLoadMenu WinSetWindowBits
WinLoadLibrary WinSetWindowPos
WinLoadMessage WinSetWindowPtr
WinLoadPointer WinSetWindowText
WinLoadProcedure WinSetWindowThunkProc
WinLoadString WinSetWindowULong
WinLockPointerUpdate WinSetWindowUShort
WinLockVisRegions WinShowCursor
WinLockWindowUpdate WinShowPointer
WinMakePoints WinShowTrackRect
WinMakeRect WinShowWindow
WinMapDlgPoints WinStartTimer
WinMapWindowPoints WinStopTimer
WinMessageBox WinSubclassWindow
WinMultWindowFromIDs WinSubstituteStrings
WinNextChar WinSubtractRect
WinOffsetRect WinTerminate
WinOpenClipbrd WinTrackRect
WinOpenWindowDC WinTranslateAccel
WinPeekMsg WinUnionRect
WinPopupMenu WinUpdateWindow
WinPostMsg WinUpper
WinPostQueueMsg WinUpperChar
WinPrevChar WinValidateRect
WinProcessDlg WinValidateRegion
WinPtInRect WinWaitEventSem
WinQueryAccelTable WinWaitMsg
WinQueryActiveWindow WinWaitMuxWaitSem
WinQueryAnchorBlock WinWindowFromDC
WinQueryAtomLength WinWindowFromID
WinQueryAtomName WinWindowFromPoint
Standard Dialogs
----------------
WinDefFileDlgProc WinFreeFileDlgList
WinDefFontDlgProc WinFontDlg
WinFileDlg
Presentation Manager Shell
--------------------------
PrfAddProgram PrfQueryProfileInt
PrfChangeProgram PrfQueryProfileSize
PrfCloseProfile PrfQueryProfileString
PrfOpenProfile PrfRemoveProgram
PrfQueryDefinition PrfReset
PrfQueryProgramTitles PrfWriteProfileData
PrfQueryProfile PrfWriteProfileString
PrfQueryProfileData
WinAddSwitchEntry WinQueryTaskSizePos
WinChangeSwitchEntry WinQueryTaskTitle
WinCreateSwitchEntry WinRemoveSwitchEntry
WinQuerySessionTitle WinSwitchToProgram
WinQuerySwitchEntry WinStartApp
WinQuerySwitchHandle WinTerminateApp
WinQuerySwitchList
Spooler
-------
SplControlDevice SplQmClose
SplCopyJob SplQmEndDoc
SplCreateDevice SplQmOpen
SplCreateQueue SplQmStartDoc
SplDeleteDevice SplQmWrite
SplDeleteJob SplQueryDevice
SplDeleteQueue SplQueryJob
SplEnumDevice SplQueryQueue
SplEnumDriver SplReleaseJob
SplEnumJob SplReleaseQueue
SplEnumPort SplSetDevice
SplEnumPrinter SplSetJob
SplEnumQueue SplSetQueue
SplEnumQueueProcessor SplStdClose
SplHoldJob SplStdDelete
SplHoldQueue SplStdGetBits
SplMessageBox SplStdOpen
SplPurgeQueue SplStdQueryLength
SplQmAbort SplStdStart
SplQmAbortDoc SplStdStop
Monitors
--------
DosMonClose DosMonReg
DosMonOpen DosMonWrite
DosMonRead
Keyboard Subsystem
------------------
KbdCharIn KbdPeek
KbdClose KbdRegister
KbdDeRegister KbdSetCp
KbdFlushBuffer KbdSetCustXt
KbdFreeFocus KbdSetFgnd
KbdGetCp KbdSetHWID
KbdGetFocus KbdSetStatus
KbdGetHWID KbdStringIn
KbdGetStatus KbdSynch
KbdOpen KbdXlate
Video Subsystem
---------------
VioCheckCharType VioSavRedrawWait
VioDeRegister VioScrLock
VioEndPopUp VioScrollDn
VioGetAnsi VioScrollLf
VioGetBuf VioScrollRt
VioGetConfig VioScrollUp
VioGetCp VioScrUnLock
VioGetCurPos VioSetAnsi
VioGetCurType VioSetCp
VioGetFont VioSetCurPos
VioGetMode VioSetCurType
VioGetPhysBuf VioSetFont
VioGetState VioSetMode
VioGlobalReg VioSetState
VioModeUndo VioShowBuf
VioModeWait VioWrtCellStr
VioPopUp VioWrtCharStr
VioPrtSc VioWrtCharStrAttr
VioPrtScToggle VioWrtNAttr
VioReadCellStr VioWrtNCell
VioReadCharStr VioWrtNChar
VioRegister VioWrtTTY
VioSavRedrawUndo
Advanced Video
--------------
VioAssociate VioQueryFonts
VioCreateLogFont VioQuerySetIds
VioCreatePS VioSetDeviceCellSize
VioDeleteSetId VioSetOrg
VioDestroyPS VioShowPS
VioGetDeviceCellSize WinDefAVioWindowProc
VioGetOrg
Mouse Subsystem
---------------
MouClose MouInitReal
MouDeRegister MouOpen
MouDrawPtr MouReadEventQue
MouFlushQue MouRegister
MouGetDevStatus MouRemovePtr
MouGetEventMask MouSetDevStatus
MouGetNumButtons MouSetEventMask
MouGetNumMickeys MouSetPtrPos
MouGetNumQueEl MouSetPtrShape
MouGetPtrPos MouSetScaleFact
MouGetPtrShape MouSetThreshold
MouGetScaleFact MouSynch
MouGetThreshold
7.2 Importing from OS/2 DLLs
----------------------------
All functions in the list above are defined in os2.a and os2.lib.
Moreover, the 32-bit wrappers for the 16-bit OS/2 API functions are
available in the dynamic link library emxwrap.dll to reduce the size
of the executables. The import library for emxwrap.dll is wrap. To
import functions not defined in os2.a and os2.lib, you have to create
an import list file for these functions.
See the emximp documentation for details.
Please note that you cannot directly call 16-bit functions not listed
above. See below for details.
7.3 Creating Presentation Manager applications using ld and emxbind
-------------------------------------------------------------------
To create a Presentation Manager application using ld and emxbind,
- #include <os2.h>
- link with os2.a (done automatically when using GCC to link)
- use rc -r to compile the resource-definition file into a binary
resource file (.res file)
- use emxbind -ep or a module definition file to set the application
type
- use the -r option of emxbind to put the resources from the binary
resource file into the .exe file. If there is a .res file on the
GCC or ld command line, it is automatically passed to emxbind
Do not use rc to put the resources into the .exe file!
Example:
cd \emx\test
rc -r pm1.rc
gcc -o pm1 pm1.c
emxbind -bp -rpm1.res /emx/bin/emxl pm1
Ditto, using a module definition file:
cd \emx\test
rc -r pm1.rc
gcc -o pm1.exe pm1.c pm1.def pm1.res
Example (compiling the `template' toolkit sample program):
cd \toolkt20\c\samples\template
copy ..\prodinfo.bmp
rc -r main.rc
gcc -s -o template.exe *.c template.def main.res
7.4 Creating Presentation Manager applications using emxomf and LINK386
-----------------------------------------------------------------------
To create a Presentation Manager application using emxomf and LINK386,
- #include <os2.h>
- link with os2.lib (done automatically when using GCC to link)
- use a module definition file which uses the WINDOWAPI keyword of the
NAME statement
- use rc -r to compile the resource-definition file into a binary
resource file (.res file)
- use rc or emxomfld to add the binary resource file to the .exe file.
Optionally, you can compile the resource-definition file and add it
to the .exe file using rc in one step. Using two steps is
recommended in makefiles.
Example:
cd \emx\test
rc -r pm1.rc
gcc -o pm1.exe pm1.c pm1.def pm1.res -Zomf
Example (compiling the `template' toolkit sample program):
cd \toolkt20\c\samples\template
copy ..\prodinfo.bmp
rc -r main.rc
gcc -Zomf -o template.exe *.c template.def main.res
If you want to use the -Zsys option, you should increase the stack
size by editing the STACKSIZE statement in the .def file. Note that
the command line arguments and the complete environment are copied to
the stack! The stack size should be at least 32768.
7.5 Creating Workplace Shell applications
-----------------------------------------
Dynamic link libraries for Workplace Shell objects should be either
DLLs without C runtime environment or stand-alone DLLs (see below).
For creating Workplace Shell applications, you need the SOM headers
and the SOM compiler from the Developer's Toolkit for OS/2 (an IBM
product).
See the `flag' example in /emx/samples.
7.6 Creating dynamic link libraries
-----------------------------------
There are six types of dynamic link libraries:
1. DLLs which use emxlibcm.dll or emxlibcs.dll or a custom C runtime
DLL. These DLLs don't contain C library functions. Calls to C
library functions are resolved by emxlibcm.dll or emxlibcs.dll or
a custom C runtime DLL (and, in all three cases, emx.dll). The
main program and all DLLs must use the same C runtime DLL.
2. Custom C runtime DLLs. These DLLs contain the C library or parts
thereof and export the C library functions to other DLLs and to
the main program. An application (main program and DLLs) should
use only one custom C runtime DLL; emxlibcm.dll and emxlibcs.dll
should not be used. Either the system call library sys.lib or
emx.dll can be used. This type of DLL is recommended if you want
to ship your application with your own DLLs, but without any emx
DLLs. This type of DLL can also be used when replacing library
functions such as malloc() which are referenced by other library
functions.
3. C runtime forwarder DLLs. These DLLs forward all C runtime
functions to emxlibcm.dll or emxlibcs.dll, and add some functions
of their own. However, they cannot safely replace functions of
emxlibcm.dll or emxlibcs.dll as the latter ones won't call the
replacement functions.
4. Stand-alone DLLs. These DLLs contain the C library or parts
thereof, which is used privately by the DLL. The main program and
the other DLLs use a different C runtime environment. You should
use only `simple' C library functions such as memcpy() which don't
require global variables.
Keep in mind that the DLL and the program using the DLL don't
share global variables such as errno, timezone, and -- very
important -- the variables used for I/O.
5. DLLs without C runtime environment. These DLLs don't call any C
library functions which require a runtime environment. Only OS/2
API functions and simple C library functions such as strcpy() can
be called.
6. Resource DLLs. These DLLs contain only resources. Some bits of
code are required for library initialization.
Write a module definition file (.def file) that contains a LIBRARY
statement and an EXPORTS statement. The EXPORTS statement has to list
all functions to be exported by your DLL. The .def file should have
the same name as the .dll file to be created.
Compile and link your program using the -Zdll option of GCC. This
option causes the dll0 startup to be used instead of crt0 and selects
appropriate libraries. As DLLs are usually multithread libraries, you
should also use the -Zmt option. Specify the name of the .def file on
the GCC or ld command line, respectively.
Using the -mprobe GCC option is recommended for creating DLLs as the
DLL might be called from a thread with uncommitted stack.
Linking with LINK386 (using GCC -Zomf) is recommended for dynamic link
libraries. Using ld and emxbind offers no advantages when creating
dynamic link libraries.
7.6.1 Creating dynamic link libraries that use a C library DLL
--------------------------------------------------------------
Dynamic link libraries that use emxlibcm.dll or emxlibcs.dll (or a
custom C runtime DLL) are allowed to call all library functions,
including stream I/O, as long as they are used together with programs
and other dynamic link libraries that use the same emxlibcm.dll or
emxlibcs.dll (or the same custom C runtime DLL used by the DLL). That
is, all I/O done by C library functions must be done in a single
place, emxlibcm.dll, emxlibcs.dll, or the custom C runtime DLL. As
the C library is initialized by the program using the DLL, your
library initialization function need not call _CRT_init(). The
following GCC options are used for building a DLL which uses a C
library DLL: -Zdll -Zcrtdll. To link an application with your import
library, use the GCC option -Zcrtdll=<lib>.
The default _DLL_InitTerm() function calls constructors and
destructors, but does not call _CRT_init() and _CRT_term() as the
client application of the DLL initializes the runtime environment by
calling appropriate functions of the C library DLL.
See /emx/test/testdll3.cc for an example.
7.6.2 Creating custom C runtime DLLs
------------------------------------
Creating a custom C runtime DLL means creating a DLL which contains
your own code and some or all code of emxlibcm.dll or emxlibcs.dll.
Write a module definition file which exports your functions and all C
library functions and variables referenced by the main program and
other DLLs using the custom C runtime DLL. You can use
/emx/lib/cdll.def as template. Don't forget to use the following
statement:
DATA
MULTIPLE NONSHARED
Use the following GCC option for building a custom C runtime DLL:
-Zdll. The options -Zomf and -Zsys are optional.
The following object files should be added to the import library for
your DLL: appinit.obj, dllinit.obj, ctor.obj, and dtor.obj. These
object files and analogous .o files live in directory /emx/lib.
If clients of your DLL call the hardware port I/O functions such as
_inp8(), either link the clients with -lemxio or use
/emx/src/lib/cdll/emxio.def in addition to your module definition file
for creating the import library (it is essential to import the
functions from emxio.dll, therefore appending emxio.def to your module
definition file won't work).
To use your custom C runtime DLL, you should invoke LINK386 instead of
GCC to link (or give crt0 or dll0 on the command line and use the
-nostdlib option and your import library).
The default _DLL_InitTerm() function calls constructors and
destructors, but does not call _CRT_init() and _CRT_term() as the
client application of the DLL initializes the runtime environment by
calling appropriate functions of the DLL.
See /emx/test/testdll4.c for an example.
7.6.3 Creating C runtime forwarder DLLs
---------------------------------------
Creating a C runtime forwarder DLL is similar to creating a custom C
runtime DLL (see above). However, instead of statically linking the C
runtime library, it is linked dynamically. That is, the exports of
the forwarder DLL are resolved by imports from emxlibcm.dll or
emxlibcs.dll.
Use the following GCC option for building a forwarder DLL: -Zdll -Zomf
-Zcrtdll. As emxbind does not support forwarders, you have to use
-Zomf.
7.6.4 Creating stand-alone dynamic link libraries
-------------------------------------------------
A stand-alone dynamic link library has its own runtime environment
which is not shared with the client application or other DLLs. Use
the following GCC options for creating a stand-alone DLL: -Zdll -Zso
-Zsys -Zomf.
The default _DLL_InitTerm() function calls constructors and
destructors, and calls _CRT_init() and _CRT_term() to initialize and
terminate the runtime environment.
See /emx/test/testdll5.c for an example.
7.6.5 Creating dynamic link libraries without C runtime environment
-------------------------------------------------------------------
To create a dynamic link library without C runtime, do not reference
any C library function which requires a runtime environment. As the
new operator of C++ calls malloc(), you cannot use C++ to create a DLL
of this type unless you provide your own memory management. Do not
use -Zmt even if the DLL is used by multithread programs; you have to
use Mutex semaphores when using functions such as strtok() which are
not thread-safe. Use the following GCC options to build a DLL without
C runtime environment: -Zdll -Zno-rte -Zomf.
The default _DLL_InitTerm() function calls constructors and
destructors, but does not call _CRT_init() and _CRT_term() as there is
no runtime environment to initialize.
See /emx/test/testdll1.c for an example.
7.6.6 Creating resource DLLs
----------------------------
To create a resource DLL, build a DLL from /emx/lib/res0.obj and add
the resources with rc:
link386 \emx\lib\res0,myres.dll,nul,,myres.def
rc myres.res myres.dll
The module definition file should start with a LIBRARY statement.
7.6.7 Creating dynamic link libraries using C++
-----------------------------------------------
You should not use the GNU C++ libraries (gpp and iostream) if you
create a DLL (unless you are building a stand-alone DLL or a private C
runtime DLL) as there is not yet a DLL version of these libraries.
As creating the module definition file for the DLL by hand is quite
boring, you should let your computer do it: see the description of the
emxexp tool for details. The sign sample of emxample.zip uses emxexp
to create the module definition file.
To call the constructors and destructors for static objects in the
DLL, make sure that the _DLL_InitTerm() function of the DLL calls
__ctordtorInit() and __ctordtorTerm().
7.7 Using the DLL version of the C library
------------------------------------------
To use emxlibcm.dll or emxlibcs.dll, simply type -Zcrtdll on the GCC
command line. This links your program with the import libraries
c_import.a or c_import.lib instead of the static C library (c, c_app,
gcc, emx). -Zcrtdll can be used with methods (E1) and (E2). See the
introduction for further information.
Note that emxlibcm.dll and emxlibcs.dll use emx.dll. Thus, the
restrictions of -Zsys do not apply.
Do not redefine functions in your program which are contained in
emxlibcm.dll or emxlibcs.dll. Other functions in emxlibcm.dll or
emxlibcs.dll will continue to use the original versions in that DLL
which will cause problems. If you have to replace library functions
and want to use a C library DLL, create a new DLL (which must not be
called emxlibc.dll, emxlibcm.dll, or emxlibcs.dll), add your
replacement functions and all the functions of emxlibcm.dll or
emxlibcs.dll except for the functions you are replacing.
7.8 Creating multithread programs
---------------------------------
Multithread programs have to use either the multithread static
libraries or the dynamic link library emxlibcm.dll. You have to say
-Zmt on the GCC command line.
Use _beginthread() to start a new thread. Do not use DosCreateThread
unless the new thread doesn't call C library functions.
The C library functions in mt/c.a, mt/c.lib, and emxlibcm.dll are not
yet completely thread-safe: access to the stream I/O data should be
serialized. The -Zmt, -Zmts, and -Zmtd options define the __MT__
preprocessor macro. The C library header files check for __MT__ to
use alternate definitions suitable for multithread programs when -Zmt,
-Zmts, or -Zmtd is used.
Each thread has its own errno value. To create a library which can be
used for both single-thread and multithread programs, use the _errno()
function instead of the errno variable.
If you are very careful, you can write multithread programs that use
the single-thread libraries. Only the main thread is allowed to call
library functions that have side effects, including functions that set
errno. All other threads should use OS/2 API functions instead.
For performance reasons, single-thread programs should be linked with
the single-thread libraries (that is, without the -Zmt option).
7.9 Calling 16-bit functions
----------------------------
Limited support for calling 16-bit functions is available. You can
call 16-bit OS/2 API functions and other 16-bit functions that use the
pascal (_pascal) or C (_cdecl) calling convention and are exported by
a dynamic link library. As no changes have been made to GCC to
support direct calls to 16-bit functions (this would require big
changes to GCC), you have to call 16-bit functions by applying the
(awkward) C preprocessor macros and functions described below. There
are two sets of macros, one for the pascal calling convention
(_THUNK_PASCAL_***) and one for the C calling convention
(_THUNK_C_***). For convenience and compatibility with emx 0.8f,
there are also macros _THUNK_*** which are aliases for the
_THUNK_PASCAL_*** macros. For brevity, only the _THUNK_*** macros are
explained below. To call a _cdecl function, use _THUNK_C_FUNCTION
etc. instead of _THUNK_FUNCTION etc.
_THUNK_FUNCTION(FUNCTION)
This macro is used for declaring the 16-bit function. The
function is declared as usual, using a prototype, but
_THUNK_FUNCTION is applied to the function name. The 16-bit
function must not be called directly.
_THUNK_PROLOG(SIZE)
For each call to the 16-bit function, this macro must be called
first. SIZE is the number of bytes in the argument list of the
16-bit function. After calling _THUNK_PROLOG, the following
macros are used to build the argument list. The macros are to be
applied left-to-right, that is, the first argument is handled
first both for the pascal and the C calling convention.
_THUNK_CHAR(ARG)
Pass an 8-bit argument to the function.
_THUNK_SHORT(ARG)
Pass a 16-bit argument to the function.
_THUNK_LONG(ARG)
Pass a 32-bit argument to the function.
_THUNK_FLAT(ARG)
Pass a 32-bit (flat) pointer to the function.
_THUNK_FAR16(ARG)
Pass a 16:16-bit far pointer to the function. After building the
argument list, the 16-bit function is called by invoking the
following macro.
_THUNK_CALL(FUNCTION)
Call the 16-bit function FUNCTION. Do not apply _THUNK_FUNCTION
to the function name.
_THUNK_CALLI(FUNCTION)
Call the 16-bit function pointed to by the 16:16-bit far pointer
FUNCTION. Use this macro instead of _THUNK_CALL when employing
DosLoadModule and DosQueryProcAddr. The pointer returned by
DosQueryProcAddr must be turned into a 16:16-bit far pointer by
calling _emx_32to16().
There should be no statements other than calls to the _THUNK macros
between _THUNK_PROLOG and _THUNK_CALL. _THUNK_PROLOG starts an
expression which is terminated by _THUNK_CALL. Therefore, the return
value of the 16-bit function is returned by _THUNK_CALL and by the
entire sequences of statements from _THUNK_PROLOG to _THUNK_CALL. The
return value is the value returned by the 16-bit function in the DX
and AX registers. If the function returns a 16-bit value, you have to
typecast the return value to SHORT or USHORT to discard the upper 16
bits.
See the description of _emx_16to32() and _emx_32to16() for converting
16-bit far pointers to 32-bit flat pointers and vice versa. This
conversion is not done automatically.
You will get a warning about the variable _tp being unused if the
16-bit function doesn't take arguments. This warning is harmless.
When passing a pointer to a structure to a 16-bit function, the
structure must not cross a 64 KByte boundary. This (currently) cannot
be assured for structures allocated in the stack (auto variables and
function arguments). To ensure that all structures passed to 16-bit
functions are properly aligned, define all those variables in a module
of their own which must be the first module linked. This doesn't work
if the combined size of all those variables exceeds 64 KByte.
Alternatively, you can define the variable twice and use
_THUNK_PTR_STRUCT_OK or _THUNK_PTR_SIZE_OK to check which one is
properly aligned. Use _tmalloc() to allocate memory for structures
passed to 16-bit functions. Example:
#include <os2.h> /* define _THUNK_*** macros */
/* Declare 16-bit function */
USHORT _THUNK_FUNCTION (Dos16Beep) (USHORT usFrequency, USHORT usDuration);
void beep (int frequency, int duration)
{
_THUNK_PROLOG (2+2);
_THUNK_SHORT (frequency);
_THUNK_SHORT (duration);
_THUNK_CALL (Dos16Beep);
}
See /emx/test/c16test1.c, /emx/test/c16test2.c,
/emx/src/lib/sys/scrsize.c, and /emx/src/lib/os2/*.c for more
examples.
8 Customizing
=============
Default values are provided for the heap size, the stack size and the
number of files that can be open simultaneously. The following
sections describe how to increase the limits.
8.1 Increasing the heap size
----------------------------
The maximum size of the heap available for malloc() is fixed. The
default for the combined size of the heap and stack is 8 MByte under
DOS. Use the -s# emx option (see section 4) to increase the heap and
stack size.
The default heap size is 32 MByte under OS/2. When using ld and
emxbind, you can change the heap size with the -h<heap_size> option of
emxbind.
When using emxomf and LINK386 without -Zsys, the heap size cannot be
changed (currently). When using -Zsys, you have to build new sys.lib
libraries after changing /emx/src/lib/sys/init.c. The following line
of that file defines the heap size:
_sys_heap_size = 0x2000000;
See build.doc for information about rebuilding libraries.
8.2 Increasing the stack size
-----------------------------
The default for the combined size of the heap and stack is 8 MByte
under DOS. When using emxbind, the default stack size is 8 MB under
OS/2. When using emxomf and LINK386, the default stack size is 0x8000
bytes under OS/2.
The stack size for DOS can be changed with the -s# emx option.
emxbind can put this option into the executable file.
The stack size for OS/2 can be changed with the -k<stack_size> option
of emxbind when using emxbind. When using LINK386, use the STACKSIZE
statement in a module definition file. The stack size should be at
least 32768 bytes. You can also use the -Zstack option of GCC.
If you are using certain beta versions of LINK386, bits 16 through 23
of the stack size should not equal 0x20000 or 0x40000 bits set.
Otherwise, your program will crash under OS/2 2.0 due to a bug in OS/2
2.0. Use only stack sizes where both the 0x20000 and 0x40000 bits are
zero or the 0x10000 or 0x80000 bits are one.
8.3 Increasing the number of files
----------------------------------
Under DOS and when using emx.dll under OS/2, you can set the number of
file handles supported by the emx runtime by setting the EMXOPT
environment variable or by using emxbind to put emx options into the
.exe file. See section 4 for the -h# emx option.
Note that you might have to change the FILES settings in the
config.sys file under DOS.
When using the system call library (-Zsys, sys.lib) you have to call
DosSetMaxFH to increase the number of file handles.
The number of file handles and streams supported by the C library is
given by the _NFILES constant in /emx/include/sys/emx.h. The default
value is 40. After changing emx.h, you have to rebuild the libraries.
(At least stdio.c and iodata.c in /emx/src/lib/io must be recompiled.)
Note that at least three file handles (for stdin, stdout and stderr)
are (almost) always predefined.
The number of file handles and streams supported by emxlibcm.dll,
emxlibcs.dll, and custom C runtime DLLs is 256.
9 Debugger (DOS)
================
emxd.exe contains a debugger (that's the difference between emx.exe
and emxd.exe). Use the -S option to enable the debugger. If you want
to debug using a terminal, enter -S1 to use COM1, -S2 to use COM2. To
debug an emx program, type
emxd -S [<options>] <program> [<arguments>]
(which works with all emx programs) or
set emx=c:\emx\bin\emxd.exe
set emxopt=-S
<program>
(which doesn't work if emx.exe is bound to the program). When
starting an emx program by running emx.exe or emxd.exe, the emx
options -d, -h#, -m#, -o, -p, -E, -F, -O, -P and -V set by emxbind are
ignored. Pass these options on the command line instead.
Command keys:
. display registers and next instruction
: show CS:EIP and next instruction (toggle)
BLANK 1 step
0 10 steps
1-9 1 through 9 steps
C set breakpoint after next instruction and start program. This
command should only be used on CALL instructions
F display floating point (387) status
N step without stopping
F2 display registers and next instruction
F5 start program without setting breakpoint
F8 1 step
F10 set breakpoint after next instruction and start program
Commands:
A <address>
display inforomation about <address> (virtual, physical and
external addresses)
A <range>
ditto, loop through <range> in steps of 1000H bytes
B
display breakpoints and watchpoints
B <address>
set breakpoint (default segment: CS). Up to 3 breakpoints and
watchpoints can be set
D
continue last D command
D <address>
display hex dump: 16 lines (default segment: DS)
D <range>
display hex dump (default segment: DS)
G
start program
G <address>
set temporary breakpoint at <address> (default segment: CS) and
start program
I
display process table: process index, process id, parent process
id, and file handle mapping
K
display breakpoints and watchpoints
K <value>
delete breakpoint or watchpoint (by number)
L <value>
display info about selector <value>
L <value> <value>
ditto, loop through range in steps of 8 (not 4!)
Q
quit, return value 0
Q <value>
quit and set the return value to <value>
R
display registers and next instruction
R <register> <value>
set register to <value>
R <condition>
set/reset processor flag
S <range> <list>
search memory
U
continue last U command
U <address>
unassemble (default segment: CS)
V <value>
display info about virtual address
V <value> <value>
ditto, loop through range in steps of 1000H bytes
VP
display info about pages that have physical memory assigned
VP <value>
display info by physical address
VP <value> <value>
ditto, loop through range in steps of 1000H bytes
VX
display info about pages that have an external address
VX <value>
display info by external address
VX <value> <value>
ditto, loop through range in steps of 1000H bytes
W
display breakpoints and watchpoints
W<l><a> <address>
set watchpoint at given address (default segment: DS). <l> is B
(byte), W (word, <address> must be even) or D (dword, the 2 low
bits of <address> must be zero). <a> is R (trap read and write
accesses), W (trap write accesses) or X (trap modifying write
accesses).
X <value>
find symbol at address <value> or below
The following arguments are used by the commands listed above:
<address>
[<value>:]<value>
selector and offset. If using the SS register for the
selector fails, type the value of SS as hexadecimal number
<symbol>
use address of variable or function <symbol>. If <symbol>
looks like a hexadecimal number you lose
<condition>
Each processor flag has two states:
NC, CY, PE, PO, NA, AC, NZ, ZR, PL, NG, DI, EI, UP, DN, NV, OV
<register>
The following registers can be used:
EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP, EFLAGS,
AX, BX, CX, DX, SI, DI, BP, SP, IP,
AL, AH, BL, BH, CL, CH, DL, DH,
CS, DS, ES, FS, GS, SS
<range>
A <range> includes all addresses between the start address and the
end address:
<address> <address>
The selectors of both addresses must be identical (the
selector of the second address should be omitted, it defaults
to the selector of the first address). The second offset must
be greater than or equal to the first offset
<list>
A <list> is made of one or more values or multi-letter strings:
<value>|'<text>' ...
<value>
A <value> is the basic element of an expression.
0 through ffffffff
Hexadecimal number
<register>
Current value of the register <register>
'<C>'
Character code (ASCII) of the character <C>
If the -S option is used, emx will display swapper statistics when
returning to DOS. It displays
Swapper statistics: F=<f> R=<r> W=<w> N=<n> S=<s>
where <f> is the number of page faults, <r> is the number of swapper
file reads, <w> is the number of swapper file writes, <n> is the
number of times the swap space of present pages has been recycled, and
<s> is the size of the swapper file. All numbers are decimal numbers.
10 Executable file format
=========================
a.out see /emx/include/a_out.h
exe OS/2 LX format with additional sections, see diagram below
┌─────────────────────────────────┐
│ │
│ DOS .exe header: │
│ │
│ ┌──────────────────────────────┤
│ │ │────────┐
│ │ Control information │────┐ │
│ │ │──┐ │ │
│ ├──────────────────────────────┤<─┘ │ │
│ │ │ │ │
│ │ Relocation table │ │ │
│ │ │ │ │
└──┴──────────────────────────────┘ │ │
│ │
┌─────────────────────────────────┐<───┘ │
│ │ │
│ DOS (emx or emxl) image: │ │
│ │ │
│ ┌──────────────────────────────┤ │
│ │ │ │
│ │ emxbind header (options) │──────┐ │
│ │ │ │ │
│ ├──────────────────────────────┤ │ │
│ │ │ │ │
│ │ Code & data │ │ │
│ │ │ │ │
└──┴──────────────────────────────┘ │ │
│ │
┌─────────────────────────────────┐<───────┘
│ │ │
│ OS/2 linear executable header: │ │
│ │ │
│ ┌──────────────────────────────┤ │
│ │ │ │
│ │ Fixed-size header │────┐ │
│ │ │──┐ │ │
│ ├──────────────────────────────┤<─┘ │ │
│ │ │ │ │
│ │ Loader section │──┐ │ │
│ │ │ │ │ │
│ ├──────────────────────────────┤<───┘ │
│ │ │ │ │
│ │ Fixup section │ │ │
│ │ │ │ │
└──┴──────────────────────────────┘ │ │
┌─────────────────────────────────┐<─┤ │
│ │ │ │
│ Resources │ │ │
│ │ │ │
└─────────────────────────────────┘ │ │
┌─────────────────────────────────┐<─│───┘
│ │ │
│ a.out executable: │ │
│ │ │
│ ┌──────────────────────────────┤ │
│ │ │──│──┐
│ │ a.out header │ │ │
│ │ │ │ │
│ ├──────────────────────────────┤<─┤ │
│ │ │ │ │
│ │ Text segment │ │ │
│ │ │ │ │
│ ├──────────────────────────────┤<─┘<─┤
│ │ │ │
│ │ Data segment │ │
│ │ │ │
│ │ ┌───────────────────────────┤ │
│ │ │ │ │
│ │ │ OS/2 emxbind header │ │
│ │ │ │ │
│ │ ├───────────────────────────┤ │
│ │ │ │ │
│ │ │ Other data │ │
│ │ │ │ │
│ ├──┴───────────────────────────┤<────┘
│ │ │
│ │ Symbol table │
│ │ │
└──┴──────────────────────────────┘
11 Known problems
=================
- sleep() and _sleep2() hold signals under DOS, that is, if the
alarm() timer elapses, the signal handler for SIGALRM isn't called
until the completion of those functions
- when using the -C# emx option, memory allocated by an unsuccessful
brk() or sbrk() call isn't freed. That is, as soon as a malloc()
call fails, further calls will also fail. Actually, this isn't a
bug -- it's a lacking feature
- emx doesn't work under DOS if more than 64 MByte of memory is
installed
- running emx programs by a DOS program started by an emx program
seems not to work under certain circumstances [Is this still true?]
- breakpoints are shared by all instances of a program under OS/2 2.1
and earlier -- this is an OS/2 bug which seems to be fixed OS/2 2.11
(ServicePak XR06200 for OS/2 2.1)
- fork() doesn't work correctly in multithread programs.
--------------------------- END OF EMXDEV.DOC ------------------------------