4 * Copyright 1996 Alexandre Julliard
12 #include "wine/winbase16.h"
13 #include "builtin16.h"
19 #include "stackframe.h"
20 #include "debugtools.h"
23 DEFAULT_DEBUG_CHANNEL(module
);
25 /* Table of all built-in DLLs */
29 static const BUILTIN16_DESCRIPTOR
*builtin_dlls
[MAX_DLLS
];
33 /* patch all the flat cs references of the code segment if necessary */
34 inline static void patch_code_segment( void *code_segment
)
37 CALLFROM16
*call
= code_segment
;
38 if (call
->flatcs
== __get_cs()) return; /* nothing to patch */
39 while (call
->pushl
== 0x68)
41 call
->flatcs
= __get_cs();
48 /***********************************************************************
49 * BUILTIN_DoLoadModule16
51 * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule.
53 static HMODULE16
BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR
*descr
)
57 SEGTABLEENTRY
*pSegTable
;
60 hModule
= GLOBAL_CreateBlock( GMEM_MOVEABLE
, descr
->module_start
,
61 descr
->module_size
, 0, WINE_LDT_FLAGS_DATA
);
62 if (!hModule
) return 0;
63 FarSetOwner16( hModule
, hModule
);
65 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
66 pModule
->self
= hModule
;
67 /* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
68 pModule
->hRsrcMap
= (void *)descr
->rsrc
;
70 /* Allocate the code segment */
72 pSegTable
= NE_SEG_TABLE( pModule
);
73 pSegTable
->hSeg
= GLOBAL_CreateBlock( GMEM_FIXED
, descr
->code_start
,
74 pSegTable
->minsize
, hModule
,
75 WINE_LDT_FLAGS_CODE
|WINE_LDT_FLAGS_32BIT
);
76 if (!pSegTable
->hSeg
) return 0;
77 patch_code_segment( descr
->code_start
);
80 /* Allocate the data segment */
82 minsize
= pSegTable
->minsize
? pSegTable
->minsize
: 0x10000;
83 minsize
+= pModule
->heap_size
;
84 if (minsize
> 0x10000) minsize
= 0x10000;
85 pSegTable
->hSeg
= GlobalAlloc16( GMEM_FIXED
, minsize
);
86 if (!pSegTable
->hSeg
) return 0;
87 FarSetOwner16( pSegTable
->hSeg
, hModule
);
88 if (pSegTable
->minsize
) memcpy( GlobalLock16( pSegTable
->hSeg
),
89 descr
->data_start
, pSegTable
->minsize
);
90 if (pModule
->heap_size
)
91 LocalInit16( GlobalHandleToSel16(pSegTable
->hSeg
),
92 pSegTable
->minsize
, minsize
);
94 if (descr
->rsrc
) NE_InitResourceHandler(hModule
);
96 NE_RegisterModule( pModule
);
98 /* make sure the 32-bit library containing this one is loaded too */
99 LoadLibraryA( descr
->owner
);
105 /***********************************************************************
108 * Find a descriptor in the list
110 static const BUILTIN16_DESCRIPTOR
*find_dll_descr( const char *dllname
)
113 for (i
= 0; i
< nb_dlls
; i
++)
115 const BUILTIN16_DESCRIPTOR
*descr
= builtin_dlls
[i
];
116 NE_MODULE
*pModule
= (NE_MODULE
*)descr
->module_start
;
117 OFSTRUCT
*pOfs
= (OFSTRUCT
*)((LPBYTE
)pModule
+ pModule
->fileinfo
);
118 BYTE
*name_table
= (BYTE
*)pModule
+ pModule
->name_table
;
120 /* check the dll file name */
121 if (!FILE_strcasecmp( pOfs
->szPathName
, dllname
))
123 /* check the dll module name (without extension) */
124 if (!FILE_strncasecmp( dllname
, name_table
+1, *name_table
) &&
125 !strcmp( dllname
+ *name_table
, ".dll" ))
132 /***********************************************************************
135 * Load a built-in module.
137 HMODULE16
BUILTIN_LoadModule( LPCSTR name
)
139 const BUILTIN16_DESCRIPTOR
*descr
;
140 char dllname
[20], *p
;
143 /* Fix the name in case we have a full path and extension */
145 if ((p
= strrchr( name
, '\\' ))) name
= p
+ 1;
146 if ((p
= strrchr( name
, '/' ))) name
= p
+ 1;
148 if (strlen(name
) >= sizeof(dllname
)-4) return (HMODULE16
)2;
150 strcpy( dllname
, name
);
151 p
= strrchr( dllname
, '.' );
152 if (!p
) strcat( dllname
, ".dll" );
153 for (p
= dllname
; *p
; p
++) *p
= FILE_tolower(*p
);
155 if ((descr
= find_dll_descr( dllname
)))
156 return BUILTIN_DoLoadModule16( descr
);
158 if ((handle
= BUILTIN32_dlopen( dllname
)))
160 if ((descr
= find_dll_descr( dllname
)))
161 return BUILTIN_DoLoadModule16( descr
);
163 ERR( "loaded .so but dll %s still not found\n", dllname
);
164 BUILTIN32_dlclose( handle
);
171 /***********************************************************************
172 * BUILTIN_GetEntryPoint16
174 * Return the ordinal, name, and type info corresponding to a CS:IP address.
175 * This is used only by relay debugging.
177 LPCSTR
BUILTIN_GetEntryPoint16( STACK16FRAME
*frame
, LPSTR name
, WORD
*pOrd
)
185 if (!(pModule
= NE_GetPtr( FarGetOwner16( GlobalHandle16( frame
->module_cs
) ))))
190 bundle
= (ET_BUNDLE
*)((BYTE
*)pModule
+ pModule
->entry_table
);
193 entry
= (ET_ENTRY
*)((BYTE
*)bundle
+6);
194 for (i
= bundle
->first
+ 1; i
<= bundle
->last
; i
++)
196 if ((entry
->offs
< frame
->entry_ip
)
197 && (entry
->segnum
== 1) /* code segment ? */
198 && (entry
->offs
>= max_offset
))
200 max_offset
= entry
->offs
;
205 } while ( (bundle
->next
)
206 && (bundle
= (ET_BUNDLE
*)((BYTE
*)pModule
+bundle
->next
)));
208 /* Search for the name in the resident names table */
209 /* (built-in modules have no non-resident table) */
211 p
= (BYTE
*)pModule
+ pModule
->name_table
;
214 p
+= *p
+ 1 + sizeof(WORD
);
215 if (*(WORD
*)(p
+ *p
+ 1) == *pOrd
) break;
218 sprintf( name
, "%.*s.%d: %.*s",
219 *((BYTE
*)pModule
+ pModule
->name_table
),
220 (char *)pModule
+ pModule
->name_table
+ 1,
221 *pOrd
, *p
, (char *)(p
+ 1) );
223 /* Retrieve type info string */
224 return *(LPCSTR
*)((LPBYTE
)MapSL( MAKESEGPTR( frame
->module_cs
, frame
->callfrom_ip
)) + 4);
228 /***********************************************************************
229 * __wine_register_dll_16 (KERNEL32.@)
231 * Register a built-in DLL descriptor.
233 void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR
*descr
)
235 assert( nb_dlls
< MAX_DLLS
);
236 builtin_dlls
[nb_dlls
++] = descr
;