WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

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

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