-/* $Id: utils.c,v 1.92 2004/06/25 19:05:20 ekohl Exp $
+/* $Id: utils.c,v 1.102 2004/12/15 03:00:33 royce Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* FUNCTIONS *****************************************************************/
-#ifdef KDBG
+#if defined(DBG) || defined(KDBG)
VOID
LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule)
NULL);
}
-#endif /* DBG */
+#endif /* DBG || KDBG */
static inline LONG LdrpDecrementLoadCount(PLDR_MODULE Module, BOOL Locked)
{
TlsData->StartAddressOfRawData = (PVOID)TlsDirectory->StartAddressOfRawData;
TlsData->TlsDataSize = TlsDirectory->EndAddressOfRawData - TlsDirectory->StartAddressOfRawData;
TlsData->TlsZeroSize = TlsDirectory->SizeOfZeroFill;
- TlsData->TlsAddressOfCallBacks = *TlsDirectory->AddressOfCallBacks;
+ if (TlsDirectory->AddressOfCallBacks)
+ TlsData->TlsAddressOfCallBacks = *TlsDirectory->AddressOfCallBacks;
+ else
+ TlsData->TlsAddressOfCallBacks = NULL;
TlsData->Module = Module;
#if 0
DbgPrint("TLS directory for %wZ\n", &Module->BaseDllName);
LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
PVOID ImageBase)
{
- USHORT NumberOfEntries;
- PUSHORT pValue16;
- ULONG RelocationRVA;
- ULONG Delta32;
- ULONG Offset;
- PULONG pValue32;
- PRELOCATION_DIRECTORY RelocationDir;
- PRELOCATION_ENTRY RelocationBlock;
- int i;
PIMAGE_DATA_DIRECTORY RelocationDDir;
- ULONG OldProtect;
- PVOID ProtectBase;
- ULONG ProtectSize;
- ULONG OldProtect2;
- PVOID ProtectBase2;
- ULONG ProtectSize2;
+ PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
+ ULONG Count, ProtectSize, OldProtect, OldProtect2;
+ PVOID Page, ProtectPage, ProtectPage2;
+ PUSHORT TypeOffset;
+ ULONG_PTR Delta;
NTSTATUS Status;
- PIMAGE_SECTION_HEADER Sections;
- ULONG MaxExtend;
- ULONG RelocationBlockOffset;
- ULONG RelocationSectionSize;
if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
{
return STATUS_UNSUCCESSFUL;
}
- Sections =
- (PIMAGE_SECTION_HEADER)((PVOID)NTHeaders + sizeof(IMAGE_NT_HEADERS));
- MaxExtend = 0;
- RelocationSectionSize = 0;
- for (i = 0; i < NTHeaders->FileHeader.NumberOfSections; i++)
- {
- if (!(Sections[i].Characteristics & IMAGE_SECTION_NOLOAD))
- {
- ULONG Extend;
- Extend =
- (ULONG)(Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize);
- MaxExtend = max(MaxExtend, Extend);
- }
-
- if (!memcmp(Sections[i].Name,".reloc", 6))
- {
- RelocationSectionSize = Sections[i].Misc.VirtualSize;
- DPRINT("Relocation section size: %lx\n", RelocationSectionSize);
- }
- }
-
RelocationDDir =
&NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
- RelocationRVA = RelocationDDir->VirtualAddress;
- if (RelocationRVA)
+ if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0)
{
- RelocationDir =
- (PRELOCATION_DIRECTORY)((PCHAR)ImageBase + RelocationRVA);
+ return STATUS_SUCCESS;
+ }
- RelocationBlockOffset = 0;
- while (RelocationBlockOffset < RelocationSectionSize)
- {
- if (RelocationDir->VirtualAddress > MaxExtend)
- {
- RelocationRVA += RelocationDir->SizeOfBlock;
- RelocationDir =
- (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
- continue;
- }
+ ProtectSize = PAGE_SIZE;
+ Delta = (ULONG_PTR)ImageBase - NTHeaders->OptionalHeader.ImageBase;
+ RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase +
+ RelocationDDir->VirtualAddress);
+ RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase +
+ RelocationDDir->VirtualAddress + RelocationDDir->Size);
- Delta32 = (ULONG)(ImageBase - NTHeaders->OptionalHeader.ImageBase);
- RelocationBlock =
- (PRELOCATION_ENTRY) (RelocationRVA + ImageBase +
- sizeof (RELOCATION_DIRECTORY));
- NumberOfEntries =
- RelocationDir->SizeOfBlock - sizeof (RELOCATION_DIRECTORY);
- NumberOfEntries = NumberOfEntries / sizeof (RELOCATION_ENTRY);
+ while (RelocationDir < RelocationEnd &&
+ RelocationDir->SizeOfBlock > 0)
+ {
+ Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) /
+ sizeof(USHORT);
+ Page = ImageBase + RelocationDir->VirtualAddress;
+ TypeOffset = (PUSHORT)(RelocationDir + 1);
+
+ /* Unprotect the page(s) we're about to relocate. */
+ ProtectPage = Page;
+ Status = NtProtectVirtualMemory(NtCurrentProcess(),
+ &ProtectPage,
+ &ProtectSize,
+ PAGE_READWRITE,
+ &OldProtect);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to unprotect relocation target.\n");
+ return Status;
+ }
- ProtectBase = ImageBase + RelocationDir->VirtualAddress;
- ProtectSize = PAGE_SIZE;
+ if (RelocationDir->VirtualAddress + PAGE_SIZE <
+ NTHeaders->OptionalHeader.SizeOfImage)
+ {
+ ProtectPage2 = ProtectPage + PAGE_SIZE;
Status = NtProtectVirtualMemory(NtCurrentProcess(),
- &ProtectBase,
+ &ProtectPage2,
&ProtectSize,
PAGE_READWRITE,
- &OldProtect);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to unprotect relocation target.\n");
- return(Status);
- }
-
- if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend)
- {
- ProtectBase2 = ImageBase + RelocationDir->VirtualAddress + PAGE_SIZE;
- ProtectSize2 = PAGE_SIZE;
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- &ProtectBase2,
- &ProtectSize2,
- PAGE_READWRITE,
- &OldProtect2);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to unprotect relocation target (2).\n");
- NtProtectVirtualMemory(NtCurrentProcess(),
- &ProtectBase,
- &ProtectSize,
- OldProtect,
- &OldProtect);
- return(Status);
- }
- }
- for (i = 0; i < NumberOfEntries; i++)
- {
- Offset = (RelocationBlock[i].TypeOffset & 0xfff);
- Offset += (ULONG)(RelocationDir->VirtualAddress + ImageBase);
-
- /*
- * What kind of relocations should we perform
- * for the current entry?
- */
- switch (RelocationBlock[i].TypeOffset >> 12)
- {
- case TYPE_RELOC_ABSOLUTE:
- break;
-
- case TYPE_RELOC_HIGH:
- pValue16 = (PUSHORT)Offset;
- *pValue16 += Delta32 >> 16;
- break;
-
- case TYPE_RELOC_LOW:
- pValue16 = (PUSHORT)Offset;
- *pValue16 += Delta32 & 0xffff;
- break;
-
- case TYPE_RELOC_HIGHLOW:
- pValue32 = (PULONG)Offset;
- *pValue32 += Delta32;
- break;
-
- case TYPE_RELOC_HIGHADJ:
- /* FIXME: do the highadjust fixup */
- DPRINT("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n");
- return STATUS_UNSUCCESSFUL;
-
- default:
- DPRINT("unexpected fixup type\n");
- return STATUS_UNSUCCESSFUL;
- }
- }
-
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- &ProtectBase,
- &ProtectSize,
- OldProtect,
- &OldProtect);
+ &OldProtect2);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to protect relocation target.\n");
- return(Status);
- }
-
- if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend)
- {
- Status = NtProtectVirtualMemory(NtCurrentProcess(),
- &ProtectBase2,
- &ProtectSize2,
- OldProtect2,
- &OldProtect2);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to protect relocation target2.\n");
- return(Status);
- }
+ DPRINT1("Failed to unprotect relocation target (2).\n");
+ NtProtectVirtualMemory(NtCurrentProcess(),
+ &ProtectPage,
+ &ProtectSize,
+ OldProtect,
+ &OldProtect);
+ return Status;
}
+ }
+ else
+ {
+ ProtectPage2 = NULL;
+ }
- RelocationRVA += RelocationDir->SizeOfBlock;
- RelocationDir =
- (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
- RelocationBlockOffset += RelocationDir->SizeOfBlock;
+ RelocationDir = LdrProcessRelocationBlock(Page,
+ Count,
+ TypeOffset,
+ Delta);
+ if (RelocationDir == NULL)
+ return STATUS_UNSUCCESSFUL;
+
+ /* Restore old page protection. */
+ NtProtectVirtualMemory(NtCurrentProcess(),
+ &ProtectPage,
+ &ProtectSize,
+ OldProtect,
+ &OldProtect);
+
+ if (ProtectPage2 != NULL)
+ {
+ NtProtectVirtualMemory(NtCurrentProcess(),
+ &ProtectPage2,
+ &ProtectSize,
+ OldProtect2,
+ &OldProtect2);
}
}
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent;
PIMAGE_TLS_DIRECTORY TlsDirectory;
- ULONG TlsSize;
+ ULONG TlsSize = 0;
NTSTATUS Status;
PLDR_MODULE ImportedModule;
PCHAR ImportedName;
DPRINT1("LdrFixupImports failed for %wZ, status=%x\n", &(*Module)->BaseDllName, Status);
return Status;
}
-#ifdef KDBG
+#if defined(DBG) || defined(KDBG)
LdrpLoadUserModuleSymbols(*Module);
-#endif
+#endif /* DBG || KDBG */
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
&(*Module)->InInitializationOrderModuleList);
((UnloadAll && Module->LoadCount >= 0) || Module->LoadCount == 0))
{
/* remove the module entry from the list */
- RemoveEntryList (&Module->InLoadOrderModuleList)
+ RemoveEntryList (&Module->InLoadOrderModuleList);
RemoveEntryList (&Module->InInitializationOrderModuleList);
NtUnmapViewOfSection (NtCurrentProcess (), Module->BaseAddress);
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
PLDR_MODULE Module;
- PMODULE_ENTRY ModulePtr = NULL;
+ PDEBUG_MODULE_INFORMATION ModulePtr = NULL;
NTSTATUS Status = STATUS_SUCCESS;
ULONG UsedSize = sizeof(ULONG);
ANSI_STRING AnsiString;
}
else if (ModuleInformation != NULL)
{
- ModulePtr->Unknown0 = 0; // FIXME: ??
- ModulePtr->Unknown1 = 0; // FIXME: ??
- ModulePtr->BaseAddress = Module->BaseAddress;
- ModulePtr->SizeOfImage = Module->SizeOfImage;
+ ModulePtr->Reserved[0] = ModulePtr->Reserved[1] = 0; // FIXME: ??
+ ModulePtr->Base = Module->BaseAddress;
+ ModulePtr->Size = Module->SizeOfImage;
ModulePtr->Flags = Module->Flags;
- ModulePtr->Unknown2 = 0; // FIXME: load order index ??
- ModulePtr->Unknown3 = 0; // FIXME: ??
+ ModulePtr->Index = 0; // FIXME: index ??
+ ModulePtr->Unknown = 0; // FIXME: ??
ModulePtr->LoadCount = Module->LoadCount;
AnsiString.Length = 0;
AnsiString.MaximumLength = 256;
- AnsiString.Buffer = ModulePtr->ModuleName;
+ AnsiString.Buffer = ModulePtr->ImageName;
RtlUnicodeStringToAnsiString(&AnsiString,
&Module->FullDllName,
FALSE);
- p = strrchr(ModulePtr->ModuleName, '\\');
+ p = strrchr(ModulePtr->ImageName, '\\');
if (p != NULL)
- ModulePtr->PathLength = p - ModulePtr->ModuleName + 1;
+ ModulePtr->ModuleNameOffset = p - ModulePtr->ImageName + 1;
else
- ModulePtr->PathLength = 0;
+ ModulePtr->ModuleNameOffset = 0;
ModulePtr++;
ModuleInformation->ModuleCount++;
}
- UsedSize += sizeof(MODULE_ENTRY);
+ UsedSize += sizeof(DEBUG_MODULE_INFORMATION);
Entry = Entry->Flink;
}
return Status;
}
+
+PIMAGE_BASE_RELOCATION STDCALL
+LdrProcessRelocationBlock(IN PVOID Address,
+ IN USHORT Count,
+ IN PUSHORT TypeOffset,
+ IN ULONG_PTR Delta)
+{
+ SHORT Offset;
+ USHORT Type;
+ USHORT i;
+ PUSHORT ShortPtr;
+ PULONG LongPtr;
+
+ for (i = 0; i < Count; i++)
+ {
+ Offset = *TypeOffset & 0xFFF;
+ Type = *TypeOffset >> 12;
+
+ switch (Type)
+ {
+ case IMAGE_REL_BASED_ABSOLUTE:
+ break;
+
+ case IMAGE_REL_BASED_HIGH:
+ ShortPtr = (PUSHORT)(Address + Offset);
+ *ShortPtr += HIWORD(Delta);
+ break;
+
+ case IMAGE_REL_BASED_LOW:
+ ShortPtr = (PUSHORT)(Address + Offset);
+ *ShortPtr += LOWORD(Delta);
+ break;
+
+ case IMAGE_REL_BASED_HIGHLOW:
+ LongPtr = (PULONG)(Address + Offset);
+ *LongPtr += Delta;
+ break;
+
+ case IMAGE_REL_BASED_HIGHADJ:
+ case IMAGE_REL_BASED_MIPS_JMPADDR:
+ default:
+ DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
+ return NULL;
+ }
+
+ TypeOffset++;
+ }
+
+ return (PIMAGE_BASE_RELOCATION)TypeOffset;
+}
+
/* EOF */