Last active
August 29, 2015 14:02
-
-
Save annulen/8e487a489ba77a6c7d56 to your computer and use it in GitHub Desktop.
Proof of concept for sysdig code generation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
flags { | |
poll = { | |
"POLLIN", | |
"POLLPRI", | |
"POLLOUT", | |
"POLLRDHUP", | |
"POLLERR", | |
"POLLHUP", | |
"POLLNVAL", | |
"POLLRDNORM", | |
"POLLRDBAND", | |
"POLLWRNORM", | |
"POLLWRBAND" | |
}, | |
prot = { | |
[0] = "PROT_NONE", | |
"PROT_READ", | |
"PROT_WRITE", | |
"PROT_EXEC", | |
"PROT_SEM", | |
"PROT_GROWSDOWN", | |
"PROT_GROWSUP", | |
"PROT_SAO" | |
}, | |
mmap = { | |
"MAP_SHARED", | |
"MAP_PRIVATE", | |
"MAP_FIXED", | |
"MAP_ANONYMOUS", | |
"MAP_32BIT", | |
"MAP_RENAME", | |
"MAP_NORESERVE", | |
"MAP_POPULATE", | |
"MAP_NONBLOCK", | |
"MAP_GROWSDOWN", | |
"MAP_DENYWRITE", | |
"MAP_EXECUTABLE", | |
"MAP_INHERIT", | |
"MAP_FILE", | |
"MAP_LOCKED" | |
}, | |
splice = { | |
"SPLICE_F_MOVE", | |
"SPLICE_F_NONBLOCK", | |
"SPLICE_F_MORE", | |
"SPLICE_F_GIFT" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
syscalls { | |
{ | |
syscall = "brk", | |
category = "EC_MEMORY", | |
enter_params = { UINT64("addr", HEX) }, | |
exit_params = { UINT64("res", HEX), | |
UINT32("vm_size"), UINT32("vm_rss"), UINT32("vm_swap") }, | |
fillers = { enter = AUTOFILL(0), exit = "f_sys_brk_munmap_mmap_x" } | |
}, | |
{ | |
syscall = "mmap", | |
category = "EC_MEMORY", | |
enter_params = { UINT64("addr", HEX), UINT64("length"), | |
FLAGS32("prot", flags.prot), FLAGS32("flags", flags.mmap), | |
FD("fd"), UINT64("offset") }, | |
exit_params = { ERRNO("res"), | |
UINT32("vm_size"), UINT32("vm_rss"), UINT32("vm_swap") }, | |
fillers = { enter = "f_sys_mmap_e", exit = "f_sys_brk_munmap_mmap_x" } | |
}, | |
{ | |
syscall = "mmap2", | |
category = "EC_MEMORY", | |
enter_params = { UINT64("addr", HEX), UINT64("length"), | |
FLAGS32("prot", flags.prot), FLAGS32("flags", flags.mmap), | |
FD("fd"), UINT64("pgoffset") }, | |
exit_params = { ERRNO("res"), | |
UINT32("vm_size"), UINT32("vm_rss"), UINT32("vm_swap") }, | |
fillers = { enter = "f_sys_mmap_e", exit = "f_sys_brk_munmap_mmap_x" } | |
}, | |
{ | |
syscall = "munmap", | |
category = "EC_MEMORY", | |
enter_params = { UINT64("addr", HEX), UINT64("length") }, | |
exit_params = { ERRNO("res"), | |
UINT32("vm_size"), UINT32("vm_rss"), UINT32("vm_swap") }, | |
fillers = { enter = AUTOFILL(0, 1), exit = "f_sys_brk_munmap_mmap_x" } | |
}, | |
{ | |
syscall = "splice", | |
category = "EC_IO_OTHER", | |
never_drop = true, | |
flags = { "EF_USES_FD", "EF_NONE" }, | |
enter_params = { FD("fd_in"), FD("fd_out"), UINT64("size"), | |
FLAGS32("flags", flags.splice) }, | |
exit_params = { ERRNO("res") }, | |
fillers = { enter = AUTOFILL(0, 2, 4, 5), exit = AUTOFILL(RETVAL) } | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PPME_SYSCALL_BRK_E = 158, | |
PPME_SYSCALL_BRK_X = 159, | |
PPME_SYSCALL_MMAP_E = 160, | |
PPME_SYSCALL_MMAP_X = 161, | |
PPME_SYSCALL_MMAP2_E = 162, | |
PPME_SYSCALL_MMAP2_X = 163, | |
PPME_SYSCALL_MUNMAP_E = 164, | |
PPME_SYSCALL_MUNMAP_X = 165, | |
PPME_SYSCALL_SPLICE_E = 166, | |
PPME_SYSCALL_SPLICE_X = 167, | |
PPM_EVENT_MAX = 168 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* PPME_SYSCALL_BRK_E */{ "brk", | |
EC_MEMORY, | |
EF_NONE, | |
1, | |
{ { "addr", PT_UINT64, PF_HEX } } }, | |
/* PPME_SYSCALL_BRK_X */{ "brk", | |
EC_MEMORY, | |
EF_NONE, | |
4, | |
{ { "res", PT_UINT64, PF_HEX }, { "vm_size", PT_UINT32, PF_DEC }, { "vm_rss", PT_UINT32, PF_DEC }, { "vm_swap", PT_UINT32, PF_DEC } } }, | |
/* PPME_SYSCALL_MMAP_E */{ "mmap", | |
EC_MEMORY, | |
EF_NONE, | |
6, | |
{ { "addr", PT_UINT64, PF_HEX }, { "length", PT_UINT64, PF_DEC }, { "prot", PT_FLAGS32, PF_HEX, prot_flags }, { "flags", PT_FLAGS32, PF_HEX, mmap_flags }, { "fd", PT_FD, PF_DEC }, { "offset", PT_UINT64, PF_DEC } } }, | |
/* PPME_SYSCALL_MMAP_X */{ "mmap", | |
EC_MEMORY, | |
EF_NONE, | |
4, | |
{ { "res", PT_ERRNO, PF_DEC }, { "vm_size", PT_UINT32, PF_DEC }, { "vm_rss", PT_UINT32, PF_DEC }, { "vm_swap", PT_UINT32, PF_DEC } } }, | |
/* PPME_SYSCALL_MMAP2_E */{ "mmap2", | |
EC_MEMORY, | |
EF_NONE, | |
6, | |
{ { "addr", PT_UINT64, PF_HEX }, { "length", PT_UINT64, PF_DEC }, { "prot", PT_FLAGS32, PF_HEX, prot_flags }, { "flags", PT_FLAGS32, PF_HEX, mmap_flags }, { "fd", PT_FD, PF_DEC }, { "pgoffset", PT_UINT64, PF_DEC } } }, | |
/* PPME_SYSCALL_MMAP2_X */{ "mmap2", | |
EC_MEMORY, | |
EF_NONE, | |
4, | |
{ { "res", PT_ERRNO, PF_DEC }, { "vm_size", PT_UINT32, PF_DEC }, { "vm_rss", PT_UINT32, PF_DEC }, { "vm_swap", PT_UINT32, PF_DEC } } }, | |
/* PPME_SYSCALL_MUNMAP_E */{ "munmap", | |
EC_MEMORY, | |
EF_NONE, | |
2, | |
{ { "addr", PT_UINT64, PF_HEX }, { "length", PT_UINT64, PF_DEC } } }, | |
/* PPME_SYSCALL_MUNMAP_X */{ "munmap", | |
EC_MEMORY, | |
EF_NONE, | |
4, | |
{ { "res", PT_ERRNO, PF_DEC }, { "vm_size", PT_UINT32, PF_DEC }, { "vm_rss", PT_UINT32, PF_DEC }, { "vm_swap", PT_UINT32, PF_DEC } } }, | |
/* PPME_SYSCALL_SPLICE_E */{ "splice", | |
EC_IO_OTHER, | |
(enum ppm_event_flags)(EF_USES_FD | EF_NONE), | |
4, | |
{ { "fd_in", PT_FD, PF_DEC }, { "fd_out", PT_FD, PF_DEC }, { "size", PT_UINT64, PF_DEC }, { "flags", PT_FLAGS32, PF_HEX, splice_flags } } }, | |
/* PPME_SYSCALL_SPLICE_X */{ "splice", | |
EC_IO_OTHER, | |
(enum ppm_event_flags)(EF_USES_FD | EF_NONE), | |
1, | |
{ { "res", PT_ERRNO, PF_DEC } } }, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef __NR_brk | |
[__NR_brk - SYSCALL_TABLE_ID0] = { UF_USED, PPME_SYSCALL_BRK_E, PPME_SYSCALL_BRK_X }, | |
#endif | |
#ifdef __NR_mmap | |
[__NR_mmap - SYSCALL_TABLE_ID0] = { UF_USED, PPME_SYSCALL_MMAP_E, PPME_SYSCALL_MMAP_X }, | |
#endif | |
#ifdef __NR_mmap2 | |
[__NR_mmap2 - SYSCALL_TABLE_ID0] = { UF_USED, PPME_SYSCALL_MMAP2_E, PPME_SYSCALL_MMAP2_X }, | |
#endif | |
#ifdef __NR_munmap | |
[__NR_munmap - SYSCALL_TABLE_ID0] = { UF_USED, PPME_SYSCALL_MUNMAP_E, PPME_SYSCALL_MUNMAP_X }, | |
#endif | |
#ifdef __NR_splice | |
[__NR_splice - SYSCALL_TABLE_ID0] = { UF_USED | UF_NEVER_DROP, PPME_SYSCALL_SPLICE_E, PPME_SYSCALL_SPLICE_X }, | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* poll_flags*/ | |
#define PPM_POLLIN (1 << 0) | |
#define PPM_POLLPRI (1 << 1) | |
#define PPM_POLLOUT (1 << 2) | |
#define PPM_POLLRDHUP (1 << 3) | |
#define PPM_POLLERR (1 << 4) | |
#define PPM_POLLHUP (1 << 5) | |
#define PPM_POLLNVAL (1 << 6) | |
#define PPM_POLLRDNORM (1 << 7) | |
#define PPM_POLLRDBAND (1 << 8) | |
#define PPM_POLLWRNORM (1 << 9) | |
#define PPM_POLLWRBAND (1 << 10) | |
extern const struct ppm_name_value poll_flags[]; | |
/* splice_flags*/ | |
#define PPM_SPLICE_F_MOVE (1 << 0) | |
#define PPM_SPLICE_F_NONBLOCK (1 << 1) | |
#define PPM_SPLICE_F_MORE (1 << 2) | |
#define PPM_SPLICE_F_GIFT (1 << 3) | |
extern const struct ppm_name_value splice_flags[]; | |
/* mmap_flags*/ | |
#define PPM_MAP_SHARED (1 << 0) | |
#define PPM_MAP_PRIVATE (1 << 1) | |
#define PPM_MAP_FIXED (1 << 2) | |
#define PPM_MAP_ANONYMOUS (1 << 3) | |
#define PPM_MAP_32BIT (1 << 4) | |
#define PPM_MAP_RENAME (1 << 5) | |
#define PPM_MAP_NORESERVE (1 << 6) | |
#define PPM_MAP_POPULATE (1 << 7) | |
#define PPM_MAP_NONBLOCK (1 << 8) | |
#define PPM_MAP_GROWSDOWN (1 << 9) | |
#define PPM_MAP_DENYWRITE (1 << 10) | |
#define PPM_MAP_EXECUTABLE (1 << 11) | |
#define PPM_MAP_INHERIT (1 << 12) | |
#define PPM_MAP_FILE (1 << 13) | |
#define PPM_MAP_LOCKED (1 << 14) | |
extern const struct ppm_name_value mmap_flags[]; | |
/* prot_flags*/ | |
#define PPM_PROT_NONE 0 | |
#define PPM_PROT_READ (1 << 0) | |
#define PPM_PROT_WRITE (1 << 1) | |
#define PPM_PROT_EXEC (1 << 2) | |
#define PPM_PROT_SEM (1 << 3) | |
#define PPM_PROT_GROWSDOWN (1 << 4) | |
#define PPM_PROT_GROWSUP (1 << 5) | |
#define PPM_PROT_SAO (1 << 6) | |
extern const struct ppm_name_value prot_flags[]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const struct ppm_name_value poll_flags[] = { | |
{ "POLLIN", PPM_POLLIN }, | |
{ "POLLPRI", PPM_POLLPRI }, | |
{ "POLLOUT", PPM_POLLOUT }, | |
{ "POLLRDHUP", PPM_POLLRDHUP }, | |
{ "POLLERR", PPM_POLLERR }, | |
{ "POLLHUP", PPM_POLLHUP }, | |
{ "POLLNVAL", PPM_POLLNVAL }, | |
{ "POLLRDNORM", PPM_POLLRDNORM }, | |
{ "POLLRDBAND", PPM_POLLRDBAND }, | |
{ "POLLWRNORM", PPM_POLLWRNORM }, | |
{ "POLLWRBAND", PPM_POLLWRBAND }, | |
{ } | |
} | |
const struct ppm_name_value splice_flags[] = { | |
{ "SPLICE_F_MOVE", PPM_SPLICE_F_MOVE }, | |
{ "SPLICE_F_NONBLOCK", PPM_SPLICE_F_NONBLOCK }, | |
{ "SPLICE_F_MORE", PPM_SPLICE_F_MORE }, | |
{ "SPLICE_F_GIFT", PPM_SPLICE_F_GIFT }, | |
{ } | |
} | |
const struct ppm_name_value mmap_flags[] = { | |
{ "MAP_SHARED", PPM_MAP_SHARED }, | |
{ "MAP_PRIVATE", PPM_MAP_PRIVATE }, | |
{ "MAP_FIXED", PPM_MAP_FIXED }, | |
{ "MAP_ANONYMOUS", PPM_MAP_ANONYMOUS }, | |
{ "MAP_32BIT", PPM_MAP_32BIT }, | |
{ "MAP_RENAME", PPM_MAP_RENAME }, | |
{ "MAP_NORESERVE", PPM_MAP_NORESERVE }, | |
{ "MAP_POPULATE", PPM_MAP_POPULATE }, | |
{ "MAP_NONBLOCK", PPM_MAP_NONBLOCK }, | |
{ "MAP_GROWSDOWN", PPM_MAP_GROWSDOWN }, | |
{ "MAP_DENYWRITE", PPM_MAP_DENYWRITE }, | |
{ "MAP_EXECUTABLE", PPM_MAP_EXECUTABLE }, | |
{ "MAP_INHERIT", PPM_MAP_INHERIT }, | |
{ "MAP_FILE", PPM_MAP_FILE }, | |
{ "MAP_LOCKED", PPM_MAP_LOCKED }, | |
{ } | |
} | |
const struct ppm_name_value prot_flags[] = { | |
{ "PROT_READ", PPM_PROT_READ }, | |
{ "PROT_WRITE", PPM_PROT_WRITE }, | |
{ "PROT_EXEC", PPM_PROT_EXEC }, | |
{ "PROT_SEM", PPM_PROT_SEM }, | |
{ "PROT_GROWSDOWN", PPM_PROT_GROWSDOWN }, | |
{ "PROT_GROWSUP", PPM_PROT_GROWSUP }, | |
{ "PROT_SAO", PPM_PROT_SAO }, | |
{ } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[PPME_SYSCALL_BRK_E] = {PPM_AUTOFILL, 1, APT_REG, { {0} }}, | |
[PPME_SYSCALL_BRK_X] = {f_sys_brk_munmap_mmap_x}, | |
[PPME_SYSCALL_MMAP_E] = {f_sys_mmap_e}, | |
[PPME_SYSCALL_MMAP_X] = {f_sys_brk_munmap_mmap_x}, | |
[PPME_SYSCALL_MMAP2_E] = {f_sys_mmap_e}, | |
[PPME_SYSCALL_MMAP2_X] = {f_sys_brk_munmap_mmap_x}, | |
[PPME_SYSCALL_MUNMAP_E] = {PPM_AUTOFILL, 2, APT_REG, { {0}, {1} }}, | |
[PPME_SYSCALL_MUNMAP_X] = {f_sys_brk_munmap_mmap_x}, | |
[PPME_SYSCALL_SPLICE_E] = {PPM_AUTOFILL, 4, APT_SOCK, { {0}, {2}, {4}, {5} }}, | |
[PPME_SYSCALL_SPLICE_X] = {PPM_AUTOFILL, 1, APT_REG, { {AF_ID_RETVAL} }}, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Generate syscall defintions for sysdig | |
-- (c) 2014 Konstantin Tokarev | |
require "strict" | |
-- Makes table immutable and forbids indexing undeclared keys | |
-- Inspired by strict.lua | |
local function protect_table(table, tablename) | |
local mt = {} | |
mt.tn = tablename | |
mt.__newindex = function(t, n, v) | |
local varname = mt.tn .. '.' .. n | |
error("cannot assign variable '" .. varname .. '" - table is protected', 2) | |
end | |
mt.__index = function(t, n) | |
local value = rawget(t, n) | |
if not value then | |
local varname = mt.tn .. '.' .. n | |
error("variable '" .. varname .."' is not defined", 2) | |
end | |
return value | |
end | |
setmetatable(table, mt) | |
end | |
-- Opens file for write | |
local function openw(file) | |
return io.open(file, "w") | |
end | |
----------------------------------- | |
-- Serialization of data structures | |
----------------------------------- | |
local function quoted(str) | |
return '"' .. (str or '') .. '"' | |
end | |
local function c_array(array, sep) | |
sep = sep or ' ' | |
return '{ ' .. table.concat(array, ',' .. sep) .. ' }' | |
end | |
local function serialize_syscall_params(syscall_params) | |
local res = {} | |
for _, p in ipairs(syscall_params) do | |
-- Insert defaults | |
if not p.type then error("type is missing") end | |
if not p.fmt then error("fmt is missing") end | |
res[#res + 1] = c_array { quoted(p.name), p.type, p.fmt, p.flags } | |
end | |
return res | |
end | |
local function serialize_flags(flags) | |
if #flags == 1 then | |
return flags[1] | |
else | |
return '(enum ppm_event_flags)(' .. table.concat(flags, ' | ') .. ')' | |
end | |
end | |
local function serialize_autofill(params) | |
local paramtype = "APT_REG" | |
if type(params[1]) == "string" then | |
-- Assert on unknown type? | |
if params[1]:find("^APT_") then | |
paramtype = table.remove(params, 1) | |
end | |
end | |
local nums = {} | |
for _, v in ipairs(params) do | |
nums[#nums + 1] = '{' .. v .. '}' | |
end | |
return table.concat({"PPM_AUTOFILL", #nums, paramtype, c_array(nums)}, ', ') | |
end | |
----------------------------------- | |
-- Code writers | |
----------------------------------- | |
local event_counter = 158 | |
local event_type = openw("event_type.inc") | |
local event_info = openw("event_info.inc") | |
local syscall_table = openw("syscall_table.inc") | |
local flags_h = openw("flags.h") | |
local flags_c = openw("flags.c") | |
local fillers = openw("ppm_events.inc") | |
local function write_event_type(id) | |
event_type:write(id, " = ", event_counter, ",\n") | |
end | |
local function finalize_event_type() | |
event_type:write("PPM_EVENT_MAX = ", event_counter, "\n") | |
end | |
local function write_event_info(id, props, params) | |
local comment = '/* ' .. id .. ' */' | |
local param_array = serialize_syscall_params(params) | |
if not props.flags then | |
props.flags = { "EF_NONE" } | |
end | |
local info = { | |
quoted(props.syscall), | |
props.category, | |
serialize_flags(props.flags), | |
#param_array, | |
c_array(param_array) | |
} | |
event_info:write(comment, c_array(info, '\n\t'), ',\n') | |
end | |
local function write_event(id, props, params) | |
write_event_type(id) | |
write_event_info(id, props, params) | |
event_counter = event_counter + 1 | |
end | |
local function write_filler(id, filler) | |
fillers:write('[', id, '] = {', filler, '},\n') | |
end | |
local function write_syscall_table(props, evt_e, evt_x) | |
local NR_syscall = '__NR_' .. props.syscall | |
local uf_flags = props.never_drop and 'UF_USED | UF_NEVER_DROP' or 'UF_USED' | |
local value = c_array{uf_flags, evt_e, evt_x} | |
syscall_table:write( | |
'#ifdef ', NR_syscall, '\n', | |
'\t[', NR_syscall, ' - SYSCALL_TABLE_ID0] =\t\t', value, ',\n', | |
'#endif\n' | |
) | |
end | |
local function validateSyscallEntry(props) | |
end | |
local function write_syscalls(table) | |
for _, props in ipairs(table) do | |
validateSyscallEntry(props) | |
local evt_id = "PPME_SYSCALL_" .. props.syscall:upper() | |
local enter_evt_id = evt_id .. "_E" | |
local exit_evt_id = evt_id .. "_X" | |
write_event(enter_evt_id, props, props.enter_params) | |
write_event(exit_evt_id, props, props.exit_params) | |
if props.fillers then | |
write_filler(enter_evt_id, props.fillers.enter) | |
write_filler(exit_evt_id, props.fillers.exit) | |
end | |
write_syscall_table(props, enter_evt_id, exit_evt_id) | |
end | |
finalize_event_type() | |
end | |
local function write_flags_h(name, flags) | |
flags_h:write('/* ', name, '*/\n') | |
if flags[0] then | |
flags_h:write('#define PPM_', flags[0], '\t\t0\n') | |
end | |
for i, flag in ipairs(flags) do | |
flags_h:write('#define PPM_', flag, '\t\t(1 << ', i-1, ')\n') | |
end | |
flags_h:write('\nextern const struct ppm_name_value ', | |
name, '[];\n\n') | |
end | |
local function write_flags_c(name, flags) | |
flags_c:write('const struct ppm_name_value ', name, '[] = {\n') | |
for _, flag in ipairs(flags) do | |
flags_c:write('\t{ "', flag, '", PPM_', flag, ' },\n') | |
end | |
flags_c:write('\t{ }\n', '}\n\n') | |
end | |
local function write_flags(table) | |
for k, v in pairs(table) do | |
local array_name = k .. "_flags" -- e.g. "file_flags" | |
write_flags_h(array_name, v) | |
write_flags_c(array_name, v) | |
table[k] = array_name | |
end | |
end | |
----------------------------------- | |
-- API generators | |
----------------------------------- | |
-- API function with 1 paramter (name), uses predefined type and fmt, no flags | |
local function api_name(_type, _fmt) | |
assert(_type and _fmt, "Invalid api declaration") | |
return function(pname) | |
return { name = pname, type = _type, fmt = _fmt } | |
end | |
end | |
-- API function with 2 parameters (name, fmt), uses predefined type, | |
-- fmt is optional (predefined used if left unspecifed) | |
-- no flags | |
local function api_name_fmt(_type, _fmt) | |
assert(_type, "Invalid api declaration") | |
return function(pname, pfmt) | |
return { name = pname, type = _type, fmt = pfmt or _fmt } | |
end | |
end | |
-- API function with 2 parameters (name, flags), uses predefined type and fmt | |
local function api_name_flags(_type, _fmt) | |
assert(_type and _fmt, "Invalid api declaration") | |
return function(pname, pflags) | |
return { name = pname, type = _type, fmt = _fmt, flags = pflags } | |
end | |
end | |
--------------------------------------- | |
-- Global declarations for syscalls.lua | |
--------------------------------------- | |
flags = function(t) | |
write_flags(t) | |
protect_table(t, "flags") | |
_G.flags = t -- Use flags.xxx in code below | |
end | |
syscalls = function(t) | |
write_syscalls(t) | |
_G.syscalls = nil -- Only one syscalls{} block is allowed | |
end | |
AUTOFILL = function(...) | |
return serialize_autofill({...}) | |
end | |
REG = "APT_REG" | |
SOCK = "APT_SOCK" | |
DEFAULT = "AF_ID_DEFAULT" | |
RETVAL = "AF_ID_RETVAL" | |
DEC = "PF_DEC" | |
HEX = "PF_HEX" | |
INT8 = api_name_fmt("PT_INT8", "PF_DEC") | |
INT16 = api_name_fmt("PT_INT16", "PF_DEC") | |
INT32 = api_name_fmt("PT_INT32", "PF_DEC") | |
INT64 = api_name_fmt("PT_INT64", "PF_DEC") | |
UINT8 = api_name_fmt("PT_UINT8", "PF_DEC") | |
UINT16 = api_name_fmt("PT_UINT16", "PF_DEC") | |
UINT32 = api_name_fmt("PT_UINT32", "PF_DEC") | |
UINT64 = api_name_fmt("PT_UINT64", "PF_DEC") | |
ERRNO = api_name("PT_ERRNO", "PF_DEC") | |
FD = api_name("PT_FD", "PF_DEC") | |
FLAGS8 = api_name_flags("PT_FLAGS8", "PF_DEC") | |
FLAGS16 = api_name_flags("PT_FLAGS16", "PF_HEX") | |
FLAGS32 = api_name_flags("PT_FLAGS32", "PF_HEX") | |
----------------------------------- | |
-- Do it! | |
----------------------------------- | |
assert(loadfile("flags.lua"))() | |
assert(loadfile("syscalls.lua"))() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- strict.lua | |
-- checks uses of undeclared global variables | |
-- All global variables must be 'declared' through a regular assignment | |
-- (even assigning nil will do) in a main chunk before being used | |
-- anywhere or assigned to inside a function. | |
-- distributed under the Lua license: http://www.lua.org/license.html | |
local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget | |
local mt = getmetatable(_G) | |
if mt == nil then | |
mt = {} | |
setmetatable(_G, mt) | |
end | |
mt.__declared = {} | |
local function what () | |
local d = getinfo(3, "S") | |
return d and d.what or "C" | |
end | |
mt.__newindex = function (t, n, v) | |
if not mt.__declared[n] then | |
local w = what() | |
if w ~= "main" and w ~= "C" then | |
error("assign to undeclared variable '"..n.."'", 2) | |
end | |
mt.__declared[n] = true | |
end | |
rawset(t, n, v) | |
end | |
mt.__index = function (t, n) | |
if not mt.__declared[n] and what() ~= "C" then | |
error("variable '"..n.."' is not declared", 2) | |
end | |
return rawget(t, n) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment