/* $Id: kLdr.h 2974 2007-02-14 10:12:44Z bird $ */ /** @file * * kLdr - The Dynamic Loader. * * Copyright (c) 2006 knut st. osmundsen * * * This file is part of kLdr. * * kLdr is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * kLdr is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with kLdr; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef __kLdr_h__ #define __kLdr_h__ #ifdef __cplusplus extern "C" { #endif /* * kLdr depend on size_t, [u]intNN_t, [u]intptr_t and some related constants. * If KLDR_NO_KLDR_H_INCLUDES is defined, these has already been defined. */ #ifndef KLDR_NO_KLDR_H_INCLUDES # include # include # ifdef _MSC_VER typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; typedef signed __int64 int64_t; typedef unsigned __int64 uint64_t; typedef int64_t intmax_t; typedef uint64_t uintmax_t; # define UINT8_C(c) (c) # define UINT16_C(c) (c) # define UINT32_C(c) (c ## U) # define UINT64_C(c) (c ## ULL) # define INT8_C(c) (c) # define INT16_C(c) (c) # define INT32_C(c) (c) # define INT64_C(c) (c ## LL) # define INT8_MIN (INT8_C(-0x7f) - 1) # define INT16_MIN (INT16_C(-0x7fff) - 1) # define INT32_MIN (INT32_C(-0x7fffffff) - 1) # define INT64_MIN (INT64_C(-0x7fffffffffffffff) - 1) # define INT8_MAX INT8_C(0x7f) # define INT16_MAX INT16_C(0x7fff) # define INT32_MAX INT32_C(0x7fffffff) # define INT64_MAX INT64_C(0x7fffffffffffffff) # define UINT8_MAX UINT8_C(0xff) # define UINT16_MAX UINT16_C(0xffff) # define UINT32_MAX UINT32_C(0xffffffff) # define UINT64_MAX UINT64_C(0xffffffffffffffff) # else # include # endif #endif /* !KLDR_NO_KLDR_H_INCLUDES */ /** @defgroup grp_kLdrBasic kLdr Basic Types * @{ */ /** The kLdr address type. */ typedef uint64_t KLDRADDR; /** Pointer to a kLdr address. */ typedef KLDRADDR *PKLDRADDR; /** Pointer to a const kLdr address. */ typedef const KLDRADDR *PCKLDRADDR; /** NIL address. */ #define NIL_KLDRADDR (~(uint64_t)0) /** @def PRI_KLDRADDR * printf format type. */ #ifdef _MSC_VER # define PRI_KLDRADDR "I64x" #else # define PRI_KLDRADDR "llx" #endif /** The kLdr size type. */ typedef uint64_t KLDRSIZE; /** Pointer to a kLdr size. */ typedef KLDRSIZE *PKLDRSIZE; /** Pointer to a const kLdr size. */ typedef const KLDRSIZE *PCKLDRSIZE; /** @def PRI_KLDRSIZE * printf format type. */ #ifdef _MSC_VER # define PRI_KLDRSIZE "I64x" #else # define PRI_KLDRSIZE "llx" #endif /** The kLdr file offset type. */ typedef long KLDRFOFF; /** Pointer to a kLdr file offset type. */ typedef KLDRFOFF *PKLDRFOFF; /** Pointer to a const kLdr file offset type. */ typedef const KLDRFOFF *PCKLDRFOFF; /** @def PRI_KLDRFOFF * printf format type. */ #define PRI_KLDRFOFF "lx" /** * Union of all the integer types. */ typedef union KLDRU { int8_t i8; /**< int8_t view. */ uint8_t u8; /**< uint8_t view. */ int16_t i16; /**< int16_t view. */ uint16_t u16; /**< uint16_t view. */ int32_t i32; /**< int32_t view. */ uint32_t u32; /**< uint32_t view. */ int64_t i64; /**< int64_t view. */ uint64_t u64; /**< uint64_t view. */ int8_t ai8[8]; /**< int8_t array view . */ uint8_t au8[8]; /**< uint8_t array view. */ int16_t ai16[4];/**< int16_t array view . */ uint16_t au16[4];/**< uint16_t array view. */ int32_t ai32[2];/**< int32_t array view . */ uint32_t au32[2];/**< uint32_t array view. */ signed char ch; /**< signed char view. */ unsigned char uch; /**< unsigned char view. */ signed short s; /**< signed short view. */ unsigned short us; /**< unsigned short view. */ signed int i; /**< signed int view. */ unsigned int u; /**< unsigned int view. */ signed long l; /**< signed long view. */ unsigned long ul; /**< unsigned long view. */ void *pv; /**< void pointer view. */ KLDRADDR Addr; /**< kLdr address view. */ KLDRSIZE Size; /**< kLdr size view. */ } KLDRU; /** Pointer to an integer union. */ typedef KLDRU *PKLDRU; /** Pointer to a const integer union. */ typedef const KLDRU *PCKLDRU; /** * Union of pointers to all the integer types. */ typedef union KLDRPU { int8_t *pi8; /**< int8_t view. */ uint8_t *pu8; /**< uint8_t view. */ int16_t *pi16; /**< int16_t view. */ uint16_t *pu16; /**< uint16_t view. */ int32_t *pi32; /**< int32_t view. */ uint32_t *pu32; /**< uint32_t view. */ int64_t *pi64; /**< int64_t view. */ uint64_t *pu64; /**< uint64_t view. */ signed char *pch; /**< signed char view. */ unsigned char *puch; /**< unsigned char view. */ signed short *ps; /**< signed short view. */ unsigned short *pus; /**< unsigned short view. */ signed int *pi; /**< signed int view. */ unsigned int *pu; /**< unsigned int view. */ signed long *pl; /**< signed long view. */ unsigned long *pul; /**< unsigned long view. */ void *pv; /**< void pointer view. */ } KLDRPU; /** Pointer to an integer pointer union. */ typedef KLDRPU *PKLDRPU; /** Pointer to a const integer pointer union. */ typedef const KLDRPU *PCKLDRPU; /** * Memory Mapping Protections. * * @remark Shared segments can be mapped using the non copy-on-write variant. * (Normally the copy-on-write variant is used because changes must * be private and not shared with other processes mapping the file.) */ typedef enum KLDRPROT { /** The usual invalid 0. */ KLDRPROT_INVALID = 0, /** No access (page not present). */ KLDRPROT_NOACCESS, /** Read only. */ KLDRPROT_READONLY, /** Read & write. */ KLDRPROT_READWRITE, /** Read & copy on write. */ KLDRPROT_WRITECOPY, /** Execute only. */ KLDRPROT_EXECUTE, /** Execute & read. */ KLDRPROT_EXECUTE_READ, /** Execute, read & write. */ KLDRPROT_EXECUTE_READWRITE, /** Execute, read & copy on write. */ KLDRPROT_EXECUTE_WRITECOPY, /** The usual end value. (exclusive) */ KLDRPROT_END, /** Blow the type up to 32-bits. */ KLDRPROT_32BIT_HACK = 0x7fffffff } KLDRPROT; /** Pointer to a loader segment. */ typedef struct KLDRSEG *PKLDRSEG; /** Pointer to a loader segment. */ typedef const struct KLDRSEG *PCKLDRSEG; /** @} */ /** @defgroup grp_kLdrRdr kLdrRdr - The file provider * @{ */ /** Pointer to a file provider instance core. */ typedef struct KLDRRDR *PKLDRRDR; /** Pointer to a file provider instance core pointer. */ typedef struct KLDRRDR **PPKLDRRDR; /** * File provider instance operations. */ typedef struct KLDRRDROPS { /** The name of this file provider. */ const char *pszName; /** Pointer to the next file provider. */ const struct KLDRRDROPS *pNext; /** Try create a new file provider instance. * * @returns 0 on success, OS specific error code on failure. * @param ppRdr Where to store the file provider instance. * @param pszFilename The filename to open. */ int (* pfnCreate)( PPKLDRRDR ppRdr, const char *pszFilename); /** Destroy the file provider instance. * * @returns 0 on success, OS specific error code on failure. * On failure, the file provider instance will be in an indeterminate state - don't touch it! * @param pRdr The file provider instance. */ int (* pfnDestroy)( PKLDRRDR pRdr); /** @copydoc kLdrRdrRead */ int (* pfnRead)( PKLDRRDR pRdr, void *pvBuf, size_t cb, KLDRFOFF off); /** @copydoc kLdrRdrAllMap */ int (* pfnAllMap)( PKLDRRDR pRdr, const void **ppvBits); /** @copydoc kLdrRdrAllUnmap */ int (* pfnAllUnmap)(PKLDRRDR pRdr, const void *pvBits); /** @copydoc kLdrRdrSize */ KLDRFOFF (* pfnSize)( PKLDRRDR pRdr); /** @copydoc kLdrRdrTell */ KLDRFOFF (* pfnTell)( PKLDRRDR pRdr); /** @copydoc kLdrRdrName */ const char * (* pfnName)(PKLDRRDR pRdr); /** @copydoc kLdrRdrPageSize */ size_t (* pfnPageSize)(PKLDRRDR pRdr); /** @copydoc kLdrRdrMap */ int (* pfnMap)( PKLDRRDR pRdr, void **ppvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fFixed); /** @copydoc kLdrRdrRefresh */ int (* pfnRefresh)( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments); /** @copydoc kLdrRdrProtect */ int (* pfnProtect)( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fUnprotectOrProtect); /** @copydoc kLdrRdrUnmap */ int (* pfnUnmap)( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments); /** @copydoc kLdrRdrDone */ void (* pfnDone)( PKLDRRDR pRdr); /** The usual non-zero dummy that makes sure we've initialized all members. */ uint32_t u32Dummy; } KLDRRDROPS; /** Pointer to file provider operations. */ typedef KLDRRDROPS *PKLDRRDROPS; /** Pointer to const file provider operations. */ typedef const KLDRRDROPS *PCKLDRRDROPS; /** * File provider instance core. */ typedef struct KLDRRDR { /** Magic number (KLDRRDR_MAGIC). */ uint32_t u32Magic; /** Pointer to the file provider operations. */ PCKLDRRDROPS pOps; } KLDRRDR; /** The magic for KLDRRDR::u32Magic. (Katsu Aki (Katsuaki Nakamura)) */ #define KLDRRDR_MAGIC 0x19610919 void kLdrRdrAddProvider(PKLDRRDROPS pAdd); int kLdrRdrOpen( PPKLDRRDR ppRdr, const char *pszFilename); int kLdrRdrClose( PKLDRRDR pRdr); int kLdrRdrRead( PKLDRRDR pRdr, void *pvBuf, size_t cb, KLDRFOFF off); int kLdrRdrAllMap( PKLDRRDR pRdr, const void **ppvBits); int kLdrRdrAllUnmap(PKLDRRDR pRdr, const void *pvBits); KLDRFOFF kLdrRdrSize( PKLDRRDR pRdr); KLDRFOFF kLdrRdrTell( PKLDRRDR pRdr); const char *kLdrRdrName(PKLDRRDR pRdr); size_t kLdrRdrPageSize(PKLDRRDR pRdr); int kLdrRdrMap( PKLDRRDR pRdr, void **ppvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fFixed); int kLdrRdrRefresh( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments); int kLdrRdrProtect( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fUnprotectOrProtect); int kLdrRdrUnmap( PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments); void kLdrRdrDone( PKLDRRDR pRdr); /** @} */ /** @defgroup grp_kLdrMod kLdrMod - The executable image intepreter * @{ */ /** * CPU Architecture. * @todo Double check the non intel architectures. */ typedef enum KLDRARCH { /** The usual invalid one. */ KLDRARCH_INVALID = 0, /** Clone or Intel 16-bit x86. */ KLDRARCH_X86_16, /** Clone or Intel 32-bit x86. */ KLDRARCH_X86_32, /** AMD64 (including clones). */ KLDRARCH_AMD64, /** Itanic (64-bit). */ KLDRARCH_IA64, /** ALPHA (64-bit). */ KLDRARCH_ALPHA, /** ALPHA limited to 32-bit. */ KLDRARCH_ALPHA_32, /** 32-bit ARM. */ KLDRARCH_ARM_32, /** 64-bit ARM. */ KLDRARCH_ARM_64, /** 32-bit MIPS. */ KLDRARCH_MIPS_32, /** 64-bit MIPS. */ KLDRARCH_MIPS_64, /** 32-bit PowerPC. */ KLDRARCH_POWERPC_32, /** 64-bit PowerPC. */ KLDRARCH_POWERPC_64, /** 32-bit SPARC. */ KLDRARCH_SPARC_32, /** 64-bit SPARC. */ KLDRARCH_SPARC_64, /** The end of the valid architecture values (exclusive). */ KLDRARCH_END, /** Hack to blow the type up to 32-bit. */ KLDRARCH_32BIT_HACK = 0x7fffffff } KLDRARCH; /** Pointer to a CPU architecture type. */ typedef KLDRARCH *PKLDRARCH; /** * CPU models. */ typedef enum KLDRCPU { /** The usual invalid cpu. */ KLDRCPU_INVALID = 0, /** @name KLDRARCH_X86_16 * @{ */ KLDRCPU_I8086, KLDRCPU_I8088, KLDRCPU_I80186, KLDRCPU_I80286, KLDRCPU_I386_16, KLDRCPU_I486_16, KLDRCPU_I486SX_16, KLDRCPU_I586_16, KLDRCPU_I686_16, KLDRCPU_P4_16, KLDRCPU_CORE2_16, KLDRCPU_K6_16, KLDRCPU_K7_16, KLDRCPU_K8_16, KLDRCPU_FIRST_X86_16 = KLDRCPU_I8086, KLDRCPU_LAST_X86_16 = KLDRCPU_K8_16, /** @} */ /** @name KLDRARCH_X86_32 * @{ */ KLDRCPU_X86_32_BLEND, KLDRCPU_I386, KLDRCPU_I486, KLDRCPU_I486SX, KLDRCPU_I586, KLDRCPU_I686, KLDRCPU_P4, KLDRCPU_CORE2_32, KLDRCPU_K6, KLDRCPU_K7, KLDRCPU_K8_32, KLDRCPU_FIRST_X86_32 = KLDRCPU_I386, KLDRCPU_LAST_X86_32 = KLDRCPU_K8_32, /** @} */ /** @name KLDRARCH_AMD64 * @{ */ KLDRCPU_AMD64_BLEND, KLDRCPU_K8, KLDRCPU_P4_64, KLDRCPU_CORE2, KLDRCPU_FIRST_AMD64 = KLDRCPU_K8, KLDRCPU_LAST_AMD64 = KLDRCPU_CORE2, /** @} */ /** The end of the valid cpu values (exclusive). */ KLDRCPU_END, /** Hack to blow the type up to 32-bit. */ KLDRCPU_32BIT_HACK = 0x7fffffff } KLDRCPU; /** Pointer to a CPU type. */ typedef KLDRCPU *PKLDRCPU; void kLdrGetArchCpu(PKLDRARCH penmArch, PKLDRCPU penmCpu); int kLdrCompareCpus(KLDRARCH enmCodeArch, KLDRCPU enmCodeCpu, KLDRARCH enmArch, KLDRCPU enmCpu); /** * Debug info type (from the loader point of view). */ typedef enum KLDRDBGINFOTYPE { /** The usual invalid enum value. */ KLDRDBGINFOTYPE_INVALID = 0, /** Unknown debug info format. */ KLDRDBGINFOTYPE_UNKNOWN, /** Stabs. */ KLDRDBGINFOTYPE_STABS, /** Debug With Arbitrary Record Format (DWARF). */ KLDRDBGINFOTYPE_DWARF, /** Microsoft Codeview debug info. */ KLDRDBGINFOTYPE_CODEVIEW, /** Watcom debug info. */ KLDRDBGINFOTYPE_WATCOM, /** IBM High Level Language debug info.. */ KLDRDBGINFOTYPE_HLL, /** The end of the valid debug info values (exclusive). */ KLDRDBGINFOTYPE_END, /** Blow the type up to 32-bit. */ KLDRDBGINFOTYPE_32BIT_HACK = 0x7fffffff } KLDRDBGINFOTYPE; /** Pointer to a kLdr debug info type. */ typedef KLDRDBGINFOTYPE *PKLDRDBGINFOTYPE; /** * Stack information. */ typedef struct KLDRSTACKINFO { /** The base address of the stack (sub) segment. * Set this to NIL_KLDRADDR if the module doesn't include any stack segment. */ KLDRADDR Address; /** The base address of the stack (sub) segment, link address. * Set this to NIL_KLDRADDR if the module doesn't include any stack (sub)segment. */ KLDRADDR LinkAddress; /** The stack size of the main thread. * If no stack (sub)segment in the module, this is the stack size of the main thread. * If the module doesn't contain this kind of information this field will be set to 0. */ KLDRSIZE cbStack; /** The stack size of non-main threads. * If the module doesn't contain this kind of information this field will be set to 0. */ KLDRSIZE cbStackThread; } KLDRSTACKINFO; /** Pointer to stack information. */ typedef KLDRSTACKINFO *PKLDRSTACKINFO; /** Pointer to const stack information. */ typedef const KLDRSTACKINFO *PCKLDRSTACKINFO; /** * Loader segment. */ typedef struct KLDRSEG { /** Variable free to use for the kLdr user. */ void *pvUser; /** The segment name. (Might not be zero terminated!) */ const char *pchName; /** The length of the segment name. */ uint32_t cchName; /** The flat selector to use for the segment (i.e. data/code). * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */ uint16_t SelFlat; /** The 16-bit selector to use for the segment. * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */ uint16_t Sel16bit; /** Segment flags. */ uint32_t fFlags; /** The segment protection. */ KLDRPROT enmProt; /** The size of the segment. */ KLDRSIZE cb; /** The required segment alignment. * The to 0 if the segment isn't supposed to be mapped. */ KLDRADDR Alignment; /** The link address. * Set to NIL_KLDRADDR if the segment isn't supposed to be * mapped or if the image doesn't have link addresses. */ KLDRADDR LinkAddress; /** File offset of the segment. * Set to -1 if no file backing (like BSS). */ KLDRFOFF offFile; /** Size of the file bits of the segment. * Set to -1 if no file backing (like BSS). */ KLDRFOFF cbFile; /** The relative virtual address when mapped. * Set to NIL_KLDRADDR if the segment isn't supposed to be mapped. */ KLDRADDR RVA; /** The size of the segment including the alignment gap up to the next segment when mapped. */ size_t cbMapped; /** The address the segment was mapped at by kLdrModMap(). * Set to 0 if not mapped. */ uintptr_t MapAddress; } KLDRSEG; /** @name Segment flags * @{ */ /** The segment is 16-bit. When not set the default of the target architecture is assumed. */ #define KLDRSEG_FLAG_16BIT 1 /** The segment requires a 16-bit selector alias. (OS/2) */ #define KLDRSEG_FLAG_OS2_ALIAS16 2 /** Conforming segment (x86 weirdness). (OS/2) */ #define KLDRSEG_FLAG_OS2_CONFORM 4 /** IOPL (ring-2) segment. (OS/2) */ #define KLDRSEG_FLAG_OS2_IOPL 8 /** @} */ /** * Loader module format. */ typedef enum KLDRFMT { /** The usual invalid 0 format. */ KLDRFMT_INVALID = 0, /** The native OS loader. */ KLDRFMT_NATIVE, /** The AOUT loader. */ KLDRFMT_AOUT, /** The ELF loader. */ KLDRFMT_ELF, /** The LX loader. */ KLDRFMT_LX, /** The Mach-O loader. */ KLDRFMT_MACHO, /** The PE loader. */ KLDRFMT_PE, /** The end of the valid format values (exclusive). */ KLDRFMT_END, /** Hack to blow the type up to 32-bit. */ KLDRFMT_32BIT_HACK = 0x7fffffff } KLDRFMT; /** * Loader module type. */ typedef enum KLDRTYPE { /** The usual invalid 0 type. */ KLDRTYPE_INVALID = 0, /** Object file. */ KLDRTYPE_OBJECT, /** Executable module, fixed load address. */ KLDRTYPE_EXECUTABLE_FIXED, /** Executable module, relocatable, non-fixed load address. */ KLDRTYPE_EXECUTABLE_RELOCATABLE, /** Executable module, position independent code, non-fixed load address. */ KLDRTYPE_EXECUTABLE_PIC, /** Shared library, fixed load address. * Typically a system library. */ KLDRTYPE_SHARED_LIBRARY_FIXED, /** Shared library, relocatable, non-fixed load address. */ KLDRTYPE_SHARED_LIBRARY_RELOCATABLE, /** Shared library, position independent code, non-fixed load address. */ KLDRTYPE_SHARED_LIBRARY_PIC, /** DLL that contains no code or data only imports and exports. (Chiefly OS/2.) */ KLDRTYPE_FORWARDER_DLL, /** Core or dump. */ KLDRTYPE_CORE, /** The end of the valid types values (exclusive). */ KLDRTYPE_END, /** Hack to blow the type up to 32-bit. */ KLDRTYPE_32BIT_HACK = 0x7fffffff } KLDRTYPE; /** * Loader endian indicator. */ typedef enum KLDRENDIAN { /** The usual invalid endian. */ KLDRENDIAN_INVALID, /** Little endian. */ KLDRENDIAN_LITTLE, /** Bit endian. */ KLDRENDIAN_BIG, /** Endianness doesn't have a meaning in the context. */ KLDRENDIAN_NA, /** The end of the valid endian values (exclusive). */ KLDRENDIAN_END, /** Hack to blow the type up to 32-bit. */ KLDRENDIAN_32BIT_HACK = 0x7fffffff } KLDRENDIAN; /** @def KLDR_LITTLE_ENDIAN * The kLdr build is for a little endian target. */ /** @def KLDR_BIG_ENDIAN * The kLdr build is for a big endian target. */ #if !defined(KLDR_LITTLE_ENDIAN) && !defined(KLDR_BIG_ENDIAN) # define KLDR_LITTLE_ENDIAN #endif #ifdef __DOXYGEN__ # define KLDR_BIG_ENDIAN #endif /** Pointer to a module interpreter method table. */ typedef struct KLDRMODOPS *PKLDRMODOPS; /** Pointer to const module interpreter methods table. */ typedef const struct KLDRMODOPS *PCKLDRMODOPS; /** * Module interpreter instance. * All members are read only unless you're kLdrMod or the module interpreter. */ typedef struct KLDRMOD { /** Magic number (KLDRMOD_MAGIC). */ uint32_t u32Magic; /** The format of this module. */ KLDRFMT enmFmt; /** The type of module. */ KLDRTYPE enmType; /** The architecture this module was built for. */ KLDRARCH enmArch; /** The minium cpu this module was built for. * This might not be accurate, so use kLdrModCanExecuteOn() to check. */ KLDRARCH enmCpu; /** The endian used by the module. */ KLDRENDIAN enmEndian; /** The filename length (bytes). */ uint32_t cchFilename; /** The filename. */ const char *pszFilename; /** The module name. */ const char *pszName; /** The module name length (bytes). */ uint32_t cchName; /** The number of segments in the module. */ uint32_t cSegments; /** Pointer to the loader methods. * Not meant for calling directly thru! */ PCKLDRMODOPS pOps; /** Pointer to the read instance. (Can be NULL after kLdrModDone().)*/ PKLDRRDR pRdr; /** The module data. */ void *pvData; /** Segments. (variable size, can be zero) */ KLDRSEG aSegments[1]; } KLDRMOD, *PKLDRMOD, **PPKLDRMOD; /** The magic for KLDRMOD::u32Magic. (Kosuke Fujishima) */ #define KLDRMOD_MAGIC 0x19640707 /** Special base address value alias for the link address. */ #define KLDRMOD_BASEADDRESS_LINK (~(KLDRADDR)1) /** Special base address value alias for the actual load address (must be mapped). */ #define KLDRMOD_BASEADDRESS_MAP (~(KLDRADDR)2) /** Special import module ordinal value used to indicate that there is no * specific module associated with the requested symbol. */ #define NIL_KLDRMOD_IMPORT (~(uint32_t)0) /** Special symbol ordinal value used to indicate that the symbol * only has a string name. */ #define NIL_KLDRMOD_SYM_ORDINAL (~(uint32_t)0) /** @name Load symbol kind flags. * @{ */ /** The bitness doesn't matter. */ #define KLDRSYMKIND_NO_BIT 0x00000000 /** 16-bit symbol. */ #define KLDRSYMKIND_16BIT 0x00000001 /** 32-bit symbol. */ #define KLDRSYMKIND_32BIT 0x00000002 /** 64-bit symbol. */ #define KLDRSYMKIND_64BIT 0x00000003 /** Mask out the bit.*/ #define KLDRSYMKIND_BIT_MASK 0x00000003 /** We don't know the type of symbol. */ #define KLDRSYMKIND_NO_TYPE 0x00000000 /** The symbol is a code object (method/function/procedure/whateveryouwannacallit). */ #define KLDRSYMKIND_CODE 0x00000010 /** The symbol is a data object. */ #define KLDRSYMKIND_DATA 0x00000020 /** Mask out the symbol type. */ #define KLDRSYMKIND_TYPE_MASK 0x00000030 /** Valid symbol kind mask. */ #define KLDRSYMKIND_MASK 0x00000033 /** Weak symbol. */ #define KLDRSYMKIND_WEAK 0x00000100 /** Forwarder symbol. */ #define KLDRSYMKIND_FORWARDER 0x00000200 /** Request a flat symbol address. */ #define KLDRSYMKIND_REQ_FLAT 0x00000000 /** Request a segmented symbol address. */ #define KLDRSYMKIND_REQ_SEGMENTED 0x40000000 /** Request type mask. */ #define KLDRSYMKIND_REQ_TYPE_MASK 0x40000000 /** @} */ /** @name kLdrModEnumSymbols flags. * @{ */ /** Returns ALL kinds of symbols. The default is to only return public/exported symbols. */ #define KLDRMOD_ENUM_SYMS_FLAGS_ALL 0x00000001 /** @} */ /** * Callback for resolving imported symbols when applying fixups. * * @returns 0 on success and *pValue and *pfKind filled. * @returns Non-zero OS specific or kLdr status code on failure. * * @param pMod The module which fixups are begin applied. * @param iImport The import module ordinal number or NIL_KLDRMOD_IMPORT. * @param iSymbol The symbol ordinal number or NIL_KLDRMOD_SYM_ORDINAL. * @param pchSymbol The symbol name. Can be NULL if iSymbol isn't nil. Doesn't have to be null-terminated. * @param cchSymbol The length of the symbol. * @param pszVersion The symbol version. NULL if not versioned. * @param puValue Where to store the symbol value. * @param pfKind Where to store the symbol kind flags. * @param pvUser The user parameter specified to the relocation function. */ typedef int FNKLDRMODGETIMPORT(PKLDRMOD pMod, uint32_t iImport, uint32_t iSymbol, const char *pchSymbol, size_t cchSymbol, const char *pszVersion, PKLDRADDR puValue, uint32_t *pfKind, void *pvUser); /** Pointer to a import callback. */ typedef FNKLDRMODGETIMPORT *PFNKLDRMODGETIMPORT; /** * Symbol enumerator callback. * * @returns 0 if enumeration should continue. * @returns non-zero if the enumeration should stop. This status code will then be returned by kLdrModEnumSymbols(). * * @param pMod The module which symbols are being enumerated.s * @param iSymbol The symbol ordinal number or NIL_KLDRMOD_SYM_ORDINAL. * @param pchSymbol The symbol name. This can be NULL if there is a symbol ordinal. * This can also be an empty string if the symbol doesn't have a name * or it's name has been stripped. * Important, this doesn't have to be a null-terminated string. * @param cchSymbol The length of the symbol. * @param pszVersion The symbol version. NULL if not versioned. * @param uValue The symbol value. * @param fKind The symbol kind flags. * @param pvUser The user parameter specified to kLdrModEnumSymbols(). */ typedef int FNKLDRMODENUMSYMS(PKLDRMOD pMod, uint32_t iSymbol, const char *pchSymbol, size_t cchSymbol, const char *pszVersion, KLDRADDR uValue, uint32_t fKind, void *pvUser); /** Pointer to a symbol enumerator callback. */ typedef FNKLDRMODENUMSYMS *PFNKLDRMODENUMSYMS; /** * Debug info enumerator callback. * * @returns 0 to continue the enumeration. * @returns non-zero if the enumeration should stop. This status code will then be returned by kLdrModEnumDbgInfo(). * * @param pMod The module. * @param iDbgInfo The debug info ordinal number / id. * @param enmType The debug info type. * @param iMajorVer The major version number of the debug info format. -1 if unknow - implies invalid iMinorVer. * @param iMinorVer The minor version number of the debug info format. -1 when iMajorVer is -1. * @param offFile The file offset *if* this type has one specific location in the executable image file. * This is -1 if there isn't any specific file location. * @param LinkAddress The link address of the debug info if it's loadable. NIL_KLDRADDR if not loadable. * @param cb The size of the debug information. -1 is used if this isn't applicable. * @param pszExtFile This points to the name of an external file containing the debug info. * This is NULL if there isn't any external file. * @param pvUser The user parameter specified to kLdrModEnumDbgInfo. */ typedef int FNKLDRENUMDBG(PKLDRMOD pMod, uint32_t iDbgInfo, KLDRDBGINFOTYPE enmType, int16_t iMajorVer, int16_t iMinorVer, KLDRFOFF offFile, KLDRADDR LinkAddress, KLDRSIZE cb, const char *pszExtFile, void *pvUser); /** Pointer to a debug info enumerator callback. */ typedef FNKLDRENUMDBG *PFNKLDRENUMDBG; /** * Resource enumerator callback. * * @returns 0 to continue the enumeration. * @returns non-zero if the enumeration should stop. This status code will then be returned by kLdrModEnumResources(). * * @param pMod The module. * @param idType The resource type id. NIL_KLDRMOD_RSRC_TYPE_ID if no type id. * @param pszType The resource type name. NULL if no type name. * @param idName The resource id. NIL_KLDRMOD_RSRC_NAME_ID if no id. * @param pszName The resource name. NULL if no name. * @param idLang The language id. * @param AddrRsrc The address value for the resource. * @param cbRsrc The size of the resource. * @param pvUser The user parameter specified to kLdrModEnumDbgInfo. */ typedef int FNKLDRENUMRSRC(PKLDRMOD pMod, uint32_t idType, const char *pszType, uint32_t idName, const char *pszName, uint32_t idLang, KLDRADDR AddrRsrc, KLDRSIZE cbRsrc, void *pvUser); /** Pointer to a resource enumerator callback. */ typedef FNKLDRENUMRSRC *PFNKLDRENUMRSRC; /** NIL resource name ID. */ #define NIL_KLDRMOD_RSRC_NAME_ID ( ~(uint32_t)0 ) /** NIL resource type ID. */ #define NIL_KLDRMOD_RSRC_TYPE_ID ( ~(uint32_t)0 ) /** @name Language ID * * Except for the special IDs #defined here, the values are considered * format specific for now since it's only used by the PE resources. * * @{ */ /** NIL language ID. */ #define NIL_KLDR_LANG_ID ( ~(uint32_t)0 ) /** Special language id value for matching any language. */ #define KLDR_LANG_ID_ANY ( ~(uint32_t)1 ) /** Special language id value indicating language neutral. */ #define KLDR_LANG_ID_NEUTRAL ( ~(uint32_t)2 ) /** Special language id value indicating user default language. */ #define KLDR_LANG_ID_USER_DEFAULT ( ~(uint32_t)3 ) /** Special language id value indicating system default language. */ #define KLDR_LANG_ID_SYS_DEFAULT ( ~(uint32_t)4 ) /** Special language id value indicating default custom locale. */ #define KLDR_LANG_ID_CUSTOM_DEFAULT ( ~(uint32_t)5 ) /** Special language id value indicating unspecified custom locale. */ #define KLDR_LANG_ID_CUSTOM_UNSPECIFIED ( ~(uint32_t)6 ) /** Special language id value indicating default custom MUI locale. */ #define KLDR_LANG_ID_UI_CUSTOM_DEFAULT ( ~(uint32_t)7 ) /** @} */ int kLdrModOpen(const char *pszFilename, PPKLDRMOD ppMod); int kLdrModOpenFromRdr(PKLDRRDR pRdr, PPKLDRMOD ppMod); int kLdrModOpenNative(const char *pszFilename, PPKLDRMOD ppMod); int kLdrModOpenNativeByHandle(uintptr_t uHandle, PPKLDRMOD ppMod); int kLdrModClose(PKLDRMOD pMod); int kLdrModQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t iSymbol, const char *pchSymbol, size_t cchSymbol, const char *pszVersion, PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind); int kLdrModEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser); int kLdrModGetImport(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName); int32_t kLdrModNumberOfImports(PKLDRMOD pMod, const void *pvBits); int kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu); int kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo); int kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress); int kLdrModQueryResource(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType, uint32_t idName, const char *pszName, uint32_t idLang, PKLDRADDR pAddrRsrc, size_t *pcbRsrc); int kLdrModEnumResources(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType, uint32_t idName, const char *pszName, uint32_t idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser); int kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser); int kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits); int kLdrModMostlyDone(PKLDRMOD pMod); /** @name Operations On The Internally Managed Mapping * @{ */ int kLdrModMap(PKLDRMOD pMod); int kLdrModUnmap(PKLDRMOD pMod); int kLdrModAllocTLS(PKLDRMOD pMod); void kLdrModFreeTLS(PKLDRMOD pMod); int kLdrModReload(PKLDRMOD pMod); int kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); int kLdrModCallInit(PKLDRMOD pMod, uintptr_t uHandle); int kLdrModCallTerm(PKLDRMOD pMod, uintptr_t uHandle); int kLdrModCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching); /** @} */ /** @name Operations On The Externally Managed Mappings * @{ */ KLDRADDR kLdrModSize(PKLDRMOD pMod); int kLdrModGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); int kLdrModRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); /** @} */ /** * The loader module operation. */ typedef struct KLDRMODOPS { /** The name of this module interpreter. */ const char *pszName; /** Pointer to the next module interpreter. */ PCKLDRMODOPS pNext; /** * Create a loader module instance interpreting the executable image found * in the specified file provider instance. * * @returns 0 on success and *ppMod pointing to a module instance. * On failure, a non-zero OS specific error code is returned. * @param pOps Pointer to the registered method table. * @param pRdr The file provider instance to use. * @param offNewHdr The offset of the new header in MZ files. -1 if not found. * @param ppMod Where to store the module instance pointer. */ int (* pfnCreate)(PCKLDRMODOPS pOps, PKLDRRDR pRdr, KLDRFOFF offNewHdr, PPKLDRMOD ppMod); /** * Destroys an loader module instance. * * The caller is responsible for calling kLdrModUnmap() and kLdrFreeTLS() first. * * @returns 0 on success, non-zero on failure. The module instance state * is unknown on failure, it's best not to touch it. * @param pMod The module. */ int (* pfnDestroy)(PKLDRMOD pMod); /** @copydoc kLdrModQuerySymbol */ int (* pfnQuerySymbol)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t iSymbol, const char *pchSymbol, size_t cchSymbol, const char *pszVersion, PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind); /** @copydoc kLdrModEnumSymbols */ int (* pfnEnumSymbols)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser); /** @copydoc kLdrModGetImport */ int (* pfnGetImport)(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName); /** @copydoc kLdrModNumberOfImports */ int32_t (* pfnNumberOfImports)(PKLDRMOD pMod, const void *pvBits); /** @copydoc kLdrModCanExecuteOn */ int (* pfnCanExecuteOn)(PKLDRMOD pMod, const void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu); /** @copydoc kLdrModGetStackInfo */ int (* pfnGetStackInfo)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo); /** @copydoc kLdrModQueryMainEntrypoint */ int (* pfnQueryMainEntrypoint)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress); /** @copydoc kLdrModQueryResource */ int (* pfnQueryResource)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType, uint32_t idName, const char *pszName, uint32_t idLang, PKLDRADDR pAddrRsrc, size_t *pcbRsrc); /** @copydoc kLdrModEnumResources */ int (* pfnEnumResources)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t idType, const char *pszType, uint32_t idName, const char *pszName, uint32_t idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser); /** @copydoc kLdrModEnumDbgInfo */ int (* pfnEnumDbgInfo)(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser); /** @copydoc kLdrModHasDbgInfo */ int (* pfnHasDbgInfo)(PKLDRMOD pMod, const void *pvBits); /** @copydoc kLdrModMap */ int (* pfnMap)(PKLDRMOD pMod); /** @copydoc kLdrModUnmap */ int (* pfnUnmap)(PKLDRMOD pMod); /** @copydoc kLdrModAllocTLS */ int (* pfnAllocTLS)(PKLDRMOD pMod); /** @copydoc kLdrModFreeTLS */ void (* pfnFreeTLS)(PKLDRMOD pMod); /** @copydoc kLdrModReload */ int (* pfnReload)(PKLDRMOD pMod); /** @copydoc kLdrModFixupMapping */ int (* pfnFixupMapping)(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); /** @copydoc kLdrModCallInit */ int (* pfnCallInit)(PKLDRMOD pMod, uintptr_t uHandle); /** @copydoc kLdrModCallTerm */ int (* pfnCallTerm)(PKLDRMOD pMod, uintptr_t uHandle); /** @copydoc kLdrModCallThread */ int (* pfnCallThread)(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching); /** @copydoc kLdrModSize */ KLDRADDR (* pfnSize)(PKLDRMOD pMod); /** @copydoc kLdrModGetBits */ int (* pfnGetBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); /** @copydoc kLdrModRelocateBits */ int (* pfnRelocateBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); /** @copydoc kLdrModMostlyDone */ int (* pfnMostlyDone)(PKLDRMOD pMod); /** Dummy which should be assigned a non-zero value. */ uint32_t uEndOfStructure; } KLDRMODOPS; /** @} */ /** @defgroup grp_kLdrDyld kLdrDyld - The dynamic loader * @{ */ /** The handle to a dynamic loader module. */ typedef struct KLDRDYLDMOD *HKLDRMOD; /** Pointer to the handle to a dynamic loader module. */ typedef HKLDRMOD *PHKLDRMOD; /** NIL handle value. */ #define NIL_HKLDRMOD ((HKLDRMOD)0) /** * File search method. * * In addition to it's own way of finding files, kLdr emulates * the methods employed by the most popular systems. */ typedef enum KLDRDYLDSEARCH { /** The usual invalid file search method. */ KLDRDYLD_SEARCH_INVALID = 0, /** Uses the kLdr file search method. * @todo invent me. */ KLDRDYLD_SEARCH_KLDR, /** Use the emulation closest to the host system. */ KLDRDYLD_SEARCH_HOST, /** Emulate the OS/2 file search method. * On non-OS/2 systems, BEGINLIBPATH, LIBPATH, ENDLIBPATH and LIBPATHSTRICT are * taken form the environment. */ KLDRDYLD_SEARCH_OS2, /** Emulate the standard window file search method. */ KLDRDYLD_SEARCH_WINDOWS, /** Emulate the alternative window file search method. */ KLDRDYLD_SEARCH_WINDOWS_ALTERED, /** Emulate the most common UNIX file search method. */ KLDRDYLD_SEARCH_UNIX_COMMON, /** End of the valid file search method values. */ KLDRDYLD_SEARCH_END, /** Hack to blow the type up to 32-bit. */ KLDRDYLD_SEARCH_32BIT_HACK = 0x7fffffff } KLDRDYLDSEARCH; /** @name kLdrDyldLoad and kLdrDyldFindByName flags. * @{ */ /** The symbols in the module should be loaded into the global unix namespace. * If not specified, the symbols are local and can only be referenced directly. */ #define KLDRYDLD_LOAD_FLAGS_GLOBAL_SYMBOLS 0x00000001 /** The symbols in the module should be loaded into the global unix namespace and * it's symbols should take precedence over all currently loaded modules. * This implies KLDRYDLD_LOAD_FLAGS_GLOBAL_SYMBOLS. */ #define KLDRYDLD_LOAD_FLAGS_DEEP_SYMBOLS 0x00000002 /** The module shouldn't be found by a global module search. * If not specified, the module can be found by unspecified module searches, * typical used when loading import/dep modules. */ #define KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE 0x00000004 /** Do a recursive initialization calls instead of defering them to the outermost call. */ #define KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT 0x00000008 /** We're loading the executable module. * @internal */ #define KLDRDYLD_LOAD_FLAGS_EXECUTABLE 0x40000000 /** @} */ int kLdrDyldLoad(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch, unsigned fFlags, PHKLDRMOD phMod, char *pszErr, size_t cchErr); int kLdrDyldUnload(HKLDRMOD hMod); int kLdrDyldFindByName(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch, unsigned fFlags, PHKLDRMOD phMod); int kLdrDyldFindByAddress(uintptr_t Address, PHKLDRMOD phMod, uint32_t *piSegment, uintptr_t *poffSegment); int kLdrDyldGetName(HKLDRMOD hMod, char *pszName, size_t cchName); int kLdrDyldGetFilename(HKLDRMOD hMod, char *pszFilename, size_t cchFilename); int kLdrDyldQuerySymbol(HKLDRMOD hMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, const char *pszSymbolVersion, uintptr_t *pValue, uint32_t *pfKind); int kLdrDyldQueryResource(HKLDRMOD hMod, uint32_t idType, const char *pszType, uint32_t idName, const char *pszName, uint32_t idLang, void **pvRsrc, size_t *pcbRsrc); int kLdrDyldEnumResources(HKLDRMOD hMod, uint32_t idType, const char *pszType, uint32_t idName, const char *pszName, uint32_t idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser); /** @name OS/2 like API * @{ */ #if defined(__OS2__) # define KLDROS2API _System #else # define KLDROS2API #endif int kLdrDosLoadModule(char *pszObject, size_t cbObject, const char *pszModule, PHKLDRMOD phMod); int kLdrDosFreeModule(HKLDRMOD hMod); int kLdrDosQueryModuleHandle(const char *pszModname, PHKLDRMOD phMod); int kLdrDosQueryModuleName(HKLDRMOD hMod, size_t cchName, char *pszName); int kLdrDosQueryProcAddr(HKLDRMOD hMod, uint32_t iOrdinal, const char *pszProcName, void **ppvProcAddr); int kLdrDosQueryProcType(HKLDRMOD hMod, uint32_t iOrdinal, const char *pszProcName, uint32_t *pfProcType); int kLdrDosQueryModFromEIP(PHKLDRMOD phMod, uint32_t *piObject, size_t cbName, char *pszName, uintptr_t *poffObject, uintptr_t ulEIP); int kLdrDosReplaceModule(const char *pszOldModule, const char *pszNewModule, const char *pszBackupModule); int kLdrDosGetResource(HKLDRMOD hMod, uint32_t idType, uint32_t idName, void **pvResAddr); int kLdrDosQueryResourceSize(HKLDRMOD hMod, uint32_t idType, uint32_t idName, uint32_t *pcb); int kLdrDosFreeResource(void *pvResAddr); /** @} */ /** @name POSIX like API * @{ */ HKLDRMOD kLdrDlOpen(const char *pszLibrary, int fFlags); const char *kLdrDlError(void); void * kLdrDlSym(HKLDRMOD hMod, const char *pszSymbol); int kLdrDlClose(HKLDRMOD hMod); /** @todo GNU extensions */ /** @} */ /** @name Win32 like API * @{ */ #if defined(_MSC_VER) # define KLDRWINAPI __stdcall #else # define KLDRWINAPI #endif HKLDRMOD KLDRWINAPI kLdrWLoadLibrary(const char *pszFilename); HKLDRMOD KLDRWINAPI kLdrWLoadLibraryEx(const char *pszFilename, void *hFileReserved, uint32_t fFlags); uint32_t KLDRWINAPI kLdrWGetModuleFileName(HKLDRMOD hMod, char *pszModName, size_t cchModName); HKLDRMOD KLDRWINAPI kLdrWGetModuleHandle(const char *pszFilename); int KLDRWINAPI kLdrWGetModuleHandleEx(uint32_t fFlags, const char *pszFilename, HKLDRMOD hMod); void * KLDRWINAPI kLdrWGetProcAddress(HKLDRMOD hMod, const char *pszProcName); uint32_t KLDRWINAPI kLdrWGetDllDirectory(size_t cchDir, char *pszDir); int KLDRWINAPI kLdrWSetDllDirectory(const char *pszDir); int KLDRWINAPI kLdrWFreeLibrary(HKLDRMOD hMod); int KLDRWINAPI kLdrWDisableThreadLibraryCalls(HKLDRMOD hMod); /** The handle to a resource that's been found. */ typedef struct KLDRWRSRCFOUND *HKLDRWRSRCFOUND; /** The handle to a loaded resource. */ typedef struct KLDRWRSRCLOADED *HKLDRWRSRCLOADED; HKLDRWRSRCFOUND KLDRWINAPI kLdrWFindResource(HKLDRMOD hMod, const char *pszType, const char *pszName); HKLDRWRSRCFOUND KLDRWINAPI kLdrWFindResourceEx(HKLDRMOD hMod, const char *pszType, const char *pszName, uint16_t idLang); uint32_t KLDRWINAPI kLdrWSizeofResource(HKLDRMOD hMod, HKLDRWRSRCFOUND hFoundRsrc); HKLDRWRSRCLOADED KLDRWINAPI kLdrWLoadResource(HKLDRMOD hMod, HKLDRWRSRCFOUND hFoundRsrc); void *KLDRWINAPI kLdrWLockResource(HKLDRMOD hMod, HKLDRWRSRCLOADED hLoadedRsrc); int KLDRWINAPI kLdrWFreeResource(HKLDRMOD hMod, HKLDRWRSRCLOADED hLoadedRsrc); typedef int (KLDRWINAPI *PFNKLDRWENUMRESTYPE)(HKLDRMOD hMod, const char *pszType, uintptr_t uUser); int KLDRWINAPI kLdrWEnumResourceTypes(HKLDRMOD hMod, PFNKLDRWENUMRESTYPE pfnEnum, uintptr_t uUser); int KLDRWINAPI kLdrWEnumResourceTypesEx(HKLDRMOD hMod, PFNKLDRWENUMRESTYPE pfnEnum, uintptr_t uUser, uint32_t fFlags, uint16_t idLang); typedef int (KLDRWINAPI *PFNKLDRWENUMRESNAME)(HKLDRMOD hMod, const char *pszType, char *pszName, uintptr_t uUser); int KLDRWINAPI kLdrWEnumResourceNames(HKLDRMOD hMod, const char *pszType, PFNKLDRWENUMRESNAME pfnEnum, uintptr_t uUser); int KLDRWINAPI kLdrWEnumResourceNamesEx(HKLDRMOD hMod, const char *pszType, PFNKLDRWENUMRESNAME pfnEnum, uintptr_t uUser, uint32_t fFlags, uint16_t idLang); typedef int (KLDRWINAPI *PFNKLDRWENUMRESLANG)(HKLDRMOD hMod, const char *pszType, const char *pszName, uint16_t idLang, uintptr_t uUser); int KLDRWINAPI kLdrWEnumResourceLanguages(HKLDRMOD hMod, const char *pszType, const char *pszName, PFNKLDRWENUMRESLANG pfnEnum, uintptr_t uUser); int KLDRWINAPI kLdrWEnumResourceLanguagesEx(HKLDRMOD hMod, const char *pszType, const char *pszName, PFNKLDRWENUMRESLANG pfnEnum, uintptr_t uUser, uint32_t fFlags, uint16_t idLang); /** @} */ /** @name Process Bootstrapping * @{ */ /** * Argument package from the stub. */ typedef struct KLDREXEARGS { /** Load & search flags, some which will become defaults. */ uint32_t fFlags; /** The default search method. */ KLDRDYLDSEARCH enmSearch; /** The executable file that the stub is supposed to load. */ char szExecutable[260]; /** The default prefix used when searching for DLLs. */ char szDefPrefix[16]; /** The default suffix used when searching for DLLs. */ char szDefSuffix[16]; /** The LD_LIBRARY_PATH prefix for the process.. */ char szLibPath[4096 - sizeof(uint32_t) - sizeof(KLDRDYLDSEARCH) - 16 - 16 - 260]; } KLDREXEARGS, *PKLDREXEARGS; /** Pointer to a const argument package from the stub. */ typedef const KLDREXEARGS *PCKLDREXEARGS; void kLdrLoadExe(PCKLDREXEARGS pArgs, void *pvOS); /** @} */ /** @} */ /** @defgroup grp_kLdrErr kLdr Status Codes * kLdr uses a mix of native status codes and it's own status codes. * A status code of 0 means success, all other status codes means failure. * @{ */ #define KLDR_ERR_BASE 420000 /** The image format is unknown. */ #define KLDR_ERR_UNKNOWN_FORMAT (KLDR_ERR_BASE + 0) /** The MZ image format isn't supported by this kLdr build. */ #define KLDR_ERR_MZ_NOT_SUPPORTED (KLDR_ERR_BASE + 1) /** The NE image format isn't supported by this kLdr build. */ #define KLDR_ERR_NE_NOT_SUPPORTED (KLDR_ERR_BASE + 2) /** The LX image format isn't supported by this kLdr build. */ #define KLDR_ERR_LX_NOT_SUPPORTED (KLDR_ERR_BASE + 3) /** The LE image format isn't supported by this kLdr build. */ #define KLDR_ERR_LE_NOT_SUPPORTED (KLDR_ERR_BASE + 4) /** The PE image format isn't supported by this kLdr build. */ #define KLDR_ERR_PE_NOT_SUPPORTED (KLDR_ERR_BASE + 5) /** The ELF image format isn't supported by this kLdr build. */ #define KLDR_ERR_ELF_NOT_SUPPORTED (KLDR_ERR_BASE + 6) /** The mach-o image format isn't supported by this kLdr build. */ #define KLDR_ERR_MACHO_NOT_SUPPORTED (KLDR_ERR_BASE + 7) /** The FAT image format isn't supported by this kLdr build or * a direct open was attempt without going thru the FAT file provider. * FAT images are also known as Universal Binaries. */ #define KLDR_ERR_FAT_NOT_SUPPORTED (KLDR_ERR_BASE + 8) /** The a.out image format isn't supported by this kLdr build. */ #define KLDR_ERR_AOUT_NOT_SUPPORTED (KLDR_ERR_BASE + 9) /** Invalid parameter to a kLdr API. */ #define KLDR_ERR_INVALID_PARAMETER (KLDR_ERR_BASE + 32) /** Invalid handle parameter to a kLdr API. */ #define KLDR_ERR_INVALID_HANDLE (KLDR_ERR_BASE + 33) /** The module wasn't loaded dynamically. */ #define KLDR_ERR_NOT_LOADED_DYNAMICALLY (KLDR_ERR_BASE + 34) /** The module wasn't found. */ #define KLDR_ERR_MODULE_NOT_FOUND (KLDR_ERR_BASE + 35) /** A prerequisit module wasn't found. */ #define KLDR_ERR_PREREQUISITE_MODULE_NOT_FOUND (KLDR_ERR_BASE + 36) /** The module is being terminated and can therefore not be loaded. */ #define KLDR_ERR_MODULE_TERMINATING (KLDR_ERR_BASE + 37) /** A prerequisit module is being terminated and can therefore not be loaded. */ #define KLDR_ERR_PREREQUISITE_MODULE_TERMINATING (KLDR_ERR_BASE + 38) /** The module initialization failed. */ #define KLDR_ERR_MODULE_INIT_FAILED (KLDR_ERR_BASE + 39) /** The initialization of a prerequisite module failed. */ #define KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED (KLDR_ERR_BASE + 40) /** The module has already failed initialization and can't be attempted reloaded until * after we've finished garbage collection. */ #define KLDR_ERR_MODULE_INIT_FAILED_ALREADY (KLDR_ERR_BASE + 41) /** A prerequisite module has already failed initialization and can't be attempted * reloaded until after we've finished garbage collection. */ #define KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED_ALREADY (KLDR_ERR_BASE + 42) /** Prerequisite recursed too deeply. */ #define KLDR_ERR_PREREQUISITE_RECURSED_TOO_DEEPLY (KLDR_ERR_BASE + 43) /** Failed to allocate the main stack. */ #define KLDR_ERR_MAIN_STACK_ALLOC_FAILED (KLDR_ERR_BASE + 44) /** Buffer overflow. */ #define KLDR_ERR_BUFFER_OVERFLOW (KLDR_ERR_BASE + 45) /** The specified ARCH+CPU isn't compatible with image. */ #define KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE (KLDR_ERR_BASE + 46) /** Symbol not found. */ #define KLDR_ERR_SYMBOL_NOT_FOUND (KLDR_ERR_BASE + 47) /** A forward symbol was encountered but the caller didn't provide any means to resolve it. */ #define KLDR_ERR_FORWARDER_SYMBOL (KLDR_ERR_BASE + 48) /** Encountered a bad fixup. */ #define KLDR_ERR_BAD_FIXUP (KLDR_ERR_BASE + 49) /** A memory allocation failed. */ #define KLDR_ERR_NO_MEMORY (KLDR_ERR_BASE + 50) /** The import ordinal was out of bounds. */ #define KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS (KLDR_ERR_BASE + 51) /** A forwarder chain was too long. */ #define KLDR_ERR_TOO_LONG_FORWARDER_CHAIN (KLDR_ERR_BASE + 52) /** The module has no debug info. */ #define KLDR_ERR_NO_DEBUG_INFO (KLDR_ERR_BASE + 53) /** The module is already mapped. * kLdrModMap() can only be called once (without kLdrModUnmap() in between). */ #define KLDR_ERR_ALREADY_MAPPED (KLDR_ERR_BASE + 54) /** The module was not mapped. * kLdrModUnmap() should not called without being preceeded by a kLdrModMap(). */ #define KLDR_ERR_NOT_MAPPED (KLDR_ERR_BASE + 55) /** Couldn't fit the address value into the field. Typically a relocation kind of error. */ #define KLDR_ERR_ADDRESS_OVERFLOW (KLDR_ERR_BASE + 56) /** Couldn't fit a calculated size value into the native size type of the host. */ #define KLDR_ERR_SIZE_OVERFLOW (KLDR_ERR_BASE + 57) /** Thread attach failed. */ #define KLDR_ERR_THREAD_ATTACH_FAILED (KLDR_ERR_BASE + 58) /** The file reader can't take more concurrent mappings. */ #define KLDR_ERR_TOO_MANY_MAPPINGS (KLDR_ERR_BASE + 59) /** The module wasn't a DLL or object file. */ #define KLDR_ERR_NOT_DLL (KLDR_ERR_BASE + 60) /** The module wasn't an EXE. */ #define KLDR_ERR_NOT_EXE (KLDR_ERR_BASE + 61) /** Not implemented yet. */ #define KLDR_ERR_TODO (KLDR_ERR_BASE + 62) /** @name kLdrModPE status codes * @{ */ #define KLDR_ERR_PE_BASE (KLDR_ERR_BASE + 63) /** The machine isn't supported by the interpreter. */ #define KLDR_ERR_PE_UNSUPPORTED_MACHINE (KLDR_ERR_PE_BASE + 0) /** The file handler isn't valid. */ #define KLDR_ERR_PE_BAD_FILE_HEADER (KLDR_ERR_PE_BASE + 1) /** The the optional headers isn't valid. */ #define KLDR_ERR_PE_BAD_OPTIONAL_HEADER (KLDR_ERR_PE_BASE + 2) /** One of the section headers aren't valid. */ #define KLDR_ERR_PE_BAD_SECTION_HEADER (KLDR_ERR_PE_BASE + 3) /** Bad forwarder entry. */ #define KLDR_ERR_PE_BAD_FORWARDER (KLDR_ERR_PE_BASE + 4) /** Forwarder module not found in the import descriptor table. */ #define KLDR_ERR_PE_FORWARDER_IMPORT_NOT_FOUND (KLDR_ERR_PE_BASE + 5) /** Bad PE fixups. */ #define KLDR_ERR_PE_BAD_FIXUP (KLDR_ERR_PE_BASE + 6) /** Bad PE import (thunk). */ #define KLDR_ERR_PE_BAD_IMPORT (KLDR_ERR_PE_BASE + 7) /** @} */ /** @name kLdrModLX status codes * @{ */ #define KLDR_ERR_LX_BASE (KLDR_ERR_PE_BASE + 8) /** validation of LX header failed. */ #define KLDR_ERR_LX_BAD_HEADER (KLDR_ERR_LX_BASE + 0) /** validation of the loader section (in the LX header) failed. */ #define KLDR_ERR_LX_BAD_LOADER_SECTION (KLDR_ERR_LX_BASE + 1) /** validation of the fixup section (in the LX header) failed. */ #define KLDR_ERR_LX_BAD_FIXUP_SECTION (KLDR_ERR_LX_BASE + 2) /** validation of the LX object table failed. */ #define KLDR_ERR_LX_BAD_OBJECT_TABLE (KLDR_ERR_LX_BASE + 3) /** A bad page map entry was encountered. */ #define KLDR_ERR_LX_BAD_PAGE_MAP (KLDR_ERR_LX_BASE + 4) /** Bad iterdata (EXEPACK) data. */ #define KLDR_ERR_LX_BAD_ITERDATA (KLDR_ERR_LX_BASE + 5) /** Bad iterdata2 (EXEPACK2) data. */ #define KLDR_ERR_LX_BAD_ITERDATA2 (KLDR_ERR_LX_BASE + 6) /** Bad bundle data. */ #define KLDR_ERR_LX_BAD_BUNDLE (KLDR_ERR_LX_BASE + 7) /** No soname. */ #define KLDR_ERR_LX_NO_SONAME (KLDR_ERR_LX_BASE + 8) /** Bad soname. */ #define KLDR_ERR_LX_BAD_SONAME (KLDR_ERR_LX_BASE + 9) /** Bad forwarder entry. */ #define KLDR_ERR_LX_BAD_FORWARDER (KLDR_ERR_LX_BASE + 10) /** internal fixup chain isn't implemented yet. */ #define KLDR_ERR_LX_NRICHAIN_NOT_SUPPORTED (KLDR_ERR_LX_BASE + 11) /** @} */ /** @name * @{ */ #define KLDR_ERR_MACHO_BASE (KLDR_ERR_LX_BASE + 12) /** Only native endian Mach-O files are supported. */ #define KLDR_ERR_MACHO_OTHER_ENDIAN_NOT_SUPPORTED (KLDR_ERR_MACHO_BASE + 0) /** 64-bit Mach-O files aren't supported yet. */ #define KLDR_ERR_MACHO_64BIT_NOT_SUPPORTED (KLDR_ERR_MACHO_BASE + 1) /** The Mach-O header is bad or contains new and unsupported features. */ #define KLDR_ERR_MACHO_BAD_HEADER (KLDR_ERR_MACHO_BASE + 2) /** The file type isn't supported. */ #define KLDR_ERR_MACHO_UNSUPPORTED_FILE_TYPE (KLDR_ERR_MACHO_BASE + 3) /** The machine (cputype / cpusubtype combination) isn't supported. */ #define KLDR_ERR_MACHO_UNSUPPORTED_MACHINE (KLDR_ERR_MACHO_BASE + 4) /** Bad load command(s). */ #define KLDR_ERR_MACHO_BAD_LOAD_COMMAND (KLDR_ERR_MACHO_BASE + 5) /** Encountered an unknown load command.*/ #define KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND (KLDR_ERR_MACHO_BASE + 6) /** Encountered a load command that's not implemented.*/ #define KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND (KLDR_ERR_MACHO_BASE + 7) /** Bad section. */ #define KLDR_ERR_MACHO_BAD_SECTION (KLDR_ERR_MACHO_BASE + 8) /** Encountered a section type that's not implemented.*/ #define KLDR_ERR_MACHO_UNSUPPORTED_SECTION (KLDR_ERR_MACHO_BASE + 9) /** Encountered a section type that's not known to the loader. (probably invalid) */ #define KLDR_ERR_MACHO_UNKNOWN_SECTION (KLDR_ERR_MACHO_BASE + 10) /** The sections aren't ordered by segment as expected by the loader. */ #define KLDR_ERR_MACHO_BAD_SECTION_ORDER (KLDR_ERR_MACHO_BASE + 11) /** The image is 32-bit and contains 64-bit load commands or vise versa. */ #define KLDR_ERR_MACHO_BIT_MIX (KLDR_ERR_MACHO_BASE + 12) /** Bad MH_OBJECT file. */ #define KLDR_ERR_MACHO_BAD_OBJECT_FILE (KLDR_ERR_MACHO_BASE + 13) /** Bad symbol table entry. */ #define KLDR_ERR_MACHO_BAD_SYMBOL (KLDR_ERR_MACHO_BASE + 14) /** Unsupported fixup type. */ #define KLDR_ERR_MACHO_UNSUPPORTED_FIXUP_TYPE (KLDR_ERR_MACHO_BASE + 15) /** @} */ /** End of the valid kLdr status codes. */ #define KLDR_ERR_END (KLDR_ERR_MACHO_BASE + 16) const char *kLdrErrStr(int rc); /** @} */ #ifdef __cplusplus } #endif #endif