Changeset 2948


Ignore:
Timestamp:
Jan 14, 2007, 11:35:04 PM (19 years ago)
Author:
bird
Message:

working on LX.

Location:
trunk/kLdr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdr.h

    r2945 r2948  
    412412    /** The length of the segment name. */
    413413    uint32_t        cchName;
     414    /** The flat selector to use for the segment (i.e. data/code).
     415     * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */
     416    uint16_t        SelFlat;
     417    /** The 16-bit selector to use for the segment.
     418     * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */
     419    uint16_t        Sel16bit;
     420    /** Segment flags. */
     421    uint32_t        fFlags;
    414422    /** The segment protection. */
    415423    KLDRPROT        enmProt;
     
    438446    uintptr_t       MapAddress;
    439447} KLDRSEG;
     448
     449
     450/** @name Segment flags
     451 * @{ */
     452/** The segment is 16-bit. When not set the default of the target architecture is assumed. */
     453#define KLDRSEG_FLAG_16BIT          1
     454/** The segment requires a 16-bit selector alias. (OS/2) */
     455#define KLDRSEG_FLAG_OS2_ALIAS16    2
     456/** Conforming segment (x86 weirdness). (OS/2) */
     457#define KLDRSEG_FLAG_OS2_CONFORM    4
     458/** IOPL (ring-2) segment. (OS/2) */
     459#define KLDRSEG_FLAG_OS2_IOPL       8
     460/** @} */
    440461
    441462
  • trunk/kLdr/kLdrModLX.c

    r2893 r2948  
    133133static int kldrModLXDoLoadFixupSection(PKLDRMODLX pModLX);
    134134static int32_t kldrModLXDoCall(uintptr_t uEntrypoint, uintptr_t uHandle, uint32_t uOp, void *pvReserved);
    135 static int kldrModLXDoReloc(uint8_t *pbPage, int off, KLDRADDR uValue, uint32_t fKind);
     135static int kldrModLXDoReloc(uint8_t *pbPage, int off, KLDRADDR PageAddress, const struct r32_rlc *prlc,
     136                            int iSelector, KLDRADDR uValue, uint32_t fKind);
    136137
    137138
     
    236237        return KLDR_ERR_LX_BAD_LOADER_SECTION;
    237238    if (    Hdr.e32_enttab
    238         &&  (Hdr.e32_enttab < off || Hdr.e32_enttab > offEnd - 2))
     239        &&  (Hdr.e32_enttab < off || Hdr.e32_enttab >= offEnd))
    239240        return KLDR_ERR_LX_BAD_LOADER_SECTION;
    240241    if (    Hdr.e32_dircnt
    241         && (Hdr.e32_dirtab < off || Hdr.e32_dirtab > offEnd))
     242        && (Hdr.e32_dirtab < off || Hdr.e32_dirtab > offEnd - 2))
    242243        return KLDR_ERR_LX_BAD_LOADER_SECTION;
    243244
     
    247248    if (    Hdr.e32_fpagetab
    248249        &&  (Hdr.e32_fpagetab < off || Hdr.e32_fpagetab > offEnd))
    249         return KLDR_ERR_LX_BAD_FIXUP_SECTION;
     250    {
     251        /*
     252         * wlink mixes the fixup section and the loader section.
     253         */
     254        off = Hdr.e32_fpagetab;
     255        offEnd = off + Hdr.e32_fixupsize;
     256        Hdr.e32_ldrsize = off - Hdr.e32_objtab;
     257    }
    250258    if (    Hdr.e32_frectab
    251259        &&  (Hdr.e32_frectab < off || Hdr.e32_frectab > offEnd))
     
    265273       + KLDR_ALIGN_Z(KLDR_OFFSETOF(KLDRMOD, aSegments[Hdr.e32_objcnt + 1]), 8)
    266274       + KLDR_ALIGN_Z(cchFilename + 1, 8)
    267        + Hdr.e32_ldrsize;
     275       + Hdr.e32_ldrsize + 2; /* +2 for two extra zeros. */
    268276    pModLX = (PKLDRMODLX)kldrHlpAlloc(cb);
    269277    if (!pModLX)
     
    332340
    333341    pModLX->pbLoaderSection = KLDR_ALIGN_P(pMod->pszFilename + pMod->cchFilename + 1, 16);
    334     pModLX->pbLoaderSectionLast = pModLX->pbLoaderSection + pModLX->Hdr.e32_ldrsize;
     342    pModLX->pbLoaderSectionLast = pModLX->pbLoaderSection + pModLX->Hdr.e32_ldrsize - 1;
    335343    pModLX->paObjs = NULL;
    336344    pModLX->paPageMappings = NULL;
     
    355363    if (rc)
    356364        return rc;
     365    ((uint8_t *)pModLX->pbLoaderSectionLast)[1] = 0;
     366    ((uint8_t *)pModLX->pbLoaderSectionLast)[2] = 0;
    357367    if (pModLX->Hdr.e32_objcnt)
    358368        pModLX->paObjs = (const struct o32_obj *)pModLX->pbLoaderSection;
     
    398408                     > pModLX->pbLoaderSectionLast))
    399409            return KLDR_ERR_LX_BAD_OBJECT_TABLE;
    400         if (i > 0)
     410        if (i > 0 && !(pModLX->paObjs[i].o32_flags & OBJRSRC))
    401411        {
    402412            if (pModLX->paObjs[i].o32_base <= pModLX->paObjs[i - 1].o32_base)
     
    427437        pMod->aSegments[i].offFile = -1;
    428438        pMod->aSegments[i].cbFile = -1;
     439        pMod->aSegments[i].SelFlat = 0;
     440        pMod->aSegments[i].Sel16bit = 0;
     441
     442        /* flags */
     443        pMod->aSegments[i].fFlags = 0;
     444        if (pModLX->paObjs[i].o32_flags & OBJBIGDEF)
     445            pMod->aSegments[i].fFlags = KLDRSEG_FLAG_16BIT;
     446        if (pModLX->paObjs[i].o32_flags & OBJALIAS16)
     447            pMod->aSegments[i].fFlags = KLDRSEG_FLAG_OS2_ALIAS16;
     448        if (pModLX->paObjs[i].o32_flags & OBJCONFORM)
     449            pMod->aSegments[i].fFlags = KLDRSEG_FLAG_OS2_CONFORM;
     450        if (pModLX->paObjs[i].o32_flags & OBJIOPL)
     451            pMod->aSegments[i].fFlags = KLDRSEG_FLAG_OS2_IOPL;
    429452
    430453        /* size and addresses */
     
    433456        pMod->aSegments[i].LinkAddress = pModLX->paObjs[i].o32_base;
    434457        pMod->aSegments[i].RVA         = NextRVA;
    435         if (fCanOptimizeMapping)
     458        if (    fCanOptimizeMapping
     459            ||  i + 1 >= pMod->cSegments
     460            ||  (pModLX->paObjs[i].o32_flags & OBJRSRC)
     461            ||  (pModLX->paObjs[i + 1].o32_flags & OBJRSRC))
    436462            pMod->aSegments[i].cbMapped = KLDR_ALIGN_Z(pModLX->paObjs[i].o32_size, OBJPAGELEN);
    437463        else
    438             pMod->aSegments[i].cbMapped = i + 1 < pMod->cSegments
    439                                         ? pModLX->paObjs[i + 1].o32_base - pModLX->paObjs[i].o32_base
    440                                         : KLDR_ALIGN_Z(pModLX->paObjs[i].o32_size, OBJPAGELEN);
     464            pMod->aSegments[i].cbMapped = pModLX->paObjs[i + 1].o32_base - pModLX->paObjs[i].o32_base;
    441465        NextRVA += pMod->aSegments[i].cbMapped;
    442466
     
    13951419                    if (cbDst < 0)
    13961420                        return KLDR_ERR_LX_BAD_ITERDATA2;
    1397                     cbSrc -= cb;
     1421                    cbSrc -= cb + 1;
    13981422                    if (cbSrc < 0)
    13991423                        return KLDR_ERR_LX_BAD_ITERDATA2;
     
    14531477                    kLdrHlpMemCopy(pbDst, pbSrc, cb1);
    14541478                    pbDst += cb1;
     1479                    pbSrc += cb1;
    14551480
    14561481                    if (off > OBJPAGELEN - cbDst)
     
    14851510                else
    14861511                {
    1487                     const unsigned  off = ((unsigned)pbSrc[2] << 4) | (*pbSrc >> 4);
     1512                    const unsigned  off = ((unsigned)pbSrc[1] << 4) | (*pbSrc >> 4);
    14881513                    const int       cb = ((*pbSrc >> 2) & 3) + 3;
    14891514
     
    15331558                    kLdrHlpMemCopy(pbDst, pbSrc, cb1);
    15341559                    pbDst += cb1;
     1560                    pbSrc += cb1;
    15351561
    15361562                    if (off > OBJPAGELEN - cbDst)
     
    19711997{
    19721998    PKLDRMODLX pModLX = (PKLDRMODLX)pMod->pvData;
    1973     uint32_t i;
     1999    uint32_t iSeg;
    19742000    int rc;
    19752001
     
    19952021     * Iterate the segments.
    19962022     */
    1997     for (i = 0; i < pModLX->Hdr.e32_objcnt; i++)
    1998     {
    1999         const struct o32_obj * const pObj = &pModLX->paObjs[i];
     2023    for (iSeg = 0; iSeg < pModLX->Hdr.e32_objcnt; iSeg++)
     2024    {
     2025        const struct o32_obj * const pObj = &pModLX->paObjs[iSeg];
     2026        KLDRADDR        PageAddress = NewBaseAddress + pModLX->pMod->aSegments[iSeg].RVA;
    20002027        uint32_t        iPage;
    2001         uint8_t        *pbPage = (uint8_t *)pvBits + (uintptr_t)pModLX->pMod->aSegments[i].RVA;
     2028        uint8_t        *pbPage = (uint8_t *)pvBits + (uintptr_t)pModLX->pMod->aSegments[iSeg].RVA;
    20022029
    20032030        /*
    20042031         * Iterate the page map pages.
    20052032         */
    2006         for (iPage = 0, rc = 0; !rc && iPage < pObj->o32_mapsize; iPage++, pbPage += OBJPAGELEN)
     2033        for (iPage = 0, rc = 0; !rc && iPage < pObj->o32_mapsize; iPage++, pbPage += OBJPAGELEN, PageAddress += OBJPAGELEN)
    20072034        {
    20082035            const uint8_t * const   pbFixupRecEnd = pModLX->pbFixupRecs + pModLX->paoffPageFixups[iPage + pObj->o32_pagemap];
    20092036            const uint8_t          *pb            = pModLX->pbFixupRecs + pModLX->paoffPageFixups[iPage + pObj->o32_pagemap - 1];
    20102037            KLDRADDR                uValue;
     2038            int                     iSelector;
    20112039            uint32_t                fKind;
    20122040
     
    20592087
    20602088                        /* the target */
    2061                         if (u.prlc->nr_flags & NR32BITOFF)
     2089                        if ((u.prlc->nr_stype & NRSRCMASK) != NRSSEG)
    20622090                        {
    2063                             offTrgObject = *(const uint32_t *)pb;
    2064                             pb += 4;
     2091                            if (u.prlc->nr_flags & NR32BITOFF)
     2092                            {
     2093                                offTrgObject = *(const uint32_t *)pb;
     2094                                pb += 4;
     2095                            }
     2096                            else
     2097                            {
     2098                                offTrgObject = *(const uint16_t *)pb;
     2099                                pb += 2;
     2100                            }
     2101
     2102                            /* calculate the symbol info. */
     2103                            uValue = offTrgObject + pMod->aSegments[iSeg].MapAddress;
    20652104                        }
    20662105                        else
    2067                         {
    2068                             offTrgObject = *(const uint16_t *)pb;
    2069                             pb += 2;
    2070                         }
    2071 
    2072                         /* calculate the symbol info. */
    2073                         uValue = offTrgObject + pMod->aSegments[i].MapAddress;
     2106                            uValue = pMod->aSegments[iSeg].MapAddress;
     2107                        if (    (u.prlc->nr_stype & NRALIAS)
     2108                            ||  (pMod->aSegments[iSeg].fFlags & KLDRSEG_FLAG_16BIT))
     2109                            iSelector = pMod->aSegments[iSeg].Sel16bit;
     2110                        else
     2111                            iSelector = pMod->aSegments[iSeg].SelFlat;
    20742112                        fKind = 0;
    20752113                        break;
     
    21182156                        if (rc)
    21192157                            return rc;
     2158                        iSelector = -1;
    21202159                        break;
    21212160                    }
     
    21692208                        if (rc)
    21702209                            return rc;
     2210                        iSelector = -1;
    21712211                        break;
    21722212                    }
     
    21932233                }
    21942234
     2235
    21952236                /*
    21962237                 * Deal with the 'source' (i.e. the place that should be modified (very logical).
     
    21982239                if (!(u.prlc->nr_stype & NRCHAIN))
    21992240                {
    2200                     rc = kldrModLXDoReloc(pbPage, u.prlc->r32_soff, uValue, fKind);
    2201                     if (rc)
    2202                         return rc;
     2241                    int off = u.prlc->r32_soff;
     2242
     2243                    /* common / simple */
     2244                    if (    (u.prlc->nr_stype & NRSRCMASK) == NROFF32
     2245                        &&  off >= 0
     2246                        &&  off <= OBJPAGELEN - 4)
     2247                        *(uint32_t *)&pbPage[off] = uValue;
     2248                    else if (    (u.prlc->nr_stype & NRSRCMASK) == NRSOFF32
     2249                            &&  off >= 0
     2250                            &&  off <= OBJPAGELEN - 4)
     2251                        *(uint32_t *)&pbPage[off] = uValue - (PageAddress + off);
     2252                    else
     2253                    {
     2254                        /* generic */
     2255                        rc = kldrModLXDoReloc(pbPage, off, PageAddress, u.prlc, iSelector, uValue, fKind);
     2256                        if (rc)
     2257                            return rc;
     2258                    }
    22032259                }
    22042260                else if (!(u.prlc->nr_flags & NRICHAIN))
    22052261                {
    2206                     const uint16_t *poffSrc = (const uint16_t *)pb;
     2262                    const int16_t *poffSrc = (const int16_t *)pb;
    22072263                    uint8_t c = u.pb[2];
    2208                     while (c-- > 0)
     2264
     2265                    /* common / simple */
     2266                    if ((u.prlc->nr_stype & NRSRCMASK) == NROFF32)
    22092267                    {
    2210                         rc = kldrModLXDoReloc(pbPage, *poffSrc++, uValue, fKind);
    2211                         if (rc)
    2212                             return rc;
     2268                        while (c-- > 0)
     2269                        {
     2270                            int off = *poffSrc++;
     2271                            if (off >= 0 && off <= OBJPAGELEN - 4)
     2272                                *(uint32_t *)&pbPage[off] = uValue;
     2273                            else
     2274                            {
     2275                                rc = kldrModLXDoReloc(pbPage, off, PageAddress, u.prlc, iSelector, uValue, fKind);
     2276                                if (rc)
     2277                                    return rc;
     2278                            }
     2279                        }
     2280                    }
     2281                    else if ((u.prlc->nr_stype & NRSRCMASK) == NRSOFF32)
     2282                    {
     2283                        while (c-- > 0)
     2284                        {
     2285                            int off = *poffSrc++;
     2286                            if (off >= 0 && off <= OBJPAGELEN - 4)
     2287                                *(uint32_t *)&pbPage[off] = uValue - (PageAddress + off);
     2288                            else
     2289                            {
     2290                                rc = kldrModLXDoReloc(pbPage, off, PageAddress, u.prlc, iSelector, uValue, fKind);
     2291                                if (rc)
     2292                                    return rc;
     2293                            }
     2294                        }
     2295                    }
     2296                    else
     2297                    {
     2298                        while (c-- > 0)
     2299                        {
     2300                            rc = kldrModLXDoReloc(pbPage, *poffSrc++, PageAddress, u.prlc, iSelector, uValue, fKind);
     2301                            if (rc)
     2302                                return rc;
     2303                        }
    22132304                    }
    22142305                    pb = (const uint8_t *)poffSrc;
     
    22162307                else
    22172308                {
     2309                    /* This is a pain because it will require virgin pages on a relocation. */
    22182310                    KLDRMODLX_ASSERT(!"NRICHAIN");
    22192311                    return KLDR_ERR_LX_NRICHAIN_NOT_SUPPORTED;
     
    22292321/**
    22302322 * Applies the relocation to one 'source' in a page.
     2323 *
     2324 * This takes care of the more esotic case while the common cases
     2325 * are dealt with seperately.
    22312326 *
    22322327 * @returns 0 on success, non-zero kLdr status code on failure.
     
    22352330 * @param   uValue      The target value.
    22362331 * @param   fKind       The target kind.
    2237  * @todo inline this.
    22382332 */
    2239 static int kldrModLXDoReloc(uint8_t *pbPage, int off, KLDRADDR uValue, uint32_t fKind)
    2240 {
    2241 
     2333static int kldrModLXDoReloc(uint8_t *pbPage, int off, KLDRADDR PageAddress, const struct r32_rlc *prlc,
     2334                            int iSelector, KLDRADDR uValue, uint32_t fKind)
     2335{
     2336    static const uint8_t s_acb[16] =
     2337    {
     2338        1, /* 0: NRSBYT */
     2339        0,
     2340        2, /* 2: NRSSEG - selector */
     2341        4, /* 3: NRSPTR - 16:16 */
     2342        0,
     2343        2, /* 5: NRSOFF - 16-bit offset */
     2344        6, /* 6: NRPTR48 - 16:32 */
     2345        4, /* 7: NROFF32 - 32-bit offset */
     2346        4, /* 8: NRSOFF32 - 32-bit offset self relative */
     2347        0, 0, 0, 0, 0, 0, 0
     2348    };
     2349#pragma pack(1) /* just to be sure */
     2350    union
     2351    {
     2352        uint8_t     ab[6];
     2353        uint32_t    off32;
     2354        uint16_t    off16;
     2355        uint8_t     off8;
     2356        struct
     2357        {
     2358            uint16_t off;
     2359            uint16_t Sel;
     2360        }           Far16;
     2361        struct
     2362        {
     2363            uint32_t off;
     2364            uint16_t Sel;
     2365        }           Far32;
     2366    }               uData;
     2367#pragma pack()
     2368    const uint8_t  *pbSrc;
     2369    uint8_t        *pbDst;
     2370    uint8_t         cb;
     2371
     2372    /*
     2373     * Compose the fixup data.
     2374     */
     2375    switch (prlc->nr_stype & NRSRCMASK)
     2376    {
     2377        case NRSBYT:       
     2378            uData.off8 = (uint8_t)uValue;
     2379            cb = 1;
     2380            break;
     2381        case NRSSEG:
     2382            if (iSelector == -1)
     2383            {
     2384                /* fixme */
     2385            }
     2386            uData.off16 = iSelector;
     2387            cb = 2;
     2388            break;
     2389        case NRSPTR:
     2390            if (iSelector == -1)
     2391            {
     2392                /* fixme */
     2393            }
     2394            uData.Far16.off = (uint16_t)uValue;
     2395            uData.Far16.Sel = iSelector;
     2396            cb = 4;
     2397            break;
     2398        case NRSOFF:
     2399            uData.off16 = (uint16_t)uValue;
     2400            cb = 2;
     2401            break;
     2402        case NRPTR48:
     2403            if (iSelector == -1)
     2404            {
     2405                /* fixme */
     2406            }
     2407            uData.Far32.off = (uint32_t)uValue;
     2408            uData.Far32.Sel = iSelector;
     2409            cb = 6;
     2410            break;
     2411        case NROFF32:
     2412            uData.off32 = (uint32_t)uValue;
     2413            cb = 4;
     2414            break;
     2415        case NRSOFF32:
     2416            uData.off32 = (uint32_t)uValue - (PageAddress + off);
     2417            cb = 4;
     2418            break;
     2419        default:
     2420            return KLDR_ERR_LX_BAD_FIXUP_SECTION; /** @todo fix error, add more checks! */
     2421    }
     2422
     2423    /*
     2424     * Apply it. This is sloooow...
     2425     */
     2426    pbSrc = &uData.ab[0];
     2427    pbDst = pbPage + off;
     2428    while (cb-- > 0)
     2429    {
     2430        if (off > OBJPAGELEN)
     2431            break;
     2432        if (off >= 0)
     2433            *pbDst = *pbSrc;
     2434        pbSrc++;
     2435        pbDst++;
     2436    }
    22422437
    22432438    return 0;
  • trunk/kLdr/kLdrModPE.c

    r2947 r2948  
    313313        pMod->aSegments[i + 1].pvUser = NULL;
    314314        pMod->aSegments[i + 1].MapAddress = 0;
     315        pMod->aSegments[i + 1].SelFlat = 0;
     316        pMod->aSegments[i + 1].Sel16bit = 0;
     317        pMod->aSegments[i + 1].fFlags = 0;
    315318
    316319        /* name */
Note: See TracChangeset for help on using the changeset viewer.