A necessary hack for PE relocation within physical address space (in FreeLdr).
authorAleksey Bragin <aleksey@reactos.org>
Tue, 5 Dec 2006 18:28:08 +0000 (18:28 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Tue, 5 Dec 2006 18:28:08 +0000 (18:28 +0000)
Using it removes code duplication from FreeLdr / winldr.

To get rid of this hack, either freeldr should be fully switched to virtual paged mode (which is not good) or code must be duplicated inside freeldr.

svn path=/trunk/; revision=25070

reactos/lib/rtl/image.c

index 1df8af5..097115d 100644 (file)
@@ -226,6 +226,10 @@ LdrProcessRelocationBlockLongLong(
     return (PIMAGE_BASE_RELOCATION)TypeOffset;
 }
 
+/* NOTE: When this function is called with LoaderName == "FLx86"
+         it's going to behave differently: it will perform all
+         relocations as needed, but will access only valid physical
+         addresses (not virtual addresses) */
 ULONG
 NTAPI
 LdrRelocateImageWithBias(
@@ -250,10 +254,10 @@ LdrRelocateImageWithBias(
     if (NtHeaders == NULL)
         return Invalid;
 
-    if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
+    /*if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
     {
         return Conflict;
-    }
+    }*/
 
     RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
 
@@ -262,7 +266,19 @@ LdrRelocateImageWithBias(
         return Success;
     }
 
-    Delta = (ULONG_PTR)BaseAddress - NtHeaders->OptionalHeader.ImageBase + AdditionalBias;
+    /* ROS/FreeLoader/arch-specific stuff, for relocating while being in PA mode */
+    if ((LoaderName != NULL) && (!strncmp(LoaderName, "FLx86", 5)))
+    {
+        /* Calculate it, converting BaseAddress to a virtual address */
+        Delta = ((ULONG_PTR)BaseAddress | 0x80000000) -
+            NtHeaders->OptionalHeader.ImageBase + AdditionalBias;
+    }
+    else
+    {
+        /* Calculate it as usual */
+        Delta = (ULONG_PTR)BaseAddress - NtHeaders->OptionalHeader.ImageBase + AdditionalBias;
+    }
+
     RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + RelocationDDir->VirtualAddress);
     RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);