Changeset 2948
- Timestamp:
- Jan 14, 2007, 11:35:04 PM (19 years ago)
- Location:
- trunk/kLdr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdr.h
r2945 r2948 412 412 /** The length of the segment name. */ 413 413 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; 414 422 /** The segment protection. */ 415 423 KLDRPROT enmProt; … … 438 446 uintptr_t MapAddress; 439 447 } 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 /** @} */ 440 461 441 462 -
trunk/kLdr/kLdrModLX.c
r2893 r2948 133 133 static int kldrModLXDoLoadFixupSection(PKLDRMODLX pModLX); 134 134 static 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); 135 static int kldrModLXDoReloc(uint8_t *pbPage, int off, KLDRADDR PageAddress, const struct r32_rlc *prlc, 136 int iSelector, KLDRADDR uValue, uint32_t fKind); 136 137 137 138 … … 236 237 return KLDR_ERR_LX_BAD_LOADER_SECTION; 237 238 if ( Hdr.e32_enttab 238 && (Hdr.e32_enttab < off || Hdr.e32_enttab > offEnd - 2))239 && (Hdr.e32_enttab < off || Hdr.e32_enttab >= offEnd)) 239 240 return KLDR_ERR_LX_BAD_LOADER_SECTION; 240 241 if ( Hdr.e32_dircnt 241 && (Hdr.e32_dirtab < off || Hdr.e32_dirtab > offEnd ))242 && (Hdr.e32_dirtab < off || Hdr.e32_dirtab > offEnd - 2)) 242 243 return KLDR_ERR_LX_BAD_LOADER_SECTION; 243 244 … … 247 248 if ( Hdr.e32_fpagetab 248 249 && (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 } 250 258 if ( Hdr.e32_frectab 251 259 && (Hdr.e32_frectab < off || Hdr.e32_frectab > offEnd)) … … 265 273 + KLDR_ALIGN_Z(KLDR_OFFSETOF(KLDRMOD, aSegments[Hdr.e32_objcnt + 1]), 8) 266 274 + KLDR_ALIGN_Z(cchFilename + 1, 8) 267 + Hdr.e32_ldrsize ;275 + Hdr.e32_ldrsize + 2; /* +2 for two extra zeros. */ 268 276 pModLX = (PKLDRMODLX)kldrHlpAlloc(cb); 269 277 if (!pModLX) … … 332 340 333 341 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; 335 343 pModLX->paObjs = NULL; 336 344 pModLX->paPageMappings = NULL; … … 355 363 if (rc) 356 364 return rc; 365 ((uint8_t *)pModLX->pbLoaderSectionLast)[1] = 0; 366 ((uint8_t *)pModLX->pbLoaderSectionLast)[2] = 0; 357 367 if (pModLX->Hdr.e32_objcnt) 358 368 pModLX->paObjs = (const struct o32_obj *)pModLX->pbLoaderSection; … … 398 408 > pModLX->pbLoaderSectionLast)) 399 409 return KLDR_ERR_LX_BAD_OBJECT_TABLE; 400 if (i > 0 )410 if (i > 0 && !(pModLX->paObjs[i].o32_flags & OBJRSRC)) 401 411 { 402 412 if (pModLX->paObjs[i].o32_base <= pModLX->paObjs[i - 1].o32_base) … … 427 437 pMod->aSegments[i].offFile = -1; 428 438 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; 429 452 430 453 /* size and addresses */ … … 433 456 pMod->aSegments[i].LinkAddress = pModLX->paObjs[i].o32_base; 434 457 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)) 436 462 pMod->aSegments[i].cbMapped = KLDR_ALIGN_Z(pModLX->paObjs[i].o32_size, OBJPAGELEN); 437 463 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; 441 465 NextRVA += pMod->aSegments[i].cbMapped; 442 466 … … 1395 1419 if (cbDst < 0) 1396 1420 return KLDR_ERR_LX_BAD_ITERDATA2; 1397 cbSrc -= cb ;1421 cbSrc -= cb + 1; 1398 1422 if (cbSrc < 0) 1399 1423 return KLDR_ERR_LX_BAD_ITERDATA2; … … 1453 1477 kLdrHlpMemCopy(pbDst, pbSrc, cb1); 1454 1478 pbDst += cb1; 1479 pbSrc += cb1; 1455 1480 1456 1481 if (off > OBJPAGELEN - cbDst) … … 1485 1510 else 1486 1511 { 1487 const unsigned off = ((unsigned)pbSrc[ 2] << 4) | (*pbSrc >> 4);1512 const unsigned off = ((unsigned)pbSrc[1] << 4) | (*pbSrc >> 4); 1488 1513 const int cb = ((*pbSrc >> 2) & 3) + 3; 1489 1514 … … 1533 1558 kLdrHlpMemCopy(pbDst, pbSrc, cb1); 1534 1559 pbDst += cb1; 1560 pbSrc += cb1; 1535 1561 1536 1562 if (off > OBJPAGELEN - cbDst) … … 1971 1997 { 1972 1998 PKLDRMODLX pModLX = (PKLDRMODLX)pMod->pvData; 1973 uint32_t i ;1999 uint32_t iSeg; 1974 2000 int rc; 1975 2001 … … 1995 2021 * Iterate the segments. 1996 2022 */ 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; 2000 2027 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; 2002 2029 2003 2030 /* 2004 2031 * Iterate the page map pages. 2005 2032 */ 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) 2007 2034 { 2008 2035 const uint8_t * const pbFixupRecEnd = pModLX->pbFixupRecs + pModLX->paoffPageFixups[iPage + pObj->o32_pagemap]; 2009 2036 const uint8_t *pb = pModLX->pbFixupRecs + pModLX->paoffPageFixups[iPage + pObj->o32_pagemap - 1]; 2010 2037 KLDRADDR uValue; 2038 int iSelector; 2011 2039 uint32_t fKind; 2012 2040 … … 2059 2087 2060 2088 /* the target */ 2061 if ( u.prlc->nr_flags & NR32BITOFF)2089 if ((u.prlc->nr_stype & NRSRCMASK) != NRSSEG) 2062 2090 { 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; 2065 2104 } 2066 2105 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; 2074 2112 fKind = 0; 2075 2113 break; … … 2118 2156 if (rc) 2119 2157 return rc; 2158 iSelector = -1; 2120 2159 break; 2121 2160 } … … 2169 2208 if (rc) 2170 2209 return rc; 2210 iSelector = -1; 2171 2211 break; 2172 2212 } … … 2193 2233 } 2194 2234 2235 2195 2236 /* 2196 2237 * Deal with the 'source' (i.e. the place that should be modified (very logical). … … 2198 2239 if (!(u.prlc->nr_stype & NRCHAIN)) 2199 2240 { 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 } 2203 2259 } 2204 2260 else if (!(u.prlc->nr_flags & NRICHAIN)) 2205 2261 { 2206 const uint16_t *poffSrc = (const uint16_t *)pb;2262 const int16_t *poffSrc = (const int16_t *)pb; 2207 2263 uint8_t c = u.pb[2]; 2208 while (c-- > 0) 2264 2265 /* common / simple */ 2266 if ((u.prlc->nr_stype & NRSRCMASK) == NROFF32) 2209 2267 { 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 } 2213 2304 } 2214 2305 pb = (const uint8_t *)poffSrc; … … 2216 2307 else 2217 2308 { 2309 /* This is a pain because it will require virgin pages on a relocation. */ 2218 2310 KLDRMODLX_ASSERT(!"NRICHAIN"); 2219 2311 return KLDR_ERR_LX_NRICHAIN_NOT_SUPPORTED; … … 2229 2321 /** 2230 2322 * 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. 2231 2326 * 2232 2327 * @returns 0 on success, non-zero kLdr status code on failure. … … 2235 2330 * @param uValue The target value. 2236 2331 * @param fKind The target kind. 2237 * @todo inline this.2238 2332 */ 2239 static int kldrModLXDoReloc(uint8_t *pbPage, int off, KLDRADDR uValue, uint32_t fKind) 2240 { 2241 2333 static 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 } 2242 2437 2243 2438 return 0; -
trunk/kLdr/kLdrModPE.c
r2947 r2948 313 313 pMod->aSegments[i + 1].pvUser = NULL; 314 314 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; 315 318 316 319 /* name */
Note:
See TracChangeset
for help on using the changeset viewer.