[FREELDR] Diverse enhancements.
[reactos.git] / boot / freeldr / freeldr / arch / powerpc / mboot.c
index 22b3c3a..aa57f06 100644 (file)
@@ -25,7 +25,6 @@
 #include "ppcmmu/mmu.h"
 #include "compat.h"
 
-#define NDEBUG
 #include <debug.h>
 
 /* We'll check this to see if we're in OFW land */
@@ -56,7 +55,9 @@ PVOID KernelMemory = 0;
 #define KernelMemorySize            (8 * 1024 * 1024)
 #define XROUNDUP(x,n)               ((((ULONG)x) + ((n) - 1)) & (~((n) - 1)))
 
-char reactos_module_strings[64][256];  // Array to hold module names
+#define TAG_MBOOT 'oobM'
+
+char reactos_module_strings[64][256];    // Array to hold module names
 
 /* Load Address of Next Module */
 ULONG_PTR NextModuleBase = 0;
@@ -113,7 +114,7 @@ int MmuPageMiss(int trapCode, ppc_trap_frame_t *trap)
     int i;
     printf("TRAP %x\n", trapCode);
     for( i = 0; i < 40; i++ )
-       printf("r[%d] %x\n", i, trap->gpr[i]);
+    printf("r[%d] %x\n", i, trap->gpr[i]);
     printf("HALT!\n");
     while(1);
 }
@@ -357,7 +358,7 @@ FrLdrGetKernelBase(VOID)
  * FrLdrGetPaeMode
  * INTERNAL
  *
- *     Determines whether PAE mode shoudl be enabled or not.
+ *     Determines whether PAE mode should be enabled or not.
  *
  * Params:
  *     None.
@@ -388,7 +389,7 @@ FrLdrGetPaeMode(VOID)
  *     None.
  *
  * Remarks:
- *     We are setting PDEs, but using the equvivalent (for our purpose) PTE structure.
+ *     We are setting PDEs, but using the equivalent (for our purpose) PTE structure.
  *     As such, please note that PageFrameNumber == PageEntryNumber.
  *
  *--*/
@@ -430,6 +431,7 @@ FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG Kern
     PCHAR sptr;
     Elf32_Ehdr ehdr;
     Elf32_Shdr *shdr;
+    LARGE_INTEGER Position;
     LPSTR TempName;
 
     TempName = strrchr(ImageName, '\\');
@@ -438,22 +440,22 @@ FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG Kern
 
     if(ModuleData)
     {
-       return TRUE;
+    return TRUE;
     }
 
     if(!KernelAddr)
-       KernelAddr = (ULONG)NextModuleBase - (ULONG)KernelMemory + KernelBase;
+    KernelAddr = (ULONG)NextModuleBase - (ULONG)KernelMemory + KernelBase;
     if(!MemLoadAddr)
-       MemLoadAddr = (PCHAR)NextModuleBase;
+    MemLoadAddr = (PCHAR)NextModuleBase;
 
     ModuleData = &reactos_modules[LoaderBlock.ModsCount];
     //printf("Loading file (elf at %x)\n", KernelAddr);
 
     /* Load the first 1024 bytes of the kernel image so we can read the PE header */
