Automate handling of support code for OS/2 binaries.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 27 Feb 2018 03:25:21 -0500
changeset 103 0aaa6d47f023
parent 102 b03f280a02a6
child 104 ab0cb5007af3
Automate handling of support code for OS/2 binaries. Now a perl script parses our headers and generates glue code, export tables, etc. This automates all the macro nonsense and bridge code, and separates out all the stuff you need for binary compat with OS/2, so you can remove it all from the build if you want to just build native libraries that supply the OS/2 API to native apps (like Winelib vs Wine). This makes upkeep details less nasty, and easier to build native binaries when implementing and improving APIs, so you can debug directly without a lot of drama.
lxapigen.pl
native/doscalls-lx.h
native/doscalls.c
native/doscalls.h
native/kbdcalls-lx.h
native/kbdcalls.c
native/kbdcalls.h
native/msg-lx.h
native/msg.c
native/msg.h
native/nls-lx.h
native/nls.c
native/nls.h
native/os2native.h
native/os2types.h
native/pmgpi-lx.h
native/pmgpi.c
native/pmgpi.h
native/pmwin-lx.h
native/pmwin.c
native/pmwin.h
native/quecalls-lx.h
native/quecalls.c
native/quecalls.h
native/sesmgr-lx.h
native/sesmgr.c
native/sesmgr.h
native/tcpip32-lx.h
native/tcpip32.c
native/tcpip32.h
native/viocalls-lx.h
native/viocalls.c
native/viocalls.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lxapigen.pl	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,235 @@
+#!/usr/bin/perl -w
+
+use warnings;
+use strict;
+
+my %typesizes = (
+    'LONG' => 4,
+    'ULONG' => 4,
+    'SHORT' => 2,
+    'USHORT' => 2,
+    'HVIO' => 2,
+    'HKBD' => 2,
+);
+
+sub typesize {
+    my $t = shift;
+    return 4 if ($t =~ /\AP/);  # pointers are 4 bytes (16:16).
+    die("Unknown type '$t', please update \%typesizes\n") if not defined $typesizes{$t};
+    return $typesizes{$t};
+}
+
+my $dirname = defined $ARGV[0] ? $ARGV[0] : 'native';
+opendir(DIRH, $dirname) or die("Failed to opendir '$dirname': $!\n");
+
+while (readdir(DIRH)) {
+    next if not /\.h\Z/;
+    next if /\Aos2/;
+    next if /\-lx\.h\Z/;
+
+    my $module = $_;
+    my $header = "$dirname/$module";
+    $module =~ s/\.h\Z//;
+    open(IN, '<', $header) or die("Failed to open '$header' for reading: $!\n");
+
+    print("$module ...\n");
+
+    my %ordinalmap = ();
+    my $has16bitfns = 0;
+
+    while (<IN>) {
+        chomp;
+        next if not /OS2APIINFO/;
+        my $line = $_;
+
+        if (/\AOS2EXPORT\s+(.*?)\s+(OS2API|OS2API16)\s+(.*?)\((.*?)\)\s+OS2APIINFO\((.*?)\);/) {
+            my %table = (
+                'rettype' => $1,
+                'apitype' => $2,
+                'fn' => $3,
+                'args' => $4,
+            );
+            my $apiinfo = $5;
+
+            my $is16bit = $table{'apitype'} eq 'OS2API16';
+            $table{'is16bit'} = $is16bit;
+            $has16bitfns |= $is16bit;
+
+            #print("rettype='$rettype' fn='$fn' args='$args' apiinfo='$apiinfo'\n");
+
+            my $fn = $table{'fn'};
+            my $ordinal;
+            if ($apiinfo =~ /\A(\d+)\Z/) {
+                $ordinal = int($1);
+            } else {
+                die("bogus OS2APIINFO for '$fn'\n");
+            }
+
+            $table{'ordinal'} = $ordinal;
+
+            if (defined $ordinalmap{$ordinal}) {
+                my $dupfn = $ordinalmap{$ordinal}{'fn'};
+                die("Duplicate ordinal #$ordinal between '$fn' and '$dupfn'\n");
+            }
+
+            $ordinalmap{$ordinal} = \%table;
+        } else {
+            die ("Couldn't parse:\n\n  $line\n\n")
+        }
+    }
+
+    close(IN);
+
+    next if (not %ordinalmap);  # no exported items?
+
+    #use Data::Dumper qw(Dumper); print Dumper \%ordinalmap;
+
+
+    # Here we go...
+
+    my $outfname = "$dirname/$module-lx.h";
+    open(OUT, '>', $outfname) or die("Failed to open '$outfname' for writing: $!\n");
+
+    print OUT <<EOF
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+EOF
+;
+
+    foreach (sort { $a <=> $b } keys(%ordinalmap) ) {
+        my $tableref = $ordinalmap{$_};
+        my $fn = $tableref->{'fn'};
+        my $argstr = $tableref->{'args'};
+        my $rettype = $tableref->{'rettype'};
+        my $is16bit = $tableref->{'is16bit'};
+        my @args = ();
+
+        if (($argstr ne 'VOID') and ($argstr ne 'void')) {
+            @args = split /,/, $argstr;
+        }
+
+        # Build a little wrapper that'll pull arguments off the stack and
+        #  convert to whatever the native calling conventions are.
+        if ($is16bit) {
+            print OUT "static $rettype bridge16to32_$fn(uint8 *args) {\n";
+            #foreach (@args) {
+            # arguments are listed backwards here.
+            for my $i (reverse 0..$#args) {
+                my $arg = $args[$i];
+                my ($t, $n) = $arg =~ /\A\s*(.*?)\s+(.*?)\s*\Z/;
+                #print("arg='$_' t='$t' n='$n'\n");
+                my $a = ($t =~ /\AP/) ? 'PTRARG' : 'ARG';  # it's a pointer?
+                print OUT "    LX_NATIVE_MODULE_16BIT_BRIDGE_$a($t, $n);\n";
+            }
+
+            print OUT "    ";
+            if (($rettype ne 'void') && ($rettype ne 'VOID')) {
+                # Currently it's reasonable to assume the retval will land in EAX.
+                print OUT "return ";
+            }
+
+            print OUT "$fn(";
+            my $comma = '';
+            foreach (@args) {
+                my ($t, $n) = /\A\s*(.*?)\s+(.*?)\s*\Z/;
+                print OUT "$comma$n";
+                $comma = ', ';
+            }
+            print OUT ");\n";
+
+            print OUT "}\n\n";
+        }
+    }
+
+    if ($has16bitfns) {
+        print OUT "LX_NATIVE_MODULE_16BIT_SUPPORT()\n";
+        foreach (sort { $a <=> $b } keys(%ordinalmap) ) {
+            my $tableref = $ordinalmap{$_};
+            next if not $tableref->{'is16bit'};
+            my $fn = $tableref->{'fn'};
+            print OUT "    LX_NATIVE_MODULE_16BIT_API($fn)\n";
+        }
+
+        print OUT "LX_NATIVE_MODULE_16BIT_SUPPORT_END()\n";
+        print OUT "\n";
+        print OUT "LX_NATIVE_MODULE_DEINIT({\n";
+        print OUT "    LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT();\n";
+        print OUT "})\n";
+        print OUT "\n";
+        print OUT "static int init16_$module(void) {\n";
+        print OUT "    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()\n";
+
+        foreach (sort { $a <=> $b } keys(%ordinalmap) ) {
+            my $tableref = $ordinalmap{$_};
+            next if not $tableref->{'is16bit'};
+            my $fn = $tableref->{'fn'};
+            my $argstr = $tableref->{'args'};
+            my $argbytes = 0;
+            my @args = ();
+
+            if (($argstr ne 'VOID') and ($argstr ne 'void')) {
+                @args = split /,/, $argstr;
+            }
+
+            foreach (@args) {
+                my ($t, $n) = /\A\s*(.*?)\s+(.*?)\s*\Z/;
+                $argbytes += typesize($t);
+            }
+            print OUT "        LX_NATIVE_INIT_16BIT_BRIDGE($fn, $argbytes)\n";
+        }
+
+        print OUT "    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END()\n";
+        print OUT "    return 1;\n";
+        print OUT "}\n\n";
+    }
+
+    print OUT "LX_NATIVE_MODULE_INIT(";
+    if ($has16bitfns) {
+        print OUT "{ if (!init16_$module()) return 0; }";
+    }
+    print OUT ")\n";
+
+    my $comma = '';
+    foreach (sort { $a <=> $b } keys(%ordinalmap) ) {
+        my $tableref = $ordinalmap{$_};
+        my $fn = $tableref->{'fn'};
+        my $ordinal = $tableref->{'ordinal'};
+        my $suffix = $tableref->{'is16bit'} ? '16' : '';
+
+        print OUT $comma;
+        # This is a hack for tcpip32, which doesn't want to step on BSD sockets symbols.
+        if ($fn =~ /\AOS2_(.*)\Z/) {
+            print OUT "    LX_NATIVE_EXPORT_DIFFERENT_NAME($fn, \"$1\", $ordinal)";
+        } else {
+            print OUT "    LX_NATIVE_EXPORT$suffix($fn, $ordinal)";
+        }
+        $comma = ",\n";
+    }
+    print OUT "\n";
+
+    print OUT <<EOF
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of $module-lx.h ... */
+
+EOF
+;
+
+    close(OUT);
+}
+
+closedir(DIRH);
+
+# end of lxapigen.pl ...
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/doscalls-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,136 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+static APIRET16 bridge16to32_DosSemRequest(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(LONG, ms);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
+    return DosSemRequest(sem, ms);
+}
+
+static APIRET16 bridge16to32_DosSemClear(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
+    return DosSemClear(sem);
+}
+
+static APIRET16 bridge16to32_DosSemWait(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(LONG, ms);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
+    return DosSemWait(sem, ms);
+}
+
+static APIRET16 bridge16to32_DosSemSet(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
+    return DosSemSet(sem);
+}
+
+LX_NATIVE_MODULE_16BIT_SUPPORT()
+    LX_NATIVE_MODULE_16BIT_API(DosSemRequest)
+    LX_NATIVE_MODULE_16BIT_API(DosSemClear)
+    LX_NATIVE_MODULE_16BIT_API(DosSemWait)
+    LX_NATIVE_MODULE_16BIT_API(DosSemSet)
+LX_NATIVE_MODULE_16BIT_SUPPORT_END()
+
+LX_NATIVE_MODULE_DEINIT({
+    LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT();
+})
+
+static int init16_doscalls(void) {
+    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()
+        LX_NATIVE_INIT_16BIT_BRIDGE(DosSemRequest, 8)
+        LX_NATIVE_INIT_16BIT_BRIDGE(DosSemClear, 4)
+        LX_NATIVE_INIT_16BIT_BRIDGE(DosSemWait, 8)
+        LX_NATIVE_INIT_16BIT_BRIDGE(DosSemSet, 4)
+    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END()
+    return 1;
+}
+
+LX_NATIVE_MODULE_INIT({ if (!init16_doscalls()) return 0; })
+    LX_NATIVE_EXPORT16(DosSemRequest, 140),
+    LX_NATIVE_EXPORT16(DosSemClear, 141),
+    LX_NATIVE_EXPORT16(DosSemWait, 142),
+    LX_NATIVE_EXPORT16(DosSemSet, 143),
+    LX_NATIVE_EXPORT(DosSetMaxFH, 209),
+    LX_NATIVE_EXPORT(DosSetPathInfo, 219),
+    LX_NATIVE_EXPORT(DosQueryPathInfo, 223),
+    LX_NATIVE_EXPORT(DosQueryHType, 224),
+    LX_NATIVE_EXPORT(DosScanEnv, 227),
+    LX_NATIVE_EXPORT(DosSleep, 229),
+    LX_NATIVE_EXPORT(DosGetDateTime, 230),
+    LX_NATIVE_EXPORT(DosDevConfig, 231),
+    LX_NATIVE_EXPORT(DosExit, 234),
+    LX_NATIVE_EXPORT(DosResetBuffer, 254),
+    LX_NATIVE_EXPORT(DosSetFilePtr, 256),
+    LX_NATIVE_EXPORT(DosClose, 257),
+    LX_NATIVE_EXPORT(DosDelete, 259),
+    LX_NATIVE_EXPORT(DosFindClose, 263),
+    LX_NATIVE_EXPORT(DosFindFirst, 264),
+    LX_NATIVE_EXPORT(DosFindNext, 265),
+    LX_NATIVE_EXPORT(DosSetFileSize, 272),
+    LX_NATIVE_EXPORT(DosOpen, 273),
+    LX_NATIVE_EXPORT(DosQueryCurrentDir, 274),
+    LX_NATIVE_EXPORT(DosQueryCurrentDisk, 275),
+    LX_NATIVE_EXPORT(DosQueryFHState, 276),
+    LX_NATIVE_EXPORT(DosQueryFSAttach, 277),
+    LX_NATIVE_EXPORT(DosQueryFileInfo, 279),
+    LX_NATIVE_EXPORT(DosWaitChild, 280),
+    LX_NATIVE_EXPORT(DosRead, 281),
+    LX_NATIVE_EXPORT(DosWrite, 282),
+    LX_NATIVE_EXPORT(DosExecPgm, 283),
+    LX_NATIVE_EXPORT(DosSetProcessCp, 289),
+    LX_NATIVE_EXPORT(DosQueryCp, 291),
+    LX_NATIVE_EXPORT(DosExitList, 296),
+    LX_NATIVE_EXPORT(DosAllocMem, 299),
+    LX_NATIVE_EXPORT(DosFreeMem, 304),
+    LX_NATIVE_EXPORT(DosSetMem, 305),
+    LX_NATIVE_EXPORT(DosCreateThread, 311),
+    LX_NATIVE_EXPORT(DosGetInfoBlocks, 312),
+    LX_NATIVE_EXPORT(DosLoadModule, 318),
+    LX_NATIVE_EXPORT(DosQueryModuleHandle, 319),
+    LX_NATIVE_EXPORT(DosQueryModuleName, 320),
+    LX_NATIVE_EXPORT(DosQueryProcAddr, 321),
+    LX_NATIVE_EXPORT(DosQueryAppType, 323),
+    LX_NATIVE_EXPORT(DosCreateEventSem, 324),
+    LX_NATIVE_EXPORT(DosCloseEventSem, 326),
+    LX_NATIVE_EXPORT(DosResetEventSem, 327),
+    LX_NATIVE_EXPORT(DosPostEventSem, 328),
+    LX_NATIVE_EXPORT(DosWaitEventSem, 329),
+    LX_NATIVE_EXPORT(DosQueryEventSem, 330),
+    LX_NATIVE_EXPORT(DosCreateMutexSem, 331),
+    LX_NATIVE_EXPORT(DosCloseMutexSem, 333),
+    LX_NATIVE_EXPORT(DosRequestMutexSem, 334),
+    LX_NATIVE_EXPORT(DosReleaseMutexSem, 335),
+    LX_NATIVE_EXPORT(DosSubSetMem, 344),
+    LX_NATIVE_EXPORT(DosSubAllocMem, 345),
+    LX_NATIVE_EXPORT(DosSubFreeMem, 346),
+    LX_NATIVE_EXPORT(DosQuerySysInfo, 348),
+    LX_NATIVE_EXPORT(DosWaitThread, 349),
+    LX_NATIVE_EXPORT(DosSetExceptionHandler, 354),
+    LX_NATIVE_EXPORT(DosUnsetExceptionHandler, 355),
+    LX_NATIVE_EXPORT(DosQuerySysState, 368),
+    LX_NATIVE_EXPORT(DosSetSignalExceptionFocus, 378),
+    LX_NATIVE_EXPORT(DosEnterMustComplete, 380),
+    LX_NATIVE_EXPORT(DosExitMustComplete, 381),
+    LX_NATIVE_EXPORT(DosSetRelMaxFH, 382),
+    LX_NATIVE_EXPORT(DosFlatToSel, 425),
+    LX_NATIVE_EXPORT(DosSelToFlat, 426),
+    LX_NATIVE_EXPORT(DosAllocThreadLocalMemory, 454),
+    LX_NATIVE_EXPORT(DosFreeThreadLocalMemory, 455),
+    LX_NATIVE_EXPORT(DosR3ExitAddr, 553),
+    LX_NATIVE_EXPORT(DosQueryHeaderInfo, 582),
+    LX_NATIVE_EXPORT(DosQueryExtLIBPATH, 874),
+    LX_NATIVE_EXPORT(DosQueryThreadContext, 877),
+    LX_NATIVE_EXPORT(DosOpenL, 981)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of doscalls-lx.h ... */
+
--- a/native/doscalls.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/doscalls.c	Tue Feb 27 03:25:21 2018 -0500
@@ -22,40 +22,7 @@
 #include <sys/resource.h>
 #include <sys/stat.h>
 
