]> git.saurik.com Git - apple/bootx.git/blobdiff - bootx.tproj/sl.subproj/macho.c
BootX-59.tar.gz
[apple/bootx.git] / bootx.tproj / sl.subproj / macho.c
index 29604048dbce8470552feeefc03fbf112ed9763c..c352e67513c88b64d8d407f660ccbdd659f5b5ed 100644 (file)
@@ -25,7 +25,7 @@
 /*
  *  macho.c - Functions for decoding a Mach-o Kernel.
  *
- *  Copyright (c) 1998-2000 Apple Computer, Inc.
+ *  Copyright (c) 1998-2003 Apple Computer, Inc.
  *
  *  DRI: Josh de Cesare
  */
@@ -40,33 +40,56 @@ static long DecodeSegment(long cmdBase);
 static long DecodeUnixThread(long cmdBase);
 static long DecodeSymbolTable(long cmdBase);
 
-static long gPPCOffset;
+static unsigned long gPPCAddress;
 
 // Public Functions
 
-long DecodeMachO(void)
+long ThinFatBinaryMachO(void **binary, unsigned long *length)
+{
+  unsigned long nfat, swapped, size;
+  struct fat_header *fhp = (struct fat_header *)*binary;
+  struct fat_arch   *fap =
+    (struct fat_arch *)((unsigned long)*binary + sizeof(struct fat_header));
+  
+  if (fhp->magic == FAT_MAGIC) {
+    nfat = fhp->nfat_arch;
+    swapped = 0;
+  } else if (fhp->magic == FAT_CIGAM) {
+    nfat = NXSwapInt(fhp->nfat_arch);
+    swapped = 1;
+  } else {
+    return -1;
+  }
+  
+  for (; nfat > 0; nfat--, fap++) {
+    if (swapped) {
+      fap->cputype = NXSwapInt(fap->cputype);
+      fap->offset = NXSwapInt(fap->offset);
+      fap->size = NXSwapInt(fap->size);
+    }
+    
+    if (fap->cputype == CPU_TYPE_POWERPC) {
+      *binary = (void *) ((unsigned long)*binary + fap->offset);
+      size = fap->size;
+      break;
+    }
+  }
+  
+  if (length != 0) *length = size;
+  
+  return 0;
+}
+
+long DecodeMachO(void *binary)
 {
-  struct fat_header  *fH;
-  struct fat_arch    *fA;
   struct mach_header *mH;
   long   ncmds, cmdBase, cmd, cmdsize, headerBase, headerAddr, headerSize;
   long   cnt, ret;
   
-  // Test for a fat header.
-  fH = (struct fat_header *)kLoadAddr;
-  if (fH->magic == FAT_MAGIC) {
-    fA = (struct fat_arch *)(kLoadAddr + sizeof(struct fat_header));
-    // see if the there is one for PPC.
-    for (cnt = 0; cnt < fH->nfat_arch; cnt++) {
-      if (fA[cnt].cputype == CPU_TYPE_POWERPC) {
-       gPPCOffset = fA[cnt].offset;
-      }
-    }
-  }
+  gPPCAddress = (unsigned long)binary;
   
-  // offset will be the start of the 
-  headerBase = kLoadAddr + gPPCOffset;
-  cmdBase = headerBase+ sizeof(struct mach_header);
+  headerBase = gPPCAddress;
+  cmdBase = headerBase + sizeof(struct mach_header);
   
   mH = (struct mach_header *)(headerBase);
   if (mH->magic != MH_MAGIC) return -1;
@@ -136,7 +159,7 @@ static long DecodeSegment(long cmdBase)
   vmaddr = (char *)segCmd->vmaddr;
   vmsize = segCmd->vmsize;
   
-  fileaddr = (char *)(kLoadAddr + gPPCOffset + segCmd->fileoff);
+  fileaddr = (char *)(gPPCAddress + segCmd->fileoff);
   filesize = segCmd->filesize;
   
 #if 0
@@ -148,6 +171,9 @@ static long DecodeSegment(long cmdBase)
   // Add the Segment to the memory-map.
   sprintf(rangeName, "Kernel-%s", segCmd->segname);
   AllocateMemoryRange(rangeName, (long)vmaddr, vmsize);
+
+  if (vmsize && (strcmp(segCmd->segname, "__PRELINK") == 0))
+    gHaveKernelCache = 1;
   
   // Handle special segments first.
   
@@ -231,7 +257,7 @@ static long DecodeSymbolTable(long cmdBase)
   symTableSave->stroff = tmpAddr + symsSize;
   symTableSave->strsize = symTab->strsize;
   
-  bcopy((char *)(kLoadAddr + gPPCOffset + symTab->symoff),
+  bcopy((char *)(gPPCAddress + symTab->symoff),
        (char *)tmpAddr, totalSize);
   
   return 0;