19ded074eSagge3-- 29ded074eSagge3-- SPDX-License-Identifier: BSD-2-Clause 39ded074eSagge3-- 49ded074eSagge3-- Copyright (c) 2021-2024 SRI International 59ded074eSagge3-- Copyright (c) 2024 Tyler Baxter <agge@FreeBSD.org> 69ded074eSagge3-- Copyright (c) 2023 Warner Losh <imp@bsdimp.com> 79ded074eSagge3-- Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org> 89ded074eSagge3-- 99ded074eSagge3 109ded074eSagge3local config = require("config") 119ded074eSagge3local util = require("tools.util") 129ded074eSagge3 139ded074eSagge3local scarg = {} 149ded074eSagge3 159ded074eSagge3scarg.__index = scarg 169ded074eSagge3 179ded074eSagge3-- Check this argument against config for ABI changes from native. Return TRUE 189ded074eSagge3-- if there are. 199ded074eSagge3local function checkAbiChanges(arg) 209ded074eSagge3 for k, v in pairs(config.known_abi_flags) do 219ded074eSagge3 if config.abiChanges(k) and v ~= nil then 229ded074eSagge3 for _, e in pairs(v) do 239ded074eSagge3 if arg:find(e) then 249ded074eSagge3 return true 259ded074eSagge3 end 269ded074eSagge3 end 279ded074eSagge3 end 289ded074eSagge3 end 299ded074eSagge3 return false 309ded074eSagge3end 319ded074eSagge3 329ded074eSagge3-- Strips the Microsoft(R) SAL annotations from this argument. 339ded074eSagge3local function stripArgAnnotations(arg) 349ded074eSagge3 arg = arg:gsub("_Contains_[^ ]*[_)] ?", "") 359ded074eSagge3 arg = arg:gsub("_In[^ ]*[_)] ?", "") 369ded074eSagge3 arg = arg:gsub("_Out[^ ]*[_)] ?", "") 379ded074eSagge3 return util.trim(arg) 389ded074eSagge3end 399ded074eSagge3 409ded074eSagge3-- Preprocessing of this argument. 419ded074eSagge3function scarg:init(line) 429ded074eSagge3 -- Trim whitespace and trailing comma. We don't want them here; 439ded074eSagge3 -- these can mess with our processing of this argument. 449ded074eSagge3 line = util.trim(line) -- This provides a clearer abort error. 459ded074eSagge3 self.scarg = util.trim(line, ',') 469ded074eSagge3 479ded074eSagge3 self.arg_abi_change = checkAbiChanges(self.scarg) 489ded074eSagge3 self.changes_abi = self.arg_abi_change 499ded074eSagge3 self.scarg = stripArgAnnotations(self.scarg) 509ded074eSagge3 519ded074eSagge3 self.name = self.scarg:match("([^* ]+)$") 529ded074eSagge3 -- Our pattern might produce a Lua pattern sequence; that's a malformed 539ded074eSagge3 -- declaration. 549ded074eSagge3 local status, type = pcall(function() 559ded074eSagge3 return util.trim(self.scarg:gsub(self.name .. "$", ""), nil) 569ded074eSagge3 end) 579ded074eSagge3 if not status then 589ded074eSagge3 util.abort(1, "Malformed argument line: " .. line) 599ded074eSagge3 end 609ded074eSagge3 self.type = type 619ded074eSagge3end 629ded074eSagge3 639ded074eSagge3-- Processes this argument. 649ded074eSagge3-- Flags if there's ABI changes from native, converts this argument to the 659ded074eSagge3-- target ABI, and handles 64-bit argument pairing. 669ded074eSagge3-- Returns TRUE if this argument is processed and ready to add. 679ded074eSagge3-- Returns FALSE if it shouldn't be added (the argument type is void). 689ded074eSagge3function scarg:process() 699ded074eSagge3 if self.type ~= "" and self.name ~= "void" then 709ded074eSagge3 -- util.is64bitType() needs a bare type so check it after 719ded074eSagge3 -- argname is removed. 729ded074eSagge3 self.changes_abi = self.changes_abi or 739ded074eSagge3 (config.abiChanges("pair_64bit") and 749ded074eSagge3 util.is64bitType(self.type)) 759ded074eSagge3 769ded074eSagge3 self.type = self.type:gsub("intptr_t", config.abi_intptr_t) 779ded074eSagge3 self.type = self.type:gsub("semid_t", config.abi_semid_t) 789ded074eSagge3 799ded074eSagge3 if util.isPtrType(self.type) then 809ded074eSagge3 self.type = self.type:gsub("size_t", config.abi_size_t) 819ded074eSagge3 self.type = self.type:gsub("^long", config.abi_long) 829ded074eSagge3 self.type = self.type:gsub("^u_long", config.abi_u_long) 839ded074eSagge3 self.type = self.type:gsub("^const u_long", "const " .. 849ded074eSagge3 config.abi_u_long) 859ded074eSagge3 elseif self.type:find("^long$") then 869ded074eSagge3 self.type = config.abi_long 879ded074eSagge3 end 889ded074eSagge3 899ded074eSagge3 if util.isPtrArrayType(self.type) and 909ded074eSagge3 config.abi_ptr_array_t ~= "" then 919ded074eSagge3 -- `* const *` -> `**` 929ded074eSagge3 self.type = self.type:gsub("[*][ ]*const[ ]*[*]", "**") 939ded074eSagge3 -- e.g., `struct aiocb **` -> `uint32_t *` 949ded074eSagge3 self.type = self.type:gsub("[^*]*[*]", 959ded074eSagge3 config.abi_ptr_array_t .. " ", 1) 969ded074eSagge3 end 979ded074eSagge3 989ded074eSagge3 if self.arg_abi_change then 999ded074eSagge3 self.type = self.type:gsub("(struct [^ ]*)", "%1" .. 1009ded074eSagge3 config.abi_type_suffix) 1019ded074eSagge3 self.type = self.type:gsub("(union [^ ]*)", "%1" .. 1029ded074eSagge3 config.abi_type_suffix) 1039ded074eSagge3 end 1049ded074eSagge3 return true 1059ded074eSagge3 end 1069ded074eSagge3 return false 1079ded074eSagge3end 1089ded074eSagge3 1099ded074eSagge3-- For pairing 64-bit arguments, pad if necessary. 1109ded074eSagge3-- Returns TRUE if this argument was padded. 1119ded074eSagge3local function pad(tbl) 1129ded074eSagge3 if #tbl % 2 == 1 then 1139ded074eSagge3 table.insert(tbl, { 1149ded074eSagge3 type = "int", 1159ded074eSagge3 name = "_pad", 1169ded074eSagge3 }) 1179ded074eSagge3 return true 1189ded074eSagge3 end 1199ded074eSagge3 return false 1209ded074eSagge3end 1219ded074eSagge3 1229ded074eSagge3-- To append to a system call's argument table. Appends to the end. 1239ded074eSagge3function scarg:append(tbl) 1249ded074eSagge3 if config.abiChanges("pair_64bit") and util.is64bitType(self.type) then 1259ded074eSagge3 pad(tbl) -- Needs argument padding. 1269ded074eSagge3 table.insert(tbl, { 1279ded074eSagge3 type = "uint32_t", 1289ded074eSagge3 name = self.name .. "1", 1299ded074eSagge3 }) 1309ded074eSagge3 table.insert(tbl, { 1319ded074eSagge3 type = "uint32_t", 1329ded074eSagge3 name = self.name .. "2", 1339ded074eSagge3 }) 1349ded074eSagge3 else 1359ded074eSagge3 table.insert(tbl, { 1369ded074eSagge3 type = self.type, 1379ded074eSagge3 name = self.name, 1389ded074eSagge3 }) 1399ded074eSagge3 end 1409ded074eSagge3end 1419ded074eSagge3 1429ded074eSagge3-- Returns TRUE if this argument has ABI changes from native. 1439ded074eSagge3-- EXAMPLE: 32-bit argument for freebsd32. 1449ded074eSagge3function scarg:changesAbi() 1459ded074eSagge3 return self.changes_abi 1469ded074eSagge3end 1479ded074eSagge3 1489ded074eSagge3function scarg:new(obj, line) 1499ded074eSagge3 obj = obj or { } 1509ded074eSagge3 setmetatable(obj, self) 1519ded074eSagge3 self.__index = self 1529ded074eSagge3 1539ded074eSagge3 -- ABI changes that we only want in this scope. 1549ded074eSagge3 self.arg_abi_change = false 1559ded074eSagge3 -- ABI changes that we want the system call object to see. 1569ded074eSagge3 self.changes_abi = false 1579ded074eSagge3 1589ded074eSagge3 obj:init(line) 1599ded074eSagge3 1609ded074eSagge3 return obj 1619ded074eSagge3end 1629ded074eSagge3 1639ded074eSagge3return scarg 164