Ignore:
Timestamp:
Nov 12, 2006, 6:38:28 AM (19 years ago)
Author:
bird
Message:

Test all kLdrDyld apis.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/testcase/tst-0-driver.c

    r2869 r2870  
    3030*******************************************************************************/
    3131#include <kLdr.h>
     32#include "tst.h"
    3233#include <stdarg.h>
    3334#include <stdio.h>
     
    3536#include <string.h>
    3637
     38
     39/*******************************************************************************
     40*   Defined Constants And Macros                                               *
     41*******************************************************************************/
     42/** Select the appropriate KLDRSYMKIND bit define. */
     43#define MY_KLDRSYMKIND_BITS     ( sizeof(void *) == 4 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT )
    3744
    3845
     
    6774    const char *pszErrInit = "Error, szErr wasn't zapped";
    6875    char szErr[512];
     76    char szBuf[512];
     77    char *psz;
     78    size_t cch;
    6979    HKLDRMOD hMod;
    7080    int rc;
    7181
     82    /*
     83     * The first thing to do is a simple load / unload test
     84     * using the tst-0-a library (it'll drag in tst-0-d).
     85     */
     86    printf("tst-0-driver: Basic API test using 'tst-0-a'...\n");
    7287    hMod = (HKLDRMOD)0xffffeeee;
    7388    strcpy(szErr, pszErrInit);
     
    8499    if (!rc)
    85100    {
     101        HKLDRMOD hMod2;
     102        HKLDRMOD hMod3;
     103        printf("tst-0-driver: hMod=%p ('tst-0-a')\n", (void *)hMod);
     104
     105        /*
     106         * Simple test of kLdrDyldFindByName.
     107         */
     108        hMod2 = (HKLDRMOD)0xffffeeee;
     109        rc = kLdrDyldFindByName("tst-0", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
     110        if (!rc)
     111            Failure("kLdrDyldFindByName(\"tst-0\",,,) didn't fail!\n");
     112        if (rc && hMod2 != NIL_HKLDRMOD)
     113            Failure("hMod2 wasn't set correctly on kLdrDyldFindByName failure!\n");
     114
     115        hMod2 = (HKLDRMOD)0xffffeeee;
     116        rc = kLdrDyldFindByName("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
     117        if (rc)
     118            Failure("kLdrDyldFindByName(\"tst-0-a\",,,) failed, rc=%d (%#x)\n", rc, rc);
     119        if (!rc && hMod2 != hMod)
     120            Failure("kLdrDyldFindByName(\"tst-0-a\",,,) returned the wrong module handle: %p instead of %p\n",
     121                    (void *)hMod2, (void *)hMod);
     122
     123        hMod2 = (HKLDRMOD)0xffffeeee;
     124        rc = kLdrDyldFindByName("tst-0-d", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
     125        if (!rc)
     126            printf("tst-0-driver: hMod2=%p ('tst-0-d')\n", (void *)hMod2);
     127        else
     128            Failure("kLdrDyldFindByName(\"tst-0-d\",,,) failed, rc=%d (%#x)\n", rc, rc);
     129
     130        /*
     131         * Get the name and filename for each of the two modules.
     132         */
     133        rc = kLdrDyldGetName(hMod2, szBuf, sizeof(szBuf));
     134        if (!rc)
     135        {
     136            printf("tst-0-driver: name: '%s' ('tst-0-d')\n", szBuf);
     137            psz = strstr(szBuf, "-0-");
     138            if (    !psz
     139                ||  strnicmp(psz, "-0-d", sizeof("-0-d") - 1))
     140                Failure("kLdrDyldGetName(\"tst-0-d\",,,) -> '%s': pattern '-0-d' not found\n", szBuf);
     141
     142            /* overflow test. */
     143            cch = strlen(szBuf);
     144            szBuf[cch + 1] = szBuf[cch] = szBuf[cch - 1] = 'x';
     145            szBuf[cch + 2] = '\0';
     146            rc = kLdrDyldGetName(hMod2, szBuf, cch);
     147            if (rc == KLDR_ERR_BUFFER_OVERFLOW)
     148            {
     149                if (!szBuf[0])
     150                    Failure("kLdrDyldGetName didn't return partial result on overflow\n");
     151                else if (szBuf[cch - 1])
     152                    Failure("kLdrDyldGetName didn't terminate partial result correctly overflow: '%s'\n", szBuf);
     153                else if (szBuf[cch] != 'x')
     154                    Failure("kLdrDyldGetName exceeded the buffer limit on partial overflow: '%s'\n", szBuf);
     155            }
     156            else
     157                Failure("kLdrDyldGetName(\"tst-0-d\",,,) -> rc=%d (%#x) instead of KLDR_ERR_BUFFER_OVERFLOW\n", rc, rc);
     158
     159            /* check that we can query the module by the returned name. */
     160            rc = kLdrDyldGetName(hMod2, szBuf, sizeof(szBuf));
     161            if (!rc)
     162            {
     163                hMod3 = (HKLDRMOD)0xffffeeee;
     164                rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
     165                if (rc || hMod3 != hMod2)
     166                    Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod2=%p\n",
     167                            szBuf, rc, rc, (void *)hMod3, (void *)hMod2);
     168            }
     169            else
     170                Failure("kLdrDyldGetName(\"tst-0-d\",,,) failed (b), rc=%d (%#x)\n", rc, rc);
     171        }
     172        else
     173            Failure("kLdrDyldGetName(\"tst-0-d\",,,) failed, rc=%d (%#x)\n", rc, rc);
     174
     175        rc = kLdrDyldGetFilename(hMod2, szBuf, sizeof(szBuf));
     176        if (!rc)
     177        {
     178            printf("tst-0-driver: filename: '%s' ('tst-0-d')\n", szBuf);
     179
     180            /* overflow test. */
     181            cch = strlen(szBuf);
     182            szBuf[cch + 1] = szBuf[cch] = szBuf[cch - 1] = 'x';
     183            szBuf[cch + 2] = '\0';
     184            rc = kLdrDyldGetFilename(hMod2, szBuf, cch);
     185            if (rc == KLDR_ERR_BUFFER_OVERFLOW)
     186            {
     187                if (!szBuf[0])
     188                    Failure("kLdrDyldGetFilename didn't return partial result on overflow\n");
     189                else if (szBuf[cch - 1])
     190                    Failure("kLdrDyldGetFilename didn't terminate partial result correctly overflow: '%s'\n", szBuf);
     191                else if (szBuf[cch] != 'x')
     192                    Failure("kLdrDyldGetFilename exceeded the buffer limit on partial overflow: '%s'\n", szBuf);
     193            }
     194            else
     195                Failure("kLdrDyldGetFilename(\"tst-0-d\",,,) -> rc=%d (%#x) instead of KLDR_ERR_BUFFER_OVERFLOW\n", rc, rc);
     196
     197            /* check that we can query the module by the returned filename. */
     198            rc = kLdrDyldGetFilename(hMod2, szBuf, sizeof(szBuf));
     199            if (!rc)
     200            {
     201                hMod3 = (HKLDRMOD)0xffffeeee;
     202                rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
     203                if (rc || hMod3 != hMod2)
     204                    Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod2=%p\n",
     205                            szBuf, rc, rc, (void *)hMod3, (void *)hMod2);
     206            }
     207            else
     208                Failure("kLdrDyldGetName(\"tst-0-d\",,,) failed (b), rc=%d (%#x)\n", rc, rc);
     209        }
     210        else
     211            Failure("kLdrDyldGetFilename(\"tst-0-d\",,,) failed, rc=%d (%#x)\n", rc, rc);
     212
     213        /* the other module */
     214        rc = kLdrDyldGetName(hMod, szBuf, sizeof(szBuf));
     215        if (!rc)
     216        {
     217            printf("tst-0-driver: name: '%s' ('tst-0-a')\n", szBuf);
     218            psz = strstr(szBuf, "-0-");
     219            if (    !psz
     220                ||  strnicmp(psz, "-0-a", sizeof("-0-a") - 1))
     221                Failure("kLdrDyldGetName(\"tst-0-a\",,,) -> '%s': pattern '-0-a' not found\n", szBuf);
     222
     223            /* check that we can query the module by the returned name. */
     224            hMod3 = (HKLDRMOD)0xffffeeee;
     225            rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
     226            if (rc || hMod3 != hMod)
     227                Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod=%p\n",
     228                        szBuf, rc, rc, (void *)hMod3, (void *)hMod);
     229        }
     230        else
     231            Failure("kLdrDyldGetName(\"tst-0-a\",,,) failed, rc=%d (%#x)\n", rc, rc);
     232
     233        rc = kLdrDyldGetFilename(hMod, szBuf, sizeof(szBuf));
     234        if (!rc)
     235        {
     236            printf("tst-0-driver: filename: '%s' ('tst-0-a')\n", szBuf);
     237
     238            /* check that we can query the module by the returned filename. */
     239            hMod3 = (HKLDRMOD)0xffffeeee;
     240            rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
     241            if (rc || hMod3 != hMod)
     242                Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod=%p\n",
     243                        szBuf, rc, rc, (void *)hMod3, (void *)hMod);
     244        }
     245        else
     246            Failure("kLdrDyldGetFilename(\"tst-0-a\",,,) failed, rc=%d (%#x)\n", rc, rc);
     247
     248
     249        /*
     250         * Resolve the symbol exported by each of the two modules and call them.
     251         */
     252        if (!g_cErrors)
     253        {
     254            uintptr_t uValue;
     255            uint32_t fKind;
     256
     257            fKind = 0xffeeffee;
     258            uValue = ~(uintptr_t)42;
     259            rc = kLdrDyldQuerySymbol(hMod, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncA"), &uValue, &fKind);
     260            if (!rc)
     261            {
     262                if (uValue == ~(uintptr_t)42)
     263                    Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",): uValue wasn't set.\n");
     264                if (fKind == 0xffeeffee)
     265                    Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",): fKind wasn't set.\n");
     266                if (    (fKind & KLDRSYMKIND_BIT_MASK) != KLDRSYMKIND_NO_BIT
     267                    &&  (fKind & KLDRSYMKIND_BIT_MASK) != MY_KLDRSYMKIND_BITS)
     268                    Failure("fKind=%#x indicates a different code 'bit' mode than we running at.\n", fKind);
     269                if (    (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_NO_TYPE
     270                    &&  (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_CODE)
     271                    Failure("fKind=%#x indicates that \"FuncA\" isn't code.\n", fKind);
     272                if (fKind & KLDRSYMKIND_FORWARDER)
     273                    Failure("fKind=%#x indicates that \"FuncA\" is a forwarder. it isn't.\n", fKind);
     274
     275                /* call it. */
     276                if (!g_cErrors)
     277                {
     278                    int (*pfnFuncA)(void) = (int (*)(void))uValue;
     279                    rc = pfnFuncA();
     280                    if (rc != 0x42000042)
     281                        Failure("FuncA returned %#x expected 0x42000042\n", rc);
     282                }
     283
     284                /*
     285                 * Test kLdrDyldFindByAddress now that we've got an address.
     286                 */
     287                hMod3 = (HKLDRMOD)0xeeeeffff;
     288                rc = kLdrDyldFindByAddress(uValue, &hMod3, NULL, NULL);
     289                if (!rc)
     290                {
     291                    uintptr_t offSegment;
     292                    uint32_t iSegment;
     293
     294                    if (hMod3 != hMod)
     295                        Failure("kLdrDyldFindByAddress(%#p/*FuncA*/, \"tst-0-a\",,,) return incorrect hMod3=%p instead of %p.\n",
     296                                uValue, hMod3, hMod);
     297
     298                    hMod3 = (HKLDRMOD)0xeeeeffff;
     299                    iSegment = 0x42424242;
     300                    rc = kLdrDyldFindByAddress(uValue, &hMod3, &iSegment, &offSegment);
     301                    if (!rc)
     302                    {
     303                        if (hMod3 != hMod)
     304                            Failure("Bad hMod3 on 2nd kLdrDyldFindByAddress call.\n");
     305                        if (iSegment > 0x1000) /* safe guess */
     306                            Failure("Bad iSegment=%#x\n", iSegment);
     307                        if (offSegment > 0x100000) /* guesswork */
     308                            Failure("Bad offSegment=%p\n", (void *)offSegment);
     309                    }
     310                    else
     311                        Failure("kLdrDyldFindByAddress(%#p/*FuncA*/, \"tst-0-a\",,,) failed (b), rc=%d (%#x)\n",
     312                                uValue, rc, rc);
     313
     314                    /* negative test */
     315                    hMod3 = (HKLDRMOD)0xeeeeffff;
     316                    iSegment = 0x42424242;
     317                    offSegment = 0x87654321;
     318                    rc = kLdrDyldFindByAddress(~(uintptr_t)16, &hMod3, &iSegment, &offSegment);
     319                    if (!rc)
     320                        Failure("negative kLdrDyldFindByAddress test returned successfully!\n");
     321                    if (iSegment != ~(uint32_t)0)
     322                        Failure("negative kLdrDyldFindByAddress: bad iSegment=%#x\n", iSegment);
     323                    if (offSegment != ~(uintptr_t)0)
     324                        Failure("negative kLdrDyldFindByAddress: bad offSegment=%p\n", (void *)offSegment);
     325                    if (hMod3 != NIL_HKLDRMOD)
     326                        Failure("negative kLdrDyldFindByAddress: bad hMod3=%p\n", (void *)hMod3);
     327                }
     328                else
     329                    Failure("kLdrDyldFindByAddress(%#p/*FuncA*/, \"tst-0-a\",,,) failed, rc=%d (%#x)\n",
     330                            uValue, rc, rc);
     331            }
     332            else
     333                Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",) failed, rc=%d (%#x)\n", rc, rc);
     334
     335            fKind = 0xffeeffee;
     336            uValue = ~(uintptr_t)42;
     337            rc = kLdrDyldQuerySymbol(hMod2, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncD"), &uValue, &fKind);
     338            if (!rc)
     339            {
     340                if (uValue == ~(uintptr_t)42)
     341                    Failure("kLdrDyldQuerySymbol(\"tst-0-d\",,\"FuncD\",): uValue wasn't set.\n");
     342                if (fKind == 0xffeeffee)
     343                    Failure("kLdrDyldQuerySymbol(\"tst-0-d\",,\"FuncD\",): fKind wasn't set.\n");
     344                if (    (fKind & KLDRSYMKIND_BIT_MASK) != KLDRSYMKIND_NO_BIT
     345                    &&  (fKind & KLDRSYMKIND_BIT_MASK) != MY_KLDRSYMKIND_BITS)
     346                    Failure("fKind=%#x indicates a different code 'bit' mode than we running at.\n", fKind);
     347                if (    (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_NO_TYPE
     348                    &&  (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_CODE)
     349                    Failure("fKind=%#x indicates that \"FuncD\" isn't code.\n", fKind);
     350                if (fKind & KLDRSYMKIND_FORWARDER)
     351                    Failure("fKind=%#x indicates that \"FuncD\" is a forwarder. it isn't.\n", fKind);
     352
     353                /* call it. */
     354                if (!g_cErrors)
     355                {
     356                    int (*pfnFuncD)(void) = (int (*)(void))uValue;
     357                    rc = pfnFuncD();
     358                    if (rc != 0x42000000)
     359                        Failure("FuncD returned %#x expected 0x42000000\n", rc);
     360                }
     361
     362                /* use the address to get the module handle. */
     363                hMod3 = (HKLDRMOD)0xeeeeffff;
     364                rc = kLdrDyldFindByAddress(uValue, &hMod3, NULL, NULL);
     365                if (!rc)
     366                {
     367                    if (hMod3 != hMod2)
     368                        Failure("kLdrDyldFindByAddress(%#p/*FuncD*/,,,) return incorrect hMod3=%p instead of %p.\n",
     369                                uValue, hMod3, hMod2);
     370                }
     371                else
     372                    Failure("kLdrDyldFindByAddress(%#p/*FuncD*/,,,) failed, rc=%d (%#x)\n",
     373                            uValue, rc, rc);
     374            }
     375            else
     376                Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",) failed, rc=%d (%#x)\n", rc, rc);
     377
     378        }
     379
     380        /*
     381         * Finally unload it.
     382         */
    86383        rc = kLdrDyldUnload(hMod);
    87384        if (rc)
    88385            Failure("kLdrDyldUnload() failed. rc=%d (%#x)\n", rc, rc);
     386        if (!rc)
     387        {
     388            rc = kLdrDyldFindByName("tst-0-d", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
     389            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     390                Failure("kLdrDyldFindByName(\"tst-0-d\",,,) return rc=%d (%#x), expected KLDR_ERR_MODULE_NOT_FOUND\n", rc, rc);
     391
     392            rc = kLdrDyldFindByName("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
     393            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     394                Failure("kLdrDyldFindByName(\"tst-0-a\",,,) return rc=%d (%#x), expected KLDR_ERR_MODULE_NOT_FOUND\n", rc, rc);
     395        }
     396    }
     397
     398    /*
     399     * Now do what tst-0 would do.
     400     */
     401    if (!g_cErrors)
     402    {
     403
    89404    }
    90405
Note: See TracChangeset for help on using the changeset viewer.