Skip to content
Permalink
Browse files

LX loader fixes and enhancements

- LX executable pages packing algorithms implementations. All three algorithms
are supported from now, including the new algorithm introduced in OS/4 kernel.
For that purpose, some code is ported from QSINIT, kLdr and lxlite.
- Memory align option is introduced in allocmem() function in LX loader, so
now executable sections can be e.g., a 0x10000-byte aligned.
- More options, fixup types and entry options are supported now. Now LDT is
initialized with 8192 16-bit descriptor. Small patch is applied to L4/Fiasco
kernel, so that, kernel should use 8192 LDT descriptors, not 512 ones, which
fit in one memory page. So, now some bits of tiling is implemented. Though, 16-
bit OS/2 code support is not yet finished. 16:16 and 16:32 fixups and entries
are now supported.
- Region align support in RegAreaAttach.
- Extra fixups support in os2exec. Now fixups other than 32-bit self-relative
ones, are supported.
  • Loading branch information
valerius2k committed Apr 25, 2020
1 parent 73b9c86 commit bc8d22291c9912c8f92f1fd2a74e4708252fe41c
Showing with 946 additions and 318 deletions.
  1. BIN filesys/os2/cmd.exe
  2. +2 −0 filesys/os2/config.sys
  3. BIN filesys/os2/doscalls.dll
  4. BIN filesys/os2/vp.exe
  5. BIN filesys/os2/zip.exe
  6. +7 −6 include/os2/exe386.h
  7. +1 −1 include/os3/allocmem.h
  8. +4 −3 include/os3/ixfmgr.h
  9. +4 −0 include/os3/segment.h
  10. 0 platform/l4env/mounted.flg
  11. +22 −22 platform/l4env/src/lib/compat/fileprov.c
  12. +36 −1 platform/l4env/src/lib/compat/rm.c
  13. +7 −0 platform/l4env/src/lib/compat/segment.c
  14. +1 −1 platform/l4env/src/server/ixf/lx/Makefile
  15. +4 −1 platform/l4env/src/server/os2app/server/src/main.c
  16. +3 −0 platform/l4env/src/server/os2exec/lib/src/exec.c
  17. +8 −1 platform/l4env/src/server/os2exec/server/src/main.c
  18. +5 −1 platform/l4env/src/server/os2exec/server/src/rpc.c
  19. +8 −1 platform/l4env/src/server/os2fs/server/src/main.c
  20. +2 −2 platform/l4env/src/server/os2srv/server/src/exec.c
  21. +3 −2 platform/l4env/src/server/os2srv/server/src/main.c
  22. +2 −2 shared/app/os2app/initdone.c
  23. +30 −5 shared/app/os2app/kal/arch/x86_32/tramp.c
  24. +63 −8 shared/app/os2app/kal/kal.c
  25. +30 −7 shared/app/os2app/kal/start.c
  26. +10 −8 shared/lib/ixf/lx/allocmem.c
  27. +25 −31 shared/lib/ixf/lx/fixup.c
  28. +4 −6 shared/lib/ixf/lx/load.c
  29. +298 −61 shared/lib/ixf/lx/loadobj.c
  30. +159 −95 shared/lib/ixf/lx/lx.c
  31. +8 −8 shared/lib/ixf/lx/mod.c
  32. +3 −2 shared/server/os2exec/api/api.c
  33. +16 −4 shared/server/os2exec/ixfmgr.c
  34. +155 −30 shared/server/os2exec/modmgr.c
  35. +1 −1 shared/server/os2fs/api/api.c
  36. +6 −6 shared/server/os2srv/api/api.c
  37. +2 −2 shared/server/os2srv/api/api.h
  38. +17 −0 shared/server/os2srv/initdone.c
BIN -292 Bytes (100%) filesys/os2/cmd.exe
Binary file not shown.
@@ -14,3 +14,5 @@ LIBPATH=c:\
SET PATH=.;c:\os2;c:\os2\mdos
SET DPATH=.;c:\;c:\os2
SET TZ=MSK-12MSD,3,-1,0,7200,10,-1,0,7200,3600
SET EMXOPT=-n -h2048

BIN +168 Bytes (100%) filesys/os2/doscalls.dll
Binary file not shown.
BIN -2.31 KB (71%) filesys/os2/vp.exe
Binary file not shown.
BIN -39.6 KB (61%) filesys/os2/zip.exe
Binary file not shown.
@@ -164,15 +164,15 @@
#define OBJBIGDEF 0x2000L
#define OBJIOPL 0x8000L

