Changeset 2869


Ignore:
Timestamp:
Nov 12, 2006, 3:47:25 AM (19 years ago)
Author:
bird
Message:

the simple testcase works.

Location:
trunk/kLdr
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdr.c

    r2855 r2869  
    106106        if (!rc)
    107107        {
    108             g_fInitialized = 1;
    109             return 0;
     108            rc = kldrDyldInit();
     109            if (!rc)
     110            {
     111                g_fInitialized = 1;
     112                return 0;
     113            }
     114            kldrHlpSemTerm();
    110115        }
    111116        kldrHlpHeapTerm();
  • trunk/kLdr/kLdrDyld.c

    r2868 r2869  
    7575 * successfully initialized. */
    7676PKLDRDYLDMOD    g_pkLdrDyldInitHead;
    77 /** Pointer to the tail module of the initalization list. */
     77/** Pointer to the tail module of the initalization list.*/
    7878PKLDRDYLDMOD    g_pkLdrDyldInitTail;
    79 /** Pointer to the head module of the termination order list. */
     79/** Pointer to the head module of the termination order list.
     80 * This is a LIFO just like the the init list. */
    8081PKLDRDYLDMOD    g_pkLdrDyldTermHead;
    8182/** Pointer to the tail module of the termination order list. */
     
    185186 * Initialize the dynamic loader.
    186187 */
    187 int kldrDyInit(void)
     188int kldrDyldInit(void)
    188189{
    189190    kLdrDyldHead = kLdrDyldTail = NULL;
     
    198199    g_cbkLdrDyldMainStack = 0;
    199200
    200     return 0;
     201    return kldrDyldFindInit();
    201202}
    202203
     
    205206 * Terminate the dynamic loader.
    206207 */
    207 void kldrDyTerm(void)
     208void kldrDyldTerm(void)
    208209{
    209210
     
    321322        g_cTotalLoadCalls++;
    322323        g_cActiveLoadCalls++;
    323         rc = kldrDyldDoLoad(pszDll, pszPrefix, pszSuffix, enmSearch, fFlags, phMod, pszErr, cchErr);
     324        rc = kldrDyldDoLoad(pszDll, pszPrefix, pszSuffix, enmSearch, fFlags, &pMod, pszErr, cchErr);
    324325        g_cActiveLoadCalls--;
    325326        kldrDyldDoModuleTerminationAndGarabageCollection();
     
    845846            if (cEntries < sizeof(s_aEntries) / sizeof(s_aEntries[0]))
    846847            {
    847                 s_aEntries[cEntries++].pMod = pMod->papPrereqs[pMod->cPrereqs - s_aEntries[i].cLeft];
     848                s_aEntries[cEntries].cLeft = ~(uint32_t)0;
     849                s_aEntries[cEntries].pMod = pMod->papPrereqs[pMod->cPrereqs - s_aEntries[i].cLeft];
    848850                s_aEntries[i].cLeft--;
     851                cEntries++;
    849852            }
    850853            else
     
    962965         * We'll have to load it from file.
    963966         */
    964         rc = kldrDyldFindNewModule(pszDll, pszPrefix, pszSuffix, enmSearch, fFlags, ppMod);
     967        rc = kldrDyldFindNewModule(pszDll, pszPrefix, pszSuffix, enmSearch, fFlags, &pMod);
    965968        if (!rc)
    966969            rc = kldrDyldModMap(pMod);
     
    11621165static void kldrDyldStackDropFrame(uint32_t iLoad1st, uint32_t iLoadEnd, int rc)
    11631166{
    1164     uint32_t iStack;
    1165     KLDRDYLD_ASSERT(iLoadEnd <= g_cStackMods);
    1166     KLDRDYLD_ASSERT(iLoad1st == g_cStackMods);
     1167    uint32_t i;
     1168    KLDRDYLD_ASSERT(iLoad1st <= g_cStackMods);
     1169    KLDRDYLD_ASSERT(iLoadEnd == g_cStackMods);
    11671170
    11681171    /*
    11691172     * First pass: Do all the cleanups we can, but don't destroy anything just yet.
    11701173     */
    1171     for (iStack = iLoadEnd; iStack < iLoad1st; iStack++)
    1172     {
    1173         PKLDRDYLDMOD pMod = g_papStackMods[--iLoad1st];
     1174    i = iLoadEnd;
     1175    while (i-- > iLoad1st)
     1176    {
     1177        PKLDRDYLDMOD pMod = g_papStackMods[i];
    11741178        kldrDyldStackCleanupOne(pMod, rc);
    11751179    }
     
    11791183     *              can be completely removed.
    11801184     */
    1181     while (iLoad1st > iLoadEnd)
    1182     {
    1183         /*
    1184          * Pop a module.
    1185          */
    1186         PKLDRDYLDMOD pMod = g_papStackMods[--iLoad1st];
    1187         g_cStackMods = iLoad1st;
     1185    for (i = iLoad1st; i < iLoadEnd ; i++)
     1186    {
     1187        PKLDRDYLDMOD pMod = g_papStackMods[i];
    11881188
    11891189        /*
     
    12101210        kldrDyldModDeref(pMod);
    12111211    }
     1212
     1213    /*
     1214     * Drop the stack frame.
     1215     */
     1216    g_cStackMods = iLoad1st;
    12121217}
    12131218
     
    12451250                case KLDRSTATE_GOOD:
    12461251                case KLDRSTATE_PENDING_GC:
     1252                case KLDRSTATE_PENDING_TERMINATION:
    12471253                    break;
    12481254
    12491255                case KLDRSTATE_INITIALIZATION_FAILED: /* just in case */
    12501256                case KLDRSTATE_PENDING_INITIALIZATION:
    1251                 case KLDRSTATE_PENDING_TERMINATION:
    12521257                    kldrDyldModUnloadPrerequisites(pMod);
    12531258                    break;
     
    13091314            case KLDRSTATE_INITIALIZATION_FAILED:
    13101315            case KLDRSTATE_PENDING_GC:
    1311                 KLDRDYLD_ASSERT(pMod->cRefs == 0); /* ??? */
     1316                KLDRDYLD_ASSERT(!pMod->cDepRefs);
     1317                KLDRDYLD_ASSERT(!pMod->cDynRefs);
    13121318                pMod->enmState = KLDRSTATE_GC;
    13131319                kldrDyldModUnmap(pMod);
     
    14281434int kldrDyldFailure(int rc, const char *pszFilename, ...)
    14291435{
    1430     kldrHlpExit(1);
     1436    /** @todo print it. */
     1437    if (g_fBootstrapping);
     1438        kldrHlpExit(1);
    14311439    return rc;
    14321440}
  • trunk/kLdr/kLdrDyldFind.c

    r2868 r2869  
    218218     */
    219219    rc = kldrHlpGetEnv("KLDR_LIBRARY_PATH", kLdrDyldPath, sizeof(kLdrDyldPath));
    220     if (rc)
    221         kLdrDyldPath[0] = '\0';
    222 
    223220    rc = kldrHlpGetEnv("KLDR_DEF_PREFIX", szTmp, sizeof(szTmp));
    224221    if (!rc)
    225222        kLdrHlpMemCopy(kLdrDyldDefPrefix, szTmp, sizeof(szTmp));
    226 
    227223    rc = kldrHlpGetEnv("KLDR_DEF_SUFFIX", szTmp, sizeof(szTmp));
    228224    if (!rc)
     
    249245    kldrHlpGetEnv("KLDR_OS2_LIBPATH", kLdrDyldOS2Libpath, sizeof(kLdrDyldOS2Libpath));
    250246    kldrHlpGetEnv("KLDR_OS2_LIBPATHSTRICT", kLdrDyldOS2LibpathStrict, sizeof(kLdrDyldOS2LibpathStrict));
     247    if (    kLdrDyldOS2LibpathStrict[0] == 'T'
     248        ||  kLdrDyldOS2LibpathStrict[0] == 't')
     249        kLdrDyldOS2LibpathStrict[0] = 'T';
     250    else
     251        kLdrDyldOS2LibpathStrict[0] = '\0';
     252    kLdrDyldOS2LibpathStrict[1] = '\0';
    251253    kldrHlpGetEnv("KLDR_OS2_BEGINLIBPATH", kLdrDyldOS2BeginLibpath, sizeof(kLdrDyldOS2BeginLibpath));
    252254    kldrHlpGetEnv("KLDR_OS2_ENDLIBPATH", kLdrDyldOS2EndLibpath, sizeof(kLdrDyldOS2EndLibpath));
     
    267269    kldrHlpGetEnv("KLDR_WINDOWS_SYSTEM_DIR", kLdrDyldWindowsSystemDir, sizeof(kLdrDyldWindowsSystemDir));
    268270    kldrHlpGetEnv("KLDR_WINDOWS_DIR", kLdrDyldWindowsDir, sizeof(kLdrDyldWindowsDir));
    269     kldrHlpGetEnv("KLDR_WINDOWS_PATH", kLdrDyldWindowsPath, sizeof(kLdrDyldWindowsPath));
     271    rc = kldrHlpGetEnv("KLDR_WINDOWS_PATH", kLdrDyldWindowsPath, sizeof(kLdrDyldWindowsPath));
     272    if (rc)
     273        kldrHlpGetEnv("PATH", kLdrDyldWindowsPath, sizeof(kLdrDyldWindowsPath));
    270274#endif
    271275
     
    279283    (void)cch;
    280284    return 0;
     285}
     286
     287
     288/**
     289 * Lazily initialize the two application directory paths.
     290 */
     291static void kldrDyldFindLazyInitAppDir(void)
     292{
     293    if (!kLdrDyldAppDir[0])
     294    {
     295#if defined(__OS2__)
     296        PPIB pPib;
     297        PTIB pTib;
     298        APIRET rc;
     299
     300        DosGetInfoBlocks(&pTib, &pPib);
     301        rc = DosQueryModuleName(pPib->pib_hmte, sizeof(kLdrDyldAppDir), kLdrDyldAppDir);
     302        if (!rc)
     303        {
     304            *kldrHlpGetFilename(kLdrDyldAppDir) = '\0';
     305             kLdrHlpMemCopy(kLdrDyldWindowsAppDir, kLdrDyldAppDir, sizeof(kLdrDyldAppDir));
     306        }
     307        else
     308        {
     309            kLdrDyldWindowsAppDir[0] = kLdrDyldAppDir[0] = '.';
     310            kLdrDyldWindowsAppDir[1] = kLdrDyldAppDir[1] = '\0';
     311        }
     312
     313
     314#elif defined(__WIN__)
     315        DWORD dwSize = GetModuleFileName(NULL /* the executable */, kLdrDyldAppDir, sizeof(kLdrDyldAppDir));
     316        if (dwSize > 0)
     317        {
     318            *kldrHlpGetFilename(kLdrDyldAppDir) = '\0';
     319            kLdrHlpMemCopy(kLdrDyldWindowsAppDir, kLdrDyldAppDir, sizeof(kLdrDyldAppDir));
     320        }
     321        else
     322        {
     323            kLdrDyldWindowsAppDir[0] = kLdrDyldAppDir[0] = '.';
     324            kLdrDyldWindowsAppDir[1] = kLdrDyldAppDir[1] = '\0';
     325        }
     326
     327#else
     328# error "Port me"
     329#endif
     330    }
    281331}
    282332
     
    390440    Args.pszName = pszName;
    391441    Args.cchName = kLdrHlpStrLen(pszName);
    392     Args.cchPrefix = Args.pszPrefix ? kLdrHlpStrLen(pszPrefix) : 0;
    393     Args.cchSuffix = Args.pszSuffix ? kLdrHlpStrLen(pszSuffix) : 0;
     442    Args.cchPrefix = Args.pszPrefix ? kLdrHlpStrLen(Args.pszPrefix) : 0;
     443    Args.cchSuffix = Args.pszSuffix ? kLdrHlpStrLen(Args.pszSuffix) : 0;
    394444    Args.cchMaxLength = Args.cchName + Args.cchSuffix + Args.cchPrefix;
    395445    Args.fFlags = fFlags;
     
    400450     */
    401451/** @todo get rid of the strlen() on the various paths here! */
    402     switch (enmSearch)
     452    switch (Args.enmSearch)
    403453    {
    404454        case KLDRDYLD_SEARCH_KLDR:
    405455        {
     456            kldrDyldFindLazyInitAppDir();
    406457            if (kLdrDyldAppDir[0] != '\0')
    407458            {
     
    432483        case KLDRDYLD_SEARCH_WINDOWS_ALTERED:
    433484        {
     485            kldrDyldFindLazyInitAppDir();
    434486            rc = kldrDyldFindTryOpenPath(kLdrDyldWindowsAppDir, kLdrHlpStrLen(kLdrDyldWindowsAppDir), &Args);
    435487            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
    436488                break;
    437             if (enmSearch == KLDRDYLD_SEARCH_WINDOWS_ALTERED)
     489            if (Args.enmSearch == KLDRDYLD_SEARCH_WINDOWS_ALTERED)
    438490            {
    439491                rc = kldrDyldFindTryOpenPath(".", 1, &Args);
     
    447499            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
    448500                break;
    449             if (enmSearch == KLDRDYLD_SEARCH_WINDOWS)
     501            if (Args.enmSearch == KLDRDYLD_SEARCH_WINDOWS)
    450502            {
    451503                rc = kldrDyldFindTryOpenPath(".", 1, &Args);
     
    513565    static char s_szFilename[1024];
    514566    char *psz;
     567
     568    /*
     569     * Ignore any attempts at opening empty paths.
     570     * This can happen when a *Dir globals is empty.
     571     */
     572    if (!cchPath)
     573        return KLDR_ERR_MODULE_NOT_FOUND; /* ignore */
    515574
    516575    /*
     
    692751        if (    cchName > cchSuffix
    693752            &&  (   fCaseSensitive
    694                  ?  kLdrHlpMemComp(pszName + cchName - cchSuffix, *ppszSuffix, cchSuffix)
    695                  :  kLdrHlpMemIComp(pszName + cchName - cchSuffix, *ppszSuffix, cchSuffix))
     753                 ?  !kLdrHlpMemComp(pszName + cchName - cchSuffix, *ppszSuffix, cchSuffix)
     754                 :  !kLdrHlpMemIComp(pszName + cchName - cchSuffix, *ppszSuffix, cchSuffix))
    696755           )
    697756            *ppszSuffix = NULL;
  • trunk/kLdr/kLdrDyldMod.c

    r2868 r2869  
    567567    uint32_t        i;
    568568
    569     KLDRDYLDMOD_ASSERT(pMod->papPrereqs);
     569    KLDRDYLDMOD_ASSERT(pMod->papPrereqs || !pMod->cPrereqs);
    570570
    571571    /*
     
    584584            pMod2->cDepRefs--;
    585585            pMod2->cRefs--;
    586             cToUnload += !pMod2->cRefs;
     586            cToUnload += !pMod2->cDepRefs && !pMod2->cDynRefs;
    587587        }
    588588    }
     
    661661        for (pMod = kLdrDyldHead; pMod; pMod = pMod->Load.pNext)
    662662        {
    663             if (    pMod->cRefs
     663            if (    pMod->cDepRefs
     664                ||  pMod->cDynRefs
    664665                ||  pMod->enmState >= KLDRSTATE_PENDING_TERMINATION
    665666                ||  pMod->enmState < KLDRSTATE_LOADED_PREREQUISITES)
     
    760761
    761762    /* sanity */
    762     KLDRDYLDMOD_ASSERT(pMod->cRefs > 0);
    763763    KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_OPEN);
    764764    KLDRDYLDMOD_ASSERT(!pMod->fMapped);
     
    10031003    int rc;
    10041004
    1005     KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_INITIALIZING);
    1006 
     1005    KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_PENDING_INITIALIZATION);
     1006
     1007    pMod->enmState = KLDRSTATE_INITIALIZING;
    10071008    rc = kLdrModCallInit(pMod->pMod, (uintptr_t)pMod->hMod);
    10081009    if (!rc)
     1010    {
    10091011        pMod->enmState = KLDRSTATE_GOOD;
     1012        /* push it onto the termination list.*/
     1013        pMod->InitTerm.pPrev = NULL;
     1014        pMod->InitTerm.pNext = g_pkLdrDyldTermHead;
     1015        if (g_pkLdrDyldTermHead)
     1016            g_pkLdrDyldTermHead->InitTerm.pPrev = pMod;
     1017        else
     1018            g_pkLdrDyldTermTail = pMod;
     1019        g_pkLdrDyldTermHead = pMod;
     1020    }
    10101021    else
    10111022        pMod->enmState = KLDRSTATE_INITIALIZATION_FAILED;
     
    10241035void kldrDyldModCallTerm(PKLDRDYLDMOD pMod)
    10251036{
    1026     KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_TERMINATING);
    1027 
     1037    KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_PENDING_TERMINATION);
     1038
     1039    pMod->enmState = KLDRSTATE_TERMINATING;
    10281040    kLdrModCallTerm(pMod->pMod, (uintptr_t)pMod->hMod);
    10291041    pMod->enmState = KLDRSTATE_PENDING_GC;
     1042    /* unlinking on destruction. */
    10301043}
    10311044
  • trunk/kLdr/kLdrHlp.c

    r2867 r2869  
    386386 *
    387387 * @returns 0 on success.
    388  * @returns KLDR_ERR_BUFFER_OVERFLOW on if the buffer is too small (it'll be partially filled).
     388 * @returns KLDR_ERR_BUFFER_OVERFLOW on if the buffer is too small.
    389389 * @returns KLDR_ERR_SYMBOL_NOT_FOUND if not found. (Yeah, abusing the status code, but it's only internally...)
    390390 * @returns OS specfic status code on other error.
     
    407407            kLdrHlpMemCopy(pszVal, pszValue, cch + 1);
    408408        else
    409         {
    410409            rc = KLDR_ERR_BUFFER_OVERFLOW;
    411             if (cchVal > 1)
    412             {
    413                 kLdrHlpMemCopy(pszVal, pszValue, *pcchVal);
    414                 pszVal[*pcchVal - 1] = '\0';
    415             }
    416         }
    417410    }
    418411    else
     
    425418    SetLastError(0);
    426419    cch = GetEnvironmentVariable(pszVar, pszVal, cchVal);
    427     if (cch < cchVal)
     420    if (cch > 0 && cch < cchVal)
    428421        return 0;
    429422
     
    796789    const uint8_t *pb = (const uint8_t *)pv;
    797790    const uint8_t  b = (uint8_t)ch;
    798     while (cb)
     791    while (cb-- > 0)
    799792    {
    800793        if (*pb == b)
     
    811804    const uint8_t *pb1 = (const uint8_t *)pv1;
    812805    const uint8_t *pb2 = (const uint8_t *)pv2;
    813     while (cb)
     806    while (cb-- > 0)
    814807    {
    815808        if (*pb1 != *pb2)
  • trunk/kLdr/kLdrInternal.h

    r2868 r2869  
    353353int kldrDyldModQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *puValue, uint32_t *pfKind);
    354354
     355int kldrDyldInit(void);
     356void kldrDyldTerm(void);
     357int kldrDyldFindInit(void);
     358
    355359int kldrDyldFailure(int rc, const char *pszFormat, ...);
    356360int kldrInit(void);
  • trunk/kLdr/kLdrModPE.c

    r2861 r2869  
    241241    pMod->enmFmt = KLDRFMT_PE;
    242242    if (s.FileHdr.Characteristics & IMAGE_FILE_DLL)
    243         pMod->enmType = s.FileHdr.Characteristics & IMAGE_FILE_RELOCS_STRIPPED
     243        pMod->enmType = !(s.FileHdr.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
    244244            ? KLDRTYPE_SHARED_LIBRARY_RELOCATABLE
    245245            : KLDRTYPE_SHARED_LIBRARY_FIXED;
    246246    else
    247         pMod->enmType = s.FileHdr.Characteristics & IMAGE_FILE_RELOCS_STRIPPED
     247        pMod->enmType = !(s.FileHdr.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
    248248            ? KLDRTYPE_EXECUTABLE_RELOCATABLE
    249249            : KLDRTYPE_EXECUTABLE_FIXED;
     
    15801580                rc = pfnGetImport(pMod, iImp, IMAGE_ORDINAL32(pThunk->u1.Ordinal), NULL, &Value, &fKind, pvUser);
    15811581            else if (KLDRMODPE_VALID_RVA(pModPE, pThunk->u1.Ordinal))
    1582                 rc = pfnGetImport(pMod, iImp, NIL_KLDRMOD_SYM_ORDINAL,
    1583                                   KLDRMODPE_RVA2TYPE(pvMapping, pThunk->u1.Ordinal, const char *),
    1584                                   &Value, &fKind, pvUser);
     1582            {
     1583                const IMAGE_IMPORT_BY_NAME *pName = KLDRMODPE_RVA2TYPE(pvMapping, pThunk->u1.Ordinal, const IMAGE_IMPORT_BY_NAME *);
     1584                rc = pfnGetImport(pMod, iImp, NIL_KLDRMOD_SYM_ORDINAL, pName->Name, &Value, &fKind, pvUser);
     1585            }
    15851586            else
    15861587            {
  • trunk/kLdr/kLdrRdrFile.c

    r2861 r2869  
    11121112    SecAttr.lpSecurityDescriptor = NULL;
    11131113    SecAttr.nLength = 0;
    1114     File = CreateFile(pszFilename, GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ, &SecAttr, OPEN_ALWAYS, 0, NULL);
     1114    File = CreateFile(pszFilename, GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ, &SecAttr, OPEN_EXISTING, 0, NULL);
    11151115    if (File == INVALID_HANDLE_VALUE)
    11161116        return GetLastError();
  • trunk/kLdr/testcase/tst-0-driver.c

    r2864 r2869  
    7272    hMod = (HKLDRMOD)0xffffeeee;
    7373    strcpy(szErr, pszErrInit);
    74     rc = kLdrDyldLoad("tst-0", NULL, NULL, KLDRDYLD_SEARCH_KLDR,
     74    rc = kLdrDyldLoad("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST,
    7575                      KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT, &hMod, szErr, sizeof(szErr));
    7676    if (rc)
    7777        Failure("kLdrDyldLoad(\"tst-0\",...) failed, rc=%d (%#x). szErr='%s'.\n", rc, rc, szErr);
    78     if (strcmp(szErr, pszErrInit))
     78    if (!strcmp(szErr, pszErrInit))
    7979        Failure("szErr wasn't set.\n");
    8080    if (hMod == (HKLDRMOD)0xffffeeee)
Note: See TracChangeset for help on using the changeset viewer.