Commit 1d4f248e authored by Kunshan Wang's avatar Kunshan Wang

WIP: boot image loading...

parent 5da7141d
......@@ -62,6 +62,11 @@ object BootImageWriter {
val UIRBUNDLE_FILE = "bundle.uir"
val IDNAMEMAP_FILE = "idnamemap"
val METAINFO_FILE = "metainfo"
val KEY_INITFUNC = "initfunc"
val KEY_THREADLOCAL = "threadlocal"
val KEY_EXTRALIBS = "extralibs"
val AS_REF = "R"
val AS_IREF = "I"
......@@ -138,10 +143,11 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val idNameMapPath = tempDir.resolve(IDNAMEMAP_FILE)
val uirBundlePath = tempDir.resolve(UIRBUNDLE_FILE)
val metaInfoPath = tempDir.resolve(METAINFO_FILE)
val zipPath = Paths.get(outputFile)
val allZipContents = Seq(globalGroup.dataFile, heapGroup.dataFile, globalGroup.allocFile, heapGroup.allocFile,
globalGroup.relocFile, heapGroup.relocFile, idNameMapPath, uirBundlePath)
globalGroup.relocFile, heapGroup.relocFile, idNameMapPath, uirBundlePath, metaInfoPath)
private val globalMemory: Space = microVM.memoryManager.globalMemory
private val smallObjectSpace: Space = microVM.memoryManager.heap.space
......@@ -180,6 +186,8 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
writeIDNameMap()
writeUIRBundle()
writeMetaInfo()
makeZipPackage()
}
......@@ -329,6 +337,22 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
bundleSerializer.writeUIR(writer)
}
}
private def writeMetaInfo(): Unit = {
tryWithResource(Files.newBufferedWriter(metaInfoPath, StandardCharsets.UTF_8)) { writer =>
val sb = new StringBuilder()
tcb.primordial.maybeFunc.foreach { func =>
sb.append("%s=%d\n".format(KEY_INITFUNC, func.id))
tcb.primordial.maybeThreadLocal.foreach { addr =>
val heapObjNum = heapGroup.allocRecs.find(_.addr == addr).getOrElse {
throw new BootImageBuilderException("BUG: Thread local object is not in the boot image")
}.num
sb.append("%s=%d\n".format(KEY_THREADLOCAL, heapObjNum))
}
}
writer.write(sb.toString)
}
}
private def makeZipPackage(): Unit = {
tryWithResource(new ZipOutputStream(Files.newOutputStream(zipPath))) { zos =>
......
......@@ -24,6 +24,7 @@ import uvm.types.TypeHybrid
import uvm.utils.IOHelpers.forEachLine
import uvm.utils.MappedIDFactory
import uvm.utils.WithUtils.tryWithResource
import scala.collection.mutable.ArrayBuffer
object BootImageLoader {
val MUTATOR_NAME = "bootimgldr"
......@@ -65,19 +66,39 @@ class BootImageLoader(file: String)(implicit microVM: MicroVM) extends AutoClose
}
def load(): Unit = {
loadExtraLibs()
val metaInfo = loadMetaInfo()
loadExtraLibs(metaInfo)
loadUIRBundle()
initializeMemory()
maybeCreatePrimordialThread(metaInfo)
}
private def loadExtraLibs(): Unit = {
Option(zip.getEntry(EXTRALIBS_FILE)) foreach { entry =>
val line = tryWithResource(zipFileTextBuf(EXTRALIBS_FILE)) { br =>
br.readLine()
private def loadMetaInfo(): Map[String, String] = {
val lines = tryWithResource(zipFileTextBuf(METAINFO_FILE)) { br =>
val ab = ArrayBuffer[String]()
var endReached = false
while(endReached) {
val maybeLine = Option(br.readLine())
maybeLine match {
case Some(line) => ab += line
case None => endReached = true
}
}
ab
}
val pairs = lines.map { line =>
val Array(k,v) = line.split("=", -1)
(k,v)
}
pairs.toMap
}
private def loadExtraLibs(metaInfo: Map[String, String]): Unit = {
for (line <- metaInfo.get("extralibs")) {
val libs = line.split(":")
for (lib <- libs) {
......@@ -277,6 +298,23 @@ class BootImageLoader(file: String)(implicit microVM: MicroVM) extends AutoClose
private def getSymbolAddr(targetSymbol: String): Word = {
microVM.nativeLibraryHolder.getSymbolAddress(targetSymbol)
}
private def maybeCreatePrimordialThread(metaInfo: Map[String, String]): Unit = {
metaInfo.get(KEY_INITFUNC).map(_.toInt).foreach { initFuncID =>
val func = microVM.globalBundle.funcNs(initFuncID)
val threadLocalAddr = metaInfo.get(KEY_THREADLOCAL).map(_.toLong).map { addr =>
addr
}.getOrElse(0L)
tryWithResource(microVM.newContext("boot-image-loader")) { ctx =>
val func = ctx.handleFromFunc(initFuncID)
val stack = ctx.newStack(func)
val thread = ctx.newThread(stack, threadLocal, htr)
}
}
}
}
class AlignedInputStream(is: InputStream) extends Closeable {
......
......@@ -52,7 +52,15 @@ class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers {
tryWithResource(microVM.newContext()) { ctx =>
val h_gs3 = ctx.handleFromGlobal("@gs3")
val h_gs3_3 = ctx.getFieldIRef(h_gs3, 3)
ctx.makeBootImage(everything.map(_.id), None, None, None, Seq(), Seq(), Seq(h_gs3_3), Seq("getchar"), filename)
val h_tl = ctx.newFixed("@i64")
val h_tl_i = ctx.getIRef(h_tl)
val h_fifty_two = ctx.handleFromInt(52, 64)
ctx.store(MemoryOrder.NOT_ATOMIC, h_tl_i, h_fifty_two)
val h_main = ctx.handleFromFunc("@main")
ctx.makeBootImage(everything.map(_.id), Some(h_main), None, Some(h_tl), Seq(), Seq(), Seq(h_gs3_3), Seq("getchar"), filename)
}
val anotherMicroVM = MicroVM()
......
......@@ -56,3 +56,13 @@
.typedef @pi32 = uptr<@i32>
.global @gs3 <@s3>
.global @gs <@s>
.typedef @pi8 = uptr<@i8>
.typedef @ppi8 = uptr<@pi8>
.funcsig @main.sig = (@i32 @ppi8) -> (@i32)
.funcdef @main VERSION %v1 <@main.sig> {
%entry(<@i32> %argc <@ppi8> %argv):
COMMINST @uvm.thread_exit
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment