diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java
index c83f50b2f29e3f87f63164436393f82af6e1f683..e92996191341e79a24bf9ec9e77a909490abbb14 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java
@@ -31,10 +31,12 @@ import com.oracle.truffle.api.interop.ForeignAccess;
 import com.oracle.truffle.api.interop.InteropException;
 import com.oracle.truffle.api.interop.Message;
 import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.UnknownIdentifierException;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_CallFactory.ToNativeNodeGen;
 import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_CallFactory.TruffleLLVM_InvokeCallNodeGen;
+import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL.LLVM_Handle;
 import com.oracle.truffle.r.ffi.impl.llvm.upcalls.BytesToNativeCharArrayCall;
 import com.oracle.truffle.r.ffi.impl.llvm.upcalls.CharSXPToNativeArrayCall;
 import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks;
@@ -46,6 +48,7 @@ import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RScalar;
 import com.oracle.truffle.r.runtime.data.RVector;
 import com.oracle.truffle.r.runtime.ffi.CallRFFI;
+import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.ffi.FFIUnwrapNode;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
@@ -95,8 +98,9 @@ final class TruffleLLVM_Call implements CallRFFI {
 
                 callbacks = (TruffleObject) context.getEnv().asGuestValue(callbacksArray);
 
+                LLVM_Handle rdllInfo = (LLVM_Handle) DLL.getRdllInfo().handle;
+                SymbolHandle setClbkAddrSymbolHandle = new SymbolHandle(rdllInfo.parsedIRs[0].lookup("Rinternals_setCallbacksAddress"));
                 Node setClbkAddrExecuteNode = Message.EXECUTE.createNode();
-                SymbolHandle setClbkAddrSymbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + "Rinternals_setCallbacksAddress"));
                 setCallbacksAddress = setClbkAddrSymbolHandle.asTruffleObject();
                 // Initialize the callbacks global variable
                 ForeignAccess.sendExecute(setClbkAddrExecuteNode, setCallbacksAddress, context.getEnv().asGuestValue(new TruffleObject[0]));
@@ -123,8 +127,13 @@ final class TruffleLLVM_Call implements CallRFFI {
 
     public static void initVariables(RContext context) {
         // must have parsed the variables module in libR
+        LLVM_Handle rdllInfo = (LLVM_Handle) DLL.getRdllInfo().handle;
         for (INIT_VAR_FUN initVarFun : INIT_VAR_FUN.values()) {
-            initVarFun.symbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + initVarFun.funName));
+            try {
+                initVarFun.symbolHandle = new SymbolHandle(rdllInfo.parsedIRs[0].lookup(initVarFun.funName));
+            } catch (UnknownIdentifierException e) {
+                throw RInternalError.shouldNotReachHere(e);
+            }
         }
         Node executeNode = Message.EXECUTE.createNode();
         RFFIVariables[] variables = RFFIVariables.initialize(context);
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java
index 2657178aac9b998e8e7fc9aabbf7843fde58cb09..66863f8698688bdfd6c7cc2c3a981d935af74496 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java
@@ -23,14 +23,25 @@
 package com.oracle.truffle.r.ffi.impl.llvm;
 
 import java.nio.file.FileSystems;
+import java.util.EnumMap;
 
+import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.interop.Message;
 import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.UnknownIdentifierException;
+import com.oracle.truffle.api.interop.UnsupportedMessageException;
+import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.ffi.impl.common.LibPaths;
+import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL.LLVM_Handle;
+import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL.ParsedLLVM_IR;
 import com.oracle.truffle.r.runtime.REnvVars;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.context.RContext.ContextState;
 import com.oracle.truffle.r.runtime.ffi.BaseRFFI;
 import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 import com.oracle.truffle.r.runtime.ffi.DLLRFFI;
 import com.oracle.truffle.r.runtime.ffi.LapackRFFI;
 import com.oracle.truffle.r.runtime.ffi.MiscRFFI;
@@ -104,9 +115,53 @@ final class TruffleLLVM_Context extends RFFIContext {
         callState.beforeDispose(context);
     }
 
