mirror of
https://github.com/reactos/reactos.git
synced 2025-05-08 19:27:00 +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
|
* FILE: lib/rtl/image.c
|
||||||
* PURPOSE: Image handling functions
|
* PURPOSE: Image handling functions
|
||||||
* Relocate functions were previously located in
|
* Relocate functions were previously located in
|
||||||
* ntoskrnl/ldr/loader.c
|
* ntoskrnl/ldr/loader.c and
|
||||||
* PROGRAMMER: Eric Kohl + original authors from loader.c file
|
* dll/ntdll/ldr/utils.c files
|
||||||
|
* PROGRAMMER: Eric Kohl + original authors from loader.c and utils.c file
|
||||||
|
* Aleksey Bragin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -149,6 +151,70 @@ RtlImageRvaToVa (
|
||||||
(ULONG_PTR)Section->VirtualAddress);
|
(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
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
LdrRelocateImageWithBias(
|
LdrRelocateImageWithBias(
|
||||||
|
@ -163,14 +229,10 @@ LdrRelocateImageWithBias(
|
||||||
PIMAGE_NT_HEADERS NtHeaders;
|
PIMAGE_NT_HEADERS NtHeaders;
|
||||||
PIMAGE_DATA_DIRECTORY RelocationDDir;
|
PIMAGE_DATA_DIRECTORY RelocationDDir;
|
||||||
PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
|
PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
|
||||||
ULONG Count, i;
|
ULONG Count;
|
||||||
PVOID Address;//, MaxAddress;
|
ULONG_PTR Address;
|
||||||
PUSHORT TypeOffset;
|
PUSHORT TypeOffset;
|
||||||
ULONG_PTR Delta;
|
LONGLONG Delta;
|
||||||
SHORT Offset;
|
|
||||||
USHORT Type;
|
|
||||||
PUSHORT ShortPtr;
|
|
||||||
PULONG LongPtr;
|
|
||||||
|
|
||||||
NtHeaders = RtlImageNtHeader(BaseAddress);
|
NtHeaders = RtlImageNtHeader(BaseAddress);
|
||||||
|
|
||||||
|
@ -192,64 +254,24 @@ LdrRelocateImageWithBias(
|
||||||
Delta = (ULONG_PTR)BaseAddress - NtHeaders->OptionalHeader.ImageBase + AdditionalBias;
|
Delta = (ULONG_PTR)BaseAddress - NtHeaders->OptionalHeader.ImageBase + AdditionalBias;
|
||||||
RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + RelocationDDir->VirtualAddress);
|
RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + RelocationDDir->VirtualAddress);
|
||||||
RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
|
RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
|
||||||
//MaxAddress = RVA(BaseAddress, DriverSize);
|
|
||||||
|
|
||||||
while (RelocationDir < RelocationEnd &&
|
while (RelocationDir < RelocationEnd &&
|
||||||
RelocationDir->SizeOfBlock > 0)
|
RelocationDir->SizeOfBlock > 0)
|
||||||
{
|
{
|
||||||
Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
|
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);
|
TypeOffset = (PUSHORT)(RelocationDir + 1);
|
||||||
|
|
||||||
for (i = 0; i < Count; i++)
|
RelocationDir = LdrProcessRelocationBlockLongLong(Address,
|
||||||
|
Count,
|
||||||
|
TypeOffset,
|
||||||
|
Delta);
|
||||||
|
|
||||||
|
if (RelocationDir == NULL)
|
||||||
{
|
{
|
||||||
Offset = *TypeOffset & 0xFFF;
|
DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n");
|
||||||
Type = *TypeOffset >> 12;
|
return Invalid;
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
|
|
Loading…
Reference in a new issue