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

4 years ago
  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. coffldr.c
  5. Abstract:
  6. This module implements the code to load COFF format image into memory
  7. and relocate it if necessary.
  8. Author:
  9. David N. Cutler (davec) 10-May-1991
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. --*/
  14. #include "bldr.h"
  15. #include "firmware.h"
  16. #include "string.h"
  17. #include "ntimage.h"
  18. ARC_STATUS
  19. FwLoadImage(
  20. IN PCHAR LoadFile,
  21. OUT PVOID *TransferRoutine
  22. )
  23. /*++
  24. Routine Description:
  25. This routine attempts to load the specified file from the specified
  26. device.
  27. Arguments:
  28. LoadFile - Supplies a pointer to string descriptor for the name of
  29. the file to load.
  30. TransferRoutine - Supplies the address of where to store the start
  31. address for the image.
  32. Return Value:
  33. ESUCCESS is returned if the specified image file is loaded
  34. successfully. Otherwise, an unsuccessful status is returned
  35. that describes the reason for failure.
  36. --*/
  37. {
  38. ULONG BasePage;
  39. ULONG Count;
  40. PIMAGE_FILE_HEADER CoffHeader;
  41. PIMAGE_OPTIONAL_HEADER OptionalHeader;
  42. PIMAGE_SECTION_HEADER SectionHeader;
  43. ULONG FileId;
  44. ULONG Index;
  45. UCHAR LocalBuffer[SECTOR_SIZE+32];
  46. PUCHAR LocalPointer;
  47. PFW_MEMORY_DESCRIPTOR MemoryDescriptor;
  48. ULONG PageCount;
  49. ARC_STATUS Status;
  50. LARGE_INTEGER SeekValue;
  51. //
  52. // Align the buffer on a Dcache fill size.
  53. //
  54. LocalPointer = (PVOID)((ULONG)((PCHAR)LocalBuffer +
  55. PCR->FirstLevelDcacheFillSize - 1) & ~(PCR->FirstLevelDcacheFillSize - 1));
  56. //
  57. // Set the image start address to null.
  58. //
  59. *TransferRoutine = NULL;
  60. //
  61. // Attempt to open the load file.
  62. //
  63. // ****** temp ******
  64. //
  65. // This will eventually use FwOpen rather than BlOpen. For now both
  66. // BlOpen and FwOpen share a single copy of the file table in the
  67. // firmware loader. Eventually there will be a separate file table
  68. // for the firmware loader and the boot loader.
  69. //
  70. // ****** temp ******
  71. //
  72. Status = BlOpen(2, LoadFile, ArcOpenReadOnly, &FileId);
  73. if (Status != ESUCCESS) {
  74. return Status;
  75. }
  76. //
  77. // Read the image header from the file.
  78. //
  79. Status = FwRead(FileId, LocalPointer, SECTOR_SIZE, &Count);
  80. if (Status != ESUCCESS) {
  81. FwClose(FileId);
  82. return Status;
  83. }
  84. //
  85. // Get a pointer to the file header and begin processing it.
  86. //
  87. CoffHeader = (PIMAGE_FILE_HEADER)LocalPointer;
  88. OptionalHeader =
  89. (PIMAGE_OPTIONAL_HEADER)((ULONG)CoffHeader + sizeof(IMAGE_FILE_HEADER));
  90. SectionHeader =
  91. (PIMAGE_SECTION_HEADER)((ULONG)CoffHeader + sizeof(IMAGE_FILE_HEADER) +
  92. CoffHeader->SizeOfOptionalHeader);
  93. //
  94. // If the image file is not the specified type, then return bad image
  95. // type status.
  96. //
  97. if (((CoffHeader->Machine != IMAGE_TYPE_R3000) &&
  98. (CoffHeader->Machine != IMAGE_TYPE_R4000)) ||
  99. ((CoffHeader->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0)) {
  100. FwClose(FileId);
  101. return EBADF;
  102. }
  103. //
  104. // ******* add code ******
  105. //
  106. // Code needs to be added here to find the appropriate piece of memory
  107. // to put the loaded image in.
  108. //
  109. // ******* add code ******
  110. //
  111. //
  112. // Return the transfer routine to the caller.
  113. //
  114. *TransferRoutine = (PVOID)OptionalHeader->AddressOfEntryPoint;
  115. //
  116. // Scan through the sections and either read them into memory or clear
  117. // the memory as appropriate.
  118. //
  119. for (Index = 0; Index < CoffHeader->NumberOfSections; Index += 1) {
  120. //
  121. // If the section is a code or initialized data section, then read
  122. // the code or data into memory.
  123. //
  124. if (((SectionHeader->Characteristics & IMAGE_SCN_CNT_CODE) != 0) ||
  125. ((SectionHeader->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) != 0)) {
  126. SeekValue.LowPart = SectionHeader->PointerToRawData;
  127. SeekValue.HighPart = 0;
  128. Status = FwSeek(FileId,
  129. &SeekValue,
  130. SeekAbsolute);
  131. if (Status != ESUCCESS) {
  132. break;
  133. }
  134. Status = FwRead(FileId,
  135. (PVOID)SectionHeader->VirtualAddress,
  136. SectionHeader->SizeOfRawData,
  137. &Count);
  138. if (Status != ESUCCESS) {
  139. break;
  140. }
  141. //
  142. // If the section is uninitialized data, then zero the specifed memory.
  143. //
  144. } else if ((SectionHeader->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0) {
  145. RtlZeroMemory((PVOID)SectionHeader->VirtualAddress,
  146. SectionHeader->SizeOfRawData);
  147. //
  148. // Unknown section type.
  149. //
  150. } else {
  151. Status = EBADF;
  152. break;
  153. }
  154. SectionHeader += 1;
  155. }
  156. //
  157. // Close file, allocate a memory descriptor if necessary, and return
  158. // completion status.
  159. //
  160. FwClose(FileId);
  161. if (Status == ESUCCESS) {
  162. //
  163. // ****** temp ******
  164. //
  165. // default the address of the memory descriptor for now.
  166. //
  167. // ****** temp ******
  168. //
  169. MemoryDescriptor = &FwMemoryTable[2];
  170. //
  171. // Compute the starting page and the number of pages that are consumed
  172. // by the loaded image, and then allocate a memory descriptor for the
  173. // allocated region.
  174. //
  175. BasePage = (OptionalHeader->BaseOfCode & 0xfffffff) >> PAGE_SHIFT;
  176. PageCount = (((OptionalHeader->BaseOfData & 0xfffffff) +
  177. OptionalHeader->SizeOfInitializedData +
  178. OptionalHeader->SizeOfUninitializedData + PAGE_SIZE - 1) >>
  179. PAGE_SHIFT) - BasePage;
  180. FwGenerateDescriptor(MemoryDescriptor,
  181. MemoryLoadedProgram,
  182. BasePage,
  183. PageCount);
  184. }
  185. return Status;
  186. }