+    private final EnumMap<NativeFunction, TruffleObject> nativeFunctions = new EnumMap<>(NativeFunction.class);
+
     @Override
     public TruffleObject lookupNativeFunction(NativeFunction function) {
-        Object symValue = RContext.getInstance().getEnv().importSymbol("@" + function.getCallName());
-        return (TruffleObject) symValue;
+        CompilerAsserts.neverPartOfCompilation();
+        if (!nativeFunctions.containsKey(function)) {
+            TruffleObject[] lookupObjects = new TruffleObject[0];
+            if (function.getLibrary() == NativeFunction.baseLibrary()) {
+                TruffleObject lookupObject = (TruffleObject) ((LLVM_Handle) DLL.getRdllInfo().handle).parsedIRs[0].lookupObject;
+                lookupObjects = new TruffleObject[]{lookupObject};
+            } else if (function.getLibrary() == NativeFunction.anyLibrary()) {
+                DLLInfo dllInfo = DLL.findLibraryContainingSymbol(RContext.getInstance(), function.getCallName());
+                if (dllInfo == null) {
+                    throw RInternalError.shouldNotReachHere("Could not find library containing symbol " + function.getCallName());
+                }
+                lookupObjects = getLookupObjects(dllInfo);
+            } else {
+                DLLInfo dllInfo = DLL.findLibrary(function.getLibrary());
+                if (dllInfo == null) {
+                    throw RInternalError.shouldNotReachHere("Could not find library  " + function.getLibrary());
+                }
+                lookupObjects = getLookupObjects(dllInfo);
+            }
+            TruffleObject target = null;
+            final Node lookupNode = Message.READ.createNode();
+            for (int i = 0; i < lookupObjects.length; i++) {
+                try {
+                    target = (TruffleObject) ForeignAccess.sendRead(lookupNode, lookupObjects[i], function.getCallName());
+                    break;
+                } catch (UnknownIdentifierException e) {
+                    continue;
+                } catch (UnsupportedMessageException e) {
+                    RInternalError.shouldNotReachHere();
+                }
+            }
+            nativeFunctions.put(function, target);
+        }
+        return nativeFunctions.get(function);
+    }
+
+    private static TruffleObject[] getLookupObjects(DLLInfo dllInfo) {
+        TruffleObject[] lookupObjects;
+        final ParsedLLVM_IR[] parsedIRs = ((LLVM_Handle) dllInfo.handle).parsedIRs;
+        lookupObjects = new TruffleObject[parsedIRs.length];
+        for (int i = 0; i < parsedIRs.length; i++) {
+            lookupObjects[i] = (TruffleObject) parsedIRs[i].lookupObject;
+        }
+        return lookupObjects;
     }
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java
index 2077369f7765430c188803e734b91c8a515c437f..5758125b4309f6fad8341ac7d54e78ad354e1164 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java
@@ -44,6 +44,11 @@ import java.util.zip.ZipInputStream;
 
 import com.oracle.truffle.api.CallTarget;
 import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.interop.Message;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.UnknownIdentifierException;