#if FOR_EXEHDR
//#if FOR_EXEHDR

#define OBJDISCARD 0x0010L
#define OBJSHARED 0x0020L
#define OBJPRELOAD 0x0040L
#define OBJEXEC 0x0004L
#define OBJCONFORM 0x4000L

#else
//#else

#define NSDISCARD 0x0010L
#define NSMOVE NSDISCARD
@@ -181,20 +181,21 @@
#define NSEXRD 0x0004L
#define NSCONFORM 0x4000L

#endif
//#endif

#define GETPAGEIDX(x) ((x).o32_pagedataoffset)
#define PUTPAGEIDX(x,i) ((x).o32_pagedataoffset = ((unsigned long)(i)))
#define PUTPAGESIZ(x,i) ((x).o32_pagesize = ((unsigned int)(i)))
#define GETPAGESIZ(x) ((x).o32_pagesize)
#define PAGEFLAGS(x) (x).o32_pageflags

#define VALID 0x0000
#define ITERDATA 0x0001
#define VALID 0x0000 // Unpacked
#define ITERDATA 0x0001 // EXEPACK:1
#define INVALID 0x0002
#define ZEROED 0x0003
#define RANGE 0x0004
#define ITERDATA2 0x0005
#define ITERDATA2 0x0005 // EXEPACK:2
#define ITERDATA3 0x0008 // OS/4

#define B32_CNT(x) (x).b32_cnt
#define B32_TYPE(x) (x).b32_type
@@ -9,7 +9,7 @@
#include <os3/dataspace.h>

void *allocmem(unsigned long long area, int base, int size, int flags,
unsigned long PIC, l4_os3_dataspace_t *ds);
unsigned long PIC, l4_os3_dataspace_t *ds, int align);

int translate_os2_flags(int flags);

@@ -25,9 +25,10 @@ typedef struct
void *addr;
unsigned long size;
l4_os3_dataspace_t ds;
unsigned long type;
unsigned long id;
unsigned long pad;
unsigned long type;
unsigned long id;
unsigned long flags;
unsigned long pad; // last 32-bit structure member won't be copied!
} l4_os3_section_t;

struct slist
@@ -14,6 +14,10 @@ void segment_gdt_set(void *desc, unsigned int size,

unsigned segment_gdt_get_entry_offset(void);

void segment_ldt_set(void *desc, unsigned int size,
unsigned int entry_number_start,
l4_os3_thread_t tid);

#if defined(__l4env__) || defined(__l4re__)

#include <l4/sys/segment.h>
Empty file.
@@ -50,8 +50,8 @@ int io_load_file(const char *filename, void **addr, unsigned long *size)
l4dm_dataspace_t ds;
int rc;

io_log("filename=%s\n", filename);
io_log("fileprov=%lu.%lu\n", fprov_id.thread.id.task, fprov_id.thread.id.lthread);
//io_log("filename=%s\n", filename);
//io_log("fileprov=%lu.%lu\n", fprov_id.thread.id.task, fprov_id.thread.id.lthread);

/* query default dataspace manager id */
if (l4_is_invalid_id(dsm))
@@ -70,19 +70,19 @@ int io_load_file(const char *filename, void **addr, unsigned long *size)
rc = l4fprov_file_open_call(&fprov_id.thread, filename, &dsm, 0,
&ds, (l4_size_t *)size, &env);

io_log("rc=%d\n", rc);
//io_log("rc=%d\n", rc);

//if (rc == -L4_ENOTFOUND)
if (rc == 2)
return rc; /* ERROR_FILE_NOT_FOUND */

io_log("size=%lu\n", *size);
//io_log("size=%lu\n", *size);

/* attach the created dataspace to our address space */
// rc = l4rm_attach(&ds, *size, 0, L4DM_RW | L4RM_MAP, addr);
rc = l4rm_attach(&ds, *size, 0, L4DM_RW | L4RM_MAP, addr);

io_log("addr=%lu\n", *addr);
//io_log("addr=%lu\n", *addr);

if (rc < 0)
return 8; /* What to return? */
@@ -126,40 +126,40 @@ int io_load_file(const char * filename, void ** addr, unsigned long * size)
char buf[256];
int len, i;

io_log("filename=%s\n", filename);
//io_log("filename=%s\n", filename);
char drv = get_drv(filename);

io_log("drv=%c:\n", drv);
//io_log("drv=%c:\n", drv);

if(drv == '\0')
{
return 2; /* ERROR_FILE_NOT_FOUND */
}

char * directory = get_directory(filename);
io_log("directory=%s\n", directory);
//io_log("directory=%s\n", directory);
if (directory==NULL)
{
return 2; /* ERROR_FILE_NOT_FOUND */
}
char * name = get_name(filename);
io_log("name=%s\n", name);
//io_log("name=%s\n", name);

DosNameConversion(directory);
DosNameConversion(name);

io_log("directory=%s\n", directory);
io_log("name=%s\n", name);
//io_log("directory=%s\n", directory);
//io_log("name=%s\n", name);
#if 0
io_log("srv_num_=%d\n", fsrouter.srv_num_);
//io_log("srv_num_=%d\n", fsrouter.srv_num_);
for(i=0; i< fsrouter.srv_num_; i++)
{
I_Fs_srv_t *srv = fsrouter.fs_srv_arr_[i];
if (srv)
{
io_log("srv->drive=%s, srv->mountpoint=%s\n", srv->drive, srv->mountpoint);
}
}
//if (srv)
//{
// io_log("srv->drive=%s, srv->mountpoint=%s\n", srv->drive, srv->mountpoint);
//}
}
#endif
struct I_Fs_srv *target_fs_srv = FSRouter_route(&fsrouter, drv);

