1*22ce4affSfengbojiang-- 2*22ce4affSfengbojiang-- SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*22ce4affSfengbojiang-- 4*22ce4affSfengbojiang-- Copyright (c) 2019 Kyle Evans <[email protected]> 5*22ce4affSfengbojiang-- 6*22ce4affSfengbojiang-- Redistribution and use in source and binary forms, with or without 7*22ce4affSfengbojiang-- modification, are permitted provided that the following conditions 8*22ce4affSfengbojiang-- are met: 9*22ce4affSfengbojiang-- 1. Redistributions of source code must retain the above copyright 10*22ce4affSfengbojiang-- notice, this list of conditions and the following disclaimer. 11*22ce4affSfengbojiang-- 2. Redistributions in binary form must reproduce the above copyright 12*22ce4affSfengbojiang-- notice, this list of conditions and the following disclaimer in the 13*22ce4affSfengbojiang-- documentation and/or other materials provided with the distribution. 14*22ce4affSfengbojiang-- 15*22ce4affSfengbojiang-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*22ce4affSfengbojiang-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*22ce4affSfengbojiang-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*22ce4affSfengbojiang-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*22ce4affSfengbojiang-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*22ce4affSfengbojiang-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*22ce4affSfengbojiang-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*22ce4affSfengbojiang-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*22ce4affSfengbojiang-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*22ce4affSfengbojiang-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*22ce4affSfengbojiang-- SUCH DAMAGE. 26*22ce4affSfengbojiang-- 27*22ce4affSfengbojiang-- $FreeBSD$ 28*22ce4affSfengbojiang-- 29*22ce4affSfengbojiang 30*22ce4affSfengbojiang 31*22ce4affSfengbojiang-- We generally assume that this script will be run by flua, however we've 32*22ce4affSfengbojiang-- carefully crafted modules for it that mimic interfaces provided by modules 33*22ce4affSfengbojiang-- available in ports. Currently, this script is compatible with lua from ports 34*22ce4affSfengbojiang-- along with the compatible luafilesystem and lua-posix modules. 35*22ce4affSfengbojianglocal lfs = require("lfs") 36*22ce4affSfengbojianglocal unistd = require("posix.unistd") 37*22ce4affSfengbojiang 38*22ce4affSfengbojianglocal savesyscall = -1 39*22ce4affSfengbojianglocal maxsyscall = -1 40*22ce4affSfengbojianglocal generated_tag = "@" .. "generated" 41*22ce4affSfengbojiang 42*22ce4affSfengbojiang-- Default configuration; any of these may get replaced by a configuration file 43*22ce4affSfengbojiang-- optionally specified. 44*22ce4affSfengbojianglocal config = { 45*22ce4affSfengbojiang os_id_keyword = "FreeBSD", 46*22ce4affSfengbojiang abi_func_prefix = "", 47*22ce4affSfengbojiang sysnames = "syscalls.c", 48*22ce4affSfengbojiang sysproto = "../sys/sysproto.h", 49*22ce4affSfengbojiang sysproto_h = "_SYS_SYSPROTO_H_", 50*22ce4affSfengbojiang syshdr = "../sys/syscall.h", 51*22ce4affSfengbojiang sysmk = "../sys/syscall.mk", 52*22ce4affSfengbojiang syssw = "init_sysent.c", 53*22ce4affSfengbojiang syscallprefix = "SYS_", 54*22ce4affSfengbojiang switchname = "sysent", 55*22ce4affSfengbojiang namesname = "syscallnames", 56*22ce4affSfengbojiang systrace = "systrace_args.c", 57*22ce4affSfengbojiang capabilities_conf = "capabilities.conf", 58*22ce4affSfengbojiang capenabled = {}, 59*22ce4affSfengbojiang mincompat = 0, 60*22ce4affSfengbojiang abi_type_suffix = "", 61*22ce4affSfengbojiang abi_flags = "", 62*22ce4affSfengbojiang abi_flags_mask = 0, 63*22ce4affSfengbojiang ptr_intptr_t_cast = "intptr_t", 64*22ce4affSfengbojiang} 65*22ce4affSfengbojiang 66*22ce4affSfengbojianglocal config_modified = {} 67*22ce4affSfengbojianglocal cleantmp = true 68*22ce4affSfengbojianglocal tmpspace = "/tmp/sysent." .. unistd.getpid() .. "/" 69*22ce4affSfengbojiang 70*22ce4affSfengbojianglocal output_files = { 71*22ce4affSfengbojiang "sysnames", 72*22ce4affSfengbojiang "syshdr", 73*22ce4affSfengbojiang "sysmk", 74*22ce4affSfengbojiang "syssw", 75*22ce4affSfengbojiang "systrace", 76*22ce4affSfengbojiang "sysproto", 77*22ce4affSfengbojiang} 78*22ce4affSfengbojiang 79*22ce4affSfengbojiang-- These ones we'll create temporary files for; generation purposes. 80*22ce4affSfengbojianglocal temp_files = { 81*22ce4affSfengbojiang "sysaue", 82*22ce4affSfengbojiang "sysdcl", 83*22ce4affSfengbojiang "syscompat", 84*22ce4affSfengbojiang "syscompatdcl", 85*22ce4affSfengbojiang "sysent", 86*22ce4affSfengbojiang "sysinc", 87*22ce4affSfengbojiang "sysarg", 88*22ce4affSfengbojiang "sysprotoend", 89*22ce4affSfengbojiang "systracetmp", 90*22ce4affSfengbojiang "systraceret", 91*22ce4affSfengbojiang} 92*22ce4affSfengbojiang 93*22ce4affSfengbojiang-- Opened files 94*22ce4affSfengbojianglocal files = {} 95*22ce4affSfengbojiang 96*22ce4affSfengbojianglocal function cleanup() 97*22ce4affSfengbojiang for _, v in pairs(files) do 98*22ce4affSfengbojiang v:close() 99*22ce4affSfengbojiang end 100*22ce4affSfengbojiang if cleantmp then 101*22ce4affSfengbojiang if lfs.dir(tmpspace) then 102*22ce4affSfengbojiang for fname in lfs.dir(tmpspace) do 103*22ce4affSfengbojiang os.remove(tmpspace .. "/" .. fname) 104*22ce4affSfengbojiang end 105*22ce4affSfengbojiang end 106*22ce4affSfengbojiang 107*22ce4affSfengbojiang if lfs.attributes(tmpspace) and not lfs.rmdir(tmpspace) then 108*22ce4affSfengbojiang io.stderr:write("Failed to clean up tmpdir: " .. 109*22ce4affSfengbojiang tmpspace .. "\n") 110*22ce4affSfengbojiang end 111*22ce4affSfengbojiang else 112*22ce4affSfengbojiang io.stderr:write("Temp files left in " .. tmpspace .. "\n") 113*22ce4affSfengbojiang end 114*22ce4affSfengbojiangend 115*22ce4affSfengbojiang 116*22ce4affSfengbojianglocal function abort(status, msg) 117*22ce4affSfengbojiang io.stderr:write(msg .. "\n") 118*22ce4affSfengbojiang cleanup() 119*22ce4affSfengbojiang os.exit(status) 120*22ce4affSfengbojiangend 121*22ce4affSfengbojiang 122*22ce4affSfengbojiang-- Each entry should have a value so we can represent abi flags as a bitmask 123*22ce4affSfengbojiang-- for convenience. One may also optionally provide an expr; this gets applied 124*22ce4affSfengbojiang-- to each argument type to indicate whether this argument is subject to ABI 125*22ce4affSfengbojiang-- change given the configured flags. 126*22ce4affSfengbojianglocal known_abi_flags = { 127*22ce4affSfengbojiang long_size = { 128*22ce4affSfengbojiang value = 0x00000001, 129*22ce4affSfengbojiang expr = "_Contains[a-z_]*_long_", 130*22ce4affSfengbojiang }, 131*22ce4affSfengbojiang time_t_size = { 132*22ce4affSfengbojiang value = 0x00000002, 133*22ce4affSfengbojiang expr = "_Contains[a-z_]*_timet_/", 134*22ce4affSfengbojiang }, 135*22ce4affSfengbojiang pointer_args = { 136*22ce4affSfengbojiang value = 0x00000004, 137*22ce4affSfengbojiang }, 138*22ce4affSfengbojiang pointer_size = { 139*22ce4affSfengbojiang value = 0x00000008, 140*22ce4affSfengbojiang expr = "_Contains[a-z_]*_ptr_", 141*22ce4affSfengbojiang }, 142*22ce4affSfengbojiang} 143*22ce4affSfengbojiang 144*22ce4affSfengbojianglocal known_flags = { 145*22ce4affSfengbojiang STD = 0x00000001, 146*22ce4affSfengbojiang OBSOL = 0x00000002, 147*22ce4affSfengbojiang UNIMPL = 0x00000004, 148*22ce4affSfengbojiang NODEF = 0x00000008, 149*22ce4affSfengbojiang NOARGS = 0x00000010, 150*22ce4affSfengbojiang NOPROTO = 0x00000020, 151*22ce4affSfengbojiang NOSTD = 0x00000040, 152*22ce4affSfengbojiang NOTSTATIC = 0x00000080, 153*22ce4affSfengbojiang 154*22ce4affSfengbojiang -- Compat flags start from here. We have plenty of space. 155*22ce4affSfengbojiang} 156*22ce4affSfengbojiang 157*22ce4affSfengbojiang-- All compat_options entries should have five entries: 158*22ce4affSfengbojiang-- definition: The preprocessor macro that will be set for this 159*22ce4affSfengbojiang-- compatlevel: The level this compatibility should be included at. This 160*22ce4affSfengbojiang-- generally represents the version of FreeBSD that it is compatible 161*22ce4affSfengbojiang-- with, but ultimately it's just the level of mincompat in which it's 162*22ce4affSfengbojiang-- included. 163*22ce4affSfengbojiang-- flag: The name of the flag in syscalls.master. 164*22ce4affSfengbojiang-- prefix: The prefix to use for _args and syscall prototype. This will be 165*22ce4affSfengbojiang-- used as-is, without "_" or any other character appended. 166*22ce4affSfengbojiang-- descr: The description of this compat option in init_sysent.c comments. 167*22ce4affSfengbojiang-- The special "stdcompat" entry will cause the other five to be autogenerated. 168*22ce4affSfengbojianglocal compat_options = { 169*22ce4affSfengbojiang { 170*22ce4affSfengbojiang definition = "COMPAT_43", 171*22ce4affSfengbojiang compatlevel = 3, 172*22ce4affSfengbojiang flag = "COMPAT", 173*22ce4affSfengbojiang prefix = "o", 174*22ce4affSfengbojiang descr = "old", 175*22ce4affSfengbojiang }, 176*22ce4affSfengbojiang { stdcompat = "FREEBSD4" }, 177*22ce4affSfengbojiang { stdcompat = "FREEBSD6" }, 178*22ce4affSfengbojiang { stdcompat = "FREEBSD7" }, 179*22ce4affSfengbojiang { stdcompat = "FREEBSD10" }, 180*22ce4affSfengbojiang { stdcompat = "FREEBSD11" }, 181*22ce4affSfengbojiang { stdcompat = "FREEBSD12" }, 182*22ce4affSfengbojiang} 183*22ce4affSfengbojiang 184*22ce4affSfengbojianglocal function trim(s, char) 185*22ce4affSfengbojiang if s == nil then 186*22ce4affSfengbojiang return nil 187*22ce4affSfengbojiang end 188*22ce4affSfengbojiang if char == nil then 189*22ce4affSfengbojiang char = "%s" 190*22ce4affSfengbojiang end 191*22ce4affSfengbojiang return s:gsub("^" .. char .. "+", ""):gsub(char .. "+$", "") 192*22ce4affSfengbojiangend 193*22ce4affSfengbojiang 194*22ce4affSfengbojiang-- We have to io.popen it, making sure it's properly escaped, and grab the 195*22ce4affSfengbojiang-- output from the handle returned. 196*22ce4affSfengbojianglocal function exec(cmd) 197*22ce4affSfengbojiang cmd = cmd:gsub('"', '\\"') 198*22ce4affSfengbojiang 199*22ce4affSfengbojiang local shcmd = "/bin/sh -c \"" .. cmd .. "\"" 200*22ce4affSfengbojiang local fh = io.popen(shcmd) 201*22ce4affSfengbojiang local output = fh:read("a") 202*22ce4affSfengbojiang 203*22ce4affSfengbojiang fh:close() 204*22ce4affSfengbojiang return output 205*22ce4affSfengbojiangend 206*22ce4affSfengbojiang 207*22ce4affSfengbojiang-- config looks like a shell script; in fact, the previous makesyscalls.sh 208*22ce4affSfengbojiang-- script actually sourced it in. It had a pretty common format, so we should 209*22ce4affSfengbojiang-- be fine to make various assumptions 210*22ce4affSfengbojianglocal function process_config(file) 211*22ce4affSfengbojiang local cfg = {} 212*22ce4affSfengbojiang local comment_line_expr = "^%s*#.*" 213*22ce4affSfengbojiang -- We capture any whitespace padding here so we can easily advance to 214*22ce4affSfengbojiang -- the end of the line as needed to check for any trailing bogus bits. 215*22ce4affSfengbojiang -- Alternatively, we could drop the whitespace and instead try to 216*22ce4affSfengbojiang -- use a pattern to strip out the meaty part of the line, but then we 217*22ce4affSfengbojiang -- would need to sanitize the line for potentially special characters. 218*22ce4affSfengbojiang local line_expr = "^([%w%p]+%s*)=(%s*[`\"]?[^\"`]+[`\"]?)" 219*22ce4affSfengbojiang 220*22ce4affSfengbojiang if file == nil then 221*22ce4affSfengbojiang return nil, "No file given" 222*22ce4affSfengbojiang end 223*22ce4affSfengbojiang 224*22ce4affSfengbojiang local fh = io.open(file) 225*22ce4affSfengbojiang if fh == nil then 226*22ce4affSfengbojiang return nil, "Could not open file" 227*22ce4affSfengbojiang end 228*22ce4affSfengbojiang 229*22ce4affSfengbojiang for nextline in fh:lines() do 230*22ce4affSfengbojiang -- Strip any whole-line comments 231*22ce4affSfengbojiang nextline = nextline:gsub(comment_line_expr, "") 232*22ce4affSfengbojiang -- Parse it into key, value pairs 233*22ce4affSfengbojiang local key, value = nextline:match(line_expr) 234*22ce4affSfengbojiang if key ~= nil and value ~= nil then 235*22ce4affSfengbojiang local kvp = key .. "=" .. value 236*22ce4affSfengbojiang key = trim(key) 237*22ce4affSfengbojiang value = trim(value) 238*22ce4affSfengbojiang local delim = value:sub(1,1) 239*22ce4affSfengbojiang if delim == '`' or delim == '"' then 240*22ce4affSfengbojiang local trailing_context 241*22ce4affSfengbojiang -- Strip off the key/value part 242*22ce4affSfengbojiang trailing_context = nextline:sub(kvp:len() + 1) 243*22ce4affSfengbojiang -- Strip off any trailing comment 244*22ce4affSfengbojiang trailing_context = trailing_context:gsub("#.*$", 245*22ce4affSfengbojiang "") 246*22ce4affSfengbojiang -- Strip off leading/trailing whitespace 247*22ce4affSfengbojiang trailing_context = trim(trailing_context) 248*22ce4affSfengbojiang if trailing_context ~= "" then 249*22ce4affSfengbojiang print(trailing_context) 250*22ce4affSfengbojiang abort(1, "Malformed line: " .. nextline) 251*22ce4affSfengbojiang end 252*22ce4affSfengbojiang end 253*22ce4affSfengbojiang if delim == '`' then 254*22ce4affSfengbojiang -- Command substition may use $1 and $2 to mean 255*22ce4affSfengbojiang -- the syscall definition file and itself 256*22ce4affSfengbojiang -- respectively. We'll go ahead and replace 257*22ce4affSfengbojiang -- $[0-9] with respective arg in case we want to 258*22ce4affSfengbojiang -- expand this in the future easily... 259*22ce4affSfengbojiang value = trim(value, delim) 260*22ce4affSfengbojiang for capture in value:gmatch("$([0-9]+)") do 261*22ce4affSfengbojiang capture = tonumber(capture) 262*22ce4affSfengbojiang if capture > #arg then 263*22ce4affSfengbojiang abort(1, "Not enough args: " .. 264*22ce4affSfengbojiang value) 265*22ce4affSfengbojiang end 266*22ce4affSfengbojiang value = value:gsub("$" .. capture, 267*22ce4affSfengbojiang arg[capture]) 268*22ce4affSfengbojiang end 269*22ce4affSfengbojiang 270*22ce4affSfengbojiang value = exec(value) 271*22ce4affSfengbojiang elseif delim == '"' then 272*22ce4affSfengbojiang value = trim(value, delim) 273*22ce4affSfengbojiang else 274*22ce4affSfengbojiang -- Strip off potential comments 275*22ce4affSfengbojiang value = value:gsub("#.*$", "") 276*22ce4affSfengbojiang -- Strip off any padding whitespace 277*22ce4affSfengbojiang value = trim(value) 278*22ce4affSfengbojiang if value:match("%s") then 279*22ce4affSfengbojiang abort(1, "Malformed config line: " .. 280*22ce4affSfengbojiang nextline) 281*22ce4affSfengbojiang end 282*22ce4affSfengbojiang end 283*22ce4affSfengbojiang cfg[key] = value 284*22ce4affSfengbojiang elseif not nextline:match("^%s*$") then 285*22ce4affSfengbojiang -- Make sure format violations don't get overlooked 286*22ce4affSfengbojiang -- here, but ignore blank lines. Comments are already 287*22ce4affSfengbojiang -- stripped above. 288*22ce4affSfengbojiang abort(1, "Malformed config line: " .. nextline) 289*22ce4affSfengbojiang end 290*22ce4affSfengbojiang end 291*22ce4affSfengbojiang 292*22ce4affSfengbojiang io.close(fh) 293*22ce4affSfengbojiang return cfg 294*22ce4affSfengbojiangend 295*22ce4affSfengbojiang 296*22ce4affSfengbojianglocal function grab_capenabled(file, open_fail_ok) 297*22ce4affSfengbojiang local capentries = {} 298*22ce4affSfengbojiang local commentExpr = "#.*" 299*22ce4affSfengbojiang 300*22ce4affSfengbojiang if file == nil then 301*22ce4affSfengbojiang print "No file" 302*22ce4affSfengbojiang return {} 303*22ce4affSfengbojiang end 304*22ce4affSfengbojiang 305*22ce4affSfengbojiang local fh = io.open(file) 306*22ce4affSfengbojiang if fh == nil then 307*22ce4affSfengbojiang if not open_fail_ok then 308*22ce4affSfengbojiang abort(1, "Failed to open " .. file) 309*22ce4affSfengbojiang end 310*22ce4affSfengbojiang return {} 311*22ce4affSfengbojiang end 312*22ce4affSfengbojiang 313*22ce4affSfengbojiang for nextline in fh:lines() do 314*22ce4affSfengbojiang -- Strip any comments 315*22ce4affSfengbojiang nextline = nextline:gsub(commentExpr, "") 316*22ce4affSfengbojiang if nextline ~= "" then 317*22ce4affSfengbojiang capentries[nextline] = true 318*22ce4affSfengbojiang end 319*22ce4affSfengbojiang end 320*22ce4affSfengbojiang 321*22ce4affSfengbojiang io.close(fh) 322*22ce4affSfengbojiang return capentries 323*22ce4affSfengbojiangend 324*22ce4affSfengbojiang 325*22ce4affSfengbojianglocal function process_compat() 326*22ce4affSfengbojiang local nval = 0 327*22ce4affSfengbojiang for _, v in pairs(known_flags) do 328*22ce4affSfengbojiang if v > nval then 329*22ce4affSfengbojiang nval = v 330*22ce4affSfengbojiang end 331*22ce4affSfengbojiang end 332*22ce4affSfengbojiang 333*22ce4affSfengbojiang nval = nval << 1 334*22ce4affSfengbojiang for _, v in pairs(compat_options) do 335*22ce4affSfengbojiang if v["stdcompat"] ~= nil then 336*22ce4affSfengbojiang local stdcompat = v["stdcompat"] 337*22ce4affSfengbojiang v["definition"] = "COMPAT_" .. stdcompat:upper() 338*22ce4affSfengbojiang v["compatlevel"] = tonumber(stdcompat:match("([0-9]+)$")) 339*22ce4affSfengbojiang v["flag"] = stdcompat:gsub("FREEBSD", "COMPAT") 340*22ce4affSfengbojiang v["prefix"] = stdcompat:lower() .. "_" 341*22ce4affSfengbojiang v["descr"] = stdcompat:lower() 342*22ce4affSfengbojiang end 343*22ce4affSfengbojiang 344*22ce4affSfengbojiang local tmpname = "sys" .. v["flag"]:lower() 345*22ce4affSfengbojiang local dcltmpname = tmpname .. "dcl" 346*22ce4affSfengbojiang files[tmpname] = io.tmpfile() 347*22ce4affSfengbojiang files[dcltmpname] = io.tmpfile() 348*22ce4affSfengbojiang v["tmp"] = tmpname 349*22ce4affSfengbojiang v["dcltmp"] = dcltmpname 350*22ce4affSfengbojiang 351*22ce4affSfengbojiang known_flags[v["flag"]] = nval 352*22ce4affSfengbojiang v["mask"] = nval 353*22ce4affSfengbojiang nval = nval << 1 354*22ce4affSfengbojiang 355*22ce4affSfengbojiang v["count"] = 0 356*22ce4affSfengbojiang end 357*22ce4affSfengbojiangend 358*22ce4affSfengbojiang 359*22ce4affSfengbojianglocal function process_abi_flags() 360*22ce4affSfengbojiang local flags, mask = config["abi_flags"], 0 361*22ce4affSfengbojiang for txtflag in flags:gmatch("([^|]+)") do 362*22ce4affSfengbojiang if known_abi_flags[txtflag] == nil then 363*22ce4affSfengbojiang abort(1, "Unknown abi_flag: " .. txtflag) 364*22ce4affSfengbojiang end 365*22ce4affSfengbojiang 366*22ce4affSfengbojiang mask = mask | known_abi_flags[txtflag]["value"] 367*22ce4affSfengbojiang end 368*22ce4affSfengbojiang 369*22ce4affSfengbojiang config["abi_flags_mask"] = mask 370*22ce4affSfengbojiangend 371*22ce4affSfengbojiang 372*22ce4affSfengbojianglocal function abi_changes(name) 373*22ce4affSfengbojiang if known_abi_flags[name] == nil then 374*22ce4affSfengbojiang abort(1, "abi_changes: unknown flag: " .. name) 375*22ce4affSfengbojiang end 376*22ce4affSfengbojiang 377*22ce4affSfengbojiang return config["abi_flags_mask"] & known_abi_flags[name]["value"] ~= 0 378*22ce4affSfengbojiangend 379*22ce4affSfengbojiang 380*22ce4affSfengbojianglocal function strip_abi_prefix(funcname) 381*22ce4affSfengbojiang local abiprefix = config["abi_func_prefix"] 382*22ce4affSfengbojiang local stripped_name 383*22ce4affSfengbojiang if abiprefix ~= "" and funcname:find("^" .. abiprefix) then 384*22ce4affSfengbojiang stripped_name = funcname:gsub("^" .. abiprefix, "") 385*22ce4affSfengbojiang else 386*22ce4affSfengbojiang stripped_name = funcname 387*22ce4affSfengbojiang end 388*22ce4affSfengbojiang 389*22ce4affSfengbojiang return stripped_name 390*22ce4affSfengbojiangend 391*22ce4affSfengbojiang 392*22ce4affSfengbojianglocal function read_file(tmpfile) 393*22ce4affSfengbojiang if files[tmpfile] == nil then 394*22ce4affSfengbojiang print("Not found: " .. tmpfile) 395*22ce4affSfengbojiang return 396*22ce4affSfengbojiang end 397*22ce4affSfengbojiang 398*22ce4affSfengbojiang local fh = files[tmpfile] 399*22ce4affSfengbojiang fh:seek("set") 400*22ce4affSfengbojiang return fh:read("a") 401*22ce4affSfengbojiangend 402*22ce4affSfengbojiang 403*22ce4affSfengbojianglocal function write_line(tmpfile, line) 404*22ce4affSfengbojiang if files[tmpfile] == nil then 405*22ce4affSfengbojiang print("Not found: " .. tmpfile) 406*22ce4affSfengbojiang return 407*22ce4affSfengbojiang end 408*22ce4affSfengbojiang files[tmpfile]:write(line) 409*22ce4affSfengbojiangend 410*22ce4affSfengbojiang 411*22ce4affSfengbojianglocal function write_line_pfile(tmppat, line) 412*22ce4affSfengbojiang for k in pairs(files) do 413*22ce4affSfengbojiang if k:match(tmppat) ~= nil then 414*22ce4affSfengbojiang files[k]:write(line) 415*22ce4affSfengbojiang end 416*22ce4affSfengbojiang end 417*22ce4affSfengbojiangend 418*22ce4affSfengbojiang 419*22ce4affSfengbojianglocal function isptrtype(type) 420*22ce4affSfengbojiang return type:find("*") or type:find("caddr_t") 421*22ce4affSfengbojiang -- XXX NOTYET: or type:find("intptr_t") 422*22ce4affSfengbojiangend 423*22ce4affSfengbojiang 424*22ce4affSfengbojianglocal process_syscall_def 425*22ce4affSfengbojiang 426*22ce4affSfengbojiang-- These patterns are processed in order on any line that isn't empty. 427*22ce4affSfengbojianglocal pattern_table = { 428*22ce4affSfengbojiang { 429*22ce4affSfengbojiang pattern = "%s*$" .. config['os_id_keyword'], 430*22ce4affSfengbojiang process = function(_, _) 431*22ce4affSfengbojiang -- Ignore... ID tag 432*22ce4affSfengbojiang end, 433*22ce4affSfengbojiang }, 434*22ce4affSfengbojiang { 435*22ce4affSfengbojiang dump_prevline = true, 436*22ce4affSfengbojiang pattern = "^#%s*include", 437*22ce4affSfengbojiang process = function(line) 438*22ce4affSfengbojiang line = line .. "\n" 439*22ce4affSfengbojiang write_line('sysinc', line) 440*22ce4affSfengbojiang end, 441*22ce4affSfengbojiang }, 442*22ce4affSfengbojiang { 443*22ce4affSfengbojiang dump_prevline = true, 444*22ce4affSfengbojiang pattern = "^#", 445*22ce4affSfengbojiang process = function(line) 446*22ce4affSfengbojiang if line:find("^#%s*if") then 447*22ce4affSfengbojiang savesyscall = maxsyscall 448*22ce4affSfengbojiang elseif line:find("^#%s*else") then 449*22ce4affSfengbojiang maxsyscall = savesyscall 450*22ce4affSfengbojiang end 451*22ce4affSfengbojiang line = line .. "\n" 452*22ce4affSfengbojiang write_line('sysent', line) 453*22ce4affSfengbojiang write_line('sysdcl', line) 454*22ce4affSfengbojiang write_line('sysarg', line) 455*22ce4affSfengbojiang write_line_pfile('syscompat[0-9]*$', line) 456*22ce4affSfengbojiang write_line('sysnames', line) 457*22ce4affSfengbojiang write_line_pfile('systrace.*', line) 458*22ce4affSfengbojiang end, 459*22ce4affSfengbojiang }, 460*22ce4affSfengbojiang { 461*22ce4affSfengbojiang -- Buffer anything else 462*22ce4affSfengbojiang pattern = ".+", 463*22ce4affSfengbojiang process = function(line, prevline) 464*22ce4affSfengbojiang local incomplete = line:find("\\$") ~= nil 465*22ce4affSfengbojiang -- Lines that end in \ get the \ stripped 466*22ce4affSfengbojiang -- Lines that start with a syscall number, prepend \n 467*22ce4affSfengbojiang line = trim(line):gsub("\\$", "") 468*22ce4affSfengbojiang if line:find("^[0-9]") and prevline then 469*22ce4affSfengbojiang process_syscall_def(prevline) 470*22ce4affSfengbojiang prevline = nil 471*22ce4affSfengbojiang end 472*22ce4affSfengbojiang 473*22ce4affSfengbojiang prevline = (prevline or '') .. line 474*22ce4affSfengbojiang incomplete = incomplete or prevline:find(",$") ~= nil 475*22ce4affSfengbojiang incomplete = incomplete or prevline:find("{") ~= nil and 476*22ce4affSfengbojiang prevline:find("}") == nil 477*22ce4affSfengbojiang if prevline:find("^[0-9]") and not incomplete then 478*22ce4affSfengbojiang process_syscall_def(prevline) 479*22ce4affSfengbojiang prevline = nil 480*22ce4affSfengbojiang end 481*22ce4affSfengbojiang 482*22ce4affSfengbojiang return prevline 483*22ce4affSfengbojiang end, 484*22ce4affSfengbojiang }, 485*22ce4affSfengbojiang} 486*22ce4affSfengbojiang 487*22ce4affSfengbojianglocal function process_sysfile(file) 488*22ce4affSfengbojiang local capentries = {} 489*22ce4affSfengbojiang local commentExpr = "^%s*;.*" 490*22ce4affSfengbojiang 491*22ce4affSfengbojiang if file == nil then 492*22ce4affSfengbojiang print "No file" 493*22ce4affSfengbojiang return {} 494*22ce4affSfengbojiang end 495*22ce4affSfengbojiang 496*22ce4affSfengbojiang local fh = io.open(file) 497*22ce4affSfengbojiang if fh == nil then 498*22ce4affSfengbojiang print("Failed to open " .. file) 499*22ce4affSfengbojiang return {} 500*22ce4affSfengbojiang end 501*22ce4affSfengbojiang 502*22ce4affSfengbojiang local function do_match(nextline, prevline) 503*22ce4affSfengbojiang local pattern, handler, dump 504*22ce4affSfengbojiang for _, v in pairs(pattern_table) do 505*22ce4affSfengbojiang pattern = v['pattern'] 506*22ce4affSfengbojiang handler = v['process'] 507*22ce4affSfengbojiang dump = v['dump_prevline'] 508*22ce4affSfengbojiang if nextline:match(pattern) then 509*22ce4affSfengbojiang if dump and prevline then 510*22ce4affSfengbojiang process_syscall_def(prevline) 511*22ce4affSfengbojiang prevline = nil 512*22ce4affSfengbojiang end 513*22ce4affSfengbojiang 514*22ce4affSfengbojiang return handler(nextline, prevline) 515*22ce4affSfengbojiang end 516*22ce4affSfengbojiang end 517*22ce4affSfengbojiang 518*22ce4affSfengbojiang abort(1, "Failed to handle: " .. nextline) 519*22ce4affSfengbojiang end 520*22ce4affSfengbojiang 521*22ce4affSfengbojiang local prevline 522*22ce4affSfengbojiang for nextline in fh:lines() do 523*22ce4affSfengbojiang -- Strip any comments 524*22ce4affSfengbojiang nextline = nextline:gsub(commentExpr, "") 525*22ce4affSfengbojiang if nextline ~= "" then 526*22ce4affSfengbojiang prevline = do_match(nextline, prevline) 527*22ce4affSfengbojiang end 528*22ce4affSfengbojiang end 529*22ce4affSfengbojiang 530*22ce4affSfengbojiang -- Dump any remainder 531*22ce4affSfengbojiang if prevline ~= nil and prevline:find("^[0-9]") then 532*22ce4affSfengbojiang process_syscall_def(prevline) 533*22ce4affSfengbojiang end 534*22ce4affSfengbojiang 535*22ce4affSfengbojiang io.close(fh) 536*22ce4affSfengbojiang return capentries 537*22ce4affSfengbojiangend 538*22ce4affSfengbojiang 539*22ce4affSfengbojianglocal function get_mask(flags) 540*22ce4affSfengbojiang local mask = 0 541*22ce4affSfengbojiang for _, v in ipairs(flags) do 542*22ce4affSfengbojiang if known_flags[v] == nil then 543*22ce4affSfengbojiang abort(1, "Checking for unknown flag " .. v) 544*22ce4affSfengbojiang end 545*22ce4affSfengbojiang 546*22ce4affSfengbojiang mask = mask | known_flags[v] 547*22ce4affSfengbojiang end 548*22ce4affSfengbojiang 549*22ce4affSfengbojiang return mask 550*22ce4affSfengbojiangend 551*22ce4affSfengbojiang 552*22ce4affSfengbojianglocal function get_mask_pat(pflags) 553*22ce4affSfengbojiang local mask = 0 554*22ce4affSfengbojiang for k, v in pairs(known_flags) do 555*22ce4affSfengbojiang if k:find(pflags) then 556*22ce4affSfengbojiang mask = mask | v 557*22ce4affSfengbojiang end 558*22ce4affSfengbojiang end 559*22ce4affSfengbojiang 560*22ce4affSfengbojiang return mask 561*22ce4affSfengbojiangend 562*22ce4affSfengbojiang 563*22ce4affSfengbojianglocal function align_sysent_comment(col) 564*22ce4affSfengbojiang write_line("sysent", "\t") 565*22ce4affSfengbojiang col = col + 8 - col % 8 566*22ce4affSfengbojiang while col < 56 do 567*22ce4affSfengbojiang write_line("sysent", "\t") 568*22ce4affSfengbojiang col = col + 8 569*22ce4affSfengbojiang end 570*22ce4affSfengbojiangend 571*22ce4affSfengbojiang 572*22ce4affSfengbojianglocal function strip_arg_annotations(arg) 573*22ce4affSfengbojiang arg = arg:gsub("_In[^ ]*[_)] ?", "") 574*22ce4affSfengbojiang arg = arg:gsub("_Out[^ ]*[_)] ?", "") 575*22ce4affSfengbojiang return trim(arg) 576*22ce4affSfengbojiangend 577*22ce4affSfengbojiang 578*22ce4affSfengbojianglocal function check_abi_changes(arg) 579*22ce4affSfengbojiang for k, v in pairs(known_abi_flags) do 580*22ce4affSfengbojiang local expr = v["expr"] 581*22ce4affSfengbojiang if abi_changes(k) and expr ~= nil and arg:find(expr) then 582*22ce4affSfengbojiang return true 583*22ce4affSfengbojiang end 584*22ce4affSfengbojiang end 585*22ce4affSfengbojiang 586*22ce4affSfengbojiang return false 587*22ce4affSfengbojiangend 588*22ce4affSfengbojiang 589*22ce4affSfengbojianglocal function process_args(args) 590*22ce4affSfengbojiang local funcargs = {} 591*22ce4affSfengbojiang 592*22ce4affSfengbojiang for arg in args:gmatch("([^,]+)") do 593*22ce4affSfengbojiang local abi_change = not isptrtype(arg) or check_abi_changes(arg) 594*22ce4affSfengbojiang 595*22ce4affSfengbojiang arg = strip_arg_annotations(arg) 596*22ce4affSfengbojiang 597*22ce4affSfengbojiang local argname = arg:match("([^* ]+)$") 598*22ce4affSfengbojiang 599*22ce4affSfengbojiang -- argtype is... everything else. 600*22ce4affSfengbojiang local argtype = trim(arg:gsub(argname .. "$", ""), nil) 601*22ce4affSfengbojiang 602*22ce4affSfengbojiang if argtype == "" and argname == "void" then 603*22ce4affSfengbojiang goto out 604*22ce4affSfengbojiang end 605*22ce4affSfengbojiang 606*22ce4affSfengbojiang -- XX TODO: Forward declarations? See: sysstubfwd in CheriBSD 607*22ce4affSfengbojiang if abi_change then 608*22ce4affSfengbojiang local abi_type_suffix = config["abi_type_suffix"] 609*22ce4affSfengbojiang argtype = argtype:gsub("_native ", "") 610*22ce4affSfengbojiang argtype = argtype:gsub("(struct [^ ]*)", "%1" .. 611*22ce4affSfengbojiang abi_type_suffix) 612*22ce4affSfengbojiang argtype = argtype:gsub("(union [^ ]*)", "%1" .. 613*22ce4affSfengbojiang abi_type_suffix) 614*22ce4affSfengbojiang end 615*22ce4affSfengbojiang 616*22ce4affSfengbojiang funcargs[#funcargs + 1] = { 617*22ce4affSfengbojiang type = argtype, 618*22ce4affSfengbojiang name = argname, 619*22ce4affSfengbojiang } 620*22ce4affSfengbojiang end 621*22ce4affSfengbojiang 622*22ce4affSfengbojiang ::out:: 623*22ce4affSfengbojiang return funcargs 624*22ce4affSfengbojiangend 625*22ce4affSfengbojiang 626*22ce4affSfengbojianglocal function handle_noncompat(sysnum, thr_flag, flags, sysflags, rettype, 627*22ce4affSfengbojiang auditev, syscallret, funcname, funcalias, funcargs, argalias) 628*22ce4affSfengbojiang local argssize 629*22ce4affSfengbojiang 630*22ce4affSfengbojiang if #funcargs > 0 or flags & known_flags["NODEF"] ~= 0 then 631*22ce4affSfengbojiang argssize = "AS(" .. argalias .. ")" 632*22ce4affSfengbojiang else 633*22ce4affSfengbojiang argssize = "0" 634*22ce4affSfengbojiang end 635*22ce4affSfengbojiang 636*22ce4affSfengbojiang write_line("systrace", string.format([[ 637*22ce4affSfengbojiang /* %s */ 638*22ce4affSfengbojiang case %d: { 639*22ce4affSfengbojiang]], funcname, sysnum)) 640*22ce4affSfengbojiang write_line("systracetmp", string.format([[ 641*22ce4affSfengbojiang /* %s */ 642*22ce4affSfengbojiang case %d: 643*22ce4affSfengbojiang]], funcname, sysnum)) 644*22ce4affSfengbojiang write_line("systraceret", string.format([[ 645*22ce4affSfengbojiang /* %s */ 646*22ce4affSfengbojiang case %d: 647*22ce4affSfengbojiang]], funcname, sysnum)) 648*22ce4affSfengbojiang 649*22ce4affSfengbojiang if #funcargs > 0 then 650*22ce4affSfengbojiang write_line("systracetmp", "\t\tswitch(ndx) {\n") 651*22ce4affSfengbojiang write_line("systrace", string.format( 652*22ce4affSfengbojiang "\t\tstruct %s *p = params;\n", argalias)) 653*22ce4affSfengbojiang 654*22ce4affSfengbojiang local argtype, argname 655*22ce4affSfengbojiang for idx, arg in ipairs(funcargs) do 656*22ce4affSfengbojiang argtype = arg["type"] 657*22ce4affSfengbojiang argname = arg["name"] 658*22ce4affSfengbojiang 659*22ce4affSfengbojiang argtype = trim(argtype:gsub("__restrict$", ""), nil) 660*22ce4affSfengbojiang -- Pointer arg? 661*22ce4affSfengbojiang if argtype:find("*") then 662*22ce4affSfengbojiang write_line("systracetmp", string.format( 663*22ce4affSfengbojiang "\t\tcase %d:\n\t\t\tp = \"userland %s\";\n\t\t\tbreak;\n", 664*22ce4affSfengbojiang idx - 1, argtype)) 665*22ce4affSfengbojiang else 666*22ce4affSfengbojiang write_line("systracetmp", string.format( 667*22ce4affSfengbojiang "\t\tcase %d:\n\t\t\tp = \"%s\";\n\t\t\tbreak;\n", 668*22ce4affSfengbojiang idx - 1, argtype)) 669*22ce4affSfengbojiang end 670*22ce4affSfengbojiang 671*22ce4affSfengbojiang if isptrtype(argtype) then 672*22ce4affSfengbojiang write_line("systrace", string.format( 673*22ce4affSfengbojiang "\t\tuarg[%d] = (%s) p->%s; /* %s */\n", 674*22ce4affSfengbojiang idx - 1, config["ptr_intptr_t_cast"], 675*22ce4affSfengbojiang argname, argtype)) 676*22ce4affSfengbojiang elseif argtype == "union l_semun" then 677*22ce4affSfengbojiang write_line("systrace", string.format( 678*22ce4affSfengbojiang "\t\tuarg[%d] = p->%s.buf; /* %s */\n", 679*22ce4affSfengbojiang idx - 1, argname, argtype)) 680*22ce4affSfengbojiang elseif argtype:sub(1,1) == "u" or argtype == "size_t" then 681*22ce4affSfengbojiang write_line("systrace", string.format( 682*22ce4affSfengbojiang "\t\tuarg[%d] = p->%s; /* %s */\n", 683*22ce4affSfengbojiang idx - 1, argname, argtype)) 684*22ce4affSfengbojiang else 685*22ce4affSfengbojiang write_line("systrace", string.format( 686*22ce4affSfengbojiang "\t\tiarg[%d] = p->%s; /* %s */\n", 687*22ce4affSfengbojiang idx - 1, argname, argtype)) 688*22ce4affSfengbojiang end 689*22ce4affSfengbojiang end 690*22ce4affSfengbojiang 691*22ce4affSfengbojiang write_line("systracetmp", 692*22ce4affSfengbojiang "\t\tdefault:\n\t\t\tbreak;\n\t\t};\n") 693*22ce4affSfengbojiang 694*22ce4affSfengbojiang write_line("systraceret", string.format([[ 695*22ce4affSfengbojiang if (ndx == 0 || ndx == 1) 696*22ce4affSfengbojiang p = "%s"; 697*22ce4affSfengbojiang break; 698*22ce4affSfengbojiang]], syscallret)) 699*22ce4affSfengbojiang end 700*22ce4affSfengbojiang write_line("systrace", string.format( 701*22ce4affSfengbojiang "\t\t*n_args = %d;\n\t\tbreak;\n\t}\n", #funcargs)) 702*22ce4affSfengbojiang write_line("systracetmp", "\t\tbreak;\n") 703*22ce4affSfengbojiang 704*22ce4affSfengbojiang local nargflags = get_mask({"NOARGS", "NOPROTO", "NODEF"}) 705*22ce4affSfengbojiang if flags & nargflags == 0 then 706*22ce4affSfengbojiang if #funcargs > 0 then 707*22ce4affSfengbojiang write_line("sysarg", string.format("struct %s {\n", 708*22ce4affSfengbojiang argalias)) 709*22ce4affSfengbojiang for _, v in ipairs(funcargs) do 710*22ce4affSfengbojiang local argname, argtype = v["name"], v["type"] 711*22ce4affSfengbojiang write_line("sysarg", string.format( 712*22ce4affSfengbojiang "\tchar %s_l_[PADL_(%s)]; %s %s; char %s_r_[PADR_(%s)];\n", 713*22ce4affSfengbojiang argname, argtype, 714*22ce4affSfengbojiang argtype, argname, 715*22ce4affSfengbojiang argname, argtype)) 716*22ce4affSfengbojiang end 717*22ce4affSfengbojiang write_line("sysarg", "};\n") 718*22ce4affSfengbojiang else 719*22ce4affSfengbojiang write_line("sysarg", string.format( 720*22ce4affSfengbojiang "struct %s {\n\tregister_t dummy;\n};\n", argalias)) 721*22ce4affSfengbojiang end 722*22ce4affSfengbojiang end 723*22ce4affSfengbojiang 724*22ce4affSfengbojiang local protoflags = get_mask({"NOPROTO", "NODEF"}) 725*22ce4affSfengbojiang if flags & protoflags == 0 then 726*22ce4affSfengbojiang if funcname == "nosys" or funcname == "lkmnosys" or 727*22ce4affSfengbojiang funcname == "sysarch" or funcname:find("^freebsd") or 728*22ce4affSfengbojiang funcname:find("^linux") or 729*22ce4affSfengbojiang funcname:find("^cloudabi") then 730*22ce4affSfengbojiang write_line("sysdcl", string.format( 731*22ce4affSfengbojiang "%s\t%s(struct thread *, struct %s *)", 732*22ce4affSfengbojiang rettype, funcname, argalias)) 733*22ce4affSfengbojiang else 734*22ce4affSfengbojiang write_line("sysdcl", string.format( 735*22ce4affSfengbojiang "%s\tsys_%s(struct thread *, struct %s *)", 736*22ce4affSfengbojiang rettype, funcname, argalias)) 737*22ce4affSfengbojiang end 738*22ce4affSfengbojiang write_line("sysdcl", ";\n") 739*22ce4affSfengbojiang write_line("sysaue", string.format("#define\t%sAUE_%s\t%s\n", 740*22ce4affSfengbojiang config['syscallprefix'], funcalias, auditev)) 741*22ce4affSfengbojiang end 742*22ce4affSfengbojiang 743*22ce4affSfengbojiang write_line("sysent", 744*22ce4affSfengbojiang string.format("\t{ .sy_narg = %s, .sy_call = (sy_call_t *)", argssize)) 745*22ce4affSfengbojiang local column = 8 + 2 + #argssize + 15 746*22ce4affSfengbojiang 747*22ce4affSfengbojiang if flags & known_flags["NOSTD"] ~= 0 then 748*22ce4affSfengbojiang write_line("sysent", string.format( 749*22ce4affSfengbojiang "lkmressys, .sy_auevent = AUE_NULL, " .. 750*22ce4affSfengbojiang ".sy_flags = %s, .sy_thrcnt = SY_THR_ABSENT },", 751*22ce4affSfengbojiang sysflags)) 752*22ce4affSfengbojiang column = column + #"lkmressys" + #"AUE_NULL" + 3 753*22ce4affSfengbojiang else 754*22ce4affSfengbojiang if funcname == "nosys" or funcname == "lkmnosys" or 755*22ce4affSfengbojiang funcname == "sysarch" or funcname:find("^freebsd") or 756*22ce4affSfengbojiang funcname:find("^linux") or 757*22ce4affSfengbojiang funcname:find("^cloudabi") then 758*22ce4affSfengbojiang write_line("sysent", string.format( 759*22ce4affSfengbojiang "%s, .sy_auevent = %s, .sy_flags = %s, .sy_thrcnt = %s },", 760*22ce4affSfengbojiang funcname, auditev, sysflags, thr_flag)) 761*22ce4affSfengbojiang column = column + #funcname + #auditev + #sysflags + 3 762*22ce4affSfengbojiang else 763*22ce4affSfengbojiang write_line("sysent", string.format( 764*22ce4affSfengbojiang "sys_%s, .sy_auevent = %s, .sy_flags = %s, .sy_thrcnt = %s },", 765*22ce4affSfengbojiang funcname, auditev, sysflags, thr_flag)) 766*22ce4affSfengbojiang column = column + #funcname + #auditev + #sysflags + 7 767*22ce4affSfengbojiang end 768*22ce4affSfengbojiang end 769*22ce4affSfengbojiang 770*22ce4affSfengbojiang align_sysent_comment(column) 771*22ce4affSfengbojiang write_line("sysent", string.format("/* %d = %s */\n", 772*22ce4affSfengbojiang sysnum, funcalias)) 773*22ce4affSfengbojiang write_line("sysnames", string.format("\t\"%s\",\t\t\t/* %d = %s */\n", 774*22ce4affSfengbojiang funcalias, sysnum, funcalias)) 775*22ce4affSfengbojiang 776*22ce4affSfengbojiang if flags & known_flags["NODEF"] == 0 then 777*22ce4affSfengbojiang write_line("syshdr", string.format("#define\t%s%s\t%d\n", 778*22ce4affSfengbojiang config['syscallprefix'], funcalias, sysnum)) 779*22ce4affSfengbojiang write_line("sysmk", string.format(" \\\n\t%s.o", 780*22ce4affSfengbojiang funcalias)) 781*22ce4affSfengbojiang end 782*22ce4affSfengbojiangend 783*22ce4affSfengbojiang 784*22ce4affSfengbojianglocal function handle_obsol(sysnum, funcname, comment) 785*22ce4affSfengbojiang write_line("sysent", 786*22ce4affSfengbojiang "\t{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, " .. 787*22ce4affSfengbojiang ".sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT },") 788*22ce4affSfengbojiang align_sysent_comment(34) 789*22ce4affSfengbojiang 790*22ce4affSfengbojiang write_line("sysent", string.format("/* %d = obsolete %s */\n", 791*22ce4affSfengbojiang sysnum, comment)) 792*22ce4affSfengbojiang write_line("sysnames", string.format( 793*22ce4affSfengbojiang "\t\"obs_%s\",\t\t\t/* %d = obsolete %s */\n", 794*22ce4affSfengbojiang funcname, sysnum, comment)) 795*22ce4affSfengbojiang write_line("syshdr", string.format("\t\t\t\t/* %d is obsolete %s */\n", 796*22ce4affSfengbojiang sysnum, comment)) 797*22ce4affSfengbojiangend 798*22ce4affSfengbojiang 799*22ce4affSfengbojianglocal function handle_compat(sysnum, thr_flag, flags, sysflags, rettype, 800*22ce4affSfengbojiang auditev, funcname, funcalias, funcargs, argalias) 801*22ce4affSfengbojiang local argssize, out, outdcl, wrap, prefix, descr 802*22ce4affSfengbojiang 803*22ce4affSfengbojiang if #funcargs > 0 or flags & known_flags["NODEF"] ~= 0 then 804*22ce4affSfengbojiang argssize = "AS(" .. argalias .. ")" 805*22ce4affSfengbojiang else 806*22ce4affSfengbojiang argssize = "0" 807*22ce4affSfengbojiang end 808*22ce4affSfengbojiang 809*22ce4affSfengbojiang for _, v in pairs(compat_options) do 810*22ce4affSfengbojiang if flags & v["mask"] ~= 0 then 811*22ce4affSfengbojiang if config["mincompat"] > v["compatlevel"] then 812*22ce4affSfengbojiang funcname = strip_abi_prefix(funcname) 813*22ce4affSfengbojiang funcname = v["prefix"] .. funcname 814*22ce4affSfengbojiang return handle_obsol(sysnum, funcname, funcname) 815*22ce4affSfengbojiang end 816*22ce4affSfengbojiang v["count"] = v["count"] + 1 817*22ce4affSfengbojiang out = v["tmp"] 818*22ce4affSfengbojiang outdcl = v["dcltmp"] 819*22ce4affSfengbojiang wrap = v["flag"]:lower() 820*22ce4affSfengbojiang prefix = v["prefix"] 821*22ce4affSfengbojiang descr = v["descr"] 822*22ce4affSfengbojiang goto compatdone 823*22ce4affSfengbojiang end 824*22ce4affSfengbojiang end 825*22ce4affSfengbojiang 826*22ce4affSfengbojiang ::compatdone:: 827*22ce4affSfengbojiang local dprotoflags = get_mask({"NOPROTO", "NODEF"}) 828*22ce4affSfengbojiang local nargflags = dprotoflags | known_flags["NOARGS"] 829*22ce4affSfengbojiang if #funcargs > 0 and flags & nargflags == 0 then 830*22ce4affSfengbojiang write_line(out, string.format("struct %s {\n", argalias)) 831*22ce4affSfengbojiang for _, v in ipairs(funcargs) do 832*22ce4affSfengbojiang local argname, argtype = v["name"], v["type"] 833*22ce4affSfengbojiang write_line(out, string.format( 834*22ce4affSfengbojiang "\tchar %s_l_[PADL_(%s)]; %s %s; char %s_r_[PADR_(%s)];\n", 835*22ce4affSfengbojiang argname, argtype, 836*22ce4affSfengbojiang argtype, argname, 837*22ce4affSfengbojiang argname, argtype)) 838*22ce4affSfengbojiang end 839*22ce4affSfengbojiang write_line(out, "};\n") 840*22ce4affSfengbojiang elseif flags & nargflags == 0 then 841*22ce4affSfengbojiang write_line("sysarg", string.format( 842*22ce4affSfengbojiang "struct %s {\n\tregister_t dummy;\n};\n", argalias)) 843*22ce4affSfengbojiang end 844*22ce4affSfengbojiang if flags & dprotoflags == 0 then 845*22ce4affSfengbojiang write_line(outdcl, string.format( 846*22ce4affSfengbojiang "%s\t%s%s(struct thread *, struct %s *);\n", 847*22ce4affSfengbojiang rettype, prefix, funcname, argalias)) 848*22ce4affSfengbojiang write_line("sysaue", string.format( 849*22ce4affSfengbojiang "#define\t%sAUE_%s%s\t%s\n", config['syscallprefix'], 850*22ce4affSfengbojiang prefix, funcname, auditev)) 851*22ce4affSfengbojiang end 852*22ce4affSfengbojiang 853*22ce4affSfengbojiang if flags & known_flags['NOSTD'] ~= 0 then 854*22ce4affSfengbojiang write_line("sysent", string.format( 855*22ce4affSfengbojiang "\t{ .sy_narg = %s, .sy_call = (sy_call_t *)%s, " .. 856*22ce4affSfengbojiang ".sy_auevent = %s, .sy_flags = 0, " .. 857*22ce4affSfengbojiang ".sy_thrcnt = SY_THR_ABSENT },", 858*22ce4affSfengbojiang "0", "lkmressys", "AUE_NULL")) 859*22ce4affSfengbojiang align_sysent_comment(8 + 2 + #"0" + 15 + #"lkmressys" + 860*22ce4affSfengbojiang #"AUE_NULL" + 3) 861*22ce4affSfengbojiang else 862*22ce4affSfengbojiang write_line("sysent", string.format( 863*22ce4affSfengbojiang "\t{ %s(%s,%s), .sy_auevent = %s, .sy_flags = %s, .sy_thrcnt = %s },", 864*22ce4affSfengbojiang wrap, argssize, funcname, auditev, sysflags, thr_flag)) 865*22ce4affSfengbojiang align_sysent_comment(8 + 9 + #argssize + 1 + #funcname + 866*22ce4affSfengbojiang #auditev + #sysflags + 4) 867*22ce4affSfengbojiang end 868*22ce4affSfengbojiang 869*22ce4affSfengbojiang write_line("sysent", string.format("/* %d = %s %s */\n", 870*22ce4affSfengbojiang sysnum, descr, funcalias)) 871*22ce4affSfengbojiang write_line("sysnames", string.format( 872*22ce4affSfengbojiang "\t\"%s.%s\",\t\t/* %d = %s %s */\n", 873*22ce4affSfengbojiang wrap, funcalias, sysnum, descr, funcalias)) 874*22ce4affSfengbojiang -- Do not provide freebsdN_* symbols in libc for < FreeBSD 7 875*22ce4affSfengbojiang local nosymflags = get_mask({"COMPAT", "COMPAT4", "COMPAT6"}) 876*22ce4affSfengbojiang if flags & nosymflags ~= 0 then 877*22ce4affSfengbojiang write_line("syshdr", string.format( 878*22ce4affSfengbojiang "\t\t\t\t/* %d is %s %s */\n", 879*22ce4affSfengbojiang sysnum, descr, funcalias)) 880*22ce4affSfengbojiang elseif flags & known_flags["NODEF"] == 0 then 881*22ce4affSfengbojiang write_line("syshdr", string.format("#define\t%s%s%s\t%d\n", 882*22ce4affSfengbojiang config['syscallprefix'], prefix, funcalias, sysnum)) 883*22ce4affSfengbojiang write_line("sysmk", string.format(" \\\n\t%s%s.o", 884*22ce4affSfengbojiang prefix, funcalias)) 885*22ce4affSfengbojiang end 886*22ce4affSfengbojiangend 887*22ce4affSfengbojiang 888*22ce4affSfengbojianglocal function handle_unimpl(sysnum, sysstart, sysend, comment) 889*22ce4affSfengbojiang if sysstart == nil and sysend == nil then 890*22ce4affSfengbojiang sysstart = tonumber(sysnum) 891*22ce4affSfengbojiang sysend = tonumber(sysnum) 892*22ce4affSfengbojiang end 893*22ce4affSfengbojiang 894*22ce4affSfengbojiang sysnum = sysstart 895*22ce4affSfengbojiang while sysnum <= sysend do 896*22ce4affSfengbojiang write_line("sysent", string.format( 897*22ce4affSfengbojiang "\t{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, " .. 898*22ce4affSfengbojiang ".sy_auevent = AUE_NULL, .sy_flags = 0, " .. 899*22ce4affSfengbojiang ".sy_thrcnt = SY_THR_ABSENT },\t\t\t/* %d = %s */\n", 900*22ce4affSfengbojiang sysnum, comment)) 901*22ce4affSfengbojiang write_line("sysnames", string.format( 902*22ce4affSfengbojiang "\t\"#%d\",\t\t\t/* %d = %s */\n", 903*22ce4affSfengbojiang sysnum, sysnum, comment)) 904*22ce4affSfengbojiang sysnum = sysnum + 1 905*22ce4affSfengbojiang end 906*22ce4affSfengbojiangend 907*22ce4affSfengbojiang 908*22ce4affSfengbojiangprocess_syscall_def = function(line) 909*22ce4affSfengbojiang local sysstart, sysend, flags, funcname, sysflags 910*22ce4affSfengbojiang local thr_flag, syscallret 911*22ce4affSfengbojiang local orig = line 912*22ce4affSfengbojiang flags = 0 913*22ce4affSfengbojiang thr_flag = "SY_THR_STATIC" 914*22ce4affSfengbojiang 915*22ce4affSfengbojiang -- Parse out the interesting information first 916*22ce4affSfengbojiang local initialExpr = "^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s*" 917*22ce4affSfengbojiang local sysnum, auditev, allflags = line:match(initialExpr) 918*22ce4affSfengbojiang 919*22ce4affSfengbojiang if sysnum == nil or auditev == nil or allflags == nil then 920*22ce4affSfengbojiang -- XXX TODO: Better? 921*22ce4affSfengbojiang abort(1, "Completely malformed: " .. line) 922*22ce4affSfengbojiang end 923*22ce4affSfengbojiang 924*22ce4affSfengbojiang if sysnum:find("-") then 925*22ce4affSfengbojiang sysstart, sysend = sysnum:match("^([%d]+)-([%d]+)$") 926*22ce4affSfengbojiang if sysstart == nil or sysend == nil then 927*22ce4affSfengbojiang abort(1, "Malformed range: " .. sysnum) 928*22ce4affSfengbojiang end 929*22ce4affSfengbojiang sysnum = nil 930*22ce4affSfengbojiang sysstart = tonumber(sysstart) 931*22ce4affSfengbojiang sysend = tonumber(sysend) 932*22ce4affSfengbojiang if sysstart ~= maxsyscall + 1 then 933*22ce4affSfengbojiang abort(1, "syscall number out of sync, missing " .. 934*22ce4affSfengbojiang maxsyscall + 1) 935*22ce4affSfengbojiang end 936*22ce4affSfengbojiang else 937*22ce4affSfengbojiang sysnum = tonumber(sysnum) 938*22ce4affSfengbojiang if sysnum ~= maxsyscall + 1 then 939*22ce4affSfengbojiang abort(1, "syscall number out of sync, missing " .. 940*22ce4affSfengbojiang maxsyscall + 1) 941*22ce4affSfengbojiang end 942*22ce4affSfengbojiang end 943*22ce4affSfengbojiang 944*22ce4affSfengbojiang -- Split flags 945*22ce4affSfengbojiang for flag in allflags:gmatch("([^|]+)") do 946*22ce4affSfengbojiang if known_flags[flag] == nil then 947*22ce4affSfengbojiang abort(1, "Unknown flag " .. flag .. " for " .. sysnum) 948*22ce4affSfengbojiang end 949*22ce4affSfengbojiang flags = flags | known_flags[flag] 950*22ce4affSfengbojiang end 951*22ce4affSfengbojiang 952*22ce4affSfengbojiang if (flags & known_flags["UNIMPL"]) == 0 and sysnum == nil then 953*22ce4affSfengbojiang abort(1, "Range only allowed with UNIMPL: " .. line) 954*22ce4affSfengbojiang end 955*22ce4affSfengbojiang 956*22ce4affSfengbojiang if (flags & known_flags["NOTSTATIC"]) ~= 0 then 957*22ce4affSfengbojiang thr_flag = "SY_THR_ABSENT" 958*22ce4affSfengbojiang end 959*22ce4affSfengbojiang 960*22ce4affSfengbojiang -- Strip earlier bits out, leave declaration + alt 961*22ce4affSfengbojiang line = line:gsub("^.+" .. allflags .. "%s*", "") 962*22ce4affSfengbojiang 963*22ce4affSfengbojiang local decl_fnd = line:find("^{") ~= nil 964*22ce4affSfengbojiang if decl_fnd and line:find("}") == nil then 965*22ce4affSfengbojiang abort(1, "Malformed, no closing brace: " .. line) 966*22ce4affSfengbojiang end 967*22ce4affSfengbojiang 968*22ce4affSfengbojiang local decl, alt 969*22ce4affSfengbojiang if decl_fnd then 970*22ce4affSfengbojiang line = line:gsub("^{", "") 971*22ce4affSfengbojiang decl, alt = line:match("([^}]*)}[%s]*(.*)$") 972*22ce4affSfengbojiang else 973*22ce4affSfengbojiang alt = line 974*22ce4affSfengbojiang end 975*22ce4affSfengbojiang 976*22ce4affSfengbojiang if decl == nil and alt == nil then 977*22ce4affSfengbojiang abort(1, "Malformed bits: " .. line) 978*22ce4affSfengbojiang end 979*22ce4affSfengbojiang 980*22ce4affSfengbojiang local funcalias, funcomment, argalias, rettype, args 981*22ce4affSfengbojiang if not decl_fnd and alt ~= nil and alt ~= "" then 982*22ce4affSfengbojiang -- Peel off one entry for name 983*22ce4affSfengbojiang funcname = trim(alt:match("^([^%s]+)"), nil) 984*22ce4affSfengbojiang alt = alt:gsub("^([^%s]+)[%s]*", "") 985*22ce4affSfengbojiang end 986*22ce4affSfengbojiang -- Do we even need it? 987*22ce4affSfengbojiang if flags & get_mask({"OBSOL", "UNIMPL"}) ~= 0 then 988*22ce4affSfengbojiang local NF = 0 989*22ce4affSfengbojiang for _ in orig:gmatch("[^%s]+") do 990*22ce4affSfengbojiang NF = NF + 1 991*22ce4affSfengbojiang end 992*22ce4affSfengbojiang 993*22ce4affSfengbojiang funcomment = funcname or '' 994*22ce4affSfengbojiang if NF < 6 then 995*22ce4affSfengbojiang funcomment = funcomment .. " " .. alt 996*22ce4affSfengbojiang end 997*22ce4affSfengbojiang 998*22ce4affSfengbojiang funcomment = trim(funcomment) 999*22ce4affSfengbojiang 1000*22ce4affSfengbojiang-- if funcname ~= nil then 1001*22ce4affSfengbojiang-- else 1002*22ce4affSfengbojiang-- funcomment = trim(alt) 1003*22ce4affSfengbojiang-- end 1004*22ce4affSfengbojiang goto skipalt 1005*22ce4affSfengbojiang end 1006*22ce4affSfengbojiang 1007*22ce4affSfengbojiang if alt ~= nil and alt ~= "" then 1008*22ce4affSfengbojiang local altExpr = "^([^%s]+)%s+([^%s]+)%s+([^%s]+)" 1009*22ce4affSfengbojiang funcalias, argalias, rettype = alt:match(altExpr) 1010*22ce4affSfengbojiang funcalias = trim(funcalias) 1011*22ce4affSfengbojiang if funcalias == nil or argalias == nil or rettype == nil then 1012*22ce4affSfengbojiang abort(1, "Malformed alt: " .. line) 1013*22ce4affSfengbojiang end 1014*22ce4affSfengbojiang end 1015*22ce4affSfengbojiang if decl_fnd then 1016*22ce4affSfengbojiang -- Don't clobber rettype set in the alt information 1017*22ce4affSfengbojiang if rettype == nil then 1018*22ce4affSfengbojiang rettype = "int" 1019*22ce4affSfengbojiang end 1020*22ce4affSfengbojiang -- Peel off the return type 1021*22ce4affSfengbojiang syscallret = line:match("([^%s]+)%s") 1022*22ce4affSfengbojiang line = line:match("[^%s]+%s(.+)") 1023*22ce4affSfengbojiang -- Pointer incoming 1024*22ce4affSfengbojiang if line:sub(1,1) == "*" then 1025*22ce4affSfengbojiang syscallret = syscallret .. " " 1026*22ce4affSfengbojiang end 1027*22ce4affSfengbojiang while line:sub(1,1) == "*" do 1028*22ce4affSfengbojiang line = line:sub(2) 1029*22ce4affSfengbojiang syscallret = syscallret .. "*" 1030*22ce4affSfengbojiang end 1031*22ce4affSfengbojiang funcname = line:match("^([^(]+)%(") 1032*22ce4affSfengbojiang if funcname == nil then 1033*22ce4affSfengbojiang abort(1, "Not a signature? " .. line) 1034*22ce4affSfengbojiang end 1035*22ce4affSfengbojiang args = line:match("^[^(]+%((.+)%)[^)]*$") 1036*22ce4affSfengbojiang args = trim(args, '[,%s]') 1037*22ce4affSfengbojiang end 1038*22ce4affSfengbojiang 1039*22ce4affSfengbojiang ::skipalt:: 1040*22ce4affSfengbojiang 1041*22ce4affSfengbojiang if funcname == nil then 1042*22ce4affSfengbojiang funcname = funcalias 1043*22ce4affSfengbojiang end 1044*22ce4affSfengbojiang 1045*22ce4affSfengbojiang funcname = trim(funcname) 1046*22ce4affSfengbojiang 1047*22ce4affSfengbojiang sysflags = "0" 1048*22ce4affSfengbojiang 1049*22ce4affSfengbojiang -- NODEF events do not get audited 1050*22ce4affSfengbojiang if flags & known_flags['NODEF'] ~= 0 then 1051*22ce4affSfengbojiang auditev = 'AUE_NULL' 1052*22ce4affSfengbojiang end 1053*22ce4affSfengbojiang 1054*22ce4affSfengbojiang -- If applicable; strip the ABI prefix from the name 1055*22ce4affSfengbojiang local stripped_name = strip_abi_prefix(funcname) 1056*22ce4affSfengbojiang 1057*22ce4affSfengbojiang if config["capenabled"][funcname] ~= nil or 1058*22ce4affSfengbojiang config["capenabled"][stripped_name] ~= nil then 1059*22ce4affSfengbojiang sysflags = "SYF_CAPENABLED" 1060*22ce4affSfengbojiang end 1061*22ce4affSfengbojiang 1062*22ce4affSfengbojiang local funcargs = {} 1063*22ce4affSfengbojiang if args ~= nil then 1064*22ce4affSfengbojiang funcargs = process_args(args) 1065*22ce4affSfengbojiang end 1066*22ce4affSfengbojiang 1067*22ce4affSfengbojiang local argprefix = '' 1068*22ce4affSfengbojiang if abi_changes("pointer_args") then 1069*22ce4affSfengbojiang for _, v in ipairs(funcargs) do 1070*22ce4affSfengbojiang if isptrtype(v["type"]) then 1071*22ce4affSfengbojiang -- argalias should be: 1072*22ce4affSfengbojiang -- COMPAT_PREFIX + ABI Prefix + funcname 1073*22ce4affSfengbojiang argprefix = config['abi_func_prefix'] 1074*22ce4affSfengbojiang funcalias = config['abi_func_prefix'] .. 1075*22ce4affSfengbojiang funcname 1076*22ce4affSfengbojiang goto ptrfound 1077*22ce4affSfengbojiang end 1078*22ce4affSfengbojiang end 1079*22ce4affSfengbojiang ::ptrfound:: 1080*22ce4affSfengbojiang end 1081*22ce4affSfengbojiang if funcalias == nil or funcalias == "" then 1082*22ce4affSfengbojiang funcalias = funcname 1083*22ce4affSfengbojiang end 1084*22ce4affSfengbojiang 1085*22ce4affSfengbojiang if argalias == nil and funcname ~= nil then 1086*22ce4affSfengbojiang argalias = argprefix .. funcname .. "_args" 1087*22ce4affSfengbojiang for _, v in pairs(compat_options) do 1088*22ce4affSfengbojiang local mask = v["mask"] 1089*22ce4affSfengbojiang if (flags & mask) ~= 0 then 1090*22ce4affSfengbojiang -- Multiple aliases doesn't seem to make 1091*22ce4affSfengbojiang -- sense. 1092*22ce4affSfengbojiang argalias = v["prefix"] .. argalias 1093*22ce4affSfengbojiang goto out 1094*22ce4affSfengbojiang end 1095*22ce4affSfengbojiang end 1096*22ce4affSfengbojiang ::out:: 1097*22ce4affSfengbojiang elseif argalias ~= nil then 1098*22ce4affSfengbojiang argalias = argprefix .. argalias 1099*22ce4affSfengbojiang end 1100*22ce4affSfengbojiang 1101*22ce4affSfengbojiang local ncompatflags = get_mask({"STD", "NODEF", "NOARGS", "NOPROTO", 1102*22ce4affSfengbojiang "NOSTD"}) 1103*22ce4affSfengbojiang local compatflags = get_mask_pat("COMPAT.*") 1104*22ce4affSfengbojiang -- Now try compat... 1105*22ce4affSfengbojiang if flags & compatflags ~= 0 then 1106*22ce4affSfengbojiang if flags & known_flags['STD'] ~= 0 then 1107*22ce4affSfengbojiang abort(1, "Incompatible COMPAT/STD: " .. line) 1108*22ce4affSfengbojiang end 1109*22ce4affSfengbojiang handle_compat(sysnum, thr_flag, flags, sysflags, rettype, 1110*22ce4affSfengbojiang auditev, funcname, funcalias, funcargs, argalias) 1111*22ce4affSfengbojiang elseif flags & ncompatflags ~= 0 then 1112*22ce4affSfengbojiang handle_noncompat(sysnum, thr_flag, flags, sysflags, rettype, 1113*22ce4affSfengbojiang auditev, syscallret, funcname, funcalias, funcargs, 1114*22ce4affSfengbojiang argalias) 1115*22ce4affSfengbojiang elseif flags & known_flags["OBSOL"] ~= 0 then 1116*22ce4affSfengbojiang handle_obsol(sysnum, funcname, funcomment) 1117*22ce4affSfengbojiang elseif flags & known_flags["UNIMPL"] ~= 0 then 1118*22ce4affSfengbojiang handle_unimpl(sysnum, sysstart, sysend, funcomment) 1119*22ce4affSfengbojiang else 1120*22ce4affSfengbojiang abort(1, "Bad flags? " .. line) 1121*22ce4affSfengbojiang end 1122*22ce4affSfengbojiang 1123*22ce4affSfengbojiang if sysend ~= nil then 1124*22ce4affSfengbojiang maxsyscall = sysend 1125*22ce4affSfengbojiang elseif sysnum ~= nil then 1126*22ce4affSfengbojiang maxsyscall = sysnum 1127*22ce4affSfengbojiang end 1128*22ce4affSfengbojiangend 1129*22ce4affSfengbojiang 1130*22ce4affSfengbojiang-- Entry point 1131*22ce4affSfengbojiang 1132*22ce4affSfengbojiangif #arg < 1 or #arg > 2 then 1133*22ce4affSfengbojiang abort(1, "usage: " .. arg[0] .. " input-file <config-file>") 1134*22ce4affSfengbojiangend 1135*22ce4affSfengbojiang 1136*22ce4affSfengbojianglocal sysfile, configfile = arg[1], arg[2] 1137*22ce4affSfengbojiang 1138*22ce4affSfengbojiang-- process_config either returns nil and a message, or a 1139*22ce4affSfengbojiang-- table that we should merge into the global config 1140*22ce4affSfengbojiangif configfile ~= nil then 1141*22ce4affSfengbojiang local res, msg = process_config(configfile) 1142*22ce4affSfengbojiang 1143*22ce4affSfengbojiang if res == nil then 1144*22ce4affSfengbojiang -- Error... handle? 1145*22ce4affSfengbojiang print(msg) 1146*22ce4affSfengbojiang os.exit(1) 1147*22ce4affSfengbojiang end 1148*22ce4affSfengbojiang 1149*22ce4affSfengbojiang for k, v in pairs(res) do 1150*22ce4affSfengbojiang if v ~= config[k] then 1151*22ce4affSfengbojiang config[k] = v 1152*22ce4affSfengbojiang config_modified[k] = true 1153*22ce4affSfengbojiang end 1154*22ce4affSfengbojiang end 1155*22ce4affSfengbojiangend 1156*22ce4affSfengbojiang 1157*22ce4affSfengbojiang-- We ignore errors here if we're relying on the default configuration. 1158*22ce4affSfengbojiangif not config_modified["capenabled"] then 1159*22ce4affSfengbojiang config["capenabled"] = grab_capenabled(config['capabilities_conf'], 1160*22ce4affSfengbojiang config_modified["capabilities_conf"] == nil) 1161*22ce4affSfengbojiangelseif config["capenabled"] ~= "" then 1162*22ce4affSfengbojiang -- Due to limitations in the config format mostly, we'll have a comma 1163*22ce4affSfengbojiang -- separated list. Parse it into lines 1164*22ce4affSfengbojiang local capenabled = {} 1165*22ce4affSfengbojiang -- print("here: " .. config["capenabled"]) 1166*22ce4affSfengbojiang for sysc in config["capenabled"]:gmatch("([^,]+)") do 1167*22ce4affSfengbojiang capenabled[sysc] = true 1168*22ce4affSfengbojiang end 1169*22ce4affSfengbojiang config["capenabled"] = capenabled 1170*22ce4affSfengbojiangend 1171*22ce4affSfengbojiangprocess_compat() 1172*22ce4affSfengbojiangprocess_abi_flags() 1173*22ce4affSfengbojiang 1174*22ce4affSfengbojiangif not lfs.mkdir(tmpspace) then 1175*22ce4affSfengbojiang abort(1, "Failed to create tempdir " .. tmpspace) 1176*22ce4affSfengbojiangend 1177*22ce4affSfengbojiang 1178*22ce4affSfengbojiangfor _, v in ipairs(temp_files) do 1179*22ce4affSfengbojiang local tmpname = tmpspace .. v 1180*22ce4affSfengbojiang files[v] = io.open(tmpname, "w+") 1181*22ce4affSfengbojiangend 1182*22ce4affSfengbojiang 1183*22ce4affSfengbojiangfor _, v in ipairs(output_files) do 1184*22ce4affSfengbojiang local tmpname = tmpspace .. v 1185*22ce4affSfengbojiang files[v] = io.open(tmpname, "w+") 1186*22ce4affSfengbojiangend 1187*22ce4affSfengbojiang 1188*22ce4affSfengbojiang-- Write out all of the preamble bits 1189*22ce4affSfengbojiangwrite_line("sysent", string.format([[ 1190*22ce4affSfengbojiang 1191*22ce4affSfengbojiang/* The casts are bogus but will do for now. */ 1192*22ce4affSfengbojiangstruct sysent %s[] = { 1193*22ce4affSfengbojiang]], config['switchname'])) 1194*22ce4affSfengbojiang 1195*22ce4affSfengbojiangwrite_line("syssw", string.format([[/* 1196*22ce4affSfengbojiang * System call switch table. 1197*22ce4affSfengbojiang * 1198*22ce4affSfengbojiang * DO NOT EDIT-- this file is automatically %s. 1199*22ce4affSfengbojiang * $%s$ 1200*22ce4affSfengbojiang */ 1201*22ce4affSfengbojiang 1202*22ce4affSfengbojiang]], generated_tag, config['os_id_keyword'])) 1203*22ce4affSfengbojiang 1204*22ce4affSfengbojiangwrite_line("sysarg", string.format([[/* 1205*22ce4affSfengbojiang * System call prototypes. 1206*22ce4affSfengbojiang * 1207*22ce4affSfengbojiang * DO NOT EDIT-- this file is automatically %s. 1208*22ce4affSfengbojiang * $%s$ 1209*22ce4affSfengbojiang */ 1210*22ce4affSfengbojiang 1211*22ce4affSfengbojiang#ifndef %s 1212*22ce4affSfengbojiang#define %s 1213*22ce4affSfengbojiang 1214*22ce4affSfengbojiang#include <sys/signal.h> 1215*22ce4affSfengbojiang#include <sys/acl.h> 1216*22ce4affSfengbojiang#include <sys/cpuset.h> 1217*22ce4affSfengbojiang#include <sys/domainset.h> 1218*22ce4affSfengbojiang#include <sys/_ffcounter.h> 1219*22ce4affSfengbojiang#include <sys/_semaphore.h> 1220*22ce4affSfengbojiang#include <sys/ucontext.h> 1221*22ce4affSfengbojiang#include <sys/wait.h> 1222*22ce4affSfengbojiang 1223*22ce4affSfengbojiang#include <bsm/audit_kevents.h> 1224*22ce4affSfengbojiang 1225*22ce4affSfengbojiangstruct proc; 1226*22ce4affSfengbojiang 1227*22ce4affSfengbojiangstruct thread; 1228*22ce4affSfengbojiang 1229*22ce4affSfengbojiang#define PAD_(t) (sizeof(register_t) <= sizeof(t) ? \ 1230*22ce4affSfengbojiang 0 : sizeof(register_t) - sizeof(t)) 1231*22ce4affSfengbojiang 1232*22ce4affSfengbojiang#if BYTE_ORDER == LITTLE_ENDIAN 1233*22ce4affSfengbojiang#define PADL_(t) 0 1234*22ce4affSfengbojiang#define PADR_(t) PAD_(t) 1235*22ce4affSfengbojiang#else 1236*22ce4affSfengbojiang#define PADL_(t) PAD_(t) 1237*22ce4affSfengbojiang#define PADR_(t) 0 1238*22ce4affSfengbojiang#endif 1239*22ce4affSfengbojiang 1240*22ce4affSfengbojiang]], generated_tag, config['os_id_keyword'], config['sysproto_h'], 1241*22ce4affSfengbojiang config['sysproto_h'])) 1242*22ce4affSfengbojiangfor _, v in pairs(compat_options) do 1243*22ce4affSfengbojiang write_line(v["tmp"], string.format("\n#ifdef %s\n\n", v["definition"])) 1244*22ce4affSfengbojiangend 1245*22ce4affSfengbojiang 1246*22ce4affSfengbojiangwrite_line("sysnames", string.format([[/* 1247*22ce4affSfengbojiang * System call names. 1248*22ce4affSfengbojiang * 1249*22ce4affSfengbojiang * DO NOT EDIT-- this file is automatically %s. 1250*22ce4affSfengbojiang * $%s$ 1251*22ce4affSfengbojiang */ 1252*22ce4affSfengbojiang 1253*22ce4affSfengbojiangconst char *%s[] = { 1254*22ce4affSfengbojiang]], generated_tag, config['os_id_keyword'], config['namesname'])) 1255*22ce4affSfengbojiang 1256*22ce4affSfengbojiangwrite_line("syshdr", string.format([[/* 1257*22ce4affSfengbojiang * System call numbers. 1258*22ce4affSfengbojiang * 1259*22ce4affSfengbojiang * DO NOT EDIT-- this file is automatically %s. 1260*22ce4affSfengbojiang * $%s$ 1261*22ce4affSfengbojiang */ 1262*22ce4affSfengbojiang 1263*22ce4affSfengbojiang]], generated_tag, config['os_id_keyword'])) 1264*22ce4affSfengbojiang 1265*22ce4affSfengbojiangwrite_line("sysmk", string.format([[# FreeBSD system call object files. 1266*22ce4affSfengbojiang# DO NOT EDIT-- this file is automatically %s. 1267*22ce4affSfengbojiang# $%s$ 1268*22ce4affSfengbojiangMIASM = ]], generated_tag, config['os_id_keyword'])) 1269*22ce4affSfengbojiang 1270*22ce4affSfengbojiangwrite_line("systrace", string.format([[/* 1271*22ce4affSfengbojiang * System call argument to DTrace register array converstion. 1272*22ce4affSfengbojiang * 1273*22ce4affSfengbojiang * DO NOT EDIT-- this file is automatically %s. 1274*22ce4affSfengbojiang * $%s$ 1275*22ce4affSfengbojiang * This file is part of the DTrace syscall provider. 1276*22ce4affSfengbojiang */ 1277*22ce4affSfengbojiang 1278*22ce4affSfengbojiangstatic void 1279*22ce4affSfengbojiangsystrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) 1280*22ce4affSfengbojiang{ 1281*22ce4affSfengbojiang int64_t *iarg = (int64_t *) uarg; 1282*22ce4affSfengbojiang switch (sysnum) { 1283*22ce4affSfengbojiang]], generated_tag, config['os_id_keyword'])) 1284*22ce4affSfengbojiang 1285*22ce4affSfengbojiangwrite_line("systracetmp", [[static void 1286*22ce4affSfengbojiangsystrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) 1287*22ce4affSfengbojiang{ 1288*22ce4affSfengbojiang const char *p = NULL; 1289*22ce4affSfengbojiang switch (sysnum) { 1290*22ce4affSfengbojiang]]) 1291*22ce4affSfengbojiang 1292*22ce4affSfengbojiangwrite_line("systraceret", [[static void 1293*22ce4affSfengbojiangsystrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) 1294*22ce4affSfengbojiang{ 1295*22ce4affSfengbojiang const char *p = NULL; 1296*22ce4affSfengbojiang switch (sysnum) { 1297*22ce4affSfengbojiang]]) 1298*22ce4affSfengbojiang 1299*22ce4affSfengbojiang-- Processing the sysfile will parse out the preprocessor bits and put them into 1300*22ce4affSfengbojiang-- the appropriate place. Any syscall-looking lines get thrown into the sysfile 1301*22ce4affSfengbojiang-- buffer, one per line, for later processing once they're all glued together. 1302*22ce4affSfengbojiangprocess_sysfile(sysfile) 1303*22ce4affSfengbojiang 1304*22ce4affSfengbojiangwrite_line("sysinc", 1305*22ce4affSfengbojiang "\n#define AS(name) (sizeof(struct name) / sizeof(register_t))\n") 1306*22ce4affSfengbojiang 1307*22ce4affSfengbojiangfor _, v in pairs(compat_options) do 1308*22ce4affSfengbojiang if v["count"] > 0 then 1309*22ce4affSfengbojiang write_line("sysinc", string.format([[ 1310*22ce4affSfengbojiang 1311*22ce4affSfengbojiang#ifdef %s 1312*22ce4affSfengbojiang#define %s(n, name) .sy_narg = n, .sy_call = (sy_call_t *)__CONCAT(%s,name) 1313*22ce4affSfengbojiang#else 1314*22ce4affSfengbojiang#define %s(n, name) .sy_narg = 0, .sy_call = (sy_call_t *)nosys 1315*22ce4affSfengbojiang#endif 1316*22ce4affSfengbojiang]], v["definition"], v["flag"]:lower(), v["prefix"], v["flag"]:lower())) 1317*22ce4affSfengbojiang end 1318*22ce4affSfengbojiang 1319*22ce4affSfengbojiang write_line(v["dcltmp"], string.format("\n#endif /* %s */\n\n", 1320*22ce4affSfengbojiang v["definition"])) 1321*22ce4affSfengbojiangend 1322*22ce4affSfengbojiang 1323*22ce4affSfengbojiangwrite_line("sysprotoend", string.format([[ 1324*22ce4affSfengbojiang 1325*22ce4affSfengbojiang#undef PAD_ 1326*22ce4affSfengbojiang#undef PADL_ 1327*22ce4affSfengbojiang#undef PADR_ 1328*22ce4affSfengbojiang 1329*22ce4affSfengbojiang#endif /* !%s */ 1330*22ce4affSfengbojiang]], config["sysproto_h"])) 1331*22ce4affSfengbojiang 1332*22ce4affSfengbojiangwrite_line("sysmk", "\n") 1333*22ce4affSfengbojiangwrite_line("sysent", "};\n") 1334*22ce4affSfengbojiangwrite_line("sysnames", "};\n") 1335*22ce4affSfengbojiang-- maxsyscall is the highest seen; MAXSYSCALL should be one higher 1336*22ce4affSfengbojiangwrite_line("syshdr", string.format("#define\t%sMAXSYSCALL\t%d\n", 1337*22ce4affSfengbojiang config["syscallprefix"], maxsyscall + 1)) 1338*22ce4affSfengbojiangwrite_line("systrace", [[ 1339*22ce4affSfengbojiang default: 1340*22ce4affSfengbojiang *n_args = 0; 1341*22ce4affSfengbojiang break; 1342*22ce4affSfengbojiang }; 1343*22ce4affSfengbojiang} 1344*22ce4affSfengbojiang]]) 1345*22ce4affSfengbojiang 1346*22ce4affSfengbojiangwrite_line("systracetmp", [[ 1347*22ce4affSfengbojiang default: 1348*22ce4affSfengbojiang break; 1349*22ce4affSfengbojiang }; 1350*22ce4affSfengbojiang if (p != NULL) 1351*22ce4affSfengbojiang strlcpy(desc, p, descsz); 1352*22ce4affSfengbojiang} 1353*22ce4affSfengbojiang]]) 1354*22ce4affSfengbojiang 1355*22ce4affSfengbojiangwrite_line("systraceret", [[ 1356*22ce4affSfengbojiang default: 1357*22ce4affSfengbojiang break; 1358*22ce4affSfengbojiang }; 1359*22ce4affSfengbojiang if (p != NULL) 1360*22ce4affSfengbojiang strlcpy(desc, p, descsz); 1361*22ce4affSfengbojiang} 1362*22ce4affSfengbojiang]]) 1363*22ce4affSfengbojiang 1364*22ce4affSfengbojiang-- Finish up; output 1365*22ce4affSfengbojiangwrite_line("syssw", read_file("sysinc")) 1366*22ce4affSfengbojiangwrite_line("syssw", read_file("sysent")) 1367*22ce4affSfengbojiang 1368*22ce4affSfengbojiangwrite_line("sysproto", read_file("sysarg")) 1369*22ce4affSfengbojiangwrite_line("sysproto", read_file("sysdcl")) 1370*22ce4affSfengbojiangfor _, v in pairs(compat_options) do 1371*22ce4affSfengbojiang write_line("sysproto", read_file(v["tmp"])) 1372*22ce4affSfengbojiang write_line("sysproto", read_file(v["dcltmp"])) 1373*22ce4affSfengbojiangend 1374*22ce4affSfengbojiangwrite_line("sysproto", read_file("sysaue")) 1375*22ce4affSfengbojiangwrite_line("sysproto", read_file("sysprotoend")) 1376*22ce4affSfengbojiang 1377*22ce4affSfengbojiangwrite_line("systrace", read_file("systracetmp")) 1378*22ce4affSfengbojiangwrite_line("systrace", read_file("systraceret")) 1379*22ce4affSfengbojiang 1380*22ce4affSfengbojiangfor _, v in ipairs(output_files) do 1381*22ce4affSfengbojiang local target = config[v] 1382*22ce4affSfengbojiang if target ~= "/dev/null" then 1383*22ce4affSfengbojiang local fh = io.open(target, "w+") 1384*22ce4affSfengbojiang if fh == nil then 1385*22ce4affSfengbojiang abort(1, "Failed to open '" .. target .. "'") 1386*22ce4affSfengbojiang end 1387*22ce4affSfengbojiang fh:write(read_file(v)) 1388*22ce4affSfengbojiang fh:close() 1389*22ce4affSfengbojiang end 1390*22ce4affSfengbojiangend 1391*22ce4affSfengbojiang 1392*22ce4affSfengbojiangcleanup() 1393