+import com.oracle.truffle.api.interop.UnsupportedMessageException;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.r.runtime.RInternalError;
@@ -94,6 +99,7 @@ public class TruffleLLVM_DLL implements DLLRFFI {
          */
         @Override
         public ContextState initialize(RContext context) {
+            // TODO: Is it really needed when using the new lookup mechanism?
             if (!context.isInitial()) {
                 for (LLVM_IR ir : truffleDLL.libRModules) {
                     parseLLVM("libR", ir);
@@ -105,8 +111,8 @@ public class TruffleLLVM_DLL implements DLLRFFI {
                 for (DLLInfo dllInfo : loadedDLLs) {
                     if (dllInfo.handle instanceof LLVM_Handle) {
                         LLVM_Handle llvmHandle = (LLVM_Handle) dllInfo.handle;
-                        for (LLVM_IR ir : llvmHandle.irs) {
-                            parseLLVM(llvmHandle.libName, ir);
+                        for (ParsedLLVM_IR parsedIR : llvmHandle.parsedIRs) {
+                            parseLLVM(llvmHandle.libName, parsedIR.ir);
                         }
                     }
                 }
@@ -128,14 +134,34 @@ public class TruffleLLVM_DLL implements DLLRFFI {
         return new ContextStateImpl();
     }
 
+    static class ParsedLLVM_IR {
+        final LLVM_IR ir;
+        final Object lookupObject;
+
+        ParsedLLVM_IR(LLVM_IR ir, Object lookupObject) {
+            this.ir = ir;
+            this.lookupObject = lookupObject;
+        }
+
+        Object lookup(String symbol) throws UnknownIdentifierException {
+            try {
+                return ForeignAccess.sendRead(Message.READ.createNode(), (TruffleObject) lookupObject, symbol);
+            } catch (UnsupportedMessageException e) {
+                throw RInternalError.shouldNotReachHere(e);
+            }
+        }
+
+    }
+
     static class LLVM_Handle {
-        private final String libName;
-        private final LLVM_IR[] irs;
+        final String libName;
+        final ParsedLLVM_IR[] parsedIRs;
 
-        LLVM_Handle(String libName, LLVM_IR[] irs) {
+        LLVM_Handle(String libName, ParsedLLVM_IR[] irs) {
             this.libName = libName;
-            this.irs = irs;
+            this.parsedIRs = irs;
         }
+
     }
 
     @FunctionalInterface
@@ -236,10 +262,13 @@ public class TruffleLLVM_DLL implements DLLRFFI {
                 } else {
                     loadNativeLibs(ar.nativeLibs);
                 }
-                for (LLVM_IR ir : irs) {
-                    parseLLVM(libName, ir);
+                ParsedLLVM_IR[] parsedIRs = new ParsedLLVM_IR[irs.length];
+                for (int i = 0; i < irs.length; i++) {
+                    LLVM_IR ir = irs[i];
+                    Object irLookupObject = parseLLVM(libName, ir).call();
+                    parsedIRs[i] = new ParsedLLVM_IR(ir, irLookupObject);
                 }
-                return new LLVM_Handle(libName, irs);
+                return new LLVM_Handle(libName, parsedIRs);
             } catch (Exception ex) {
                 CompilerDirectives.transferToInterpreter();
                 StringBuilder sb = new StringBuilder();
@@ -276,15 +305,30 @@ public class TruffleLLVM_DLL implements DLLRFFI {
     }
 
     private static class TruffleLLVM_DLSymNode extends Node implements DLSymNode {
+        @Child private Node lookupNode = Message.READ.createNode();
+
         @Override
         public SymbolHandle execute(Object handle, String symbol) throws UnsatisfiedLinkError {
             assert handle instanceof LLVM_Handle;
-            Object symValue = RContext.getInstance().getEnv().importSymbol("@" + symbol);
+            LLVM_Handle llvmHandle = (LLVM_Handle) handle;
+            Object symValue = null;
+            for (int i = 0; i < llvmHandle.parsedIRs.length; i++) {
+                ParsedLLVM_IR pir = llvmHandle.parsedIRs[i];
+                try {
+                    symValue = ForeignAccess.sendRead(lookupNode, (TruffleObject) pir.lookupObject, symbol);
+                    break;
+                } catch (UnknownIdentifierException e) {
+                    continue;
+                } catch (UnsupportedMessageException e) {
+                    RInternalError.shouldNotReachHere();
+                }
+            }
             if (symValue == null) {
                 throw new UnsatisfiedLinkError();
             }
             return new SymbolHandle(symValue);
         }
+
     }
 
     private static class TruffleLLVM_DLCloseNode extends Node implements DLCloseNode {
@@ -321,25 +365,10 @@ public class TruffleLLVM_DLL implements DLLRFFI {
      */
     private LLVM_IR[] libRModules;
 
-    private static final String[] PARSE_ERRORS = new String[0];
-
-    private static boolean parseFails(String libName, LLVM_IR ir) {
-        for (int i = 0; i < PARSE_ERRORS.length / 2; i++) {
-            String plibName = PARSE_ERRORS[i * 2];
-            String pModule = PARSE_ERRORS[i * 2 + 1];
-            if (libName.equals(plibName) && ir.name.equals(pModule)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static void parseLLVM(String libName, LLVM_IR ir) {
+    private static CallTarget parseLLVM(String libName, LLVM_IR ir) {
         if (ir instanceof LLVM_IR.Binary) {
             LLVM_IR.Binary bir = (LLVM_IR.Binary) ir;
-            if (!parseFails(libName, ir)) {
-                parseBinary(libName, bir);
-            }
+            return parseBinary(libName, bir);
         } else {
             throw RInternalError.unimplemented("LLVM text IR");
         }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNodeFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNodeFactory.java
index 905e78c7c47a1a5b4f0e9c65e473fddd43225983..8a3b57d6323ad6b0a74e9ec9e6c40cb6daa91ba3 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNodeFactory.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNodeFactory.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.ffi.impl.llvm;
 
 import static com.oracle.truffle.r.runtime.ffi.NativeFunction.anyLibrary;
+import static com.oracle.truffle.r.runtime.ffi.NativeFunction.baseLibrary;
 
 import java.nio.charset.StandardCharsets;
 
@@ -67,7 +68,9 @@ final class TruffleLLVM_DownCallNodeFactory extends DownCallNodeFactory {
                 CompilerAsserts.neverPartOfCompilation();
                 String library = fn.getLibrary();
                 DLLInfo dllInfo = null;
-                if (library != anyLibrary()) {
+                if (library == baseLibrary()) {
+                    dllInfo = DLL.getRdllInfo();
+                } else if (library != anyLibrary()) {
                     dllInfo = DLL.findLibrary(library);
                 }
                 SymbolHandle result = DLL.findSymbol(fn.getCallName(), dllInfo);
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java
index a7dc6e740a5ede59a4cd9aad56ffe4d230f34788..5e723d35fe9cd5295f7bbc4602035ccc9cf857fc 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java
@@ -29,11 +29,11 @@ import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.ffi.impl.common.JavaUpCallsRFFIImpl;
 import com.oracle.truffle.r.ffi.impl.common.RFFIUtils;
+import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_DLL.LLVM_Handle;
 import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks;
 import com.oracle.truffle.r.runtime.REnvVars;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
-import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
 import com.oracle.truffle.r.runtime.data.RDouble;
 import com.oracle.truffle.r.runtime.data.RInteger;
@@ -42,10 +42,9 @@ import com.oracle.truffle.r.runtime.data.RScalar;
 import com.oracle.truffle.r.runtime.data.RString;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.ffi.DLL;
-import com.oracle.truffle.r.runtime.ffi.FFIUnwrapNode;
 import com.oracle.truffle.r.runtime.ffi.DLL.CEntry;
 import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
-import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
+import com.oracle.truffle.r.runtime.ffi.FFIUnwrapNode;
 import com.oracle.truffle.r.runtime.ffi.VectorRFFIWrapper;
 import com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray;
 
@@ -58,7 +57,12 @@ public class TruffleLLVM_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl {
     private TruffleObject setSymbolHandle;
 
     void initialize() {
-        setSymbolHandle = new SymbolHandle(RContext.getInstance().getEnv().importSymbol("@" + "Rdynload_setSymbol")).asTruffleObject();
+        LLVM_Handle rdllInfo = (LLVM_Handle) DLL.getRdllInfo().handle;
+        try {
+            setSymbolHandle = (TruffleObject) rdllInfo.parsedIRs[0].lookup("Rdynload_setSymbol");
+        } catch (Exception e) {
+            RInternalError.shouldNotReachHere(e);
+        }
     }
 
     public Object charSXPToNativeCharArray(Object x) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
index fb0226d2080966810efdb9fd8d4db8bb7830be52..44aede983333c09a0e1551b17c79f618437efd7d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
@@ -829,6 +829,10 @@ public class DLL {
         return null;
     }
 
+    public static DLLInfo getRdllInfo() {
+        return ContextStateImpl.libRdllInfo;
+    }
+
     /**
      * Search for symbol {@code name} in library defined by {@code dllInfo}, or {@code null} for
      * search in all loaded libraries. Used in the rare cases where no Truffle execution context
diff --git a/com.oracle.truffle.r.test.native/urand/Makefile b/com.oracle.truffle.r.test.native/urand/Makefile
index cf9282e5b6a815a8ba2c31968b22e8329dc9c997..fb67e638de045306edd177ff77057c15d5b17430 100644
--- a/com.oracle.truffle.r.test.native/urand/Makefile
+++ b/com.oracle.truffle.r.test.native/urand/Makefile
@@ -43,11 +43,22 @@ C_LIBNAME := liburand.so
 C_OBJECTS := $(subst $(SRC),$(OBJ),$(C_SOURCES:.c=.o))
 C_LIB := $(OBJ)/$(C_LIBNAME)
 
-
 INCLUDE_DIR := $(NATIVE_PROJECT)/include
 
+ifeq ($(FASTR_RFFI),llvm)
+
 all: $(C_LIB)
 
+else
+
+C_LIB_LLVM_DUMMY := $(C_LIB)l
+all: $(C_LIB) $(C_LIB_LLVM_DUMMY)
+
+$(C_LIB_LLVM_DUMMY):
+	touch $(C_LIB_LLVM_DUMMY)
+	
+endif
+
 $(C_LIB): $(OBJ) $(C_OBJECTS)
 	$(DYLIB_LD) $(DYLIB_LDFLAGS)  -o $(C_LIB) $(C_OBJECTS)
 
diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py
index ac48d796fdeb6583b2679c7281e3eaa1de538c45..151d71ec30ed087fbd93a60dfd5f2ed726ead077 100644
--- a/mx.fastr/suite.py
+++ b/mx.fastr/suite.py
@@ -162,6 +162,7 @@ suite = {
       "output" : "com.oracle.truffle.r.test.native",
       "results" :[
          "urand/lib/liburand.so",
+         "urand/lib/liburand.sol",
        ],
       "workingSets" : "FastR",
     },