@@ -191,14 +191,14 @@ int io_load_file(const char * filename, void ** addr, unsigned long * size)
io_log("opendir() successful\n");


io_log("name=%s\n", name);
//io_log("name=%s\n", name);
while(diren = readdir(dir))
{
len = strlen(name);
strncpy(buf, diren->d_name, len);
buf[len] = '\0';
io_log("diren->d_name=%s\n", diren->d_name);
io_log("buf=%s\n", buf);
//io_log("diren->d_name=%s\n", diren->d_name);
//io_log("buf=%s\n", buf);
if(!diren)
break;
if(strcasecmp(buf, name)==0) {
@@ -223,15 +223,15 @@ int io_load_file(const char * filename, void ** addr, unsigned long * size)

//io_log("newfilename=%s", newfilename);
f = fopen(newfilename, "rb");
io_log("file opened\n");
//io_log("file opened\n");
if(f) {
fseek(f, 0, SEEK_END);
*size = ftell(f); /* Extract the size of the file and reads it into a buffer.*/
rewind(f);
*addr = (void *)malloc(*size+1);
fread(*addr, *size, 1, f);
fclose(f);
io_log("successful return\n");
//io_log("successful return\n");
return 0; /*NO_ERROR;*/
}

@@ -190,6 +190,36 @@ long RegAreaReserve(unsigned long size,
return RegAreaReserveInArea(size, flags, addr, area);
}

static int
__find_free_region(l4_size_t size, l4_uint32_t area, int align,
l4rm_region_desc_t ** region, l4_addr_t * addr)
{
l4rm_region_desc_t *rp = l4rm_get_region_list();
l4_size_t a_size = 1UL << align;
l4_addr_t a_addr, offs;

/* search region */
while (rp)
{
if (IS_FREE_REGION(rp) && (REGION_AREA(rp) == area))
{
a_addr = (rp->start + a_size - 1) & ~(a_size - 1);
offs = a_addr - rp->start;
if ((rp->end - rp->start + 1) >= (size + offs))
{
/* found suitable region */
*region = rp;
*addr = a_addr;
return 0;
}
}
rp = rp->next;
}

/* nothing found */
return -L4_ENOMAP;
}

long RegAreaAttach(void **addr,
unsigned long size,
unsigned long long area,
@@ -199,14 +229,19 @@ long RegAreaAttach(void **addr,
unsigned char align)
{
ULONG rights = 0;
l4rm_region_desc_t *region;
int rc = NO_ERROR;

if (flags & DATASPACE_READ)
rights |= L4DM_READ;
if (flags & DATASPACE_WRITE)
rights |= L4DM_WRITE;

rc = l4rm_area_attach(&ds.ds, (unsigned long)area, size, offset, rights, addr);
if (! (rc = __find_free_region(size, area, align, &region, addr)) )
{
rc = l4rm_area_attach_to_region(&ds.ds, (unsigned long)area, *addr, size,
offset, rights);
}

if (rc < 0)
{
@@ -18,6 +18,13 @@ unsigned segment_gdt_get_entry_offset(void)
return fiasco_gdt_get_entry_offset();
}

void segment_ldt_set(void *desc, unsigned int size,
unsigned int entry_number_start,
l4_os3_thread_t tid)
{
fiasco_ldt_set(desc, size, entry_number_start, tid.thread.id.task);
}

#elif defined(L4API_l4f)

#include <l4/sys/utcb.h>
@@ -8,7 +8,7 @@ TRG = lx.ixf
MODE = l4env
SYSTEMS = x86-l4v2
SRC_C = lx.c mod.c load.c loadobj.c \
fixup.c debug.c allocmem.c
fixup.c debug.c allocmem.c unpack.c
CFLAGS += -I$(PKGDIR)/include

NO_DEFAULT_RELOC= 1
@@ -179,7 +179,7 @@ void parse_options(int argc, char *argv[], struct options *opts)
// Parse command line arguments
for (;;)
{
opt = getopt_long(argc, argv, "e", long_options, &optionid);
opt = getopt_long(argc, argv, "e:t", long_options, &optionid);
if (opt == -1) break;
switch (opt)
{
@@ -193,6 +193,9 @@ void parse_options(int argc, char *argv[], struct options *opts)
io_log("using %s as a terminal\n", optarg);
break;

case '?':
break;

default:
io_log("Error: Unknown option %c\n", opt);
usage();
@@ -100,6 +100,9 @@ APIRET ExcClientGetSect(HMODULE hmod,
long ret;

ret = os2exec_getsect_call(&execsrv, hmod, index, sect, &env);
io_log("$$$3 sect->type=%x\n", sect->type);
io_log("$$$3 sect->id=%x\n", sect->id);
io_log("$$$3 sect->flags=%x\n", sect->flags);
return (APIRET)ret;
}

@@ -157,6 +157,8 @@ void parse_options(int argc, char *argv[], struct options *opts)
const struct option long_options[] =
{
{ "events", no_argument, NULL, 'e'},
{ "TIMEOUT", 1, NULL, 't' },
{ "LOOKFOR", 1, NULL, 'l' },
{ 0, 0, 0, 0}
};

@@ -166,7 +168,7 @@ void parse_options(int argc, char *argv[], struct options *opts)
// Parse command line arguments
for (;;)
{
opt = getopt_long(argc, argv, "e", long_options, &optionid);
opt = getopt_long(argc, argv, "e:t:l", long_options, &optionid);

if (opt == -1)
break;
@@ -178,6 +180,11 @@ void parse_options(int argc, char *argv[], struct options *opts)
opts->use_events = 1;
break;

case 't':
case 'l':
case '?':
break;

default:
io_log("Error: Unknown option %c\n", opt);
usage();
@@ -80,7 +80,11 @@ os2exec_getsect_component (CORBA_Object _dice_corba_obj,
l4_os3_section_t *sect /* out */,
CORBA_Server_Environment *_dice_corba_env)
{
return ExcGetSect(hmod, index, sect);
long rc = ExcGetSect(hmod, index, sect);
io_log("$$$2 sect->type=%x\n", sect->type);
io_log("$$$2 sect->id=%x\n", sect->id);
io_log("$$$2 sect->flags=%x\n", sect->flags);
return rc;
}


@@ -94,13 +94,15 @@ void parse_options(int argc, char **argv, struct options *opts)
const struct option long_options[] =
{
{ "events", no_argument, NULL, 'e'},
{ "TIMEOUT", 1, NULL, 't' },
{ "LOOKFOR", 1, NULL, 'l' },
{ 0, 0, 0, 0}
};

// Parse command line arguments
for (;;)
{
opt = getopt_long(argc, argv, "e", long_options, &optionid);
opt = getopt_long(argc, argv, "e:t:l", long_options, &optionid);

if (opt == -1)
break;
@@ -112,6 +114,11 @@ void parse_options(int argc, char **argv, struct options *opts)
opts->use_events = 1;
break;

case 't':
case 'l':
case '?':
break;

default:
io_log("Error: Unknown option %c\n", opt);
usage();

0 comments on commit bc8d222

Please sign in to comment.