ldr.h revision 0c8e85263a357c44964520942cb5816ab1c2e69d
/* $Id$ */
/** @file
* IPRT - Loader Internals.
*/
/*
* Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#ifndef ___internal_ldr_h
#define ___internal_ldr_h
#include <iprt/types.h>
#include "internal/magics.h"
RT_C_DECLS_BEGIN
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
#ifdef DOXYGEN_RUNNING
/** @def LDR_WITH_NATIVE
* Define this to get native support. */
# define LDR_WITH_NATIVE
/** @def LDR_WITH_ELF32
* Define this to get 32-bit ELF support. */
# define LDR_WITH_ELF32
/** @def LDR_WITH_ELF64
* Define this to get 64-bit ELF support. */
# define LDR_WITH_ELF64
/** @def LDR_WITH_PE
* Define this to get 32-bit and 64-bit PE support. */
# define LDR_WITH_PE
/** @def LDR_WITH_LX
* Define this to get LX support. */
# define LDR_WITH_LX
/** @def LDR_WITH_MACHO
* Define this to get mach-o support (not implemented yet). */
# define LDR_WITH_MACHO
#endif /* DOXYGEN_RUNNING */
#if defined(LDR_WITH_ELF32) || defined(LDR_WITH_ELF64)
/** @def LDR_WITH_ELF
* This is defined if any of the ELF versions is requested.
*/
# define LDR_WITH_ELF
#endif
/* These two may clash with winnt.h. */
#undef IMAGE_DOS_SIGNATURE
#undef IMAGE_NT_SIGNATURE
/** Little endian uint32_t ELF signature ("\x7fELF"). */
#define IMAGE_ELF_SIGNATURE (0x7f | ('E' << 8) | ('L' << 16) | ('F' << 24))
/** Little endian uint32_t PE signature ("PE\0\0"). */
#define IMAGE_NT_SIGNATURE 0x00004550
/** Little endian uint16_t LX signature ("LX") */
#define IMAGE_LX_SIGNATURE ('L' | ('X' << 8))
/** Little endian uint16_t LE signature ("LE") */
#define IMAGE_LE_SIGNATURE ('L' | ('E' << 8))
/** Little endian uint16_t NE signature ("NE") */
#define IMAGE_NE_SIGNATURE ('N' | ('E' << 8))
/** Little endian uint16_t MZ signature ("MZ"). */
#define IMAGE_DOS_SIGNATURE ('M' | ('Z' << 8))
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* Loader state.
*/
typedef enum RTLDRSTATE
{
/** Invalid. */
LDR_STATE_INVALID = 0,
/** Opened. */
LDR_STATE_OPENED,
/** The image can no longer be relocated. */
LDR_STATE_DONE,
/** The image was loaded, not opened. */
LDR_STATE_LOADED,
/** The usual 32-bit hack. */
LDR_STATE_32BIT_HACK = 0x7fffffff
} RTLDRSTATE;
/** Pointer to a loader item. */
typedef struct RTLDRMODINTERNAL *PRTLDRMODINTERNAL;
/**
* Loader module operations.
*/
typedef struct RTLDROPS
{
/** The name of the executable format. */
const char *pszName;
/**
* Release any resources attached to the module.
* The caller will do RTMemFree on pMod on return.
*
* @returns iprt status code.
* @param pMod Pointer to the loader module structure.
* @remark Compulsory entry point.
*/
DECLCALLBACKMEMBER(int, pfnClose)(PRTLDRMODINTERNAL pMod);
/**
* Gets a simple symbol.
* This entrypoint can be omitted if RTLDROPS::pfnGetSymbolEx() is provided.
*
* @returns iprt status code.
* @param pMod Pointer to the loader module structure.
* @param pszSymbol The symbol name.
* @param ppvValue Where to store the symbol value.
*/
DECLCALLBACKMEMBER(int, pfnGetSymbol)(PRTLDRMODINTERNAL pMod, const char *pszSymbol, void **ppvValue);
/**
* Called when we're done with getting bits and relocating them.
* This is used to release resources used by the loader to support those actions.
*
* After this call none of the extended loader functions can be called.
*
* @returns iprt status code.
* @param pMod Pointer to the loader module structure.
* @remark This is an optional entry point.
*/
DECLCALLBACKMEMBER(int, pfnDone)(PRTLDRMODINTERNAL pMod);
/**
* Enumerates the symbols exported by the module.
*
* @returns iprt status code, which might have been returned by pfnCallback.
* @param pMod Pointer to the loader module structure.
* @param fFlags Flags indicating what to return and such.
* @param pvBits Pointer to the bits returned by RTLDROPS::pfnGetBits(), optional.
* @param BaseAddress The image base addressto use when calculating the symbol values.
* @param pfnCallback The callback function which each symbol is to be
* fed to.
* @param pvUser User argument to pass to the enumerator.
* @remark This is an optional entry point.
*/
DECLCALLBACKMEMBER(int, pfnEnumSymbols)(PRTLDRMODINTERNAL pMod, unsigned fFlags, const void *pvBits, RTUINTPTR BaseAddress,
PFNRTLDRENUMSYMS pfnCallback, void *pvUser);
/* extended functions: */
/**
* Gets the size of the loaded image (i.e. in memory).
*
* @returns in memory size, in bytes.
* @returns ~(size_t)0 if it's not an extended image.
* @param pMod Pointer to the loader module structure.
* @remark Extended loader feature.
*/
DECLCALLBACKMEMBER(size_t, pfnGetImageSize)(PRTLDRMODINTERNAL pMod);
/**
* Gets the image bits fixed up for a specified address.
*
* @returns iprt status code.
* @param pMod Pointer to the loader module structure.
* @param pvBits Where to store the bits. The size of this buffer is equal or
* larger to the value returned by pfnGetImageSize().
* @param BaseAddress The base address which the image should be fixed up to.
* @param pfnGetImport The callback function to use to resolve imports (aka unresolved externals).
* @param pvUser User argument to pass to the callback.
* @remark Extended loader feature.
*/
DECLCALLBACKMEMBER(int, pfnGetBits)(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR BaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser);
/**
* Relocate bits obtained using pfnGetBits to a new address.
*
* @returns iprt status code.
* @param pMod Pointer to the loader module structure.
* @param pvBits Where to store the bits. The size of this buffer is equal or
* larger to the value returned by pfnGetImageSize().
* @param NewBaseAddress The base address which the image should be fixed up to.
* @param OldBaseAddress The base address which the image is currently fixed up to.
* @param pfnGetImport The callback function to use to resolve imports (aka unresolved externals).
* @param pvUser User argument to pass to the callback.
* @remark Extended loader feature.
*/
DECLCALLBACKMEMBER(int, pfnRelocate)(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR NewBaseAddress, RTUINTPTR OldBaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser);
/**
* Gets a symbol with special base address and stuff.
* This entrypoint can be omitted if RTLDROPS::pfnGetSymbolEx() is provided and the special BaseAddress feature isn't supported.
*
* @returns iprt status code.
* @retval VERR_LDR_FORWARDER forwarder, use pfnQueryForwarderInfo. Buffer size
* in @a pValue.
* @param pMod Pointer to the loader module structure.
* @param pvBits Pointer to bits returned by RTLDROPS::pfnGetBits(), optional.
* @param BaseAddress The image base address to use when calculating the symbol value.
* @param iOrdinal Symbol table ordinal, UINT32_MAX if the symbol name
* should be used.
* @param pszSymbol The symbol name.
* @param pValue Where to store the symbol value.
* @remark Extended loader feature.
*/
DECLCALLBACKMEMBER(int, pfnGetSymbolEx)(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress,
uint32_t iOrdinal, const char *pszSymbol, RTUINTPTR *pValue);
/**
* Query forwarder information on the specified symbol.
*
* This is an optional entrypoint.
*
* @returns iprt status code.
* @param pMod Pointer to the loader module structure.
* @param pvBits Pointer to bits returned by RTLDROPS::pfnGetBits(),
* optional.
* @param iOrdinal Symbol table ordinal of the forwarded symbol to query.
* UINT32_MAX if the symbol name should be used.
* @param pszSymbol The symbol name of the forwarded symbol to query.
* @param pInfo Where to return the forwarder information.
* @param cbInfo The size of the pInfo buffer. The pfnGetSymbolEx
* entrypoint returns the required size in @a pValue when
* the return code is VERR_LDR_FORWARDER.
* @remark Extended loader feature.
*/
DECLCALLBACKMEMBER(int, pfnQueryForwarderInfo)(PRTLDRMODINTERNAL pMod, const void *pvBits, uint32_t iOrdinal,
const char *pszSymbol, PRTLDRIMPORTINFO pInfo, size_t cbInfo);
/**
* Enumerates the debug info contained in the module.
*
* @returns iprt status code, which might have been returned by pfnCallback.
* @param pMod Pointer to the loader module structure.
* @param pvBits Pointer to the bits returned by RTLDROPS::pfnGetBits(), optional.
* @param pfnCallback The callback function which each debug info part is
* to be fed to.
* @param pvUser User argument to pass to the enumerator.
* @remark This is an optional entry point that can be NULL.
*/
DECLCALLBACKMEMBER(int, pfnEnumDbgInfo)(PRTLDRMODINTERNAL pMod, const void *pvBits,
PFNRTLDRENUMDBG pfnCallback, void *pvUser);
/**
* Enumerates the segments in the module.
*
* @returns iprt status code, which might have been returned by pfnCallback.
* @param pMod Pointer to the loader module structure.
* @param pfnCallback The callback function which each debug info part is
* to be fed to.
* @param pvUser User argument to pass to the enumerator.
* @remark This is an optional entry point that can be NULL.
*/
DECLCALLBACKMEMBER(int, pfnEnumSegments)(PRTLDRMODINTERNAL pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser);
/**
* Converts a link address to a segment:offset address.
*
* @returns IPRT status code.
*
* @param pMod Pointer to the loader module structure.
* @param LinkAddress The link address to convert.
* @param piSeg Where to return the segment index.
* @param poffSeg Where to return the segment offset.
* @remark This is an optional entry point that can be NULL.
*/
DECLCALLBACKMEMBER(int, pfnLinkAddressToSegOffset)(PRTLDRMODINTERNAL pMod, RTLDRADDR LinkAddress,
uint32_t *piSeg, PRTLDRADDR poffSeg);
/**
* Converts a link address to a RVA.
*
* @returns IPRT status code.
*
* @param pMod Pointer to the loader module structure.
* @param LinkAddress The link address to convert.
* @param pRva Where to return the RVA.
* @remark This is an optional entry point that can be NULL.
*/
DECLCALLBACKMEMBER(int, pfnLinkAddressToRva)(PRTLDRMODINTERNAL pMod, RTLDRADDR LinkAddress, PRTLDRADDR pRva);
/**
* Converts a segment:offset to a RVA.
*
* @returns IPRT status code.
*
* @param pMod Pointer to the loader module structure.
* @param iSeg The segment index.
* @param offSeg The segment offset.
* @param pRva Where to return the RVA.
* @remark This is an optional entry point that can be NULL.
*/
DECLCALLBACKMEMBER(int, pfnSegOffsetToRva)(PRTLDRMODINTERNAL pMod, uint32_t iSeg, RTLDRADDR offSeg, PRTLDRADDR pRva);
/**
* Converts a RVA to a segment:offset.
*
* @returns IPRT status code.
*
* @param pMod Pointer to the loader module structure.
* @param Rva The RVA to convert.
* @param piSeg Where to return the segment index.
* @param poffSeg Where to return the segment offset.
* @remark This is an optional entry point that can be NULL.
*/
DECLCALLBACKMEMBER(int, pfnRvaToSegOffset)(PRTLDRMODINTERNAL pMod, RTLDRADDR Rva, uint32_t *piSeg, PRTLDRADDR poffSeg);
/**
* Reads a debug info part (section) from the image.
*
* This is primarily needed for getting DWARF sections in ELF image with fixups
* applied and won't be required by most other loader backends.
*
* @returns IPRT status code.
*
* @param pMod Pointer to the loader module structure.
* @param pvBuf The buffer to read into.
* @param iDbgInfo The debug info ordinal number if the request
* corresponds exactly to a debug info part from
* pfnEnumDbgInfo. Otherwise, pass UINT32_MAX.
* @param off The offset into the image file.
* @param cb The number of bytes to read.
* @param pMod Pointer to the loader module structure.
*/
DECLCALLBACKMEMBER(int, pfnReadDbgInfo)(PRTLDRMODINTERNAL pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void *pvBuf);
/**
* Generic method for querying image properties.
*
* @returns IPRT status code.
* @retval VERR_NOT_SUPPORTED if the property query isn't supported (either all
* or that specific property).
* @retval VERR_NOT_FOUND the property was not found in the module.
*
* @param pMod Pointer to the loader module structure.
* @param enmLdrProp The property to query (valid).
* @param pvBuf Pointer to the return buffer (valid).
* @param cbBuf The size of the return buffer (valid as per
* property).
* @param pcbRet The number of bytes actually returned. If
* VERR_BUFFER_OVERFLOW is returned, this is set to the
* required buffer size.
*/
DECLCALLBACKMEMBER(int, pfnQueryProp)(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void *pvBuf, size_t cbBuf, size_t *pcbRet);
/**
* Verify the image signature.
*
* This may permform additional integrity checks on the image structures that
* was not done when opening the image.
*
* @returns IPRT status code.
* @retval VERR_LDRVI_NOT_SIGNED if not signed.
*
* @param pMod Pointer to the loader module structure.
* @param pfnCallback Callback that does the signature and certificate
* verficiation.
* @param pvUser User argument for the callback.
* @param pErrInfo Pointer to an error info buffer. Optional.
*/
DECLCALLBACKMEMBER(int, pfnVerifySignature)(PRTLDRMODINTERNAL pMod, PFNRTLDRVALIDATESIGNEDDATA pfnCallback, void *pvUser,
PRTERRINFO pErrInfo);
/**
* Calculate the image hash according the image signing rules.
*
* @returns IPRT status code.
* @param hLdrMod The module handle.
* @param enmDigest Which kind of digest.
* @param pszDigest Where to store the image digest.
* @param cbDigest Size of the buffer @a pszDigest points at.
*/
DECLCALLBACKMEMBER(int, pfnHashImage)(PRTLDRMODINTERNAL pMod, RTDIGESTTYPE enmDigest, char *pszDigest, size_t cbDigest);
/** Dummy entry to make sure we've initialized it all. */
RTUINT uDummy;
} RTLDROPS;
typedef RTLDROPS *PRTLDROPS;
typedef const RTLDROPS *PCRTLDROPS;
/**
* Loader module core.
*/
typedef struct RTLDRMODINTERNAL
{
/** The loader magic value (RTLDRMOD_MAGIC). */
uint32_t u32Magic;
/** State. */
RTLDRSTATE eState;
/** Loader ops. */
PCRTLDROPS pOps;
/** Pointer to the reader instance. This is NULL for native image. */
PRTLDRREADER pReader;
/** Image format. */
RTLDRFMT enmFormat;
/** Image type. */
RTLDRTYPE enmType;
/** Image endianness. */
RTLDRENDIAN enmEndian;
/** Image target architecture. */
RTLDRARCH enmArch;
} RTLDRMODINTERNAL;
/**
* Validates that a loader module handle is valid.
*
* @returns true if valid.
* @returns false if invalid.
* @param hLdrMod The loader module handle.
*/
DECLINLINE(bool) rtldrIsValid(RTLDRMOD hLdrMod)
{
return VALID_PTR(hLdrMod)
&& ((PRTLDRMODINTERNAL)hLdrMod)->u32Magic == RTLDRMOD_MAGIC;
}
/**
* Native loader module.
*/
typedef struct RTLDRMODNATIVE
{
/** The core structure. */
RTLDRMODINTERNAL Core;
/** The native handle. */
uintptr_t hNative;
/** The load flags (RTLDRLOAD_FLAGS_XXX). */
uint32_t fFlags;
} RTLDRMODNATIVE;
/** Pointer to a native module. */
typedef RTLDRMODNATIVE *PRTLDRMODNATIVE;
/** @copydoc RTLDROPS::pfnGetSymbol */
DECLCALLBACK(int) rtldrNativeGetSymbol(PRTLDRMODINTERNAL pMod, const char *pszSymbol, void **ppvValue);
/** @copydoc RTLDROPS::pfnClose */
DECLCALLBACK(int) rtldrNativeClose(PRTLDRMODINTERNAL pMod);
/**
* Load a native module using the native loader.
*
* @returns iprt status code.
* @param pszFilename The image filename.
* @param phHandle Where to store the module handle on success.
* @param fFlags RTLDRLOAD_FLAGS_XXX.
* @param pErrInfo Where to return extended error information. Optional.
*/
int rtldrNativeLoad(const char *pszFilename, uintptr_t *phHandle, uint32_t fFlags, PRTERRINFO pErrInfo);
/**
* Load a system library.
*
* @returns iprt status code.
* @param pszFilename The image filename.
* @param pszExt Extension to add. NULL if none.
* @param fFlags RTLDRLOAD_FLAGS_XXX.
* @param phLdrMod Where to return the module handle on success.
*/
int rtldrNativeLoadSystem(const char *pszFilename, const char *pszExt, uint32_t fFlags, PRTLDRMOD phLdrMod);
int rtldrPEOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF offNtHdrs, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo);
int rtldrELFOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo);
int rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo);
/*int rtldrLXOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF offLX, PRTLDRMOD phLdrMod);
int rtldrMachoOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF offSomething, PRTLDRMOD phLdrMod);*/
DECLHIDDEN(int) rtLdrReadAt(RTLDRMOD hLdrMod, void *pvBuf, uint32_t iDbgInfo, RTFOFF off, size_t cb);
RT_C_DECLS_END
#endif