Re: Phix+EuGTK
- Posted by petelomax Dec 14, 2020
- 2223 views
4.15.0-54-generic
define_c_proc works when inside a class function, but not when inside a class procedure.
Right. I've now got the same crash (proc not func) on Ubuntu 20.04.1 LTS with a uname -r of 5.4.0-58-generic
building edb...
Some small progress, I think it's this (sort of) thing, from builtins\VM\pcfunc.e, line 308:
[PE64] mov rcx,rsp -- put 2 copies of rsp onto the stack... push rsp push rcx or rsp,8 -- [rsp] is now 1st or 2nd copy: -- if on entry rsp was xxx8: both copies remain on the stack -- if on entry rsp was xxx0: or rsp,8 effectively pops one of them (+8) -- obviously rsp is now xxx8, whatever alignment we started with mov rax,[lib] -- mov r15,h4 sub rsp,8*5 -- minimum 4 param shadow space, and align mov rdx,[name] call :%pLoadMint -- (rax:=(int64)rax; rdx preserved) shl rdx,2 -- lpProcName mov rcx,rax -- hModule call "kernel32.dll","GetProcAddress" lea rdi,[addr] -- add rsp,8*5 -- pop rsp mov rsp,[rsp+8*5] -- equivalent to the add/pop call :%pStoreMint [ELF64] mov rax,[lib] mov rsi,[name] call :%pLoadMint -- (rax:=(int64)rax) shl rsi,2 -- symbol mov rdi,rax -- handle call "libdl.so.2", "dlsym" lea rdi,[addr] call :%pStoreMint []
The windows code is aligning the stack, but the Linux code isn't...
There's a movaps instruction which is expecting the stack to be aligned,
and I guess some kernels were built with whatever-compiler-flag it is
that causes it to emit movups instructions instead. And I originally ported
Phix to Linux on such a machine.
Anyway, it's fixed! The above needs to become
[64] mov rcx,rsp -- put 2 copies of rsp onto the stack... push rsp push rcx or rsp,8 -- [rsp] is now 1st or 2nd copy: -- if on entry rsp was xxx8: both copies remain on the stack -- if on entry rsp was xxx0: or rsp,8 effectively pops one of them (+8) -- obviously rsp is now xxx8, whatever alignment we started with mov rax,[lib] -- mov r15,h4 sub rsp,8*5 -- minimum 4 param shadow space, and align [PE64] mov rdx,[name] call :%pLoadMint -- (rax:=(int64)rax; rdx preserved) shl rdx,2 -- lpProcName mov rcx,rax -- hModule call "kernel32.dll","GetProcAddress" [ELF64] mov rsi,[name] call :%pLoadMint -- (rax:=(int64)rax) shl rsi,2 -- symbol mov rdi,rax -- handle call "libdl.so.2", "dlsym" [64] lea rdi,[addr] -- add rsp,8*5 -- pop rsp mov rsp,[rsp+8*5] -- equivalent to the add/pop call :%pStoreMint []
and further down, also in builtins\VM\pcfunc.e, line 1115, replace
if platform()=WINDOWS then if la<5 then args &= repeat(0,5-la) argdefs &= repeat(#01000004,5-la) elsif remainder(la,2)!=1 then args &= 0 argdefs &= #01000004 -- (C_INT) end if else -- LINUX if la<6 then args &= repeat(0,6-la) argdefs &= repeat(#01000004,6-la) end if end if #ilASM{ [PE64]
with
if platform()=WINDOWS then if la<5 then args &= repeat(0,5-la) argdefs &= repeat(#01000004,5-la) la = 5 end if else -- LINUX -- if la<6 then if la<7 then args &= repeat(0,7-la) argdefs &= repeat(#01000004,7-la) la = 7 end if end if if remainder(la,2)!=1 then args &= 0 argdefs &= #01000004 -- (C_INT) end if #ilASM{ --14/12/20 -- [PE64] [64]
Obviously, a quick './p -c p' and you should be good.
I'll have a quick trawl for other places that need the same treatment.