-// DosQueryHeaderInfo() is an undocumented OS/2 API that is exported from DOSCALLS. Java uses it.
-//  This isn't mentioned in the docs or the SDK (beyond the ordinal being listed). I got the basic details
-//  from Odin32, which lists it in their os2newapi.h header.
-enum
-{
-    QHINF_EXEINFO = 1,
-    QHINF_READRSRCTBL,
-    QHINF_READFILE,
-    QHINF_LIBPATHLENGTH,
-    QHINF_LIBPATH,
-    QHINF_FIXENTRY,
-    QHINF_STE,
-    QHINF_MAPSEL
-};
-
-OS2EXPORT APIRET OS2API DosQueryHeaderInfo(HMODULE hmod, ULONG ulIndex, PVOID pvBuffer, ULONG cbBuffer, ULONG ulSubFunction);
-
-// This is also undocumented (thanks, EDM/2!). Of course, Java uses it.
-OS2EXPORT APIRET OS2API DosQuerySysState(ULONG func, ULONG arg1, ULONG pid, ULONG _res_, PVOID buf, ULONG bufsz);
-
-// This is also undocumented (no idea about this at all, including function params). Of course, Java uses it.
-OS2EXPORT APIRET DosR3ExitAddr(void);
-
-// These are 16-bit APIs that aren't in the 4.5 toolkit headers. Yeah, Java uses them! Winging it.
-typedef int HSEM16, *PHSEM16;
-static APIRET16 DosSemRequest(PHSEM16 sem, LONG ms);
-static APIRET16 DosSemClear(PHSEM16 sem);
-static APIRET16 DosSemWait(PHSEM16 sem, LONG ms);
-static APIRET16 DosSemSet(PHSEM16 sem);
-static APIRET16 bridge16to32_DosSemRequest(uint8 *args);
-static APIRET16 bridge16to32_DosSemClear(uint8 *args);
-static APIRET16 bridge16to32_DosSemWait(uint8 *args);
-static APIRET16 bridge16to32_DosSemSet(uint8 *args);
-
+#include "doscalls-lx.h"
 
 static pthread_mutex_t GMutexDosCalls;
 
@@ -2783,7 +2750,7 @@
     return (__sync_lock_test_and_set(lock, 1) == 0);
 } // trySpinLock
 
-static APIRET16 DosSemRequest(PHSEM16 sem, LONG ms)
+APIRET16 DosSemRequest(PHSEM16 sem, LONG ms)
 {
     TRACE_NATIVE("DosSemRequest(%p, %u)", sem, (uint) ms);
     if (ms == 0) {
@@ -2812,14 +2779,14 @@
     return NO_ERROR;
 } // DosSemRequest
 
-static APIRET16 DosSemClear(PHSEM16 sem)
+APIRET16 DosSemClear(PHSEM16 sem)
 {
     TRACE_NATIVE("DosSemClear(%p)", sem);
     __sync_lock_release(sem);
     return NO_ERROR;
 } // DosSemClear
 
-static APIRET16 DosSemWait(PHSEM16 sem, LONG ms)
+APIRET16 DosSemWait(PHSEM16 sem, LONG ms)
 {
     TRACE_NATIVE("DosSemWait(%p, %u)", sem, (uint) ms);
     if (ms == 0) {
@@ -2848,39 +2815,13 @@
     return NO_ERROR;
 } // DosSemWait
 
-static APIRET16 DosSemSet(PHSEM16 sem)
+APIRET16 DosSemSet(PHSEM16 sem)
 {
     TRACE_NATIVE("DosSemSet(%p)", sem);
     __sync_bool_compare_and_swap(sem, 1, 0);
     return NO_ERROR;
 } // DosSemSet
 
-static APIRET16 bridge16to32_DosSemRequest(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(LONG, ms);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
-    return DosSemRequest(sem, ms);
-} // bridge16to32_DosSemRequest
-
-static APIRET16 bridge16to32_DosSemClear(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
-    return DosSemClear(sem);
-} // bridge16to32_DosSemClear
-
-static APIRET16 bridge16to32_DosSemWait(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(LONG, ms);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
-    return DosSemWait(sem, ms);
-} // bridge16to32_DosSemWait
-
-static APIRET16 bridge16to32_DosSemSet(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
-    return DosSemSet(sem);
-} // bridge16to32_DosSemSet
-
 APIRET DosCloseMutexSem(HMTX hmtx)
 {
     TRACE_NATIVE("DosCloseMutexSem(%u)", (uint) hmtx);
@@ -2930,58 +2871,23 @@
 } // DosSetFileSize
 
 
-LX_NATIVE_MODULE_16BIT_SUPPORT()
-    LX_NATIVE_MODULE_16BIT_API(DosSemRequest)
-    LX_NATIVE_MODULE_16BIT_API(DosSemClear)
-    LX_NATIVE_MODULE_16BIT_API(DosSemWait)
-    LX_NATIVE_MODULE_16BIT_API(DosSemSet)
-LX_NATIVE_MODULE_16BIT_SUPPORT_END()
-
-LX_NATIVE_MODULE_DEINIT({
-    GLoaderState->dosExit = NULL;
-
-    ExitListItem *next = GExitList;
-    GExitList = NULL;
-
-    for (ExitListItem *item = next; item; item = next) {
-        next = item->next;
-        free(item);
-    } // for
-
-    for (uint32 i = 0; i < MaxHFiles; i++) {
-        if (HFiles[i].fd > 2)  // don't close -1, or any stdio handles.
-            close(HFiles[i].fd);
-    } // for
-    free(HFiles);
-    HFiles = NULL;
-    MaxHFiles = 0;
-
-    pthread_mutex_destroy(&GMutexDosCalls);
-
-    LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT();
-})
-
-static int initDoscalls(void)
+LX_NATIVE_CONSTRUCTOR(doscalls)
 {
-    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()
-        LX_NATIVE_INIT_16BIT_BRIDGE(DosSemRequest, 8)
-        LX_NATIVE_INIT_16BIT_BRIDGE(DosSemClear, 4)
-        LX_NATIVE_INIT_16BIT_BRIDGE(DosSemWait, 8)
-        LX_NATIVE_INIT_16BIT_BRIDGE(DosSemSet, 4)
-    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END()
-
-    GLoaderState->dosExit = DosExit;
+    if (GLoaderState) {
+        GLoaderState->dosExit = DosExit;
+    }
 
     if (pthread_mutex_init(&GMutexDosCalls, NULL) == -1) {
         fprintf(stderr, "pthread_mutex_init failed!\n");
-        return 0;
+        abort();
     } // if
 
     MaxHFiles = 20;  // seems to be OS/2's default.
     HFiles = (HFileInfo *) malloc(sizeof (HFileInfo) * MaxHFiles);
     if (!HFiles) {
+        pthread_mutex_destroy(&GMutexDosCalls);
         fprintf(stderr, "Out of memory!\n");
-        return 0;
+        abort();
     } // if
 
     HFileInfo *info = HFiles;
@@ -3007,88 +2913,32 @@
         HFiles[i].type = 1;  // !!! FIXME: could be a pipe or file.
         HFiles[i].attr = DAW_STDIN | DAW_STDOUT | DAW_LEVEL1 | DAW_CHARACTER;
     } // for
-
-    return 1;
-} // initDoscalls
-
-LX_NATIVE_MODULE_INIT({ if (!initDoscalls()) return NULL; })
-    LX_NATIVE_EXPORT16(DosSemRequest, 140),
-    LX_NATIVE_EXPORT16(DosSemClear, 141),
-    LX_NATIVE_EXPORT16(DosSemWait, 142),
-    LX_NATIVE_EXPORT16(DosSemSet, 143),
-    LX_NATIVE_EXPORT(DosSetMaxFH, 209),
-    LX_NATIVE_EXPORT(DosSetPathInfo, 219),
-    LX_NATIVE_EXPORT(DosQueryPathInfo, 223),
-    LX_NATIVE_EXPORT(DosQueryHType, 224),
-    LX_NATIVE_EXPORT(DosScanEnv, 227),
-    LX_NATIVE_EXPORT(DosSleep, 229),
-    LX_NATIVE_EXPORT(DosGetDateTime, 230),
-    LX_NATIVE_EXPORT(DosDevConfig, 231),
-    LX_NATIVE_EXPORT(DosExit, 234),
-    LX_NATIVE_EXPORT(DosResetBuffer, 254),
-    LX_NATIVE_EXPORT(DosSetFilePtr, 256),
-    LX_NATIVE_EXPORT(DosClose, 257),
-    LX_NATIVE_EXPORT(DosDelete, 259),
-    LX_NATIVE_EXPORT(DosFindClose, 263),
-    LX_NATIVE_EXPORT(DosFindFirst, 264),
-    LX_NATIVE_EXPORT(DosFindNext, 265),
-    LX_NATIVE_EXPORT(DosSetFileSize, 272),
-    LX_NATIVE_EXPORT(DosOpen, 273),
-    LX_NATIVE_EXPORT(DosQueryCurrentDir, 274),
-    LX_NATIVE_EXPORT(DosQueryCurrentDisk, 275),
-    LX_NATIVE_EXPORT(DosQueryFHState, 276),
-    LX_NATIVE_EXPORT(DosQueryFSAttach, 277),
-    LX_NATIVE_EXPORT(DosQueryFileInfo, 279),
-    LX_NATIVE_EXPORT(DosWaitChild, 280),
-    LX_NATIVE_EXPORT(DosRead, 281),
-    LX_NATIVE_EXPORT(DosWrite, 282),
-    LX_NATIVE_EXPORT(DosExecPgm, 283),
-    LX_NATIVE_EXPORT(DosSetProcessCp, 289),
-    LX_NATIVE_EXPORT(DosQueryCp, 291),
-    LX_NATIVE_EXPORT(DosExitList, 296),
-    LX_NATIVE_EXPORT(DosAllocMem, 299),
-    LX_NATIVE_EXPORT(DosFreeMem, 304),
-    LX_NATIVE_EXPORT(DosSetMem, 305),
-    LX_NATIVE_EXPORT(DosCreateThread, 311),
-    LX_NATIVE_EXPORT(DosGetInfoBlocks, 312),
-    LX_NATIVE_EXPORT(DosLoadModule, 318),
-    LX_NATIVE_EXPORT(DosQueryModuleHandle, 319),
-    LX_NATIVE_EXPORT(DosQueryModuleName, 320),
-    LX_NATIVE_EXPORT(DosQueryProcAddr, 321),
-    LX_NATIVE_EXPORT(DosQueryAppType, 323),
-    LX_NATIVE_EXPORT(DosCreateEventSem, 324),
-    LX_NATIVE_EXPORT(DosCloseEventSem, 326),
-    LX_NATIVE_EXPORT(DosResetEventSem, 327),
-    LX_NATIVE_EXPORT(DosPostEventSem, 328),
-    LX_NATIVE_EXPORT(DosWaitEventSem, 329),
-    LX_NATIVE_EXPORT(DosQueryEventSem, 330),
-    LX_NATIVE_EXPORT(DosCreateMutexSem, 331),
-    LX_NATIVE_EXPORT(DosCloseMutexSem, 333),
-    LX_NATIVE_EXPORT(DosRequestMutexSem, 334),
-    LX_NATIVE_EXPORT(DosReleaseMutexSem, 335),
-    LX_NATIVE_EXPORT(DosSubSetMem, 344),
-    LX_NATIVE_EXPORT(DosSubAllocMem, 345),
-    LX_NATIVE_EXPORT(DosSubFreeMem, 346),
-    LX_NATIVE_EXPORT(DosQuerySysInfo, 348),
-    LX_NATIVE_EXPORT(DosWaitThread, 349),
-    LX_NATIVE_EXPORT(DosSetExceptionHandler, 354),
-    LX_NATIVE_EXPORT(DosUnsetExceptionHandler, 355),
-    LX_NATIVE_EXPORT(DosQuerySysState, 368),
-    LX_NATIVE_EXPORT(DosSetSignalExceptionFocus, 378),
-    LX_NATIVE_EXPORT(DosEnterMustComplete, 380),
-    LX_NATIVE_EXPORT(DosExitMustComplete, 381),
-    LX_NATIVE_EXPORT(DosSetRelMaxFH, 382),
-    LX_NATIVE_EXPORT(DosFlatToSel, 425),
-    LX_NATIVE_EXPORT(DosSelToFlat, 426),
-    LX_NATIVE_EXPORT(DosAllocThreadLocalMemory, 454),
-    LX_NATIVE_EXPORT(DosFreeThreadLocalMemory, 455),
-    LX_NATIVE_EXPORT(DosR3ExitAddr, 553),
-    LX_NATIVE_EXPORT(DosQueryHeaderInfo, 582),
-    LX_NATIVE_EXPORT(DosQueryExtLIBPATH, 874),
-    LX_NATIVE_EXPORT(DosQueryThreadContext, 877),
-    LX_NATIVE_EXPORT(DosOpenL, 981)
-LX_NATIVE_MODULE_INIT_END()
-
+}
+
+LX_NATIVE_DESTRUCTOR(doscalls)
+{
+    if (GLoaderState) {
+        GLoaderState->dosExit = NULL;
+    }
+
+    ExitListItem *next = GExitList;
+    GExitList = NULL;
+
+    for (ExitListItem *item = next; item; item = next) {
+        next = item->next;
+        free(item);
+    } // for
+
+    for (uint32 i = 0; i < MaxHFiles; i++) {
+        if (HFiles[i].fd > 2)  // don't close -1, or any stdio handles.
+            close(HFiles[i].fd);
+    } // for
+    free(HFiles);
+    HFiles = NULL;
+    MaxHFiles = 0;
+
+    pthread_mutex_destroy(&GMutexDosCalls);
+}
 
 // end of doscalls.c ...
 
--- a/native/doscalls.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/doscalls.h	Tue Feb 27 03:25:21 2018 -0500
@@ -398,78 +398,111 @@
 
 typedef void *PCONTEXTRECORD;  // !!! FIXME
 
+
+// DosQueryHeaderInfo() is an undocumented OS/2 API that is exported from DOSCALLS. Java uses it.
+//  This isn't mentioned in the docs or the SDK (beyond the ordinal being listed). I got the basic details
+//  from Odin32, which lists it in their os2newapi.h header.
+enum
+{
+    QHINF_EXEINFO = 1,
+    QHINF_READRSRCTBL,
+    QHINF_READFILE,
+    QHINF_LIBPATHLENGTH,
+    QHINF_LIBPATH,
+    QHINF_FIXENTRY,
+    QHINF_STE,
+    QHINF_MAPSEL
+};
+
+OS2EXPORT APIRET OS2API DosQueryHeaderInfo(HMODULE hmod, ULONG ulIndex, PVOID pvBuffer, ULONG cbBuffer, ULONG ulSubFunction) OS2APIINFO(582);
+
+// This is also undocumented (thanks, EDM/2!). Of course, Java uses it.
+OS2EXPORT APIRET OS2API DosQuerySysState(ULONG func, ULONG arg1, ULONG pid, ULONG _res_, PVOID buf, ULONG bufsz) OS2APIINFO(368);
+
+// This is also undocumented (no idea about this at all, including function params). Of course, Java uses it.
+OS2EXPORT APIRET OS2API DosR3ExitAddr(void) OS2APIINFO(553);
+
+// These are 16-bit APIs that aren't in the 4.5 toolkit headers. Yeah, Java uses them! Winging it.
+typedef int HSEM16, *PHSEM16;  // !!! FIXME: int? Not short?
+OS2EXPORT APIRET16 OS2API16 DosSemRequest(PHSEM16 sem, LONG ms) OS2APIINFO(140);
+OS2EXPORT APIRET16 OS2API16 DosSemClear(PHSEM16 sem) OS2APIINFO(141);
+OS2EXPORT APIRET16 OS2API16 DosSemWait(PHSEM16 sem, LONG ms) OS2APIINFO(142);
+OS2EXPORT APIRET16 OS2API16 DosSemSet(PHSEM16 sem) OS2APIINFO(143);
+
+
+
 // !!! FIXME: these should probably get sorted alphabetically and/or grouped
 // !!! FIXME:  into areas of functionality, but for now, I'm just listing them
 // !!! FIXME:  in the order I implemented them to get things running.
 
