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