aboutsummaryrefslogtreecommitdiff
path: root/sys/tools
diff options
context:
space:
mode:
authorBrooks Davis <brooks@FreeBSD.org>2021-11-22 22:36:57 +0000
committerBrooks Davis <brooks@FreeBSD.org>2021-11-22 22:36:57 +0000
commit64007b000a2fdbac64c35aa05dd192609325a0a3 (patch)
tree664d1c08cf842abd250e17158f18ad3464a64acc /sys/tools
parent79634eb90bff52e9b651bdae6f57082741778d1b (diff)
downloadsrc-64007b000a2fdbac64c35aa05dd192609325a0a3.tar.gz
src-64007b000a2fdbac64c35aa05dd192609325a0a3.zip
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
Diffstat (limited to 'sys/tools')
-rw-r--r--sys/tools/makesyscalls.lua106
1 files 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']))