>if we do dll's
>
>how do we ...
>
>a) call to a function in another segment.

One way is to link the program with a static library of stubs, each one 
looking like this:

strcpy_stub:
        call far 1234:5678
        rts

...where 1234:5678 is the seg:offset address of the real strcpy.

This has drawbacks in that (a) you have to fill in the address in the code (or 
load it from a table somewhere) each time the shared library's segment moves, 
and (b) there will be two extra words pushed onto the stack which will make 
accessing parameters on the stack interesting from the other side.

Another method is to use a system call; you'd pass in a library handle and a 
function number, and then all parameters go on the stack or those passed in 
registers would get saved in a structure or something like that. This has the 
advantage of being much more flexible; you don't have to do code patching at 
run time, it lets you load shared libraries dynamically, the library can move 
whenever it likes and the program won't care, and so on, but will be slower 
and will require extra code in the kernel. I suppose we could implement all 
this in an ld.so that did illegal things hooking interrupts.

Actually calling the function isn't hard; it's working out how to manage the 
whole process that will cause problems.

>b) which stack does the dll use (if the calling processes then SS != DS
>which bcc appears not to like, if its own then dealing with reentrance may
>be lots of fun if two processes call the same dll)

A shared library will use it's calling process' stack and data segment.

Another problem is coping with global data in a library. Global data is 
accessed via DS; except, when you build the library, the compiler has no 
notion of what memory the calling process is going to use and so doesn't know 
where to put it.

One technique we could use is that the stub malloc's a structure and passes it 
in to the library as an implicit parameter to all functions. Slightly extra 
overhead and a bit more work, but this gives the maximum portability. (OTOH 
doing this for libc is a little problematic as we don't have a malloc yet. Off 
the stack, perhaps?)

unsigned int __dll_termcap_handle;
struct __dll_termcap_globals_s __dll_termcap_globals;

void __dll_load_termcap(void)
{
        __dll_termcap_handle = dll_load("termcap.so");
        dll_exec(__dll_termcap_handle, __DLL_TERMCAP_INIT,
                &__dll_termcap_globals);
}

...all to be executed before main() starts.

>I think that shared libraries / dlls are a must for any serious OS for a
>constrained platform.

Especially on a platform with as limited memory as ours.

-- 
+- David Given ------------McQ-+ A friend is someone you call to help
|  Work: [EMAIL PROTECTED]          | you move. A real friend is someone
|  Play: [EMAIL PROTECTED]      | you call to help you move a body. 
+- http://wiredsoc.ml.org/~dg -+ 

Reply via email to