1 static char RCSId
[] = "$Id: relay.c,v 1.1 1993/06/29 15:55:18 root Exp $";
2 static char Copyright
[] = "Copyright Robert J. Amstadt, 1993";
10 #include <linux/unistd.h>
11 #include <linux/head.h>
12 #include <linux/ldt.h>
13 #include <linux/segment.h>
17 #include "prototypes.h"
22 struct dll_name_table_entry_s dll_builtin_table
[N_BUILTINS
] =
24 { "KERNEL", KERNEL_table
, 410, 1 },
25 { "USER", USER_table
, 540, 2 },
26 { "GDI", GDI_table
, 490, 3 },
27 { "UNIXLIB", UNIXLIB_table
, 10, 4 },
28 { "WIN87EM", WIN87EM_table
, 10, 5 },
29 { "SHELL", SHELL_table
, 256, 6 },
32 unsigned short *Stack16Frame
;
34 /**********************************************************************
37 * We get a stack frame pointer to data that looks like this:
41 * +00 previous saved_16ss
42 * +02 previous saved_16ebp
43 * +06 previous saved_16esp
47 * +12 length of 16-bit arguments
53 DLLRelay(unsigned int func_num
, unsigned int seg_off
)
55 struct dll_table_entry_s
*dll_p
;
60 int arg_table
[DLL_MAX_ARGS
];
66 * Determine address of arguments.
68 Stack16Frame
= (unsigned short *) seg_off
;
69 arg_ptr
= (void *) (seg_off
+ 0x18);
72 * Extract the DLL number and ordinal number.
74 dll_id
= ((func_num
>> 16) & 0xffff) - 1;
75 ordinal
= func_num
& 0xffff;
76 dll_p
= &dll_builtin_table
[dll_id
].dll_table
[ordinal
];
80 unsigned int *ret_addr
;
81 unsigned short *stack_p
;
83 ret_addr
= (unsigned int *) ((char *) seg_off
+ 0x14);
84 printf("RELAY: Calling %s.%d, 16-bit stack at %04x:%04x, ",
85 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
86 seg_off
>> 16, seg_off
& 0xffff);
87 printf("return to %08x\n", *ret_addr
);
90 stack_p
= (unsigned short *) seg_off
;
91 for (i
= 0; i
< 24; i
++, stack_p
++)
93 printf("%04x ", *stack_p
);
98 #endif /* STACK_DEBUG */
100 #endif /* RELAY_DEBUG */
103 * Make sure we have a handler defined for this call.
105 if (dll_p
->handler
== NULL
)
109 sprintf(buffer
, "No handler for routine %s.%d",
110 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
113 func_ptr
= dll_p
->handler
;
116 * OK, special case. If the handler is define as taking no arguments
117 * then pass the address of the arguments on the 16-bit stack to the
118 * handler. It will just ignore the pointer if it really takes no
119 * arguments. This allows us to write slightly faster library routines
122 if (dll_p
->n_args
== 0)
123 return (*func_ptr
)(arg_ptr
);
126 * Getting this far means we need to convert the 16-bit argument stack.
128 for (i
= 0; i
< dll_p
->n_args
; i
++)
133 offset
= dll_p
->args
[i
].dst_arg
;
135 switch (dll_p
->args
[i
].src_type
)
137 case DLL_ARGTYPE_SIGNEDWORD
:
138 sp
= (short *) ((char *) arg_ptr
+ offset
);
142 case DLL_ARGTYPE_WORD
:
143 sp
= (short *) ((char *) arg_ptr
+ offset
);
144 arg_table
[i
] = (int) *sp
& 0xffff;
147 case DLL_ARGTYPE_LONG
:
148 case DLL_ARGTYPE_FARPTR
:
149 ip
= (int *) ((char *) arg_ptr
+ offset
);
158 return (*func_ptr
)(arg_table
[0], arg_table
[1], arg_table
[2],
159 arg_table
[3], arg_table
[4], arg_table
[5],
160 arg_table
[6], arg_table
[7], arg_table
[8],
161 arg_table
[9], arg_table
[10], arg_table
[11],
162 arg_table
[12], arg_table
[13], arg_table
[14],
166 /**********************************************************************
169 struct dll_table_entry_s
*
170 FindDLLTable(char *dll_name
)
174 for (i
= 0; i
< N_BUILTINS
; i
++)
175 if (strcmp(dll_builtin_table
[i
].dll_name
, dll_name
) == 0)
176 return dll_builtin_table
[i
].dll_table
;
181 /**********************************************************************
182 * FindOrdinalFromName
185 FindOrdinalFromName(struct dll_table_entry_s
*dll_table
, char *func_name
)
189 for (i
= 0; i
< N_BUILTINS
; i
++)
190 if (dll_table
== dll_builtin_table
[i
].dll_table
)
196 limit
= dll_builtin_table
[i
].dll_table_length
;
197 for (i
= 0; i
< limit
; i
++)
198 if (strcasecmp(dll_table
[i
].export_name
, func_name
) == 0)