Changeset 2875


Ignore:
Timestamp:
Nov 12, 2006, 9:59:45 AM (19 years ago)
Author:
bird
Message:

Got the stub loader working (but without stack allocation/switching).

Location:
trunk/kLdr
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/Makefile.kmk

    r2874 r2875  
    144144kLdrExeStub-win_CFLAGS = -W3 -Zl
    145145kLdrExeStub-win_CFLAGS.debug = -Zi
    146 kLdrExeStub-win_LDFLAGS = -Entry:WinMain -FIXED:NO
     146kLdrExeStub-win_LDFLAGS = -Entry:WindowsMain -SubSystem:Console -FIXED:NO
    147147kLdrExeStub-win_LIBS = $(TARGET_kLdr:.dll=.lib)
    148148kLdrExeStub-win_SOURCES = kLdrExeStub-win.c
  • trunk/kLdr/kLdr.h

    r2874 r2875  
    921921typedef struct KLDREXEARGS
    922922{
    923     /** Flags. (Currently unused, MBZ.) */
     923    /** Load & search flags, some which will become defaults. */
    924924    uint32_t        fFlags;
    925     /** The search method to use when loading this executable. */
     925    /** The default search method. */
    926926    KLDRDYLDSEARCH  enmSearch;
    927927    /** The executable file that the stub is supposed to load. */
     
    937937typedef const KLDREXEARGS *PCKLDREXEARGS;
    938938
    939 void kLdrLoadExe(PKLDREXEARGS pArgs, void *pvOS);
     939void kLdrLoadExe(PCKLDREXEARGS pArgs, void *pvOS);
    940940
    941941/** @} */
  • trunk/kLdr/kLdrDyld.c

    r2874 r2875  
    9898uint32_t        kLdrDyldFlags = 0;
    9999/** The default search method. */
    100 KLDRDYLDSEARCH  kLdrDyldSearch = KLDRDYLD_SEARCH_INVALID;
     100KLDRDYLDSEARCH  kLdrDyldSearch = KLDRDYLD_SEARCH_HOST;
    101101
    102102
     
    146146 * @{ */
    147147void       kldrDyldDoLoadExeStackSwitch(PKLDRDYLDMOD pExe, void *pvStack, size_t cbStack);
    148 void       kldrDyldDoLoadExe(PKLDRDYLDMOD pExe);
    149148static int kldrDyldDoLoad(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch,
    150149                          unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr);
     
    229228 * @param   pvOS        OS specific argument.
    230229 */
    231 #ifndef __OS2__
    232 void kLdrDyldLoadExe(PKLDREXEARGS pArgs, void *pvOS)
     230#ifndef __OS2__  /* kLdrDyldLoadExe is implemented in assembly on OS/2. */
     231void kLdrDyldLoadExe(PCKLDREXEARGS pArgs, void *pvOS)
    233232#else
    234 void kldrDyldLoadExe(PKLDREXEARGS pArgs, void *pvOS)
     233void kldrDyldLoadExe(PCKLDREXEARGS pArgs, void *pvOS)
    235234#endif
    236235{
     
    241240
    242241    /*
    243      * Copy the arguments into the globals and do loader init (probably already initialized).
    244      */
    245     kLdrDyldFlags = pArgs->fFlags;
     242     * Indicate that we're boostrapping and ensure that initialization was successful.
     243     */
     244    g_fBootstrapping = 1;
     245    rc = kldrInit();
     246    if (rc)
     247        kldrDyldFailure(rc, "Init failure, rc=%d", rc);
     248
     249    /*
     250     * Validate the argument package.
     251     */
     252    if (pArgs->fFlags & ~(  KLDRYDLD_LOAD_FLAGS_GLOBAL_SYMBOLS
     253                          | KLDRYDLD_LOAD_FLAGS_DEEP_SYMBOLS
     254                          | KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT
     255                          | KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE))
     256        kldrDyldFailure(KLDR_ERR_INVALID_PARAMETER, "Bad fFlags=%#x", pArgs->fFlags);
     257    if (    pArgs->enmSearch <= KLDRDYLD_SEARCH_INVALID
     258        ||  pArgs->enmSearch >= KLDRDYLD_SEARCH_END)
     259        kldrDyldFailure(KLDR_ERR_INVALID_PARAMETER, "Bad enmSearch=%d", pArgs->enmSearch);
     260
     261    /*
     262     * Set defaults.
     263     */
     264    kLdrDyldFlags |= (pArgs->fFlags & KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT);
    246265    kLdrDyldSearch = pArgs->enmSearch;
     266
     267    /** @todo make sense of this default prefix/suffix stuff. */
    247268    if (pArgs->szDefPrefix[0] != '\0')
    248269        kLdrHlpMemCopy(kLdrDyldDefPrefix, pArgs->szDefPrefix, KLDR_MIN(sizeof(pArgs->szDefPrefix), sizeof(kLdrDyldDefPrefix)));
    249270    if (pArgs->szDefSuffix[0] != '\0')
    250271        kLdrHlpMemCopy(kLdrDyldDefSuffix, pArgs->szDefSuffix, KLDR_MIN(sizeof(pArgs->szDefSuffix), sizeof(kLdrDyldDefSuffix)));
    251     /* append */ /** @todo create a function for doing this, an exposed api preferably. */
    252     cbStack = sizeof(kLdrDyldPath) - kLdrHlpStrLen(kLdrDyldPath); /* borrow cbStack for a itty bit. */
    253     kLdrHlpMemCopy(kLdrDyldPath, pArgs->szLibPath, KLDR_MIN(sizeof(pArgs->szLibPath), cbStack));
    254     kLdrDyldPath[sizeof(kLdrDyldPath) - 1] = '\0';
    255 
    256     g_fBootstrapping = 1;
    257     rc = kldrInit();
    258     if (rc)
    259         kldrDyldFailure(rc, "Init failure, rc=%d", rc);
     272
     273    /** @todo append that path to the one for the specified search method. */
     274    /** @todo create a function for doing this, an exposed api preferably. */
     275    /* append path */
     276    cbStack = sizeof(kLdrDyldLibraryPath) - kLdrHlpStrLen(kLdrDyldLibraryPath); /* borrow cbStack for a itty bit. */
     277    kLdrHlpMemCopy(kLdrDyldLibraryPath, pArgs->szLibPath, KLDR_MIN(sizeof(pArgs->szLibPath), cbStack));
     278    kLdrDyldLibraryPath[sizeof(kLdrDyldLibraryPath) - 1] = '\0';
    260279
    261280    /*
     
    269288     * Open and map the executable module before we join paths with kLdrDyldLoad().
    270289     */
    271     rc = kldrDyldFindNewModule(pArgs->szExecutable, NULL, NULL, kLdrDyldSearch,
    272                                kLdrDyldFlags | KLDRDYLD_LOAD_FLAGS_EXECUTABLE, &pExe);
     290    rc = kldrDyldFindNewModule(pArgs->szExecutable, NULL, NULL, pArgs->enmSearch,
     291                               pArgs->fFlags | KLDRDYLD_LOAD_FLAGS_EXECUTABLE, &pExe);
    273292    if (rc)
    274293        kldrDyldFailure(rc, "Can't find/open the executable '%s', rc=%d", pArgs->szExecutable, rc);
     
    745764    {
    746765        if (fFlags & KLDRDYLD_LOAD_FLAGS_EXECUTABLE)
    747             pLoadedMod->cDepRefs = 0xffff;
     766        {
     767            pLoadedMod->cDepRefs++; /* just make it stick. */
     768            pLoadedMod->cRefs++;
     769        }
    748770        else
    749771            rc = kldrDyldModDynamicLoad(pLoadedMod);
  • trunk/kLdr/kLdrDyldFind.c

    r2870 r2875  
    105105/** @name The kLdr search method parameters.
    106106 * @{ */
     107/** The kLdr EXE search path.
     108 * During EXE searching the it's initialized with the values of the KLDR_PATH and
     109 * the PATH env.vars. Both ';' and ':' can be used as separators.
     110 */
     111char            kLdrDyldExePath[8192];
    107112/** The kLdr DLL search path.
    108113 * During initialization the KLDR_LIBRARY_PATH env.var. and the path in the
    109114 * executable stub is appended. Both ';' and ':' can be used as separators.
    110115 */
    111 char            kLdrDyldPath[8192];
     116char            kLdrDyldLibraryPath[8192];
    112117/** The kLdr application directory.
    113118 * This is initialized when the executable is 'loaded' or by a kLdr user.
     
    195200*   Internal Functions                                                         *
    196201*******************************************************************************/
    197 static int kldrDyldFindDoSearch(const char *pszName, const char *pszPrefix, const char *pszSuffix,
     202static int kldrDyldFindDoDllSearch(const char *pszName, const char *pszPrefix, const char *pszSuffix,
    198203                                KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRRDR ppRdr);
     204static int kldrDyldFindDoExeSearch(const char *pszName, const char *pszPrefix, const char *pszSuffix,
     205                                   KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRRDR ppRdr);
    199206static int kldrDyldFindTryOpen(const char *pszFilename, PPKLDRRDR ppRdr);
    200207static int kldrDyldFindTryOpenPath(const char *pchPath, size_t cchPath, PCKLDRDYLDFINDARGS pArgs);
    201208static int kldrDyldFindEnumeratePath(const char *pszSearchPath, PCKLDRDYLDFINDARGS pArgs);
    202 static int kldrDyldFindGetDefaults(KLDRDYLDSEARCH *penmSearch, const char **pszPrefix, const char **pszSuffix, const char *pszName);
     209static int kldrDyldFindGetDefaults(KLDRDYLDSEARCH *penmSearch, const char **pszPrefix,
     210                                   const char **pszSuffix, const char *pszName, uint32_t fFlags);
    203211
    204212
     
    217225     * The kLdr search parameters.
    218226     */
    219     rc = kldrHlpGetEnv("KLDR_LIBRARY_PATH", kLdrDyldPath, sizeof(kLdrDyldPath));
     227    rc = kldrHlpGetEnv("KLDR_LIBRARY_PATH", kLdrDyldLibraryPath, sizeof(kLdrDyldLibraryPath));
    220228    rc = kldrHlpGetEnv("KLDR_DEF_PREFIX", szTmp, sizeof(szTmp));
    221229    if (!rc)
     
    358366    if (!kldrHlpIsFilenameOnly(pszName))
    359367        rc = kldrDyldFindTryOpen(pszName, &pRdr);
     368    else if (!(fFlags & KLDRDYLD_LOAD_FLAGS_EXECUTABLE))
     369        rc = kldrDyldFindDoDllSearch(pszName, pszPrefix, pszSuffix, enmSearch, fFlags, &pRdr);
    360370    else
    361         rc = kldrDyldFindDoSearch(pszName, pszPrefix, pszSuffix, enmSearch, fFlags, &pRdr);
     371        rc = kldrDyldFindDoExeSearch(pszName, pszPrefix, pszSuffix, enmSearch, fFlags, &pRdr);
    362372    if (!rc)
    363373    {
     
    411421
    412422/**
    413  * Searches for a file using the specified method.
     423 * Searches for a DLL file using the specified method.
    414424 *
    415425 * @returns 0 on success and *ppMod pointing to the new module.
     
    423433 * @param   ppRdr       Where to store the pointer to the file provider instance on success.
    424434 */
    425 static int kldrDyldFindDoSearch(const char *pszName, const char *pszPrefix, const char *pszSuffix,
    426                                 KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRRDR ppRdr)
     435static int kldrDyldFindDoDllSearch(const char *pszName, const char *pszPrefix, const char *pszSuffix,
     436                                   KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRRDR ppRdr)
    427437{
    428438    int rc;
     
    435445    Args.pszPrefix = pszPrefix;
    436446    Args.pszSuffix = pszSuffix;
    437     rc = kldrDyldFindGetDefaults(&Args.enmSearch, &Args.pszPrefix, &Args.pszSuffix, pszName);
     447    rc = kldrDyldFindGetDefaults(&Args.enmSearch, &Args.pszPrefix, &Args.pszSuffix, pszName, fFlags);
    438448    if (rc)
    439449        return rc;
     
    464474            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
    465475                break;
    466             rc = kldrDyldFindEnumeratePath(kLdrDyldPath, &Args);
     476            rc = kldrDyldFindEnumeratePath(kLdrDyldLibraryPath, &Args);
    467477            break;
    468478        }
     
    525535
    526536/**
     537 * Searches for an EXE file using the specified method.
     538 *
     539 * @returns 0 on success and *ppMod pointing to the new module.
     540 * @returns KLDR_ERR_MODULE_NOT_FOUND if the specified file couldn't be opened.
     541 * @returns non-zero kLdr or OS specific status code on other failures.
     542 * @param   pszName     The name.
     543 * @param   pszPrefix   The prefix, optional.
     544 * @param   pszSuffix   The suffix, optional.
     545 * @param   enmSearch   The search method.
     546 * @param   fFlags      The load/search flags.
     547 * @param   ppRdr       Where to store the pointer to the file provider instance on success.
     548 */
     549static int kldrDyldFindDoExeSearch(const char *pszName, const char *pszPrefix, const char *pszSuffix,
     550                                   KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRRDR ppRdr)
     551{
     552    int rc;
     553    KLDRDYLDFINDARGS Args;
     554
     555    /*
     556     * Initialize the argument structure and resolve defaults.
     557     */
     558    Args.enmSearch = enmSearch;
     559    Args.pszPrefix = pszPrefix;
     560    Args.pszSuffix = pszSuffix;
     561    rc = kldrDyldFindGetDefaults(&Args.enmSearch, &Args.pszPrefix, &Args.pszSuffix, pszName, fFlags);
     562    if (rc)
     563        return rc;
     564    Args.pszName = pszName;
     565    Args.cchName = kLdrHlpStrLen(pszName);
     566    Args.cchPrefix = Args.pszPrefix ? kLdrHlpStrLen(Args.pszPrefix) : 0;
     567    Args.cchSuffix = Args.pszSuffix ? kLdrHlpStrLen(Args.pszSuffix) : 0;
     568    Args.cchMaxLength = Args.cchName + Args.cchSuffix + Args.cchPrefix;
     569    Args.fFlags = fFlags;
     570    Args.ppRdr = ppRdr;
     571
     572    /*
     573     * If we're bootstrapping a process, we'll start by looking in the
     574     * application directory and the check out the path.
     575     */
     576    if (g_fBootstrapping)
     577    {
     578        kldrDyldFindLazyInitAppDir();
     579        if (kLdrDyldAppDir[0] != '\0')
     580        {
     581            rc = kldrDyldFindTryOpenPath(kLdrDyldAppDir, kLdrHlpStrLen(kLdrDyldAppDir), &Args);
     582            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     583                return rc;
     584        }
     585    }
     586
     587    /*
     588     * Search the EXE search path. Initialize it the first time around.
     589     */
     590    if (!kLdrDyldExePath[0])
     591    {
     592        size_t cch;
     593        kldrHlpGetEnv("KLDR_EXE_PATH", kLdrDyldExePath, sizeof(kLdrDyldExePath) - 10);
     594        cch = kLdrHlpStrLen(kLdrDyldExePath);
     595        kLdrDyldExePath[cch++] = ';';
     596        kldrHlpGetEnv("PATH", &kLdrDyldExePath[cch], sizeof(kLdrDyldExePath) - cch);
     597    }
     598    return kldrDyldFindEnumeratePath(kLdrDyldExePath, &Args);
     599}
     600
     601
     602/**
    527603 * Try open the specfied file.
    528604 *
     
    565641    static char s_szFilename[1024];
    566642    char *psz;
     643    int rc;
    567644
    568645    /*
     
    612689    *psz = '\0';
    613690
     691
    614692    /*
    615693     * Try open it.
    616694     */
    617     return kldrDyldFindTryOpen(s_szFilename, pArgs->ppRdr);
     695    rc = kldrDyldFindTryOpen(s_szFilename, pArgs->ppRdr);
     696    /* If we're opening an executable, try again without the suffix.*/
     697    if (    rc
     698        &&  pArgs->cchSuffix
     699        &&  (pArgs->fFlags & KLDRDYLD_LOAD_FLAGS_EXECUTABLE))
     700    {
     701        psz -= pArgs->cchSuffix;
     702        *psz = '\0';
     703        rc = kldrDyldFindTryOpen(s_szFilename, pArgs->ppRdr);
     704    }
     705    return rc;
    618706}
    619707
     
    689777 * @param   ppszSuffix  The suffix. In/Out.
    690778 * @param   pszName     The name. In.
     779 * @param   fFlags      The load/search flags.
    691780 */
    692781static int kldrDyldFindGetDefaults(KLDRDYLDSEARCH *penmSearch, const char **ppszPrefix, const char **ppszSuffix,
    693                                    const char *pszName)
     782                                   const char *pszName, uint32_t fFlags)
    694783{
    695784    unsigned fCaseSensitive;
     
    722811        case KLDRDYLD_SEARCH_OS2:
    723812            if (!*ppszSuffix)
    724                 *ppszSuffix = ".dll";
     813                *ppszSuffix = !(fFlags & KLDRDYLD_LOAD_FLAGS_EXECUTABLE) ? ".dll" : ".exe";
    725814            fCaseSensitive = 0;
    726815            break;
     
    729818        case KLDRDYLD_SEARCH_WINDOWS_ALTERED:
    730819            if (!*ppszSuffix)
    731                 *ppszSuffix = ".dll";
     820                *ppszSuffix = !(fFlags & KLDRDYLD_LOAD_FLAGS_EXECUTABLE) ? ".dll" : ".exe";
    732821            fCaseSensitive = 0;
    733822            break;
     
    790879     * Defaults.
    791880     */
    792     rc = kldrDyldFindGetDefaults(&enmSearch, &pszPrefix, &pszSuffix, pszName);
     881    rc = kldrDyldFindGetDefaults(&enmSearch, &pszPrefix, &pszSuffix, pszName, fFlags);
    793882    if (rc)
    794883        return rc;
     
    812901        PKLDRRDR pRdr;
    813902        if (fOS2LibpathStrict)
    814             rc = kldrDyldFindDoSearch(pszName, pszPrefix, pszSuffix, enmSearch, fFlags, &pRdr);
     903            rc = kldrDyldFindDoDllSearch(pszName, pszPrefix, pszSuffix, enmSearch, fFlags, &pRdr);
    815904        else
    816905            rc = kldrDyldFindTryOpen(pszName, &pRdr);
  • trunk/kLdr/kLdrDyldOS.c

    r2854 r2875  
    8989int kldrDyldOSStartExe(uintptr_t uMainEPAddress, void *pvStack, size_t cbStack)
    9090{
     91#if defined(__OS2__)
     92
     93#elif defined(__WIN__)
     94    /*
     95     * Invoke the entrypoint on the current stack for now.
     96     * Deal with other formats and stack switching another day.
     97     */
     98    int rc;
     99    int (*pfnEP)(void);
     100    pfnEP = (int (*)(void))uMainEPAddress;
     101
     102    rc = pfnEP();
     103
     104    TerminateProcess(GetCurrentProcess(), rc);
     105    kldrHlpAssert(!"TerminateProcess failed");
     106    for (;;)
     107        TerminateProcess(GetCurrentProcess(), rc);
     108
     109//#elif defined(__NT__)
     110#else
     111# error "Port me"
     112#endif
     113
    91114    return -1;
    92115}
    93116
     117
    94118void kldrDyldDoLoadExeStackSwitch(PKLDRDYLDMOD pExe, void *pvStack, size_t cbStack)
    95119{
    96     kldrHlpAssert(!"not implemented");
     120    //kldrHlpAssert(!"not implemented");
     121
     122    /** @todo implement this properly! */
     123    kldrDyldDoLoadExe(pExe);
    97124}
  • trunk/kLdr/kLdrExeStub-win.c

    r2874 r2875  
    4848
    4949/**
    50  * Window 'main'
     50 * Windows 'main'.
    5151 */
    52 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int nCmdShow)
     52int WindowsMain(void)
    5353{
    5454    return kLdrDyldLoadExe(&g_Args, NULL);
  • trunk/kLdr/kLdrInternal.h

    r2869 r2875  
    313313
    314314
     315int kldrInit(void);
     316void kldrTerm(void);
     317
     318int kldrDyldInit(void);
     319void kldrDyldTerm(void);
     320
     321void kldrDyldDoLoadExe(PKLDRDYLDMOD pExe);
     322int kldrDyldFailure(int rc, const char *pszFormat, ...);
     323
     324int kldrDyldOSStartExe(uintptr_t uMainEntrypoint, void *pvStack, size_t cbStack);
     325void *kldrDyldOSAllocStack(size_t cb);
     326
     327int kldrDyldFindInit(void);
    315328int kldrDyldFindNewModule(const char *pszName, const char *pszPrefix, const char *pszSuffix,
    316329                          KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRDYLDMOD ppMod);
     
    353366int kldrDyldModQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *puValue, uint32_t *pfKind);
    354367
    355 int kldrDyldInit(void);
    356 void kldrDyldTerm(void);
    357 int kldrDyldFindInit(void);
    358 
    359 int kldrDyldFailure(int rc, const char *pszFormat, ...);
    360 int kldrInit(void);
    361 void kldrTerm(void);
    362 
    363 
    364 int kldrDyldOSStartExe(uintptr_t uMainEntrypoint, void *pvStack, size_t cbStack);
    365 void *kldrDyldOSAllocStack(size_t cb);
    366 
    367368
    368369/** Pointer to the head module (the executable).
     
    403404extern char             g_szkLdrDyldError[1024];
    404405
    405 extern char             kLdrDyldPath[8192];
     406extern char             kLdrDyldExePath[8192];
     407extern char             kLdrDyldLibraryPath[8192];
    406408extern char             kLdrDyldDefPrefix[16];
    407409extern char             kLdrDyldDefSuffix[16];
     410
     411extern int              g_fBootstrapping;
    408412
    409413
  • trunk/kLdr/testcase/Makefile.kmk

    r2873 r2875  
    113113TEMPLATE_TSTBAREPROG_EXTENDS = TSTBARE
    114114ifneq ($(filter win win32 win64,$(BUILD_TARGET)),)
    115 TEMPLATE_TSTBAREPROG_LDFLAGS += -Entry:WinMain -FIXED:NO
     115TEMPLATE_TSTBAREPROG_LDFLAGS += -Entry:WindowsMain -FIXED:NO
    116116else
    117117TEMPLATE_TSTBAREPROG_LDFLAGS.nt += -FIXED:NO
  • trunk/kLdr/testcase/tstExeMainStub.c

    r2873 r2875  
    3636
    3737#elif defined(__WIN__)
    38 # include <windows.h>
     38/* nothing */
    3939
    4040#elif defined(__NT__)
     
    6464 * Window 'main'
    6565 */
    66 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int nCmdShow)
     66int WindowsMain(void)
    6767{
    6868    int rc;
Note: See TracChangeset for help on using the changeset viewer.