From 8c0ef382f8ef0581ef9df09a551408b26edaf02d Mon Sep 17 00:00:00 2001
From: Joshua Warner <joshua.warner@readytalk.com>
Date: Thu, 3 May 2012 12:04:34 -0600
Subject: [PATCH] write out bootimage directly from the bootimage-generator,
 eliminating one of the steps in a custom bootimage build

---
 makefile          | 13 ++-----------
 readme.txt        | 14 +-------------
 src/bootimage.cpp | 25 +++++++++++++++++--------
 3 files changed, 20 insertions(+), 32 deletions(-)

diff --git a/makefile b/makefile
index ff01cd7ba2..67b4e7e738 100755
--- a/makefile
+++ b/makefile
@@ -576,10 +576,7 @@ bootimage-generator-objects = \
 	$(call cpp-objects,$(bootimage-generator-sources),$(src),$(build))
 bootimage-generator = $(build)/bootimage-generator
 
-bootimage-bin = $(build)/bootimage.bin
 bootimage-object = $(build)/bootimage-bin.o
-
-codeimage-bin = $(build)/codeimage.bin
 codeimage-object = $(build)/codeimage-bin.o
 
 ifeq ($(bootimage),true)
@@ -910,14 +907,8 @@ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
 	$(ar) cru $(@) $(^)
 	$(ranlib) $(@)
 
-$(bootimage-bin): $(bootimage-generator)
-	$(<) $(classpath-build) $(@) $(codeimage-object)
-
-$(bootimage-object): $(bootimage-bin) $(converter)
-	@echo "creating $(@)"
-	$(converter) $(<) $(@) _binary_bootimage_bin_start \
-		_binary_bootimage_bin_end $(platform) $(arch) $(pointer-size) \
-		writable
+$(bootimage-object) $(codeimage-object): $(bootimage-generator)
+	$(<) $(classpath-build) $(bootimage-object) $(codeimage-object)
 
 executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
 	$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
diff --git a/readme.txt b/readme.txt
index a81b6b2693..d214dda8b7 100644
--- a/readme.txt
+++ b/readme.txt
@@ -557,19 +557,7 @@ Step 6: Build the boot and code images.
  $ ../build/linux-i386-bootimage/bootimage-generator stage2 \
      bootimage.bin codeimage.bin
 
-Step 7: Make an object file out of the boot and code images.
-
- $ ../build/linux-i386-bootimage/binaryToObject \
-     bootimage.bin bootimage-bin.o \
-     _binary_bootimage_bin_start _binary_bootimage_bin_end \
-     linux i386 8 writable
-
- $ ../build/linux-i386-bootimage/binaryToObject \
-     codeimage.bin codeimage-bin.o \
-     _binary_codeimage_bin_start _binary_codeimage_bin_end \
-     linux i386 8 executable
-
-Step 8: Write a driver which starts the VM and runs the desired main
+Step 7: Write a driver which starts the VM and runs the desired main
 method.  Note the bootimageBin function, which will be called by the
 VM to get a handle to the embedded boot image.  We tell the VM about
 this function via the "avian.bootimage" property.
diff --git a/src/bootimage.cpp b/src/bootimage.cpp
index 67e89db8fe..21a1da5f22 100644
--- a/src/bootimage.cpp
+++ b/src/bootimage.cpp
@@ -1604,6 +1604,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
           image->bootClassCount, image->stringCount, image->callCount,
           image->heapSize, image->codeSize);
 
+  Buffer bootimageData;
+
   if (true) {
     { BootImage targetImage;
 
@@ -1620,13 +1622,13 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
 #include "bootimage-fields.cpp"
 #undef THUNK_FIELD
 
-      bootimageOutput->writeChunk(&targetImage, sizeof(BootImage));
+      bootimageData.write(&targetImage, sizeof(BootImage));
     }
 
-    bootimageOutput->writeChunk(bootClassTable, image->bootClassCount * sizeof(unsigned));
-    bootimageOutput->writeChunk(appClassTable, image->appClassCount * sizeof(unsigned));
-    bootimageOutput->writeChunk(stringTable, image->stringCount * sizeof(unsigned));
-    bootimageOutput->writeChunk(callTable, image->callCount * sizeof(unsigned) * 2);
+    bootimageData.write(bootClassTable, image->bootClassCount * sizeof(unsigned));
+    bootimageData.write(appClassTable, image->appClassCount * sizeof(unsigned));
+    bootimageData.write(stringTable, image->stringCount * sizeof(unsigned));
+    bootimageData.write(callTable, image->callCount * sizeof(unsigned) * 2);
 
     unsigned offset = sizeof(BootImage)
       + (image->bootClassCount * sizeof(unsigned))
@@ -1636,13 +1638,13 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
 
     while (offset % TargetBytesPerWord) {
       uint8_t c = 0;
-      bootimageOutput->write(c);
+      bootimageData.write(&c, 1);
       ++ offset;
     }
 
-    bootimageOutput->writeChunk(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord));
+    bootimageData.write(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord));
 
-    bootimageOutput->writeChunk(heap, pad(image->heapSize, TargetBytesPerWord));
+    bootimageData.write(heap, pad(image->heapSize, TargetBytesPerWord));
 
     // fwrite(code, pad(image->codeSize, TargetBytesPerWord), 1, codeOutput);
     
@@ -1653,6 +1655,13 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
     //   return false;
     // }
 
+    SymbolInfo bootimageSymbols[] = {
+      SymbolInfo(0, "_binary_bootimage_bin_start"),
+      SymbolInfo(bootimageData.length, "_binary_bootimage_bin_end")
+    };
+
+    platform->writeObject(bootimageOutput, Slice<SymbolInfo>(bootimageSymbols, 2), Slice<const uint8_t>(bootimageData.data, bootimageData.length), Platform::Writable, TargetBytesPerWord);
+
     compilationHandler.symbols.add(SymbolInfo(0, strdup("_binary_codeimage_bin_start")));
     compilationHandler.symbols.add(SymbolInfo(image->codeSize, strdup("_binary_codeimage_bin_end")));