forked from M-Labs/artiq
llvm_ir: fixed stack leak on ffi call
This commit is contained in:
parent
f89275b02a
commit
a289d69883
|
@ -1359,11 +1359,24 @@ class LLVMIRGenerator:
|
||||||
else:
|
else:
|
||||||
llfun = self.map(insn.static_target_function)
|
llfun = self.map(insn.static_target_function)
|
||||||
llenv = self.llbuilder.extract_value(llclosure, 0, name="env.fun")
|
llenv = self.llbuilder.extract_value(llclosure, 0, name="env.fun")
|
||||||
return llfun, [llenv] + list(llargs), {}
|
return llfun, [llenv] + list(llargs), {}, None
|
||||||
|
|
||||||
def _prepare_ffi_call(self, insn):
|
def _prepare_ffi_call(self, insn):
|
||||||
llargs = []
|
llargs = []
|
||||||
llarg_attrs = {}
|
llarg_attrs = {}
|
||||||
|
|
||||||
|
stack_save_needed = False
|
||||||
|
for i, arg in enumerate(insn.arguments()):
|
||||||
|
llarg = self.map(arg)
|
||||||
|
if isinstance(llarg.type, (ll.LiteralStructType, ll.IdentifiedStructType)):
|
||||||
|
stack_save_needed = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if stack_save_needed:
|
||||||
|
llcallstackptr = self.llbuilder.call(self.llbuiltin("llvm.stacksave"), [])
|
||||||
|
else:
|
||||||
|
llcallstackptr = None
|
||||||
|
|
||||||
for i, arg in enumerate(insn.arguments()):
|
for i, arg in enumerate(insn.arguments()):
|
||||||
llarg = self.map(arg)
|
llarg = self.map(arg)
|
||||||
if isinstance(llarg.type, (ll.LiteralStructType, ll.IdentifiedStructType)):
|
if isinstance(llarg.type, (ll.LiteralStructType, ll.IdentifiedStructType)):
|
||||||
|
@ -1399,7 +1412,7 @@ class LLVMIRGenerator:
|
||||||
if 'nowrite' in insn.target_function().type.flags:
|
if 'nowrite' in insn.target_function().type.flags:
|
||||||
llfun.attributes.add('inaccessiblememonly')
|
llfun.attributes.add('inaccessiblememonly')
|
||||||
|
|
||||||
return llfun, list(llargs), llarg_attrs
|
return llfun, list(llargs), llarg_attrs, llcallstackptr
|
||||||
|
|
||||||
def _build_rpc(self, fun_loc, fun_type, args, llnormalblock, llunwindblock):
|
def _build_rpc(self, fun_loc, fun_type, args, llnormalblock, llunwindblock):
|
||||||
llservice = ll.Constant(lli32, fun_type.service)
|
llservice = ll.Constant(lli32, fun_type.service)
|
||||||
|
@ -1535,9 +1548,9 @@ class LLVMIRGenerator:
|
||||||
insn.arguments(),
|
insn.arguments(),
|
||||||
llnormalblock=None, llunwindblock=None)
|
llnormalblock=None, llunwindblock=None)
|
||||||
elif types.is_external_function(functiontyp):
|
elif types.is_external_function(functiontyp):
|
||||||
llfun, llargs, llarg_attrs = self._prepare_ffi_call(insn)
|
llfun, llargs, llarg_attrs, llcallstackptr = self._prepare_ffi_call(insn)
|
||||||
else:
|
else:
|
||||||
llfun, llargs, llarg_attrs = self._prepare_closure_call(insn)
|
llfun, llargs, llarg_attrs, llcallstackptr = self._prepare_closure_call(insn)
|
||||||
|
|
||||||
if self.has_sret(functiontyp):
|
if self.has_sret(functiontyp):
|
||||||
llstackptr = self.llbuilder.call(self.llbuiltin("llvm.stacksave"), [])
|
llstackptr = self.llbuilder.call(self.llbuiltin("llvm.stacksave"), [])
|
||||||
|
@ -1556,6 +1569,9 @@ class LLVMIRGenerator:
|
||||||
# {} elsewhere.
|
# {} elsewhere.
|
||||||
llresult = ll.Constant(llunit, [])
|
llresult = ll.Constant(llunit, [])
|
||||||
|
|
||||||
|
if llcallstackptr != None:
|
||||||
|
self.llbuilder.call(self.llbuiltin("llvm.stackrestore"), [llcallstackptr])
|
||||||
|
|
||||||
return llresult
|
return llresult
|
||||||
|
|
||||||
def process_Invoke(self, insn):
|
def process_Invoke(self, insn):
|
||||||
|
|
Loading…
Reference in New Issue