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