Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

247 lines
5.9 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
coffldr.c
Abstract:
This module implements the code to load COFF format image into memory
and relocate it if necessary.
Author:
David N. Cutler (davec) 10-May-1991
Environment:
Kernel mode only.
Revision History:
--*/
#include "bldr.h"
#include "firmware.h"
#include "string.h"
#include "ntimage.h"
ARC_STATUS
FwLoadImage(
IN PCHAR LoadFile,
OUT PVOID *TransferRoutine
)
/*++
Routine Description:
This routine attempts to load the specified file from the specified
device.
Arguments:
LoadFile - Supplies a pointer to string descriptor for the name of
the file to load.
TransferRoutine - Supplies the address of where to store the start
address for the image.
Return Value:
ESUCCESS is returned if the specified image file is loaded
successfully. Otherwise, an unsuccessful status is returned
that describes the reason for failure.
--*/
{
ULONG BasePage;
ULONG Count;
PIMAGE_FILE_HEADER CoffHeader;
PIMAGE_OPTIONAL_HEADER OptionalHeader;
PIMAGE_SECTION_HEADER SectionHeader;
ULONG FileId;
ULONG Index;
UCHAR LocalBuffer[SECTOR_SIZE+32];
PUCHAR LocalPointer;
PFW_MEMORY_DESCRIPTOR MemoryDescriptor;
ULONG PageCount;
ARC_STATUS Status;
LARGE_INTEGER SeekValue;
//
// Align the buffer on a Dcache fill size.
//
LocalPointer = (PVOID)((ULONG)((PCHAR)LocalBuffer +
PCR->FirstLevelDcacheFillSize - 1) & ~(PCR->FirstLevelDcacheFillSize - 1));
//
// Set the image start address to null.
//
*TransferRoutine = NULL;
//
// Attempt to open the load file.
//
// ****** temp ******
//
// This will eventually use FwOpen rather than BlOpen. For now both
// BlOpen and FwOpen share a single copy of the file table in the
// firmware loader. Eventually there will be a separate file table
// for the firmware loader and the boot loader.
//
// ****** temp ******
//
Status = BlOpen(2, LoadFile, ArcOpenReadOnly, &FileId);
if (Status != ESUCCESS) {
return Status;
}
//
// Read the image header from the file.
//
Status = FwRead(FileId, LocalPointer, SECTOR_SIZE, &Count);
if (Status != ESUCCESS) {
FwClose(FileId);
return Status;
}
//
// Get a pointer to the file header and begin processing it.
//
CoffHeader = (PIMAGE_FILE_HEADER)LocalPointer;
OptionalHeader =
(PIMAGE_OPTIONAL_HEADER)((ULONG)CoffHeader + sizeof(IMAGE_FILE_HEADER));
SectionHeader =
(PIMAGE_SECTION_HEADER)((ULONG)CoffHeader + sizeof(IMAGE_FILE_HEADER) +
CoffHeader->SizeOfOptionalHeader);
//
// If the image file is not the specified type, then return bad image
// type status.
//
if (((CoffHeader->Machine != IMAGE_TYPE_R3000) &&
(CoffHeader->Machine != IMAGE_TYPE_R4000)) ||
((CoffHeader->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0)) {
FwClose(FileId);
return EBADF;
}
//
// ******* add code ******
//
// Code needs to be added here to find the appropriate piece of memory
// to put the loaded image in.
//
// ******* add code ******
//
//
// Return the transfer routine to the caller.
//
*TransferRoutine = (PVOID)OptionalHeader->AddressOfEntryPoint;
//
// Scan through the sections and either read them into memory or clear
// the memory as appropriate.
//
for (Index = 0; Index < CoffHeader->NumberOfSections; Index += 1) {
//
// If the section is a code or initialized data section, then read
// the code or data into memory.
//
if (((SectionHeader->Characteristics & IMAGE_SCN_CNT_CODE) != 0) ||
((SectionHeader->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) != 0)) {
SeekValue.LowPart = SectionHeader->PointerToRawData;
SeekValue.HighPart = 0;
Status = FwSeek(FileId,
&SeekValue,
SeekAbsolute);
if (Status != ESUCCESS) {
break;
}
Status = FwRead(FileId,
(PVOID)SectionHeader->VirtualAddress,
SectionHeader->SizeOfRawData,
&Count);
if (Status != ESUCCESS) {
break;
}
//
// If the section is uninitialized data, then zero the specifed memory.
//
} else if ((SectionHeader->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0) {
RtlZeroMemory((PVOID)SectionHeader->VirtualAddress,
SectionHeader->SizeOfRawData);
//
// Unknown section type.
//
} else {
Status = EBADF;
break;
}
SectionHeader += 1;
}
//
// Close file, allocate a memory descriptor if necessary, and return
// completion status.
//
FwClose(FileId);
if (Status == ESUCCESS) {
//
// ****** temp ******
//
// default the address of the memory descriptor for now.
//
// ****** temp ******
//
MemoryDescriptor = &FwMemoryTable[2];
//
// Compute the starting page and the number of pages that are consumed
// by the loaded image, and then allocate a memory descriptor for the
// allocated region.
//
BasePage = (OptionalHeader->BaseOfCode & 0xfffffff) >> PAGE_SHIFT;
PageCount = (((OptionalHeader->BaseOfData & 0xfffffff) +
OptionalHeader->SizeOfInitializedData +
OptionalHeader->SizeOfUninitializedData + PAGE_SIZE - 1) >>
PAGE_SHIFT) - BasePage;
FwGenerateDescriptor(MemoryDescriptor,
MemoryLoadedProgram,
BasePage,
PageCount);
}
return Status;
}