-    if (!FsReadFile(KernelImage, sizeof(ehdr), NULL, &ehdr)) {
+    if (ArcRead(KernelImage, &ehdr, sizeof(ehdr), NULL) != ESUCCESS) {
 
         /* Fail if we couldn't read */
-       printf("Couldn't read the elf header\n");
+    printf("Couldn't read the elf header\n");
         return FALSE;
     }
 
@@ -462,41 +464,43 @@ FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG Kern
     //phnum = ehdr.e_phnum;
     shsize = ehdr.e_shentsize;
     shnum = ehdr.e_shnum;
-    sptr = (PCHAR)MmHeapAlloc(shnum * shsize);
+    sptr = (PCHAR)FrLdrTempAlloc(shnum * shsize, TAG_MBOOT);
 
     /* Read section headers */
-    FsSetFilePointer(KernelImage,  ehdr.e_shoff);
-    FsReadFile(KernelImage, shsize * shnum, NULL, sptr);
+    Position.QuadPart = ehdr.e_shoff;
+    ArcSeek(KernelImage, &Position, SeekAbsolute);
+    ArcRead(KernelImage, sptr, shsize * shnum, NULL);
 
     /* Now we'll get the PE Header */
     for( i = 0; i < shnum; i++ )
     {
-       shdr = ELF_SECTION(i);
-       shdr->sh_addr = 0;
-
-       /* Find the PE Header */
-       if (shdr->sh_type == TYPE_PEHEADER)
-       {
-           FsSetFilePointer(KernelImage, shdr->sh_offset);
-           FsReadFile(KernelImage, shdr->sh_size, NULL, MemLoadAddr);
-           ImageHeader = (PIMAGE_DOS_HEADER)MemLoadAddr;
-           NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)MemLoadAddr + SWAPD(ImageHeader->e_lfanew));
+    shdr = ELF_SECTION(i);
+    shdr->sh_addr = 0;
+
+    /* Find the PE Header */
+    if (shdr->sh_type == TYPE_PEHEADER)
+    {
+        Position.QuadPart = shdr->sh_offset;
+        ArcSeek(KernelImage, &Position, SeekAbsolute);
+        ArcRead(KernelImage, MemLoadAddr, shdr->sh_size, NULL);
+        ImageHeader = (PIMAGE_DOS_HEADER)MemLoadAddr;
+        NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)MemLoadAddr + SWAPD(ImageHeader->e_lfanew));
 #if 0
-           printf("NtHeader at %x\n", SWAPD(ImageHeader->e_lfanew));
-           printf("SectionAlignment %x\n",
-                  SWAPD(NtHeader->OptionalHeader.SectionAlignment));
-           SectionAddr = ROUND_UP
-               (shdr->sh_size, SWAPD(NtHeader->OptionalHeader.SectionAlignment));
-           printf("Header ends at %x\n", SectionAddr);
+        printf("NtHeader at %x\n", SWAPD(ImageHeader->e_lfanew));
+        printf("SectionAlignment %x\n",
+           SWAPD(NtHeader->OptionalHeader.SectionAlignment));
+        SectionAddr = ROUND_UP
+        (shdr->sh_size, SWAPD(NtHeader->OptionalHeader.SectionAlignment));
+        printf("Header ends at %x\n", SectionAddr);
 #endif
-           break;
-       }
+        break;
+    }
     }
 
     if(i == shnum)
     {
-       printf("No peheader section encountered :-(\n");
-       return 0;
+    printf("No peheader section encountered :-(\n");
+    return 0;
     }
 #if 0
     else
