source: trunk/kLdr/kLdr.h@ 2944

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

split up kLdrHlp.c and kLdr.c to make it more flexible (like using the module interpreters without the dynamic loader bit and similar).

  • Property svn:keywords set to Id
File size: 51.3 KB
Line 
1/* $Id: kLdr.h 2944 2007-01-13 15:55:40Z bird $ */
2/** @file
3 *
4 * kLdr - The Dynamic Loader.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird@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#ifndef __kLdr_h__
28#define __kLdr_h__
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34/*
35 * kLdr depend on size_t, [u]intNN_t, [u]intptr_t and some related constants.
36 * If KLDR_NO_KLDR_H_INCLUDES is defined, these has already been defined.
37 */
38#ifndef KLDR_NO_KLDR_H_INCLUDES
39# include <sys/types.h>
40# include <stddef.h>
41# ifdef _MSC_VER
42 typedef signed char int8_t;
43 typedef unsigned char uint8_t;
44 typedef signed short int16_t;
45 typedef unsigned short uint16_t;
46 typedef signed int int32_t;
47 typedef unsigned int uint32_t;
48 typedef signed __int64 int64_t;
49 typedef unsigned __int64 uint64_t;
50 typedef int64_t intmax_t;
51 typedef uint64_t uintmax_t;
52# define UINT16_C(c) (c ## U)
53# define UINT32_C(c) (c ## U)
54# define UINT64_C(c) (c ## ULL)
55# else
56# include <stdint.h>
57# endif
58#endif /* !KLDR_NO_KLDR_H_INCLUDES */
59
60
61/** @defgroup grp_kLdrRdr kLdrRdr - The file provider
62 * @{ */
63
64/** The kLdr address type. */
65typedef uint64_t KLDRADDR;
66/** Pointer to a kLdr address. */
67typedef KLDRADDR *PKLDRADDR;
68/** Pointer to a const kLdr address. */
69typedef const KLDRADDR *PCKLDRADDR;
70
71/** NIL address. */
72#define NIL_KLDRADDR (~(uint64_t)0)
73
74/** @def PRI_KLDRADDR
75 * printf format type. */
76#ifdef _MSC_VER
77# define PRI_KLDRADDR "I64x"
78#else
79# define PRI_KLDRADDR "llx"
80#endif
81
82
83/** The kLdr size type. */
84typedef uint64_t KLDRSIZE;
85/** Pointer to a kLdr size. */
86typedef KLDRSIZE *PKLDRSIZE;
87/** Pointer to a const kLdr size. */
88typedef const KLDRSIZE *PCKLDRSIZE;
89
90/** @def PRI_KLDRSIZE
91 * printf format type. */
92#ifdef _MSC_VER
93# define PRI_KLDRSIZE "I64x"
94#else
95# define PRI_KLDRSIZE "llx"
96#endif
97
98/** Pointer to a loader segment. */
99typedef struct KLDRSEG *PKLDRSEG;
100/** Pointer to a loader segment. */
101typedef const struct KLDRSEG *PCKLDRSEG;
102
103
104
105
106/**
107 * Memory Mapping Protections.
108 *
109 * @remark Shared segments can be mapped using the non copy-on-write variant.
110 * (Normally the copy-on-write variant is used because changes must
111 * be private and not shared with other processes mapping the file.)
112 */
113typedef enum KLDRPROT
114{
115 /** The usual invalid 0. */
116 KLDRPROT_INVALID = 0,
117 /** No access (page not present). */
118 KLDRPROT_NOACCESS,
119 /** Read only. */
120 KLDRPROT_READONLY,
121 /** Read & write. */
122 KLDRPROT_READWRITE,
123 /** Read & copy on write. */
124 KLDRPROT_WRITECOPY,
125 /** Execute only. */
126 KLDRPROT_EXECUTE,
127 /** Execute & read. */
128 KLDRPROT_EXECUTE_READ,
129 /** Execute, read & write. */
130 KLDRPROT_EXECUTE_READWRITE,
131 /** Execute, read & copy on write. */
132 KLDRPROT_EXECUTE_WRITECOPY,
133 /** The usual end value. (exclusive) */
134 KLDRPROT_END,
135 /** Blow the type up to 32-bits. */
136 KLDRPROT_32BIT_HACK = 0x7fffffff
137} KLDRPROT;
138
139
140/** Pointer to a file provider instance core. */
141typedef struct KLDRRDR *PKLDRRDR;
142/** Pointer to a file provider instance core pointer. */
143typedef struct KLDRRDR **PPKLDRRDR;
144
145/**
146 * File provider instance operations.
147 */
148typedef struct KLDRRDROPS
149{
150 /** The name of this file provider. */
151 const char *pszName;
152 /** Pointer to the next file provider. */
153 const struct KLDRRDROPS *pNext;
154
155 /** Try create a new file provider instance.
156 *
157 * @returns 0 on success, OS specific error code on failure.
158 * @param ppRdr Where to store the file provider instance.
159 * @param pszFilename The filename to open.
160 */
161 int (* pfnCreate)( PPKLDRRDR ppRdr, const char *pszFilename);
162 /** Destroy the file provider instance.
163 *
164 * @returns 0 on success, OS specific error code on failure.
165 * On failure, the file provider instance will be in an indeterminate state - don't touch it!
166 * @param pRdr The file provider instance.
167 */
168 int (* pfnDestroy)( PKLDRRDR pRdr);
169 /** @copydoc kLdrRdrRead */
170 int (* pfnRead)( PKLDRRDR pRdr, void *pvBuf, size_t cb, off_t off);
171 /** @copydoc kLdrRdrAllMap */
172 int (* pfnAllMap)( PKLDRRDR pRdr, const void **ppvBits);
173 /** @copydoc kLdrRdrAllUnmap */
174 int (* pfnAllUnmap)(PKLDRRDR pRdr, const void *pvBits);
175 /** @copydoc kLdrRdrSize */
176 off_t (* pfnSize)( PKLDRRDR pRdr);
177 /** @copydoc kLdrRdrTell */
178 off_t (* pfnTell)( PKLDRRDR pRdr);
179 /** @copydoc kLdrRdrName */
180 const char * (* pfnName)(PKLDRRDR pRdr);
181 /** @copydoc kLdrRdrPageSize */
182 size_t (* pfnPageSize)(PKLDRRDR pRdr);
183 /** @copydoc kLdrRdrMap */
184 int (* pfnMap)( PKLDRRDR pRdr, void **ppvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fFixed);
185 /** @copydoc kLdrRdrRefresh */
186 int (* pfnRefresh)( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments);
187 /** @copydoc kLdrRdrProtect */
188 int (* pfnProtect)( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fUnprotectOrProtect);
189 /** @copydoc kLdrRdrUnmap */
190 int (* pfnUnmap)( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments);
191 /** @copydoc kLdrRdrDone */
192 void (* pfnDone)( PKLDRRDR pRdr);
193 /** The usual non-zero dummy that makes sure we've initialized all members. */
194 uint32_t u32Dummy;
195} KLDRRDROPS;
196/** Pointer to file provider operations. */
197typedef KLDRRDROPS *PKLDRRDROPS;
198/** Pointer to const file provider operations. */
199typedef const KLDRRDROPS *PCKLDRRDROPS;
200
201
202/**
203 * File provider instance core.
204 */
205typedef struct KLDRRDR
206{
207 /** Magic number (KLDRRDR_MAGIC). */
208 uint32_t u32Magic;
209 /** Pointer to the file provider operations. */
210 PCKLDRRDROPS pOps;
211} KLDRRDR;
212
213/** The magic for KLDRRDR::u32Magic. (Katsu Aki (Katsuaki Nakamura)) */
214#define KLDRRDR_MAGIC 0x19610919
215
216void kLdrRdrAddProvider(PKLDRRDROPS pAdd);
217
218int kLdrRdrOpen( PPKLDRRDR ppRdr, const char *pszFilename);
219int kLdrRdrClose( PKLDRRDR pRdr);
220int kLdrRdrRead( PKLDRRDR pRdr, void *pvBuf, size_t cb, off_t off);
221int kLdrRdrAllMap( PKLDRRDR pRdr, const void **ppvBits);
222int kLdrRdrAllUnmap(PKLDRRDR pRdr, const void *pvBits);
223off_t kLdrRdrSize( PKLDRRDR pRdr);
224off_t kLdrRdrTell( PKLDRRDR pRdr);
225const char *kLdrRdrName(PKLDRRDR pRdr);
226size_t kLdrRdrPageSize(PKLDRRDR pRdr);
227int kLdrRdrMap( PKLDRRDR pRdr, void **ppvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fFixed);
228int kLdrRdrRefresh( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments);
229int kLdrRdrProtect( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fUnprotectOrProtect);
230int kLdrRdrUnmap( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments);
231void kLdrRdrDone( PKLDRRDR pRdr);
232
233/** @} */
234
235
236
237/** @defgroup grp_kLdrMod kLdrMod - The executable image intepreter
238 * @{ */
239
240/**
241 * CPU Architecture.
242 * @todo Double check the non intel architectures.
243 */
244typedef enum KLDRARCH
245{
246 /** The usual invalid one. */
247 KLDRARCH_INVALID = 0,
248 /** Clone or Intel 16-bit x86. */
249 KLDRARCH_X86_16,
250 /** Clone or Intel 32-bit x86. */
251 KLDRARCH_X86_32,
252 /** AMD64 (including clones). */
253 KLDRARCH_AMD64,
254 /** Itanic (64-bit). */
255 KLDRARCH_IA64,
256 /** ALPHA (64-bit). */
257 KLDRARCH_ALPHA,
258 /** ALPHA limited to 32-bit. */
259 KLDRARCH_ALPHA_32,
260 /** 32-bit ARM. */
261 KLDRARCH_ARM_32,
262 /** 64-bit ARM. */
263 KLDRARCH_ARM_64,
264 /** 32-bit MIPS. */
265 KLDRARCH_MIPS_32,
266 /** 64-bit MIPS. */
267 KLDRARCH_MIPS_64,
268 /** 32-bit PowerPC. */
269 KLDRARCH_POWERPC_32,
270 /** 64-bit PowerPC. */
271 KLDRARCH_POWERPC_64,
272 /** 32-bit SPARC. */
273 KLDRARCH_SPARC_32,
274 /** 64-bit SPARC. */
275 KLDRARCH_SPARC_64,
276 /** The end of the valid architecture values (exclusive). */
277 KLDRARCH_END,
278 /** Hack to blow the type up to 32-bit. */
279 KLDRARCH_32BIT_HACK = 0x7fffffff
280} KLDRARCH;
281/** Pointer to a CPU architecture type. */
282typedef KLDRARCH *PKLDRARCH;
283
284/**
285 * CPU models.
286 */
287typedef enum KLDRCPU
288{
289 /** The usual invalid cpu. */
290 KLDRCPU_INVALID = 0,
291 /** @name KLDRARCH_X86_16
292 * @{ */
293 KLDRCPU_I8086,
294 KLDRCPU_I8088,
295 KLDRCPU_I80186,
296 KLDRCPU_I80286,
297 KLDRCPU_I386_16,
298 KLDRCPU_I486_16,
299 KLDRCPU_I486SX_16,
300 KLDRCPU_I586_16,
301 KLDRCPU_I686_16,
302 KLDRCPU_P4_16,
303 KLDRCPU_CORE2_16,
304 KLDRCPU_K6_16,
305 KLDRCPU_K7_16,
306 KLDRCPU_K8_16,
307 KLDRCPU_FIRST_X86_16 = KLDRCPU_I8086,
308 KLDRCPU_LAST_X86_16 = KLDRCPU_K8_16,
309 /** @} */
310
311 /** @name KLDRARCH_X86_32
312 * @{ */
313 KLDRCPU_X86_32_BLEND,
314 KLDRCPU_I386,
315 KLDRCPU_I486,
316 KLDRCPU_I486SX,
317 KLDRCPU_I586,
318 KLDRCPU_I686,
319 KLDRCPU_P4,
320 KLDRCPU_CORE2_32,
321 KLDRCPU_K6,
322 KLDRCPU_K7,
323 KLDRCPU_K8_32,
324 KLDRCPU_FIRST_X86_32 = KLDRCPU_I386,
325 KLDRCPU_LAST_X86_32 = KLDRCPU_K8_32,
326 /** @} */
327
328 /** @name KLDRARCH_AMD64
329 * @{ */
330 KLDRCPU_AMD64_BLEND,
331 KLDRCPU_K8,
332 KLDRCPU_P4_64,
333 KLDRCPU_CORE2,
334 KLDRCPU_FIRST_AMD64 = KLDRCPU_K8,
335 KLDRCPU_LAST_AMD64 = KLDRCPU_CORE2,
336 /** @} */
337
338 /** The end of the valid cpu values (exclusive). */
339 KLDRCPU_END,
340 /** Hack to blow the type up to 32-bit. */
341 KLDRCPU_32BIT_HACK = 0x7fffffff
342} KLDRCPU;
343/** Pointer to a CPU type. */
344typedef KLDRCPU *PKLDRCPU;
345
346void kLdrGetArchCpu(PKLDRARCH penmArch, PKLDRCPU penmCpu);
347int kLdrCompareCpus(KLDRARCH enmCodeArch, KLDRCPU enmCodeCpu, KLDRARCH enmArch, KLDRCPU enmCpu);
348
349
350/**
351 * Debug info type (from the loader point of view).
352 */
353typedef enum KLDRDBGINFOTYPE
354{
355 /** The usual invalid enum value. */
356 KLDRDBGINFOTYPE_INVALID = 0,
357 /** Unknown debug info format. */
358 KLDRDBGINFOTYPE_UNKNOWN,
359 /** Stabs. */
360 KLDRDBGINFOTYPE_STABS,
361 /** Debug With Arbitrary Record Format (DWARF). */
362 KLDRDBGINFOTYPE_DWARF,
363 /** Microsoft Codeview debug info. */
364 KLDRDBGINFOTYPE_CODEVIEW,
365 /** Watcom debug info. */
366 KLDRDBGINFOTYPE_WATCOM,
367 /** IBM High Level Language debug info.. */
368 KLDRDBGINFOTYPE_HLL,
369 /** The end of the valid debug info values (exclusive). */
370 KLDRDBGINFOTYPE_END,
371 /** Blow the type up to 32-bit. */
372 KLDRDBGINFOTYPE_32BIT_HACK = 0x7fffffff
373} KLDRDBGINFOTYPE;
374/** Pointer to a kLdr debug info type. */
375typedef KLDRDBGINFOTYPE *PKLDRDBGINFOTYPE;
376
377
378/**
379 * Stack information.
380 */
381typedef struct KLDRSTACKINFO
382{
383 /** The base address of the stack (sub) segment.
384 * Set this to NIL_KLDRADDR if the module doesn't include any stack segment. */
385 KLDRADDR Address;
386 /** The base address of the stack (sub) segment, link address.
387 * Set this to NIL_KLDRADDR if the module doesn't include any stack (sub)segment. */
388 KLDRADDR LinkAddress;
389 /** The stack size of the main thread.
390 * If no stack (sub)segment in the module, this is the stack size of the main thread.
391 * If the module doesn't contain this kind of information this field will be set to 0. */
392 KLDRSIZE cbStack;
393 /** The stack size of non-main threads.
394 * If the module doesn't contain this kind of information this field will be set to 0. */
395 KLDRSIZE cbStackThread;
396} KLDRSTACKINFO;
397/** Pointer to stack information. */
398typedef KLDRSTACKINFO *PKLDRSTACKINFO;
399/** Pointer to const stack information. */
400typedef const KLDRSTACKINFO *PCKLDRSTACKINFO;
401
402
403/**
404 * Loader segment.
405 */
406typedef struct KLDRSEG
407{
408 /** Variable free to use for the kLdr user. */
409 void *pvUser;
410 /** The segment name. (Might not be zero terminated!) */
411 const char *pchName;
412 /** The length of the segment name. */
413 uint32_t cchName;
414 /** The segment protection. */
415 KLDRPROT enmProt;
416 /** The size of the segment. */
417 KLDRSIZE cb;
418 /** The required segment alignment.
419 * The to 0 if the segment isn't supposed to be mapped. */
420 KLDRADDR Alignment;
421 /** The link address.
422 * Set to NIL_KLDRADDR if the segment isn't supposed to be
423 * mapped or if the image doesn't have link addresses. */
424 KLDRADDR LinkAddress;
425 /** File offset of the segment.
426 * Set to -1 if no file backing (like BSS). */
427 off_t offFile;
428 /** Size of the file bits of the segment.
429 * Set to -1 if no file backing (like BSS). */
430 off_t cbFile;
431 /** The relative virtual address when mapped.
432 * Set to NIL_KLDRADDR if the segment isn't supposed to be mapped. */
433 KLDRADDR RVA;
434 /** The size of the segment including the alignment gap up to the next segment when mapped. */
435 size_t cbMapped;
436 /** The address the segment was mapped at by kLdrModMap().
437 * Set to 0 if not mapped. */
438 uintptr_t MapAddress;
439} KLDRSEG;
440
441
442/**
443 * Loader module format.
444 */
445typedef enum KLDRFMT
446{
447 /** The usual invalid 0 format. */
448 KLDRFMT_INVALID = 0,
449 /** The native OS loader. */
450 KLDRFMT_NATIVE,
451 /** The AOUT loader. */
452 KLDRFMT_AOUT,
453 /** The ELF loader. */
454 KLDRFMT_ELF,
455 /** The LX loader. */
456 KLDRFMT_LX,
457 /** The mach-o loader. */
458 KLDRFMT_MACHO,
459 /** The LX loader. */
460 KLDRFMT_PE,
461 /** The end of the valid format values (exclusive). */
462 KLDRFMT_END,
463 /** Hack to blow the type up to 32-bit. */
464 KLDRFMT_32BIT_HACK = 0x7fffffff
465} KLDRFMT;
466
467
468/**
469 * Loader module type.
470 */
471typedef enum KLDRTYPE
472{
473 /** The usual invalid 0 type. */
474 KLDRTYPE_INVALID = 0,
475 /** Object file. */
476 KLDRTYPE_OBJECT,
477 /** Executable module, fixed load address. */
478 KLDRTYPE_EXECUTABLE_FIXED,
479 /** Executable module, relocatable, non-fixed load address. */
480 KLDRTYPE_EXECUTABLE_RELOCATABLE,
481 /** Executable module, position independent code, non-fixed load address. */
482 KLDRTYPE_EXECUTABLE_PIC,
483 /** Shared library, fixed load address.
484 * Typically a system library. */
485 KLDRTYPE_SHARED_LIBRARY_FIXED,
486 /** Shared library, relocatable, non-fixed load address. */
487 KLDRTYPE_SHARED_LIBRARY_RELOCATABLE,
488 /** Shared library, position independent code, non-fixed load address. */
489 KLDRTYPE_SHARED_LIBRARY_PIC,
490 /** DLL that contains no code or data only imports and exports. (Chiefly OS/2.) */
491 KLDRTYPE_FORWARDER_DLL,
492 /** Core or dump. */
493 KLDRTYPE_CORE,
494 /** The end of the valid types values (exclusive). */
495 KLDRTYPE_END,
496 /** Hack to blow the type up to 32-bit. */
497 KLDRTYPE_32BIT_HACK = 0x7fffffff
498} KLDRTYPE;
499
500
501/**
502 * Loader endian indicator.
503 */
504typedef enum KLDRENDIAN
505{
506 /** The usual invalid endian. */
507 KLDRENDIAN_INVALID,
508 /** Little endian. */
509 KLDRENDIAN_LITTLE,
510 /** Bit endian. */
511 KLDRENDIAN_BIG,
512 /** Endianness doesn't have a meaning in the context. */
513 KLDRENDIAN_NA,
514 /** The end of the valid endian values (exclusive). */
515 KLDRENDIAN_END,
516 /** Hack to blow the type up to 32-bit. */
517 KLDRENDIAN_32BIT_HACK = 0x7fffffff
518} KLDRENDIAN;
519
520
521/** Pointer to a module interpreter method table. */
522typedef struct KLDRMODOPS *PKLDRMODOPS;
523/** Pointer to const module interpreter methods table. */
524typedef const struct KLDRMODOPS *PCKLDRMODOPS;
525
526/**
527 * Module interpreter instance.
528 * All members are read only unless you're kLdrMod or the module interpreter.
529 */
530typedef struct KLDRMOD
531{
532 /** Magic number (KLDRMOD_MAGIC). */
533 uint32_t u32Magic;
534 /** The format of this module. */
535 KLDRFMT enmFmt;
536 /** The type of module. */
537 KLDRTYPE enmType;
538 /** The architecture this module was built for. */
539 KLDRARCH enmArch;
540 /** The minium cpu this module was built for.
541 * This might not be accurate, so use kLdrModCanExecuteOn() to check. */
542 KLDRARCH enmCpu;
543 /** The endian used by the module. */
544 KLDRENDIAN enmEndian;
545 /** The filename length (bytes). */
546 uint32_t cchFilename;
547 /** The filename. */
548 const char *pszFilename;
549 /** The module name. */
550 const char *pszName;
551 /** The module name length (bytes). */
552 uint32_t cchName;
553 /** The number of segments in the module. */
554 uint32_t cSegments;
555 /** Pointer to the loader methods.
556 * Not meant for calling directly thru! */
557 PCKLDRMODOPS pOps;
558 /** Pointer to the read instance. (Can be NULL after kLdrModDone().)*/
559 PKLDRRDR pRdr;
560 /** The module data. */
561 void *pvData;
562 /** Segments. (variable size, can be zero) */
563 KLDRSEG aSegments[1];
564} KLDRMOD, *PKLDRMOD, **PPKLDRMOD;
565
566/** The magic for KLDRMOD::u32Magic. (Kosuke Fujishima) */
567#define KLDRMOD_MAGIC 0x19640707
568
569
570/** Special base address value alias for the link address. */
571#define KLDRMOD_BASEADDRESS_LINK (~(KLDRADDR)1)
572/** Special base address value alias for the actual load address (must be mapped). */
573#define KLDRMOD_BASEADDRESS_MAP (~(KLDRADDR)2)
574
575/** Special import module ordinal value used to indicate that there is no
576 * specific module associated with the requested symbol. */
577#define NIL_KLDRMOD_IMPORT (~(uint32_t)0)
578
579/** Special symbol ordinal value used to indicate that the symbol
580 * only has a string name. */
581#define NIL_KLDRMOD_SYM_ORDINAL (~(uint32_t)0)
582
583
584/** @name Load symbol kind flags.
585 * @{ */
586/** The bitness doesn't matter. */
587#define KLDRSYMKIND_NO_BIT 0x00000000
588/** 16-bit symbol. */
589#define KLDRSYMKIND_16BIT 0x00000001
590/** 32-bit symbol. */
591#define KLDRSYMKIND_32BIT 0x00000002
592/** 64-bit symbol. */
593#define KLDRSYMKIND_64BIT 0x00000003
594/** Mask out the bit.*/
595#define KLDRSYMKIND_BIT_MASK 0x00000003
596/** We don't know the type of symbol. */
597#define KLDRSYMKIND_NO_TYPE 0x00000000
598/** The symbol is a code object (method/function/procedure/whateveryouwannacallit). */
599#define KLDRSYMKIND_CODE 0x00000010
600/** The symbol is a data object. */
601#define KLDRSYMKIND_DATA 0x00000020
602/** Mask out the symbol type. */
603#define KLDRSYMKIND_TYPE_MASK 0x00000030
604/** Valid symbol kind mask. */
605#define KLDRSYMKIND_MASK 0x00000033
606/** Weak symbol. */
607#define KLDRSYMKIND_WEAK 0x00000100
608/** Forwarder symbol. */
609#define KLDRSYMKIND_FORWARDER 0x00000200
610/** Request a flat symbol address. */
611#define KLDRSYMKIND_REQ_FLAT 0x00000000
612/** Request a segmented symbol address. */
613#define KLDRSYMKIND_REQ_SEGMENTED 0x40000000
614/** @} */
615
616/** @name kLdrModEnumSymbols flags.
617 * @{ */
618/** Returns ALL kinds of symbols. The default is to only return public/exported symbols. */
619#define KLDRMOD_ENUM_SYMS_FLAGS_ALL 0x00000001
620/** @} */
621
622
623/**
624 * Callback for resolving imported symbols when applying fixups.
625 *
626 * @returns 0 on success and *pValue and *pfKind filled.
627 * @returns Non-zero OS specific or kLdr status code on failure.
628 *
629 * @param pMod The module which fixups are begin applied.
630 * @param iImport The import module ordinal number or NIL_KLDRMOD_IMPORT.
631 * @param iSymbol The symbol ordinal number or NIL_KLDRMOD_SYM_ORDINAL.
632 * @param pchSymbol The symbol name. Can be NULL if iSymbol isn't nil. Doesn't have to be null-terminated.
633 * @param cchSymbol The length of the symbol.
634 * @param pszVersion The symbol version. NULL if not versioned.
635 * @param puValue Where to store the symbol value.
636 * @param pfKind Where to store the symbol kind flags.
637 * @param pvUser The user parameter specified to the relocation function.
638 */
639typedef int FNKLDRMODGETIMPORT(PKLDRMOD pMod, uint32_t iImport, uint32_t iSymbol, const char *pchSymbol, size_t cchSymbol,
640 const char *pszVersion, PKLDRADDR puValue, uint32_t *pfKind, void *pvUser);
641/** Pointer to a import callback. */
642typedef FNKLDRMODGETIMPORT *PFNKLDRMODGETIMPORT;
643
644/**
645 * Symbol enumerator callback.
646 *
647 * @returns 0 if enumeration should continue.
648 * @returns non-zero if the enumeration should stop. This status code will then be returned by kLdrModEnumSymbols().
649 *
650 * @param pMod The module which symbols are being enumerated.s
651 * @param iSymbol The symbol ordinal number or NIL_KLDRMOD_SYM_ORDINAL.
652 * @param pchSymbol The symbol name. This can be NULL if there is a symbol ordinal.
653 * This can also be an empty string if the symbol doesn't have a name
654 * or it's name has been stripped.
655 * Important, this doesn't have to be a null-terminated string.
656 * @param cchSymbol The length of the symbol.
657 * @param pszVersion The symbol version. NULL if not versioned.
658 * @param uValue The symbol value.
659 * @param fKind The symbol kind flags.
660 * @param pvUser The user parameter specified to kLdrModEnumSymbols().
661 */
662typedef int FNKLDRMODENUMSYMS(PKLDRMOD pMod, uint32_t iSymbol, const char *pchSymbol, size_t cchSymbol, const char *pszVersion,
663 KLDRADDR uValue, uint32_t fKind, void *pvUser);
664/** Pointer to a symbol enumerator callback. */
665typedef FNKLDRMODENUMSYMS *PFNKLDRMODENUMSYMS;
666
667/**
668 * Debug info enumerator callback.
669 *
670 * @returns 0 to continue the enumeration.
671 * @returns non-zero if the enumeration should stop. This status code will then be returned by kLdrModEnumDbgInfo().
672 *
673 * @param pMod The module.
674 * @param iDbgInfo The debug info ordinal number / id.
675 * @param enmType The debug info type.
676 * @param iMajorVer The major version number of the debug info format. -1 if unknow - implies invalid iMinorVer.
677 * @param iMinorVer The minor version number of the debug info format. -1 when iMajorVer is -1.
678 * @param offFile The file offset *if* this type has one specific location in the executable image file.
679 * This is -1 if there isn't any specific file location.
680 * @param LinkAddress The link address of the debug info if it's loadable. NIL_KLDRADDR if not loadable.
681 * @param cb The size of the debug information. -1 is used if this isn't applicable.
682 * @param pszExtFile This points to the name of an external file containing the debug info.
683 * This is NULL if there isn't any external file.
684 * @param pvUser The user parameter specified to kLdrModEnumDbgInfo.
685 */
686typedef int FNKLDRENUMDBG(PKLDRMOD pMod, uint32_t iDbgInfo, KLDRDBGINFOTYPE enmType, int16_t iMajorVer, int16_t iMinorVer,
687 off_t offFile, KLDRADDR LinkAddress, KLDRSIZE cb, const char *pszExtFile, void *pvUser);
688/** Pointer to a debug info enumerator callback. */
689typedef FNKLDRENUMDBG *PFNKLDRENUMDBG;
690
691/**
692 * Resource enumerator callback.
693 *
694 * @returns 0 to continue the enumeration.
695 * @returns non-zero if the enumeration should stop. This status code will then be returned by kLdrModEnumResources().
696 *
697 * @param pMod The module.
698 * @param idType The resource type id. NIL_KLDRMOD_RSRC_TYPE_ID if no type id.
699 * @param pszType The resource type name. NULL if no type name.
700 * @param idName The resource id. NIL_KLDRMOD_RSRC_NAME_ID if no id.
701 * @param pszName The resource name. NULL if no name.
702 * @param idLang The language id.
703 * @param AddrRsrc The address value for the resource.
704 * @param cbRsrc The size of the resource.
705 * @param pvUser The user parameter specified to kLdrModEnumDbgInfo.
706 */
707typedef int FNKLDRENUMRSRC(PKLDRMOD pMod, uint32_t idType, const char *pszType, uint32_t idName, const char *pszName,
708 uint32_t idLang, KLDRADDR AddrRsrc, KLDRSIZE cbRsrc, void *pvUser);
709/** Pointer to a resource enumerator callback. */
710typedef FNKLDRENUMRSRC *PFNKLDRENUMRSRC;
711
712/** NIL resource name ID. */
713#define NIL_KLDRMOD_RSRC_NAME_ID ( ~(uint32_t)0 )
714/** NIL resource type ID. */
715#define NIL_KLDRMOD_RSRC_TYPE_ID ( ~(uint32_t)0 )
716/** @name Language ID
717 *
718 * Except for the special IDs #defined here, the values are considered
719 * format specific for now since it's only used by the PE resources.
720 *
721 * @{ */
722/** NIL language ID. */
723#define NIL_KLDR_LANG_ID ( ~(uint32_t)0 )
724/** Special language id value for matching any language. */
725#define KLDR_LANG_ID_ANY ( ~(uint32_t)1 )
726/** Special language id value indicating language neutral. */
727#define KLDR_LANG_ID_NEUTRAL ( ~(uint32_t)2 )
728/** Special language id value indicating user default language. */
729#define KLDR_LANG_ID_USER_DEFAULT ( ~(uint32_t)3 )
730/** Special language id value indicating system default language. */
731#define KLDR_LANG_ID_SYS_DEFAULT ( ~(uint32_t)4 )
732/** Special language id value indicating default custom locale. */
733#define KLDR_LANG_ID_CUSTOM_DEFAULT ( ~(uint32_t)5 )
734/** Special language id value indicating unspecified custom locale. */
735#define KLDR_LANG_ID_CUSTOM_UNSPECIFIED ( ~(uint32_t)6 )
736/** Special language id value indicating default custom MUI locale. */
737#define KLDR_LANG_ID_UI_CUSTOM_DEFAULT ( ~(uint32_t)7 )
738/** @} */
739
740
741int kLdrModOpen(const char *pszFilename, PPKLDRMOD ppMod);
742int kLdrModOpenFromRdr(PKLDRRDR pRdr, PPKLDRMOD ppMod);
743int kLdrModOpenNative(const char *pszFilename, PPKLDRMOD ppMod);
744int kLdrModOpenNativeByHandle(uintptr_t uHandle, PPKLDRMOD ppMod);
745int kLdrModClose(PKLDRMOD pMod);
746
747int kLdrModQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t iSymbol,
748 const char *pchSymbol, size_t cchSymbol, const char *pszVersion,
749 PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind);
750int kLdrModEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress,
751 uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
752int kLdrModGetImport(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName);
753int32_t kLdrModNumberOfImports(PKLDRMOD pMod, const void *pvBits);
754int kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu);
755int kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
756int kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
757int kLdrModQueryResource(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType,
758 uint32_t idName, const char *pszName, uint32_t idLang, PKLDRADDR pAddrRsrc, size_t *pcbRsrc);
759int kLdrModEnumResources(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType,
760 uint32_t idName, const char *pszName, uint32_t idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser);
761int kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
762int kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits);
763int kLdrModMostlyDone(PKLDRMOD pMod);
764
765
766/** @name Operations On The Internally Managed Mapping
767 * @{ */
768int kLdrModMap(PKLDRMOD pMod);
769int kLdrModUnmap(PKLDRMOD pMod);
770int kLdrModAllocTLS(PKLDRMOD pMod);
771void kLdrModFreeTLS(PKLDRMOD pMod);
772int kLdrModReload(PKLDRMOD pMod);
773int kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
774int kLdrModCallInit(PKLDRMOD pMod, uintptr_t uHandle);
775int kLdrModCallTerm(PKLDRMOD pMod, uintptr_t uHandle);
776int kLdrModCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching);
777/** @} */
778
779/** @name Operations On The Externally Managed Mappings
780 * @{ */
781KLDRADDR kLdrModSize(PKLDRMOD pMod);
782int kLdrModGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
783int kLdrModRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
784 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
785/** @} */
786
787
788/**
789 * The loader module operation.
790 */
791typedef struct KLDRMODOPS
792{
793 /** The name of this module interpreter. */
794 const char *pszName;
795 /** Pointer to the next module interpreter. */
796 PCKLDRMODOPS pNext;
797
798 /**
799 * Create a loader module instance interpreting the executable image found
800 * in the specified file provider instance.
801 *
802 * @returns 0 on success and *ppMod pointing to a module instance.
803 * On failure, a non-zero OS specific error code is returned.
804 * @param pOps Pointer to the registered method table.
805 * @param pRdr The file provider instance to use.
806 * @param offNewHdr The offset of the new header in MZ files. -1 if not found.
807 * @param ppMod Where to store the module instance pointer.
808 */
809 int (* pfnCreate)(PCKLDRMODOPS pOps, PKLDRRDR pRdr, off_t offNewHdr, PPKLDRMOD ppMod);
810 /**
811 * Destroys an loader module instance.
812 *
813 * The caller is responsible for calling kLdrModUnmap() and kLdrFreeTLS() first.
814 *
815 * @returns 0 on success, non-zero on failure. The module instance state
816 * is unknown on failure, it's best not to touch it.
817 * @param pMod The module.
818 */
819 int (* pfnDestroy)(PKLDRMOD pMod);
820
821 /** @copydoc kLdrModQuerySymbol */
822 int (* pfnQuerySymbol)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t iSymbol,
823 const char *pchSymbol, size_t cchSymbol, const char *pszVersion,
824 PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind);
825 /** @copydoc kLdrModEnumSymbols */
826 int (* pfnEnumSymbols)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t fFlags,
827 PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
828 /** @copydoc kLdrModGetImport */
829 int (* pfnGetImport)(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName);
830 /** @copydoc kLdrModNumberOfImports */
831 int32_t (* pfnNumberOfImports)(PKLDRMOD pMod, const void *pvBits);
832 /** @copydoc kLdrModCanExecuteOn */
833 int (* pfnCanExecuteOn)(PKLDRMOD pMod, const void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu);
834 /** @copydoc kLdrModGetStackInfo */
835 int (* pfnGetStackInfo)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
836 /** @copydoc kLdrModQueryMainEntrypoint */
837 int (* pfnQueryMainEntrypoint)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
838 /** @copydoc kLdrModQueryResource */
839 int (* pfnQueryResource)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType,
840 uint32_t idName, const char *pszName, uint32_t idLang, PKLDRADDR pAddrRsrc, size_t *pcbRsrc);
841 /** @copydoc kLdrModEnumResources */
842 int (* pfnEnumResources)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType,
843 uint32_t idName, const char *pszName, uint32_t idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser);
844 /** @copydoc kLdrModEnumDbgInfo */
845 int (* pfnEnumDbgInfo)(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
846 /** @copydoc kLdrModHasDbgInfo */
847 int (* pfnHasDbgInfo)(PKLDRMOD pMod, const void *pvBits);
848 /** @copydoc kLdrModMap */
849 int (* pfnMap)(PKLDRMOD pMod);
850 /** @copydoc kLdrModUnmap */
851 int (* pfnUnmap)(PKLDRMOD pMod);
852 /** @copydoc kLdrModAllocTLS */
853 int (* pfnAllocTLS)(PKLDRMOD pMod);
854 /** @copydoc kLdrModFreeTLS */
855 void (* pfnFreeTLS)(PKLDRMOD pMod);
856 /** @copydoc kLdrModReload */
857 int (* pfnReload)(PKLDRMOD pMod);
858 /** @copydoc kLdrModFixupMapping */
859 int (* pfnFixupMapping)(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
860 /** @copydoc kLdrModCallInit */
861 int (* pfnCallInit)(PKLDRMOD pMod, uintptr_t uHandle);
862 /** @copydoc kLdrModCallTerm */
863 int (* pfnCallTerm)(PKLDRMOD pMod, uintptr_t uHandle);
864 /** @copydoc kLdrModCallThread */
865 int (* pfnCallThread)(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching);
866 /** @copydoc kLdrModSize */
867 KLDRADDR (* pfnSize)(PKLDRMOD pMod);
868 /** @copydoc kLdrModGetBits */
869 int (* pfnGetBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
870 /** @copydoc kLdrModRelocateBits */
871 int (* pfnRelocateBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
872 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
873 /** @copydoc kLdrModMostlyDone */
874 int (* pfnMostlyDone)(PKLDRMOD pMod);
875 /** Dummy which should be assigned a non-zero value. */
876 uint32_t uEndOfStructure;
877} KLDRMODOPS;
878
879
880/** @} */
881
882
883
884
885/** @defgroup grp_kLdrDyld kLdrDyld - The dynamic loader
886 * @{ */
887
888/** The handle to a dynamic loader module. */
889typedef struct KLDRDYLDMOD *HKLDRMOD;
890/** Pointer to the handle to a dynamic loader module. */
891typedef HKLDRMOD *PHKLDRMOD;
892/** NIL handle value. */
893#define NIL_HKLDRMOD ((HKLDRMOD)0)
894
895
896/**
897 * File search method.
898 *
899 * In addition to it's own way of finding files, kLdr emulates
900 * the methods employed by the most popular systems.
901 */
902typedef enum KLDRDYLDSEARCH
903{
904 /** The usual invalid file search method. */
905 KLDRDYLD_SEARCH_INVALID = 0,
906 /** Uses the kLdr file search method.
907 * @todo invent me. */
908 KLDRDYLD_SEARCH_KLDR,
909 /** Use the emulation closest to the host system. */
910 KLDRDYLD_SEARCH_HOST,
911 /** Emulate the OS/2 file search method.
912 * On non-OS/2 systems, BEGINLIBPATH, LIBPATH, ENDLIBPATH and LIBPATHSTRICT are
913 * taken form the environment. */
914 KLDRDYLD_SEARCH_OS2,
915 /** Emulate the standard window file search method. */
916 KLDRDYLD_SEARCH_WINDOWS,
917 /** Emulate the alternative window file search method. */
918 KLDRDYLD_SEARCH_WINDOWS_ALTERED,
919 /** Emulate the most common UNIX file search method. */
920 KLDRDYLD_SEARCH_UNIX_COMMON,
921 /** End of the valid file search method values. */
922 KLDRDYLD_SEARCH_END,
923 /** Hack to blow the type up to 32-bit. */
924 KLDRDYLD_SEARCH_32BIT_HACK = 0x7fffffff
925} KLDRDYLDSEARCH;
926
927/** @name kLdrDyldLoad and kLdrDyldFindByName flags.
928 * @{ */
929/** The symbols in the module should be loaded into the global unix namespace.
930 * If not specified, the symbols are local and can only be referenced directly. */
931#define KLDRYDLD_LOAD_FLAGS_GLOBAL_SYMBOLS 0x00000001
932/** The symbols in the module should be loaded into the global unix namespace and
933 * it's symbols should take precedence over all currently loaded modules.
934 * This implies KLDRYDLD_LOAD_FLAGS_GLOBAL_SYMBOLS. */
935#define KLDRYDLD_LOAD_FLAGS_DEEP_SYMBOLS 0x00000002
936/** The module shouldn't be found by a global module search.
937 * If not specified, the module can be found by unspecified module searches,
938 * typical used when loading import/dep modules. */
939#define KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE 0x00000004
940/** Do a recursive initialization calls instead of defering them to the outermost call. */
941#define KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT 0x00000008
942/** We're loading the executable module.
943 * @internal */
944#define KLDRDYLD_LOAD_FLAGS_EXECUTABLE 0x40000000
945/** @} */
946
947
948int kLdrDyldLoad(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch,
949 unsigned fFlags, PHKLDRMOD phMod, char *pszErr, size_t cchErr);
950int kLdrDyldUnload(HKLDRMOD hMod);
951int kLdrDyldFindByName(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch,
952 unsigned fFlags, PHKLDRMOD phMod);
953int kLdrDyldFindByAddress(uintptr_t Address, PHKLDRMOD phMod, uint32_t *piSegment, uintptr_t *poffSegment);
954int kLdrDyldGetName(HKLDRMOD hMod, char *pszName, size_t cchName);
955int kLdrDyldGetFilename(HKLDRMOD hMod, char *pszFilename, size_t cchFilename);
956int kLdrDyldQuerySymbol(HKLDRMOD hMod, uint32_t uSymbolOrdinal, const char *pszSymbolName,
957 const char *pszSymbolVersion, uintptr_t *pValue, uint32_t *pfKind);
958int kLdrDyldQueryResource(HKLDRMOD hMod, uint32_t idType, const char *pszType, uint32_t idName,
959 const char *pszName, uint32_t idLang, void **pvRsrc, size_t *pcbRsrc);
960int kLdrDyldEnumResources(HKLDRMOD hMod, uint32_t idType, const char *pszType, uint32_t idName,
961 const char *pszName, uint32_t idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser);
962
963/** @name OS/2 like API
964 * @{ */
965#if defined(__OS2__)
966# define KLDROS2API _System
967#else
968# define KLDROS2API
969#endif
970int kLdrDosLoadModule(char *pszObject, size_t cbObject, const char *pszModule, PHKLDRMOD phMod);
971int kLdrDosFreeModule(HKLDRMOD hMod);
972int kLdrDosQueryModuleHandle(const char *pszModname, PHKLDRMOD phMod);
973int kLdrDosQueryModuleName(HKLDRMOD hMod, size_t cchName, char *pszName);
974int kLdrDosQueryProcAddr(HKLDRMOD hMod, uint32_t iOrdinal, const char *pszProcName, void **ppvProcAddr);
975int kLdrDosQueryProcType(HKLDRMOD hMod, uint32_t iOrdinal, const char *pszProcName, uint32_t *pfProcType);
976int kLdrDosQueryModFromEIP(PHKLDRMOD phMod, uint32_t *piObject, size_t cbName, char *pszName, uintptr_t *poffObject, uintptr_t ulEIP);
977int kLdrDosReplaceModule(const char *pszOldModule, const char *pszNewModule, const char *pszBackupModule);
978int kLdrDosGetResource(HKLDRMOD hMod, uint32_t idType, uint32_t idName, void **pvResAddr);
979int kLdrDosQueryResourceSize(HKLDRMOD hMod, uint32_t idType, uint32_t idName, uint32_t *pcb);
980int kLdrDosFreeResource(void *pvResAddr);
981/** @} */
982
983/** @name POSIX like API
984 * @{ */
985HKLDRMOD kLdrDlOpen(const char *pszLibrary, int fFlags);
986const char *kLdrDlError(void);
987void * kLdrDlSym(HKLDRMOD hMod, const char *pszSymbol);
988int kLdrDlClose(HKLDRMOD hMod);
989/** @todo GNU extensions */
990/** @} */
991
992/** @name Win32 like API
993 * @{ */
994#if defined(_MSC_VER)
995# define KLDRWINAPI __stdcall
996#else
997# define KLDRWINAPI
998#endif
999HKLDRMOD KLDRWINAPI kLdrWLoadLibrary(const char *pszFilename);
1000HKLDRMOD KLDRWINAPI kLdrWLoadLibraryEx(const char *pszFilename, void *hFileReserved, uint32_t fFlags);
1001uint32_t KLDRWINAPI kLdrWGetModuleFileName(HKLDRMOD hMod, char *pszModName, size_t cchModName);
1002HKLDRMOD KLDRWINAPI kLdrWGetModuleHandle(const char *pszFilename);
1003int KLDRWINAPI kLdrWGetModuleHandleEx(uint32_t fFlags, const char *pszFilename, HKLDRMOD hMod);
1004void * KLDRWINAPI kLdrWGetProcAddress(HKLDRMOD hMod, const char *pszProcName);
1005uint32_t KLDRWINAPI kLdrWGetDllDirectory(size_t cchDir, char *pszDir);
1006int KLDRWINAPI kLdrWSetDllDirectory(const char *pszDir);
1007int KLDRWINAPI kLdrWFreeLibrary(HKLDRMOD hMod);
1008int KLDRWINAPI kLdrWDisableThreadLibraryCalls(HKLDRMOD hMod);
1009
1010/** The handle to a resource that's been found. */
1011typedef struct KLDRWRSRCFOUND *HKLDRWRSRCFOUND;
1012/** The handle to a loaded resource. */
1013typedef struct KLDRWRSRCLOADED *HKLDRWRSRCLOADED;
1014HKLDRWRSRCFOUND KLDRWINAPI kLdrWFindResource(HKLDRMOD hMod, const char *pszType, const char *pszName);
1015HKLDRWRSRCFOUND KLDRWINAPI kLdrWFindResourceEx(HKLDRMOD hMod, const char *pszType, const char *pszName, uint16_t idLang);
1016uint32_t KLDRWINAPI kLdrWSizeofResource(HKLDRMOD hMod, HKLDRWRSRCFOUND hFoundRsrc);
1017HKLDRWRSRCLOADED KLDRWINAPI kLdrWLoadResource(HKLDRMOD hMod, HKLDRWRSRCFOUND hFoundRsrc);
1018void *KLDRWINAPI kLdrWLockResource(HKLDRMOD hMod, HKLDRWRSRCLOADED hLoadedRsrc);
1019int KLDRWINAPI kLdrWFreeResource(HKLDRMOD hMod, HKLDRWRSRCLOADED hLoadedRsrc);
1020
1021typedef int (KLDRWINAPI *PFNKLDRWENUMRESTYPE)(HKLDRMOD hMod, const char *pszType, uintptr_t uUser);
1022int KLDRWINAPI kLdrWEnumResourceTypes(HKLDRMOD hMod, PFNKLDRWENUMRESTYPE pfnEnum, uintptr_t uUser);
1023int KLDRWINAPI kLdrWEnumResourceTypesEx(HKLDRMOD hMod, PFNKLDRWENUMRESTYPE pfnEnum, uintptr_t uUser, uint32_t fFlags, uint16_t idLang);
1024
1025typedef int (KLDRWINAPI *PFNKLDRWENUMRESNAME)(HKLDRMOD hMod, const char *pszType, char *pszName, uintptr_t uUser);
1026int KLDRWINAPI kLdrWEnumResourceNames(HKLDRMOD hMod, const char *pszType, PFNKLDRWENUMRESNAME pfnEnum, uintptr_t uUser);
1027int KLDRWINAPI kLdrWEnumResourceNamesEx(HKLDRMOD hMod, const char *pszType, PFNKLDRWENUMRESNAME pfnEnum, uintptr_t uUser, uint32_t fFlags, uint16_t idLang);
1028
1029typedef int (KLDRWINAPI *PFNKLDRWENUMRESLANG)(HKLDRMOD hMod, const char *pszType, const char *pszName, uint16_t idLang, uintptr_t uUser);
1030int KLDRWINAPI kLdrWEnumResourceLanguages(HKLDRMOD hMod, const char *pszType, const char *pszName, PFNKLDRWENUMRESLANG pfnEnum, uintptr_t uUser);
1031int KLDRWINAPI kLdrWEnumResourceLanguagesEx(HKLDRMOD hMod, const char *pszType, const char *pszName,
1032 PFNKLDRWENUMRESLANG pfnEnum, uintptr_t uUser, uint32_t fFlags, uint16_t idLang);
1033/** @} */
1034
1035
1036/** @name Process Bootstrapping
1037 * @{ */
1038
1039/**
1040 * Argument package from the stub.
1041 */
1042typedef struct KLDREXEARGS
1043{
1044 /** Load & search flags, some which will become defaults. */
1045 uint32_t fFlags;
1046 /** The default search method. */
1047 KLDRDYLDSEARCH enmSearch;
1048 /** The executable file that the stub is supposed to load. */
1049 char szExecutable[260];
1050 /** The default prefix used when searching for DLLs. */
1051 char szDefPrefix[16];
1052 /** The default suffix used when searching for DLLs. */
1053 char szDefSuffix[16];
1054 /** The LD_LIBRARY_PATH prefix for the process.. */
1055 char szLibPath[4096 - sizeof(uint32_t) - sizeof(KLDRDYLDSEARCH) - 16 - 16 - 260];
1056} KLDREXEARGS, *PKLDREXEARGS;
1057/** Pointer to a const argument package from the stub. */
1058typedef const KLDREXEARGS *PCKLDREXEARGS;
1059
1060void kLdrLoadExe(PCKLDREXEARGS pArgs, void *pvOS);
1061
1062/** @} */
1063
1064/** @} */
1065
1066
1067/** @defgroup grp_kLdrErr kLdr Status Codes
1068 * kLdr uses a mix of native status codes and it's own status codes.
1069 * A status code of 0 means success, all other status codes means failure.
1070 * @{
1071 */
1072#ifdef __OS2__
1073# define KLDR_ERR_BASE 420000
1074#elif defined(__WIN__)
1075# define KLDR_ERR_BASE 420000
1076#else
1077# error "port me"
1078#endif
1079/** The image format is unknown. */
1080#define KLDR_ERR_UNKNOWN_FORMAT (KLDR_ERR_BASE + 0)
1081/** The MZ image format isn't supported by this kLdr build. */
1082#define KLDR_ERR_MZ_NOT_SUPPORTED (KLDR_ERR_BASE + 1)
1083/** The NE image format isn't supported by this kLdr build. */
1084#define KLDR_ERR_NE_NOT_SUPPORTED (KLDR_ERR_BASE + 2)
1085/** The LX image format isn't supported by this kLdr build. */
1086#define KLDR_ERR_LX_NOT_SUPPORTED (KLDR_ERR_BASE + 3)
1087/** The LE image format isn't supported by this kLdr build. */
1088#define KLDR_ERR_LE_NOT_SUPPORTED (KLDR_ERR_BASE + 4)
1089/** The PE image format isn't supported by this kLdr build. */
1090#define KLDR_ERR_PE_NOT_SUPPORTED (KLDR_ERR_BASE + 5)
1091/** The ELF image format isn't supported by this kLdr build. */
1092#define KLDR_ERR_ELF_NOT_SUPPORTED (KLDR_ERR_BASE + 6)
1093/** The mach-o image format isn't supported by this kLdr build. */
1094#define KLDR_ERR_MACHO_NOT_SUPPORTED (KLDR_ERR_BASE + 7)
1095/** The mach-o image format isn't supported by this kLdr build. */
1096#define KLDR_ERR_AOUT_NOT_SUPPORTED (KLDR_ERR_BASE + 8)
1097
1098/** Invalid parameter to a kLdr API. */
1099#define KLDR_ERR_INVALID_PARAMETER (KLDR_ERR_BASE + 32)
1100/** Invalid handle parameter to a kLdr API. */
1101#define KLDR_ERR_INVALID_HANDLE (KLDR_ERR_BASE + 33)
1102/** The module wasn't loaded dynamically. */
1103#define KLDR_ERR_NOT_LOADED_DYNAMICALLY (KLDR_ERR_BASE + 34)
1104/** The module wasn't found. */
1105#define KLDR_ERR_MODULE_NOT_FOUND (KLDR_ERR_BASE + 35)
1106/** A prerequisit module wasn't found. */
1107#define KLDR_ERR_PREREQUISITE_MODULE_NOT_FOUND (KLDR_ERR_BASE + 36)
1108/** The module is being terminated and can therefore not be loaded. */
1109#define KLDR_ERR_MODULE_TERMINATING (KLDR_ERR_BASE + 37)
1110/** A prerequisit module is being terminated and can therefore not be loaded. */
1111#define KLDR_ERR_PREREQUISITE_MODULE_TERMINATING (KLDR_ERR_BASE + 38)
1112/** The module initialization failed. */
1113#define KLDR_ERR_MODULE_INIT_FAILED (KLDR_ERR_BASE + 39)
1114/** The initialization of a prerequisite module failed. */
1115#define KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED (KLDR_ERR_BASE + 40)
1116/** The module has already failed initialization and can't be attempted reloaded until
1117 * after we've finished garbage collection. */
1118#define KLDR_ERR_MODULE_INIT_FAILED_ALREADY (KLDR_ERR_BASE + 41)
1119/** A prerequisite module has already failed initialization and can't be attempted
1120 * reloaded until after we've finished garbage collection. */
1121#define KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED_ALREADY (KLDR_ERR_BASE + 42)
1122/** Prerequisite recursed too deeply. */
1123#define KLDR_ERR_PREREQUISITE_RECURSED_TOO_DEEPLY (KLDR_ERR_BASE + 43)
1124/** Failed to allocate the main stack. */
1125#define KLDR_ERR_MAIN_STACK_ALLOC_FAILED (KLDR_ERR_BASE + 44)
1126/** Buffer overflow. */
1127#define KLDR_ERR_BUFFER_OVERFLOW (KLDR_ERR_BASE + 45)
1128/** The specified ARCH+CPU isn't compatible with image. */
1129#define KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE (KLDR_ERR_BASE + 45)
1130/** Symbol not found. */
1131#define KLDR_ERR_SYMBOL_NOT_FOUND (KLDR_ERR_BASE + 46)
1132/** A forward symbol was encountered but the caller didn't provide any means to resolve it. */
1133#define KLDR_ERR_FORWARDER_SYMBOL (KLDR_ERR_BASE + 47)
1134/** Encountered a bad fixup. */
1135#define KLDR_ERR_BAD_FIXUP (KLDR_ERR_BASE + 48)
1136/** A memory allocation failed. */
1137#define KLDR_ERR_NO_MEMORY (KLDR_ERR_BASE + 49)
1138/** The import ordinal was out of bounds. */
1139#define KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS (KLDR_ERR_BASE + 50)
1140/** A forwarder chain was too long. */
1141#define KLDR_ERR_TOO_LONG_FORWARDER_CHAIN (KLDR_ERR_BASE + 51)
1142/** The module has no debug info. */
1143#define KLDR_ERR_NO_DEBUG_INFO (KLDR_ERR_BASE + 52)
1144/** The module is already mapped.
1145 * kLdrModMap() can only be called once (without kLdrModUnmap() in between). */
1146#define KLDR_ERR_ALREADY_MAPPED (KLDR_ERR_BASE + 53)
1147/** The module was not mapped.
1148 * kLdrModUnmap() should not called without being preceeded by a kLdrModMap(). */
1149#define KLDR_ERR_NOT_MAPPED (KLDR_ERR_BASE + 54)
1150/** Couldn't fit the address value into the field. Typically a relocation kind of error. */
1151#define KLDR_ERR_ADDRESS_OVERFLOW (KLDR_ERR_BASE + 55)
1152/** Thread attach failed. */
1153#define KLDR_ERR_THREAD_ATTACH_FAILED (KLDR_ERR_BASE + 57)
1154/** The file reader can't take more concurrent mappings. */
1155#define KLDR_ERR_TOO_MANY_MAPPINGS (KLDR_ERR_BASE + 58)
1156/** The module wasn't a DLL or object file. */
1157#define KLDR_ERR_NOT_DLL (KLDR_ERR_BASE + 59)
1158/** The module wasn't an EXE. */
1159#define KLDR_ERR_NOT_EXE (KLDR_ERR_BASE + 60)
1160
1161
1162/** @name kLdrModPE status codes
1163 * @{ */
1164#define KLDR_ERR_PE_BASE (KLDR_ERR_BASE + 61)
1165/** The machine isn't supported by the interpreter. */
1166#define KLDR_ERR_PE_UNSUPPORTED_MACHINE (KLDR_ERR_PE_BASE + 0)
1167/** The file handler isn't valid. */
1168#define KLDR_ERR_PE_BAD_FILE_HEADER (KLDR_ERR_PE_BASE + 1)
1169/** The the optional headers isn't valid. */
1170#define KLDR_ERR_PE_BAD_OPTIONAL_HEADER (KLDR_ERR_PE_BASE + 2)
1171/** One of the section headers aren't valid. */
1172#define KLDR_ERR_PE_BAD_SECTION_HEADER (KLDR_ERR_PE_BASE + 3)
1173/** Bad forwarder entry. */
1174#define KLDR_ERR_PE_BAD_FORWARDER (KLDR_ERR_PE_BASE + 4)
1175/** Forwarder module not found in the import descriptor table. */
1176#define KLDR_ERR_PE_FORWARDER_IMPORT_NOT_FOUND (KLDR_ERR_PE_BASE + 5)
1177/** Bad PE fixups. */
1178#define KLDR_ERR_PE_BAD_FIXUP (KLDR_ERR_PE_BASE + 6)
1179/** Bad PE import (thunk). */
1180#define KLDR_ERR_PE_BAD_IMPORT (KLDR_ERR_PE_BASE + 7)
1181/** @} */
1182
1183/** @name kLdrModLX status codes
1184 * @{ */
1185#define KLDR_ERR_LX_BASE (KLDR_ERR_PE_BASE + 8)
1186/** validation of LX header failed. */
1187#define KLDR_ERR_LX_BAD_HEADER (KLDR_ERR_LX_BASE + 0)
1188/** validation of the loader section (in the LX header) failed. */
1189#define KLDR_ERR_LX_BAD_LOADER_SECTION (KLDR_ERR_LX_BASE + 1)
1190/** validation of the fixup section (in the LX header) failed. */
1191#define KLDR_ERR_LX_BAD_FIXUP_SECTION (KLDR_ERR_LX_BASE + 2)
1192/** validation of the LX object table failed. */
1193#define KLDR_ERR_LX_BAD_OBJECT_TABLE (KLDR_ERR_LX_BASE + 3)
1194/** A bad page map entry was encountered. */
1195#define KLDR_ERR_LX_BAD_PAGE_MAP (KLDR_ERR_LX_BASE + 4)
1196/** Bad iterdata (EXEPACK) data. */
1197#define KLDR_ERR_LX_BAD_ITERDATA (KLDR_ERR_LX_BASE + 5)
1198/** Bad iterdata2 (EXEPACK2) data. */
1199#define KLDR_ERR_LX_BAD_ITERDATA2 (KLDR_ERR_LX_BASE + 6)
1200/** Bad bundle data. */
1201#define KLDR_ERR_LX_BAD_BUNDLE (KLDR_ERR_LX_BASE + 7)
1202/** No soname. */
1203#define KLDR_ERR_LX_NO_SONAME (KLDR_ERR_LX_BASE + 8)
1204/** Bad soname. */
1205#define KLDR_ERR_LX_BAD_SONAME (KLDR_ERR_LX_BASE + 9)
1206/** Bad forwarder entry. */
1207#define KLDR_ERR_LX_BAD_FORWARDER (KLDR_ERR_LX_BASE + 10)
1208/** internal fixup chain isn't implemented yet. */
1209#define KLDR_ERR_LX_NRICHAIN_NOT_SUPPORTED (KLDR_ERR_LX_BASE + 11)
1210/** @} */
1211
1212/** End of the valid kLdr status codes. */
1213#define KLDR_ERR_END (KLDR_ERR_LX_BASE + 12)
1214
1215/** @} */
1216
1217
1218#ifdef __cplusplus
1219}
1220#endif
1221
1222#endif
1223
Note: See TracBrowser for help on using the repository browser.