git: 64007b000a2f - main - makesyscalls: handle 64-bit args on 32-bit
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 22 Nov 2021 22:37:53 UTC
The branch main has been updated by brooks: URL: https://cgit.FreeBSD.org/src/commit/?id=64007b000a2fdbac64c35aa05dd192609325a0a3 commit 64007b000a2fdbac64c35aa05dd192609325a0a3 Author: Brooks Davis <brooks@FreeBSD.org> AuthorDate: 2021-11-22 22:36:57 +0000 Commit: Brooks Davis <brooks@FreeBSD.org> CommitDate: 2021-11-22 22:36:57 +0000 makesyscalls: handle 64-bit args on 32-bit On 32-bit architectures, 64-bit arguments are passed in pairs of registers. On non-x86 architectures these arguments must be in evenly aligned registers which necessiciates inserting a pad register into the argument list. This has historically been supported by adding ifdefs around padded and unpadded syscall defintions in syscalls.master. In order to enable generation of 32-bit support files from the base syscalls.master, pull this support in to makesyscalls.lua enabled by adding pair_64bit to abi_flags. The changes to sys_proto.h simply add #ifdef PAD64_REQUIRED around pad arguments in struct <syscall>_args. In systrace_args(), replace static syscall index values with post-incremented indexs allowing a simple ifdef around the argument. Under -O1 or higher code generation is identical. systrace_entry_setargdesc() is a bit more complicated as we switch on argument indices. Solve this with some use of define/undef pairs to compute the correct indices. Reviewed by: kevans --- sys/tools/makesyscalls.lua | 106 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 87 insertions(+), 19 deletions(-) diff --git a/sys/tools/makesyscalls.lua b/sys/tools/makesyscalls.lua index a5387463e4e2..1e66a6b319f3 100644 --- a/sys/tools/makesyscalls.lua +++ b/sys/tools/makesyscalls.lua @@ -167,6 +167,14 @@ local known_abi_flags = { "[*][*]", }, }, + pair_64bit = { + value = 0x00000010, + exprs = { + "^dev_t[ ]*$", + "^id_t[ ]*$", + "^off_t[ ]*$", + }, + }, } local known_flags = { @@ -426,6 +434,11 @@ local function isptrarraytype(type) return type:find("[*][*]") or type:find("[*][ ]*const[ ]*[*]") end +-- Find types that are always 64-bits wide +local function is64bittype(type) + return type:find("^dev_t[ ]*$") or type:find("^id_t[ ]*$") or type:find("^off_t[ ]*$") +end + local process_syscall_def -- These patterns are processed in order on any line that isn't empty. @@ -648,10 +661,27 @@ local function process_args(args) abi_type_suffix) end - funcargs[#funcargs + 1] = { - type = argtype, - name = argname, - } + if abi_changes("pair_64bit") and is64bittype(argtype) then + if #funcargs % 2 == 1 then + funcargs[#funcargs + 1] = { + type = "int", + name = "_pad", + } + end + funcargs[#funcargs + 1] = { + type = "uint32_t", + name = argname .. "1", + } + funcargs[#funcargs + 1] = { + type = "uint32_t", + name = argname .. "2", + } + else + funcargs[#funcargs + 1] = { + type = argtype, + name = argname, + } + end end ::out:: @@ -686,45 +716,62 @@ local function handle_noncompat(sysnum, thr_flag, flags, sysflags, rettype, write_line("systrace", string.format( "\t\tstruct %s *p = params;\n", argalias)) - local argtype, argname + + local argtype, argname, desc, padding + padding = "" for idx, arg in ipairs(funcargs) do argtype = arg["type"] argname = arg["name"] argtype = trim(argtype:gsub("__restrict$", ""), nil) + if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then + write_line("systracetmp", "#ifdef PAD64_REQUIRED\n") + end -- Pointer arg? if argtype:find("*") then - write_line("systracetmp", string.format( - "\t\tcase %d:\n\t\t\tp = \"userland %s\";\n\t\t\tbreak;\n", - idx - 1, argtype)) + desc = "userland " .. argtype else - write_line("systracetmp", string.format( - "\t\tcase %d:\n\t\t\tp = \"%s\";\n\t\t\tbreak;\n", - idx - 1, argtype)) + desc = argtype; + end + write_line("systracetmp", string.format( + "\t\tcase %d%s:\n\t\t\tp = \"%s\";\n\t\t\tbreak;\n", + idx - 1, padding, desc)) + if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then + padding = " - _P_" + write_line("systracetmp", "#define _P_ 0\n#else\n#define _P_ 1\n#endif\n") end if isptrtype(argtype) then write_line("systrace", string.format( - "\t\tuarg[%d] = (%s)p->%s; /* %s */\n", - idx - 1, config["ptr_intptr_t_cast"], + "\t\tuarg[a++] = (%s)p->%s; /* %s */\n", + config["ptr_intptr_t_cast"], argname, argtype)) elseif argtype == "union l_semun" then write_line("systrace", string.format( - "\t\tuarg[%d] = p->%s.buf; /* %s */\n", - idx - 1, argname, argtype)) + "\t\tuarg[a++] = p->%s.buf; /* %s */\n", + argname, argtype)) elseif argtype:sub(1,1) == "u" or argtype == "size_t" then write_line("systrace", string.format( - "\t\tuarg[%d] = p->%s; /* %s */\n", - idx - 1, argname, argtype)) + "\t\tuarg[a++] = p->%s; /* %s */\n", + argname, argtype)) else + if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then + write_line("systrace", "#ifdef PAD64_REQUIRED\n") + end write_line("systrace", string.format( - "\t\tiarg[%d] = p->%s; /* %s */\n", - idx - 1, argname, argtype)) + "\t\tiarg[a++] = p->%s; /* %s */\n", + argname, argtype)) + if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then + write_line("systrace", "#endif\n") + end end end write_line("systracetmp", "\t\tdefault:\n\t\t\tbreak;\n\t\t};\n") + if padding ~= "" then + write_line("systracetmp", "#undef _P_\n\n") + end write_line("systraceret", string.format([[ if (ndx == 0 || ndx == 1) @@ -743,11 +790,17 @@ local function handle_noncompat(sysnum, thr_flag, flags, sysflags, rettype, argalias)) for _, v in ipairs(funcargs) do local argname, argtype = v["name"], v["type"] + if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then + write_line("sysarg", "#ifdef PAD64_REQUIRED\n") + end write_line("sysarg", string.format( "\tchar %s_l_[PADL_(%s)]; %s %s; char %s_r_[PADR_(%s)];\n", argname, argtype, argtype, argname, argname, argtype)) + if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then + write_line("sysarg", "#endif\n") + end end write_line("sysarg", "};\n") else @@ -1284,6 +1337,20 @@ struct thread; ]], generated_tag, config['os_id_keyword'], config['sysproto_h'], config['sysproto_h'])) +if abi_changes("pair_64bit") then + write_line("sysarg", string.format([[ +#if !defined(PAD64_REQUIRED) && !defined(__amd64__) +#define PAD64_REQUIRED +#endif +]])) +end +if abi_changes("pair_64bit") then + write_line("systrace", string.format([[ +#if !defined(PAD64_REQUIRED) && !defined(__amd64__) +#define PAD64_REQUIRED +#endif +]])) +end for _, v in pairs(compat_options) do write_line(v["tmp"], string.format("\n#ifdef %s\n\n", v["definition"])) end @@ -1324,6 +1391,7 @@ static void systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) { int64_t *iarg = (int64_t *)uarg; + int a = 0; switch (sysnum) { ]], generated_tag, config['os_id_keyword']))