GitLab will be upgraded to the 12.10.14-ce.0 on 28 Sept 2020 at 2.00pm (AEDT) to 2.30pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

Commit 3a3670f0 authored by Kunshan Wang's avatar Kunshan Wang

Do NULL check during mem addressing

parent 8f32698a
...@@ -5,11 +5,11 @@ import uvm.UvmException ...@@ -5,11 +5,11 @@ import uvm.UvmException
/** Parent of all exceptions in the implementation part. This does not include the data structure and parser outside uvm.refimpl. */ /** Parent of all exceptions in the implementation part. This does not include the data structure and parser outside uvm.refimpl. */
class UvmRefImplException(message: String = null, cause: Throwable = null) extends UvmException(message, cause) class UvmRefImplException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
/** Thrown when the micro VM cannot allocate memory. */ /** Thrown if the internal state of the micro VM is inconsistent. This usually mean there is a bug in the micro VM. */
class UvmOutOfMemoryException(message: String = null, cause: Throwable = null) extends UvmRefImplException(message, cause) class UvmInternalException(message: String = null, cause: Throwable = null) extends UvmRefImplException(message, cause)
/** Thrown when an action not required by the specification and not implemented by this refimpl is performed. */ /** Thrown when an action not required by the specification and not implemented by this refimpl is performed. */
class UnimplementedOprationException(message: String = null, cause: Throwable = null) extends UvmRefImplException(message, cause) class UvmUnimplementedOperationException(message: String = null, cause: Throwable = null) extends UvmRefImplException(message, cause)
/** /**
* Thrown when a dynamic error (errors that cannot be found at compile time) happens. This refimpl may sometimes throw * Thrown when a dynamic error (errors that cannot be found at compile time) happens. This refimpl may sometimes throw
...@@ -18,8 +18,14 @@ class UnimplementedOprationException(message: String = null, cause: Throwable = ...@@ -18,8 +18,14 @@ class UnimplementedOprationException(message: String = null, cause: Throwable =
*/ */
class UvmRuntimeException(message: String = null, cause: Throwable = null) extends UvmRefImplException(message, cause) class UvmRuntimeException(message: String = null, cause: Throwable = null) extends UvmRefImplException(message, cause)
/** Thrown when the micro VM cannot allocate memory. */
class UvmOutOfMemoryException(message: String = null, cause: Throwable = null) extends UvmRuntimeException(message, cause)
/** Thrown when an operation has undefined behaviour according to the specification. */
class UvmUndefinedBehaviorException(message: String = null, cause: Throwable = null) extends UvmRuntimeException(message, cause)
/** Thrown when a division by zero is executed and the exception clause is not present. */ /** Thrown when a division by zero is executed and the exception clause is not present. */
class UvmDivisionByZeroException(message: String = null, cause: Throwable = null) extends UvmRuntimeException(message, cause) class UvmDivisionByZeroException(message: String = null, cause: Throwable = null) extends UvmUndefinedBehaviorException(message, cause)
/** Thrown when accessing Mu memory but the address is outside the allocated region. */ /** Thrown when accessing Mu memory but the address is outside the allocated region. */
class UvmIllegalMemoryAccessException(message: String = null, cause: Throwable = null) extends UvmRuntimeException(message, cause) class UvmIllegalMemoryAccessException(message: String = null, cause: Throwable = null) extends UvmRuntimeException(message, cause)
......
...@@ -384,7 +384,11 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor { ...@@ -384,7 +384,11 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
} }
case i @ InstGetIRef(referentTy, opnd) => { case i @ InstGetIRef(referentTy, opnd) => {
results(0).asIRef = (opnd.asRef, 0L) val baseAddr = opnd.asRef
if (baseAddr == 0L) {
throw new UvmUndefinedBehaviorException(ctx + "Attempted to use GETIREF on a NULL reference")
}
results(0).asIRef = (baseAddr, 0L)
continueNormally() continueNormally()
} }
...@@ -520,7 +524,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor { ...@@ -520,7 +524,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
case i @ InstNewThread(stack, newStackAction, excClause) => { case i @ InstNewThread(stack, newStackAction, excClause) => {
val newStack = stack.asStack.getOrElse { val newStack = stack.asStack.getOrElse {
throw new UvmRuntimeException(ctx + "Attempt to bind to a NULL stack.") throw new UvmUndefinedBehaviorException(ctx + "Attempt to bind a new thread to a NULL stack.")
} }
val newThread = newStackAction match { val newThread = newStackAction match {
...@@ -541,7 +545,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor { ...@@ -541,7 +545,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
case i @ InstSwapStack(swappee, curStackAction, newStackAction, excClause, keepAlives) => { case i @ InstSwapStack(swappee, curStackAction, newStackAction, excClause, keepAlives) => {
val oldStack = curStack val oldStack = curStack
val newStack = swappee.asStack.getOrElse { val newStack = swappee.asStack.getOrElse {
throw new UvmRuntimeException(ctx + "Swappee must not be NULL.") throw new UvmUndefinedBehaviorException(ctx + "Swappee must not be NULL.")
} }
def handleOldStack() = curStackAction match { def handleOldStack() = curStackAction match {
...@@ -570,7 +574,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor { ...@@ -570,7 +574,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
case i: InstCommInst => interpretCurrentCommonInstruction() case i: InstCommInst => interpretCurrentCommonInstruction()
case i => { case i => {
throw new UvmRefImplException("Unimplemented instruction %s".format(i.getClass.getName)) throw new UvmUnimplementedOperationException("Unimplemented instruction %s".format(i.getClass.getName))
} }
} }
} catch { } catch {
......
...@@ -331,6 +331,9 @@ trait InterpreterActions extends InterpreterThreadState { ...@@ -331,6 +331,9 @@ trait InterpreterActions extends InterpreterThreadState {
dst.asPtr = src.asPtr + addrIncr dst.asPtr = src.asPtr + addrIncr
} else { } else {
val (sb,so) = src.asIRef val (sb,so) = src.asIRef
if (sb == 0L && so == 0L) {
throw new UvmUndefinedBehaviorException(ctx + "Attempted to execute memory addressing instruction on a NULL iref.")
}
dst.asIRef = (sb, so + addrIncr) dst.asIRef = (sb, so + addrIncr)
} }
} }
......
...@@ -356,7 +356,7 @@ object MemoryOperations { ...@@ -356,7 +356,7 @@ object MemoryOperations {
val highWord = memorySupport.loadLong(loc + 8, !ptr) val highWord = memorySupport.loadLong(loc + 8, !ptr)
(BigInt(highWord) << 64) + lowWord (BigInt(highWord) << 64) + lowWord
} }
case _ => throw new UnimplementedOprationException("Loading int of length %d is not supported".format(l)) case _ => throw new UvmUnimplementedOperationException("Loading int of length %d is not supported".format(l))
} }
br.asInstanceOf[BoxInt].value = OpHelper.unprepare(bi, l) br.asInstanceOf[BoxInt].value = OpHelper.unprepare(bi, l)
case _: TypeFloat => case _: TypeFloat =>
...@@ -396,7 +396,7 @@ object MemoryOperations { ...@@ -396,7 +396,7 @@ object MemoryOperations {
case _: TypeUPtr | _: TypeUFuncPtr => case _: TypeUPtr | _: TypeUFuncPtr =>
val addr = memorySupport.loadLong(loc, !ptr) val addr = memorySupport.loadLong(loc, !ptr)
br.asInstanceOf[BoxPointer].addr = addr br.asInstanceOf[BoxPointer].addr = addr
case _ => throw new UnimplementedOprationException("Loading of type %s is not supporing".format(ty.getClass.getName)) case _ => throw new UvmUnimplementedOperationException("Loading of type %s is not supporing".format(ty.getClass.getName))
} }
ty match { ty match {
...@@ -423,7 +423,7 @@ object MemoryOperations { ...@@ -423,7 +423,7 @@ object MemoryOperations {
memorySupport.storeLong(loc, (bi & 0xffffffffffffffffL).longValue, !ptr) memorySupport.storeLong(loc, (bi & 0xffffffffffffffffL).longValue, !ptr)
memorySupport.storeLong(loc + 8, (bi >> 64).longValue, !ptr) memorySupport.storeLong(loc + 8, (bi >> 64).longValue, !ptr)
} }
case _ => throw new UnimplementedOprationException("Storing int of length %d is not supported".format(l)) case _ => throw new UvmUnimplementedOperationException("Storing int of length %d is not supported".format(l))
} }
case _: TypeFloat => case _: TypeFloat =>
val fv = nvb.asInstanceOf[BoxFloat].value val fv = nvb.asInstanceOf[BoxFloat].value
...@@ -459,7 +459,7 @@ object MemoryOperations { ...@@ -459,7 +459,7 @@ object MemoryOperations {
case _: TypeUPtr | _: TypeUFuncPtr => case _: TypeUPtr | _: TypeUFuncPtr =>
val addr = nvb.asInstanceOf[BoxPointer].addr val addr = nvb.asInstanceOf[BoxPointer].addr
memorySupport.storeLong(loc, addr, !ptr) memorySupport.storeLong(loc, addr, !ptr)
case _ => throw new UnimplementedOprationException("Storing of type %s is not supporing".format(ty.getClass.getName)) case _ => throw new UvmUnimplementedOperationException("Storing of type %s is not supporing".format(ty.getClass.getName))
} }
ty match { ty match {
...@@ -490,7 +490,7 @@ object MemoryOperations { ...@@ -490,7 +490,7 @@ object MemoryOperations {
val (succ2, rv) = memorySupport.cmpXchgLong(loc, ebi.longValue, dbi.longValue, !ptr) val (succ2, rv) = memorySupport.cmpXchgLong(loc, ebi.longValue, dbi.longValue, !ptr)
(succ2, BigInt(rv)) (succ2, BigInt(rv))
} }
case _ => throw new UnimplementedOprationException("CmpXchg on int of length %d is not supported".format(l)) case _ => throw new UvmUnimplementedOperationException("CmpXchg on int of length %d is not supported".format(l))
} }
br.asInstanceOf[BoxInt].value = OpHelper.unprepare(rbi, l) br.asInstanceOf[BoxInt].value = OpHelper.unprepare(rbi, l)
succ succ
...@@ -538,7 +538,7 @@ object MemoryOperations { ...@@ -538,7 +538,7 @@ object MemoryOperations {
val (succ, rl) = memorySupport.cmpXchgLong(loc, el, dl, !ptr) val (succ, rl) = memorySupport.cmpXchgLong(loc, el, dl, !ptr)
br.asInstanceOf[BoxPointer].addr = rl br.asInstanceOf[BoxPointer].addr = rl
succ succ
case _ => throw new UnimplementedOprationException("CmpXchg of type %s is not supporing".format(ty.getClass.getName)) case _ => throw new UvmUnimplementedOperationException("CmpXchg of type %s is not supporing".format(ty.getClass.getName))
} }
} }
...@@ -549,12 +549,12 @@ object MemoryOperations { ...@@ -549,12 +549,12 @@ object MemoryOperations {
val rbi: BigInt = l match { val rbi: BigInt = l match {
case 32 => memorySupport.atomicRMWInt(op, loc, obi.intValue, !ptr) case 32 => memorySupport.atomicRMWInt(op, loc, obi.intValue, !ptr)
case 64 => memorySupport.atomicRMWLong(op, loc, obi.longValue, !ptr) case 64 => memorySupport.atomicRMWLong(op, loc, obi.longValue, !ptr)
case _ => throw new UnimplementedOprationException("AtomicRMW on int of length %d is not supported".format(l)) case _ => throw new UvmUnimplementedOperationException("AtomicRMW on int of length %d is not supported".format(l))
} }
br.asInstanceOf[BoxInt].value = OpHelper.unprepare(rbi, l) br.asInstanceOf[BoxInt].value = OpHelper.unprepare(rbi, l)
case _ => case _ =>
if (op != XCHG) { if (op != XCHG) {
throw new UnimplementedOprationException("AtomicRMW operation other than XCHG only supports int. %s found.".format(ty.getClass.getName)) throw new UvmUnimplementedOperationException("AtomicRMW operation other than XCHG only supports int. %s found.".format(ty.getClass.getName))
} else { } else {
ty match { ty match {
case _: TypeRef => case _: TypeRef =>
...@@ -595,7 +595,7 @@ object MemoryOperations { ...@@ -595,7 +595,7 @@ object MemoryOperations {
val rl = memorySupport.atomicRMWLong(op, loc, ol, !ptr) val rl = memorySupport.atomicRMWLong(op, loc, ol, !ptr)
br.asInstanceOf[BoxPointer].addr = rl br.asInstanceOf[BoxPointer].addr = rl
case _ => case _ =>
throw new UnimplementedOprationException("AtomicRMW XCHG of type %s is not supporing".format(ty.getClass.getName)) throw new UvmUnimplementedOperationException("AtomicRMW XCHG of type %s is not supporing".format(ty.getClass.getName))
} }
} }
} }
...@@ -615,7 +615,7 @@ object MemoryOperations { ...@@ -615,7 +615,7 @@ object MemoryOperations {
val actualNum = memorySupport.loadInt(loc) val actualNum = memorySupport.loadInt(loc)
expNum == actualNum expNum == actualNum
} }
case _ => throw new UnimplementedOprationException("Futex of %d bit int is not supported".format(len)) case _ => throw new UvmUnimplementedOperationException("Futex of %d bit int is not supported".format(len))
} }
val US_ASCII = Charset.forName("US-ASCII") val US_ASCII = Charset.forName("US-ASCII")
......
...@@ -221,10 +221,10 @@ class InterpreterStack(val id: Int, val stackMemory: StackMemory, stackBottomFun ...@@ -221,10 +221,10 @@ class InterpreterStack(val id: Int, val stackMemory: StackMemory, stackBottomFun
top.state = FrameState.Running top.state = FrameState.Running
} }
case mf: UndefinedMuFrame => { case mf: UndefinedMuFrame => {
throw new UvmRefImplException("Unwound to a frame for undefined Mu function %s. Stack ID: %d.".format(mf.func.repr, id)) throw new UvmInternalException("Unwound to a frame for undefined Mu function %s. Stack ID: %d.".format(mf.func.repr, id))
} }
case nf: NativeFrame => { case nf: NativeFrame => {
throw new UnimplementedOprationException("Cannot unwind to native frames. Stack ID: %d.".format(id)) throw new UvmUnimplementedOperationException("Cannot unwind to native frames. Stack ID: %d.".format(id))
} }
} }
} }
...@@ -282,13 +282,13 @@ class InterpreterStack(val id: Int, val stackMemory: StackMemory, stackBottomFun ...@@ -282,13 +282,13 @@ class InterpreterStack(val id: Int, val stackMemory: StackMemory, stackBottomFun
val toFrame = cursor.frame val toFrame = cursor.frame
for ((curFrame, i) <- frames.takeWhile(_ != toFrame).zipWithIndex) { for ((curFrame, i) <- frames.takeWhile(_ != toFrame).zipWithIndex) {
if (curFrame.isInstanceOf[NativeFrame]) { if (curFrame.isInstanceOf[NativeFrame]) {
throw new UnimplementedOprationException( throw new UvmUnimplementedOperationException(
"Popping native frames is not supported. Found native frame at depth %d in stack %d".format(i, id)) "Popping native frames is not supported. Found native frame at depth %d in stack %d".format(i, id))
} }
for (c2 <- frameCursors if c2 != cursor) { for (c2 <- frameCursors if c2 != cursor) {
if (c2.frame == curFrame) { if (c2.frame == curFrame) {
throw new UnimplementedOprationException( throw new UvmUnimplementedOperationException(
"Frame %s at depth %d in stack %d is referred by another frame cursor %d. Current cursor: %d".format( "Frame %s at depth %d in stack %d is referred by another frame cursor %d. Current cursor: %d".format(
c2.frame.toString, i, id, c2.id, cursor.id)) c2.frame.toString, i, id, c2.id, cursor.id))
} }
......
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