Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ldrreloc.c File Reference

#include "ntrtlp.h"

Go to the source code of this file.

Defines

#define SWAP_SHORT(_dst, _src)
#define SWAP_INT(_dst, _src)
#define SWAP_LONG_LONG(_dst, _src)
#define LDRP_RELOCATION_INCREMENT   0x1
#define LDRP_RELOCATION_FINAL   0x2

Functions

ULONG LdrRelocateImage (IN PVOID NewBase, IN PUCHAR LoaderName, IN ULONG Success, IN ULONG Conflict, IN ULONG Invalid)
PIMAGE_BASE_RELOCATION LdrProcessRelocationBlock (IN ULONG_PTR VA, IN ULONG SizeOfBlock, IN PUSHORT NextOffset, IN LONG_PTR Diff)


Define Documentation

#define LDRP_RELOCATION_FINAL   0x2
 

Definition at line 58 of file ldrreloc.c.

Referenced by LdrProcessRelocationBlock().

#define LDRP_RELOCATION_INCREMENT   0x1
 

Definition at line 53 of file ldrreloc.c.

Referenced by LdrProcessRelocationBlock().

#define SWAP_INT _dst,
_src   ) 
 

Value:

((((unsigned char *)_dst)[3] = ((unsigned char *)_src)[0]), \ (((unsigned char *)_dst)[2] = ((unsigned char *)_src)[1]), \ (((unsigned char *)_dst)[1] = ((unsigned char *)_src)[2]), \ (((unsigned char *)_dst)[0] = ((unsigned char *)_src)[3]))

Definition at line 34 of file ldrreloc.c.

#define SWAP_LONG_LONG _dst,
_src   ) 
 

Value:

((((unsigned char *)_dst)[7] = ((unsigned char *)_src)[0]), \ (((unsigned char *)_dst)[6] = ((unsigned char *)_src)[1]), \ (((unsigned char *)_dst)[5] = ((unsigned char *)_src)[2]), \ (((unsigned char *)_dst)[4] = ((unsigned char *)_src)[3]), \ (((unsigned char *)_dst)[3] = ((unsigned char *)_src)[4]), \ (((unsigned char *)_dst)[2] = ((unsigned char *)_src)[5]), \ (((unsigned char *)_dst)[1] = ((unsigned char *)_src)[6]), \ (((unsigned char *)_dst)[0] = ((unsigned char *)_src)[7]))

Definition at line 40 of file ldrreloc.c.

#define SWAP_SHORT _dst,
_src   ) 
 

Value:

((((unsigned char *)_dst)[1] = ((unsigned char *)_src)[0]), \ (((unsigned char *)_dst)[0] = ((unsigned char *)_src)[1]))

Definition at line 30 of file ldrreloc.c.


Function Documentation

PIMAGE_BASE_RELOCATION LdrProcessRelocationBlock IN ULONG_PTR  VA,
IN ULONG  SizeOfBlock,
IN PUSHORT  NextOffset,
IN LONG_PTR  Diff
 

Definition at line 194 of file ldrreloc.c.

References LDRP_RELOCATION_FINAL, LDRP_RELOCATION_INCREMENT, NULL, Offset, PSHORT, PUSHORT, RTL_PAGED_CODE, SHORT, and USHORT.

Referenced by LdrRelocateImage().