@@ -515,27 +519,28 @@ FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG Kern
     /* Walk each section */
     for (i=0; i < SectionCount; i++, Section++)
     {
-       shdr = ELF_SECTION((SWAPD(Section->PointerToRawData)+1));
-
-       shdr->sh_addr = SectionAddr = SWAPD(Section->VirtualAddress);
-       shdr->sh_addr += KernelAddr;
-
-       Section->PointerToRawData = SWAPD((Section->VirtualAddress - KernelAddr));
-
-       if (shdr->sh_type != SHT_NOBITS)
-       {
-           /* Content area */
-           printf("Loading section %d at %x (real: %x:%d)\n", i, KernelAddr + SectionAddr, MemLoadAddr+SectionAddr, shdr->sh_size);
-           FsSetFilePointer(KernelImage, shdr->sh_offset);
-           FsReadFile(KernelImage, shdr->sh_size, NULL, MemLoadAddr + SectionAddr);
-       }
-       else
-       {
-           /* Zero it out */
-           printf("BSS section %d at %x\n", i, KernelAddr + SectionAddr);
-           memset(MemLoadAddr + SectionAddr, 0,
-                  ROUND_UP(shdr->sh_size,
-                           SWAPD(NtHeader->OptionalHeader.SectionAlignment)));
+    shdr = ELF_SECTION((SWAPD(Section->PointerToRawData)+1));
+
+    shdr->sh_addr = SectionAddr = SWAPD(Section->VirtualAddress);
+    shdr->sh_addr += KernelAddr;
+
+    Section->PointerToRawData = SWAPD((Section->VirtualAddress - KernelAddr));
+
+    if (shdr->sh_type != SHT_NOBITS)
+    {
+        /* Content area */
+        printf("Loading section %d at %x (real: %x:%d)\n", i, KernelAddr + SectionAddr, MemLoadAddr+SectionAddr, shdr->sh_size);
+        Position.QuadPart = shdr->sh_offset;
+        ArcSeek(KernelImage, &Position, SeekAbsolute);
+        ArcRead(KernelImage, MemLoadAddr + SectionAddr, shdr->sh_size, NULL);
+    }
+    else
+    {
+        /* Zero it out */
+        printf("BSS section %d at %x\n", i, KernelAddr + SectionAddr);
+        memset(MemLoadAddr + SectionAddr, 0,
+           ROUND_UP(shdr->sh_size,
+                SWAPD(NtHeader->OptionalHeader.SectionAlignment)));
         }
     }
 
@@ -544,112 +549,114 @@ FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG Kern
 
     /* Handle relocation sections */
     for (i = 0; i < shnum; i++) {
-       Elf32_Rela reloc = { };
-       ULONG *Target32;
-       USHORT *Target16;
-       int numreloc, relstart, targetSection;
-       Elf32_Sym symbol;
-       PCHAR RelocSection, SymbolSection;
-
-       shdr = ELF_SECTION(i);
-       /* Only relocs here */
-       if((shdr->sh_type != SHT_REL) &&
-          (shdr->sh_type != SHT_RELA)) continue;
-
-       relstart = shdr->sh_offset;
-       relsize = shdr->sh_type == SHT_RELA ? 12 : 8;
-       numreloc = shdr->sh_size / relsize;
-       targetSection = shdr->sh_info;
-
-       if (!ELF_SECTION(targetSection)->sh_addr) continue;
-
-       RelocSection = MmHeapAlloc(shdr->sh_size);
-       FsSetFilePointer(KernelImage, relstart);
-       FsReadFile(KernelImage, shdr->sh_size, NULL, RelocSection);
-
-       /* Get the symbol section */
-       shdr = ELF_SECTION(shdr->sh_link);
-
-       SymbolSection = MmHeapAlloc(shdr->sh_size);
-       FsSetFilePointer(KernelImage, shdr->sh_offset);
-       FsReadFile(KernelImage, shdr->sh_size, NULL, SymbolSection);
-
-       for(j = 0; j < numreloc; j++)
-       {
-           ULONG S,A,P;
+    Elf32_Rela reloc = { };
+    ULONG *Target32;
+    USHORT *Target16;
+    int numreloc, relstart, targetSection;
+    Elf32_Sym symbol;
+    PCHAR RelocSection, SymbolSection;
+
+    shdr = ELF_SECTION(i);
+    /* Only relocs here */
+    if((shdr->sh_type != SHT_REL) &&
+       (shdr->sh_type != SHT_RELA)) continue;
+
+    relstart = shdr->sh_offset;
+    relsize = shdr->sh_type == SHT_RELA ? 12 : 8;
+    numreloc = shdr->sh_size / relsize;
+    targetSection = shdr->sh_info;
+
+    if (!ELF_SECTION(targetSection)->sh_addr) continue;
+
+    RelocSection = FrLdrTempAlloc(shdr->sh_size, TAG_MBOOT);
+    Position.QuadPart = relstart;
+    ArcSeek(KernelImage, &Position, SeekAbsolute);
+    ArcRead(KernelImage, RelocSection, shdr->sh_size, NULL);
+
+    /* Get the symbol section */
+    shdr = ELF_SECTION(shdr->sh_link);
+
+    SymbolSection = FrLdrTempAlloc(shdr->sh_size, TAG_MBOOT);
+    Position.QuadPart = shdr->sh_offset;
+    ArcSeek(KernelImage, &Position, SeekAbsolute);
+    ArcRead(KernelImage, SymbolSection, shdr->sh_size, NULL);
+
+    for(j = 0; j < numreloc; j++)
+    {
+        ULONG S,A,P;
 
-           /* Get the reloc */
-           memcpy(&reloc, RelocSection + (j * relsize), sizeof(reloc));
+        /* Get the reloc */
+        memcpy(&reloc, RelocSection + (j * relsize), sizeof(reloc));
 
-           /* Get the symbol */
-           memcpy(&symbol, SymbolSection + (ELF32_R_SYM(reloc.r_info) * sizeof(symbol)), sizeof(symbol));
+        /* Get the symbol */
+        memcpy(&symbol, SymbolSection + (ELF32_R_SYM(reloc.r_info) * sizeof(symbol)), sizeof(symbol));
 
-           /* Compute addends */
-           S = symbol.st_value + ELF_SECTION(symbol.st_shndx)->sh_addr;
-           A = reloc.r_addend;
-           P = reloc.r_offset + ELF_SECTION(targetSection)->sh_addr;
+        /* Compute addends */
+        S = symbol.st_value + ELF_SECTION(symbol.st_shndx)->sh_addr;
+        A = reloc.r_addend;
+        P = reloc.r_offset + ELF_SECTION(targetSection)->sh_addr;
 
 #if 0
-           printf("Symbol[%d] %d -> %d(%x:%x) -> %x(+%x)@%x\n",
-                  ELF32_R_TYPE(reloc.r_info),
-                  ELF32_R_SYM(reloc.r_info),
-                  symbol.st_shndx,
-                  ELF_SECTION(symbol.st_shndx)->sh_addr,
-                  symbol.st_value,
-                  S,
-                  A,
-                  P);
+        printf("Symbol[%d] %d -> %d(%x:%x) -> %x(+%x)@%x\n",
+           ELF32_R_TYPE(reloc.r_info),
+           ELF32_R_SYM(reloc.r_info),
+           symbol.st_shndx,
+           ELF_SECTION(symbol.st_shndx)->sh_addr,
+           symbol.st_value,
+           S,
+           A,
+           P);
 #endif
 
-           Target32 = (ULONG*)(((PCHAR)MemLoadAddr) + (P - KernelAddr));
-           Target16 = (USHORT *)Target32;
-
-           switch (ELF32_R_TYPE(reloc.r_info))
-           {
-           case R_PPC_NONE:
-               break;
-           case R_PPC_ADDR32:
-               *Target32 = S + A;
-               break;
-           case R_PPC_REL32:
-               *Target32 = S + A - P;
-               break;
-           case R_PPC_UADDR32: /* Special: Treat as RVA */
-               *Target32 = S + A - KernelAddr;
-               break;
-           case R_PPC_ADDR24:
-               *Target32 = (ADDR24_MASK & (S+A)) | (*Target32 & ~ADDR24_MASK);
-               break;
-           case R_PPC_REL24:
-               *Target32 = (ADDR24_MASK & (S+A-P)) | (*Target32 & ~ADDR24_MASK);
-               break;
-           case R_PPC_ADDR16_LO:
-               *Target16 = S + A;
-               break;
-           case R_PPC_ADDR16_HA:
-               *Target16 = (S + A + 0x8000) >> 16;
-               break;
-           default:
-               break;
-           }
+        Target32 = (ULONG*)(((PCHAR)MemLoadAddr) + (P - KernelAddr));
+        Target16 = (USHORT *)Target32;
+
+        switch (ELF32_R_TYPE(reloc.r_info))
+        {
+        case R_PPC_NONE:
+        break;
+        case R_PPC_ADDR32:
+        *Target32 = S + A;
+        break;
+        case R_PPC_REL32:
+        *Target32 = S + A - P;
+        break;
+        case R_PPC_UADDR32: /* Special: Treat as RVA */
+        *Target32 = S + A - KernelAddr;
+        break;
+        case R_PPC_ADDR24:
+        *Target32 = (ADDR24_MASK & (S+A)) | (*Target32 & ~ADDR24_MASK);
+        break;
+        case R_PPC_REL24:
+        *Target32 = (ADDR24_MASK & (S+A-P)) | (*Target32 & ~ADDR24_MASK);
+        break;
+        case R_PPC_ADDR16_LO:
+        *Target16 = S + A;
+        break;
+        case R_PPC_ADDR16_HA:
+        *Target16 = (S + A + 0x8000) >> 16;
+        break;
+        default:
+        break;
+        }
 
 #if 0
-           printf("reloc[%d:%x]: (type %x sym %d val %d) off %x add %x (old %x new %x)\n",
-                  j,
-                  ((ULONG)Target32) - ((ULONG)MemLoadAddr),
-                  ELF32_R_TYPE(reloc.r_info),
-                  ELF32_R_SYM(reloc.r_info),
-                  symbol.st_value,
-                  reloc.r_offset, reloc.r_addend,
-                  x, *Target32);
+        printf("reloc[%d:%x]: (type %x sym %d val %d) off %x add %x (old %x new %x)\n",
+           j,
+           ((ULONG)Target32) - ((ULONG)MemLoadAddr),
+           ELF32_R_TYPE(reloc.r_info),
+           ELF32_R_SYM(reloc.r_info),
+           symbol.st_value,
+           reloc.r_offset, reloc.r_addend,
+           x, *Target32);
 #endif
-       }
+    }
 
-       MmHeapFree(SymbolSection);
-       MmHeapFree(RelocSection);
+    FrLdrTempFree(SymbolSection, TAG_MBOOT);
+    FrLdrTempFree(RelocSection, TAG_MBOOT);
     }
 
-    MmHeapFree(sptr);
+    FrLdrTempFree(sptr, TAG_MBOOT);
 
     ModuleData->ModStart = (ULONG)MemLoadAddr;
     /* Increase the next Load Base */
@@ -658,10 +665,10 @@ FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG Kern
     ModuleData->String = (ULONG)MmAllocateMemory(strlen(ImageName)+1);
     strcpy((PCHAR)ModuleData->String, ImageName);
     printf("Module %s (%x-%x) next at %x\n",
-          ModuleData->String,
-          ModuleData->ModStart,
-          ModuleData->ModEnd,
-          NextModuleBase);
+       ModuleData->String,
+       ModuleData->ModStart,
+       ModuleData->ModEnd,
+       NextModuleBase);
     LoaderBlock.ModsCount++;
 
     /* Return Success */
