source: trunk/kLdr/kLdrMod.c@ 2848

Last change on this file since 2848 was 2848, checked in by bird, 19 years ago

stubbed all the interpreter entry points.

  • Property svn:keywords set to Id
File size: 16.2 KB
Line 
1/* $Id: kLdrMod.c 2848 2006-11-02 00:08:16Z bird $ */
2/** @file
3 *
4 * kLdr - The Dynamic Loader, The module interpreter.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird-kbuild-src@anduin.net>
7 *
8 *
9 * This file is part of kLdr.
10 *
11 * kLdr is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * kLdr is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kLdr; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <kLdr.h>
32#include "kLdrHlp.h"
33#include "kLdrInternal.h"
34#include "kLdrModMZ.h"
35#if 1 /* testing headers */
36# include "kLdrModPE.h"
37# include "kLdrModLX.h"
38# include "kLdrModELF32.h"
39# include "kLdrModELF64.h"
40#endif
41
42
43/**
44 * Open a executable image by file name.
45 *
46 * @returns 0 on success and *ppMod pointing to a module instance.
47 * On failure, a non-zero OS specific error code is returned.
48 * @param pszFilename The filename to open.
49 * @param ppMod Where to store the module handle.
50 */
51int kLdrModOpen(const char *pszFilename, PPKLDRMOD ppMod)
52{
53 /*
54 * Open the file using a bit provider.
55 */
56 PKLDRRDR pRdr;
57 int rc = kLdrRdrOpen(&pRdr, pszFilename);
58 if (!rc)
59 {
60 rc = kLdrModOpenFromRdr(pRdr, ppMod);
61 if (!rc)
62 return 0;
63 kLdrRdrClose(pRdr);
64 }
65 return rc;
66}
67
68
69/**
70 * Open a executable image from a file provider instance.
71 *
72 * @returns 0 on success and *ppMod pointing to a module instance.
73 * On failure, a non-zero OS specific error code is returned.
74 * @param pRdr The file provider instance to use.
75 * On success, the ownership of the instance is taken by the
76 * module and the caller must not ever touch it again.
77 * (The instance is not closed on failure, the call has to do that.)
78 * @param ppMod Where to store the module handle.
79 */
80int kLdrModOpenFromRdr(PKLDRRDR pRdr, PPKLDRMOD ppMod)
81{
82 union
83 {
84 uint32_t u32;
85 uint16_t u16;
86 uint16_t au16[2];
87 uint8_t au8[4];
88 } u;
89 off_t offHdr = 0;
90 int rc;
91
92 /*
93 * Try figure out what kind of image this is.
94 * Always read the 'new header' if we encounter MZ.
95 */
96 rc = kLdrRdrRead(pRdr, &u, sizeof(u), 0);
97 if (rc)
98 return rc;
99 if ( u.u16 == IMAGE_DOS_SIGNATURE
100 && kLdrRdrSize(pRdr) > sizeof(IMAGE_DOS_HEADER))
101 {
102 rc = kLdrRdrRead(pRdr, &u, sizeof(u.u32), KLDR_OFFSETOF(IMAGE_DOS_HEADER, e_lfanew));
103 if (rc)
104 return rc;
105 if ((off_t)u.u32 < kLdrRdrSize(pRdr))
106 {
107 offHdr = u.u32;
108 rc = kLdrRdrRead(pRdr, &u, sizeof(u.u32), offHdr);
109 if (rc)
110 return rc;
111 }
112 else
113 u.u16 = IMAGE_DOS_SIGNATURE;
114 }
115
116 /*
117 * Use the magic to select the appropriate image interpreter.
118 */
119 if (u.u16 == IMAGE_DOS_SIGNATURE)
120 return KLDR_ERR_MZ_NOT_SUPPORTED;
121 else if (u.u16 == IMAGE_NE_SIGNATURE)
122 return KLDR_ERR_NE_NOT_SUPPORTED;
123 else if (u.u16 == IMAGE_LX_SIGNATURE)
124 return KLDR_ERR_LX_NOT_SUPPORTED;
125 else if (u.u16 == IMAGE_LE_SIGNATURE)
126 return KLDR_ERR_LE_NOT_SUPPORTED;
127 else if (u.u32 == IMAGE_NT_SIGNATURE)
128 return KLDR_ERR_PE_NOT_SUPPORTED;
129 else if (u.u32 == IMAGE_ELF_SIGNATURE)
130 return KLDR_ERR_ELF_NOT_SUPPORTED;
131 return KLDR_ERR_UNKNOWN_FORMAT;
132}
133
134
135/**
136 * Open a executable image using the native loader (if any).
137 *
138 * @returns 0 on success and *ppMod pointing to a module instance.
139 * On failure, a non-zero OS specific error code is returned.
140 * @param pszFilename The filename to open.
141 * @param ppMod Where to store the module handle.
142 */
143int kLdrModOpenNative(const char *pszFilename, PPKLDRMOD ppMod)
144{
145#ifdef __OS2__
146
147 //DosLoadModule()
148#elif defined(__WIN__)
149
150#else
151# error "Port me"
152#endif
153 return -1;
154}
155
156
157
158/**
159 * Closes an open module.
160 *
161 * The caller is responsible for calling kLdrModUnmap() and kLdrFreeTLS()
162 * before closing the module.
163 *
164 * @returns 0 on success,
165 * @param pMod The module.
166 */
167int kLdrModClose(PKLDRMOD pMod)
168{
169 //pMod->
170 return -1;
171}
172
173
174
175/**
176 * Queries a symbol by name or ordinal number.
177 *
178 * @returns 0 and *puValue and *pfKind on success.
179 * KLDR_ERR_SYMBOL_NOT_FOUND is returned if the symbol wasn't found.
180 * Other failures could stem from bad executable format failures,
181 * read failure in case pvBits isn't specified and no mapping should be used.
182 * @param pMod The module.
183 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
184 * This can be used by some module interpreters to reduce memory consumption.
185 * @param BaseAddress The module base address to use when calculating the symbol value.
186 * There are two special values that can be used:
187 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
188 * @param uSymbol The symbol ordinal. (optional)
189 * @param pszSymbol The symbol name. (optional)
190 * @param puValue Where to store the symbol value. (optional)
191 * @param pfKind Where to store the symbol kind. (optional)
192 */
193int kLdrModQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t uSymbol,
194 const char *pszSymbol, PKLDRADDR puValue, uint32_t *pfKind)
195{
196 return -1;
197}
198
199
200/**
201 * Enumerate the symbols in the module.
202 *
203 * @returns 0 on success and non-zero a status code on failure.
204 * @param pMod The module which symbols should be enumerated.
205 * @param fFlags The enumeration flags. A combination of the KLDRMOD_ENUM_SYMS_FLAGS_* \#defines.
206 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
207 * This can be used by some module interpreters to reduce memory consumption.
208 * @param BaseAddress The module base address to use when calculating the symbol values.
209 * There are two special values that could be can:
210 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
211 * @param pfnCallback The enumeration callback function.
212 * @param pvUser The user argument to the callback function.
213 */
214int kLdrModEnumSymbols(PKLDRMOD pMod, uint32_t fFlags, const void *pvBits, KLDRADDR BaseAddress,
215 PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
216{
217 return -1;
218}
219
220
221/**
222 * Get the name of an import module by ordinal number.
223 *
224 * @returns 0 and name in pszName on success.
225 * On buffer overruns KLDR_ERR_BUFFER_OVERFLOW will be returned.
226 * On other failures and appropriate error code is returned.
227 * @param pMod The module.
228 * @param pvBits Optional pointer to bits returned by kLdrModGetBits().
229 * This can be used by some module interpreters to reduce memory consumption.
230 * @param iImport The import module ordinal number.
231 * @param pszName Where to store the name.
232 * @param cchName The size of the name buffer.
233 */
234int kLdrModGetImport(PKLDRMOD pMod, void *pvBits, uint32_t iImport, const char *pszName, size_t cchName)
235{
236 return -1;
237}
238
239
240/**
241 * Get the number of import modules.
242 *
243 * @returns The number of import modules. -1 if something really bad happens.
244 * @param pMod The module.
245 * @param pvBits Optional pointer to bits returned by kLdrModGetBits().
246 * This can be used by some module interpreters to reduce memory consumption.
247 */
248int32_t kLdrModNumberOfImports(PKLDRMOD pMod, void *pvBits)
249{
250 return -1;
251}
252
253
254/**
255 * Checks if this module can be executed by the specified arch+cpu.
256 *
257 * @returns 0 if it can, KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE if it can't.
258 * Other failures may occur and cause other return values.
259 * @param pMod The module.
260 * @param pvBits Optional pointer to bits returned by kLdrModGetBits().
261 * This can be used by some module interpreters to reduce memory consumption.
262 */
263int kLdrModCanExecuteOn(PKLDRMOD pMod, void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu)
264{
265 //return KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
266 return 0;
267}
268
269
270/**
271 * Gets the image stack info.
272 *
273 * @returns 0 on success, non-zero on failure.
274 * @param pMod
275 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
276 * This can be used by some module interpreters to reduce memory consumption.
277 * @param BaseAddress The module base address to use when calculating the stack address.
278 * There are two special values that can be used:
279 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
280 * @param pStackInfo The stack information.
281 */
282int kLdrModGetStackInfo(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
283{
284 return -1;
285}
286
287
288/**
289 * Queries the main entrypoint of the module.
290 *
291 * Only executable are supposed to have an main entrypoint, though some object and DLL
292 * formats will also allow this.
293 *
294 * @returns 0 and *pMainEPAddress on success. Non-zero status code on failure.
295 * @param pMod The module.
296 * @param pvBits Optional pointer to bits returned by kLdrModGetBits() currently located at BaseAddress.
297 * This can be used by some module interpreters to reduce memory consumption.
298 * @param BaseAddress The module base address to use when calculating the entrypoint address.
299 * There are two special values that can be used:
300 * KLDRMOD_BASEADDRESS_LINK and KLDRMOD_BASEADDRESS_MAP.
301 * @param pMainEPAddress Where to store the entry point address.
302 */
303int kLdrModQueryMainEntrypoint(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
304{
305 return 1;
306}
307
308
309/**
310 * Get the size of the mapped module.
311 *
312 * @returns The size of the mapped module (in bytes).
313 * @param pMod The module.
314 */
315size_t kLdrModSize(PKLDRMOD pMod)
316{
317 return 0;
318}
319
320
321/**
322 * Maps the module into the memory of the caller.
323 *
324 * On success the actual addresses for the segments can be found in MapAddress
325 * member of each segment in the segment array.
326 *
327 * @returns 0 on success, non-zero OS or kLdr status code on failure.
328 * @param pMod The module to be mapped.
329 * @remark kLdr only supports one mapping at a time of a module.
330 */
331int kLdrModMap(PKLDRMOD pMod)
332{
333 return -1;
334}
335
336
337/**
338 * Unmaps a module previously mapped by kLdrModMap().
339 *
340 * @returns 0 on success, non-zero OS or kLdr status code on failure.
341 * @param pMod The module to unmap.
342 */
343int kLdrModUnmap(PKLDRMOD pMod)
344{
345 return -1;
346}
347
348
349/**
350 * Allocates Thread Local Storage for module mapped by kLdrModMap().
351 *
352 * Calling kLdrModAllocTLS() more than once without calling kLdrModFreeTLS()
353 * between each invocation is not supported.
354 *
355 * @returns 0 on success, non-zero OS or kLdr status code on failure.
356 * @param pMod The module.
357 */
358int kLdrModAllocTLS(PKLDRMOD pMod)
359{
360 return 0;
361}
362
363
364/**
365 * Frees Thread Local Storage previously allocated by kLdrModAllocTLS().
366 *
367 * The caller is responsible for only calling kLdrModFreeTLS() once
368 * after calling kLdrModAllocTLS().
369 *
370 * @returns 0 on success, non-zero OS or kLdr status code on failure.
371 * @param pMod The module.
372 */
373void kLdrModFreeTLS(PKLDRMOD pMod)
374{
375}
376
377
378/**
379 * Reloads all dirty pages in a module previously mapped by kLdrModMap().
380 *
381 * The module interpreter may omit code pages if it can safely apply code
382 * fixups again in a subsequent kLdrModFixupMapping() call.
383 *
384 * The caller is responsible for freeing TLS before calling this function.
385 *
386 * @returns 0 on success, non-zero OS or kLdr status code on failure.
387 * @param pMod The module.
388 */
389int kLdrModReload(PKLDRMOD pMod)
390{
391 return -1;
392}
393
394
395/**
396 * Fixup the mapping made by kLdrModMap().
397 *
398 * The caller is only responsible for not calling this function more than
399 * once without doing kLDrModReload() inbetween.
400 *
401 * @returns 0 on success, non-zero OS or kLdr status code on failure.
402 * @param pMod The module.
403 * @param pfnGetImport The callback for resolving external (imported) symbols.
404 * @param pvUser The callback user argument.
405 */
406int kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
407{
408 return -1;
409}
410
411
412/**
413 * Call the module initializiation function of a mapped module (if any).
414 *
415 * @returns 0 on success or no init function, non-zero on init function failure or invalid pMod.
416 * @param pMod The module.
417 */
418int kLdrModCallInit(PKLDRMOD pMod)
419{
420 return -1;
421}
422
423
424/**
425 * Call the module termination function of a mapped module (if any).
426 *
427 * @returns 0 on success or no term function, non-zero on invalid pMod.
428 * @param pMod The module.
429 *
430 * @remark Termination function failure will be ignored by the module interpreter.
431 */
432int kLdrModCallTerm(PKLDRMOD pMod)
433{
434 return 0;
435}
436
437
438/**
439 * Call the thread attach or detach function of a mapped module (if any).
440 *
441 * @returns 0 on success or no attach/detach function, non-zero on attach failure or invalid pMod.
442 * @param pMod The module.
443 *
444 * @remark Detach function failure will be ignored by the module interpreter.
445 */
446int kLdrModCallThread(PKLDRMOD pMod, unsigned fAttachingOrDetaching)
447{
448 return 0;
449}
450
451
452/**
453 * Gets the module bits.
454 *
455 * The module interpreter will fill a mapping allocated by the caller with the
456 * module bits reallocated to the specified address.
457 *
458 * @returns 0 on succes, non-zero OS or kLdr status code on failure.
459 * @param pMod The module.
460 * @param pvBits Where to put the bits.
461 * @param BaseAddress The base address that should correspond to the first byte in pvBits
462 * upon return.
463 * @param pfnGetImport The callback ufor resolving external (imported) symbols.
464 * @param pvUser The callback user argument.
465 */
466int kLdrModGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
467{
468 return -1;
469}
470
471
472/**
473 * Relocates the module bits previously obtained by kLdrModGetBits().
474 *
475 * @returns 0 on succes, non-zero OS or kLdr status code on failure.
476 * @param pMod The module.
477 * @param pvBits Where to put the bits.
478 * @param NewBaseAddress The new base address.
479 * @param OldBaseAddress The old base address (i.e. the one specified to kLdrModGetBits() or as
480 * NewBaseAddressto the previous kLdrModRelocateBits() call).
481 * @param pfnGetImport The callback ufor resolving external (imported) symbols.
482 * @param pvUser The callback user argument.
483 */
484int kLdrModRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
485 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
486{
487 return -1;
488}
489
490
491
Note: See TracBrowser for help on using the repository browser.