-OS2EXPORT APIRET OS2API DosGetInfoBlocks(PTIB *pptib, PPIB *pppib);
-OS2EXPORT APIRET OS2API DosQuerySysInfo(ULONG iStart, ULONG iLast, PVOID pBuf, ULONG cbBuf);
-OS2EXPORT APIRET OS2API DosQueryModuleName(HMODULE hmod, ULONG cbName, PCHAR pch);
-OS2EXPORT APIRET OS2API DosScanEnv(PSZ pszName, PSZ *ppszValue);
-OS2EXPORT APIRET OS2API DosWrite(HFILE hFile, PVOID pBuffer, ULONG cbWrite, PULONG pcbActual);
-OS2EXPORT VOID OS2API DosExit(ULONG action, ULONG result);
-OS2EXPORT APIRET OS2API DosExitList(ULONG ordercode, PFNEXITLIST pfn);
-OS2EXPORT APIRET OS2API DosCreateEventSem(PSZ pszName, PHEV phev, ULONG flAttr, BOOL32 fState);
-OS2EXPORT APIRET OS2API DosCreateMutexSem(PSZ pszName, PHMTX phmtx, ULONG flAttr, BOOL32 fState);
-OS2EXPORT APIRET OS2API DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec);
-OS2EXPORT APIRET OS2API DosUnsetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec);
-OS2EXPORT ULONG OS2API DosFlatToSel(VOID);
-OS2EXPORT APIRET OS2API DosSetSignalExceptionFocus(BOOL32 flag, PULONG pulTimes);
-OS2EXPORT APIRET OS2API DosSetRelMaxFH(PLONG pcbReqCount, PULONG pcbCurMaxFH);
-OS2EXPORT APIRET OS2API DosAllocMem(PPVOID ppb, ULONG cb, ULONG flag);
-OS2EXPORT APIRET OS2API DosSubSetMem(PVOID pbBase, ULONG flag, ULONG cb);
-OS2EXPORT APIRET OS2API DosSubAllocMem(PVOID pbBase, PPVOID ppb, ULONG cb);
-OS2EXPORT APIRET OS2API DosQueryHType(HFILE hFile, PULONG pType, PULONG pAttr);
-OS2EXPORT APIRET OS2API DosSetMem(PVOID pb, ULONG cb, ULONG flag);
-OS2EXPORT APIRET OS2API DosGetDateTime(PDATETIME pdt);
-OS2EXPORT APIRET OS2API DosOpen(PSZ pszFileName, PHFILE pHf, PULONG pulAction, ULONG cbFile, ULONG ulAttribute, ULONG fsOpenFlags, ULONG fsOpenMode, PEAOP2 peaop2);
-OS2EXPORT APIRET OS2API DosRequestMutexSem(HMTX hmtx, ULONG ulTimeout);
-OS2EXPORT APIRET OS2API DosReleaseMutexSem(HMTX hmtx);
-OS2EXPORT APIRET OS2API DosSetFilePtr(HFILE hFile, LONG ib, ULONG method, PULONG ibActual);
-OS2EXPORT APIRET OS2API DosRead(HFILE hFile, PVOID pBuffer, ULONG cbRead, PULONG pcbActual);
-OS2EXPORT APIRET OS2API DosClose(HFILE hFile);
-OS2EXPORT APIRET OS2API DosEnterMustComplete(PULONG pulNesting);
-OS2EXPORT APIRET OS2API DosExitMustComplete(PULONG pulNesting);
-OS2EXPORT APIRET OS2API DosQueryPathInfo(PSZ pszPathName, ULONG ulInfoLevel, PVOID pInfoBuf, ULONG cbInfoBuf);
-OS2EXPORT APIRET OS2API DosQueryFileInfo(HFILE hf, ULONG ulInfoLevel, PVOID pInfo, ULONG cbInfoBuf);
-OS2EXPORT APIRET OS2API DosCreateThread(PTID ptid, PFNTHREAD pfn, ULONG param, ULONG flag, ULONG cbStack);
-OS2EXPORT APIRET OS2API DosExecPgm(PCHAR pObjname, LONG cbObjname, ULONG execFlag, PSZ pArg, PSZ pEnv, PRESULTCODES pRes, PSZ pName);
-OS2EXPORT APIRET OS2API DosResetEventSem(HEV hev, PULONG pulPostCt);
-OS2EXPORT APIRET OS2API DosPostEventSem(HEV hev);
-OS2EXPORT APIRET OS2API DosCloseEventSem(HEV hev);
-OS2EXPORT APIRET OS2API DosWaitEventSem(HEV hev, ULONG ulTimeout);
-OS2EXPORT APIRET OS2API DosQueryEventSem(HEV hev, PULONG pulPostCt);
-OS2EXPORT APIRET OS2API DosFreeMem(PVOID pb);
-OS2EXPORT APIRET OS2API DosWaitChild(ULONG action, ULONG option, PRESULTCODES pres, PPID ppid, PID pid);
-OS2EXPORT APIRET OS2API DosWaitThread(PTID ptid, ULONG option);
-OS2EXPORT APIRET OS2API DosSleep(ULONG msec);
-OS2EXPORT APIRET OS2API DosSubFreeMem(PVOID pbBase, PVOID pb, ULONG cb);
-OS2EXPORT APIRET OS2API DosDelete(PSZ pszFile);
-OS2EXPORT APIRET OS2API DosQueryCurrentDir(ULONG disknum, PBYTE pBuf, PULONG pcbBuf);
-OS2EXPORT APIRET OS2API DosSetPathInfo(PSZ pszPathName, ULONG ulInfoLevel, PVOID pInfoBuf, ULONG cbInfoBuf, ULONG flOptions);
-OS2EXPORT APIRET OS2API DosQueryModuleHandle(PSZ pszModname, PHMODULE phmod);
-OS2EXPORT APIRET OS2API DosQueryProcAddr(HMODULE hmod, ULONG ordinal, PSZ pszName, PFN* ppfn);
-OS2EXPORT APIRET OS2API DosQueryCp(ULONG cb, PULONG arCP, PULONG pcCP);
-OS2EXPORT APIRET OS2API DosOpenL(PSZ pszFileName, PHFILE pHf, PULONG pulAction, LONGLONG cbFile, ULONG ulAttribute, ULONG fsOpenFlags, ULONG fsOpenMode, PEAOP2 peaop2);
-OS2EXPORT APIRET OS2API DosFindFirst(PSZ pszFileSpec, PHDIR phdir, ULONG flAttribute, PVOID pfindbuf, ULONG cbBuf, PULONG pcFileNames, ULONG ulInfoLevel);
-OS2EXPORT APIRET OS2API DosFindNext(HDIR hDir, PVOID pfindbuf, ULONG cbfindbuf, PULONG pcFilenames);
-OS2EXPORT APIRET OS2API DosFindClose(HDIR hDir);
-OS2EXPORT APIRET OS2API DosQueryCurrentDisk(PULONG pdisknum, PULONG plogical);
-OS2EXPORT APIRET OS2API DosDevConfig(PVOID pdevinfo, ULONG item);
-OS2EXPORT APIRET OS2API DosLoadModule(PSZ pszName, ULONG cbName, PSZ pszModname, PHMODULE phmod);
-OS2EXPORT APIRET OS2API DosResetBuffer(HFILE hFile);
-OS2EXPORT APIRET OS2API DosQueryAppType(PSZ pszName, PULONG pFlags);
-OS2EXPORT APIRET OS2API DosAllocThreadLocalMemory(ULONG cb, PULONG *p);
-OS2EXPORT APIRET OS2API DosFreeThreadLocalMemory(ULONG *p);
-OS2EXPORT APIRET OS2API DosQueryFHState(HFILE hFile, PULONG pMode);
-OS2EXPORT APIRET OS2API DosQueryExtLIBPATH(PSZ pszExtLIBPATH, ULONG flags);
-OS2EXPORT APIRET OS2API DosSetMaxFH(ULONG cFH);
-OS2EXPORT APIRET OS2API DosQueryThreadContext(TID tid, ULONG level, PCONTEXTRECORD pcxt);
-OS2EXPORT ULONG OS2API DosSelToFlat(VOID);
-OS2EXPORT APIRET OS2API DosCloseMutexSem(HMTX hmtx);
-OS2EXPORT APIRET OS2API DosSetProcessCp(ULONG cp);
-OS2EXPORT APIRET OS2API DosQueryFSAttach(PSZ pszDeviceName, ULONG ulOrdinal, ULONG ulFSAInfoLevel, PFSQBUFFER2 pfsqb, PULONG pcbBuffLength);
-OS2EXPORT APIRET OS2API DosSetFileSize(HFILE hFile, ULONG cbSize);
+OS2EXPORT APIRET OS2API DosGetInfoBlocks(PTIB *pptib, PPIB *pppib) OS2APIINFO(312);
+OS2EXPORT APIRET OS2API DosQuerySysInfo(ULONG iStart, ULONG iLast, PVOID pBuf, ULONG cbBuf) OS2APIINFO(348);
+OS2EXPORT APIRET OS2API DosQueryModuleName(HMODULE hmod, ULONG cbName, PCHAR pch) OS2APIINFO(320);
+OS2EXPORT APIRET OS2API DosScanEnv(PSZ pszName, PSZ *ppszValue) OS2APIINFO(227);
+OS2EXPORT APIRET OS2API DosWrite(HFILE hFile, PVOID pBuffer, ULONG cbWrite, PULONG pcbActual) OS2APIINFO(282);
+OS2EXPORT VOID OS2API DosExit(ULONG action, ULONG result) OS2APIINFO(234);
+OS2EXPORT APIRET OS2API DosExitList(ULONG ordercode, PFNEXITLIST pfn) OS2APIINFO(296);
+OS2EXPORT APIRET OS2API DosCreateEventSem(PSZ pszName, PHEV phev, ULONG flAttr, BOOL32 fState) OS2APIINFO(324);
+OS2EXPORT APIRET OS2API DosCreateMutexSem(PSZ pszName, PHMTX phmtx, ULONG flAttr, BOOL32 fState) OS2APIINFO(331);
+OS2EXPORT APIRET OS2API DosSetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec) OS2APIINFO(354);
+OS2EXPORT APIRET OS2API DosUnsetExceptionHandler(PEXCEPTIONREGISTRATIONRECORD pERegRec) OS2APIINFO(355);
+OS2EXPORT ULONG OS2API DosFlatToSel(VOID) OS2APIINFO(425);
+OS2EXPORT APIRET OS2API DosSetSignalExceptionFocus(BOOL32 flag, PULONG pulTimes) OS2APIINFO(378);
+OS2EXPORT APIRET OS2API DosSetRelMaxFH(PLONG pcbReqCount, PULONG pcbCurMaxFH) OS2APIINFO(382);
+OS2EXPORT APIRET OS2API DosAllocMem(PPVOID ppb, ULONG cb, ULONG flag) OS2APIINFO(299);
+OS2EXPORT APIRET OS2API DosSubSetMem(PVOID pbBase, ULONG flag, ULONG cb) OS2APIINFO(344);
+OS2EXPORT APIRET OS2API DosSubAllocMem(PVOID pbBase, PPVOID ppb, ULONG cb) OS2APIINFO(345);
+OS2EXPORT APIRET OS2API DosQueryHType(HFILE hFile, PULONG pType, PULONG pAttr) OS2APIINFO(224);
+OS2EXPORT APIRET OS2API DosSetMem(PVOID pb, ULONG cb, ULONG flag) OS2APIINFO(305);
+OS2EXPORT APIRET OS2API DosGetDateTime(PDATETIME pdt) OS2APIINFO(230);
+OS2EXPORT APIRET OS2API DosOpen(PSZ pszFileName, PHFILE pHf, PULONG pulAction, ULONG cbFile, ULONG ulAttribute, ULONG fsOpenFlags, ULONG fsOpenMode, PEAOP2 peaop2) OS2APIINFO(273);
+OS2EXPORT APIRET OS2API DosRequestMutexSem(HMTX hmtx, ULONG ulTimeout) OS2APIINFO(334);
+OS2EXPORT APIRET OS2API DosReleaseMutexSem(HMTX hmtx) OS2APIINFO(335);
+OS2EXPORT APIRET OS2API DosSetFilePtr(HFILE hFile, LONG ib, ULONG method, PULONG ibActual) OS2APIINFO(256);
+OS2EXPORT APIRET OS2API DosRead(HFILE hFile, PVOID pBuffer, ULONG cbRead, PULONG pcbActual) OS2APIINFO(281);
+OS2EXPORT APIRET OS2API DosClose(HFILE hFile) OS2APIINFO(257);
+OS2EXPORT APIRET OS2API DosEnterMustComplete(PULONG pulNesting) OS2APIINFO(380);
+OS2EXPORT APIRET OS2API DosExitMustComplete(PULONG pulNesting) OS2APIINFO(381);
+OS2EXPORT APIRET OS2API DosQueryPathInfo(PSZ pszPathName, ULONG ulInfoLevel, PVOID pInfoBuf, ULONG cbInfoBuf) OS2APIINFO(223);
+OS2EXPORT APIRET OS2API DosQueryFileInfo(HFILE hf, ULONG ulInfoLevel, PVOID pInfo, ULONG cbInfoBuf) OS2APIINFO(279);
+OS2EXPORT APIRET OS2API DosCreateThread(PTID ptid, PFNTHREAD pfn, ULONG param, ULONG flag, ULONG cbStack) OS2APIINFO(311);
+OS2EXPORT APIRET OS2API DosExecPgm(PCHAR pObjname, LONG cbObjname, ULONG execFlag, PSZ pArg, PSZ pEnv, PRESULTCODES pRes, PSZ pName) OS2APIINFO(283);
+OS2EXPORT APIRET OS2API DosResetEventSem(HEV hev, PULONG pulPostCt) OS2APIINFO(327);
+OS2EXPORT APIRET OS2API DosPostEventSem(HEV hev) OS2APIINFO(328);
+OS2EXPORT APIRET OS2API DosCloseEventSem(HEV hev) OS2APIINFO(326);
+OS2EXPORT APIRET OS2API DosWaitEventSem(HEV hev, ULONG ulTimeout) OS2APIINFO(329);
+OS2EXPORT APIRET OS2API DosQueryEventSem(HEV hev, PULONG pulPostCt) OS2APIINFO(330);
+OS2EXPORT APIRET OS2API DosFreeMem(PVOID pb) OS2APIINFO(304);
+OS2EXPORT APIRET OS2API DosWaitChild(ULONG action, ULONG option, PRESULTCODES pres, PPID ppid, PID pid) OS2APIINFO(280);
+OS2EXPORT APIRET OS2API DosWaitThread(PTID ptid, ULONG option) OS2APIINFO(349);
+OS2EXPORT APIRET OS2API DosSleep(ULONG msec) OS2APIINFO(229);
+OS2EXPORT APIRET OS2API DosSubFreeMem(PVOID pbBase, PVOID pb, ULONG cb) OS2APIINFO(346);
+OS2EXPORT APIRET OS2API DosDelete(PSZ pszFile) OS2APIINFO(259);
+OS2EXPORT APIRET OS2API DosQueryCurrentDir(ULONG disknum, PBYTE pBuf, PULONG pcbBuf) OS2APIINFO(274);
+OS2EXPORT APIRET OS2API DosSetPathInfo(PSZ pszPathName, ULONG ulInfoLevel, PVOID pInfoBuf, ULONG cbInfoBuf, ULONG flOptions) OS2APIINFO(219);
+OS2EXPORT APIRET OS2API DosQueryModuleHandle(PSZ pszModname, PHMODULE phmod) OS2APIINFO(319);
+OS2EXPORT APIRET OS2API DosQueryProcAddr(HMODULE hmod, ULONG ordinal, PSZ pszName, PFN* ppfn) OS2APIINFO(321);
+OS2EXPORT APIRET OS2API DosQueryCp(ULONG cb, PULONG arCP, PULONG pcCP) OS2APIINFO(291);
+OS2EXPORT APIRET OS2API DosOpenL(PSZ pszFileName, PHFILE pHf, PULONG pulAction, LONGLONG cbFile, ULONG ulAttribute, ULONG fsOpenFlags, ULONG fsOpenMode, PEAOP2 peaop2) OS2APIINFO(981);
+OS2EXPORT APIRET OS2API DosFindFirst(PSZ pszFileSpec, PHDIR phdir, ULONG flAttribute, PVOID pfindbuf, ULONG cbBuf, PULONG pcFileNames, ULONG ulInfoLevel) OS2APIINFO(264);
+OS2EXPORT APIRET OS2API DosFindNext(HDIR hDir, PVOID pfindbuf, ULONG cbfindbuf, PULONG pcFilenames) OS2APIINFO(265);
+OS2EXPORT APIRET OS2API DosFindClose(HDIR hDir) OS2APIINFO(263);
+OS2EXPORT APIRET OS2API DosQueryCurrentDisk(PULONG pdisknum, PULONG plogical) OS2APIINFO(275);
+OS2EXPORT APIRET OS2API DosDevConfig(PVOID pdevinfo, ULONG item) OS2APIINFO(231);
+OS2EXPORT APIRET OS2API DosLoadModule(PSZ pszName, ULONG cbName, PSZ pszModname, PHMODULE phmod) OS2APIINFO(318);
+OS2EXPORT APIRET OS2API DosResetBuffer(HFILE hFile) OS2APIINFO(254);
+OS2EXPORT APIRET OS2API DosQueryAppType(PSZ pszName, PULONG pFlags) OS2APIINFO(323);
+OS2EXPORT APIRET OS2API DosAllocThreadLocalMemory(ULONG cb, PULONG *p) OS2APIINFO(454);
+OS2EXPORT APIRET OS2API DosFreeThreadLocalMemory(ULONG *p) OS2APIINFO(455);
+OS2EXPORT APIRET OS2API DosQueryFHState(HFILE hFile, PULONG pMode) OS2APIINFO(276);
+OS2EXPORT APIRET OS2API DosQueryExtLIBPATH(PSZ pszExtLIBPATH, ULONG flags) OS2APIINFO(874);
+OS2EXPORT APIRET OS2API DosSetMaxFH(ULONG cFH) OS2APIINFO(209);
+OS2EXPORT APIRET OS2API DosQueryThreadContext(TID tid, ULONG level, PCONTEXTRECORD pcxt) OS2APIINFO(877);
+OS2EXPORT ULONG OS2API DosSelToFlat(VOID) OS2APIINFO(426);
+OS2EXPORT APIRET OS2API DosCloseMutexSem(HMTX hmtx) OS2APIINFO(333);
+OS2EXPORT APIRET OS2API DosSetProcessCp(ULONG cp) OS2APIINFO(289);
+OS2EXPORT APIRET OS2API DosQueryFSAttach(PSZ pszDeviceName, ULONG ulOrdinal, ULONG ulFSAInfoLevel, PFSQBUFFER2 pfsqb, PULONG pcbBuffLength) OS2APIINFO(277);
+OS2EXPORT APIRET OS2API DosSetFileSize(HFILE hFile, ULONG cbSize) OS2APIINFO(272);
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/kbdcalls-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,41 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+static APIRET16 bridge16to32_KbdCharIn(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HKBD, hkbd);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, fWait);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PKBDKEYINFO, pkbci);
+    return KbdCharIn(pkbci, fWait, hkbd);
+}
+
+LX_NATIVE_MODULE_16BIT_SUPPORT()
+    LX_NATIVE_MODULE_16BIT_API(KbdCharIn)
+LX_NATIVE_MODULE_16BIT_SUPPORT_END()
+
+LX_NATIVE_MODULE_DEINIT({
+    LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT();
+})
+
+static int init16_kbdcalls(void) {
+    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()
+        LX_NATIVE_INIT_16BIT_BRIDGE(KbdCharIn, 8)
+    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END()
+    return 1;
+}
+
+LX_NATIVE_MODULE_INIT({ if (!init16_kbdcalls()) return 0; })
+    LX_NATIVE_EXPORT16(KbdCharIn, 4)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of kbdcalls-lx.h ... */
+
--- a/native/kbdcalls.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/kbdcalls.c	Tue Feb 27 03:25:21 2018 -0500
@@ -9,6 +9,8 @@
 #include "os2native16.h"
 #include "kbdcalls.h"
 
+#include "kbdcalls-lx.h"
+
 APIRET16 KbdCharIn(PKBDKEYINFO pkbci, USHORT fWait, HKBD hkbd)
 {
     TRACE_NATIVE("KbdCharIn(%p, %u, %u)", pkbci, fWait, hkbd);
@@ -18,33 +20,5 @@
     return NO_ERROR;
 } // kbdCharIn
 
-static APIRET16 bridge16to32_KbdCharIn(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HKBD, hkbd);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, fWait);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PKBDKEYINFO, pkbci);
-    return KbdCharIn(pkbci, fWait, hkbd);
-} // bridge16to32_KbdCharIn
-
-LX_NATIVE_MODULE_16BIT_SUPPORT()
-    LX_NATIVE_MODULE_16BIT_API(KbdCharIn)
-LX_NATIVE_MODULE_16BIT_SUPPORT_END()
-
-LX_NATIVE_MODULE_DEINIT({
-    LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT();
-})
-
-static int initKbdcalls(void)
-{
-    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()
-        LX_NATIVE_INIT_16BIT_BRIDGE(KbdCharIn, 6)
-    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END()
-    return 1;
-} // initViocalls
-
-LX_NATIVE_MODULE_INIT({ if (!initKbdcalls()) return NULL; })
-    LX_NATIVE_EXPORT16(KbdCharIn, 4)
-LX_NATIVE_MODULE_INIT_END()
-
 // end of kbdcalls.c ...
 
--- a/native/kbdcalls.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/kbdcalls.h	Tue Feb 27 03:25:21 2018 -0500
@@ -27,7 +27,7 @@
 } KBDKEYINFO, *PKBDKEYINFO;
 #pragma pack(pop)
 
-OS2EXPORT APIRET16 OS2API16 KbdCharIn(PKBDKEYINFO pkbci, USHORT fWait, HKBD hkbd);
+OS2EXPORT APIRET16 OS2API16 KbdCharIn(PKBDKEYINFO pkbci, USHORT fWait, HKBD hkbd) OS2APIINFO(4);
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/msg-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,19 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+LX_NATIVE_MODULE_INIT()
+    LX_NATIVE_EXPORT(DosPutMessage, 5)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of msg-lx.h ... */
+
--- a/native/msg.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/msg.c	Tue Feb 27 03:25:21 2018 -0500
@@ -11,15 +11,13 @@
 #include "os2native.h"
 #include "msg.h"
 
+#include "msg-lx.h"
+
 APIRET DosPutMessage(HFILE handle, ULONG msglen, PCHAR msg)
 {
     write(handle, msg, msglen);
     return 0;
 } // DosPutMessage
 
-LX_NATIVE_MODULE_INIT()
-    LX_NATIVE_EXPORT(DosPutMessage, 5)
-LX_NATIVE_MODULE_INIT_END()
-
 // end of msg.c ...
 
--- a/native/msg.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/msg.h	Tue Feb 27 03:25:21 2018 -0500
@@ -15,7 +15,7 @@
 extern "C" {
 #endif
 
-OS2EXPORT APIRET OS2API DosPutMessage(HFILE hfile, ULONG cbMsg, PCHAR pBuf);
+OS2EXPORT APIRET OS2API DosPutMessage(HFILE hfile, ULONG cbMsg, PCHAR pBuf) OS2APIINFO(5);
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/nls-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,21 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+LX_NATIVE_MODULE_INIT()
+    LX_NATIVE_EXPORT(DosQueryCtryInfo, 5),
+    LX_NATIVE_EXPORT(DosQueryDBCSEnv, 6),
+    LX_NATIVE_EXPORT(DosMapCase, 7)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of nls-lx.h ... */
+
--- a/native/nls.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/nls.c	Tue Feb 27 03:25:21 2018 -0500
@@ -9,6 +9,8 @@
 #include "os2native.h"
 #include "nls.h"
 
+#include "nls-lx.h"
+
 APIRET DosQueryDBCSEnv(ULONG buflen, PCOUNTRYCODE pcc, PCHAR buf)
 {
     // !!! FIXME: implement this for real.
@@ -74,11 +76,5 @@
     return NO_ERROR;
 } // DosQueryCtryInfo
 
-LX_NATIVE_MODULE_INIT()
-    LX_NATIVE_EXPORT(DosQueryDBCSEnv, 6),
-    LX_NATIVE_EXPORT(DosQueryCtryInfo, 5),
-    LX_NATIVE_EXPORT(DosMapCase, 7)
-LX_NATIVE_MODULE_INIT_END()
-
 // end of nls.c ...
 
--- a/native/nls.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/nls.h	Tue Feb 27 03:25:21 2018 -0500
@@ -39,9 +39,9 @@
     USHORT abReserved2[5];
 } COUNTRYINFO, *PCOUNTRYINFO;
 
-OS2EXPORT APIRET OS2API DosQueryDBCSEnv(ULONG cb, PCOUNTRYCODE pcc, PCHAR pBuf);
-OS2EXPORT APIRET OS2API DosMapCase(ULONG cb, PCOUNTRYCODE pcc, PCHAR pch);
-OS2EXPORT APIRET OS2API DosQueryCtryInfo(ULONG cb, PCOUNTRYCODE pcc, PCOUNTRYINFO pci, PULONG pcbActual);
+OS2EXPORT APIRET OS2API DosQueryDBCSEnv(ULONG cb, PCOUNTRYCODE pcc, PCHAR pBuf) OS2APIINFO(6);
+OS2EXPORT APIRET OS2API DosMapCase(ULONG cb, PCOUNTRYCODE pcc, PCHAR pch) OS2APIINFO(7);
+OS2EXPORT APIRET OS2API DosQueryCtryInfo(ULONG cb, PCOUNTRYCODE pcc, PCOUNTRYINFO pci, PULONG pcbActual) OS2APIINFO(5);
 
 #ifdef __cplusplus
 }
--- a/native/os2native.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/os2native.h	Tue Feb 27 03:25:21 2018 -0500
@@ -9,6 +9,12 @@
 #ifndef _INCL_OS2NATIVE_H_
 #define _INCL_OS2NATIVE_H_
 
+/* Unless forced off, build in support for OS/2 binaries (the LX export tables, 16-bit bridge code, etc) */
+#ifndef LX_LEGACY
+#define LX_LEGACY 1
+#endif
+
+#define _DARWIN_C_SOURCE 1
 #define _POSIX_C_SOURCE 199309
 #define _DEFAULT_SOURCE
 #define _GNU_SOURCE
@@ -28,19 +34,19 @@
 static LxLoaderState *GLoaderState = NULL;
 
 #if 1
-#define TRACE_NATIVE(...) do { if (GLoaderState->trace_native) { fprintf(stderr, "2INE TRACE [%lu]: ", (unsigned long) pthread_self()); fprintf(stderr, __VA_ARGS__); fprintf(stderr, ";\n"); } } while (0)
+#define TRACE_NATIVE(...) do { if (GLoaderState && GLoaderState->trace_native) { fprintf(stderr, "2INE TRACE [%lu]: ", (unsigned long) pthread_self()); fprintf(stderr, __VA_ARGS__); fprintf(stderr, ";\n"); } } while (0)
 #else
 #define TRACE_NATIVE(...) do {} while (0)
 #endif
 
 #if 1
-#define TRACE_EVENT(...) do { if (GLoaderState->trace_events) { fprintf(stderr, "2INE TRACE [%lu]: ", (unsigned long) pthread_self()); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); } } while (0)
+#define TRACE_EVENT(...) do { if (GLoaderState && GLoaderState->trace_events) { fprintf(stderr, "2INE TRACE [%lu]: ", (unsigned long) pthread_self()); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); } } while (0)
 #else
 #define TRACE_EVENT(...) do {} while (0)
 #endif
 
 OS2EXPORT const LxExport * lxNativeModuleInit(LxLoaderState *lx_state, uint32 *lx_num_exports);
-void OS2EXPORT lxNativeModuleDeinit(void);
+OS2EXPORT void lxNativeModuleDeinit(void);
 
 #define LX_NATIVE_MODULE_DEINIT(deinitcode) \
     void lxNativeModuleDeinit(void) { \
@@ -63,6 +69,9 @@
     return lx_native_exports; \
 }
 
+#define LX_NATIVE_CONSTRUCTOR(modname) void __attribute__((constructor)) lxNativeConstructor_##modname(void)
+#define LX_NATIVE_DESTRUCTOR(modname) void __attribute__((destructor)) lxNativeDestructor_##modname(void)
+
 #endif
 
 // end of os2native.h ...
--- a/native/os2types.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/os2types.h	Tue Feb 27 03:25:21 2018 -0500
@@ -15,6 +15,10 @@
 extern "C" {
 #endif
 
+// this doesn't do anything when compiling, but a script parses these in
+//  the headers to generate some code.
+#define OS2APIINFO(retfcount)
+
 #ifndef APIENTRY
 #define APIENTRY
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/pmgpi-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,19 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+LX_NATIVE_MODULE_INIT()
+    LX_NATIVE_EXPORT(GpiQueryTextBox, 489)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of pmgpi-lx.h ... */
+
--- a/native/pmgpi.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/pmgpi.c	Tue Feb 27 03:25:21 2018 -0500
@@ -9,6 +9,8 @@
 #include "os2native.h"
 #include "pmgpi.h"
 
+#include "pmgpi-lx.h"
+
 BOOL GpiQueryTextBox(HPS hps, LONG lCount1, PCH pchString, LONG lCount2, PPOINTL aptlPoints)
 {
     TRACE_NATIVE("GpiQueryTextBox(%u, %d, '%s', %d, %p)", (unsigned int) hps, (int) lCount1, pchString, (int) lCount2, aptlPoints);
@@ -16,9 +18,5 @@
     return 0;
 } // GpiQueryTextBox
 
-LX_NATIVE_MODULE_INIT()
-    LX_NATIVE_EXPORT(GpiQueryTextBox, 489)
-LX_NATIVE_MODULE_INIT_END()
-
 // end of pmgpi.c ...
 
--- a/native/pmgpi.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/pmgpi.h	Tue Feb 27 03:25:21 2018 -0500
@@ -16,7 +16,7 @@
 extern "C" {
 #endif
 
-OS2EXPORT BOOL OS2API GpiQueryTextBox(HPS hps, LONG lCount1, PCH pchString, LONG lCount2, PPOINTL aptlPoints);
+OS2EXPORT BOOL OS2API GpiQueryTextBox(HPS hps, LONG lCount1, PCH pchString, LONG lCount2, PPOINTL aptlPoints) OS2APIINFO(489);
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/pmwin-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,36 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+LX_NATIVE_MODULE_INIT()
+    LX_NATIVE_EXPORT(WinBeginPaint, 703),
+    LX_NATIVE_EXPORT(WinCreateMsgQueue, 716),
+    LX_NATIVE_EXPORT(WinDestroyMsgQueue, 726),
+    LX_NATIVE_EXPORT(WinDestroyWindow, 728),
+    LX_NATIVE_EXPORT(WinEndPaint, 738),
+    LX_NATIVE_EXPORT(WinFillRect, 743),
+    LX_NATIVE_EXPORT(WinGetLastError, 753),
+    LX_NATIVE_EXPORT(WinInitialize, 763),
+    LX_NATIVE_EXPORT(WinTerminate, 888),
+    LX_NATIVE_EXPORT(WinPostQueueMsg, 902),
+    LX_NATIVE_EXPORT(WinCreateStdWindow, 908),
+    LX_NATIVE_EXPORT(WinCreateWindow, 909),
+    LX_NATIVE_EXPORT(WinDefWindowProc, 911),
+    LX_NATIVE_EXPORT(WinDispatchMsg, 912),
+    LX_NATIVE_EXPORT(WinGetMsg, 915),
+    LX_NATIVE_EXPORT(WinPostMsg, 919),
+    LX_NATIVE_EXPORT(WinSendMsg, 920),
+    LX_NATIVE_EXPORT(WinRegisterClass, 926)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of pmwin-lx.h ... */
+
--- a/native/pmwin.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/pmwin.c	Tue Feb 27 03:25:21 2018 -0500
@@ -10,6 +10,8 @@
 #include "pmwin.h"
 #include "SDL.h"
 
+#include "pmwin-lx.h"
+
 // NOTE: PM reference manual says OS/2 generally ignores the HAB you pass
 //  to functions, instead getting that info from the current thread, but
 //  other IBM platforms might not do that, so programs should always pass
@@ -1639,26 +1641,5 @@
     return TRUE;
 } // WinFillRect
 
-LX_NATIVE_MODULE_INIT()
-    LX_NATIVE_EXPORT(WinBeginPaint, 703),
-    LX_NATIVE_EXPORT(WinCreateMsgQueue, 716),
-    LX_NATIVE_EXPORT(WinDestroyMsgQueue, 726),
-    LX_NATIVE_EXPORT(WinDestroyWindow, 728),
-    LX_NATIVE_EXPORT(WinEndPaint, 738),
-    LX_NATIVE_EXPORT(WinFillRect, 743),
-    LX_NATIVE_EXPORT(WinGetLastError, 753),
-    LX_NATIVE_EXPORT(WinInitialize, 763),
-    LX_NATIVE_EXPORT(WinTerminate, 888),
-    LX_NATIVE_EXPORT(WinPostQueueMsg, 902),
-    LX_NATIVE_EXPORT(WinCreateStdWindow, 908),
-    LX_NATIVE_EXPORT(WinCreateWindow, 909),
-    LX_NATIVE_EXPORT(WinDefWindowProc, 911),
-    LX_NATIVE_EXPORT(WinDispatchMsg, 912),
-    LX_NATIVE_EXPORT(WinGetMsg, 915),
-    LX_NATIVE_EXPORT(WinPostMsg, 919),
-    LX_NATIVE_EXPORT(WinSendMsg, 920),
-    LX_NATIVE_EXPORT(WinRegisterClass, 926)
-LX_NATIVE_MODULE_INIT_END()
-
 // end of pmwin.c ...
 
--- a/native/pmwin.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/pmwin.h	Tue Feb 27 03:25:21 2018 -0500
@@ -876,24 +876,24 @@
 
 // API entry points...
 
-OS2EXPORT HAB OS2API WinInitialize(ULONG flOptions);
-OS2EXPORT BOOL OS2API WinTerminate(HAB hab);
-OS2EXPORT ERRORID OS2API WinGetLastError(HAB hab);
-OS2EXPORT HMQ OS2API WinCreateMsgQueue(HAB hab, LONG cmsg);
-OS2EXPORT BOOL OS2API WinGetMsg(HAB hab, PQMSG pqmsg, HWND hwndFilter, ULONG msgFilterFirst, ULONG msgFilterLast);
-OS2EXPORT MRESULT OS2API WinDispatchMsg(HAB hab, PQMSG pqmsg);
-OS2EXPORT BOOL OS2API WinDestroyMsgQueue(HMQ hmq);
-OS2EXPORT HWND OS2API WinCreateStdWindow(HWND hwndParent, ULONG flStyle, PULONG pflCreateFlags, PSZ pszClientClass, PSZ pszTitle, ULONG styleClient, HMODULE hmod, ULONG idResources, PHWND phwndClient);
-OS2EXPORT HWND OS2API WinCreateWindow(HWND hwndParent, PSZ pszClass, PSZ pszName, ULONG flStyle, LONG x, LONG y, LONG cx, LONG cy, HWND hwndOwner, HWND hwndInsertBehind, ULONG id, PVOID pCtlData, PVOID pPresParams);
-OS2EXPORT BOOL OS2API WinDestroyWindow(HWND hwnd);
-OS2EXPORT BOOL OS2API WinRegisterClass(HAB hab, PSZ pszClassName, PFNWP pfnWndProc, ULONG flStyle, ULONG cbWindowData);
-OS2EXPORT MRESULT OS2API WinDefWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
-OS2EXPORT MRESULT OS2API WinSendMsg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
-OS2EXPORT BOOL OS2API WinPostMsg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
-OS2EXPORT BOOL OS2API WinPostQueueMsg(HMQ hmq, ULONG msg, MPARAM mp1, MPARAM mp2);
-OS2EXPORT HPS OS2API WinBeginPaint(HWND hwnd, HPS hps, PRECTL prclPaint);
-OS2EXPORT BOOL OS2API WinEndPaint(HPS hps);
-OS2EXPORT BOOL OS2API WinFillRect(HPS hps, PRECTL prcl, LONG lColor);
+OS2EXPORT HAB OS2API WinInitialize(ULONG flOptions) OS2APIINFO(763);
+OS2EXPORT BOOL OS2API WinTerminate(HAB hab) OS2APIINFO(888);
+OS2EXPORT ERRORID OS2API WinGetLastError(HAB hab) OS2APIINFO(753);
+OS2EXPORT HMQ OS2API WinCreateMsgQueue(HAB hab, LONG cmsg) OS2APIINFO(716);
+OS2EXPORT BOOL OS2API WinGetMsg(HAB hab, PQMSG pqmsg, HWND hwndFilter, ULONG msgFilterFirst, ULONG msgFilterLast) OS2APIINFO(915);
+OS2EXPORT MRESULT OS2API WinDispatchMsg(HAB hab, PQMSG pqmsg) OS2APIINFO(912);
+OS2EXPORT BOOL OS2API WinDestroyMsgQueue(HMQ hmq) OS2APIINFO(726);
+OS2EXPORT HWND OS2API WinCreateStdWindow(HWND hwndParent, ULONG flStyle, PULONG pflCreateFlags, PSZ pszClientClass, PSZ pszTitle, ULONG styleClient, HMODULE hmod, ULONG idResources, PHWND phwndClient) OS2APIINFO(908);
+OS2EXPORT HWND OS2API WinCreateWindow(HWND hwndParent, PSZ pszClass, PSZ pszName, ULONG flStyle, LONG x, LONG y, LONG cx, LONG cy, HWND hwndOwner, HWND hwndInsertBehind, ULONG id, PVOID pCtlData, PVOID pPresParams) OS2APIINFO(909);
+OS2EXPORT BOOL OS2API WinDestroyWindow(HWND hwnd) OS2APIINFO(728);
+OS2EXPORT BOOL OS2API WinRegisterClass(HAB hab, PSZ pszClassName, PFNWP pfnWndProc, ULONG flStyle, ULONG cbWindowData) OS2APIINFO(926);
+OS2EXPORT MRESULT OS2API WinDefWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) OS2APIINFO(911);
+OS2EXPORT MRESULT OS2API WinSendMsg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) OS2APIINFO(920);
+OS2EXPORT BOOL OS2API WinPostMsg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) OS2APIINFO(919);
+OS2EXPORT BOOL OS2API WinPostQueueMsg(HMQ hmq, ULONG msg, MPARAM mp1, MPARAM mp2) OS2APIINFO(902);
+OS2EXPORT HPS OS2API WinBeginPaint(HWND hwnd, HPS hps, PRECTL prclPaint) OS2APIINFO(703);
+OS2EXPORT BOOL OS2API WinEndPaint(HPS hps) OS2APIINFO(738);
+OS2EXPORT BOOL OS2API WinFillRect(HPS hps, PRECTL prcl, LONG lColor) OS2APIINFO(743);
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/quecalls-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,26 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+LX_NATIVE_MODULE_INIT()
+    LX_NATIVE_EXPORT(DosReadQueue, 9),
+    LX_NATIVE_EXPORT(DosPurgeQueue, 10),
+    LX_NATIVE_EXPORT(DosCloseQueue, 11),
+    LX_NATIVE_EXPORT(DosQueryQueue, 12),
+    LX_NATIVE_EXPORT(DosPeekQueue, 13),
+    LX_NATIVE_EXPORT(DosWriteQueue, 14),
+    LX_NATIVE_EXPORT(DosOpenQueue, 15),
+    LX_NATIVE_EXPORT(DosCreateQueue, 16)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of quecalls-lx.h ... */
+
--- a/native/quecalls.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/quecalls.c	Tue Feb 27 03:25:21 2018 -0500
@@ -9,6 +9,8 @@
 #include "os2native.h"
 #include "quecalls.h"
 
+#include "quecalls-lx.h"
+
 
 APIRET DosCreateQueue(PHQUEUE phq, ULONG priority, PSZ pszName)
 {
@@ -66,17 +68,5 @@
     return ERROR_QUE_INVALID_HANDLE;
 } // DosWriteQueue
 
-
-LX_NATIVE_MODULE_INIT()
-    LX_NATIVE_EXPORT(DosReadQueue, 9),
-    LX_NATIVE_EXPORT(DosPurgeQueue, 10),
-    LX_NATIVE_EXPORT(DosCloseQueue, 11),
-    LX_NATIVE_EXPORT(DosQueryQueue, 12),
-    LX_NATIVE_EXPORT(DosPeekQueue, 13),
-    LX_NATIVE_EXPORT(DosWriteQueue, 14),
-    LX_NATIVE_EXPORT(DosOpenQueue, 15),
-    LX_NATIVE_EXPORT(DosCreateQueue, 16)
-LX_NATIVE_MODULE_INIT_END()
-
 // end of quecalls.c ...
 
--- a/native/quecalls.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/quecalls.h	Tue Feb 27 03:25:21 2018 -0500
@@ -30,14 +30,14 @@
     QUE_CONVERT_ADDRESS = 4
 };
 
-OS2EXPORT APIRET OS2API DosCreateQueue(PHQUEUE phq, ULONG priority, PSZ pszName);
-OS2EXPORT APIRET OS2API DosCloseQueue(HQUEUE hq);
-OS2EXPORT APIRET OS2API DosOpenQueue(PPID ppid, PHQUEUE phq, PSZ pszName);
-OS2EXPORT APIRET OS2API DosPeekQueue(HQUEUE hq, PREQUESTDATA pRequest, PULONG pcbData, PPVOID ppbuf, PULONG element, BOOL32 nowait, PBYTE ppriority, HEV hsem);
-OS2EXPORT APIRET OS2API DosPurgeQueue(HQUEUE hq);
-OS2EXPORT APIRET OS2API DosQueryQueue(HQUEUE hq, PULONG pcbEntries);
-OS2EXPORT APIRET OS2API DosReadQueue(HQUEUE hq, PREQUESTDATA pRequest, PULONG pcbData, PPVOID ppbuf, ULONG element, BOOL32 wait, PBYTE ppriority, HEV hsem);
-OS2EXPORT APIRET OS2API DosWriteQueue(HQUEUE hq, ULONG request, ULONG cbData, PVOID pbData, ULONG priority);
+OS2EXPORT APIRET OS2API DosCreateQueue(PHQUEUE phq, ULONG priority, PSZ pszName) OS2APIINFO(16);
+OS2EXPORT APIRET OS2API DosCloseQueue(HQUEUE hq) OS2APIINFO(11);
+OS2EXPORT APIRET OS2API DosOpenQueue(PPID ppid, PHQUEUE phq, PSZ pszName) OS2APIINFO(15);
+OS2EXPORT APIRET OS2API DosPeekQueue(HQUEUE hq, PREQUESTDATA pRequest, PULONG pcbData, PPVOID ppbuf, PULONG element, BOOL32 nowait, PBYTE ppriority, HEV hsem) OS2APIINFO(13);
+OS2EXPORT APIRET OS2API DosPurgeQueue(HQUEUE hq) OS2APIINFO(10);
+OS2EXPORT APIRET OS2API DosQueryQueue(HQUEUE hq, PULONG pcbEntries) OS2APIINFO(12);
+OS2EXPORT APIRET OS2API DosReadQueue(HQUEUE hq, PREQUESTDATA pRequest, PULONG pcbData, PPVOID ppbuf, ULONG element, BOOL32 wait, PBYTE ppriority, HEV hsem) OS2APIINFO(9);
+OS2EXPORT APIRET OS2API DosWriteQueue(HQUEUE hq, ULONG request, ULONG cbData, PVOID pbData, ULONG priority) OS2APIINFO(14);
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/sesmgr-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,19 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+LX_NATIVE_MODULE_INIT()
+    LX_NATIVE_EXPORT(DosStartSession, 37)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of sesmgr-lx.h ... */
+
--- a/native/sesmgr.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/sesmgr.c	Tue Feb 27 03:25:21 2018 -0500
@@ -9,9 +9,7 @@
 #include "os2native.h"
 #include "sesmgr.h"
 
-LX_NATIVE_MODULE_INIT()
-    LX_NATIVE_EXPORT(DosStartSession, 37)
-LX_NATIVE_MODULE_INIT_END()
+#include "sesmgr-lx.h"
 
 APIRET DosStartSession(PSTARTDATA psd, PULONG pidSession, PPID ppid)
 {
--- a/native/sesmgr.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/sesmgr.h	Tue Feb 27 03:25:21 2018 -0500
@@ -40,7 +40,7 @@
     ULONG ObjectBuffLen;
 } STARTDATA, *PSTARTDATA;
 
-OS2EXPORT APIRET OS2API DosStartSession(PSTARTDATA psd, PULONG pidSession, PPID ppid);
+OS2EXPORT APIRET OS2API DosStartSession(PSTARTDATA psd, PULONG pidSession, PPID ppid) OS2APIINFO(37);
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/tcpip32-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,44 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+LX_NATIVE_MODULE_INIT()
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_accept, "accept", 1),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_bind, "bind", 2),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_connect, "connect", 3),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getsockname, "getsockname", 6),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_recv, "recv", 10),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_os2_select, "os2_select", 12),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_send, "send", 13),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_setsockopt, "setsockopt", 15),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_socket, "socket", 16),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_soclose, "soclose", 17),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_sock_errno, "sock_errno", 20),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_shutdown, "shutdown", 25),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_sock_init, "sock_init", 26),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_select, "select", 32),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_gettimeofday, "gettimeofday", 102),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_inet_addr, "inet_addr", 105),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_inet_ntoa, "inet_ntoa", 110),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_gethostbyname, "gethostbyname", 111),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getservbyname, "getservbyname", 124),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Raccept, "Raccept", 156),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rbind, "Rbind", 157),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rconnect, "Rconnect", 158),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rgetsockname, "Rgetsockname", 159),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rlisten, "Rlisten", 160),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rgethostbyname, "Rgethostbyname", 161),
+    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_htons, "htons", 205)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of tcpip32-lx.h ... */
+
--- a/native/tcpip32.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/tcpip32.c	Tue Feb 27 03:25:21 2018 -0500
@@ -20,6 +20,8 @@
 #include <errno.h>
 #include <poll.h>
 
+#include "tcpip32-lx.h"
+
 int OS2_sock_init(void)
 {
     TRACE_NATIVE("sock_init()");
@@ -404,36 +406,5 @@
     return OS2_gethostbyname(name);
 } // OS2_Rgethostbyname
 
