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 5da7141d authored by Kunshan Wang's avatar Kunshan Wang
Browse files

Tested the relocator.

parent 1e77a314
......@@ -691,11 +691,12 @@ class MuCtx(val ctxID: MuInternalID, _mutator: Mutator)(
}
}
// do nothing
assert(microVM.memoryManager.globalMemory.isInSpace(objRef) || pinSet.contains(objRef),
val addr = objRef + offset
assert(microVM.memoryManager.globalMemory.isInSpace(addr) || pinSet.contains(objRef),
"Attempt to get address of objref %d 0x%x, offset %d, 0x%x, which is neither a global cell nor pinned by the current thread.".format(
objRef, objRef, offset, offset))
val ptrTy = InternalTypePool.ptrOf(objTy)
val box = new BoxPointer(objRef + offset)
val box = new BoxPointer(addr)
addHandle(MuUPtrValue(ptrTy, box))
}
......
......@@ -131,6 +131,10 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val symsMap = syms.map(_.toAddrSymPair).toMap
val symsRevMap = syms.map(_.toAddrSymPair.swap).toMap
val relocsMap = relocs.map(_.toAddrSymPair).toMap
{
logger.debug("Relocation map: " + relocsMap.toString)
}
val idNameMapPath = tempDir.resolve(IDNAMEMAP_FILE)
val uirBundlePath = tempDir.resolve(UIRBUNDLE_FILE)
......@@ -220,13 +224,14 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val begin = alloc.addr
MemoryDataScanner.scanAllocUnit(begin, new MemoryFieldHandler {
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = if (toAddr != 0L) {
relocsMap.get(toAddr) match {
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {
relocsMap.get(iRef) match {
case Some(symbol) => {
// by symbol
val fieldOffset = iRef - objRef
val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_SYM, 0, 0, symbol)
group.relocRecs += reloc
logger.debug("External uptr relocation: %d 0x%x -> %s".format(iRef, iRef, symbol))
}
case None => {
// maybe a "reasonable" pointer to a mu global cell. Relocate it too.
......@@ -239,12 +244,21 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val targetOffset = toAddr - targetAddr
val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_GLOBAL, targetNum, targetOffset, NO_SYM)
group.relocRecs += reloc
case None => logger.info("UPtr field not pointing to Mu global cell: %d 0x%x -> %d 0x%x".format(
logger.info("Relocation entry for uptr field automatically generated: %d 0x%x -> %d 0x%x".format(
iRef, iRef, toAddr, toAddr))
}
case None => }
}
}
}
def visitUFPField(objRef: Word, iRef: Word, toAddr: Word): Unit = {
relocsMap.get(iRef).foreach { symbol =>
// by symbol
val fieldOffset = iRef - objRef
val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_SYM, 0, 0, symbol)
group.relocRecs += reloc
logger.debug("External ufuncptr relocation: %d 0x%x -> %s".format(iRef, iRef, symbol))
}
}
def visitRefField(objRef: Word, iRef: Word, toObj: Word, isWeak: Boolean): Unit = if (toObj != 0L) {
val fieldOffset = iRef - objRef
......
......@@ -165,15 +165,16 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor
}
def maybeGetGlobalCellRec(iref: Word): Option[GlobalCellRec] = {
require(microVM.memoryManager.globalMemory.isInSpace(iref),
"Address %d 0x%x is not in the global space".format(iref, iref))
for ((begin, gcr) <- globalCellMap.to(iref).lastOption) yield {
assert(begin <= iref && iref < gcr.end,
"Address %d 0x%x is in the global space, but the previous global cell's address range is %d 0x%x - %d 0x%x".format(
iref, iref, begin, begin, gcr.end, gcr.end))
if (microVM.memoryManager.globalMemory.isInSpace(iref)) {
for ((begin, gcr) <- globalCellMap.to(iref).lastOption) yield {
assert(begin <= iref && iref < gcr.end,
"Address %d 0x%x is in the global space, but the previous global cell's address range is %d 0x%x - %d 0x%x".format(
iref, iref, begin, begin, gcr.end, gcr.end))
gcr
gcr
}
} else {
None
}
}
......@@ -383,7 +384,12 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor
toFunc.foreach(tls+=)
}
override def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {}
override def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {
maybeGetGlobalCellRec(toAddr).foreach{ gcr =>
tls += gcr.g
}
}
override def visitUFPField(objRef: Word, iRef: Word, toAddr: Word): Unit = {}
override def visitStackRefField(objRef: Word, iRef: Word, toStack: Option[InterpreterStack]): Unit =
toStack.foreach(o => throw noReach("stack", objRef, iRef, o))
override def visitThreadRefField(objRef: Word, iRef: Word, toThread: Option[InterpreterThread]): Unit =
......
......@@ -47,6 +47,11 @@ object MemoryDataScanner extends StrictLogging {
logger.debug(logField("UPtr", toAddr))
handler.visitUPtrField(objRef, iRef, toAddr)
}
case t: TypeUFuncPtr => {
val toAddr = memorySupport.loadLong(iRef, false)
logger.debug(logField("UFuncPtr", toAddr))
handler.visitUFPField(objRef, iRef, toAddr)
}
case t: TypeRef => {
val toObj = memorySupport.loadLong(iRef)
logger.debug(logField("Ref", toObj))
......
......@@ -23,6 +23,7 @@ import uvm.refimpl.mem.MemorySupport
*/
trait MemoryFieldHandler {
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit
def visitUFPField(objRef: Word, iRef: Word, toAddr: Word): Unit
def visitRefField(objRef: Word, iRef: Word, toObj: Word, isWeak: Boolean): Unit
def visitIRefField(objRef: Word, iRef: Word, toObj: Word, toOffset: Word): Unit
......@@ -81,6 +82,7 @@ trait RefFieldHandler extends MemoryFieldHandler {
}
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {}
def visitUFPField(objRef: Word, iRef: Word, toAddr: Word): Unit = {}
def visitFuncRefField(objRef: Word, iRef: Word, toFunc: Option[Function]): Unit = {}
def visitThreadRefField(objRef: Word, iRef: Word, toThread: Option[InterpreterThread]): Unit = {}
def visitFCRefField(objRef: Word, iRef: Word, toFCRef: Option[FrameCursor]): Unit = {}
......
......@@ -8,12 +8,28 @@ import uvm.ir.textinput.TestingBundlesValidators.MagicalOur
import uvm.refimpl.mem.HeaderUtils
import uvm.types.Type
import uvm.refimpl.Word
import uvm.utils.WithUtils._
import uvm.ssavariables.MemoryOrder
import uvm.refimpl.MuUPtrValue
import uvm.refimpl.MuUFPValue
class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers {
override def makeMicroVM = new MicroVM(new VMConf())
preloadBundles("tests/uvm-refimpl-test/transitive-closure.uir")
preloadHails("tests/uvm-refimpl-test/transitive-closure.hail")
{
tryWithResource(microVM.newContext()) { ctx =>
val h_gs = ctx.handleFromGlobal("@gs")
val h_gs_2 = ctx.getFieldIRef(h_gs, 2)
val h_gs_2_ptr = ctx.getAddr(h_gs_2)
val h_gs3 = ctx.handleFromGlobal("@gs3")
val h_gs3_2 = ctx.getFieldIRef(h_gs3, 2)
ctx.store(MemoryOrder.NOT_ATOMIC, h_gs3_2, h_gs_2_ptr)
}
}
val our = new MagicalOur(microVM.globalBundle)
......@@ -33,11 +49,35 @@ class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers {
val filename = "target/boot-image-read-write-test.muref"
val everything = microVM.globalBundle.allTopLevels()
microVM.makeBootImage(everything.map(_.id), filename)
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 anotherMicroVM = MicroVM()
anotherMicroVM.loadBootImage(filename)
microVM.globalBundle.allNs("@gd").id shouldEqual anotherMicroVM.globalBundle.allNs("@gd").id
tryWithResource(anotherMicroVM.newContext()) { ctx =>
val h_gs = ctx.handleFromGlobal("@gs")
val h_gs_2 = ctx.getFieldIRef(h_gs, 2)
val h_gs_2_ptr = ctx.getAddr(h_gs_2)
val h_gs3 = ctx.handleFromGlobal("@gs3")
val h_gs3_2 = ctx.getFieldIRef(h_gs3, 2)
val h_gs3_2_val = ctx.load(MemoryOrder.NOT_ATOMIC, h_gs3_2).asInstanceOf[MuUPtrValue]
val h_gs3_3 = ctx.getFieldIRef(h_gs3, 3)
val h_gs3_3_val = ctx.load(MemoryOrder.NOT_ATOMIC, h_gs3_3).asInstanceOf[MuUFPValue]
val gs_2_ptr = ctx.handleToPtr(h_gs_2_ptr)
val gs3_2_val = ctx.handleToPtr(h_gs3_2_val)
val gs3_3_val = ctx.handleToFP(h_gs3_3_val)
gs3_2_val shouldEqual gs_2_ptr
val getchar_val = anotherMicroVM.nativeLibraryHolder.getSymbolAddress("getchar")
gs3_3_val shouldEqual getchar_val
}
}
}
\ No newline at end of file
......@@ -11,3 +11,6 @@
.init @gr1 = 42
.init @gr2 = &@gr1
.init @gs3[0] = 43
.init @gs3[1] = 44
......@@ -49,3 +49,10 @@
.global @gr1 <@i64>
.global @gr2 <@irefi64>
.funcsig @getchar.sig = (@i32) -> ()
.typedef @getchar.fp = ufuncptr<@getchar.sig>
.typedef @s3 = struct<@i32 @pi32 @pi32 @getchar.fp>
.typedef @pi32 = uptr<@i32>
.global @gs3 <@s3>
.global @gs <@s>
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