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.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

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)( ...@@ -691,11 +691,12 @@ class MuCtx(val ctxID: MuInternalID, _mutator: Mutator)(
} }
} }
// do nothing // 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( "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)) objRef, objRef, offset, offset))
val ptrTy = InternalTypePool.ptrOf(objTy) val ptrTy = InternalTypePool.ptrOf(objTy)
val box = new BoxPointer(objRef + offset) val box = new BoxPointer(addr)
addHandle(MuUPtrValue(ptrTy, box)) addHandle(MuUPtrValue(ptrTy, box))
} }
......
...@@ -131,6 +131,10 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol], ...@@ -131,6 +131,10 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val symsMap = syms.map(_.toAddrSymPair).toMap val symsMap = syms.map(_.toAddrSymPair).toMap
val symsRevMap = syms.map(_.toAddrSymPair.swap).toMap val symsRevMap = syms.map(_.toAddrSymPair.swap).toMap
val relocsMap = relocs.map(_.toAddrSymPair).toMap val relocsMap = relocs.map(_.toAddrSymPair).toMap
{
logger.debug("Relocation map: " + relocsMap.toString)
}
val idNameMapPath = tempDir.resolve(IDNAMEMAP_FILE) val idNameMapPath = tempDir.resolve(IDNAMEMAP_FILE)
val uirBundlePath = tempDir.resolve(UIRBUNDLE_FILE) val uirBundlePath = tempDir.resolve(UIRBUNDLE_FILE)
...@@ -220,13 +224,14 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol], ...@@ -220,13 +224,14 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val begin = alloc.addr val begin = alloc.addr
MemoryDataScanner.scanAllocUnit(begin, new MemoryFieldHandler { MemoryDataScanner.scanAllocUnit(begin, new MemoryFieldHandler {
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = if (toAddr != 0L) { def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {
relocsMap.get(toAddr) match { relocsMap.get(iRef) match {
case Some(symbol) => { case Some(symbol) => {
// by symbol // by symbol
val fieldOffset = iRef - objRef val fieldOffset = iRef - objRef
val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_SYM, 0, 0, symbol) val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_SYM, 0, 0, symbol)
group.relocRecs += reloc group.relocRecs += reloc
logger.debug("External uptr relocation: %d 0x%x -> %s".format(iRef, iRef, symbol))
} }
case None => { case None => {
// maybe a "reasonable" pointer to a mu global cell. Relocate it too. // maybe a "reasonable" pointer to a mu global cell. Relocate it too.
...@@ -239,12 +244,21 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol], ...@@ -239,12 +244,21 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val targetOffset = toAddr - targetAddr val targetOffset = toAddr - targetAddr
val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_GLOBAL, targetNum, targetOffset, NO_SYM) val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_GLOBAL, targetNum, targetOffset, NO_SYM)
group.relocRecs += reloc 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)) 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) { def visitRefField(objRef: Word, iRef: Word, toObj: Word, isWeak: Boolean): Unit = if (toObj != 0L) {
val fieldOffset = iRef - objRef val fieldOffset = iRef - objRef
......
...@@ -165,15 +165,16 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor ...@@ -165,15 +165,16 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor
} }
def maybeGetGlobalCellRec(iref: Word): Option[GlobalCellRec] = { def maybeGetGlobalCellRec(iref: Word): Option[GlobalCellRec] = {
require(microVM.memoryManager.globalMemory.isInSpace(iref), if (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,
for ((begin, gcr) <- globalCellMap.to(iref).lastOption) yield { "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(
assert(begin <= iref && iref < gcr.end, iref, iref, begin, begin, gcr.end, 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 ...@@ -383,7 +384,12 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor
toFunc.foreach(tls+=) 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 = override def visitStackRefField(objRef: Word, iRef: Word, toStack: Option[InterpreterStack]): Unit =
toStack.foreach(o => throw noReach("stack", objRef, iRef, o)) toStack.foreach(o => throw noReach("stack", objRef, iRef, o))
override def visitThreadRefField(objRef: Word, iRef: Word, toThread: Option[InterpreterThread]): Unit = override def visitThreadRefField(objRef: Word, iRef: Word, toThread: Option[InterpreterThread]): Unit =
......
...@@ -47,6 +47,11 @@ object MemoryDataScanner extends StrictLogging { ...@@ -47,6 +47,11 @@ object MemoryDataScanner extends StrictLogging {
logger.debug(logField("UPtr", toAddr)) logger.debug(logField("UPtr", toAddr))
handler.visitUPtrField(objRef, iRef, 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 => { case t: TypeRef => {
val toObj = memorySupport.loadLong(iRef) val toObj = memorySupport.loadLong(iRef)
logger.debug(logField("Ref", toObj)) logger.debug(logField("Ref", toObj))
......
...@@ -23,6 +23,7 @@ import uvm.refimpl.mem.MemorySupport ...@@ -23,6 +23,7 @@ import uvm.refimpl.mem.MemorySupport
*/ */
trait MemoryFieldHandler { trait MemoryFieldHandler {
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit 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 visitRefField(objRef: Word, iRef: Word, toObj: Word, isWeak: Boolean): Unit
def visitIRefField(objRef: Word, iRef: Word, toObj: Word, toOffset: Word): Unit def visitIRefField(objRef: Word, iRef: Word, toObj: Word, toOffset: Word): Unit
...@@ -81,6 +82,7 @@ trait RefFieldHandler extends MemoryFieldHandler { ...@@ -81,6 +82,7 @@ trait RefFieldHandler extends MemoryFieldHandler {
} }
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {} 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 visitFuncRefField(objRef: Word, iRef: Word, toFunc: Option[Function]): Unit = {}
def visitThreadRefField(objRef: Word, iRef: Word, toThread: Option[InterpreterThread]): Unit = {} def visitThreadRefField(objRef: Word, iRef: Word, toThread: Option[InterpreterThread]): Unit = {}
def visitFCRefField(objRef: Word, iRef: Word, toFCRef: Option[FrameCursor]): Unit = {} def visitFCRefField(objRef: Word, iRef: Word, toFCRef: Option[FrameCursor]): Unit = {}
......
...@@ -8,12 +8,28 @@ import uvm.ir.textinput.TestingBundlesValidators.MagicalOur ...@@ -8,12 +8,28 @@ import uvm.ir.textinput.TestingBundlesValidators.MagicalOur
import uvm.refimpl.mem.HeaderUtils import uvm.refimpl.mem.HeaderUtils
import uvm.types.Type import uvm.types.Type
import uvm.refimpl.Word 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 { class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers {
override def makeMicroVM = new MicroVM(new VMConf()) override def makeMicroVM = new MicroVM(new VMConf())
preloadBundles("tests/uvm-refimpl-test/transitive-closure.uir") preloadBundles("tests/uvm-refimpl-test/transitive-closure.uir")
preloadHails("tests/uvm-refimpl-test/transitive-closure.hail") 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) val our = new MagicalOur(microVM.globalBundle)
...@@ -33,11 +49,35 @@ class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers { ...@@ -33,11 +49,35 @@ class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers {
val filename = "target/boot-image-read-write-test.muref" val filename = "target/boot-image-read-write-test.muref"
val everything = microVM.globalBundle.allTopLevels() 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() val anotherMicroVM = MicroVM()
anotherMicroVM.loadBootImage(filename) anotherMicroVM.loadBootImage(filename)
microVM.globalBundle.allNs("@gd").id shouldEqual anotherMicroVM.globalBundle.allNs("@gd").id 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 @@ ...@@ -11,3 +11,6 @@
.init @gr1 = 42 .init @gr1 = 42
.init @gr2 = &@gr1 .init @gr2 = &@gr1
.init @gs3[0] = 43
.init @gs3[1] = 44
...@@ -49,3 +49,10 @@ ...@@ -49,3 +49,10 @@
.global @gr1 <@i64> .global @gr1 <@i64>
.global @gr2 <@irefi64> .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