-
-LX_NATIVE_MODULE_INIT()
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_accept, "accept", 1),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_bind, "bind", 2),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_connect, "connect", 3),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getsockname, "getsockname", 6),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_listen, "listen", 9),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_recv, "recv", 10),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_os2_select, "os2_select", 12),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_send, "send", 13),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_setsockopt, "setsockopt", 15),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_socket, "socket", 16),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_soclose, "soclose", 17),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_sock_errno, "sock_errno", 20),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_shutdown, "shutdown", 25),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_sock_init, "sock_init", 26),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_select, "select", 32),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_gettimeofday, "gettimeofday", 102),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_inet_addr, "inet_addr", 105),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_inet_ntoa, "inet_ntoa", 110),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_gethostbyname, "gethostbyname", 111),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_getservbyname, "getservbyname", 124),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Raccept, "Raccept", 156),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rbind, "Rbind", 157),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rconnect, "Rconnect", 158),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rgetsockname, "Rgetsockname", 159),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rlisten, "Rlisten", 160),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_Rgethostbyname, "Rgethostbyname", 161),
-    LX_NATIVE_EXPORT_DIFFERENT_NAME(OS2_htons, "htons", 205)
-LX_NATIVE_MODULE_INIT_END()
-
 // end of tcpip32.c ...
 
--- a/native/tcpip32.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/tcpip32.h	Tue Feb 27 03:25:21 2018 -0500
@@ -125,32 +125,32 @@
 } OS2_timezone;
 #pragma pack(pop)
 
-OS2EXPORT int OS2API OS2_sock_init(void);
-OS2EXPORT int OS2API OS2_recv(int sock, void *buf, size_t len, int os2flags);
-OS2EXPORT int OS2API OS2_connect(int sock, const OS2_sockaddr *os2addr, int addrlen);
-OS2EXPORT int OS2API OS2_shutdown(int sock, int kind);
-OS2EXPORT int OS2API OS2_socket(int family, int os2socktype, int protocol);
-OS2EXPORT ssize_t OS2API OS2_send(int sock, const void *buf, size_t len, int os2flags);
-OS2EXPORT int OS2API OS2_soclose(int sock);
-OS2EXPORT int OS2API OS2_sock_errno(void);
-OS2EXPORT unsigned long OS2API OS2_inet_addr(const char *name);
-OS2EXPORT OS2_hostent * OS2API OS2_gethostbyname(const char *name);
-OS2EXPORT unsigned short OS2API OS2_htons(unsigned short val);
-OS2EXPORT char * OS2API OS2_inet_ntoa(OS2_in_addr os2inaddr);
-OS2EXPORT OS2_servent * OS2API OS2_getservbyname(const char *name, const char *proto);
-OS2EXPORT int OS2API OS2_select(int sock, OS2_fd_set *readfds, OS2_fd_set *writefds, OS2_fd_set *errorfds, OS2_timeval *timeout);
-OS2EXPORT int OS2API OS2_os2_select(int *socks, int noreads, int nowrites, int noexcept, long timeout);
-OS2EXPORT int OS2API OS2_getsockname(int sock, OS2_sockaddr *os2name, int *namelen);
-OS2EXPORT int OS2API OS2_setsockopt(int sock, int os2level, int os2name, const void *value, int len);
-OS2EXPORT int OS2API OS2_bind(int sock, const OS2_sockaddr *os2name, int os2namelen);
-OS2EXPORT int OS2API OS2_accept(int sock, OS2_sockaddr *os2name, int *os2namelen);
-OS2EXPORT int OS2API OS2_Rgetsockname(int sock, OS2_sockaddr *os2name, int *namelen);
-OS2EXPORT int OS2API OS2_Rbind(int sock, OS2_sockaddr *os2name, int os2namelen, OS2_sockaddr *os2remote);
-OS2EXPORT int OS2API OS2_Raccept(int sock, OS2_sockaddr *os2name, int *os2namelen);
-OS2EXPORT int OS2API OS2_Rconnect(int sock, const OS2_sockaddr *os2name, int os2namelen);
-OS2EXPORT int OS2API OS2_Rlisten(int sock, int backlog);
-OS2EXPORT OS2_hostent * OS2API OS2_Rgethostbyname(const char *name);
-OS2EXPORT int OS2API OS2_gettimeofday(OS2_timeval *os2tv, OS2_timezone *os2tz);
+OS2EXPORT int OS2API OS2_sock_init(void) OS2APIINFO(26);
+OS2EXPORT int OS2API OS2_recv(int sock, void *buf, size_t len, int os2flags) OS2APIINFO(10);
+OS2EXPORT int OS2API OS2_connect(int sock, const OS2_sockaddr *os2addr, int addrlen) OS2APIINFO(3);
+OS2EXPORT int OS2API OS2_shutdown(int sock, int kind) OS2APIINFO(25);
+OS2EXPORT int OS2API OS2_socket(int family, int os2socktype, int protocol) OS2APIINFO(16);
+OS2EXPORT ssize_t OS2API OS2_send(int sock, const void *buf, size_t len, int os2flags) OS2APIINFO(13);
+OS2EXPORT int OS2API OS2_soclose(int sock) OS2APIINFO(17);
+OS2EXPORT int OS2API OS2_sock_errno(void) OS2APIINFO(20);
+OS2EXPORT unsigned long OS2API OS2_inet_addr(const char *name) OS2APIINFO(105);
+OS2EXPORT OS2_hostent * OS2API OS2_gethostbyname(const char *name) OS2APIINFO(111);
+OS2EXPORT unsigned short OS2API OS2_htons(unsigned short val) OS2APIINFO(205);
+OS2EXPORT char * OS2API OS2_inet_ntoa(OS2_in_addr os2inaddr) OS2APIINFO(110);
+OS2EXPORT OS2_servent * OS2API OS2_getservbyname(const char *name, const char *proto) OS2APIINFO(124);
+OS2EXPORT int OS2API OS2_select(int sock, OS2_fd_set *readfds, OS2_fd_set *writefds, OS2_fd_set *errorfds, OS2_timeval *timeout) OS2APIINFO(32);
+OS2EXPORT int OS2API OS2_os2_select(int *socks, int noreads, int nowrites, int noexcept, long timeout) OS2APIINFO(12);
+OS2EXPORT int OS2API OS2_getsockname(int sock, OS2_sockaddr *os2name, int *namelen) OS2APIINFO(6);
+OS2EXPORT int OS2API OS2_setsockopt(int sock, int os2level, int os2name, const void *value, int len) OS2APIINFO(15);
+OS2EXPORT int OS2API OS2_bind(int sock, const OS2_sockaddr *os2name, int os2namelen) OS2APIINFO(2);
+OS2EXPORT int OS2API OS2_accept(int sock, OS2_sockaddr *os2name, int *os2namelen) OS2APIINFO(1);
+OS2EXPORT int OS2API OS2_Rgetsockname(int sock, OS2_sockaddr *os2name, int *namelen) OS2APIINFO(159);
+OS2EXPORT int OS2API OS2_Rbind(int sock, OS2_sockaddr *os2name, int os2namelen, OS2_sockaddr *os2remote) OS2APIINFO(157);
+OS2EXPORT int OS2API OS2_Raccept(int sock, OS2_sockaddr *os2name, int *os2namelen) OS2APIINFO(156);
+OS2EXPORT int OS2API OS2_Rconnect(int sock, const OS2_sockaddr *os2name, int os2namelen) OS2APIINFO(158);
+OS2EXPORT int OS2API OS2_Rlisten(int sock, int backlog) OS2APIINFO(160);
+OS2EXPORT OS2_hostent * OS2API OS2_Rgethostbyname(const char *name) OS2APIINFO(161);
+OS2EXPORT int OS2API OS2_gettimeofday(OS2_timeval *os2tv, OS2_timezone *os2tz) OS2APIINFO(102);
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/native/viocalls-lx.h	Tue Feb 27 03:25:21 2018 -0500
@@ -0,0 +1,151 @@
+/**
+ * 2ine; an OS/2 emulator for Linux.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+/* THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. see lxapigen.pl */
+
+/* This is glue code for OS/2 binaries. Native binaries don't need this. */
+#if LX_LEGACY
+
+static APIRET16 bridge16to32_VioScrollUp(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, pCell);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cbLines);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRightCol);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usBotRow);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usLeftCol);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usTopRow);
+    return VioScrollUp(usTopRow, usLeftCol, usBotRow, usRightCol, cbLines, pCell, hvio);
+}
+
+static APIRET16 bridge16to32_VioGetCurPos(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pusColumn);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pusRow);
+    return VioGetCurPos(pusRow, pusColumn, hvio);
+}
+
+static APIRET16 bridge16to32_VioWrtCellStr(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cb);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCH, pchCellStr);
+    return VioWrtCellStr(pchCellStr, cb, usRow, usColumn, hvio);
+}
+
+static APIRET16 bridge16to32_VioSetCurPos(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
+    return VioSetCurPos(usRow, usColumn, hvio);
+}
+
+static APIRET16 bridge16to32_VioGetMode(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVIOMODEINFO, pvioModeInfo);
+    return VioGetMode(pvioModeInfo, hvio);
+}
+
+static APIRET16 bridge16to32_VioReadCellStr(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcb);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCH, pchCellStr);
+    return VioReadCellStr(pchCellStr, pcb, usRow, usColumn, hvio);
+}
+
+static APIRET16 bridge16to32_VioGetCurType(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVIOCURSORINFO, pvioCursorInfo);
+    return VioGetCurType(pvioCursorInfo, hvio);
+}
+
+static APIRET16 bridge16to32_VioGetBuf(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcbLVB);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PULONG, pLVB);
+    return VioGetBuf(pLVB, pcbLVB, hvio);
+}
+
+static APIRET16 bridge16to32_VioSetCurType(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVIOCURSORINFO, pvioCursorInfo);
+    return VioSetCurType(pvioCursorInfo, hvio);
+}
+
+static APIRET16 bridge16to32_VioWrtCharStrAtt(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, pAttr);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cb);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCH, pch);
+    return VioWrtCharStrAtt(pch, cb, usRow, usColumn, pAttr, hvio);
+}
+
+static APIRET16 bridge16to32_VioWrtNCell(uint8 *args) {
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cb);
+    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, pCell);
+    return VioWrtNCell(pCell, cb, usRow, usColumn, hvio);
+}
+
+LX_NATIVE_MODULE_16BIT_SUPPORT()
+    LX_NATIVE_MODULE_16BIT_API(VioScrollUp)
+    LX_NATIVE_MODULE_16BIT_API(VioGetCurPos)
+    LX_NATIVE_MODULE_16BIT_API(VioWrtCellStr)
+    LX_NATIVE_MODULE_16BIT_API(VioSetCurPos)
+    LX_NATIVE_MODULE_16BIT_API(VioGetMode)
+    LX_NATIVE_MODULE_16BIT_API(VioReadCellStr)
+    LX_NATIVE_MODULE_16BIT_API(VioGetCurType)
+    LX_NATIVE_MODULE_16BIT_API(VioGetBuf)
+    LX_NATIVE_MODULE_16BIT_API(VioSetCurType)
+    LX_NATIVE_MODULE_16BIT_API(VioWrtCharStrAtt)
+    LX_NATIVE_MODULE_16BIT_API(VioWrtNCell)
+LX_NATIVE_MODULE_16BIT_SUPPORT_END()
+
+LX_NATIVE_MODULE_DEINIT({
+    LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT();
+})
+
+static int init16_viocalls(void) {
+    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioScrollUp, 16)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioGetCurPos, 10)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioWrtCellStr, 12)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioSetCurPos, 6)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioGetMode, 6)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioReadCellStr, 14)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioGetCurType, 6)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioGetBuf, 10)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioSetCurType, 6)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioWrtCharStrAtt, 16)
+        LX_NATIVE_INIT_16BIT_BRIDGE(VioWrtNCell, 12)
+    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END()
+    return 1;
+}
+
+LX_NATIVE_MODULE_INIT({ if (!init16_viocalls()) return 0; })
+    LX_NATIVE_EXPORT16(VioScrollUp, 7),
+    LX_NATIVE_EXPORT16(VioGetCurPos, 9),
+    LX_NATIVE_EXPORT16(VioWrtCellStr, 10),
+    LX_NATIVE_EXPORT16(VioSetCurPos, 15),
+    LX_NATIVE_EXPORT16(VioGetMode, 21),
+    LX_NATIVE_EXPORT16(VioReadCellStr, 24),
+    LX_NATIVE_EXPORT16(VioGetCurType, 27),
+    LX_NATIVE_EXPORT16(VioGetBuf, 31),
+    LX_NATIVE_EXPORT16(VioSetCurType, 32),
+    LX_NATIVE_EXPORT16(VioWrtCharStrAtt, 48),
+    LX_NATIVE_EXPORT16(VioWrtNCell, 52)
+LX_NATIVE_MODULE_INIT_END()
+
+#endif /* LX_LEGACY */
+
+/* end of viocalls-lx.h ... */
+
--- a/native/viocalls.c	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/viocalls.c	Tue Feb 27 03:25:21 2018 -0500
@@ -31,6 +31,8 @@
 
 #include <locale.h>
 
+#include "viocalls-lx.h"
+
 enum
 {
     VIOATTR_BACK_BLACK = 0x00,
@@ -230,14 +232,6 @@
     return NO_ERROR;
 } // VioGetMode
 
