xref: /freebsd/sys/tools/syscalls/core/syscall.lua (revision bbc0f33b1317bb922ff3d960216ce7b4af88b8af)
19ded074eSagge3--
29ded074eSagge3-- SPDX-License-Identifier: BSD-2-Clause
39ded074eSagge3--
49ded074eSagge3-- Copyright (c) 2024 Tyler Baxter <agge@FreeBSD.org>
59ded074eSagge3-- Copyright (c) 2023 Warner Losh <imp@bsdimp.com>
69ded074eSagge3-- Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org>
79ded074eSagge3--
89ded074eSagge3
99ded074eSagge3local config = require("config")
109ded074eSagge3local scarg = require("core.scarg")
119ded074eSagge3local scret = require("core.scret")
129ded074eSagge3local util = require("tools.util")
139ded074eSagge3
149ded074eSagge3local syscall = {}
159ded074eSagge3
169ded074eSagge3syscall.__index = syscall
179ded074eSagge3
189ded074eSagge3syscall.known_flags = util.set {
199ded074eSagge3	"STD",
209ded074eSagge3	"OBSOL",
219ded074eSagge3	"RESERVED",
229ded074eSagge3	"UNIMPL",
239ded074eSagge3	"NODEF",
249ded074eSagge3	"NOARGS",
259ded074eSagge3	"NOPROTO",
269ded074eSagge3	"NOSTD",
272ea829e3SBrooks Davis
282ea829e3SBrooks Davis	-- flags beyond this point are modifiers
299ded074eSagge3	"CAPENABLED",
30*bbc0f33bSBrooks Davis	"NOLIB",
312ea829e3SBrooks Davis	"NOTSTATIC",
329ded074eSagge3	"SYSMUX",
339ded074eSagge3}
349ded074eSagge3
359ded074eSagge3-- Native is an arbitrarily large number to have a constant and not
369ded074eSagge3-- interfere with compat numbers.
379ded074eSagge3local native = 1000000
389ded074eSagge3
399ded074eSagge3-- Processes and assigns the appropriate thread flag for this system call.
409ded074eSagge3function syscall:processThr()
419ded074eSagge3	self.thr = "SY_THR_STATIC"
429ded074eSagge3	for k, _ in pairs(self.type) do
439ded074eSagge3		if k == "NOTSTATIC" then
449ded074eSagge3			self.thr = "SY_THR_ABSENT"
459ded074eSagge3		end
469ded074eSagge3	end
479ded074eSagge3end
489ded074eSagge3
499ded074eSagge3-- Processes and assigns the appropriate capability flag for this system call.
509ded074eSagge3-- "SYF_CAPENABLED" for capability enabled; "0" for NOT capability enabled.
519ded074eSagge3function syscall:processCap()
529ded074eSagge3	self.cap = "0"
539ded074eSagge3	local stripped = util.stripAbiPrefix(self.name, self.prefix)
549ded074eSagge3	for k, _ in pairs(self.type) do
559ded074eSagge3		if k == "CAPENABLED" then
569ded074eSagge3			self.cap = "SYF_CAPENABLED"
579ded074eSagge3		end
589ded074eSagge3	end
599ded074eSagge3end
609ded074eSagge3
619ded074eSagge3-- Check that this system call has a known type.
629ded074eSagge3local function checkType(type)
639ded074eSagge3	for k, _ in pairs(type) do
649ded074eSagge3		if not syscall.known_flags[k] and not
659ded074eSagge3			k:match("^COMPAT") then
669ded074eSagge3			util.abort(1, "Bad type: " .. k)
679ded074eSagge3		end
689ded074eSagge3	end
699ded074eSagge3end
709ded074eSagge3
719ded074eSagge3-- If there are ABI changes from native, process this system call to match the
729ded074eSagge3-- target ABI.
739ded074eSagge3function syscall:processChangesAbi()
749ded074eSagge3	-- First, confirm we want to uphold our changes_abi flag.
759ded074eSagge3	if config.syscall_no_abi_change[self.name] then
769ded074eSagge3		self.changes_abi = false
779ded074eSagge3	end
789ded074eSagge3	self.noproto = not util.isEmpty(config.abi_flags) and
799ded074eSagge3	    not self.changes_abi
809ded074eSagge3	if config.abiChanges("pointer_args") then
819ded074eSagge3		for _, v in ipairs(self.args) do
829ded074eSagge3			if util.isPtrType(v.type, config.abi_intptr_t) then
839ded074eSagge3				if config.syscall_no_abi_change[self.name] then
849ded074eSagge3					print("WARNING: " .. self.name ..
859ded074eSagge3					    " in syscall_no_abi_change, " ..
869ded074eSagge3					    "but pointers args are present")
879ded074eSagge3				end
889ded074eSagge3				self.changes_abi = true
899ded074eSagge3				goto ptrfound
909ded074eSagge3			end
919ded074eSagge3		end
929ded074eSagge3		::ptrfound::
939ded074eSagge3	end
949ded074eSagge3	if config.syscall_abi_change[self.name] then
959ded074eSagge3		self.changes_abi = true
969ded074eSagge3	end
979ded074eSagge3	if self.changes_abi then
989ded074eSagge3		self.noproto = false
999ded074eSagge3	end
1009ded074eSagge3end
1019ded074eSagge3
1029ded074eSagge3-- Final processing of flags. Process any flags that haven't already been
1039ded074eSagge3-- processed (e.g., dictionaries from syscalls.conf).
1049ded074eSagge3function syscall:processFlags()
1059ded074eSagge3	if config.obsol[self.name] or (self:compatLevel() > 0 and
1069ded074eSagge3	    self:compatLevel() < tonumber(config.mincompat)) then
1079ded074eSagge3		self.args = nil
1089ded074eSagge3		self.type.OBSOL = true
1099ded074eSagge3		-- Don't apply any ABI handling, declared as obsolete.
1109ded074eSagge3		self.changes_abi = false
1119ded074eSagge3	end
1129ded074eSagge3	if config.unimpl[self.name] then
1139ded074eSagge3		self.type.UNIMPL = true
1149ded074eSagge3	end
1159ded074eSagge3	if self.noproto or self.type.SYSMUX then
1169ded074eSagge3		self.type.NOPROTO = true
1179ded074eSagge3	end
1189ded074eSagge3	if self.type.NODEF then
1199ded074eSagge3		self.audit = "AUE_NULL"
1209ded074eSagge3	end
1219ded074eSagge3end
1229ded074eSagge3
1239ded074eSagge3-- Returns TRUE if prefix and arg_prefix are assigned; FALSE if they're left
1249ded074eSagge3-- unassigned.  Relies on a valid changes_abi flag, so should be called AFTER
1259ded074eSagge3-- processChangesAbi().
1269ded074eSagge3function syscall:processPrefix()
1279ded074eSagge3	-- If there are ABI changes from native, assign the correct prefixes.
1289ded074eSagge3	if self.changes_abi then
1299ded074eSagge3		self.arg_prefix = config.abi_func_prefix
1309ded074eSagge3		self.prefix = config.abi_func_prefix
1319ded074eSagge3		return true
1329ded074eSagge3	end
1339ded074eSagge3	return false
1349ded074eSagge3end
1359ded074eSagge3
1369ded074eSagge3-- Validate that we're not skipping system calls by comparing this system call
1379ded074eSagge3-- number to the previous system call number.  Called higher up the call stack
1389ded074eSagge3-- by class FreeBSDSyscall.
1399ded074eSagge3function syscall:validate(prev)
1409ded074eSagge3	return prev + 1 == self.num
1419ded074eSagge3end
1429ded074eSagge3
1439ded074eSagge3-- Return the compat prefix for this system call.
1449ded074eSagge3function syscall:compatPrefix()
1459ded074eSagge3	local c = self:compatLevel()
1469ded074eSagge3	if self.type.OBSOL then
1479ded074eSagge3		return "obs_"
1489ded074eSagge3	end
1499ded074eSagge3	if self.type.RESERVED then
1509ded074eSagge3		return "reserved #"
1519ded074eSagge3	end
1529ded074eSagge3	if self.type.UNIMPL then
1539ded074eSagge3		return "unimp_"
1549ded074eSagge3	end
1559ded074eSagge3	if c == 3 then
1569ded074eSagge3		return "o"
1579ded074eSagge3	end
1589ded074eSagge3	if c < native then
1599ded074eSagge3		return "freebsd" .. tostring(c) .. "_"
1609ded074eSagge3	end
1619ded074eSagge3	return ""
1629ded074eSagge3end
1639ded074eSagge3
1649ded074eSagge3-- Return the symbol name for this system call.
1659ded074eSagge3function syscall:symbol()
1669ded074eSagge3	return self:compatPrefix() .. self.name
1679ded074eSagge3end
1689ded074eSagge3
1699ded074eSagge3--
1709ded074eSagge3-- Return the compatibility level for this system call.
1719ded074eSagge3-- 	0 is obsolete.
1729ded074eSagge3-- 	< 0 is this isn't really a system call we care about.
1739ded074eSagge3-- 	3 is 4.3BSD in theory, but anything before FreeBSD 4.
1749ded074eSagge3-- 	>= 4 is FreeBSD version, this system call was replaced with a new
1759ded074eSagge3-- 	    version.
1769ded074eSagge3--
1779ded074eSagge3function syscall:compatLevel()
1789ded074eSagge3	if self.type.UNIMPL or self.type.RESERVED then
1799ded074eSagge3		return -1
1809ded074eSagge3	elseif self.type.OBSOL then
1819ded074eSagge3		return 0
1829ded074eSagge3	elseif self.type.COMPAT then
1839ded074eSagge3		return 3
1849ded074eSagge3	end
1859ded074eSagge3	for k, _ in pairs(self.type) do
1869ded074eSagge3		local l = k:match("^COMPAT(%d+)")
1879ded074eSagge3		if l ~= nil then
1889ded074eSagge3			return tonumber(l)
1899ded074eSagge3		end
1909ded074eSagge3	end
1919ded074eSagge3	return native
1929ded074eSagge3end
1939ded074eSagge3
1949ded074eSagge3-- Adds the definition for this system call. Guarded by whether we already have
1959ded074eSagge3-- a system call number or not.
1969ded074eSagge3function syscall:addDef(line)
1979ded074eSagge3	if self.num == nil then
1989ded074eSagge3		local words = util.split(line, "%S+")
1999ded074eSagge3		self.num = words[1]
2009ded074eSagge3		self.audit = words[2]
2019ded074eSagge3		self.type = util.setFromString(words[3], "[^|]+")
2029ded074eSagge3		checkType(self.type)
2039ded074eSagge3		self.name = words[4]
2049ded074eSagge3		-- These next three are optional, and either all present
2059ded074eSagge3		-- or all absent.
2069ded074eSagge3		self.altname = words[5]
2079ded074eSagge3		self.alttag = words[6]
2089ded074eSagge3		self.rettype = words[7]
2099ded074eSagge3		return true
2109ded074eSagge3	end
2119ded074eSagge3	return false
2129ded074eSagge3end
2139ded074eSagge3
2149ded074eSagge3-- Adds the function declaration for this system call. If addDef() found an
2159ded074eSagge3-- opening curly brace, then we're looking for a function declaration.
2169ded074eSagge3function syscall:addFunc(line)
2179ded074eSagge3	if self.name == "{" then
2189ded074eSagge3		local words = util.split(line, "%S+")
2199ded074eSagge3		-- Expect line is `type syscall(` or `type syscall(void);`.
2209ded074eSagge3		if #words ~= 2 then
2219ded074eSagge3			util.abort(1, "Malformed line " .. line)
2229ded074eSagge3		end
2239ded074eSagge3
2249ded074eSagge3		local ret = scret:new({}, line)
2259ded074eSagge3		self.ret = ret:add()
2269ded074eSagge3		-- Don't clobber rettype set in the alt information.
2279ded074eSagge3		if self.rettype == nil then
2289ded074eSagge3			self.rettype = "int"
2299ded074eSagge3		end
2309ded074eSagge3
2319ded074eSagge3		self.name = words[2]:match("([%w_]+)%(")
2329ded074eSagge3		if words[2]:match("%);$") then
2339ded074eSagge3			-- Now we're looking for ending curly brace.
2349ded074eSagge3			self.expect_rbrace = true
2359ded074eSagge3		end
2369ded074eSagge3		return true
2379ded074eSagge3	end
2389ded074eSagge3	return false
2399ded074eSagge3end
2409ded074eSagge3
2419ded074eSagge3-- Adds the argument(s) for this system call. Once addFunc() assigns a name
2429ded074eSagge3-- for this system call, arguments are next in syscalls.master.
2439ded074eSagge3function syscall:addArgs(line)
2449ded074eSagge3	if not self.expect_rbrace then
2459ded074eSagge3		if line:match("%);$") then
2469ded074eSagge3			self.expect_rbrace = true
2479ded074eSagge3			return true
2489ded074eSagge3		end
2499ded074eSagge3		local arg = scarg:new({}, line)
2509ded074eSagge3		-- We don't want to add this argument if it doesn't process.
2519ded074eSagge3		-- scarg:process() handles those conditions.
2529ded074eSagge3		if arg:process() then
2539ded074eSagge3			arg:append(self.args)
2549ded074eSagge3		end
2559ded074eSagge3		-- If this argument has ABI changes, set globally for this
2569ded074eSagge3		-- system call.
2579ded074eSagge3		self.changes_abi = self.changes_abi or arg:changesAbi()
2589ded074eSagge3		return true
2599ded074eSagge3	end
2609ded074eSagge3	return false
2619ded074eSagge3end
2629ded074eSagge3
2639ded074eSagge3-- Once we have a good syscall, add some final information to it.
2649ded074eSagge3function syscall:finalize()
2659ded074eSagge3	if self.name == nil then
2669ded074eSagge3		self.name = ""
2679ded074eSagge3	end
2689ded074eSagge3
2699ded074eSagge3	-- Preserve the original name as the alias.
2709ded074eSagge3	self.alias = self.name
2719ded074eSagge3
2729ded074eSagge3	self:processChangesAbi()	-- process changes to the ABI
2739ded074eSagge3	self:processFlags()		-- process any unprocessed flags
2749ded074eSagge3
2759ded074eSagge3	-- If there's changes to the ABI, these prefixes will be changed by
2769ded074eSagge3	-- processPrefix(); otherwise, they'll remain empty.
2779ded074eSagge3	self.prefix = ""
2789ded074eSagge3	self.arg_prefix = ""
2799ded074eSagge3	self:processPrefix()
2809ded074eSagge3
2819ded074eSagge3	self:processCap()	-- capability flag
2829ded074eSagge3	self:processThr()	-- thread flag
2839ded074eSagge3
2849ded074eSagge3	-- Assign argument alias.
2859ded074eSagge3	if self.alttag ~= nil then
2869ded074eSagge3		self.arg_alias = self.alttag
2879ded074eSagge3	elseif self.arg_alias == nil and self.name ~= nil then
2889ded074eSagge3		-- argalias should be:
2899ded074eSagge3		--   COMPAT_PREFIX + ABI Prefix + funcname
2909ded074eSagge3		self.arg_alias = self:compatPrefix() .. self.arg_prefix ..
2919ded074eSagge3		    self.name .. "_args"
2929ded074eSagge3	elseif self.arg_alias ~= nil then
2939ded074eSagge3		self.arg_alias = self.arg_prefix .. self.arg_alias
2949ded074eSagge3	end
2959ded074eSagge3
2969ded074eSagge3	-- An empty string would not want a prefix; the entry doesn't have
2979ded074eSagge3	-- a name so we want to keep the empty string.
2989ded074eSagge3	if self.name ~= nil and self.name ~= "" then
2999ded074eSagge3		self.name = self.prefix .. self.name
3009ded074eSagge3	end
3019ded074eSagge3
3029ded074eSagge3	self:processArgstrings()
3039ded074eSagge3	self:processArgsize()
3049ded074eSagge3end
3059ded074eSagge3
3069ded074eSagge3-- Assigns the correct args_size. Defaults to "0", except if there's arguments
3079ded074eSagge3-- or NODEF flag.
3089ded074eSagge3function syscall:processArgsize()
3099ded074eSagge3	if self.type.SYSMUX then	-- catch this first
3109ded074eSagge3		self.args_size = "0"
3119ded074eSagge3	elseif self.arg_alias ~= nil and
3129ded074eSagge3	    (#self.args ~= 0 or self.type.NODEF) then
3139ded074eSagge3		self.args_size = "AS(" .. self.arg_alias .. ")"
3149ded074eSagge3	else
3159ded074eSagge3		self.args_size = "0"
3169ded074eSagge3	end
3179ded074eSagge3end
3189ded074eSagge3
3199ded074eSagge3-- Constructs argstr_* strings for generated declerations/wrappers.
3209ded074eSagge3function syscall:processArgstrings()
3219ded074eSagge3	local type = ""
3229ded074eSagge3	local type_var = ""
3239ded074eSagge3	local var = ""
3249ded074eSagge3	local comma = ""
3259ded074eSagge3
3269ded074eSagge3	for _, v in ipairs(self.args) do
3279ded074eSagge3		local argname, argtype = v.name, v.type
3289ded074eSagge3		type = type .. comma .. argtype
3299ded074eSagge3		type_var = type_var .. comma .. argtype ..  " " .. argname
3309ded074eSagge3		var = var .. comma .. argname
3319ded074eSagge3		comma = ", "
3329ded074eSagge3	end
3339ded074eSagge3	if type == "" then
3349ded074eSagge3		type = "void"
3359ded074eSagge3		type_var = "void"
3369ded074eSagge3	end
3379ded074eSagge3
3389ded074eSagge3	self.argstr_type = type
3399ded074eSagge3	self.argstr_type_var = type_var
3409ded074eSagge3	self.argstr_var = var
3419ded074eSagge3end
3429ded074eSagge3
3439ded074eSagge3-- Interface to add this system call to the master system call table.
3449ded074eSagge3-- The system call is built up one line at a time. The states describe the
3459ded074eSagge3-- current parsing state.
3469ded074eSagge3-- Returns TRUE when ready to add and FALSE while still parsing.
3479ded074eSagge3function syscall:add(line)
3489ded074eSagge3	if self:addDef(line) then
3499ded074eSagge3		return self:isAdded(line)
3509ded074eSagge3	end
3519ded074eSagge3	if self:addFunc(line) then
3529ded074eSagge3		return false -- Function added; keep going.
3539ded074eSagge3	end
3549ded074eSagge3	if self:addArgs(line) then
3559ded074eSagge3		return false -- Arguments added; keep going.
3569ded074eSagge3	end
3579ded074eSagge3	return self:isAdded(line) -- Final validation, before adding.
3589ded074eSagge3end
3599ded074eSagge3
3609ded074eSagge3-- Returns TRUE if this system call was succesfully added. There's two entry
3619ded074eSagge3-- points to this function: (1) the entry in syscalls.master is one-line, or
3629ded074eSagge3-- (2) the entry is a full system call. This function handles those cases and
3639ded074eSagge3-- decides whether to exit early for (1) or validate a full system call for
3649ded074eSagge3-- (2).  This function also handles cases where we don't want to add, and
3659ded074eSagge3-- instead want to abort.
3669ded074eSagge3function syscall:isAdded(line)
3679ded074eSagge3	-- This system call is a range - exit early.
3689ded074eSagge3	if tonumber(self.num) == nil then
3699ded074eSagge3		-- The only allowed types are RESERVED and UNIMPL.
3709ded074eSagge3		if not (self.type.RESERVED or self.type.UNIMPL) then
3719ded074eSagge3			util.abort(1, "Range only allowed with RESERVED " ..
3729ded074eSagge3			    "and UNIMPL: " ..  line)
3739ded074eSagge3		end
3749ded074eSagge3		self:finalize()
3759ded074eSagge3		return true
3769ded074eSagge3	-- This system call is a loadable system call - exit early.
3779ded074eSagge3	elseif self.altname ~= nil and self.alttag ~= nil and
3789ded074eSagge3		   self.rettype ~= nil then
3799ded074eSagge3		self:finalize()
3809ded074eSagge3		return true
3819ded074eSagge3	-- This system call is only one line, and should only be one line
3829ded074eSagge3	-- (we didn't make it to addFunc()) - exit early.
3839ded074eSagge3	elseif self.name ~= "{"  and self.ret == nil then
3849ded074eSagge3		self:finalize()
3859ded074eSagge3		return true
3869ded074eSagge3	-- This is a full system call and we've passed multiple states to
3879ded074eSagge3	-- get here - final exit.
3889ded074eSagge3	elseif self.expect_rbrace then
3899ded074eSagge3		if not line:match("}$") then
3909ded074eSagge3			util.abort(1, "Expected '}' found '" .. line ..
3919ded074eSagge3			    "' instead.")
3929ded074eSagge3		end
3939ded074eSagge3		self:finalize()
3949ded074eSagge3		return true
3959ded074eSagge3	end
3969ded074eSagge3	return false
3979ded074eSagge3end
3989ded074eSagge3
3999ded074eSagge3-- Return TRUE if this system call is native.
4009ded074eSagge3function syscall:native()
4019ded074eSagge3	return self:compatLevel() == native
4029ded074eSagge3end
4039ded074eSagge3
4049ded074eSagge3-- Make a shallow copy of `self` and replace the system call number with num
4059ded074eSagge3-- (which should be a number).
4069ded074eSagge3-- For system call ranges.
4079ded074eSagge3function syscall:shallowCopy(num)
4089ded074eSagge3	local obj = syscall:new()
4099ded074eSagge3
4109ded074eSagge3	-- shallow copy
4119ded074eSagge3	for k, v in pairs(self) do
4129ded074eSagge3		obj[k] = v
4139ded074eSagge3	end
4149ded074eSagge3	obj.num = num	-- except override range
4159ded074eSagge3	return obj
4169ded074eSagge3end
4179ded074eSagge3
4189ded074eSagge3-- Make a deep copy of the parameter object. Save copied tables in `copies`,
4199ded074eSagge3-- indexed by original table.
4209ded074eSagge3-- CREDIT: http://lua-users.org/wiki/CopyTable
4219ded074eSagge3-- For a full system call (the nested arguments table should be a deep copy).
4229ded074eSagge3local function deepCopy(orig, copies)
4239ded074eSagge3	copies = copies or {}
4249ded074eSagge3	local orig_type = type(orig)
4259ded074eSagge3	local copy
4269ded074eSagge3	if orig_type == 'table' then
4279ded074eSagge3		if copies[orig] then
4289ded074eSagge3			copy = copies[orig]
4299ded074eSagge3		else
4309ded074eSagge3			copy = {}
4319ded074eSagge3			copies[orig] = copy
4329ded074eSagge3			for orig_key, orig_value in next, orig, nil do
4339ded074eSagge3				copy[deepCopy(orig_key, copies)] =
4349ded074eSagge3				    deepCopy(orig_value, copies)
4359ded074eSagge3			end
4369ded074eSagge3			setmetatable(copy, deepCopy(getmetatable(orig), copies))
4379ded074eSagge3		end
4389ded074eSagge3	else -- number, string, boolean, etc
4399ded074eSagge3		copy = orig
4409ded074eSagge3	end
4419ded074eSagge3	return copy
4429ded074eSagge3end
4439ded074eSagge3
4449ded074eSagge3--
4459ded074eSagge3-- In syscalls.master, system calls come in two types: (1) a fully defined
4469ded074eSagge3-- system call with function declaration, with a distinct number for each system
4479ded074eSagge3-- call; or (2) a one-line entry, sometimes with a distinct number and sometimes
4489ded074eSagge3-- with a range of numbers. One-line entries can be obsolete, reserved, no
4499ded074eSagge3-- definition, etc. Ranges are only allowed for reserved and unimplemented.
4509ded074eSagge3--
4519ded074eSagge3-- This function provides the iterator to traverse system calls by number. If
4529ded074eSagge3-- the entry is a fully defined system call with a distinct number, the iterator
4539ded074eSagge3-- creates a deep copy and captures any nested objects; if the entry is a range
4549ded074eSagge3-- of numbers, the iterator creates shallow copies from the start of the range
4559ded074eSagge3-- to the end of the range.
4569ded074eSagge3--
4579ded074eSagge3function syscall:iter()
4589ded074eSagge3	local s = tonumber(self.num)
4599ded074eSagge3	local e
4609ded074eSagge3	if s == nil then
4619ded074eSagge3		s, e = string.match(self.num, "(%d+)%-(%d+)")
4629ded074eSagge3		s, e = tonumber(s), tonumber(e)
4639ded074eSagge3		return function ()
4649ded074eSagge3			if s <= e then
4659ded074eSagge3				s = s + 1
4669ded074eSagge3				return self:shallowCopy(s - 1)
4679ded074eSagge3			end
4689ded074eSagge3		end
4699ded074eSagge3	else
4709ded074eSagge3		e = s
4719ded074eSagge3		self.num = s	-- Replace string with number, like the clones.
4729ded074eSagge3		return function ()
4739ded074eSagge3			if s == e then
4749ded074eSagge3				local deep_copy = deepCopy(self)
4759ded074eSagge3				s = e + 1
4769ded074eSagge3				return deep_copy
4779ded074eSagge3			end
4789ded074eSagge3		end
4799ded074eSagge3	end
4809ded074eSagge3end
4819ded074eSagge3
4829ded074eSagge3function syscall:new(obj)
4839ded074eSagge3	obj = obj or { }
4849ded074eSagge3	setmetatable(obj, self)
4859ded074eSagge3	self.__index = self
4869ded074eSagge3
4879ded074eSagge3	self.expect_rbrace = false
4889ded074eSagge3	self.changes_abi = false
4899ded074eSagge3	self.args = {}
4909ded074eSagge3	self.noproto = false
4919ded074eSagge3
4929ded074eSagge3	return obj
4939ded074eSagge3end
4949ded074eSagge3
4959ded074eSagge3return syscall
496