@@ -672,7 +679,7 @@ FrLdrMapModule(FILE *KernelImage, PCHAR ImageName, PCHAR MemLoadAddr, ULONG Kern
  * FrLdrMapKernel
  * INTERNAL
  *
- *     Maps the Kernel into memory, does PE Section Mapping, initalizes the
+ *     Maps the Kernel into memory, does PE Section Mapping, initializes the
  *     uninitialized data sections, and relocates the image.
  *
  * Params:
@@ -704,6 +711,8 @@ FrLdrLoadModule(FILE *ModuleImage,
                 LPCSTR ModuleName,
                 PULONG ModuleSize)
 {
+    ARC_STATUS Status;
+    FILEINFORMATION FileInfo;
     ULONG LocalModuleSize;
     ULONG_PTR ThisModuleBase = NextModuleBase;
     PLOADER_MODULE ModuleData;
@@ -725,9 +734,12 @@ FrLdrLoadModule(FILE *ModuleImage,
     } while(TempName);
     NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
 
-
     /* Get Module Size */
-    LocalModuleSize = FsGetFileSize(ModuleImage);
+    Status = ArcGetFileInformation(ModuleImage, &FileInfo);
+    if (Status != ESUCCESS || FileInfo.EndingAddress.HighPart != 0)
+        LocalModuleSize = 0;
+    else
+        LocalModuleSize = FileInfo.EndingAddress.LowPart;
 
     /* Fill out Module Data Structure */
     ModuleData->ModStart = NextModuleBase;
@@ -738,7 +750,7 @@ FrLdrLoadModule(FILE *ModuleImage,
     ModuleData->String = (ULONG_PTR)NameBuffer;
 
     /* Load the file image */
-    FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
+    ArcRead(ModuleImage, (PVOID)NextModuleBase, LocalModuleSize, NULL);
 
     /* Move to next memory block and increase Module Count */
     NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
@@ -750,10 +762,10 @@ FrLdrLoadModule(FILE *ModuleImage,
     }
 
     printf("Module %s (%x-%x) next at %x\n",
-          ModuleData->String,
-          ModuleData->ModStart,
-          ModuleData->ModEnd,
-          NextModuleBase);
+       ModuleData->String,
+       ModuleData->ModStart,
+       ModuleData->ModEnd,
+       NextModuleBase);
 
     return ThisModuleBase;
 }