tools/mksyscall: Unify the fixed and variable arguments process

Signed-off-by: Xiang Xiao <iaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2020-05-08 03:33:36 +08:00 committed by patacongo
parent e7e81dd74d
commit a6c82a27db

View File

@ -42,31 +42,14 @@ static FILE *g_stubstream;
* Private Functions
****************************************************************************/
static bool is_vararg(const char *type, int ndx, int nparms)
static bool is_vararg(const char *type)
{
if (strcmp(type, "...") == 0)
{
if (ndx != (nparms - 1))
{
fprintf(stderr, "%d: ... is not the last in the argument list\n",
g_lineno);
exit(11);
}
else if (nparms < 2)
{
fprintf(stderr, "%d: Need one parameter before ...\n", g_lineno);
exit(14);
}
return true;
}
return false;
return strcmp(type, "...") == 0;
}
static bool is_union(const char *type)
{
return (strncmp(type, "union", 5) == 0);
return strncmp(type, "union ", 6) == 0;
}
static const char *check_funcptr(const char *type)
@ -202,14 +185,12 @@ static FILE *open_proxy(void)
return stream;
}
static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
static void generate_proxy(int nfixed, int nparms)
{
FILE *stream = open_proxy();
char formal[MAX_PARMSIZE];
char actual[MAX_PARMSIZE];
char fieldname[MAX_PARMSIZE];
bool bvarargs = false;
int nformal;
int nactual;
int i;
/* Generate "up-front" information, include correct header files */
@ -228,16 +209,10 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
* final parameter type will be encoded as "..."
*/
if (is_vararg(g_parm[PARM1_INDEX + nparms - 1], nparms - 1, nparms))
if (nfixed != nparms)
{
nformal = nparms - 1;
bvarargs = true;
fprintf(stream, "#include <stdarg.h>\n");
}
else
{
nformal = nparms;
}
if (g_parm[HEADER_INDEX] && strlen(g_parm[HEADER_INDEX]) > 0)
{
@ -259,13 +234,13 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
/* Generate the formal parameter list */
if (nformal <= 0)
if (nparms <= 0)
{
fprintf(stream, "void");
}
else
{
for (i = 0; i < nformal; i++)
for (i = 0; i < nfixed; i++)
{
/* The formal and actual parameter types may be encoded.. extra the
* formal parameter type.
@ -288,7 +263,7 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
/* Handle the end of the formal parameter list */
if (bvarargs)
if (i < nparms)
{
fprintf(stream, ", ...)\n{\n");
@ -296,25 +271,32 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
* the varargs.
*/
if (nvartypes > 0)
fprintf(stream, " va_list ap;\n");
for (; i < nparms; i++)
{
fprintf(stream, " va_list ap;\n");
for (i = 0; i < nvartypes; i++)
{
fprintf(stream, " %s parm%d;\n", vartypes[i], nparms + i);
}
fprintf(stream, "\n va_start(ap, parm%d);\n", nparms - 1);
for (i = 0; i < nvartypes; i++)
{
fprintf(stream, " parm%d = va_arg(ap, %s);\n",
nparms + i, vartypes[i]);
}
fprintf(stream, " va_end(ap);\n\n");
get_formalparmtype(g_parm[PARM1_INDEX + i], formal);
fprintf(stream, " %s parm%d;\n", formal, i + 1);
}
fprintf(stream, "\n va_start(ap, parm%d);\n", nfixed);
for (i = nfixed; i < nparms; i++)
{
get_formalparmtype(g_parm[PARM1_INDEX + i], formal);
get_actualparmtype(g_parm[PARM1_INDEX + i], actual);
if (is_union(formal))
{
fprintf(stream, " parm%d = (%s)va_arg(ap, %s);\n",
i + 1, formal, actual);
}
else
{
fprintf(stream, " parm%d = va_arg(ap, %s);\n", i + 1, actual);
}
}
fprintf(stream, " va_end(ap);\n\n");
}
else
{
@ -325,20 +307,14 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
* are special cases.
*/
nactual = nformal;
if (bvarargs)
{
nactual += nvartypes;
}
if (strcmp(g_parm[RETTYPE_INDEX], "void") == 0)
{
fprintf(stream, " (void)sys_call%d(", nactual);
fprintf(stream, " (void)sys_call%d(", nparms);
}
else
{
fprintf(stream, " return (%s)sys_call%d(", g_parm[RETTYPE_INDEX],
nactual);
nparms);
}
/* Create the parameter list with the matching types. The first parameter
@ -347,11 +323,11 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
fprintf(stream, "(unsigned int)SYS_%s", g_parm[NAME_INDEX]);
for (i = 0; i < nactual; i++)
for (i = 0; i < nparms; i++)
{
/* Is the parameter a union member */
if (i < nparms && is_union(g_parm[PARM1_INDEX + i]))
if (is_union(g_parm[PARM1_INDEX + i]))
{
/* Then we will have to pick a field name that can be cast to a
* uintptr_t. There probably should be some error handling here
@ -369,10 +345,10 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
/* Handle the tail end of the function. */
fprintf(stream, ");\n}\n\n");
fprintf(stream, ");\n}\n");
if (g_parm[COND_INDEX][0] != '\0')
{
fprintf(stream, "#endif /* %s */\n", g_parm[COND_INDEX]);
fprintf(stream, "\n#endif /* %s */\n", g_parm[COND_INDEX]);
}
fclose(stream);
@ -428,13 +404,12 @@ static void stub_close(FILE *stream)
}
}
static void generate_stub(int nparms, csvparm_t *vartypes, int nvartypes)
static void generate_stub(int nfixed, int nparms)
{
FILE *stream = open_stub();
char formal[MAX_PARMSIZE];
char actual[MAX_PARMSIZE];
int i;
int j;
/* Generate "up-front" information, include correct header files */
@ -470,19 +445,7 @@ static void generate_stub(int nparms, csvparm_t *vartypes, int nvartypes)
for (i = 0; i < nparms; i++)
{
/* Check for a variable number of arguments */
if (is_vararg(g_parm[PARM1_INDEX + i], i, nparms))
{
for (j = 0; j < nvartypes; j++)
{
fprintf(stream, ", uintptr_t parm%d", nparms + j);
}
}
else
{
fprintf(stream, ", uintptr_t parm%d", i + 1);
}
fprintf(stream, ", uintptr_t parm%d", i + 1);
}
fprintf(stream, ")\n{\n");
@ -508,7 +471,7 @@ static void generate_stub(int nparms, csvparm_t *vartypes, int nvartypes)
{
/* Get the formal type of the parameter, and get the type that we
* actually have to cast to. For example for a formal type like
* 'int parm[]' we have to cast the actual parameter to 'int*'.
* 'int parm[]' we have to cast the actual parameter to 'int *'.
* The worst is a union type like 'union sigval' where we have to
* cast to (union sigval)((FAR void *)parm)
* -- Yech.
@ -523,57 +486,35 @@ static void generate_stub(int nparms, csvparm_t *vartypes, int nvartypes)
if (i > 0)
{
/* Check for a variable number of arguments */
fprintf(stream, ", ");
}
if (is_vararg(actual, i, nparms))
{
for (j = 0; j < nvartypes; j++)
{
fprintf(stream, ", (%s)parm%d", vartypes[j], i + j + 1);
}
}
else
{
if (is_union(formal))
{
fprintf(stream, ", (%s)((%s)parm%d)", formal, actual,
i + 1);
}
else
{
fprintf(stream, ", (%s)parm%d", actual, i + 1);
}
}
if (is_union(formal))
{
fprintf(stream, "(%s)((%s)parm%d)", formal, actual, i + 1);
}
else
{
if (is_union(formal))
{
fprintf(stream, "(%s)((%s)parm%d)", formal, actual, i + 1);
}
else
{
fprintf(stream, "(%s)parm%d", actual, i + 1);
}
fprintf(stream, "(%s)parm%d", actual, i + 1);
}
}
/* Tail end of the function. If the proxied function has no return
/* Tail end of the function. If the stubs function has no return
* value, just return zero (OK).
*/
if (strcmp(g_parm[RETTYPE_INDEX], "void") == 0)
{
fprintf(stream, ");\n return 0;\n}\n\n");
fprintf(stream, ");\n return 0;\n}\n");
}
else
{
fprintf(stream, ");\n}\n\n");
fprintf(stream, ");\n}\n");
}
if (g_parm[COND_INDEX][0] != '\0')
{
fprintf(stream, "#endif /* %s */\n", g_parm[COND_INDEX]);
fprintf(stream, "\n#endif /* %s */\n", g_parm[COND_INDEX]);
}
stub_close(stream);
@ -668,8 +609,7 @@ int main(int argc, char **argv, char **envp)
while ((ptr = read_line(stream)) != NULL)
{
csvparm_t *vartypes = NULL;
int nvartypes = 0;
int nfixed;
/* Parse the line from the CVS file */
@ -680,6 +620,10 @@ int main(int argc, char **argv, char **envp)
exit(8);
}
/* Assume no variable arguments by default */
nfixed = nargs - PARM1_INDEX;
/* Search for an occurrence of "...". This is followed by the list
* types in the variable arguments. The number of types is the
* maximum number of variable arguments.
@ -687,28 +631,40 @@ int main(int argc, char **argv, char **envp)
for (i = PARM1_INDEX; i < nargs; i++)
{
if (strcmp(g_parm[i], "...") == 0)
if (is_vararg(g_parm[i]))
{
nvartypes = nargs - i - 1;
nargs = i + 1;
/* "..." is the last argument? */
if (nvartypes > 0)
if (i == --nargs)
{
vartypes = &g_parm[i + 1];
/* Yes, generate the default variable arguments */
while (nargs < PARM1_INDEX + 6)
{
strcpy(g_parm[nargs++], "uintptr_t");
}
}
else
{
/* Move up one slot to overwrite "..." */
memmove(g_parm[i], g_parm[i + 1],
sizeof(g_parm[i]) * (nargs - i));
}
nfixed = i - PARM1_INDEX;
break;
}
}
if (proxies)
{
generate_proxy(nargs - PARM1_INDEX, vartypes, nvartypes);
generate_proxy(nfixed, nargs - PARM1_INDEX);
}
else
{
g_stubstream = NULL;
generate_stub(nargs - PARM1_INDEX, vartypes, nvartypes);
generate_stub(nfixed, nargs - PARM1_INDEX);
if (g_stubstream != NULL)
{
fprintf(g_stubstream, "\n#endif /* __STUB_H */\n");