mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
Reapply fixed half of 24020 (relocation update in rtl). Tested on vmware and real hardware.
svn path=/trunk/; revision=24112
This commit is contained in:
parent
63ae604355
commit
efcc4447c1
1 changed files with 80 additions and 58 deletions
|
@ -3,8 +3,10 @@
|
|||
* FILE: lib/rtl/image.c
|
||||
* PURPOSE: Image handling functions
|
||||
* Relocate functions were previously located in
|
||||
* ntoskrnl/ldr/loader.c
|
||||
* PROGRAMMER: Eric Kohl + original authors from loader.c file
|
||||
* ntoskrnl/ldr/loader.c and
|
||||
* dll/ntdll/ldr/utils.c files
|
||||
* PROGRAMMER: Eric Kohl + original authors from loader.c and utils.c file
|
||||
* Aleksey Bragin
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -149,6 +151,70 @@ RtlImageRvaToVa (
|
|||
(ULONG_PTR)Section->VirtualAddress);
|
||||
}
|
||||
|
||||
PIMAGE_BASE_RELOCATION
|
||||
LdrProcessRelocationBlockLongLong(
|
||||
IN ULONG_PTR Address,
|
||||
IN ULONG Count,
|
||||
IN PUSHORT TypeOffset,
|
||||
IN LONGLONG Delta
|
||||
)
|
||||
{
|
||||
SHORT Offset;
|
||||
USHORT Type;
|
||||
USHORT i;
|
||||
PUSHORT ShortPtr;
|
||||
PULONG LongPtr;
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Offset = *TypeOffset & 0xFFF;
|
||||
Type = *TypeOffset >> 12;
|
||||
ShortPtr = (PUSHORT)(RVA(Address, Offset));
|
||||
|
||||
/*
|
||||
* Don't relocate within the relocation section itself.
|
||||
* GCC/LD generates sometimes relocation records for the relocation section.
|
||||
* This is a bug in GCC/LD.
|
||||
* Fix for it disabled, since it was only in ntoskrnl and not in ntdll
|
||||
*/
|
||||
/*
|
||||
if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
|
||||
(ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
|
||||
{*/
|
||||
switch (Type)
|
||||
{
|
||||
/* case IMAGE_REL_BASED_SECTION : */
|
||||
/* case IMAGE_REL_BASED_REL32 : */
|
||||
case IMAGE_REL_BASED_ABSOLUTE:
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGH:
|
||||
*ShortPtr = HIWORD(MAKELONG(0, *ShortPtr) + (LONG)Delta);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_LOW:
|
||||
*ShortPtr += LOWORD(Delta);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGHLOW:
|
||||
LongPtr = (PULONG)RVA(Address, Offset);
|
||||
*LongPtr += (ULONG)Delta;
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGHADJ:
|
||||
case IMAGE_REL_BASED_MIPS_JMPADDR:
|
||||
default:
|
||||
DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
|
||||
DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset);
|
||||
return (PIMAGE_BASE_RELOCATION)NULL;
|
||||
}
|
||||
|
||||
TypeOffset++;
|
||||
}
|
||||
|
||||
return (PIMAGE_BASE_RELOCATION)TypeOffset;
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
LdrRelocateImageWithBias(
|
||||
|
@ -163,14 +229,10 @@ LdrRelocateImageWithBias(
|
|||
PIMAGE_NT_HEADERS NtHeaders;
|
||||
PIMAGE_DATA_DIRECTORY RelocationDDir;
|
||||
PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
|
||||
ULONG Count, i;
|
||||
PVOID Address;//, MaxAddress;
|
||||
ULONG Count;
|
||||
ULONG_PTR Address;
|
||||
PUSHORT TypeOffset;
|
||||
ULONG_PTR Delta;
|
||||
SHORT Offset;
|
||||
USHORT Type;
|
||||
PUSHORT ShortPtr;
|
||||
PULONG LongPtr;
|
||||
LONGLONG Delta;
|
||||
|
||||
NtHeaders = RtlImageNtHeader(BaseAddress);
|
||||
|
||||
|
@ -192,64 +254,24 @@ LdrRelocateImageWithBias(
|
|||
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);
|
||||
//MaxAddress = RVA(BaseAddress, DriverSize);
|
||||
|
||||
while (RelocationDir < RelocationEnd &&
|
||||
RelocationDir->SizeOfBlock > 0)
|
||||
{
|
||||
Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
|
||||
Address = RVA(BaseAddress, RelocationDir->VirtualAddress);
|
||||
Address = (ULONG_PTR)RVA(BaseAddress, RelocationDir->VirtualAddress);
|
||||
TypeOffset = (PUSHORT)(RelocationDir + 1);
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
RelocationDir = LdrProcessRelocationBlockLongLong(Address,
|
||||
Count,
|
||||
TypeOffset,
|
||||
Delta);
|
||||
|
||||
if (RelocationDir == NULL)
|
||||
{
|
||||
Offset = *TypeOffset & 0xFFF;
|
||||
Type = *TypeOffset >> 12;
|
||||
ShortPtr = (PUSHORT)(RVA(Address, Offset));
|
||||
|
||||
/* Don't relocate after the end of the loaded driver */
|
||||
/*if ((PVOID)ShortPtr >= MaxAddress)
|
||||
{
|
||||
break;
|
||||
}*/
|
||||
|
||||
/*
|
||||
* Don't relocate within the relocation section itself.
|
||||
* GCC/LD generates sometimes relocation records for the relocation section.
|
||||
* This is a bug in GCC/LD.
|
||||
*/
|
||||
if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
|
||||
(ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case IMAGE_REL_BASED_ABSOLUTE:
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGH:
|
||||
*ShortPtr += HIWORD(Delta);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_LOW:
|
||||
*ShortPtr += LOWORD(Delta);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGHLOW:
|
||||
LongPtr = (PULONG)ShortPtr;
|
||||
*LongPtr += Delta;
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGHADJ:
|
||||
case IMAGE_REL_BASED_MIPS_JMPADDR:
|
||||
default:
|
||||
DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
|
||||
DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset);
|
||||
return Invalid;
|
||||
}
|
||||
}
|
||||
TypeOffset++;
|
||||
DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n");
|
||||
return Invalid;
|
||||
}
|
||||
RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
|
||||
}
|
||||
|
||||
return Success;
|
||||
|
|
Loading…
Reference in a new issue