Add mksyscall tool

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3446 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-03-31 04:23:17 +00:00
parent a521443817
commit db0f306719
14 changed files with 587 additions and 15 deletions

View File

@ -1632,4 +1632,6 @@
from sched/ to lib/pthread where they more appropriately belong.
* sched/ and lib/semaphore/: Move some semaphore-related interfaces
from sched/ to lib/pthread where they more appropriately belong.
* syscall/: The beginnings of an options syscall interface.
* syscall/: The beginnings of an optional syscall kernal interface.
* tools/mksyscall.c: Add a tool that will auto-generate syscall proxies
and stubs from a comma-separated-value (CSV) data file.

View File

@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
<p>Last Updated: March 28, 2011</p>
<p>Last Updated: March 30, 2011</p>
</td>
</tr>
</table>
@ -2176,6 +2176,18 @@ nuttx-6.1 2011-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
of the nuttx source tree
* apps/namedapp/binfs.c: Create a tiny filesystem that can be used
to show the internal named apps under /bin.
* fs/fs_opendir.c: Correct an error that occurs when a file system is
mounted in the root directory. This was discovered while mounting
the named app's /bin directory.
* lib/: Move all source files into a subdirectory of lib/ named after
the header file in which the library function is prototyped.
* sched/ and lib/pthread/: Move pthread attribute-related interfaces
from sched/ to lib/pthread where they more appropriately belong.
* sched/ and lib/semaphore/: Move some semaphore-related interfaces
from sched/ to lib/pthread where they more appropriately belong.
* syscall/: The beginnings of an optional syscall kernel interface.
* tools/mksyscall.c: Add a tool that will auto-generate syscall proxies
and stubs from a comma-separated-value (CSV) data file.
apps-6.1 2011-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;

View File

@ -33,4 +33,4 @@
#
############################################################################
SEM_SRCS = sem_init.c sem_getvalue.c sem_destroy.c
SEM_SRCS = sem_init.c sem_getvalue.c

View File

@ -39,6 +39,7 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <semaphore.h>
#include <errno.h>

View File

@ -39,6 +39,7 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <limits.h>
#include <semaphore.h>
#include <errno.h>

View File

@ -115,7 +115,7 @@ ifneq ($(CONFIG_DISABLE_SIGNALS),y)
PTHREAD_SRCS += pthread_condtimedwait.c pthread_kill.c pthread_sigmask.c
endif
SEM_SRCS = sem_initialize.c sem_open.c sem_close.c sem_unlink.c \
SEM_SRCS = sem_initialize.c sem_destroy.c sem_open.c sem_close.c sem_unlink.c \
sem_wait.c sem_trywait.c sem_post.c sem_findnamed.c
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
SEM_SRCS += sem_waitirq.c

View File

@ -42,6 +42,8 @@
#include <semaphore.h>
#include <errno.h>
#include "sem_internal.h"
/****************************************************************************
* Definitions
****************************************************************************/

View File

@ -97,11 +97,30 @@ Auto-Generated Files
Stubs and proxies for the sycalls are automatically generated from this CSV
database. Here the following definition is used:
STUB - A tiny bit of code that executes with within the NuttX kernel that
is used to map a software interrupt received by the kernel to a
kernel function call.
Proxy - Another tiny bit of code that executes in the user space. A proxy
Proxy - A tiny bit of code that executes in the user space. A proxy
has exactly the same function prototype as does the "real" function
for which it proxies. However, it only serves to map the function
call into a syscall, marshalling all of the parameters as necessary.
call into a syscall, marshalling all of the system call parameters
as necessary.
STUB - Another tiny bit of code that executes within the NuttX kernel
that is used to map a software interrupt received by the kernel to
a kernel function call. The stubs receive the marshalled system
call data, and perform the actually kernel function call (in
kernel-mode) on behalf of the proxy function.
Sub-Directories
===============
stubs - Autogenerated stub files are placed in this directory.
proxies - Autogenerated proxy files are placed in this directory.
mksyscall
=========
mksyscall is C program that is used used during the initial NuttX build
by the logic in the top-level syscall/ directory. Information about the
stubs and proxies is maintained in a comma separated value (CSV) file
in the syscall/ directory. The mksyscall program will accept this CVS
file as input and generate all of the required proxy or stub files as
output. See tools/README.txt for additonal information.

36
syscall/proxies/Make.defs Normal file
View File

@ -0,0 +1,36 @@
############################################################################
# syscall/proxies/Make.defs
#
# Copyright (C) 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# 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.
#
############################################################################
PROXY_SRCS := ${shell ls *.c}

36
syscall/stubs/Make.defs Normal file
View File

@ -0,0 +1,36 @@
############################################################################
# syscall/stubs/Make.defs
#
# Copyright (C) 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# 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.
#
############################################################################
STUB_SRCS := ${shell ls *.c}

View File

@ -104,6 +104,7 @@
"seekdir","dirent.h","void","FAR DIR*","off_t"
"select","sys/select.h","int","int","FAR fd_set*","FAR fd_set*","FAR fd_set*","FAR struct timeval*"
"sem_close","semaphore.h","int","FAR sem_t*"
"sem_destroy","semaphore.h","int","FAR sem_t*"
"sem_open","semaphore.h","FAR sem_t*","FAR const char*","int","..."
"sem_post","semaphore.h","int","FAR sem_t*"
"sem_trywait","semaphore.h","int","FAR sem_t*"

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

View File

@ -35,12 +35,19 @@
all: mkconfig mksyscall
default: mkconfig mksyscall
.PHONY: clean
# Add CFLAGS=-g on the make command line build debug versions
CFLAGS = -O2 -Wall
# mkconfig - Convert a .config file into a C config.h file
mkconfig: mkconfig.c
@gcc $(CFLAGS) -o mkconfig mkconfig.c
# mksyscall - Convert a CSV file into syscall stubs and proxies
mksyscall: mksyscall.c
@gcc $(CFLAGS) -o mksyscall mksyscall.c

View File

@ -31,17 +31,39 @@ mkconfig.c
into include/nuttx/config.h. config.h is a another version of the
NuttX configuration that can be included by C files.
mksyscall.c
This is C file that is used to build mksyscall program. The mksyscall
program is used during the initial NuttX build by the logic in the top-
level syscall/ directory.
If you build NuttX as a separately compiled, monolithic kernel and separate
applications, then there is a syscall layer that is used to get from the
user application space to the NuttX kernel space. In the user application
"proxies" for each of the kernel functions are provided. The proxies have
the same function signature as the kernel function, but only execute a
system call.
Within the kernel, there are "stubs" for each of the system calls. The
stubs receive the marshalled system call data, and perform the actually
kernel function call (in kernel-mode) on behalf of the proxy function.
Information about the stubs and proxies is maintained in a comma separated
value (CSV) file in the syscall/ directory. The mksyscall program will
accept this CVS file as input and generate all of the required proxy or
stub files as output. See syscall/README.txt for additonal information.
Makefile.host
This is the makefile that is used to make the mkconfig program from
the mkconfig.c C file or the mksyscall program from the mksyscall.c file.
mkromfsimg.sh
This script may be used to automate the generate of a ROMFS file system
image. It accepts an rcS script "template" and generates and image that
may be mounted under /etc in the NuttX pseudo file system.
Makefile.mkconfig
This is the makefile that is used to make the mkconfig program from
the mkconfig.c C file.
mkdeps.sh
mknulldeps.sh

433
tools/mksyscall.c Normal file
View File

@ -0,0 +1,433 @@
/****************************************************************************
* tools/mksyscall.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
/****************************************************************************
* Definitions
****************************************************************************/
#define LINESIZE (PATH_MAX > 256 ? PATH_MAX : 256)
#define MAX_FIELDS 16
#define MAX_PARMSIZE 128
#define NAME_INDEX 0
#define HEADER_INDEX 1
#define RETTYPE_INDEX 2
#define PARM1_INDEX 3
/****************************************************************************
* Private Data
****************************************************************************/
static bool g_debug;
static char g_line[LINESIZE+1];
static char g_parm[MAX_FIELDS][MAX_PARMSIZE];
/****************************************************************************
* Private Functions
****************************************************************************/
static char *skip_space(char *ptr)
{
while (*ptr && isspace(*ptr)) ptr++;
return ptr;
}
static char *read_line(FILE *stream)
{
char *ptr;
for (;;)
{
g_line[LINESIZE] = '\0';
if (!fgets(g_line, LINESIZE, stream))
{
return NULL;
}
else
{
if (g_debug)
{
printf("Line: %s\n", g_line);
}
ptr = skip_space(g_line);
if (*ptr && *ptr != '#' && *ptr != '\n')
{
return ptr;
}
}
}
}
static char *copy_parm(char *src, char *dest)
{
char *start = src;
int i;
for (i = 0; i < MAX_PARMSIZE; i++)
{
if (*src == '"')
{
*dest = '\0';
return src;
}
else if (*src == '\n' || *src == '\0')
{
fprintf(stderr, "Unexpected end of line: \"%s\"\n", start);
exit(4);
}
else
{
*dest++ = *src++;
}
}
fprintf(stderr, "Parameter too long: \"%s\"\n", start);
exit(3);
}
static char *find_parm(char *ptr)
{
char *start = ptr;
if (*ptr != '"')
{
fprintf(stderr, "I'm confused: \"%s\"\n", start);
exit(5);
}
ptr++;
ptr = skip_space(ptr);
if (*ptr == '\n' || *ptr == '\0')
{
return NULL;
}
else if (*ptr != ',')
{
fprintf(stderr, "Expected ',': \"%s\"\n", start);
exit(6);
}
ptr++;
ptr = skip_space(ptr);
if (*ptr != '"')
{
fprintf(stderr, "Expected \": \"%s\"\n", start);
exit(7);
}
ptr++;
return ptr;
}
static int parse_csvline(char *ptr)
{
int nparms;
int i;
/* Format "arg1","arg2","arg3",... Spaces will be tolerated outside of the
* quotes. Any initial spaces have already been skipped so the first thing
* should be '"'.
*/
if (*ptr != '"')
{
fprintf(stderr, "Bad line: \"%s\"\n", g_line);
exit(2);
}
ptr++;
nparms = 0;
do
{
ptr = copy_parm(ptr, &g_parm[nparms][0]);
nparms++;
ptr = find_parm(ptr);
}
while (ptr);
if (g_debug)
{
printf("Parameters: %d\n", nparms);
for (i = 0; i < nparms; i++)
{
printf(" Parm%d: \"%s\"\n", i+1, g_parm[i]);
}
}
return nparms;
}
static FILE *open_proxy(void)
{
char filename[MAX_PARMSIZE+4];
FILE *stream;
snprintf(filename, MAX_PARMSIZE+3, "%s.c", g_parm[NAME_INDEX]);
filename[MAX_PARMSIZE+3] = '\0';
stream = fopen(filename, "w");
if (stream == NULL)
{
fprintf(stderr, "Failed to open %s: %s\n", filename, strerror(errno));
exit(10);
}
return stream;
}
static void generate_proxy(int nparms)
{
FILE *stream = open_proxy();
int i;
fprintf(stream, "/* Auto-generated %s proxy file -- do not edit */\n\n", g_parm[NAME_INDEX]);
fprintf(stream, "#include <%s>\n\n", g_parm[HEADER_INDEX]);
fprintf(stream, "%s %s(", g_parm[RETTYPE_INDEX], g_parm[NAME_INDEX]);
if (nparms <= 0)
{
fprintf(stream, "void");
}
else
{
for (i = 0; i < nparms; i++)
{
if (i > 0)
{
fprintf(stream, ", %s parm%d", g_parm[PARM1_INDEX+i], i+1);
}
else
{
fprintf(stream, "%s parm%d", g_parm[PARM1_INDEX+i], i+1);
}
}
}
fprintf(stream, ")\n{\n");
fprintf(stream, " return (%s)sys_call%d(", g_parm[RETTYPE_INDEX], nparms);
for (i = 0; i < nparms; i++)
{
if (i > 0)
{
fprintf(stream, ", (uintptr_t)parm%d", i+1);
}
else
{
fprintf(stream, "(uintptr_t)parm%d", i+1);
}
}
fprintf(stream, ");\n}\n");
fclose(stream);
}
static FILE *open_stub(void)
{
char filename[MAX_PARMSIZE+8];
FILE *stream;
snprintf(filename, MAX_PARMSIZE+7, "STUB_%s.c", g_parm[NAME_INDEX]);
filename[MAX_PARMSIZE+7] = '\0';
stream = fopen(filename, "w");
if (stream == NULL)
{
fprintf(stderr, "Failed to open %s: %s\n", filename, strerror(errno));
exit(9);
}
return stream;
}
static void generate_stub(int nparms)
{
FILE *stream = open_stub();
int i;
fprintf(stream, "/* Auto-generated %s stub file -- do not edit */\n\n", g_parm[0]);
fprintf(stream, "#include <%s>\n\n", g_parm[HEADER_INDEX]);
fprintf(stream, "uintptr_t STUB_%s(", g_parm[NAME_INDEX]);
if (nparms <= 0)
{
fprintf(stream, "void");
}
else
{
for (i = 0; i < nparms; i++)
{
if (i > 0)
{
fprintf(stream, ", uintptr_t parm%d", i+1);
}
else
{
fprintf(stream, "uintptr_t parm%d", i+1);
}
}
}
fprintf(stream, ")\n{\n");
fprintf(stream, " return (uintptr_t)%s(", g_parm[NAME_INDEX]);
for (i = 0; i < nparms; i++)
{
if (i > 0)
{
fprintf(stream, ", (%s)parm%d", g_parm[PARM1_INDEX+i], i+1);
}
else
{
fprintf(stream, "(%s)parm%d", g_parm[PARM1_INDEX+i], i+1);
}
}
fprintf(stream, ");\n}\n");
fclose(stream);
}
static void show_usage(const char *progname)
{
fprintf(stderr, "USAGE: %s [-p|s] <CSV file>\n", progname);
exit(1);
}
/****************************************************************************
* Public Functions
****************************************************************************/
int main(int argc, char **argv, char **envp)
{
char *csvpath;
bool proxies = false;
FILE *stream;
char *ptr;
int ch;
/* Parse command line options */
g_debug = false;
while ((ch = getopt(argc, argv, ":dps")) > 0)
{
switch (ch)
{
case 'd' :
g_debug = true;
break;
case 'p' :
proxies = true;
break;
case 's' :
proxies = false;
break;
case '?' :
fprintf(stderr, "Unrecognized option: %c\n", optopt);
show_usage(argv[0]);
case ':' :
fprintf(stderr, "Missing option argument, option: %c\n", optopt);
show_usage(argv[0]);
break;
fprintf(stderr, "Unexpected option: %c\n", ch);
show_usage(argv[0]);
}
}
if (optind >= argc)
{
fprintf(stderr, "Missing <CSV file>\n");
show_usage(argv[0]);
}
csvpath = argv[optind];
if (++optind < argc)
{
fprintf(stderr, "Unexpected garbage at the end of the line\n");
show_usage(argv[0]);
}
/* Open the CSV file */
stream= fopen(csvpath, "r");
if (!stream)
{
fprintf(stderr, "open %s failed: %s\n", csvpath, strerror(errno));
exit(3);
}
/* Process each line in the CVS file */
while ((ptr = read_line(stream)) != NULL)
{
/* Parse the line from the CVS file */
int nargs = parse_csvline(ptr);
if (nargs < 3)
{
fprintf(stderr, "Only %d arguments found: %s\n", nargs, g_line);
exit(8);
}
if (proxies)
{
generate_proxy(nargs-3);
}
else
{
generate_stub(nargs-3);
}
}
/* Close the CSV file */
fclose(stream);
return 0;
}