-static APIRET16 bridge16to32_VioGetMode(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVIOMODEINFO, pvmi);
-    return VioGetMode(pvmi, hvio);
-} // bridge16to32_VioGetMode
-
-
 APIRET16 VioGetCurPos(PUSHORT pusRow, PUSHORT pusColumn, HVIO hvio)
 {
     TRACE_NATIVE("VioGetCurPos(%p, %p, %u)", pusRow, pusColumn, (uint) hvio);
@@ -256,14 +250,6 @@
     return NO_ERROR;
 } // VioGetCurPos
 
-static APIRET16 bridge16to32_VioGetCurPos(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pusRow);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pusColumn);
-    return VioGetCurPos(pusRow, pusColumn, hvio);
-} // bridge16to32_VioGetCurPos
-
 APIRET16 VioGetBuf(PULONG pLVB, PUSHORT pcbLVB, HVIO hvio)
 {
     TRACE_NATIVE("VioGetBuf(%p, %p, %u)", pLVB, pcbLVB, (uint) hvio);
@@ -279,16 +265,6 @@
     return NO_ERROR;
 } // VioGetBuf
 
-static APIRET16 bridge16to32_VioGetBuf(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcbLVB);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PULONG, pLVB);
-    const APIRET16 retval = VioGetBuf(pLVB, pcbLVB, hvio);
-    *pLVB = GLoaderState->convert32to1616((void *) *pLVB);
-    return retval;
-} // bridge16to32_VioGetBuf
-
 APIRET16 VioGetCurType(PVIOCURSORINFO pvioCursorInfo, HVIO hvio)
 {
     TRACE_NATIVE("VioGetCurType(%p, %u)", pvioCursorInfo, (uint) hvio);
@@ -304,13 +280,6 @@
     return NO_ERROR;
 } // VioGetCurType
 
-static APIRET16 bridge16to32_VioGetCurType(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVIOCURSORINFO, pvioCursorInfo);
-    return VioGetCurType(pvioCursorInfo, hvio);
-} // bridge16to32_VioGetCurType
-
 APIRET16 VioScrollUp(USHORT usTopRow, USHORT usLeftCol, USHORT usBotRow, USHORT usRightCol, USHORT cbLines, PBYTE pCell, HVIO hvio)
 {
     TRACE_NATIVE("VioScrollUp(%u, %u, %u, %u, %u, %p, %u)", (uint) usTopRow, (uint) usLeftCol, (uint) usBotRow, (uint) usRightCol, (uint) cbLines, pCell, (uint) hvio);
@@ -378,18 +347,6 @@
     return NO_ERROR;
 } // VioScrollUp
 
-static APIRET16 bridge16to32_VioScrollUp(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, pCell);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cbLines);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRightCol);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usBotRow);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usLeftCol);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usTopRow);
-    return VioScrollUp(usTopRow, usLeftCol, usBotRow, usRightCol, cbLines, pCell, hvio);
-} // bridge16to32_VioGetCurType
-
 APIRET16 VioSetCurPos(USHORT usRow, USHORT usColumn, HVIO hvio)
 {
     TRACE_NATIVE("VioSetCurPos(%u, %u, %u)", (uint) usRow, (uint) usColumn, (uint) hvio);
@@ -411,14 +368,6 @@
     return NO_ERROR;
 } // VioSetCurPos
 
-static APIRET16 bridge16to32_VioSetCurPos(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
-    return VioSetCurPos(usRow, usColumn, hvio);
-} // bridge16to32_VioSetCurPos
-
 APIRET16 VioSetCurType(PVIOCURSORINFO pvioCursorInfo, HVIO hvio)
 {
     TRACE_NATIVE("VioSetCurType(%p, %u)", pvioCursorInfo, (uint) hvio);
@@ -426,13 +375,6 @@
     return NO_ERROR;
 } // VioSetCurType
 
-static APIRET16 bridge16to32_VioSetCurType(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVIOCURSORINFO, pvioCursorInfo);
-    return VioSetCurType(pvioCursorInfo, hvio);
-} // bridge16to32_VioSetCurType
-
 APIRET16 VioReadCellStr(PCH pchCellStr, PUSHORT pcb, USHORT usRow, USHORT usColumn, HVIO hvio)
 {
     TRACE_NATIVE("VioReadCellStr(%p, %p, %u, %u, %u)", pchCellStr, pcb, (uint) usRow, (uint) usColumn, (uint) hvio);
@@ -455,16 +397,6 @@
     return NO_ERROR;
 } // VioReadCellStr
 
-static APIRET16 bridge16to32_VioReadCellStr(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcb);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCH, pchCellStr);
-    return VioReadCellStr(pchCellStr, pcb, usRow, usColumn, hvio);
-} // bridge16to32_VioReadCellStr
-
 APIRET16 VioWrtCellStr(PCH pchCellStr, USHORT cb, USHORT usRow, USHORT usColumn, HVIO hvio)
 {
     TRACE_NATIVE("VioWrtCellStr(%p, %u, %u, %u, %u)", pchCellStr, (uint) cb, (uint) usRow, (uint) usColumn, (uint) hvio);
@@ -491,16 +423,6 @@
     return NO_ERROR;
 } // VioWrtCellStr
 
-static APIRET16 bridge16to32_VioWrtCellStr(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cb);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCH, pchCellStr);
-    return VioWrtCellStr(pchCellStr, cb, usRow, usColumn, hvio);
-} // bridge16to32_VioWrtCellStr
-
 APIRET16 VioWrtCharStrAtt(PCH pch, USHORT cb, USHORT usRow, USHORT usColumn, PBYTE pAttr, HVIO hvio)
 {
     TRACE_NATIVE("VioWrtCharStrAtt(%p, %u, %u, %u, %p, %u)", pch, (uint) cb, (uint) usRow, (uint) usColumn, pAttr, (uint) hvio);
@@ -531,18 +453,6 @@
     return NO_ERROR;
 } // VioWrtCharStrAtt
 
-static APIRET16 bridge16to32_VioWrtCharStrAtt(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, pAttr);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cb);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCH, pch);
-    return VioWrtCharStrAtt(pch, cb, usRow, usColumn, pAttr, hvio);
-} // bridge16to32_VioWrtCharStrAtt
-
-
 APIRET16 VioWrtNCell(PBYTE pCell, USHORT cb, USHORT usRow, USHORT usColumn, HVIO hvio)
 {
     TRACE_NATIVE("VioWrtNCell(%p, %u, %u, %u, %u)", pCell, (uint) cb, (uint) usRow, (uint) usColumn, (uint) hvio);
@@ -570,67 +480,10 @@
     return NO_ERROR;
 } // VioWrtNCell
 
-static APIRET16 bridge16to32_VioWrtNCell(uint8 *args)
-{
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HVIO, hvio);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usColumn);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, usRow);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cb);
-    LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, pCell);
-    return VioWrtNCell(pCell, cb, usRow, usColumn, hvio);
-} // bridge16to32_VioWrtNCell
-
-
-LX_NATIVE_MODULE_16BIT_SUPPORT()
-    LX_NATIVE_MODULE_16BIT_API(VioScrollUp)
-    LX_NATIVE_MODULE_16BIT_API(VioGetCurPos)
-    LX_NATIVE_MODULE_16BIT_API(VioWrtCellStr)
-    LX_NATIVE_MODULE_16BIT_API(VioSetCurPos)
-    LX_NATIVE_MODULE_16BIT_API(VioGetMode)
-    LX_NATIVE_MODULE_16BIT_API(VioReadCellStr)
-    LX_NATIVE_MODULE_16BIT_API(VioGetCurType)
-    LX_NATIVE_MODULE_16BIT_API(VioGetBuf)
-    LX_NATIVE_MODULE_16BIT_API(VioSetCurType)
-    LX_NATIVE_MODULE_16BIT_API(VioWrtCharStrAtt)
-    LX_NATIVE_MODULE_16BIT_API(VioWrtNCell)
-LX_NATIVE_MODULE_16BIT_SUPPORT_END()
-
-static int initViocalls(void)
+LX_NATIVE_DESTRUCTOR(viocalls)
 {
-    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioScrollUp, 26)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioGetCurPos, 6)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioWrtCellStr, 12)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioSetCurPos, 6)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioGetMode, 6)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioReadCellStr, 12)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioGetCurType, 6)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioGetBuf, 10)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioSetCurType, 6)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioWrtCharStrAtt, 16)
-        LX_NATIVE_INIT_16BIT_BRIDGE(VioWrtNCell, 12)
-    LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END()
-    return 1;
-} // initViocalls
-
-LX_NATIVE_MODULE_INIT({ if (!initViocalls()) return NULL; })
-    LX_NATIVE_EXPORT16(VioScrollUp, 7),
-    LX_NATIVE_EXPORT16(VioGetCurPos, 9),
-    LX_NATIVE_EXPORT16(VioWrtCellStr, 10),
-    LX_NATIVE_EXPORT16(VioSetCurPos, 15),
-    LX_NATIVE_EXPORT16(VioGetMode, 21),
-    LX_NATIVE_EXPORT16(VioReadCellStr, 24),
-    LX_NATIVE_EXPORT16(VioGetCurType, 27),
-    LX_NATIVE_EXPORT16(VioGetBuf, 31),
-    LX_NATIVE_EXPORT16(VioSetCurType, 32),
-    LX_NATIVE_EXPORT16(VioWrtCharStrAtt, 48),
-    LX_NATIVE_EXPORT16(VioWrtNCell, 52)
-LX_NATIVE_MODULE_INIT_END()
-
-LX_NATIVE_MODULE_DEINIT({
     deinitNcurses();
-    LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT();
-})
+}
 
 // end of viocalls.c ...
 
--- a/native/viocalls.h	Mon Feb 26 12:54:16 2018 -0500
+++ b/native/viocalls.h	Tue Feb 27 03:25:21 2018 -0500
@@ -50,17 +50,17 @@
     USHORT attr;
 } VIOCURSORINFO, *PVIOCURSORINFO;
 
-OS2EXPORT APIRET16 OS2API16 VioGetMode(PVIOMODEINFO pvioModeInfo, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioGetCurPos(PUSHORT pusRow, PUSHORT pusColumn, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioGetBuf(PULONG pLVB, PUSHORT pcbLVB, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioGetCurType(PVIOCURSORINFO pvioCursorInfo, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioScrollUp(USHORT usTopRow, USHORT usLeftCol, USHORT usBotRow, USHORT usRightCol, USHORT cbLines, PBYTE pCell, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioSetCurPos(USHORT usRow, USHORT usColumn, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioSetCurType(PVIOCURSORINFO pvioCursorInfo, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioReadCellStr(PCH pchCellStr, PUSHORT pcb, USHORT usRow, USHORT usColumn, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioWrtCellStr(PCH pchCellStr, USHORT cb, USHORT usRow, USHORT usColumn, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioWrtCharStrAtt(PCH pch, USHORT cb, USHORT usRow, USHORT usColumn, PBYTE pAttr, HVIO hvio);
-OS2EXPORT APIRET16 OS2API16 VioWrtNCell(PBYTE pCell, USHORT cb, USHORT usRow, USHORT usColumn, HVIO hvio);
+OS2EXPORT APIRET16 OS2API16 VioGetMode(PVIOMODEINFO pvioModeInfo, HVIO hvio) OS2APIINFO(21);
+OS2EXPORT APIRET16 OS2API16 VioGetCurPos(PUSHORT pusRow, PUSHORT pusColumn, HVIO hvio) OS2APIINFO(9);
+OS2EXPORT APIRET16 OS2API16 VioGetBuf(PULONG pLVB, PUSHORT pcbLVB, HVIO hvio) OS2APIINFO(31);
+OS2EXPORT APIRET16 OS2API16 VioGetCurType(PVIOCURSORINFO pvioCursorInfo, HVIO hvio) OS2APIINFO(27);
+OS2EXPORT APIRET16 OS2API16 VioScrollUp(USHORT usTopRow, USHORT usLeftCol, USHORT usBotRow, USHORT usRightCol, USHORT cbLines, PBYTE pCell, HVIO hvio) OS2APIINFO(7);
+OS2EXPORT APIRET16 OS2API16 VioSetCurPos(USHORT usRow, USHORT usColumn, HVIO hvio) OS2APIINFO(15);
+OS2EXPORT APIRET16 OS2API16 VioSetCurType(PVIOCURSORINFO pvioCursorInfo, HVIO hvio) OS2APIINFO(32);
+OS2EXPORT APIRET16 OS2API16 VioReadCellStr(PCH pchCellStr, PUSHORT pcb, USHORT usRow, USHORT usColumn, HVIO hvio) OS2APIINFO(24);
+OS2EXPORT APIRET16 OS2API16 VioWrtCellStr(PCH pchCellStr, USHORT cb, USHORT usRow, USHORT usColumn, HVIO hvio) OS2APIINFO(10);
+OS2EXPORT APIRET16 OS2API16 VioWrtCharStrAtt(PCH pch, USHORT cb, USHORT usRow, USHORT usColumn, PBYTE pAttr, HVIO hvio) OS2APIINFO(48);
+OS2EXPORT APIRET16 OS2API16 VioWrtNCell(PBYTE pCell, USHORT cb, USHORT usRow, USHORT usColumn, HVIO hvio) OS2APIINFO(52);
 
 #ifdef __cplusplus
 }