Commit 11b66353 authored by Kunshan Wang's avatar Kunshan Wang

Fixed symbol resolution bug

parent d43f9678
......@@ -24,9 +24,20 @@ object NativeLibraryHolder {
}
class ManualLibrary(val handle: Long) extends AutoCloseable {
def maybeGetSymbolAddress(symbol: String): Option[Long] = {
try {
Some(getSymbolAddress(symbol))
} catch {
case e: UnsatisfiedLinkError => None
}
}
@throws[UnsatisfiedLinkError]("if symbol is not found in the library")
def getSymbolAddress(symbol: String): Long = {
ForeignThief.dlsym(handle, symbol)
}
override def close(): Unit = {
if (handle != 0L) {
ForeignThief.dlclose(handle)
......@@ -71,19 +82,35 @@ class NativeLibraryHolder() extends AutoCloseable {
lib
}
}
/**
* Get the address of a symbol.
*
* @param symbol the symbol.
* @return Some(addr) if the address is found, or None otherwise
*/
def getSymbolAddress(symbol: String): Long = {
def maybeGetSymbolAddress(symbol: String): Option[Long] = {
for (lib <- libs) {
val addr = lib.getSymbolAddress(symbol)
if (addr != 0L) {
return addr
lib.maybeGetSymbolAddress(symbol) match {
case None =>
case Some(addr) => return Some(addr)
}
}
throw new UvmExternalLibraryException("Symbol cannot be resolved: %s".format(symbol))
None
}
/**
* Get the address of a symbol.
*
* @param symbol the symbol.
* @return The address of the symbol
* @throws UvmExternalLibraryException if the symbol cannot be resolved
*/
@throws[UvmExternalLibraryException]("symbol cannot be resolved")
def getSymbolAddress(symbol: String): Long = {
maybeGetSymbolAddress(symbol) match {
case None => throw new UvmExternalLibraryException("Symbol cannot be resolved: %s".format(symbol))
case Some(addr) => addr
}
}
}
package uvm.refimpl.nat
import uvm._
import uvm.refimpl._
import uvm.UvmTestBase
import uvm.ir.textinput.ExtraMatchers
import uvm.refimpl.UvmBundleTesterBase
......@@ -14,100 +16,76 @@ import java.nio.charset.StandardCharsets
import uvm.refimpl.HowToResume
import java.io.StringWriter
import java.io.OutputStreamWriter
import uvm.ir.irbuilder.IRBuilder
import scala.collection.mutable.HashMap
import uvm.utils.WithUtils.tryWithResource
import uvm.refimpl.TrapHandlerResult.Rebind
import uvm.refimpl.HowToResume.PassValues
class NativeLibraryHolderTest extends UvmBundleTesterBase {
behavior of "NativeLibraryHolder"
// FIXME: implement the bundle builder
/*
it should "link EXTERN consts with C symbols" in {
val message = "Hello world!\n\0".getBytes(StandardCharsets.US_ASCII)
val ctx = microVM.newContext()
val b = ctx.newBundle()
val int_t = ctx.newTypeInt(b, 32)
ctx.setName(b, int_t, "@int")
val void_t = ctx.newTypeVoid(b)
ctx.setName(b, void_t, "@void")
val voidp_t = ctx.newTypeUPtr(b)
ctx.setName(b, voidp_t, "@voidp")
ctx.setTypeUPtr(voidp_t, void_t)
val size_t = ctx.newTypeInt(b, 64)
ctx.setName(b, size_t, "@size_t")
val ssize_t = ctx.newTypeInt(b, 64)
ctx.setName(b, ssize_t, "@ssize_t")
val write_sig = ctx.newFuncSig(b, Seq(int_t, voidp_t, size_t), Seq(ssize_t))
val write_fp = ctx.newTypeUFuncPtr(b)
ctx.setTypeUFuncPtr(write_fp, write_sig)
val write = ctx.newConstExtern(b, write_fp, "write")
val stdout = ctx.newConstInt(b, int_t, 1)
val hw_sz = ctx.newConstInt(b, size_t, message.size)
val ch_t = ctx.newTypeInt(b, 8)
val str_t = ctx.newTypeHybrid(b, Seq(), ch_t)
val str_t_id = ctx.getID(b, str_t)
val refstr_t = ctx.newTypeRef(b)
ctx.setTypeRef(refstr_t, str_t)
val ptrstr_t = ctx.newTypeUPtr(b)
ctx.setTypeUPtr(ptrstr_t, str_t)
val hw_g = ctx.newGlobalCell(b, refstr_t)
val hw_g_id = ctx.getID(b, hw_g)
val write_test_sig = ctx.newFuncSig(b, Seq(), Seq())
val write_test = ctx.newFunc(b, write_test_sig)
val write_test_id = ctx.getID(b, write_test)
val write_test_v1 = ctx.newFuncVer(b, write_test)
{
val fv = write_test_v1
val entry = ctx.newBB(fv)
val load_i = ctx.newLoad(entry, false, MemoryOrder.NOT_ATOMIC, refstr_t, hw_g)
val hw_r = ctx.getInstRes(load_i, 0)
val pin_i = ctx.newCommInst(entry, CommInsts("@uvm.native.pin").id, Seq(), Seq(refstr_t), Seq(), Seq(hw_r))
val hw_p = ctx.getInstRes(pin_i, 0)
val ptrcast_i = ctx.newConv(entry, ConvOptr.PTRCAST, ptrstr_t, voidp_t, hw_p)
val hw_vp = ctx.getInstRes(ptrcast_i, 0)
val ccall_i = ctx.newCCall(entry, Flag("#DEFAULT"), write_fp, write_sig, write, Seq(stdout, hw_vp, hw_sz))
val rv = ctx.getInstRes(ccall_i, 0)
val thread_exit_i = ctx.newCommInst(entry, CommInsts("@uvm.thread_exit").id, Seq(), Seq(), Seq(), Seq())
}
ctx.loadBundleFromNode(b)
System.err.print("Bundle dump:\n")
microVM.debugPrintGlobalBundle(new OutputStreamWriter(System.err))
val h_hw_g_ir = ctx.handleFromGlobal(hw_g_id)
val h_sz = ctx.handleFromInt(message.size, 64)
val h_new_str_r = ctx.newHybrid(str_t_id, h_sz)
ctx.store(MemoryOrder.NOT_ATOMIC, h_hw_g_ir, h_new_str_r)
val h_new_str_p = ctx.pin(h_new_str_r)
val p_new_str_p = ctx.handleToPtr(h_new_str_p)
for ((ch, i) <- message.zipWithIndex) {
val ord = ch.toByte
val loc = p_new_str_p + i
NativeSupport.theMemory.putByte(loc, ord)
class ConvenientNs(b: IRBuilder, prefix: String) {
val map = new HashMap[Symbol, MuID]()
def muNameOf(sym: Symbol): MuName = "@" + prefix + "." + sym.name
def symLookup(sym: Symbol): MuID = {
map.getOrElseUpdate(sym, {
b.genSym(muNameOf(sym))
})
}
ctx.unpin(h_new_str_r)
val func = ctx.handleFromFunc(write_test_id)
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
fail("There is no trap!")
}
microVM.nativeLibraryHolder.loadLibrary("tests/c-snippets/simplecfuncs.so")
it should "link EXTERN consts with C symbols" in {
tryWithResource(microVM.newContext()) { ctx =>
val b = ctx.newIRBuilder
val ns = new ConvenientNs(b, "hello-world-test")
implicit def _lookup = ns.symLookup _
b.newTypeInt('i32, 32)
b.newFuncSig('hwsig, Seq('i32), Seq('i32))
b.newTypeUFuncPtr('hwfp, 'hwsig)
b.newConstExtern('hw, 'hwfp, "hello_world")
b.newConstInt('fortytwo, 'i32, 42)
b.newFuncSig('mainsig, Seq(), Seq())
b.newFunc('main, 'mainsig)
b.newFuncVer('mainv1, 'main, Seq('entry))
b.newBB('entry, Seq(), Seq(), None, Seq('ccall, 'trap, 'threadexit))
b.newCCall('ccall, Seq('rv), Flag("#DEFAULT"), 'hwfp, 'hwsig, 'hw, Seq('fortytwo), None, None)
b.newTrap('trap, Seq(), Seq(), None, Some('trapka))
b.newKeepaliveClause('trapka, Seq('rv))
b.newCommInst('threadexit, Seq(), CommInsts("@uvm.thread_exit"), Seq(), Seq(), Seq(), Seq(), None, None)
b.load()
System.err.print("Bundle dump:\n")
microVM.debugPrintGlobalBundle(new OutputStreamWriter(System.err))
val func = ctx.handleFromFunc('main)
val TrapID = ns.symLookup('trap)
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
val cursor = ctx.newCursor(st)
val iid = ctx.curInst(cursor)
iid match {
case TrapID => {
val Seq(rv: MuIntValue) = ctx.dumpKeepalives(cursor)
ctx.closeCursor(cursor)
ctx.handleToSInt(rv) shouldBe 43
Rebind(st, PassValues(Seq()))
}
case _ => fail("Unexpected trap %d".format(iid))
}
}
}
ctx.closeContext()
}
*/
}
\ No newline at end of file
MU_INCLUDE = ../../cbinding
.PHONY: all
all: structtest.so callbacktest.so ncs_tests.so
all: structtest.so callbacktest.so ncs_tests.so simplecfuncs.so
structtest.so: structtest.c
$(CC) -std=c11 -fPIC -shared -o structtest.so structtest.c
......@@ -12,6 +12,9 @@ callbacktest.so: callbacktest.c
ncs_tests.so: ncs_tests.c
$(CC) -std=c11 -fPIC -shared -I $(MU_INCLUDE) -o ncs_tests.so ncs_tests.c
simplecfuncs.so: simplecfuncs.c
$(CC) -std=c11 -fPIC -shared -o simplecfuncs.so simplecfuncs.c
.PHONY: clean
clean:
rm *.so
#include<stdio.h>
int hello_world(int n) {
printf("Hello world from C!\n");
return n + 1;
}
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