示例#1
0
/** @copydoc RTLDROPS::pfnGetSymbolEx */
static DECLCALLBACK(int) rtkldr_GetSymbolEx(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress,
                                            const char *pszSymbol, RTUINTPTR *pValue)
{
    PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
    KLDRADDR uValue;

#if defined(RT_OS_OS2) || defined(RT_OS_DARWIN)
    /*
     * Add underscore prefix.
     */
    if (pszSymbol)
    {
        size_t cch = strlen(pszSymbol);
        char *psz = (char *)alloca(cch + 2);
        memcpy(psz + 1, pszSymbol, cch + 1);
        *psz = '_';
        pszSymbol = psz;
    }
#endif

    int rc = kLdrModQuerySymbol(pModkLdr, pvBits, BaseAddress,
                                NIL_KLDRMOD_SYM_ORDINAL, pszSymbol, strlen(pszSymbol), NULL,
                                NULL, NULL, &uValue, NULL);
    if (!rc)
    {
        *pValue = uValue;
        return VINF_SUCCESS;
    }
    return rtkldrConvertError(rc);
}
示例#2
0
/** @copydoc RTLDROPS::pfnRelocate */
static DECLCALLBACK(int) rtkldr_Relocate(PRTLDRMODINTERNAL pMod, void *pvBits, RTUINTPTR NewBaseAddress,
                                         RTUINTPTR OldBaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser)
{
    PKLDRMOD            pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
    RTLDRMODKLDRARGS    Args;
    Args.pvUser         = pvUser;
    Args.u.pfnGetImport = pfnGetImport;
    Args.pMod           = (PRTLDRMODKLDR)pMod;
    Args.pvBits         = pvBits;
    Args.rc             = VINF_SUCCESS;
    int rc = kLdrModRelocateBits(pModkLdr, pvBits, NewBaseAddress, OldBaseAddress, rtkldrGetImportWrapper, &Args);
    if (Args.rc != VINF_SUCCESS)
        rc = Args.rc;
    else
        rc = rtkldrConvertError(rc);
    return rc;
}
示例#3
0
/** @copydoc RTLDROPS::pfnEnumSymbols */
static DECLCALLBACK(int) rtkldr_EnumSymbols(PRTLDRMODINTERNAL pMod, unsigned fFlags, const void *pvBits, RTUINTPTR BaseAddress,
                                            PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
{
    PKLDRMOD            pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
    RTLDRMODKLDRARGS    Args;
    Args.pvUser         = pvUser;
    Args.u.pfnEnumSyms  = pfnCallback;
    Args.pMod           = (PRTLDRMODKLDR)pMod;
    Args.pvBits         = pvBits;
    Args.rc             = VINF_SUCCESS;
    int rc = kLdrModEnumSymbols(pModkLdr, pvBits, BaseAddress,
                                fFlags & RTLDR_ENUM_SYMBOL_FLAGS_ALL ? KLDRMOD_ENUM_SYMS_FLAGS_ALL : 0,
                                rtkldrEnumSymbolsWrapper, &Args);
    if (Args.rc != VINF_SUCCESS)
        rc = Args.rc;
    else
        rc = rtkldrConvertError(rc);
    return rc;
}
示例#4
0
/**
 * Open a image using kLdr.
 *
 * @returns iprt status code.
 * @param   pReader     The loader reader instance which will provide the raw image bits.
 * @param   fFlags      Reserved, MBZ.
 * @param   enmArch     CPU architecture specifier for the image to be loaded.
 * @param   phLdrMod    Where to store the handle.
 */
int rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod)
{
    /* Convert enmArch to k-speak. */
    KCPUARCH enmCpuArch;
    switch (enmArch)
    {
        case RTLDRARCH_WHATEVER:
            enmCpuArch = KCPUARCH_UNKNOWN;
            break;
        case RTLDRARCH_X86_32:
            enmCpuArch = KCPUARCH_X86_32;
            break;
        case RTLDRARCH_AMD64:
            enmCpuArch = KCPUARCH_AMD64;
            break;
        default:
            return VERR_INVALID_PARAMETER;
    }

    /* Create a rtkldrRdr_ instance. */
    PRTKLDRRDR pRdr = (PRTKLDRRDR)RTMemAllocZ(sizeof(*pRdr));
    if (!pRdr)
        return VERR_NO_MEMORY;
    pRdr->Core.u32Magic = KRDR_MAGIC;
    pRdr->Core.pOps = &g_kLdrRdrFileOps;
    pRdr->pReader = pReader;

    /* Try open it. */
    PKLDRMOD pMod;
    int krc = kLdrModOpenFromRdr(&pRdr->Core, fFlags, enmCpuArch, &pMod);
    if (!krc)
    {
        /* Create a module wrapper for it. */
        PRTLDRMODKLDR pNewMod = (PRTLDRMODKLDR)RTMemAllocZ(sizeof(*pNewMod));
        if (pNewMod)
        {
            pNewMod->Core.u32Magic = RTLDRMOD_MAGIC;
            pNewMod->Core.eState = LDR_STATE_OPENED;
            pNewMod->Core.pOps = &g_rtkldrOps;
            pNewMod->pMod = pMod;
            *phLdrMod = &pNewMod->Core;

#ifdef LOG_ENABLED
            Log(("rtldrkLdrOpen: '%s' (%s) %u segments\n",
                 pMod->pszName, pMod->pszFilename, pMod->cSegments));
            for (unsigned iSeg = 0; iSeg < pMod->cSegments; iSeg++)
            {
                Log(("Segment #%-2u: RVA=%08llx cb=%08llx '%.*s'\n", iSeg,
                     pMod->aSegments[iSeg].RVA,
                     pMod->aSegments[iSeg].cb,
                     pMod->aSegments[iSeg].cchName,
                     pMod->aSegments[iSeg].pchName));
            }
#endif
            return VINF_SUCCESS;
        }
        kLdrModClose(pMod);
        krc = KERR_NO_MEMORY;
    }
    return rtkldrConvertError(krc);
}
示例#5
0
/** @copydoc RTLDROPS::pfnDone */
static DECLCALLBACK(int) rtkldr_Done(PRTLDRMODINTERNAL pMod)
{
    PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
    int rc = kLdrModMostlyDone(pModkLdr);
    return rtkldrConvertError(rc);
}
/**
 * Open a image using kLdr.
 *
 * @returns iprt status code.
 * @param   pReader     The loader reader instance which will provide the raw image bits.
 * @param   fFlags      Reserved, MBZ.
 * @param   enmArch     CPU architecture specifier for the image to be loaded.
 * @param   phLdrMod    Where to store the handle.
 * @param   pErrInfo    Where to return extended error information. Optional.
 */
int rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo)
{
    /* Convert enmArch to k-speak. */
    KCPUARCH enmCpuArch;
    switch (enmArch)
    {
    case RTLDRARCH_WHATEVER:
        enmCpuArch = KCPUARCH_UNKNOWN;
        break;
    case RTLDRARCH_X86_32:
        enmCpuArch = KCPUARCH_X86_32;
        break;
    case RTLDRARCH_AMD64:
        enmCpuArch = KCPUARCH_AMD64;
        break;
    default:
        return VERR_INVALID_PARAMETER;
    }
    KU32 fKFlags = 0;
    if (fFlags & RTLDR_O_FOR_DEBUG)
        fKFlags |= KLDRMOD_OPEN_FLAGS_FOR_INFO;

    /* Create a rtkldrRdr_ instance. */
    PRTKLDRRDR pRdr = (PRTKLDRRDR)RTMemAllocZ(sizeof(*pRdr));
    if (!pRdr)
        return VERR_NO_MEMORY;
    pRdr->Core.u32Magic = KRDR_MAGIC;
    pRdr->Core.pOps = &g_kLdrRdrFileOps;
    pRdr->pReader = pReader;

    /* Try open it. */
    PKLDRMOD pMod;
    int krc = kLdrModOpenFromRdr(&pRdr->Core, fKFlags, enmCpuArch, &pMod);
    if (!krc)
    {
        /* Create a module wrapper for it. */
        PRTLDRMODKLDR pNewMod = (PRTLDRMODKLDR)RTMemAllocZ(sizeof(*pNewMod));
        if (pNewMod)
        {
            pNewMod->Core.u32Magic = RTLDRMOD_MAGIC;
            pNewMod->Core.eState   = LDR_STATE_OPENED;
            pNewMod->Core.pOps     = &g_rtkldrOps;
            pNewMod->Core.pReader  = pReader;
            switch (pMod->enmFmt)
            {
            case KLDRFMT_NATIVE:
                pNewMod->Core.enmFormat = RTLDRFMT_NATIVE;
                break;
            case KLDRFMT_AOUT:
                pNewMod->Core.enmFormat = RTLDRFMT_AOUT;
                break;
            case KLDRFMT_ELF:
                pNewMod->Core.enmFormat = RTLDRFMT_ELF;
                break;
            case KLDRFMT_LX:
                pNewMod->Core.enmFormat = RTLDRFMT_LX;
                break;
            case KLDRFMT_MACHO:
                pNewMod->Core.enmFormat = RTLDRFMT_MACHO;
                break;
            case KLDRFMT_PE:
                pNewMod->Core.enmFormat = RTLDRFMT_PE;
                break;
            default:
                AssertMsgFailed(("%d\n", pMod->enmFmt));
                pNewMod->Core.enmFormat = RTLDRFMT_NATIVE;
                break;
            }
            switch (pMod->enmType)
            {
            case KLDRTYPE_OBJECT:
                pNewMod->Core.enmType = RTLDRTYPE_OBJECT;
                break;
            case KLDRTYPE_EXECUTABLE_FIXED:
                pNewMod->Core.enmType = RTLDRTYPE_EXECUTABLE_FIXED;
                break;
            case KLDRTYPE_EXECUTABLE_RELOCATABLE:
                pNewMod->Core.enmType = RTLDRTYPE_EXECUTABLE_RELOCATABLE;
                break;
            case KLDRTYPE_EXECUTABLE_PIC:
                pNewMod->Core.enmType = RTLDRTYPE_EXECUTABLE_PIC;
                break;
            case KLDRTYPE_SHARED_LIBRARY_FIXED:
                pNewMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_FIXED;
                break;
            case KLDRTYPE_SHARED_LIBRARY_RELOCATABLE:
                pNewMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_RELOCATABLE;
                break;
            case KLDRTYPE_SHARED_LIBRARY_PIC:
                pNewMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_PIC;
                break;
            case KLDRTYPE_FORWARDER_DLL:
                pNewMod->Core.enmType = RTLDRTYPE_FORWARDER_DLL;
                break;
            case KLDRTYPE_CORE:
                pNewMod->Core.enmType = RTLDRTYPE_CORE;
                break;
            case KLDRTYPE_DEBUG_INFO:
                pNewMod->Core.enmType = RTLDRTYPE_DEBUG_INFO;
                break;
            default:
                AssertMsgFailed(("%d\n", pMod->enmType));
                pNewMod->Core.enmType = RTLDRTYPE_OBJECT;
                break;
            }
            switch (pMod->enmEndian)
            {
            case KLDRENDIAN_LITTLE:
                pNewMod->Core.enmEndian = RTLDRENDIAN_LITTLE;
                break;
            case KLDRENDIAN_BIG:
                pNewMod->Core.enmEndian = RTLDRENDIAN_BIG;
                break;
            case KLDRENDIAN_NA:
                pNewMod->Core.enmEndian = RTLDRENDIAN_NA;
                break;
            default:
                AssertMsgFailed(("%d\n", pMod->enmEndian));
                pNewMod->Core.enmEndian = RTLDRENDIAN_NA;
                break;
            }
            switch (pMod->enmArch)
            {
            case KCPUARCH_X86_32:
                pNewMod->Core.enmArch   = RTLDRARCH_X86_32;
                break;
            case KCPUARCH_AMD64:
                pNewMod->Core.enmArch   = RTLDRARCH_AMD64;
                break;
            default:
                AssertMsgFailed(("%d\n", pMod->enmArch));
                pNewMod->Core.enmArch = RTLDRARCH_WHATEVER;
                break;
            }
            pNewMod->pMod          = pMod;
            *phLdrMod = &pNewMod->Core;

#ifdef LOG_ENABLED
            Log(("rtldrkLdrOpen: '%s' (%s) %u segments\n",
                 pMod->pszName, pMod->pszFilename, pMod->cSegments));
            for (unsigned iSeg = 0; iSeg < pMod->cSegments; iSeg++)
            {
                Log(("Segment #%-2u: RVA=%08llx cb=%08llx '%.*s'\n", iSeg,
                     pMod->aSegments[iSeg].RVA,
                     pMod->aSegments[iSeg].cb,
                     pMod->aSegments[iSeg].cchName,
                     pMod->aSegments[iSeg].pchName));
            }
#endif
            return VINF_SUCCESS;
        }

        /* bail out */
        kLdrModClose(pMod);
        krc = KERR_NO_MEMORY;
    }
    else
        RTMemFree(pRdr);

    return rtkldrConvertError(krc);
}