From 29cd838eab01ed7110f3ccb2e8c6a35c8a31dbcc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:21:29 +0200 Subject: Adding upstream version 1:0.1.9998svn3589+dfsg. Signed-off-by: Daniel Baumann --- src/lib/kStuff/include/k/kLdr.h | 959 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 959 insertions(+) create mode 100644 src/lib/kStuff/include/k/kLdr.h (limited to 'src/lib/kStuff/include/k/kLdr.h') diff --git a/src/lib/kStuff/include/k/kLdr.h b/src/lib/kStuff/include/k/kLdr.h new file mode 100644 index 0000000..4aefb66 --- /dev/null +++ b/src/lib/kStuff/include/k/kLdr.h @@ -0,0 +1,959 @@ +/* $Id: kLdr.h 117 2020-03-15 15:23:36Z bird $ */ +/** @file + * kLdr - The Dynamic Loader. + */ + +/* + * Copyright (c) 2006-2007 Knut St. Osmundsen + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef ___k_kLdr_h___ +#define ___k_kLdr_h___ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Include the base typedefs and macros. + */ +#include +#include +#include + + +/** @defgroup grp_kLdrBasic kLdr Basic Types + * @{ */ + +/** The kLdr address type. */ +typedef KU64 KLDRADDR; +/** Pointer to a kLdr address. */ +typedef KLDRADDR *PKLDRADDR; +/** Pointer to a const kLdr address. */ +typedef const KLDRADDR *PCKLDRADDR; + +/** NIL address. */ +#define NIL_KLDRADDR (~(KU64)0) + +/** @def PRI_KLDRADDR + * printf format type. */ +#ifdef _MSC_VER +# define PRI_KLDRADDR "I64x" +#else +# define PRI_KLDRADDR "llx" +#endif + +/** Align a KSIZE value. */ +#define KLDR_ALIGN_ADDR(val, align) ( ((val) + ((align) - 1)) & ~(KLDRADDR)((align) - 1) ) + + +/** The kLdr size type. */ +typedef KU64 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 +{ + KI8 i8; /**< KI8 view. */ + KU8 u8; /**< KU8 view. */ + KI16 i16; /**< KI16 view. */ + KU16 u16; /**< KU16 view. */ + KI32 i32; /**< KI32 view. */ + KU32 u32; /**< KU32 view. */ + KI64 i64; /**< KI64 view. */ + KU64 u64; /**< KU64 view. */ + + KI8 ai8[8]; /**< KI8 array view . */ + KU8 au8[8]; /**< KU8 array view. */ + KI16 ai16[4];/**< KI16 array view . */ + KU16 au16[4];/**< KU16 array view. */ + KI32 ai32[2];/**< KI32 array view . */ + KU32 au32[2];/**< KU32 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 +{ + KI8 *pi8; /**< KI8 view. */ + KU8 *pu8; /**< KU8 view. */ + KI16 *pi16; /**< KI16 view. */ + KU16 *pu16; /**< KU16 view. */ + KI32 *pi32; /**< KI32 view. */ + KU32 *pu32; /**< KU32 view. */ + KI64 *pi64; /**< KI64 view. */ + KU64 *pu64; /**< KU64 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; + +/** @} */ + + +/** @defgroup grp_kLdrMod kLdrMod - The executable image intepreter + * @{ */ + +/** + * 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. */ + KU32 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. */ + KU16 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. */ + KU16 Sel16bit; + /** Segment flags. */ + KU32 fFlags; + /** The segment protection. */ + KPROT 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. */ + KSIZE cbMapped; + /** The address the segment was mapped at by kLdrModMap(). + * Set to 0 if not mapped. */ + KUPTR 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, + /** Debug module (debug info with empty code & data segments). */ + KLDRTYPE_DEBUG_INFO, + /** 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; + + +/** @name KLDRMOD::fFlags + * @{ */ +/** The link address doesn't form a contiguous image, from the first to the + * last segment. */ +#define KLDRMOD_FLAGS_NON_CONTIGUOUS_LINK_ADDRS K_BIT32(0) +/** @} */ + +/** 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). */ + KU32 u32Magic; + /** The format of this module. */ + KLDRFMT enmFmt; + /** The type of module. */ + KLDRTYPE enmType; + /** The CPU architecture this module was built for. */ + KCPUARCH enmArch; + /** The minium cpu this module was built for. + * This might not be accurate, so use kLdrModCanExecuteOn() to check. */ + KCPU enmCpu; + /** The endian used by the module. */ + KLDRENDIAN enmEndian; + /** Module open flags, KLDRMOD_OPEN_FLAGS_XXX. */ + KU32 fFlags; + /** The filename length (bytes). */ + KU32 cchFilename; + /** The filename. */ + const char *pszFilename; + /** The module name. */ + const char *pszName; + /** The module name length (bytes). */ + KU32 cchName; + /** The number of segments in the module. */ + KU32 cSegments; + /** Pointer to the loader methods. + * Not meant for calling directly thru! */ + PCKLDRMODOPS pOps; + /** Pointer to the read instance. (Can be NULL after kLdrModDone().)*/ + PKRDR 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 (~(KU32)0) + +/** Special symbol ordinal value used to indicate that the symbol + * only has a string name. */ +#define NIL_KLDRMOD_SYM_ORDINAL (~(KU32)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, KU32 iImport, KU32 iSymbol, const char *pchSymbol, KSIZE cchSymbol, + const char *pszVersion, PKLDRADDR puValue, KU32 *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, KU32 iSymbol, const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion, + KLDRADDR uValue, KU32 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 pszPartNm The name of the debug info part, NULL if not applicable. + * @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, KU32 iDbgInfo, KLDRDBGINFOTYPE enmType, KI16 iMajorVer, KI16 iMinorVer, + const char *pszPartNm, 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, KU32 idType, const char *pszType, KU32 idName, const char *pszName, + KU32 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 ( ~(KU32)0 ) +/** NIL resource type ID. */ +#define NIL_KLDRMOD_RSRC_TYPE_ID ( ~(KU32)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 ( ~(KU32)0 ) +/** Special language id value for matching any language. */ +#define KLDR_LANG_ID_ANY ( ~(KU32)1 ) +/** Special language id value indicating language neutral. */ +#define KLDR_LANG_ID_NEUTRAL ( ~(KU32)2 ) +/** Special language id value indicating user default language. */ +#define KLDR_LANG_ID_USER_DEFAULT ( ~(KU32)3 ) +/** Special language id value indicating system default language. */ +#define KLDR_LANG_ID_SYS_DEFAULT ( ~(KU32)4 ) +/** Special language id value indicating default custom locale. */ +#define KLDR_LANG_ID_CUSTOM_DEFAULT ( ~(KU32)5 ) +/** Special language id value indicating unspecified custom locale. */ +#define KLDR_LANG_ID_CUSTOM_UNSPECIFIED ( ~(KU32)6 ) +/** Special language id value indicating default custom MUI locale. */ +#define KLDR_LANG_ID_UI_CUSTOM_DEFAULT ( ~(KU32)7 ) +/** @} */ + +/** @name KLDRMOD_OPEN_FLAGS_XXX - Module Open Flags + * @{ */ +/** Indicates that we won't be loading the module, we're just getting + * information (like symbols and line numbers) out of it. */ +#define KLDRMOD_OPEN_FLAGS_FOR_INFO K_BIT32(0) +/** Native: Non-stub kLdrModCallInit & kLdrModCallTerm. */ +#define KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM K_BIT32(1) +/** Mask of valid flags. */ +#define KLDRMOD_OPEN_FLAGS_VALID_MASK KU32_C(0x00000003) +/** @} */ + +int kLdrModOpen(const char *pszFilename, KU32 fFlags, KCPUARCH enmCpuArch, PPKLDRMOD ppMod); +int kLdrModOpenFromRdr(PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, PPKLDRMOD ppMod); +int kLdrModOpenNative(const char *pszFilename, KU32 fFlags, PPKLDRMOD ppMod); +int kLdrModOpenNativeByHandle(KUPTR uHandle, KU32 fFlags, PPKLDRMOD ppMod); +int kLdrModClose(PKLDRMOD pMod); + +int kLdrModQuerySymbol(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 iSymbol, + const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion, + PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, KU32 *pfKind); +int kLdrModEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, + KU32 fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser); +int kLdrModGetImport(PKLDRMOD pMod, const void *pvBits, KU32 iImport, char *pszName, KSIZE cchName); +KI32 kLdrModNumberOfImports(PKLDRMOD pMod, const void *pvBits); +int kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KCPUARCH enmArch, KCPU enmCpu); +int kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo); +int kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress); +int kLdrModQueryImageUuid(PKLDRMOD pMod, const void *pvBits, void *pvUuid, KSIZE cbUuid); +int kLdrModQueryResource(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 idType, const char *pszType, + KU32 idName, const char *pszName, KU32 idLang, PKLDRADDR pAddrRsrc, KSIZE *pcbRsrc); +int kLdrModEnumResources(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 idType, const char *pszType, + KU32 idName, const char *pszName, KU32 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 kLdrModReload(PKLDRMOD pMod); +int kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); +/** @} */ + +/** @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); +/** @} */ + +/** @name Operations on both internally and externally managed mappings. + * @{ */ +/** Special pvMapping value to pass to kLdrModAllocTLS, + * kLdrModFreeTLS, kLdrModCallInit, kLdrModCallTerm, and kLdrModCallThread that + * specifies the internal mapping (kLdrModMap). */ +#define KLDRMOD_INT_MAP ((void *)~(KUPTR)0) +int kLdrModAllocTLS(PKLDRMOD pMod, void *pvMapping); +void kLdrModFreeTLS(PKLDRMOD pMod, void *pvMapping); +int kLdrModCallInit(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle); +int kLdrModCallTerm(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle); +int kLdrModCallThread(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle, unsigned fAttachingOrDetaching); +/** @} */ + + +/** + * 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 fFlags Flags, MBZ. + * @param enmCpuArch The desired CPU architecture. KCPUARCH_UNKNOWN means + * anything goes, but with a preference for the current + * host architecture. + * @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, PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, 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, KU32 iSymbol, + const char *pchSymbol, KSIZE cchSymbol, const char *pszVersion, + PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, KU32 *pfKind); + /** @copydoc kLdrModEnumSymbols */ + int (* pfnEnumSymbols)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 fFlags, + PFNKLDRMODENUMSYMS pfnCallback, void *pvUser); + /** @copydoc kLdrModGetImport */ + int (* pfnGetImport)(PKLDRMOD pMod, const void *pvBits, KU32 iImport, char *pszName, KSIZE cchName); + /** @copydoc kLdrModNumberOfImports */ + KI32 (* pfnNumberOfImports)(PKLDRMOD pMod, const void *pvBits); + /** @copydoc kLdrModCanExecuteOn */ + int (* pfnCanExecuteOn)(PKLDRMOD pMod, const void *pvBits, KCPUARCH enmArch, KCPU 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 kLdrModQueryImageUuid */ + int (* pfnQueryImageUuid)(PKLDRMOD pMod, const void *pvBits, void *pvUuid, KSIZE pcbUuid); + /** @copydoc kLdrModQueryResource */ + int (* pfnQueryResource)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 idType, const char *pszType, + KU32 idName, const char *pszName, KU32 idLang, PKLDRADDR pAddrRsrc, KSIZE *pcbRsrc); + /** @copydoc kLdrModEnumResources */ + int (* pfnEnumResources)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, KU32 idType, const char *pszType, + KU32 idName, const char *pszName, KU32 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, void *pvMapping); + /** @copydoc kLdrModFreeTLS */ + void (*pfnFreeTLS)(PKLDRMOD pMod, void *pvMapping); + /** @copydoc kLdrModReload */ + int (* pfnReload)(PKLDRMOD pMod); + /** @copydoc kLdrModFixupMapping */ + int (* pfnFixupMapping)(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); + /** @copydoc kLdrModCallInit */ + int (* pfnCallInit)(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle); + /** @copydoc kLdrModCallTerm */ + int (* pfnCallTerm)(PKLDRMOD pMod, void *pvMapping, KUPTR uHandle); + /** @copydoc kLdrModCallThread */ + int (* pfnCallThread)(PKLDRMOD pMod, void *pvMapping, KUPTR 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. */ + KU32 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, KSIZE cchErr); +int kLdrDyldUnload(HKLDRMOD hMod); +int kLdrDyldFindByName(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch, + unsigned fFlags, PHKLDRMOD phMod); +int kLdrDyldFindByAddress(KUPTR Address, PHKLDRMOD phMod, KU32 *piSegment, KUPTR *poffSegment); +int kLdrDyldGetName(HKLDRMOD hMod, char *pszName, KSIZE cchName); +int kLdrDyldGetFilename(HKLDRMOD hMod, char *pszFilename, KSIZE cchFilename); +int kLdrDyldQuerySymbol(HKLDRMOD hMod, KU32 uSymbolOrdinal, const char *pszSymbolName, + const char *pszSymbolVersion, KUPTR *pValue, KU32 *pfKind); +int kLdrDyldQueryResource(HKLDRMOD hMod, KU32 idType, const char *pszType, KU32 idName, + const char *pszName, KU32 idLang, void **pvRsrc, KSIZE *pcbRsrc); +int kLdrDyldEnumResources(HKLDRMOD hMod, KU32 idType, const char *pszType, KU32 idName, + const char *pszName, KU32 idLang, PFNKLDRENUMRSRC pfnCallback, void *pvUser); + + +/** @name OS/2 like API + * @{ */ +#if defined(__OS2__) +# define KLDROS2API _System +#else +# define KLDROS2API +#endif +int kLdrDosLoadModule(char *pszObject, KSIZE cbObject, const char *pszModule, PHKLDRMOD phMod); +int kLdrDosFreeModule(HKLDRMOD hMod); +int kLdrDosQueryModuleHandle(const char *pszModname, PHKLDRMOD phMod); +int kLdrDosQueryModuleName(HKLDRMOD hMod, KSIZE cchName, char *pszName); +int kLdrDosQueryProcAddr(HKLDRMOD hMod, KU32 iOrdinal, const char *pszProcName, void **ppvProcAddr); +int kLdrDosQueryProcType(HKLDRMOD hMod, KU32 iOrdinal, const char *pszProcName, KU32 *pfProcType); +int kLdrDosQueryModFromEIP(PHKLDRMOD phMod, KU32 *piObject, KSIZE cbName, char *pszName, KUPTR *poffObject, KUPTR ulEIP); +int kLdrDosReplaceModule(const char *pszOldModule, const char *pszNewModule, const char *pszBackupModule); +int kLdrDosGetResource(HKLDRMOD hMod, KU32 idType, KU32 idName, void **pvResAddr); +int kLdrDosQueryResourceSize(HKLDRMOD hMod, KU32 idType, KU32 idName, KU32 *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, KU32 fFlags); +KU32 KLDRWINAPI kLdrWGetModuleFileName(HKLDRMOD hMod, char *pszModName, KSIZE cchModName); +HKLDRMOD KLDRWINAPI kLdrWGetModuleHandle(const char *pszFilename); +int KLDRWINAPI kLdrWGetModuleHandleEx(KU32 fFlags, const char *pszFilename, HKLDRMOD hMod); +void * KLDRWINAPI kLdrWGetProcAddress(HKLDRMOD hMod, const char *pszProcName); +KU32 KLDRWINAPI kLdrWGetDllDirectory(KSIZE 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, KU16 idLang); +KU32 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, KUPTR uUser); +int KLDRWINAPI kLdrWEnumResourceTypes(HKLDRMOD hMod, PFNKLDRWENUMRESTYPE pfnEnum, KUPTR uUser); +int KLDRWINAPI kLdrWEnumResourceTypesEx(HKLDRMOD hMod, PFNKLDRWENUMRESTYPE pfnEnum, KUPTR uUser, KU32 fFlags, KU16 idLang); + +typedef int (KLDRWINAPI *PFNKLDRWENUMRESNAME)(HKLDRMOD hMod, const char *pszType, char *pszName, KUPTR uUser); +int KLDRWINAPI kLdrWEnumResourceNames(HKLDRMOD hMod, const char *pszType, PFNKLDRWENUMRESNAME pfnEnum, KUPTR uUser); +int KLDRWINAPI kLdrWEnumResourceNamesEx(HKLDRMOD hMod, const char *pszType, PFNKLDRWENUMRESNAME pfnEnum, KUPTR uUser, KU32 fFlags, KU16 idLang); + +typedef int (KLDRWINAPI *PFNKLDRWENUMRESLANG)(HKLDRMOD hMod, const char *pszType, const char *pszName, KU16 idLang, KUPTR uUser); +int KLDRWINAPI kLdrWEnumResourceLanguages(HKLDRMOD hMod, const char *pszType, const char *pszName, PFNKLDRWENUMRESLANG pfnEnum, KUPTR uUser); +int KLDRWINAPI kLdrWEnumResourceLanguagesEx(HKLDRMOD hMod, const char *pszType, const char *pszName, + PFNKLDRWENUMRESLANG pfnEnum, KUPTR uUser, KU32 fFlags, KU16 idLang); +/** @} */ + + +/** @name Process Bootstrapping + * @{ */ + +/** + * Argument package from the stub. + */ +typedef struct KLDREXEARGS +{ + /** Load & search flags, some which will become defaults. */ + KU32 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(KU32) - 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); /** @todo fix this mess... */ +void kLdrDyldLoadExe(PCKLDREXEARGS pArgs, void *pvOS); +/** @} */ + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif + -- cgit v1.2.3