00200 { 00201 PUCHAR FixupVA; 00202 USHORT Offset; 00203 LONG Temp; 00204 LONG TempOrig; 00205 ULONG Temp32; 00206 ULONGLONG Value64; 00207 LONGLONG Temp64; 00208 LONG_PTR ActualDiff; 00209 00210 RTL_PAGED_CODE(); 00211 00212 while (SizeOfBlock--) { 00213 00214 Offset = *NextOffset & (USHORT)0xfff; 00215 FixupVA = (PUCHAR)(VA + Offset); 00216 00217 // 00218 // Apply the fixups. 00219 // 00220 00221 switch ((*NextOffset) >> 12) { 00222 00223 case IMAGE_REL_BASED_HIGHLOW : 00224 // 00225 // HighLow - (32-bits) relocate the high and low half 00226 // of an address. 00227 // 00228 *(LONG UNALIGNED *)FixupVA += (ULONG) Diff; 00229 break; 00230 00231 case IMAGE_REL_BASED_HIGH : 00232 // 00233 // High - (16-bits) relocate the high half of an address. 00234 // 00235 Temp = *(PUSHORT)FixupVA << 16; 00236 Temp += (ULONG) Diff; 00237 *(PUSHORT)FixupVA = (USHORT)(Temp >> 16); 00238 break; 00239 00240 case IMAGE_REL_BASED_HIGHADJ : 00241 // 00242 // Adjust high - (16-bits) relocate the high half of an 00243 // address and adjust for sign extension of low half. 00244 // 00245 00246 #if defined(NTOS_KERNEL_RUNTIME) 00247 // 00248 // If the address has already been relocated then don't 00249 // process it again now or information will be lost. 00250 // 00251 if (Offset & LDRP_RELOCATION_FINAL) { 00252 ++NextOffset; 00253 --SizeOfBlock; 00254 break; 00255 } 00256 #endif 00257 00258 Temp = *(PUSHORT)FixupVA << 16; 00259 #if defined(BLDR_KERNEL_RUNTIME) 00260 TempOrig = Temp; 00261 #endif 00262 ++NextOffset; 00263 --SizeOfBlock; 00264 Temp += (LONG)(*(PSHORT)NextOffset); 00265 Temp += (ULONG) Diff; 00266 Temp += 0x8000; 00267 *(PUSHORT)FixupVA = (USHORT)(Temp >> 16); 00268 00269 #if defined(BLDR_KERNEL_RUNTIME) 00270 ActualDiff = ((((ULONG_PTR)(Temp - TempOrig)) >> 16) - 00271 (((ULONG_PTR)Diff) >> 16 )); 00272 00273 if (ActualDiff == 1) { 00274 // 00275 // Mark the relocation as needing an increment if it is 00276 // relocated again. 00277 // 00278 *(NextOffset - 1) |= LDRP_RELOCATION_INCREMENT; 00279 } 00280 else if (ActualDiff != 0) { 00281 // 00282 // Mark the relocation as cannot be reprocessed. 00283 // 00284 *(NextOffset - 1) |= LDRP_RELOCATION_FINAL; 00285 } 00286 #endif 00287 00288 break; 00289 00290 case IMAGE_REL_BASED_LOW : 00291 // 00292 // Low - (16-bit) relocate the low half of an address. 00293 // 00294 Temp = *(PSHORT)FixupVA; 00295 Temp += (ULONG) Diff; 00296 *(PUSHORT)FixupVA = (USHORT)Temp; 00297 break; 00298 00299 case IMAGE_REL_BASED_IA64_IMM64: 00300 00301 // 00302 // Align it to bundle address before fixing up the 00303 // 64-bit immediate value of the movl instruction. 00304 // 00305 00306 FixupVA = (PUCHAR)((ULONG_PTR)FixupVA & ~(15)); 00307 Value64 = (ULONGLONG)0; 00308 00309 // 00310 // Extract the lower 32 bits of IMM64 from bundle 00311 // 00312 00313 00314 EXT_IMM64(Value64, 00315 (PULONG)FixupVA + EMARCH_ENC_I17_IMM7B_INST_WORD_X, 00316 EMARCH_ENC_I17_IMM7B_SIZE_X, 00317 EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X, 00318 EMARCH_ENC_I17_IMM7B_VAL_POS_X); 00319 EXT_IMM64(Value64, 00320 (PULONG)FixupVA + EMARCH_ENC_I17_IMM9D_INST_WORD_X, 00321 EMARCH_ENC_I17_IMM9D_SIZE_X, 00322 EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X, 00323 EMARCH_ENC_I17_IMM9D_VAL_POS_X); 00324 EXT_IMM64(Value64, 00325 (PULONG)FixupVA + EMARCH_ENC_I17_IMM5C_INST_WORD_X, 00326 EMARCH_ENC_I17_IMM5C_SIZE_X, 00327 EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X, 00328 EMARCH_ENC_I17_IMM5C_VAL_POS_X); 00329 EXT_IMM64(Value64, 00330 (PULONG)FixupVA + EMARCH_ENC_I17_IC_INST_WORD_X, 00331 EMARCH_ENC_I17_IC_SIZE_X, 00332 EMARCH_ENC_I17_IC_INST_WORD_POS_X, 00333 EMARCH_ENC_I17_IC_VAL_POS_X); 00334 EXT_IMM64(Value64, 00335 (PULONG)FixupVA + EMARCH_ENC_I17_IMM41a_INST_WORD_X, 00336 EMARCH_ENC_I17_IMM41a_SIZE_X, 00337 EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X, 00338 EMARCH_ENC_I17_IMM41a_VAL_POS_X); 00339 00340 // 00341 // Update 64-bit address 00342 // 00343 00344 Value64+=Diff; 00345 00346 // 00347 // Insert IMM64 into bundle 00348 // 00349 00350 INS_IMM64(Value64, 00351 ((PULONG)FixupVA + EMARCH_ENC_I17_IMM7B_INST_WORD_X), 00352 EMARCH_ENC_I17_IMM7B_SIZE_X, 00353 EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X, 00354 EMARCH_ENC_I17_IMM7B_VAL_POS_X); 00355 INS_IMM64(Value64, 00356 ((PULONG)FixupVA + EMARCH_ENC_I17_IMM9D_INST_WORD_X), 00357 EMARCH_ENC_I17_IMM9D_SIZE_X, 00358 EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X, 00359 EMARCH_ENC_I17_IMM9D_VAL_POS_X); 00360 INS_IMM64(Value64, 00361 ((PULONG)FixupVA + EMARCH_ENC_I17_IMM5C_INST_WORD_X), 00362 EMARCH_ENC_I17_IMM5C_SIZE_X, 00363 EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X, 00364 EMARCH_ENC_I17_IMM5C_VAL_POS_X); 00365 INS_IMM64(Value64, 00366 ((PULONG)FixupVA + EMARCH_ENC_I17_IC_INST_WORD_X), 00367 EMARCH_ENC_I17_IC_SIZE_X, 00368 EMARCH_ENC_I17_IC_INST_WORD_POS_X, 00369 EMARCH_ENC_I17_IC_VAL_POS_X); 00370 INS_IMM64(Value64, 00371 ((PULONG)FixupVA + EMARCH_ENC_I17_IMM41a_INST_WORD_X), 00372 EMARCH_ENC_I17_IMM41a_SIZE_X, 00373 EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X, 00374 EMARCH_ENC_I17_IMM41a_VAL_POS_X); 00375 INS_IMM64(Value64, 00376 ((PULONG)FixupVA + EMARCH_ENC_I17_IMM41b_INST_WORD_X), 00377 EMARCH_ENC_I17_IMM41b_SIZE_X, 00378 EMARCH_ENC_I17_IMM41b_INST_WORD_POS_X, 00379 EMARCH_ENC_I17_IMM41b_VAL_POS_X); 00380 INS_IMM64(Value64, 00381 ((PULONG)FixupVA + EMARCH_ENC_I17_IMM41c_INST_WORD_X), 00382 EMARCH_ENC_I17_IMM41c_SIZE_X, 00383 EMARCH_ENC_I17_IMM41c_INST_WORD_POS_X, 00384 EMARCH_ENC_I17_IMM41c_VAL_POS_X); 00385 INS_IMM64(Value64, 00386 ((PULONG)FixupVA + EMARCH_ENC_I17_SIGN_INST_WORD_X), 00387 EMARCH_ENC_I17_SIGN_SIZE_X, 00388 EMARCH_ENC_I17_SIGN_INST_WORD_POS_X, 00389 EMARCH_ENC_I17_SIGN_VAL_POS_X); 00390 break; 00391 00392 case IMAGE_REL_BASED_DIR64: 00393 00394 *(ULONG_PTR UNALIGNED *)FixupVA += Diff; 00395 00396 break; 00397 00398 case IMAGE_REL_BASED_MIPS_JMPADDR : 00399 // 00400 // JumpAddress - (32-bits) relocate a MIPS jump address. 00401 // 00402 Temp = (*(PULONG)FixupVA & 0x3ffffff) << 2; 00403 Temp += (ULONG) Diff; 00404 *(PULONG)FixupVA = (*(PULONG)FixupVA & ~0x3ffffff) | 00405 ((Temp >> 2) & 0x3ffffff); 00406 00407 break; 00408 00409 case IMAGE_REL_BASED_ABSOLUTE : 00410 // 00411 // Absolute - no fixup required. 00412 // 00413 break; 00414 00415 case IMAGE_REL_BASED_SECTION : 00416 // 00417 // Section Relative reloc. Ignore for now. 00418 // 00419 break; 00420 00421 case IMAGE_REL_BASED_REL32 : 00422 // 00423 // Relative intrasection. Ignore for now. 00424 // 00425 break; 00426 00427 case IMAGE_REL_BASED_HIGH3ADJ : 00428 // 00429 // Similar to HIGHADJ except this is the third word. 00430 // Adjust low half of high dword of an address and adjust for 00431 // sign extension of the low dword. 00432 // 00433 00434 Temp64 = *(PUSHORT)FixupVA << 16; 00435 ++NextOffset; 00436 --SizeOfBlock; 00437 Temp64 += (LONG)((SHORT)NextOffset[1]); 00438 Temp64 <<= 16; 00439 Temp64 += (LONG)((USHORT)NextOffset[0]); 00440 Temp64 += Diff; 00441 Temp64 += 0x8000; 00442 Temp64 >>=16; 00443 Temp64 += 0x8000; 00444 *(PUSHORT)FixupVA = (USHORT)(Temp64 >> 16); 00445 ++NextOffset; 00446 --SizeOfBlock; 00447 break; 00448 00449 default : 00450 // 00451 // Illegal - illegal relocation type. 00452 // 00453 00454 return (PIMAGE_BASE_RELOCATION)NULL; 00455 } 00456 ++NextOffset; 00457 } 00458 return (PIMAGE_BASE_RELOCATION)NextOffset; 00459 }

ULONG LdrRelocateImage IN PVOID  NewBase,
IN PUCHAR  LoaderName,
IN ULONG  Success,
IN ULONG  Conflict,
IN ULONG  Invalid
 

Definition at line 91 of file ldrreloc.c.

References DbgPrint, LdrProcessRelocationBlock(), Offset, PUSHORT, RTL_PAGED_CODE, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), TRUE, and USHORT.

Referenced by LdrpInitializeProcess(), LdrpMapDll(), MiLoadSystemImage(), and MiReloadBootLoadedDrivers().

00101 : 00102 00103 This routine relocates an image file that was not loaded into memory 00104 at the preferred address. 00105 00106 Arguments: 00107 00108 NewBase - Supplies a pointer to the image base. 00109 00110 LoaderName - Indicates which loader routine is being called from. 00111 00112 Success - Value to return if relocation successful. 00113 00114 Conflict - Value to return if can't relocate. 00115 00116 Invalid - Value to return if relocations are invalid. 00117 00118 Return Value: 00119 00120 Success if image is relocated. 00121 Conflict if image can't be relocated. 00122 Invalid if image contains invalid fixups. 00123 00124 --*/ 00125 00126 { 00127 LONG_PTR Diff; 00128 ULONG TotalCountBytes; 00129 ULONG_PTR VA; 00130 ULONG_PTR OldBase; 00131 ULONG SizeOfBlock; 00132 PUCHAR FixupVA; 00133 USHORT Offset; 00134 PUSHORT NextOffset; 00135 PIMAGE_NT_HEADERS NtHeaders; 00136 PIMAGE_BASE_RELOCATION NextBlock; 00137 00138 RTL_PAGED_CODE(); 00139 00140 NtHeaders = RtlImageNtHeader( NewBase ); 00141 if ( NtHeaders ) { 00142 OldBase = NtHeaders->OptionalHeader.ImageBase; 00143 } 00144 else { 00145 return Invalid; 00146 } 00147 00148 // 00149 // Locate the relocation section. 00150 // 00151 00152 NextBlock = (PIMAGE_BASE_RELOCATION)RtlImageDirectoryEntryToData( 00153 NewBase, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &TotalCountBytes); 00154 00155 if (!NextBlock || !TotalCountBytes) { 00156 00157 // 00158 // The image does not contain a relocation table, and therefore 00159 // cannot be relocated. 00160 // 00161 #if DBG 00162 DbgPrint("%s: Image can't be relocated, no fixup information.\n", LoaderName); 00163 #endif // DBG 00164 return Conflict; 00165 } 00166 00167 // 00168 // If the image has a relocation table, then apply the specified fixup 00169 // information to the image. 00170 // 00171 00172 while (TotalCountBytes) { 00173 SizeOfBlock = NextBlock->SizeOfBlock; 00174 TotalCountBytes -= SizeOfBlock; 00175 SizeOfBlock -= sizeof(IMAGE_BASE_RELOCATION); 00176 SizeOfBlock /= sizeof(USHORT); 00177 NextOffset = (PUSHORT)((PCHAR)NextBlock + sizeof(IMAGE_BASE_RELOCATION)); 00178 00179 VA = (ULONG_PTR)NewBase + NextBlock->VirtualAddress; 00180 Diff = (PCHAR)NewBase - (PCHAR)OldBase; 00181 00182 if ( !(NextBlock = LdrProcessRelocationBlock(VA,SizeOfBlock,NextOffset,Diff)) ) { 00183 #if DBG 00184 DbgPrint("%s: Unknown base relocation type\n", LoaderName); 00185 #endif 00186 return Invalid; 00187 } 00188 } 00189 00190 return Success; 00191 }


Generated on Sat May 15 19:44:31 2004 for test by doxygen 1.3.7