VirtualBox

source: kStuff/trunk/kLdr/kLdrInternal.h@ 28

Last change on this file since 28 was 2, checked in by bird, 17 years ago

Imported http://svn.netlabs.org/repos/libc/trunk/kStuff, revision 3612.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 16.0 KB
Line 
1/* $Id: kLdrInternal.h 2 2007-11-16 16:07:14Z bird $ */
2/** @file
3 * kLdr - The Dynamic Loader, internal header.
4 */
5
6/*
7 * Copyright (c) 2006-2007 knut st. osmundsen <[email protected]>
8 *
9 * This file is part of kStuff.
10 *
11 * kStuff is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * In addition to the permissions in the GNU Lesser General Public
17 * License, you are granted unlimited permission to link the compiled
18 * version of this file into combinations with other programs, and to
19 * distribute those combinations without any restriction coming from
20 * the use of this file.
21 *
22 * kStuff is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
26 *
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with kStuff; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 * 02110-1301, USA
31 */
32
33#ifndef ___kLdrInternal_h___
34#define ___kLdrInternal_h___
35
36#include <k/kHlp.h>
37#include <k/kRdr.h>
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43#if !defined(__X86__) && !defined(__AMD64__)
44# if defined(__i386__) || defined(_M_IX86)
45# define __X86__
46# elif defined(__x86_64__) || defined(_M_X64) || defined(__AMD64__) || defined(_M_AMD64)
47# define __AMD64__
48# else
49# error "can't figure out the target arch."
50# endif
51#endif
52
53/* ignore definitions in winnt.h */
54#undef IMAGE_DOS_SIGNATURE
55#undef IMAGE_NT_SIGNATURE
56
57/** @name Signatures we know
58 * @{ */
59/** ELF signature ("\x7fELF"). */
60#define IMAGE_ELF_SIGNATURE K_LE2H_U32(0x7f | ('E' << 8) | ((KU32)'L' << 16) | ((KU32)'F' << 24))
61/** PE signature ("PE\0\0"). */
62#define IMAGE_NT_SIGNATURE K_LE2H_U32('P' | ('E' << 8))
63/** LX signature ("LX") */
64#define IMAGE_LX_SIGNATURE K_LE2H_U16('L' | ('X' << 8))
65/** LE signature ("LE") */
66#define IMAGE_LE_SIGNATURE K_LE2H_U16('L' | ('E' << 8))
67/** NE signature ("NE") */
68#define IMAGE_NE_SIGNATURE K_LE2H_U16('N' | ('E' << 8))
69/** MZ signature ("MZ"). */
70#define IMAGE_DOS_SIGNATURE K_LE2H_U16('M' | ('Z' << 8))
71/** The FAT signature (universal binaries). */
72#define IMAGE_FAT_SIGNATURE KU32_C(0xcafebabe)
73/** The FAT signature (universal binaries), other endian. */
74#define IMAGE_FAT_SIGNATURE_OE KU32_C(0xbebafeca)
75/** The 32-bit Mach-O signature. */
76#define IMAGE_MACHO32_SIGNATURE KU32_C(0xfeedface)
77/** The 32-bit Mach-O signature, other endian. */
78#define IMAGE_MACHO32_SIGNATURE_OE KU32_C(0xcefaedfe)
79/** The 64-bit Mach-O signature. */
80#define IMAGE_MACHO64_SIGNATURE KU32_C(0xfeedfacf)
81/** The 64-bit Mach-O signature, other endian. */
82#define IMAGE_MACHO64_SIGNATURE_OE KU32_C(0xfefaedfe)
83/** @} */
84
85/** @defgroup grp_kLdrInternal Internals
86 * @internal
87 * @{
88 */
89
90
91/**
92 * The state of a dynamic loader module.
93 * @image html KLDRSTATE.gif "The state diagram"
94 */
95typedef enum KLDRSTATE
96{
97 /** The usual invalid 0 enum. */
98 KLDRSTATE_INVALID = 0,
99
100 /** The module has just been opened and linked into the load list.
101 *
102 * Prev state: -
103 * Next state: MAPPED, PENDING_DESTROY
104 */
105 KLDRSTATE_OPEN,
106
107 /** The module segments has been mapped into the process memory.
108 *
109 * Prev state: OPEN
110 * Next state: LOADED_PREREQUISITES, PENDING_DESTROY
111 */
112 KLDRSTATE_MAPPED,
113 /** The module has been reloaded and needs to be fixed up again.
114 * This can occure when the loader is called recursivly.
115 *
116 * The reason RELOADED modules must go back to the PENDING_GC state is
117 * because we want to guard against uninit order issues, and therefore
118 * doesn't unmap modules untill all pending termintation callbacks has
119 * been executed.
120 *
121 * Prev state: PENDING_GC
122 * Next state: RELOADED_LOADED_PREREQUISITES, PENDING_GC
123 */
124 KLDRSTATE_RELOADED,
125
126 /** The immediate prerequisites have been loaded.
127 *
128 * Prev state: MAPPED
129 * Next state: FIXED_UP, PENDING_DESTROY
130 */
131 KLDRSTATE_LOADED_PREREQUISITES,
132 /** The immediate prerequisites have been loaded for a reloaded module.
133 *
134 * Prev state: RELOADED
135 * Next state: RELOADED_FIXED_UP, PENDING_GC
136 */
137 KLDRSTATE_RELOADED_LOADED_PREREQUISITES,
138
139 /** Fixups has been applied.
140 *
141 * Prev state: LOADED_PREREQUISITES
142 * Next state: PENDING_INITIALIZATION, PENDING_DESTROY
143 */
144 KLDRSTATE_FIXED_UP,
145 /** Fixups has been applied.
146 *
147 * Prev state: RELOADED_LOADED_PREREQUISITES
148 * Next state: PENDING_INITIALIZATION, PENDING_GC
149 */
150 KLDRSTATE_RELOADED_FIXED_UP,
151
152 /** Pending initialization.
153 * While the module is in this state the loader is in reentrant mode.
154 *
155 * Prev state: FIXED_UP, RELOADED_FIXED_UP
156 * Next state: INITIALIZATION, PENDING_GC
157 */
158 KLDRSTATE_PENDING_INITIALIZATION,
159
160 /** Initializing.
161 * While the module is in this state the loader is in reentrant mode.
162 *
163 * Prev state: PENDING_INITIALIZATION
164 * Next state: GOOD, PENDING_GC
165 */
166 KLDRSTATE_INITIALIZING,
167
168 /** Initialization failed.
169 *
170 * This is somewhat similar to PENDING_GC except that, a module
171 * in this state cannot be reloaded untill we've done GC. This ensures
172 * that a init failure during recursive loading is propagated up.
173 *
174 * While the module is in this state the loader is in reentrant mode.
175 *
176 * Prev state: INITIALIZING
177 * Next state: GC
178 */
179 KLDRSTATE_INITIALIZATION_FAILED,
180
181 /** The module has been successfully loaded and initialized.
182 * While the module is in this state the loader can be in reentrant
183 * or 'unused' mode.
184 *
185 * Prev state: INITIALIZING
186 * Next state: PENDING_TERMINATION
187 */
188 KLDRSTATE_GOOD,
189
190 /** Pending termination, reference count is 0.
191 * While the module is in this state the loader is in reentrant mode.
192 * Prerequisite modules are dropped when a module enters this state.
193 *
194 * Prev state: GOOD
195 * Next state: TERMINATING, GOOD
196 */
197 KLDRSTATE_PENDING_TERMINATION,
198
199 /** Terminating, reference count is still 0.
200 * While the module is in this state the loader is in reentrant mode.
201 *
202 * Prev state: PENDING_TERMINATION
203 * Next state: PENDING_GC
204 */
205 KLDRSTATE_TERMINATING,
206
207 /** Pending garbage collection.
208 * Prerequisite modules are dropped when a module enters this state (if not done already).
209 *
210 * Prev state: TERMINATING, PENDING_INITIALIZATION, INITIALIZATION_FAILED
211 * Next state: GC, RELOADED
212 */
213 KLDRSTATE_PENDING_GC,
214
215 /** Being garbage collected.
216 *
217 * Prev state: PENDING_GC, INITIALIZATION_FAILED
218 * Next state: PENDING_DESTROY, DESTROYED
219 */
220 KLDRSTATE_GC,
221
222 /** The module has be unlinked, but there are still stack references to it.
223 *
224 * Prev state: GC, FIXED_UP, LOADED_PREREQUISITES, MAPPED, OPEN
225 * Next state: DESTROYED
226 */
227 KLDRSTATE_PENDING_DESTROY,
228
229 /** The module has been destroyed but not freed yet.
230 *
231 * This happens when a module ends up being destroyed when cRefs > 0. The
232 * module structure will be freed when cRefs reaches 0.
233 *
234 * Prev state: GC, PENDING_DESTROY
235 */
236 KLDRSTATE_DESTROYED,
237
238 /** The end of valid states (exclusive) */
239 KLDRSTATE_END = KLDRSTATE_DESTROYED,
240 /** The usual 32-bit blowup. */
241 KLDRSTATE_32BIT_HACK = 0x7fffffff
242} KLDRSTATE;
243
244
245/**
246 * Dynamic loader module.
247 */
248typedef struct KLDRDYLDMOD
249{
250 /** Magic number. */
251 KU32 u32MagicHead;
252 /** The module state. */
253 KLDRSTATE enmState;
254 /** The module. */
255 PKLDRMOD pMod;
256 /** The module handle. */
257 HKLDRMOD hMod;
258 /** The total number of references. */
259 KU32 cRefs;
260 /** The number of dependency references. */
261 KU32 cDepRefs;
262 /** The number of dynamic load references. */
263 KU32 cDynRefs;
264 /** Set if this is the executable module.
265 * When clear, the module is a shared object or relocatable object. */
266 KU32 fExecutable : 1;
267 /** Global DLL (set) or specific DLL (clear). */
268 KU32 fGlobalOrSpecific : 1;
269 /** Whether the module contains bindable symbols in the global unix namespace. */
270 KU32 fBindable : 1;
271 /** Set if linked into the global init list. */
272 KU32 fInitList : 1;
273 /** Already loaded or checked prerequisites.
274 * This flag is used when loading prerequisites, when set it means that
275 * this module is already seen and shouldn't be processed again. */
276 KU32 fAlreadySeen : 1;
277 /** Set if the module is currently mapped.
278 * This is used to avoid unnecessary calls to kLdrModUnmap during cleanup. */
279 KU32 fMapped : 1;
280 /** Set if TLS allocation has been done. (part of the mapping). */
281 KU32 fAllocatedTLS : 1;
282 /** Reserved for future use. */
283 KU32 f25Reserved : 25;
284 /** The load list linkage. */
285 struct
286 {
287 /** The next module in the list. */
288 struct KLDRDYLDMOD *pNext;
289 /** The prev module in the list. */
290 struct KLDRDYLDMOD *pPrev;
291 } Load;
292 /** The initialization and termination list linkage.
293 * If non-recursive initialization is used, the module will be pushed on
294 * the initialization list.
295 * A module will be linked into the termination list upon a successful
296 * return from module initialization. */
297 struct
298 {
299 /** The next module in the list. */
300 struct KLDRDYLDMOD *pNext;
301 /** The prev module in the list. */
302 struct KLDRDYLDMOD *pPrev;
303 } InitTerm;
304 /** The bind order list linkage.
305 * The module is not in this list when fBindable is clear. */
306 struct
307 {
308 /** The next module in the list. */
309 struct KLDRDYLDMOD *pNext;
310 /** The prev module in the list. */
311 struct KLDRDYLDMOD *pPrev;
312 } Bind;
313
314 /** The number of prerequisite modules in the prereq array. */
315 KU32 cPrereqs;
316 /** Pointer to an array of prerequisite module pointers.
317 * This array is only filled when in the states starting with
318 * KLDRSTATE_LOADED_PREREQUISITES thru KLDRSTATE_GOOD.
319 */
320 struct KLDRDYLDMOD **papPrereqs;
321
322 /** Magic number. */
323 KU32 u32MagicTail;
324} KLDRDYLDMOD, *PKLDRDYLDMOD, **PPKLDRDYLDMOD;
325
326/** KLDRDYLDMOD magic value. (Fuyumi Soryo) */
327#define KLDRDYMOD_MAGIC 0x19590106
328
329/** Return / crash validation of a module handle argument. */
330#define KLDRDYLD_VALIDATE_HKLDRMOD(hMod) \
331 do { \
332 if ( (hMod) == NIL_HKLDRMOD \
333 || (hMod)->u32MagicHead != KLDRDYMOD_MAGIC \
334 || (hMod)->u32MagicTail != KLDRDYMOD_MAGIC) \
335 { \
336 return KERR_INVALID_HANDLE; \
337 } \
338 } while (0)
339
340
341int kldrInit(void);
342void kldrTerm(void);
343
344int kldrDyldInit(void);
345void kldrDyldTerm(void);
346
347void kldrDyldDoLoadExe(PKLDRDYLDMOD pExe);
348int kldrDyldFailure(int rc, const char *pszFormat, ...);
349
350int kldrDyldOSStartExe(KUPTR uMainEntrypoint, void *pvStack, KSIZE cbStack);
351void *kldrDyldOSAllocStack(KSIZE cb);
352
353int kldrDyldFindInit(void);
354int kldrDyldFindNewModule(const char *pszName, const char *pszPrefix, const char *pszSuffix,
355 KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRDYLDMOD ppMod);
356int kldrDyldFindExistingModule(const char *pszName, const char *pszPrefix, const char *pszSuffix,
357 KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRDYLDMOD ppMod);
358
359int kldrDyldGetPrerequisite(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch,
360 unsigned fFlags, PKLDRDYLDMOD pDep, PPKLDRDYLDMOD ppMod);
361
362
363int kldrDyldModCreate(PKRDR pRdr, KU32 fFlags, PPKLDRDYLDMOD ppMod);
364void kldrDyldModDestroy(PKLDRDYLDMOD pMod);
365void kldrDyldModAddRef(PKLDRDYLDMOD pMod);
366void kldrDyldModDeref(PKLDRDYLDMOD pMod);
367void kldrDyldModAddDep(PKLDRDYLDMOD pMod, PKLDRDYLDMOD pDep);
368void kldrDyldModRemoveDep(PKLDRDYLDMOD pMod, PKLDRDYLDMOD pDep);
369int kldrDyldModDynamicLoad(PKLDRDYLDMOD pMod);
370int kldrDyldModDynamicUnload(PKLDRDYLDMOD pMod);
371void kldrDyldModMarkGlobal(PKLDRDYLDMOD pMod);
372void kldrDyldModMarkSpecific(PKLDRDYLDMOD pMod);
373void kldrDyldModSetBindable(PKLDRDYLDMOD pMod, unsigned fDeep);
374void kldrDyldModClearBindable(PKLDRDYLDMOD pMod);
375int kldrDyldModMap(PKLDRDYLDMOD pMod);
376int kldrDyldModUnmap(PKLDRDYLDMOD pMod);
377int kldrDyldModLoadPrerequisites(PKLDRDYLDMOD pMod, const char *pszPrefix, const char *pszSuffix,
378 KLDRDYLDSEARCH enmSearch, unsigned fFlags);
379int kldrDyldModCheckPrerequisites(PKLDRDYLDMOD pMod);
380void kldrDyldModUnloadPrerequisites(PKLDRDYLDMOD pMod);
381int kldrDyldModFixup(PKLDRDYLDMOD pMod);
382int kldrDyldModCallInit(PKLDRDYLDMOD pMod);
383void kldrDyldModCallTerm(PKLDRDYLDMOD pMod);
384int kldrDyldModReload(PKLDRDYLDMOD pMod);
385int kldrDyldModAttachThread(PKLDRDYLDMOD pMod);
386void kldrDyldModDetachThread(PKLDRDYLDMOD pMod);
387int kldrDyldModGetMainStack(PKLDRDYLDMOD pMod, void **ppvStack, KSIZE *pcbStack);
388int kldrDyldModStartExe(PKLDRDYLDMOD pMod);
389
390int kldrDyldModGetName(PKLDRDYLDMOD pMod, char *pszName, KSIZE cchName);
391int kldrDyldModGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, KSIZE cchFilename);
392int kldrDyldModQuerySymbol(PKLDRDYLDMOD pMod, KU32 uSymbolOrdinal, const char *pszSymbolName, KUPTR *puValue, KU32 *pfKind);
393
394
395/** Pointer to the head module (the executable).
396 * (This is exported, so no prefix.) */
397extern PKLDRDYLDMOD kLdrDyldHead;
398/** Pointer to the tail module.
399 * (This is exported, so no prefix.) */
400extern PKLDRDYLDMOD kLdrDyldTail;
401/** Pointer to the head module of the initialization list.
402 * The outermost load call will pop elements from this list in LIFO order (i.e.
403 * from the tail). The list is only used during non-recursive initialization
404 * and may therefore share the pNext/pPrev members with the termination list
405 * since we don't push a module onto the termination list untill it has been
406 * successfully initialized. */
407extern PKLDRDYLDMOD g_pkLdrDyldInitHead;
408/** Pointer to the tail module of the initalization list. */
409extern PKLDRDYLDMOD g_pkLdrDyldInitTail;
410/** Pointer to the head module of the termination order list. */
411extern PKLDRDYLDMOD g_pkLdrDyldTermHead;
412/** Pointer to the tail module of the termination order list. */
413extern PKLDRDYLDMOD g_pkLdrDyldTermTail;
414/** Pointer to the head module of the bind order list.
415 * The modules in this list makes up the global namespace used when binding symbol unix fashion. */
416extern PKLDRDYLDMOD g_pkLdrDyldBindHead;
417/** Pointer to the tail module of the bind order list. */
418extern PKLDRDYLDMOD g_pkLdrDyldBindTail;
419
420/** Indicates that the other MainStack globals have been filled in. */
421extern unsigned g_fkLdrDyldDoneMainStack;
422/** Whether the stack was allocated seperatly or was part of the executable. */
423extern unsigned g_fkLdrDyldMainStackAllocated;
424/** Pointer to the main stack object. */
425extern void *g_pvkLdrDyldMainStack;
426/** The size of the main stack object. */
427extern KSIZE g_cbkLdrDyldMainStack;
428
429/** The global error buffer. */
430extern char g_szkLdrDyldError[1024];
431
432extern char kLdrDyldExePath[8192];
433extern char kLdrDyldLibraryPath[8192];
434extern char kLdrDyldDefPrefix[16];
435extern char kLdrDyldDefSuffix[16];
436
437extern int g_fBootstrapping;
438
439
440/** @name The Loader semaphore
441 * @{ */
442int kLdrDyldSemInit(void);
443void kLdrDyldSemTerm(void);
444int kLdrDyldSemRequest(void);
445void kLdrDyldSemRelease(void);
446/** @} */
447
448
449/** @name Module interpreter method tables
450 * @{ */
451extern KLDRMODOPS g_kLdrModLXOps;
452extern KLDRMODOPS g_kLdrModMachOOps;
453extern KLDRMODOPS g_kLdrModNativeOps;
454extern KLDRMODOPS g_kLdrModPEOps;
455/** @} */
456
457
458/** @} */
459#ifdef __cplusplus
460}
461#endif
462
463#endif
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette