1
0
Fork 0
forked from nuttx/nuttx-update

Improve proxy/stub parameter passing for variadic OS interfaces.

In the past a very low effort interface was used:

- All parmeters were treated as though they were type uinptr_t, and
- The maximum number of parmeters (6) was passed in all cases.

The first is potentially wrong and the second is very inefficient.  This commit improves this by:

- Making tools/mksyscall.c more intelligent, and
- Extending the syntax for variadic functions.

For example, in syscall.cvs, the open() API was represened like this:

    "open","fcntl.h","","int","const char*","int","..."

In reality, open may take only a single optional argument of type mode_t which is not the same size as uintptr_t.  And there is not reason to pass 6 parameters in that case.

And this has been extended to:

    "open","fcntl.h","","int","const char*","int","...","mode_t"

The existence of the "mode_t" tells tools/mksyscall that there is at most one optional parameter and, if present, it is of type mode_t.
This commit is contained in:
Gregory Nutt 2020-05-05 15:02:07 -06:00 committed by Abdelatif Guettouche
parent b525218b55
commit 6906853f8e
5 changed files with 96 additions and 101 deletions

View file

@ -41,7 +41,7 @@
"if_indextoname","net/if.h","defined(CONFIG_NETDEV_IFINDEX)","FAR char *","unsigned int","FAR char *" "if_indextoname","net/if.h","defined(CONFIG_NETDEV_IFINDEX)","FAR char *","unsigned int","FAR char *"
"if_nametoindex","net/if.h","defined(CONFIG_NETDEV_IFINDEX)","unsigned int","FAR const char *" "if_nametoindex","net/if.h","defined(CONFIG_NETDEV_IFINDEX)","unsigned int","FAR const char *"
"insmod","nuttx/module.h","defined(CONFIG_MODULE)","FAR void *","FAR const char *","FAR const char *" "insmod","nuttx/module.h","defined(CONFIG_MODULE)","FAR void *","FAR const char *","FAR const char *"
"ioctl","sys/ioctl.h","","int","int","int","..." "ioctl","sys/ioctl.h","","int","int","int","...","unsigned int"
"kill","signal.h","","int","pid_t","int" "kill","signal.h","","int","pid_t","int"
"link","unistd.h","defined(CONFIG_PSEUDOFS_SOFTLINKS)","int","FAR const char *","FAR const char *" "link","unistd.h","defined(CONFIG_PSEUDOFS_SOFTLINKS)","int","FAR const char *","FAR const char *"
"listen","sys/socket.h","defined(CONFIG_NET)","int","int","int" "listen","sys/socket.h","defined(CONFIG_NET)","int","int","int"
@ -54,7 +54,7 @@
"mq_close","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t" "mq_close","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t"
"mq_getattr","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t","struct mq_attr *" "mq_getattr","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t","struct mq_attr *"
"mq_notify","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t","const struct sigevent*" "mq_notify","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t","const struct sigevent*"
"mq_open","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","mqd_t","const char*","int","..." "mq_open","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","mqd_t","const char*","int","...","mode_t","FAR struct mq_attr*"
"mq_receive","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","ssize_t","mqd_t","char*","size_t","FAR unsigned int*" "mq_receive","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","ssize_t","mqd_t","char*","size_t","FAR unsigned int*"
"mq_send","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t","const char*","size_t","unsigned int" "mq_send","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t","const char*","size_t","unsigned int"
"mq_setattr","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t","const struct mq_attr *","struct mq_attr *" "mq_setattr","mqueue.h","!defined(CONFIG_DISABLE_MQUEUE)","int","mqd_t","const struct mq_attr *","struct mq_attr *"
@ -66,12 +66,12 @@
"nx_task_spawn","nuttx/spawn.h","defined(CONFIG_LIB_SYSCALL) && !defined(CONFIG_BUILD_KERNEL)","int","FAR const struct spawn_syscall_parms_s *" "nx_task_spawn","nuttx/spawn.h","defined(CONFIG_LIB_SYSCALL) && !defined(CONFIG_BUILD_KERNEL)","int","FAR const struct spawn_syscall_parms_s *"
"nx_vsyslog","nuttx/syslog/syslog.h","","int","int","FAR const IPTR char*","FAR va_list*" "nx_vsyslog","nuttx/syslog/syslog.h","","int","int","FAR const IPTR char*","FAR va_list*"
"on_exit","stdlib.h","defined(CONFIG_SCHED_ONEXIT)","int","CODE void (*)(int, FAR void *)","FAR void *" "on_exit","stdlib.h","defined(CONFIG_SCHED_ONEXIT)","int","CODE void (*)(int, FAR void *)","FAR void *"
"open","fcntl.h","","int","const char*","int","..." "open","fcntl.h","","int","const char*","int","...","mode_t"
"opendir","dirent.h","","FAR DIR*","FAR const char*" "opendir","dirent.h","","FAR DIR*","FAR const char*"
"pgalloc", "nuttx/arch.h", "defined(CONFIG_BUILD_KERNEL)", "uintptr_t", "uintptr_t", "unsigned int" "pgalloc", "nuttx/arch.h", "defined(CONFIG_BUILD_KERNEL)", "uintptr_t", "uintptr_t", "unsigned int"
"poll","poll.h","","int","FAR struct pollfd*","nfds_t","int" "poll","poll.h","","int","FAR struct pollfd*","nfds_t","int"
"ppoll","poll.h","","int","FAR struct pollfd*","nfds_t","FAR const struct timespec *","FAR const sigset_t *" "ppoll","poll.h","","int","FAR struct pollfd*","nfds_t","FAR const struct timespec *","FAR const sigset_t *"
"prctl","sys/prctl.h", "CONFIG_TASK_NAME_SIZE > 0","int","int","..." "prctl","sys/prctl.h", "CONFIG_TASK_NAME_SIZE > 0","int","int","...","uintptr_t"
"pread","unistd.h","","ssize_t","int","FAR void*","size_t","off_t" "pread","unistd.h","","ssize_t","int","FAR void*","size_t","off_t"
"pselect","sys/select.h","","int","int","FAR fd_set*","FAR fd_set*","FAR fd_set*","FAR const struct timespec *","FAR const sigset_t *" "pselect","sys/select.h","","int","int","FAR fd_set*","FAR fd_set*","FAR fd_set*","FAR const struct timespec *","FAR const sigset_t *"
"pwrite","unistd.h","","ssize_t","int","FAR const void*","size_t","off_t" "pwrite","unistd.h","","ssize_t","int","FAR const void*","size_t","off_t"
@ -133,7 +133,7 @@
"select","sys/select.h","","int","int","FAR fd_set*","FAR fd_set*","FAR fd_set*","FAR struct timeval*" "select","sys/select.h","","int","int","FAR fd_set*","FAR fd_set*","FAR fd_set*","FAR struct timeval*"
"sem_close","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t*" "sem_close","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t*"
"sem_destroy","semaphore.h","","int","FAR sem_t*" "sem_destroy","semaphore.h","","int","FAR sem_t*"
"sem_open","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t*","FAR const char*","int","..." "sem_open","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t*","FAR const char*","int","...","mode_t","unsigned int"
"sem_post","semaphore.h","","int","FAR sem_t*" "sem_post","semaphore.h","","int","FAR sem_t*"
"sem_setprotocol","nuttx/semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int" "sem_setprotocol","nuttx/semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int"
"sem_timedwait","semaphore.h","","int","FAR sem_t*","FAR const struct timespec *" "sem_timedwait","semaphore.h","","int","FAR sem_t*","FAR const struct timespec *"

Can't render this file because it has a wrong number of fields in line 2.

View file

@ -77,7 +77,7 @@ SYSCALL_LOOKUP(sem_setprotocol, 2, STUB_sem_setprotocol)
/* Named semaphores */ /* Named semaphores */
#ifdef CONFIG_FS_NAMED_SEMAPHORES #ifdef CONFIG_FS_NAMED_SEMAPHORES
SYSCALL_LOOKUP(sem_open, 6, STUB_sem_open) SYSCALL_LOOKUP(sem_open, 4, STUB_sem_open)
SYSCALL_LOOKUP(sem_close, 1, STUB_sem_close) SYSCALL_LOOKUP(sem_close, 1, STUB_sem_close)
SYSCALL_LOOKUP(sem_unlink, 1, STUB_sem_unlink) SYSCALL_LOOKUP(sem_unlink, 1, STUB_sem_unlink)
#endif #endif
@ -197,7 +197,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
*/ */
SYSCALL_LOOKUP(close, 1, STUB_close) SYSCALL_LOOKUP(close, 1, STUB_close)
SYSCALL_LOOKUP(ioctl, 6, STUB_ioctl) SYSCALL_LOOKUP(ioctl, 3, STUB_ioctl)
SYSCALL_LOOKUP(read, 3, STUB_read) SYSCALL_LOOKUP(read, 3, STUB_read)
SYSCALL_LOOKUP(write, 3, STUB_write) SYSCALL_LOOKUP(write, 3, STUB_write)
SYSCALL_LOOKUP(pread, 4, STUB_pread) SYSCALL_LOOKUP(pread, 4, STUB_pread)
@ -234,7 +234,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
SYSCALL_LOOKUP(fcntl, 6, STUB_fcntl) SYSCALL_LOOKUP(fcntl, 6, STUB_fcntl)
SYSCALL_LOOKUP(lseek, 3, STUB_lseek) SYSCALL_LOOKUP(lseek, 3, STUB_lseek)
SYSCALL_LOOKUP(mmap, 6, STUB_mmap) SYSCALL_LOOKUP(mmap, 6, STUB_mmap)
SYSCALL_LOOKUP(open, 6, STUB_open) SYSCALL_LOOKUP(open, 3, STUB_open)
SYSCALL_LOOKUP(opendir, 1, STUB_opendir) SYSCALL_LOOKUP(opendir, 1, STUB_opendir)
SYSCALL_LOOKUP(readdir, 1, STUB_readdir) SYSCALL_LOOKUP(readdir, 1, STUB_readdir)
SYSCALL_LOOKUP(rewinddir, 1, STUB_rewinddir) SYSCALL_LOOKUP(rewinddir, 1, STUB_rewinddir)
@ -333,7 +333,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
SYSCALL_LOOKUP(mq_close, 1, STUB_mq_close) SYSCALL_LOOKUP(mq_close, 1, STUB_mq_close)
SYSCALL_LOOKUP(mq_getattr, 2, STUB_mq_getattr) SYSCALL_LOOKUP(mq_getattr, 2, STUB_mq_getattr)
SYSCALL_LOOKUP(mq_notify, 2, STUB_mq_notify) SYSCALL_LOOKUP(mq_notify, 2, STUB_mq_notify)
SYSCALL_LOOKUP(mq_open, 6, STUB_mq_open) SYSCALL_LOOKUP(mq_open, 4, STUB_mq_open)
SYSCALL_LOOKUP(mq_receive, 4, STUB_mq_receive) SYSCALL_LOOKUP(mq_receive, 4, STUB_mq_receive)
SYSCALL_LOOKUP(mq_send, 4, STUB_mq_send) SYSCALL_LOOKUP(mq_send, 4, STUB_mq_send)
SYSCALL_LOOKUP(mq_setattr, 3, STUB_mq_setattr) SYSCALL_LOOKUP(mq_setattr, 3, STUB_mq_setattr)
@ -379,7 +379,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
/* The following is defined only if CONFIG_TASK_NAME_SIZE > 0 */ /* The following is defined only if CONFIG_TASK_NAME_SIZE > 0 */
#if CONFIG_TASK_NAME_SIZE > 0 #if CONFIG_TASK_NAME_SIZE > 0
SYSCALL_LOOKUP(prctl, 5, STUB_prctl) SYSCALL_LOOKUP(prctl, 2, STUB_prctl)
#endif #endif
/* The following is defined only if entropy pool random number generator /* The following is defined only if entropy pool random number generator
@ -387,7 +387,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
*/ */
#ifdef CONFIG_CRYPTO_RANDOM_POOL #ifdef CONFIG_CRYPTO_RANDOM_POOL
SYSCALL_LOOKUP(getrandom, 2, STUB_getrandom) SYSCALL_LOOKUP(getrandom, 2, STUB_getrandom)
#endif #endif
/**************************************************************************** /****************************************************************************

View file

@ -81,8 +81,7 @@ uintptr_t STUB_getgid(int nbr);
uintptr_t STUB_sem_close(int nbr, uintptr_t parm1); uintptr_t STUB_sem_close(int nbr, uintptr_t parm1);
uintptr_t STUB_sem_destroy(int nbr, uintptr_t parm1); uintptr_t STUB_sem_destroy(int nbr, uintptr_t parm1);
uintptr_t STUB_sem_open(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t STUB_sem_open(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, uintptr_t parm3, uintptr_t parm4);
uintptr_t parm6);
uintptr_t STUB_sem_post(int nbr, uintptr_t parm1); uintptr_t STUB_sem_post(int nbr, uintptr_t parm1);
uintptr_t STUB_sem_setprotocol(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_sem_setprotocol(int nbr, uintptr_t parm1, uintptr_t parm2);
uintptr_t STUB_sem_timedwait(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_sem_timedwait(int nbr, uintptr_t parm1, uintptr_t parm2);
@ -190,8 +189,7 @@ uintptr_t STUB_nx_vsyslog(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t STUB_close(int nbr, uintptr_t parm1); uintptr_t STUB_close(int nbr, uintptr_t parm1);
uintptr_t STUB_ioctl(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t STUB_ioctl(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, uintptr_t parm3);
uintptr_t parm6);
uintptr_t STUB_read(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t STUB_read(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3); uintptr_t parm3);
uintptr_t STUB_write(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t STUB_write(int nbr, uintptr_t parm1, uintptr_t parm2,
@ -245,8 +243,7 @@ uintptr_t STUB_mmap(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm6); uintptr_t parm6);
uintptr_t STUB_munmap(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_munmap(int nbr, uintptr_t parm1, uintptr_t parm2);
uintptr_t STUB_open(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t STUB_open(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, uintptr_t parm3);
uintptr_t parm6);
uintptr_t STUB_opendir(int nbr, uintptr_t parm1); uintptr_t STUB_opendir(int nbr, uintptr_t parm1);
uintptr_t STUB_readdir(int nbr, uintptr_t parm1); uintptr_t STUB_readdir(int nbr, uintptr_t parm1);
uintptr_t STUB_rewinddir(int nbr, uintptr_t parm1); uintptr_t STUB_rewinddir(int nbr, uintptr_t parm1);
@ -344,8 +341,7 @@ uintptr_t STUB_mq_close(int nbr, uintptr_t parm1);
uintptr_t STUB_mq_getattr(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_mq_getattr(int nbr, uintptr_t parm1, uintptr_t parm2);
uintptr_t STUB_mq_notify(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_mq_notify(int nbr, uintptr_t parm1, uintptr_t parm2);
uintptr_t STUB_mq_open(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t STUB_mq_open(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, uintptr_t parm3, uintptr_t parm4);
uintptr_t parm6);
uintptr_t STUB_mq_receive(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t STUB_mq_receive(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3, uintptr_t parm4); uintptr_t parm3, uintptr_t parm4);
uintptr_t STUB_mq_send(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t STUB_mq_send(int nbr, uintptr_t parm1, uintptr_t parm2,
@ -403,8 +399,7 @@ uintptr_t STUB_socket(int nbr, uintptr_t parm1, uintptr_t parm2,
/* The following is defined only if CONFIG_TASK_NAME_SIZE > 0 */ /* The following is defined only if CONFIG_TASK_NAME_SIZE > 0 */
uintptr_t STUB_prctl(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t STUB_prctl(int nbr, uintptr_t parm1, uintptr_t parm2);
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5);
/* The following is defined only if entropy pool random number generator /* The following is defined only if entropy pool random number generator
* is enabled. * is enabled.

View file

@ -1,35 +1,20 @@
/**************************************************************************** /****************************************************************************
* tools/csvparser.h * tools/csvparser.h
* *
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. * Licensed to the Apache Software Foundation (ASF) under one or more
* Author: Gregory Nutt <gnutt@nuttx.org> * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* *
* Redistribution and use in source and binary forms, with or without * http://www.apache.org/licenses/LICENSE-2.0
* modification, are permitted provided that the following conditions
* are met:
* *
* 1. Redistributions of source code must retain the above copyright * Unless required by applicable law or agreed to in writing, software
* notice, this list of conditions and the following disclaimer. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* 2. Redistributions in binary form must reproduce the above copyright * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* notice, this list of conditions and the following disclaimer in * License for the specific language governing permissions and limitations
* the documentation and/or other materials provided with the * under the License.
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* *
****************************************************************************/ ****************************************************************************/
@ -51,20 +36,27 @@
#define MAX_FIELDS 16 #define MAX_FIELDS 16
#define MAX_PARMSIZE 256 #define MAX_PARMSIZE 256
#define NAME_INDEX 0 #define NAME_INDEX 0
#define HEADER_INDEX 1 #define HEADER_INDEX 1
#define COND_INDEX 2 #define COND_INDEX 2
#define RETTYPE_INDEX 3 #define RETTYPE_INDEX 3
#define PARM1_INDEX 4 #define PARM1_INDEX 4
/****************************************************************************
* Public Types
****************************************************************************/
typedef char csvparm_t[MAX_PARMSIZE];
/**************************************************************************** /****************************************************************************
* Public Data * Public Data
****************************************************************************/ ****************************************************************************/
extern bool g_debug; extern bool g_debug;
extern char g_line[LINESIZE+1]; extern char g_line[LINESIZE + 1];
extern char g_parm[MAX_FIELDS][MAX_PARMSIZE]; extern csvparm_t g_parm[MAX_FIELDS];
extern int g_lineno; extern int g_lineno;
/**************************************************************************** /****************************************************************************
* Public Function Prototypes * Public Function Prototypes

View file

@ -1,35 +1,20 @@
/**************************************************************************** /****************************************************************************
* tools/mksyscall.c * tools/mksyscall.c
* *
* Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. * Licensed to the Apache Software Foundation (ASF) under one or more
* Author: Gregory Nutt <gnutt@nuttx.org> * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* *
* Redistribution and use in source and binary forms, with or without * http://www.apache.org/licenses/LICENSE-2.0
* modification, are permitted provided that the following conditions
* are met:
* *
* 1. Redistributions of source code must retain the above copyright * Unless required by applicable law or agreed to in writing, software
* notice, this list of conditions and the following disclaimer. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* 2. Redistributions in binary form must reproduce the above copyright * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* notice, this list of conditions and the following disclaimer in * License for the specific language governing permissions and limitations
* the documentation and/or other materials provided with the * under the License.
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* *
****************************************************************************/ ****************************************************************************/
@ -46,10 +31,6 @@
#include "csvparser.h" #include "csvparser.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
@ -221,7 +202,7 @@ static FILE *open_proxy(void)
return stream; return stream;
} }
static void generate_proxy(int nparms) static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
{ {
FILE *stream = open_proxy(); FILE *stream = open_proxy();
char formal[MAX_PARMSIZE]; char formal[MAX_PARMSIZE];
@ -315,20 +296,21 @@ static void generate_proxy(int nparms)
* the varargs. * the varargs.
*/ */
if (nparms < 7) if (nvartypes > 0)
{ {
fprintf(stream, " va_list ap;\n"); fprintf(stream, " va_list ap;\n");
for (i = nparms; i < 7; i++) for (i = 0; i < nvartypes; i++)
{ {
fprintf(stream, " uintptr_t parm%d;\n", i); fprintf(stream, " %s parm%d;\n", vartypes[i], nparms + i);
} }
fprintf(stream, "\n va_start(ap, parm%d);\n", nparms - 1); fprintf(stream, "\n va_start(ap, parm%d);\n", nparms - 1);
for (i = nparms; i < 7; i++) for (i = 0; i < nvartypes; i++)
{ {
fprintf(stream, " parm%d = va_arg(ap, uintptr_t);\n", i); fprintf(stream, " parm%d = va_arg(ap, %s);\n",
nparms + i, vartypes[i]);
} }
fprintf(stream, " va_end(ap);\n\n"); fprintf(stream, " va_end(ap);\n\n");
@ -343,7 +325,12 @@ static void generate_proxy(int nparms)
* are special cases. * are special cases.
*/ */
nactual = bvarargs ? 6 : nparms; nactual = nformal;
if (bvarargs)
{
nactual += nvartypes;
}
if (strcmp(g_parm[RETTYPE_INDEX], "void") == 0) if (strcmp(g_parm[RETTYPE_INDEX], "void") == 0)
{ {
fprintf(stream, " (void)sys_call%d(", nactual); fprintf(stream, " (void)sys_call%d(", nactual);
@ -441,7 +428,7 @@ static void stub_close(FILE *stream)
} }
} }
static void generate_stub(int nparms) static void generate_stub(int nparms, csvparm_t *vartypes, int nvartypes)
{ {
FILE *stream = open_stub(); FILE *stream = open_stub();
char formal[MAX_PARMSIZE]; char formal[MAX_PARMSIZE];
@ -487,11 +474,9 @@ static void generate_stub(int nparms)
if (is_vararg(g_parm[PARM1_INDEX + i], i, nparms)) if (is_vararg(g_parm[PARM1_INDEX + i], i, nparms))
{ {
/* Always receive six arguments in this case */ for (j = 0; j < nvartypes; j++)
for (j = i + 1; j <= 6; j++)
{ {
fprintf(stream, ", uintptr_t parm%d", j); fprintf(stream, ", uintptr_t parm%d", nparms + j);
} }
} }
else else
@ -542,11 +527,9 @@ static void generate_stub(int nparms)
if (is_vararg(actual, i, nparms)) if (is_vararg(actual, i, nparms))
{ {
/* Always pass six arguments */ for (j = 0; j < nvartypes; j++)
for (j = i + 1; j <= 6; j++)
{ {
fprintf(stream, ", parm%d", j); fprintf(stream, ", (%s)parm%d", vartypes[j], i + j + 1);
} }
} }
else else
@ -618,6 +601,7 @@ int main(int argc, char **argv, char **envp)
FILE *stream; FILE *stream;
char *ptr; char *ptr;
int ch; int ch;
int i;
/* Parse command line options */ /* Parse command line options */
@ -684,6 +668,9 @@ int main(int argc, char **argv, char **envp)
while ((ptr = read_line(stream)) != NULL) while ((ptr = read_line(stream)) != NULL)
{ {
csvparm_t *vartypes = NULL;
int nvartypes = 0;
/* Parse the line from the CVS file */ /* Parse the line from the CVS file */
int nargs = parse_csvline(ptr); int nargs = parse_csvline(ptr);
@ -693,14 +680,35 @@ int main(int argc, char **argv, char **envp)
exit(8); exit(8);
} }
/* 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.
*/
for (i = PARM1_INDEX; i < nargs; i++)
{
if (strcmp(g_parm[i], "...") == 0)
{
nvartypes = nargs - i - 1;
nargs = i + 1;
if (nvartypes > 0)
{
vartypes = &g_parm[i + 1];
}
break;
}
}
if (proxies) if (proxies)
{ {
generate_proxy(nargs - PARM1_INDEX); generate_proxy(nargs - PARM1_INDEX, vartypes, nvartypes);
} }
else else
{ {
g_stubstream = NULL; g_stubstream = NULL;
generate_stub(nargs - PARM1_INDEX); generate_stub(nargs - PARM1_INDEX, vartypes, nvartypes);
if (g_stubstream != NULL) if (g_stubstream != NULL)
{ {
fprintf(g_stubstream, "\n#endif /* __STUB_H */\n"); fprintf(g_stubstream, "\n#endif /* __STUB_H */\n");