-
-
Notifications
You must be signed in to change notification settings - Fork 232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Running executables from a Debian chroot #68
Comments
I probably need to add "error" and "__overflow" wrapped function to Box86 (error is a bit tricky, but __overflow is a trivial "iFpi" function). |
FYI, I have added the 2 missing function in the Dynarec branch. |
Thanks. du doesn't work:
glxgears runs at native speed (with vblank_mode=0 to disable vsync).
The terrain bench crashes with SIGILL in jpeg_CreateDecompress:
|
The About glmark2: 90% of native is very good :D \o/. I guess you are using the dynarec to get that number. The jpeg crash, well, that probably a callback that I didn't wrapped. I'll check that back later. |
When running du without logging, I just get:
|
Ah, sounds like a bug in an dynarec opcode. |
I actually wasn't using dynarec - I didn't realise you had to run cmake with -DARM_DYNAREC=1... |
Ah, damn, so that's a bug even in the Interpretor (so glmark2 runing at 90% with the interpretor, glmark is mostly GL code, with very few C code around the tests) |
Also, I should have fixed the crash in |
And I have just pused some changes in COMPILE.md about Dynarec compilation. Be sure to have |
For du, the function that is trying to be logged is openat64. The I recompiled with dynarec, and gzip went from 3.5% of native speed to 25% of native, which is a big improvement. glmark2 now runs at 98% of native speed. When running make in parallel, it doesn't wait for wrapper.h to be built before building files that depend on it, so I have to use EDIT: I recompiled without my patches and du behaves in the same way. |
strace shows that this call is causing the error:
With native du:
|
Ah, nice intel. So the |
and |
The only important one is O_DIRECT, which newer kernels don't like: |
This also happens with
|
It seems the flags are different between architectures so some translation will have to be done. |
These are the differences:
So the O_DIRECTORY flag on x86 is the O_DIRECT flag on arm. This could be fixed with something like (untested):
for all the functions using these flags, maybe by adding an "I/O flag type" for the wrapper functions. |
Wow, nice debug. Thanks a lot! |
I think only the open.* functions need fixing, everything else should be fine. |
So, I tried to a push a first workarournd with commit aad4c91 I'll try to get a more portable solution later. |
So, did you just grep for functions taking flags? Most of these flag types are unrelated. Also, they aren't AT_ flags, they're file open flags - maybe you got mixed up with the first field of openat, which can be an AT_ flag. du does at least somewhat work, but does crash with |
bah yeah, I somewhat looked for "at" function using flags. I'll recheck what flags it is, maybe I was a bit too fast :( |
diff --git a/rebuild_wrappers.py b/rebuild_wrappers.py
index c037a83..042956d 100755
--- a/rebuild_wrappers.py
+++ b/rebuild_wrappers.py
@@ -4,7 +4,7 @@ import os
import glob
import sys
-values = ['E', 'e', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'L', 'p', 'V']
+values = ['E', 'e', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'L', 'p', 'V', 'O']
def splitchar(s):
ret = [len(s)]
i = 0
@@ -226,6 +226,11 @@ typedef union ui64_s {
#else
#define ST0val ST0.d
#endif
+#ifndef NOALIGN
+int oflag_convert(int flag) { return (flag&~0740000) + (flag&0140000)*4 + (flag&0600000)/4; }
+#else
+int oflag_convert(int flag) { return flag; }
+#endif
""",
"wrapper.h": """/*****************************************************************
@@ -249,6 +254,7 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
// o = stdout
// C = unsigned byte c = char
// W = unsigned short w = short
+// O = file open flag
// Q = ...
// S8 = struct, 8 bytes
@@ -292,8 +298,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
# First part: typedefs
for v in gbl["()"]:
- # E e v c w i I C W u U f d D L p V
- types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "void*", "void*"]
+ # E e v c w i I C W u U f d D L p V O
+ types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "void*", "void*", "int32_t"]
if len(values) != len(types):
raise NotImplementedError("len(values) = {lenval} != len(types) = {lentypes}".format(lenval=len(values), lentypes=len(types)))
@@ -303,8 +309,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
if k != "()":
file.write("\n#if " + k + "\n")
for v in gbl[k]:
- # E e v c w i I C W u U f d D L p V
- types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "void*", "void*"]
+ # E e v c w i I C W u U f d D L p V O
+ types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "void*", "void*", "int32_t"]
if len(values) != len(types):
raise NotImplementedError("len(values) = {lenval} != len(types) = {lentypes}".format(lenval=len(values), lentypes=len(types)))
@@ -344,10 +350,11 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
"*(long double*)(R_ESP + {p}), ", # D
"FromLD((void*)(R_ESP + {p})), ", # L
"*(void**)(R_ESP + {p}), ", # p
- "(void*)(R_ESP + {p}), " # V
+ "(void*)(R_ESP + {p}), ", # V
+ "oflag_convert(*(int32_t*)(R_ESP + {p})), ", # O
]
- # E e v c w i I C W u U f d D L p V
- deltas = [0, 0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 0]
+ # E e v c w i I C W u U f d D L p V O
+ deltas = [0, 0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 0, 4]
if len(values) != len(arg):
raise NotImplementedError("len(values) = {lenval} != len(arg) = {lenarg}".format(lenval=len(values), lenarg=len(arg)))
if len(values) != len(deltas):
@@ -374,6 +381,7 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # L
"R_EAX=(uintptr_t)fn({0});", # p
"\n#error Invalid return type: va_list\n", # V
+ "\n#error Invalid return type: oflag\n", # O
]
if len(values) != len(vals):
raise NotImplementedError("len(values) = {lenval} != len(vals) = {lenvals}".format(lenval=len(values), lenvals=len(vals)))
diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h
index 79562ec..150eaa6 100755
--- a/src/wrapped/wrappedlibc_private.h
+++ b/src/wrapped/wrappedlibc_private.h
@@ -1188,15 +1188,15 @@ GO(_obstack_newchunk, vFpi)
GOM(obstack_vprintf, iFEppVV) // Weak
// __obstack_vprintf_chk
// on_exit // Weak
-GOM(open, iFEpiu) //Weak
-GOM(__open, iFEpiu) //Weak
-GO(__open_2, iFpi)
-GOM(open64, iFEpiu) //Weak
+GOM(open, iFEpOu) //Weak
+GOM(__open, iFEpOu) //Weak
+GO(__open_2, iFpO)
+GOM(open64, iFEpOu) //Weak
// __open64 // Weak
-GO(__open64_2, iFpi)
-GOW(openat, iFipiu)
+GO(__open64_2, iFpO)
+GOW(openat, iFipOu)
// __openat_2
-GOW(openat64, iFipiuuuuu) // variable arg...
+GOW(openat64, iFipOuuuuu) // variable arg...
// __openat64_2
// __open_catalog
GOW(opendir, pFp)
|
Ah oops, I didn't saw your post and did ... just like you :) ! |
Rather than do |
I did an |
My way is faster, though: #include <iostream>
#include <chrono>
int arith(int flag) {
return (flag&~0740000) + (flag&0140000)*4 + (flag&0600000)/4;
}
int log(int flag) {
return (flag&~0740000) | ((flag&0140000)<<2) | ((flag&0600000)>>2);
}
int main()
{
for (int i = 0; i < 11; ++i)
{
for (auto& x : {arith, log})
{
unsigned p = 0;
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < 200000000; ++i)
p += x(i);
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
if (i)
std::cout << p << " elapsed time: " << elapsed_seconds.count() << "s\n";
}
}
}
You can say "broken compiler" all you want, but at least for current compilers, using arithmetic operators is over 10% faster. |
Oh, that's a bit surprising. And has you can see, the artimetic as 1 instruction more.
in the addition pus a left shift (the *4)
So yeah, compiler optimisation issue, it could have use the same trick and do an Anyway, why I stick to Logic is not for speed (that not really important there), but for safety. As you have already seen, I do A LOT of mistakes... And applying 2 times the same flags (by mistake) with a OR is harmless, while with an ADD, it's not the same ending flag at all. |
With this patch, another one to force logging to /dev/null and some more wrapped functions, I can use proot to get an emulated shell working: diff --git a/src/main.c b/src/main.c
index 88bb131..4289d95 100755
--- a/src/main.c
+++ b/src/main.c
@@ -271,6 +272,10 @@ void PrintHelp() {
}
int main(int argc, const char **argv, const char **env) {
+ if(argc > 1 && !strcmp(argv[1], "-E")) {
+ argv += 4;
+ argc -= 4;
+ }
// trying to open and load 1st arg
if(argc==1) {
|
For the logging, why not using the env var BOX86_LOG=0? Do you want your argc/argv patch to be merge? A chroot is interesting :) What function did you had to wrap? |
proot doesn't seem to pass environment variables to box86 properly. The argv/argc patch should probably be fixed by adding an option to proot to not prepend command-line options that would be used by qemu.
If I execute it manually with bash, or dash and a shell option, it works:
I've attached a patch with the extra functions I have wrapped: |
Do you mind if I push your wrappers in? |
That's why I've posted them. |
Great, thanks. It's done. |
I think this ticket can be closed now! |
I've tried running some executables from a first-stage bootstrapped i386 Debian chroot created using this script.
However, most programs give errors like these:
I tried commenting out libc from library_list.h, but then I get these errors:
(With a wrapped libc.so, many programs can display their help text, and quite a few, such as cat, sort, gzip, dd, env, sleep and dmesg do work.)
The text was updated successfully, but these errors were encountered: