Comments (18)
For my personal historical reference.
game.zip
libgdsummator.linux.release.64.zip
from libriscv.
From reading https://github.com/fwsGonzo/rvscript/blob/master/engine/mods/hello_world/scripts/src/gameplay.cpp.
The translated design seems to be:
// RSICV
#define PUBLIC(x) extern "C" __attribute__((used, retain)) x
PUBLIC(GDNativeBool summator_library_init(const GDNativeInterface *p_interface, const GDNativeExtensionClassLibraryPtr p_library, GDNativeInitialization *r_initialization));
// Godot Engine
NativeExtensionRISCV::open_library("scripts/summator.elf", "summator_library_init", "scripts/summator.map");
// Inside open_library
// https://github.com/fwsGonzo/rvscript/blob/121c3990aa6c1afa79a7673b7f6e5c7a34642f31/engine/src/manage_scripts.cpp#L10
err = get_dynamic_library_symbol_handle(library, p_entry_symbol, symbol_map, entry_funcptr, false);
if (err != OK) {
close_dynamic_library(library);
return err;
}
GDNativeInitializationFunction initialization_function = (GDNativeInitializationFunction)entry_funcptr;
initialization_function(&gdnative_interface, this, &initialization);
level_initialized = -1;
return OK;
// Others
NativeExtensionRISCV::preempt() {}
NativeExtensionRISCV::resume() {}
from libriscv.
There is no shared library support right now, although it would be possible to add support for simple shared libraries. I can whip up some code that lets you load dependency-free shared libraries but I don't know if that is what you want.
libriscv primarily supports static binaries, so compiling the code with -static is the best option. Then you get everything you need inside the program. You can still make function calls and retrieve symbols from the binary, just like normal.
Looking at your shared object, it seems to have many dependencies:
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-riscv64-lp64d.so.1]
This is what makes it a little bit harder to support shared libraries.
from libriscv.
Looking at https://godotengine.org/article/introducing-gd-extensions it seems to require you to compile shared libraries for your native system anyway. So GDExtensionSummator would be compiled to amd64 (x86_64), or you can't load it on your system with dlopen.
On the other hand... you could create a GDExtension that loads RISC-V binaries and provides scripting facilities that way. But in the end it has to be compiled down to a shared library compatible with your native system.
from libriscv.
I was able to provide a main() and call that singular function maybe there some room to work with. It crashes with unaligned memory access in librisc. Will post later today.
from libriscv.
I'm not sure what could cause that but there are some candidates. For example, in C++ there are often global objects with constructors and destructors, and guess what happens when you return from main? The destructors of all the global objects gets called. So, one way to avoid that is to just stop the emulator just before returning from main.
There is a secret halt instruction that you can invoke like this, which simply makes the emulator stop running:
inline void halt() {
// Clobber memory because wake-ups can have things changed
asm (".insn i SYSTEM, 0, x0, x0, 0x7ff" ::: "memory");
}
You can also call _exit(status)
and get the status via machine.return_value()
if you need that. There are many tricks!
I would need to see the code and how you call into the VM to understand the problem better.
from libriscv.
/opt/libriscv/emulator/build/rvlinux game/bin/summator/libgdsummator.linux.release.64.elf
>>> Program exited, exit code = 0 (0x0)
Instructions executed: 59159
Pages in use: 59 (236 kB memory)
libgdsummator.linux.release.64.zip
I'll try to describe the environment but it gets tricky.
- https://github.com/fire/GDExtensionSummator/tree/riscv
- https://github.com/V-Sekai/godot/tree/native-extension-riscv
I'll post this and then post more info.
from libriscv.
So using the testsuite
64 I was able to load that file up to the opening /etc/hostname
and then it stops from a windows embedded into Godot Engine binary. Still looking for more clues.
from libriscv.
https://github.com/fwsGonzo/libriscv/blob/master/lib/libriscv/win32/system_calls.cpp#L268-L302
Works with newlib64. Although I have no idea why linux64 is failing with opening /etc/hostname
.
from libriscv.
It's likely because there's something wrong with the system call handler in lib/libriscv/win32/system_calls.cpp
.
None of the Linux system calls for Windows have been tested or even written properly. All they do is build, with a lot of warnings. Pay special attention to the wording. We are simulating a Linux program, on Windows, so the Linux system calls have to be handled on a Windows host, as if they were on Linux.
Newlib working makes sense, because it doesn't pretend to have many working system calls, and simply says no (-ENOSYS).
rvscript is using Newlib as a base, with a game engine API on top.
from libriscv.
I thought rvscript was using linux64. I missed the detail! The explanations are helpful!
from libriscv.
You don't really need many system calls to get going. My advice is for every need to make a dedicated system call.
If you need to read a file into a string in the RISC-V program, just make a new system call for it, and have it take a buffer-length combo as arguments. If you are wondering how to implement your own system calls check out script_functions.cpp in rvscript repo, or just ask.
from libriscv.
I only need this one call from the starting comment.
address = machine.address_of(p_entry_symbol.utf8().get_data());
machine.vmcall<MAX_MEMORY>(address, &gdnative_interface, this, &initialization);
It does look tough though.
I also had some problems with the execution direction.
The Godot Engine API calls the p_entry_symbol to initialize structures on the host. Then I think Godot Engine uses that api structure to call something to be determined.
from libriscv.
Without looking at all the code I can't tell if that's going to work, but I'm going to guess no. There is a hard border between a sandbox and the host environment that exists in all cases, also with WebAssembly. To work with it you have to think of the RISC-V program as being completely separate, so when you want to run code that needs some data, that data needs to be copied into the RISC-V program (or using shared pages).
I built a framework (rvscript) to simplify some things, but in the end, creating sandbox APIs are a little bit of extra work because of the total isolation.
For example, looking at your code you are passing this
into the VM, however it lives in a completely separate (isolated) address space. The correct thing to do here is to probably call that function yourself. My advice is to implement the Godot extension as a regular DLL, on Windows, using the normal method. Add libriscv as a dependency, and then use libriscv inside your Godot extension DLL. It is not possible to build the extension itself inside the RISC-V program (at least not very fun).
Instead, you can make your Godot extension a plugin that loads a RISC-V program and interfaces with Godot using your plugin. That would work, and you don't have to write a ton of code to get started.
from libriscv.
Thinking about this:
- It should be possible execute main() on the riscv program
- inside of main() it can has a bool syscall(SYSCALL_GODOT_GDEXTENSION, const GDNativeInterface *p_interface, const GDNativeExtensionClassLibraryPtr p_library, GDNativeInitialization *r_initialization)
- This design won't work as is.
GDNativeInitialization contains a int, a byte buffer, and function pointer.
GDNativeExtensionClassLibraryPtr is used to call the host runtime.
GDNativeInterface is a struct that contains uint, uint, string buffer and 5 pages of function pointers.
I think the function pointers need to converted to syscalls.
From the guest it needs to tell Godot Engine the exposed things which are also function pointers.. so converted to syscalls.
classdb_register_extension_class
classdb_register_extension_class_method
classdb_register_extension_class_integer_constant
classdb_register_extension_class_property
classdb_register_extension_class_property_group
classdb_register_extension_class_property_subgroup
classdb_register_extension_class_signal
classdb_unregister_extension_class
Godot Engine can now call the listings through machine.vmcall.
This does sound workable hm.
from libriscv.
I'd like to have the scripting to be done via riscv programs.
Godot extension a plugin that loads a RISC-V program and interfaces with Godot using your plugin.
I think you're suggesting making a gdextension that implements the riscv host and write a new interface for the riscv host to load riscv programs. This is too complicated. godot
-> gdextension
-> riscv script
has three stages. I think the gdextension layer is not essential. So it becomes godot riscv host -> riscv script.
The proposed design of the riscv host is it executes the main() of the riscv program. The main calls a number of syscalls that sets up the version, the levels (of engine subsystems) and then calls the syscalls to register the rest. The godot engine host may call through the listings given previously through machine.vmcall.
Will this work?
from libriscv.
If you do away with the extension then you can have godot <-> riscv script, and you are right about how this would work.
I pressed close issue somehow, maybe an accidental keyboard shortcut. 😞
from libriscv.
If the initialization is very boilerplate I would consider making a single system call, or calling it automatically outside of RISC-V. It really depends on how it works. But a single system call that just takes a struct by reference is OK. You can pass function pointers from RISC-V to the host, but they have no meaning, so you will need to vmcall the function pointer later to get the scripting behavior. It's used as a common way to create events.
In my (private) engine events are wrapped RISC-V function calls, and it looks like this:
Script* m_script = nullptr;
Script::gaddr_t m_funcaddr;
Basically, which RISC-V program the function belongs to, and then the address itself.
Modern game engines are very data oriented, and that makes it easier to create a simple system call API that can modify the ECS.
from libriscv.
Related Issues (20)
- Fast simulator mode with C-extension support HOT 1
- Trouble executing linux compiled testsuite64 in Windows HOT 22
- Provide default code formatting with a .clang-format HOT 1
- Windows system calls need improvement HOT 2
- Flat memory mode HOT 2
- Expand compressed instructions for fastsim HOT 1
- Move away from PC+/-4 to save some computations in faster modes HOT 2
- Binary translation should translate whole binary HOT 11
- Bytecode simulation HOT 2
- Binary translation doesn't always work with fastsim HOT 1
- Two potential performance improvements HOT 1
- Optionally avoid creating new execute segment HOT 1
- Go HTTP client panics
- Instruction counting wrong for compressed HOT 1
- Road to 1.0
- Question: getting system call arguments dynamically and simulating hardware? HOT 5
- Finish B-extension support HOT 3
- Detect computed goto HOT 1
- MSVC compatibility HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from libriscv.