mirror of
https://github.com/PureDarwin/PureDarwin.git
synced 2026-01-25 04:06:25 +00:00
Add migcom tool
This commit is contained in:
@@ -3,4 +3,5 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/prefix)
|
||||
|
||||
add_subdirectory(cctools)
|
||||
add_subdirectory(dtrace_ctf)
|
||||
add_subdirectory(mig)
|
||||
add_subdirectory(xar)
|
||||
|
||||
34
tools/mig/CMakeLists.txt
Normal file
34
tools/mig/CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
add_executable(migcom)
|
||||
target_sources(migcom PRIVATE
|
||||
error.c
|
||||
global.c
|
||||
header.c
|
||||
mig.c
|
||||
routine.c
|
||||
server.c
|
||||
routine.c
|
||||
server.c
|
||||
statement.c
|
||||
string.c
|
||||
type.c
|
||||
user.c
|
||||
utils.c
|
||||
|
||||
${CMAKE_CURRENT_BINARY_DIR}/y.tab.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lexxer.yy.c
|
||||
)
|
||||
target_compile_definitions(migcom PRIVATE MIG_VERSION=\"\")
|
||||
target_include_directories(migcom PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c
|
||||
COMMAND yacc -d -b "${CMAKE_CURRENT_BINARY_DIR}/y" ${CMAKE_CURRENT_SOURCE_DIR}/parser.y
|
||||
COMMENT "Yacc parser.y" VERBATIM
|
||||
)
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lexxer.yy.c
|
||||
COMMAND lex -o "${CMAKE_CURRENT_BINARY_DIR}/lexxer.yy.c" ${CMAKE_CURRENT_SOURCE_DIR}/lexxer.l
|
||||
COMMENT "Lex lexxer.l" VERBATIM
|
||||
)
|
||||
|
||||
add_executable(mig IMPORTED)
|
||||
set_property(TARGET mig PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/mig.sh)
|
||||
add_dependencies(mig migcom)
|
||||
54
tools/mig/alloc.h
Normal file
54
tools/mig/alloc.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#ifndef _ALLOC_H
|
||||
#define _ALLOC_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#endif /* _ALLOC_H */
|
||||
111
tools/mig/error.c
Normal file
111
tools/mig/error.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "global.h"
|
||||
#include "error.h"
|
||||
|
||||
extern int lineno;
|
||||
extern char *yyinname;
|
||||
|
||||
static char *program;
|
||||
__private_extern__
|
||||
int mig_errors = 0;
|
||||
|
||||
/*ARGSUSED*/
|
||||
/*VARARGS1*/
|
||||
void
|
||||
fatal(char *format, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
va_start(pvar, format);
|
||||
fprintf(stderr, "%s: fatal: \"%s\", line %d: ", program, yyinname, lineno-1);
|
||||
(void) vfprintf(stderr, format, pvar);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(pvar);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
__private_extern__
|
||||
/*ARGSUSED*/
|
||||
/*VARARGS1*/
|
||||
void
|
||||
warn(char *format, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
va_start(pvar, format);
|
||||
if (!BeQuiet && (mig_errors == 0)) {
|
||||
fprintf(stderr, "\"%s\", line %d: warning: ", yyinname, lineno-1);
|
||||
(void) vfprintf(stderr, format, pvar);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
va_end(pvar);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
/*VARARGS1*/
|
||||
void
|
||||
error(char *format, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
va_start(pvar, format);
|
||||
fprintf(stderr, "\"%s\", line %d: ", yyinname, lineno-1);
|
||||
(void) vfprintf(stderr, format, pvar);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(pvar);
|
||||
mig_errors++;
|
||||
}
|
||||
|
||||
void
|
||||
set_program_name(char *name)
|
||||
{
|
||||
program = name;
|
||||
}
|
||||
61
tools/mig/error.h
Normal file
61
tools/mig/error.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#ifndef _ERROR_H
|
||||
#define _ERROR_H
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
extern void fatal(char *format, ...);
|
||||
extern void warn(char *format, ...);
|
||||
extern void error(char *format, ...);
|
||||
|
||||
extern int mig_errors;
|
||||
extern void set_program_name(char *name);
|
||||
|
||||
#endif /* _ERROR_H */
|
||||
151
tools/mig/global.c
Normal file
151
tools/mig/global.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include "strdefs.h"
|
||||
#include "global.h"
|
||||
#include "error.h"
|
||||
#include "mig_machine.h"
|
||||
|
||||
boolean_t PrintVersion = FALSE;
|
||||
boolean_t BeQuiet = FALSE;
|
||||
boolean_t BeVerbose = FALSE;
|
||||
boolean_t UseMsgRPC = TRUE;
|
||||
boolean_t GenSymTab = FALSE;
|
||||
boolean_t UseEventLogger = FALSE;
|
||||
boolean_t BeLint = FALSE;
|
||||
boolean_t BeAnsiC = TRUE;
|
||||
boolean_t CheckNDR = FALSE;
|
||||
boolean_t PackMsg = PACK_MESSAGES;
|
||||
boolean_t UseSplitHeaders = FALSE;
|
||||
boolean_t ShortCircuit = FALSE;
|
||||
boolean_t UseRPCTrap = FALSE;
|
||||
boolean_t TestRPCTrap= FALSE;
|
||||
boolean_t IsVoucherCodeAllowed = TRUE;
|
||||
|
||||
boolean_t IsKernelUser = FALSE;
|
||||
boolean_t IsKernelServer = FALSE;
|
||||
boolean_t UseSpecialReplyPort = FALSE;
|
||||
boolean_t HasUseSpecialReplyPort = FALSE;
|
||||
boolean_t HasConsumeOnSendError = FALSE;
|
||||
u_int ConsumeOnSendError = 0;
|
||||
|
||||
string_t RCSId = strNULL;
|
||||
|
||||
string_t SubsystemName = strNULL;
|
||||
u_int SubsystemBase = 0;
|
||||
|
||||
string_t MsgOption = strNULL;
|
||||
string_t WaitTime = strNULL;
|
||||
string_t SendTime = strNULL;
|
||||
string_t ErrorProc = "MsgError";
|
||||
string_t ServerPrefix = "";
|
||||
string_t UserPrefix = "";
|
||||
string_t ServerDemux = strNULL;
|
||||
string_t ServerImpl = strNULL;
|
||||
string_t ServerSubsys = strNULL;
|
||||
int MaxMessSizeOnStack = -1; /* by default, always on stack */
|
||||
int UserTypeLimit = -1; /* by default, assume unlimited size. */
|
||||
|
||||
string_t yyinname;
|
||||
|
||||
char NewCDecl[] = "(defined(__STDC__) || defined(c_plusplus))";
|
||||
char LintLib[] = "defined(LINTLIBRARY)";
|
||||
|
||||
void
|
||||
init_global()
|
||||
{
|
||||
yyinname = strmake("<no name yet>");
|
||||
}
|
||||
|
||||
string_t UserFilePrefix = strNULL;
|
||||
string_t UserHeaderFileName = strNULL;
|
||||
string_t ServerHeaderFileName = strNULL;
|
||||
string_t InternalHeaderFileName = strNULL;
|
||||
string_t DefinesHeaderFileName = strNULL;
|
||||
string_t UserFileName = strNULL;
|
||||
string_t ServerFileName = strNULL;
|
||||
string_t GenerationDate = strNULL;
|
||||
|
||||
void
|
||||
more_global()
|
||||
{
|
||||
if (SubsystemName == strNULL)
|
||||
fatal("no SubSystem declaration");
|
||||
|
||||
if (UserHeaderFileName == strNULL)
|
||||
UserHeaderFileName = strconcat(SubsystemName, ".h");
|
||||
else if (streql(UserHeaderFileName, "/dev/null"))
|
||||
UserHeaderFileName = strNULL;
|
||||
|
||||
if (UserFileName == strNULL)
|
||||
UserFileName = strconcat(SubsystemName, "User.c");
|
||||
else if (streql(UserFileName, "/dev/null"))
|
||||
UserFileName = strNULL;
|
||||
|
||||
if (ServerFileName == strNULL)
|
||||
ServerFileName = strconcat(SubsystemName, "Server.c");
|
||||
else if (streql(ServerFileName, "/dev/null"))
|
||||
ServerFileName = strNULL;
|
||||
|
||||
if (ServerDemux == strNULL)
|
||||
ServerDemux = strconcat(SubsystemName, "_server");
|
||||
|
||||
if (ServerImpl == strNULL)
|
||||
ServerImpl = strconcat(SubsystemName, "_impl");
|
||||
|
||||
if (ServerSubsys == strNULL) {
|
||||
if (ServerPrefix != strNULL)
|
||||
ServerSubsys = strconcat(ServerPrefix, SubsystemName);
|
||||
else
|
||||
ServerSubsys = SubsystemName;
|
||||
ServerSubsys = strconcat(ServerSubsys, "_subsystem");
|
||||
}
|
||||
if (HasUseSpecialReplyPort && !BeAnsiC) {
|
||||
fatal("Cannot use UseSpecialReplyPort in non ANSI mode\n");
|
||||
}
|
||||
}
|
||||
113
tools/mig/global.h
Normal file
113
tools/mig/global.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#ifndef _GLOBAL_H
|
||||
#define _GLOBAL_H
|
||||
|
||||
#include "type.h"
|
||||
|
||||
extern boolean_t PrintVersion; /* print bootstrap_cmds project version and exit */
|
||||
extern boolean_t BeQuiet; /* no warning messages */
|
||||
extern boolean_t BeVerbose; /* summarize types, routines */
|
||||
extern boolean_t BeDebug; /* enters in the debug mode */
|
||||
extern boolean_t UseMsgRPC;
|
||||
extern boolean_t GenSymTab;
|
||||
extern boolean_t UseEventLogger;
|
||||
extern boolean_t BeLint;
|
||||
extern boolean_t BeAnsiC;
|
||||
extern boolean_t CheckNDR;
|
||||
extern boolean_t PackMsg;
|
||||
extern boolean_t UseSplitHeaders;
|
||||
extern boolean_t ShortCircuit;
|
||||
extern boolean_t UseRPCTrap;
|
||||
extern boolean_t TestRPCTrap;
|
||||
extern boolean_t IsVoucherCodeAllowed;
|
||||
|
||||
extern boolean_t IsKernelUser;
|
||||
extern boolean_t IsKernelServer;
|
||||
extern boolean_t UseSpecialReplyPort;
|
||||
extern boolean_t HasUseSpecialReplyPort; /* whether UseSpecialReplyPort has ever been set to TRUE */
|
||||
extern boolean_t HasConsumeOnSendError; /* whether ConsumeOnSendError has ever been set */
|
||||
extern u_int ConsumeOnSendError;
|
||||
|
||||
extern string_t RCSId;
|
||||
|
||||
extern string_t SubsystemName;
|
||||
extern u_int SubsystemBase;
|
||||
|
||||
extern string_t MsgOption;
|
||||
extern string_t WaitTime;
|
||||
extern string_t SendTime;
|
||||
extern string_t ErrorProc;
|
||||
extern string_t ServerPrefix;
|
||||
extern string_t UserPrefix;
|
||||
extern string_t ServerDemux;
|
||||
extern string_t ServerImpl;
|
||||
extern string_t ServerSubsys;
|
||||
extern int MaxMessSizeOnStack;
|
||||
extern int UserTypeLimit;
|
||||
|
||||
extern int yylineno;
|
||||
extern string_t yyinname;
|
||||
|
||||
extern void init_global(void);
|
||||
|
||||
extern string_t UserFilePrefix;
|
||||
extern string_t UserHeaderFileName;
|
||||
extern string_t ServerHeaderFileName;
|
||||
extern string_t InternalHeaderFileName;
|
||||
extern string_t DefinesHeaderFileName;
|
||||
extern string_t UserFileName;
|
||||
extern string_t ServerFileName;
|
||||
|
||||
extern void more_global(void);
|
||||
|
||||
extern char NewCDecl[];
|
||||
extern char LintLib[];
|
||||
|
||||
#endif /* _GLOBAL_H */
|
||||
569
tools/mig/header.c
Normal file
569
tools/mig/header.c
Normal file
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include "write.h"
|
||||
#include "utils.h"
|
||||
#include "global.h"
|
||||
#include "strdefs.h"
|
||||
#include "error.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
WriteIncludes(FILE *file, boolean_t isuser, boolean_t isdef)
|
||||
{
|
||||
if (isdef) {
|
||||
fprintf(file, "#include <mach/port.h>\n");
|
||||
fprintf(file, "#include <mach/machine/kern_return.h>\n");
|
||||
if (!isuser)
|
||||
fprintf(file, "#include <mach/mig_errors.h>\n");
|
||||
}
|
||||
else {
|
||||
fprintf(file, "#include <string.h>\n");
|
||||
fprintf(file, "#include <mach/ndr.h>\n");
|
||||
fprintf(file, "#include <mach/boolean.h>\n");
|
||||
fprintf(file, "#include <mach/kern_return.h>\n");
|
||||
fprintf(file, "#include <mach/notify.h>\n");
|
||||
fprintf(file, "#include <mach/mach_types.h>\n");
|
||||
fprintf(file, "#include <mach/message.h>\n");
|
||||
fprintf(file, "#include <mach/mig_errors.h>\n");
|
||||
fprintf(file, "#include <mach/port.h>\n");
|
||||
|
||||
if (IsVoucherCodeAllowed && !IsKernelUser && !IsKernelServer) {
|
||||
fprintf(file, "\t\n/* BEGIN VOUCHER CODE */\n\n");
|
||||
fprintf(file, "#ifndef KERNEL\n");
|
||||
fprintf(file, "#if defined(__has_include)\n");
|
||||
fprintf(file, "#if __has_include(<mach/mig_voucher_support.h>)\n");
|
||||
fprintf(file, "#ifndef USING_VOUCHERS\n");
|
||||
fprintf(file, "#define USING_VOUCHERS\n");
|
||||
fprintf(file, "#endif\n");
|
||||
|
||||
|
||||
fprintf(file, "#ifndef __VOUCHER_FORWARD_TYPE_DECLS__\n");
|
||||
fprintf(file, "#define __VOUCHER_FORWARD_TYPE_DECLS__\n");
|
||||
|
||||
fprintf(file, "#ifdef __cplusplus\n");
|
||||
fprintf(file, "extern \"C\" {\n");
|
||||
fprintf(file, "#endif\n");
|
||||
|
||||
fprintf(file, "\textern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import));\n");
|
||||
|
||||
fprintf(file, "#ifdef __cplusplus\n");
|
||||
fprintf(file, "}\n");
|
||||
fprintf(file, "#endif\n");
|
||||
|
||||
fprintf(file, "#endif // __VOUCHER_FORWARD_TYPE_DECLS__\n");
|
||||
fprintf(file, "#endif // __has_include(<mach/mach_voucher_types.h>)\n");
|
||||
fprintf(file, "#endif // __has_include\n");
|
||||
fprintf(file, "#endif // !KERNEL\n");
|
||||
|
||||
fprintf(file, "\t\n/* END VOUCHER CODE */\n\n");
|
||||
}
|
||||
|
||||
fprintf(file, "\t\n/* BEGIN MIG_STRNCPY_ZEROFILL CODE */\n\n");
|
||||
fprintf(file, "#if defined(__has_include)\n");
|
||||
fprintf(file, "#if __has_include(<mach/mig_strncpy_zerofill_support.h>)\n");
|
||||
fprintf(file, "#ifndef USING_MIG_STRNCPY_ZEROFILL\n");
|
||||
fprintf(file, "#define USING_MIG_STRNCPY_ZEROFILL\n");
|
||||
fprintf(file, "#endif\n");
|
||||
|
||||
fprintf(file, "#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__\n");
|
||||
fprintf(file, "#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__\n");
|
||||
|
||||
fprintf(file, "#ifdef __cplusplus\n");
|
||||
fprintf(file, "extern \"C\" {\n");
|
||||
fprintf(file, "#endif\n");
|
||||
|
||||
fprintf(file, "\textern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import));\n");
|
||||
|
||||
fprintf(file, "#ifdef __cplusplus\n");
|
||||
fprintf(file, "}\n");
|
||||
fprintf(file, "#endif\n");
|
||||
|
||||
fprintf(file, "#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */\n");
|
||||
fprintf(file, "#endif /* __has_include(<mach/mig_strncpy_zerofill_support.h>) */\n");
|
||||
fprintf(file, "#endif /* __has_include */\n");
|
||||
fprintf(file, "\t\n/* END MIG_STRNCPY_ZEROFILL CODE */\n\n");
|
||||
|
||||
if (ShortCircuit)
|
||||
fprintf(file, "#include <mach/rpc.h>\n");
|
||||
if (isuser && IsKernelUser) {
|
||||
fprintf(file, "#if\t(__MigKernelSpecificCode) || (_MIG_KERNEL_SPECIFIC_CODE_)\n");
|
||||
fprintf(file, "#include <kern/ipc_mig.h>\n");
|
||||
fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
|
||||
}
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
WriteETAPDefines(FILE *file)
|
||||
{
|
||||
statement_t *stat;
|
||||
int fnum;
|
||||
char *fname;
|
||||
int first = TRUE;
|
||||
|
||||
fprintf(file, "\n#ifndef subsystem_to_name_map_%s\n", SubsystemName);
|
||||
fprintf(file, "#define subsystem_to_name_map_%s \\\n", SubsystemName);
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext)
|
||||
if (stat->stKind == skRoutine) {
|
||||
fnum = SubsystemBase + stat->stRoutine->rtNumber;
|
||||
fname = stat->stRoutine->rtName;
|
||||
if (! first)
|
||||
fprintf(file, ",\\\n");
|
||||
fprintf(file, " { \"%s\", %d }", fname, fnum);
|
||||
first = FALSE;
|
||||
}
|
||||
fprintf(file, "\n#endif\n");
|
||||
}
|
||||
|
||||
static void
|
||||
WriteProlog(FILE *file, char *protect, boolean_t more, boolean_t isuser)
|
||||
{
|
||||
if (protect != strNULL) {
|
||||
fprintf(file, "#ifndef\t_%s\n", protect);
|
||||
fprintf(file, "#define\t_%s\n", protect);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
fprintf(file, "/* Module %s */\n", SubsystemName);
|
||||
fprintf(file, "\n");
|
||||
|
||||
if (more) {
|
||||
WriteIncludes(file, isuser, UseSplitHeaders);
|
||||
}
|
||||
fprintf(file, "#ifdef AUTOTEST\n");
|
||||
fprintf(file, "#ifndef FUNCTION_PTR_T\n");
|
||||
fprintf(file, "#define FUNCTION_PTR_T\n");
|
||||
fprintf(file, "typedef void (*function_ptr_t)");
|
||||
fprintf(file, "(mach_port_t, char *, mach_msg_type_number_t);\n");
|
||||
fprintf(file, "typedef struct {\n");
|
||||
fprintf(file, " char *name;\n");
|
||||
fprintf(file, " function_ptr_t function;\n");
|
||||
fprintf(file, "} function_table_entry;\n");
|
||||
fprintf(file, "typedef function_table_entry *function_table_t;\n");
|
||||
fprintf(file, "#endif /* FUNCTION_PTR_T */\n");
|
||||
fprintf(file, "#endif /* AUTOTEST */\n");
|
||||
fprintf(file, "\n#ifndef\t%s_MSG_COUNT\n", SubsystemName);
|
||||
fprintf(file, "#define\t%s_MSG_COUNT\t%d\n", SubsystemName, rtNumber);
|
||||
fprintf(file, "#endif\t/* %s_MSG_COUNT */\n\n", SubsystemName);
|
||||
}
|
||||
|
||||
static void
|
||||
WriteEpilog(FILE *file, char *protect, boolean_t isuser)
|
||||
{
|
||||
char *defname = isuser ? "__AfterMigUserHeader" : "__AfterMigServerHeader";
|
||||
|
||||
WriteETAPDefines(file);
|
||||
fprintf(file, "\n#ifdef %s\n%s\n#endif /* %s */\n", defname, defname, defname);
|
||||
if (protect != strNULL) {
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "#endif\t /* _%s */\n", protect);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WriteUserRoutine(FILE *file, routine_t *rt)
|
||||
{
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName);
|
||||
WriteMigExternal(file);
|
||||
fprintf(file, "%s %s\n", ReturnTypeStr(rt), rt->rtUserName);
|
||||
if (BeLint) {
|
||||
fprintf(file, "#if\t%s\n", LintLib);
|
||||
fprintf(file, " (");
|
||||
WriteList(file, rt->rtArgs, WriteNameDecl, akbUserArg, ", " , "");
|
||||
fprintf(file, ")\n");
|
||||
WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ";\n", ";\n");
|
||||
fprintf(file, "{ ");
|
||||
fprintf(file, "return ");
|
||||
fprintf(file, "%s(", rt->rtUserName);
|
||||
WriteList(file, rt->rtArgs, WriteNameDecl, akbUserArg, ", ", "");
|
||||
fprintf(file, "); }\n");
|
||||
fprintf(file, "#else\n");
|
||||
}
|
||||
if (BeAnsiC) {
|
||||
fprintf(file, "(\n");
|
||||
WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n");
|
||||
fprintf(file, ");\n");
|
||||
}
|
||||
else {
|
||||
fprintf(file, "#if\t%s\n", NewCDecl);
|
||||
fprintf(file, "(\n");
|
||||
WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n");
|
||||
fprintf(file, ");\n");
|
||||
fprintf(file, "#else\n");
|
||||
|
||||
fprintf(file, " ();\n");
|
||||
fprintf(file, "#endif\t/* %s */\n", NewCDecl);
|
||||
}
|
||||
if (BeLint) {
|
||||
fprintf(file, "#endif\t/* %s */\n", LintLib);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WriteUserRequestUnion(FILE *file, statement_t *stats)
|
||||
{
|
||||
statement_t *stat;
|
||||
|
||||
fprintf(file, "/* union of all requests */\n\n");
|
||||
fprintf(file, "#ifndef __RequestUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
|
||||
fprintf(file, "#define __RequestUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
|
||||
fprintf(file, "union __RequestUnion__%s%s_subsystem {\n", UserPrefix, SubsystemName);
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext) {
|
||||
if (stat->stKind == skRoutine) {
|
||||
routine_t *rt;
|
||||
|
||||
rt = stat->stRoutine;
|
||||
fprintf(file, "\t__Request__%s_t Request_%s;\n", rt->rtName, rt->rtUserName);
|
||||
}
|
||||
}
|
||||
fprintf(file, "};\n");
|
||||
fprintf(file, "#endif /* !__RequestUnion__%s%s_subsystem__defined */\n", UserPrefix, SubsystemName);
|
||||
}
|
||||
|
||||
void
|
||||
WriteUserReplyUnion(FILE *file, statement_t *stats)
|
||||
{
|
||||
statement_t *stat;
|
||||
|
||||
fprintf(file, "/* union of all replies */\n\n");
|
||||
fprintf(file, "#ifndef __ReplyUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
|
||||
fprintf(file, "#define __ReplyUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
|
||||
fprintf(file, "union __ReplyUnion__%s%s_subsystem {\n", UserPrefix, SubsystemName);
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext) {
|
||||
if (stat->stKind == skRoutine) {
|
||||
routine_t *rt;
|
||||
|
||||
rt = stat->stRoutine;
|
||||
fprintf(file, "\t__Reply__%s_t Reply_%s;\n", rt->rtName, rt->rtUserName);
|
||||
}
|
||||
}
|
||||
fprintf(file, "};\n");
|
||||
fprintf(file, "#endif /* !__RequestUnion__%s%s_subsystem__defined */\n", UserPrefix, SubsystemName);
|
||||
}
|
||||
|
||||
void
|
||||
WriteUserHeader(FILE *file, statement_t *stats)
|
||||
{
|
||||
statement_t *stat;
|
||||
char *protect = strconcat(SubsystemName, "_user_");
|
||||
|
||||
WriteProlog(file, protect, TRUE, TRUE);
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext)
|
||||
switch (stat->stKind) {
|
||||
|
||||
case skImport:
|
||||
case skUImport:
|
||||
case skDImport:
|
||||
WriteImport(file, stat->stFileName);
|
||||
break;
|
||||
|
||||
case skRoutine:
|
||||
case skSImport:
|
||||
case skIImport:
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("WriteHeader(): bad statement_kind_t (%d)", (int) stat->stKind);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "#ifdef __BeforeMigUserHeader\n");
|
||||
fprintf(file, "__BeforeMigUserHeader\n");
|
||||
fprintf(file, "#endif /* __BeforeMigUserHeader */\n");
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "#include <sys/cdefs.h>\n");
|
||||
fprintf(file, "__BEGIN_DECLS\n");
|
||||
fprintf(file, "\n");
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext) {
|
||||
if (stat->stKind == skRoutine)
|
||||
WriteUserRoutine(file, stat->stRoutine);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "__END_DECLS\n");
|
||||
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "/********************** Caution **************************/\n");
|
||||
fprintf(file, "/* The following data types should be used to calculate */\n");
|
||||
fprintf(file, "/* maximum message sizes only. The actual message may be */\n");
|
||||
fprintf(file, "/* smaller, and the position of the arguments within the */\n");
|
||||
fprintf(file, "/* message layout may vary from what is presented here. */\n");
|
||||
fprintf(file, "/* For example, if any of the arguments are variable- */\n");
|
||||
fprintf(file, "/* sized, and less than the maximum is sent, the data */\n");
|
||||
fprintf(file, "/* will be packed tight in the actual message to reduce */\n");
|
||||
fprintf(file, "/* the presence of holes. */\n");
|
||||
fprintf(file, "/********************** Caution **************************/\n");
|
||||
fprintf(file, "\n");
|
||||
|
||||
WriteRequestTypes(file, stats);
|
||||
WriteUserRequestUnion(file, stats);
|
||||
|
||||
WriteReplyTypes(file, stats);
|
||||
WriteUserReplyUnion(file, stats);
|
||||
|
||||
WriteEpilog(file, protect, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
WriteDefinesRoutine(FILE *file, routine_t *rt)
|
||||
{
|
||||
char *up = (char *)malloc(strlen(rt->rtName)+1);
|
||||
|
||||
up = toupperstr(strcpy(up, rt->rtName));
|
||||
fprintf(file, "#define\tMACH_ID_%s\t\t%d\t/* %s() */\n", up, rt->rtNumber + SubsystemBase, rt->rtName);
|
||||
if (rt->rtKind == rkRoutine)
|
||||
fprintf(file, "#define\tMACH_ID_%s_REPLY\t\t%d\t/* %s() */\n", up, rt->rtNumber + SubsystemBase + 100, rt->rtName);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
WriteServerRoutine(FILE *file, routine_t *rt)
|
||||
{
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName);
|
||||
WriteMigExternal(file);
|
||||
|
||||
// MIG_SERVER_ROUTINE can be defined by system headers to resolve to an attribute that
|
||||
// tells the compiler that this is a MIG server routine. Useful for static analysis.
|
||||
fprintf(file, "MIG_SERVER_ROUTINE\n%s %s\n", ReturnTypeStr(rt), rt->rtServerName);
|
||||
|
||||
if (BeLint) {
|
||||
fprintf(file, "#if\t%s\n", LintLib);
|
||||
fprintf(file, " (");
|
||||
WriteList(file, rt->rtArgs, WriteNameDecl, akbServerArg, ", " , "");
|
||||
fprintf(file, ")\n");
|
||||
WriteList(file, rt->rtArgs, WriteServerVarDecl, akbServerArg, ";\n", ";\n");
|
||||
fprintf(file, "{ ");
|
||||
fprintf(file, "return ");
|
||||
fprintf(file, "%s(", rt->rtServerName);
|
||||
WriteList(file, rt->rtArgs, WriteNameDecl, akbServerArg, ", ", "");
|
||||
fprintf(file, "); }\n");
|
||||
fprintf(file, "#else /* %s */\n",LintLib);
|
||||
}
|
||||
if (BeAnsiC) {
|
||||
fprintf(file, "(\n");
|
||||
WriteList(file, rt->rtArgs, WriteServerVarDecl, akbServerArg, ",\n", "\n");
|
||||
fprintf(file, ");\n");
|
||||
}
|
||||
else {
|
||||
fprintf(file, "#if\t%s\n", NewCDecl);
|
||||
fprintf(file, "(\n");
|
||||
WriteList(file, rt->rtArgs, WriteServerVarDecl, akbServerArg, ",\n", "\n");
|
||||
fprintf(file, ");\n");
|
||||
fprintf(file, "#else\n");
|
||||
|
||||
fprintf(file, " ();\n");
|
||||
fprintf(file, "#endif\t/* %s */\n", NewCDecl);
|
||||
}
|
||||
if (BeLint) {
|
||||
fprintf(file, "#endif\t/* %s */\n", LintLib);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WriteDispatcher(FILE *file)
|
||||
{
|
||||
statement_t *stat;
|
||||
int descr_count = 0;
|
||||
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext)
|
||||
if (stat->stKind == skRoutine) {
|
||||
routine_t *rt = stat->stRoutine;
|
||||
descr_count += rtCountArgDescriptors(rt->rtArgs, (int *) 0);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
|
||||
WriteMigExternal(file);
|
||||
fprintf(file, "boolean_t %s(\n", ServerDemux);
|
||||
fprintf(file, "\t\tmach_msg_header_t *InHeadP,\n");
|
||||
fprintf(file, "\t\tmach_msg_header_t *OutHeadP);\n\n");
|
||||
|
||||
WriteMigExternal(file);
|
||||
fprintf(file, "mig_routine_t %s_routine(\n", ServerDemux);
|
||||
fprintf(file, "\t\tmach_msg_header_t *InHeadP);\n\n");
|
||||
|
||||
fprintf(file, "\n/* Description of this subsystem, for use in direct RPC */\n");
|
||||
fprintf(file, "extern const struct %s {\n", ServerSubsys);
|
||||
if (UseRPCTrap) {
|
||||
fprintf(file, "\tstruct subsystem *\tsubsystem;\t/* Reserved for system use */\n");
|
||||
}
|
||||
else {
|
||||
fprintf(file, "\tmig_server_routine_t\tserver;\t/* Server routine */\n");
|
||||
}
|
||||
fprintf(file, "\tmach_msg_id_t\tstart;\t/* Min routine number */\n");
|
||||
fprintf(file, "\tmach_msg_id_t\tend;\t/* Max routine number + 1 */\n");
|
||||
fprintf(file, "\tunsigned int\tmaxsize;\t/* Max msg size */\n");
|
||||
if (UseRPCTrap) {
|
||||
fprintf(file, "\tvm_address_t\tbase_addr;\t/* Base address */\n");
|
||||
fprintf(file, "\tstruct rpc_routine_descriptor\t/*Array of routine descriptors */\n");
|
||||
}
|
||||
else {
|
||||
fprintf(file, "\tvm_address_t\treserved;\t/* Reserved */\n");
|
||||
fprintf(file, "\tstruct routine_descriptor\t/*Array of routine descriptors */\n");
|
||||
}
|
||||
fprintf(file, "\t\troutine[%d];\n", rtNumber);
|
||||
if (UseRPCTrap) {
|
||||
fprintf(file, "\tstruct rpc_routine_arg_descriptor\t/*Array of arg descriptors */\n");
|
||||
fprintf(file, "\t\targ_descriptor[%d];\n", descr_count);
|
||||
}
|
||||
fprintf(file, "} %s;\n", ServerSubsys);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
WriteBogusServerRoutineAnnotationDefine(FILE *file) {
|
||||
// MIG_SERVER_ROUTINE can be defined by system headers to resolve to
|
||||
// an attribute that tells the compiler that this is a MIG server routine.
|
||||
// Useful for static analysis.
|
||||
fprintf(file, "#ifndef MIG_SERVER_ROUTINE\n");
|
||||
fprintf(file, "#define MIG_SERVER_ROUTINE\n");
|
||||
fprintf(file, "#endif\n");
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
WriteServerHeader(FILE *file, statement_t *stats)
|
||||
{
|
||||
statement_t *stat;
|
||||
char *protect = strconcat(SubsystemName, "_server_");
|
||||
|
||||
WriteProlog(file, protect, TRUE, FALSE);
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext)
|
||||
switch (stat->stKind) {
|
||||
|
||||
case skImport:
|
||||
case skSImport:
|
||||
case skDImport:
|
||||
WriteImport(file, stat->stFileName);
|
||||
break;
|
||||
|
||||
case skRoutine:
|
||||
case skUImport:
|
||||
case skIImport:
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("WriteServerHeader(): bad statement_kind_t (%d)", (int) stat->stKind);
|
||||
}
|
||||
fprintf(file, "\n#ifdef __BeforeMigServerHeader\n");
|
||||
fprintf(file, "__BeforeMigServerHeader\n");
|
||||
fprintf(file, "#endif /* __BeforeMigServerHeader */\n\n");
|
||||
|
||||
WriteBogusServerRoutineAnnotationDefine(file);
|
||||
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext) {
|
||||
if (stat->stKind == skRoutine)
|
||||
WriteServerRoutine(file, stat->stRoutine);
|
||||
}
|
||||
WriteDispatcher(file);
|
||||
|
||||
WriteRequestTypes(file, stats);
|
||||
WriteServerRequestUnion(file, stats);
|
||||
|
||||
WriteReplyTypes(file, stats);
|
||||
WriteServerReplyUnion(file, stats);
|
||||
|
||||
WriteEpilog(file, protect, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
WriteInternalRedefine(FILE *file, routine_t *rt)
|
||||
{
|
||||
fprintf(file, "#define %s %s_external\n", rt->rtUserName, rt->rtUserName);
|
||||
}
|
||||
|
||||
void
|
||||
WriteInternalHeader(FILE *file, statement_t *stats)
|
||||
{
|
||||
statement_t *stat;
|
||||
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext)
|
||||
switch (stat->stKind) {
|
||||
|
||||
case skRoutine:
|
||||
WriteInternalRedefine(file, stat->stRoutine);
|
||||
break;
|
||||
|
||||
case skImport:
|
||||
case skUImport:
|
||||
case skSImport:
|
||||
case skDImport:
|
||||
case skIImport:
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("WriteInternalHeader(): bad statement_kind_t (%d)", (int) stat->stKind);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WriteDefinesHeader(FILE *file, statement_t *stats)
|
||||
{
|
||||
statement_t *stat;
|
||||
char *protect = strconcat(SubsystemName, "_defines");
|
||||
|
||||
WriteProlog(file, protect, FALSE, FALSE);
|
||||
fprintf(file, "\n/*\tDefines related to the Subsystem %s\t*/\n\n", SubsystemName);
|
||||
for (stat = stats; stat != stNULL; stat = stat->stNext)
|
||||
switch (stat->stKind) {
|
||||
|
||||
case skRoutine:
|
||||
WriteDefinesRoutine(file, stat->stRoutine);
|
||||
break;
|
||||
|
||||
case skImport:
|
||||
case skSImport:
|
||||
case skUImport:
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("WriteDefinesHeader(): bad statement_kind_t (%d)", (int) stat->stKind);
|
||||
}
|
||||
WriteEpilog(file, protect, FALSE);
|
||||
}
|
||||
52
tools/mig/lexxer.h
Normal file
52
tools/mig/lexxer.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
extern void LookFileName(void);
|
||||
extern void LookString(void);
|
||||
extern void LookQString(void);
|
||||
extern void LookNormal(void);
|
||||
314
tools/mig/lexxer.l
Normal file
314
tools/mig/lexxer.l
Normal file
@@ -0,0 +1,314 @@
|
||||
%k 10000
|
||||
%n 5000
|
||||
%a 20000
|
||||
%e 10000
|
||||
%p 25000
|
||||
|
||||
Ident ([A-Za-z_][A-Za-z_0-9]*)
|
||||
Number ([0-9]+)
|
||||
String ([-/._$A-Za-z0-9]+)
|
||||
QString (\"[^"\n]*\")
|
||||
AString (\<[^>\n]*\>)
|
||||
FileName ({QString}|{AString})
|
||||
|
||||
/* new flex syntax to accomplish the same thing as #define YY_NO_UNPUT */
|
||||
%option nounput
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* "Portions Copyright (c) 1999, 2008 Apple Inc. All Rights
|
||||
* Reserved. This file contains Original Code and/or Modifications of
|
||||
* Original Code as defined in and that are subject to the Apple Public
|
||||
* Source License Version 1.0 (the 'License'). You may not use this file
|
||||
* except in compliance with the License. Please obtain a copy of the
|
||||
* License at http://www.apple.com/publicsource and read it before using
|
||||
* this file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License."
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include "strdefs.h"
|
||||
#include "type.h"
|
||||
#include <sys/types.h>
|
||||
#include <mach/message.h>
|
||||
#include <mach/std_types.h>
|
||||
#include "statement.h"
|
||||
#include "global.h"
|
||||
#include "y.tab.h" // was parser.h
|
||||
#include "lexxer.h"
|
||||
#include "mig_machine.h"
|
||||
|
||||
#define PortSize (sizeof (mach_port_t) * NBBY)
|
||||
#ifdef __STDC__
|
||||
#define stringize(x) #x
|
||||
#else /* __STDC__ */
|
||||
#define stringize(x) "x"
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef LDEBUG
|
||||
#define RETURN(sym) \
|
||||
{ \
|
||||
printf("yylex: returning '%s' (%d)\n", stringize(sym), (sym)); \
|
||||
return (sym); \
|
||||
}
|
||||
#else /* LDEBUG */
|
||||
#define RETURN(sym) return (sym)
|
||||
#endif /* LDEBUG */
|
||||
|
||||
#define TPRETURN(intype, outtype, tsize) \
|
||||
{ \
|
||||
yylval.symtype.innumber = (intype); \
|
||||
yylval.symtype.instr = stringize(intype); \
|
||||
yylval.symtype.outnumber = (outtype); \
|
||||
yylval.symtype.outstr = stringize(outtype); \
|
||||
yylval.symtype.size = (tsize); \
|
||||
RETURN(sySymbolicType); \
|
||||
}
|
||||
|
||||
#define TRETURN(type, tsize) TPRETURN(type,type,tsize)
|
||||
|
||||
#define SAVE(s) do {oldYYBegin = s; BEGIN s; } while (0)
|
||||
|
||||
#define RESTORE BEGIN oldYYBegin
|
||||
|
||||
#define FRETURN(val) \
|
||||
{ \
|
||||
yylval.flag = (val); \
|
||||
RETURN(syIPCFlag); \
|
||||
}
|
||||
|
||||
#define YY_NO_UNPUT /* suppress yyunput generation */
|
||||
|
||||
static int oldYYBegin = 0;
|
||||
|
||||
int lineno = 0; /* Replaces lex yylineno */
|
||||
|
||||
static void doSharp(char *); /* process body of # directives */
|
||||
extern void yyerror(char *);
|
||||
%}
|
||||
|
||||
%Start Normal String FileName QString SkipToEOL
|
||||
|
||||
%%
|
||||
|
||||
<Normal>[Rr][Oo][Uu][Tt][Ii][Nn][Ee] RETURN(syRoutine);
|
||||
<Normal>[Ss][Ii][Mm][Pp][Ll][Ee][Rr][Oo][Uu][Tt][Ii][Nn][Ee] RETURN(sySimpleRoutine);
|
||||
<Normal>[Ss][Uu][Bb][Ss][Yy][Ss][Tt][Ee][Mm] RETURN(sySubsystem);
|
||||
<Normal>[Mm][Ss][Gg][Oo][Pp][Tt][Ii][Oo][Nn] RETURN(syMsgOption);
|
||||
<Normal>[Uu][Ss][Ee][Ss][Pp][Ee][Cc][Ii][Aa][Ll][Rr][Ee][Pp][Ll][Yy][Pp][Oo][Rr][Tt] RETURN(syUseSpecialReplyPort);
|
||||
<Normal>[Cc][Oo][Nn][Ss][Uu][Mm][Ee][Oo][Nn][Ss][Ee][Nn][Dd][Ee][Rr][Rr][Oo][Rr] RETURN(syConsumeOnSendError);
|
||||
<Normal>[Mm][Ss][Gg][Ss][Ee][Qq][Nn][Oo] RETURN(syMsgSeqno);
|
||||
<Normal>[Ww][Aa][Ii][Tt][Tt][Ii][Mm][Ee] RETURN(syWaitTime);
|
||||
<Normal>[Ss][Ee][Nn][Dd][Tt][Ii][Mm][Ee] RETURN(sySendTime);
|
||||
<Normal>[Nn][Oo][Ww][Aa][Ii][Tt][Tt][Ii][Mm][Ee] RETURN(syNoWaitTime);
|
||||
<Normal>[Nn][Oo][Ss][Ee][Nn][Dd][Tt][Ii][Mm][Ee] RETURN(syNoSendTime);
|
||||
<Normal>[Ii][Nn] RETURN(syIn);
|
||||
<Normal>[Oo][Uu][Tt] RETURN(syOut);
|
||||
<Normal>[Uu][Ss][Ee][Rr][Ii][Mm][Pp][Ll] RETURN(syUserImpl);
|
||||
<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Ii][Mm][Pp][Ll] RETURN(syServerImpl);
|
||||
<Normal>[Ss][Ee][Cc][Tt][Oo][Kk][Ee][Nn] RETURN(sySecToken);
|
||||
<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Ss][Ee][Cc][Tt][Oo][Kk][Ee][Nn] RETURN(syServerSecToken);
|
||||
<Normal>[Uu][Ss][Ee][Rr][Ss][Ee][Cc][Tt][Oo][Kk][Ee][Nn] RETURN(syUserSecToken);
|
||||
<Normal>[Aa][Uu][Dd][Ii][Tt][Tt][Oo][Kk][Ee][Nn] RETURN(syAuditToken);
|
||||
<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Aa][Uu][Dd][Ii][Tt][Tt][Oo][Kk][Ee][Nn] RETURN(syServerAuditToken);
|
||||
<Normal>[Uu][Ss][Ee][Rr][Aa][Uu][Dd][Ii][Tt][Tt][Oo][Kk][Ee][Nn] RETURN(syUserAuditToken);
|
||||
<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Cc][Oo][Nn][Tt][Ee][Xx][Tt][Tt][Oo][Kk][Ee][Nn] RETURN(syServerContextToken);
|
||||
<Normal>[Ii][Nn][Oo][Uu][Tt] RETURN(syInOut);
|
||||
<Normal>[Rr][Ee][Qq][Uu][Ee][Ss][Tt][Pp][Oo][Rr][Tt] RETURN(syRequestPort);
|
||||
<Normal>[Rr][Ee][Pp][Ll][Yy][Pp][Oo][Rr][Tt] RETURN(syReplyPort);
|
||||
<Normal>[Uu][Rr][Ee][Pp][Ll][Yy][Pp][Oo][Rr][Tt] RETURN(syUReplyPort);
|
||||
<Normal>[Ss][Rr][Ee][Pp][Ll][Yy][Pp][Oo][Rr][Tt] RETURN(sySReplyPort);
|
||||
<Normal>[Aa][Rr][Rr][Aa][Yy] RETURN(syArray);
|
||||
<Normal>[Oo][Ff] RETURN(syOf);
|
||||
<Normal>[Ee][Rr][Rr][Oo][Rr] RETURN(syErrorProc);
|
||||
<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Pp][Rr][Ee][Ff][Ii][Xx] RETURN(syServerPrefix);
|
||||
<Normal>[Uu][Ss][Ee][Rr][Pp][Rr][Ee][Ff][Ii][Xx] RETURN(syUserPrefix);
|
||||
<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Dd][Ee][Mm][Uu][Xx] RETURN(syServerDemux);
|
||||
<Normal>[Rr][Cc][Ss][Ii][Dd] RETURN(syRCSId);
|
||||
<Normal>[Ii][Mm][Pp][Oo][Rr][Tt] RETURN(syImport);
|
||||
<Normal>[Uu][Ii][Mm][Pp][Oo][Rr][Tt] RETURN(syUImport);
|
||||
<Normal>[Ss][Ii][Mm][Pp][Oo][Rr][Tt] RETURN(sySImport);
|
||||
<Normal>[Dd][Ii][Mm][Pp][Oo][Rr][Tt] RETURN(syDImport);
|
||||
<Normal>[Ii][Ii][Mm][Pp][Oo][Rr][Tt] RETURN(syIImport);
|
||||
<Normal>[Tt][Yy][Pp][Ee] RETURN(syType);
|
||||
<Normal>[Kk][Ee][Rr][Nn][Ee][Ll][Ss][Ee][Rr][Vv][Ee][Rr] RETURN(syKernelServer);
|
||||
<Normal>[Kk][Ee][Rr][Nn][Ee][Ll][Uu][Ss][Ee][Rr] RETURN(syKernelUser);
|
||||
<Normal>[Ss][Kk][Ii][Pp] RETURN(sySkip);
|
||||
<Normal>[Ss][Tt][Rr][Uu][Cc][Tt] RETURN(syStruct);
|
||||
<Normal>[Ii][Nn][Tt][Rr][Aa][Nn] RETURN(syInTran);
|
||||
<Normal>[Oo][Uu][Tt][Tt][Rr][Aa][Nn] RETURN(syOutTran);
|
||||
<Normal>[Dd][Ee][Ss][Tt][Rr][Uu][Cc][Tt][Oo][Rr] RETURN(syDestructor);
|
||||
<Normal>[Cc][Tt][Yy][Pp][Ee] RETURN(syCType);
|
||||
<Normal>[Cc][Uu][Ss][Ee][Rr][Tt][Yy][Pp][Ee] RETURN(syCUserType);
|
||||
<Normal>[Cc][Ss][Ee][Rr][Vv][Ee][Rr][Tt][Yy][Pp][Ee] RETURN(syCServerType);
|
||||
<Normal>[Cc]_[Ss][Tt][Rr][Ii][Nn][Gg] RETURN(syCString);
|
||||
|
||||
<Normal>[Ss][Aa][Mm][Ee][Cc][Oo][Uu][Nn][Tt] FRETURN(flSameCount);
|
||||
<Normal>[Rr][Ee][Tt][Cc][Oo][Dd][Ee] FRETURN(flRetCode);
|
||||
<Normal>[Pp][Hh][Yy][Ss][Ii][Cc][Aa][Ll][Cc][Oo][Pp][Yy] FRETURN(flPhysicalCopy);
|
||||
<Normal>[Oo][Vv][Ee][Rr][Ww][Rr][Ii][Tt][Ee] FRETURN(flOverwrite);
|
||||
<Normal>[Dd][Ee][Aa][Ll][Ll][Oo][Cc] FRETURN(flDealloc);
|
||||
<Normal>[Nn][Oo][Tt][Dd][Ee][Aa][Ll][Ll][Oo][Cc] FRETURN(flNotDealloc);
|
||||
<Normal>[Cc][Oo][Uu][Nn][Tt][Ii][Nn][Oo][Uu][Tt] FRETURN(flCountInOut);
|
||||
<Normal>[Pp][Oo][Ll][Yy][Mm][Oo][Rr][Pp][Hh][Ii][Cc] TPRETURN(MACH_MSG_TYPE_POLYMORPHIC, MACH_MSG_TYPE_POLYMORPHIC, PortSize);
|
||||
<Normal>[Aa][Uu][Tt][Oo] FRETURN(flAuto);
|
||||
<Normal>[Cc][Oo][Nn][Ss][Tt] FRETURN(flConst);
|
||||
<Normal>"PointerTo" RETURN(syPointerTo);
|
||||
<Normal>"PointerToIfNot" RETURN(syPointerToIfNot);
|
||||
<Normal>"ValueOf" RETURN(syValueOf);
|
||||
<Normal>"UserTypeLimit" RETURN(syUserTypeLimit);
|
||||
<Normal>"OnStackLimit" RETURN(syOnStackLimit);
|
||||
|
||||
|
||||
<Normal>"MACH_MSG_TYPE_UNSTRUCTURED" TRETURN(MACH_MSG_TYPE_UNSTRUCTURED,0);
|
||||
<Normal>"MACH_MSG_TYPE_BIT" TRETURN(MACH_MSG_TYPE_BIT,1);
|
||||
<Normal>"MACH_MSG_TYPE_BOOLEAN" TRETURN(MACH_MSG_TYPE_BOOLEAN,32);
|
||||
<Normal>"MACH_MSG_TYPE_INTEGER_8" TRETURN(MACH_MSG_TYPE_INTEGER_8,8);
|
||||
<Normal>"MACH_MSG_TYPE_INTEGER_16" TRETURN(MACH_MSG_TYPE_INTEGER_16,16);
|
||||
<Normal>"MACH_MSG_TYPE_INTEGER_32" TRETURN(MACH_MSG_TYPE_INTEGER_32,32);
|
||||
<Normal>"MACH_MSG_TYPE_INTEGER_64" TRETURN(MACH_MSG_TYPE_INTEGER_64,64);
|
||||
<Normal>"MACH_MSG_TYPE_REAL_32" TRETURN(MACH_MSG_TYPE_REAL_32,32);
|
||||
<Normal>"MACH_MSG_TYPE_REAL_64" TRETURN(MACH_MSG_TYPE_REAL_64,64);
|
||||
<Normal>"MACH_MSG_TYPE_CHAR" TRETURN(MACH_MSG_TYPE_CHAR,8);
|
||||
<Normal>"MACH_MSG_TYPE_BYTE" TRETURN(MACH_MSG_TYPE_BYTE,8);
|
||||
|
||||
<Normal>"MACH_MSG_TYPE_MOVE_RECEIVE" TPRETURN(MACH_MSG_TYPE_MOVE_RECEIVE,MACH_MSG_TYPE_PORT_RECEIVE,PortSize);
|
||||
<Normal>"MACH_MSG_TYPE_COPY_SEND" TPRETURN(MACH_MSG_TYPE_COPY_SEND,MACH_MSG_TYPE_PORT_SEND,PortSize);
|
||||
<Normal>"MACH_MSG_TYPE_MAKE_SEND" TPRETURN(MACH_MSG_TYPE_MAKE_SEND,MACH_MSG_TYPE_PORT_SEND,PortSize);
|
||||
<Normal>"MACH_MSG_TYPE_MOVE_SEND" TPRETURN(MACH_MSG_TYPE_MOVE_SEND,MACH_MSG_TYPE_PORT_SEND,PortSize);
|
||||
<Normal>"MACH_MSG_TYPE_MAKE_SEND_ONCE" TPRETURN(MACH_MSG_TYPE_MAKE_SEND_ONCE,MACH_MSG_TYPE_PORT_SEND_ONCE,PortSize);
|
||||
<Normal>"MACH_MSG_TYPE_MOVE_SEND_ONCE" TPRETURN(MACH_MSG_TYPE_MOVE_SEND_ONCE,MACH_MSG_TYPE_PORT_SEND_ONCE,PortSize);
|
||||
|
||||
<Normal>"MACH_MSG_TYPE_PORT_NAME" TRETURN(MACH_MSG_TYPE_PORT_NAME,PortSize);
|
||||
<Normal>"MACH_MSG_TYPE_PORT_RECEIVE" TPRETURN(MACH_MSG_TYPE_POLYMORPHIC,MACH_MSG_TYPE_PORT_RECEIVE,PortSize);
|
||||
<Normal>"MACH_MSG_TYPE_PORT_SEND" TPRETURN(MACH_MSG_TYPE_POLYMORPHIC,MACH_MSG_TYPE_PORT_SEND,PortSize);
|
||||
<Normal>"MACH_MSG_TYPE_PORT_SEND_ONCE" TPRETURN(MACH_MSG_TYPE_POLYMORPHIC,MACH_MSG_TYPE_PORT_SEND_ONCE,PortSize);
|
||||
<Normal>"MACH_MSG_TYPE_POLYMORPHIC" TPRETURN(MACH_MSG_TYPE_POLYMORPHIC, MACH_MSG_TYPE_POLYMORPHIC, PortSize);
|
||||
|
||||
<Normal>":" RETURN(syColon);
|
||||
<Normal>";" RETURN(sySemi);
|
||||
<Normal>"," RETURN(syComma);
|
||||
<Normal>"+" RETURN(syPlus);
|
||||
<Normal>"-" RETURN(syMinus);
|
||||
<Normal>"*" RETURN(syStar);
|
||||
<Normal>"/" RETURN(syDiv);
|
||||
<Normal>"(" RETURN(syLParen);
|
||||
<Normal>")" RETURN(syRParen);
|
||||
<Normal>"=" RETURN(syEqual);
|
||||
<Normal>"^" RETURN(syCaret);
|
||||
<Normal>"~" RETURN(syTilde);
|
||||
<Normal>"<" RETURN(syLAngle);
|
||||
<Normal>">" RETURN(syRAngle);
|
||||
<Normal>"[" RETURN(syLBrack);
|
||||
<Normal>"]" RETURN(syRBrack);
|
||||
<Normal>"|" RETURN(syBar);
|
||||
|
||||
<Normal>{Ident} { yylval.identifier = strmake(yytext);
|
||||
RETURN(syIdentifier); }
|
||||
<Normal>{Number} { yylval.number = atoi(yytext); RETURN(syNumber); }
|
||||
|
||||
<String>{String} { yylval.string = strmake(yytext);
|
||||
SAVE(Normal); RETURN(syString); }
|
||||
<FileName>{FileName} { yylval.string = strmake(yytext);
|
||||
SAVE(Normal); RETURN(syFileName); }
|
||||
<QString>{QString} { yylval.string = strmake(yytext);
|
||||
SAVE(Normal); RETURN(syQString); }
|
||||
|
||||
^\#[ \t]*{Number}[ \t]*\"[^"]*\" { doSharp(yytext+1);
|
||||
BEGIN SkipToEOL; }
|
||||
^\#\ *{Number} { doSharp(yytext+1);
|
||||
BEGIN SkipToEOL; }
|
||||
^\#pragma { BEGIN SkipToEOL; }
|
||||
^\# { yyerror("illegal # directive");
|
||||
BEGIN SkipToEOL; }
|
||||
|
||||
<SkipToEOL>\n { RESTORE; lineno++; }
|
||||
<SkipToEOL>. ;
|
||||
|
||||
[ \t] ;
|
||||
\n lineno++;
|
||||
. { SAVE(Normal); RETURN(syError); }
|
||||
|
||||
%%
|
||||
|
||||
extern void
|
||||
LookNormal()
|
||||
{
|
||||
SAVE(Normal);
|
||||
}
|
||||
|
||||
extern void
|
||||
LookString()
|
||||
{
|
||||
SAVE(String);
|
||||
}
|
||||
|
||||
extern void
|
||||
LookQString()
|
||||
{
|
||||
SAVE(QString);
|
||||
}
|
||||
|
||||
extern void
|
||||
LookFileName()
|
||||
{
|
||||
SAVE(FileName);
|
||||
}
|
||||
|
||||
static void
|
||||
doSharp(char *body)
|
||||
{
|
||||
char *startName, *endName;
|
||||
|
||||
lineno = atoi(body);
|
||||
startName = strchr(body, '"');
|
||||
if (startName != NULL) {
|
||||
endName = strrchr(body, '"');
|
||||
*endName = '\0';
|
||||
strfree(yyinname);
|
||||
yyinname = strmake(startName+1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
88
tools/mig/mig.1
Normal file
88
tools/mig/mig.1
Normal file
@@ -0,0 +1,88 @@
|
||||
.TH MIG 1 "Nov 20, 2009" "Apple Computer, Inc."
|
||||
.SH NAME
|
||||
mig \- Mach Interface Generator
|
||||
.SH SYNOPSIS
|
||||
.B mig
|
||||
[
|
||||
.I "option \&..."
|
||||
]
|
||||
.I "file"
|
||||
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.I mig
|
||||
command invokes the Mach Interface Generator to generate Remote Procedure Call (RPC)
|
||||
code for client-server style Mach IPC from specification files.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-q/-Q
|
||||
Omit /
|
||||
.I emit
|
||||
warning messages.
|
||||
.TP
|
||||
.B \-v/-V
|
||||
Verbose mode ( on /
|
||||
.I off
|
||||
) will summarize types and routines as they are processed.
|
||||
.TP
|
||||
.B \-l/-L
|
||||
Controls (
|
||||
.I off
|
||||
/ on ) whether or not generated code logs RPC events to system logs.
|
||||
.TP
|
||||
.B \-k/-K
|
||||
Controls (
|
||||
.I on
|
||||
/ off ) whether generated code complies with ANSI C standards.
|
||||
.TP
|
||||
.B \-s/-S
|
||||
Controls ( on /
|
||||
.I off
|
||||
) whether generated server-side code includes a generated symbol table.
|
||||
.TP
|
||||
.BI \-i " prefix"
|
||||
Specify User file prefix.
|
||||
.TP
|
||||
.BI \-user " path"
|
||||
Specify name of user-side RPC generated source file.
|
||||
.TP
|
||||
.BI \-server " path"
|
||||
Specify name of server-side RPC generated source file.
|
||||
.TP
|
||||
.BI \-header " path"
|
||||
Specify name of user-side generated header file.
|
||||
.TP
|
||||
.BI \-sheader " path"
|
||||
Specify name of server-side generated header file.
|
||||
.TP
|
||||
.BI \-iheader " path"
|
||||
Specify internal header file name.
|
||||
.TP
|
||||
.BI \-dheader " path"
|
||||
Specify defines generated header file.
|
||||
.TP
|
||||
.BI \-maxonstack " value"
|
||||
Specify maximum size of message on stack.
|
||||
.TP
|
||||
.B \-split
|
||||
Use split headers.
|
||||
.TP
|
||||
.BI \-arch " arch"
|
||||
Specify machine architecture for target code.
|
||||
.TP
|
||||
.B \-MD
|
||||
Option is passed to the C compiler for dependency generation.
|
||||
.TP
|
||||
.B \-cpp
|
||||
This option is ignored.
|
||||
.TP
|
||||
.BI \-cc " path"
|
||||
Specify pathname to specific C compiler to use as the preprocessor.
|
||||
.TP
|
||||
.BI \-migcom " path"
|
||||
Specify pathname to specific migcom compiler to use for source code generation.
|
||||
.TP
|
||||
.BI \-isysroot " path"
|
||||
Specify SDK root directory.
|
||||
.TP
|
||||
Additional options provided are passed along to the C compiler unchanged.
|
||||
405
tools/mig/mig.c
Normal file
405
tools/mig/mig.c
Normal file
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Switches are;
|
||||
* -[v,Q] verbose or not quiet: prints out type
|
||||
* and routine information as mig runs.
|
||||
* -[V,q] not verbose or quiet : don't print
|
||||
* information during compilation
|
||||
* (this is the default)
|
||||
* -[r,R] do or don't use rpc calls instead of
|
||||
* send/receive pairs. Default is -r.
|
||||
* -[s,S] generate symbol table or not: generate a
|
||||
* table of rpc-name, number, routine triplets
|
||||
* as an external data structure -- main use is
|
||||
* for protection system's specification of rights
|
||||
* and for protection dispatch code. Default is -s.
|
||||
* -[l,L] -L generate code that insert code for logging
|
||||
* the most important events that happen at the
|
||||
* stub level (message conception, target routine
|
||||
* calls). Default is -l.
|
||||
* -[k,K] -K enforces MIG to generate K&R C language, with the
|
||||
* addition of ANSI C syntax under #ifdef __STDC__.
|
||||
* Default is -k.
|
||||
* -[n,N] -n enforces NDR checking and conversion logic generation.
|
||||
* Default is -N (no checking).
|
||||
* -i <prefix>
|
||||
* Put each user routine in its own file. The
|
||||
* file is named <prefix><routine-name>.c.
|
||||
* -user <name>
|
||||
* Name the user-side file <name>
|
||||
* -server <name>
|
||||
* Name the server-side file <name>
|
||||
* -header <name>
|
||||
* Name the user-side header file <name>
|
||||
* -iheader <name>
|
||||
* Name the user-side internal header file <name>
|
||||
* -sheader <name>
|
||||
* Name the server-side header file <name>
|
||||
* -dheader <name>
|
||||
* Name the defines (msgh_ids) header file <name>
|
||||
*
|
||||
* DESIGN:
|
||||
* Mig uses a lexxer module created by lex from lexxer.l and
|
||||
* a parser module created by yacc from parser.y to parse an
|
||||
* interface definitions module for a mach server.
|
||||
* The parser module calls routines in statement.c
|
||||
* and routines.c to build a list of statement structures.
|
||||
* The most interesting statements are the routine definitions
|
||||
* which contain information about the name, type, characteristics
|
||||
* of the routine, an argument list containing information for
|
||||
* each argument type, and a list of special arguments. The
|
||||
* argument type structures are build by routines in type.c
|
||||
* Once parsing is completed, the three code generation modules:
|
||||
* header.c user.c and server.c are called sequentially. These
|
||||
* do some code generation directly and also call the routines
|
||||
* in utils.c for common (parameterized) code generation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "error.h"
|
||||
#include "lexxer.h"
|
||||
#include "global.h"
|
||||
#include "write.h"
|
||||
|
||||
extern int yyparse(void);
|
||||
static FILE *myfopen(const char *name, const char *mode);
|
||||
|
||||
static void
|
||||
parseArgs(int argc,char *argv[])
|
||||
{
|
||||
if (argc == 2 && streql(argv[1], "-version")) {
|
||||
PrintVersion = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
while (--argc > 0)
|
||||
if ((++argv)[0][0] == '-') {
|
||||
switch (argv[0][1]) {
|
||||
|
||||
case 'q':
|
||||
BeQuiet = TRUE;
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
BeQuiet = FALSE;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
BeVerbose = TRUE;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
BeVerbose = FALSE;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
UseMsgRPC = TRUE;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
UseMsgRPC = FALSE;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
UseEventLogger = FALSE;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
UseEventLogger = TRUE;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
BeAnsiC = TRUE;
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
BeAnsiC = FALSE;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (streql(argv[0], "-novouchers")) {
|
||||
IsVoucherCodeAllowed = FALSE;
|
||||
} else {
|
||||
CheckNDR = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
CheckNDR = FALSE;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (streql(argv[0], "-server")) {
|
||||
--argc; ++argv;
|
||||
if (argc == 0)
|
||||
fatal("missing name for -server option");
|
||||
ServerFileName = strmake(argv[0]);
|
||||
}
|
||||
else if (streql(argv[0], "-sheader")) {
|
||||
--argc; ++argv;
|
||||
if (argc == 0)
|
||||
fatal ("missing name for -sheader option");
|
||||
ServerHeaderFileName = strmake(argv[0]);
|
||||
}
|
||||
else if (streql(argv[0], "-split"))
|
||||
UseSplitHeaders = TRUE;
|
||||
else
|
||||
GenSymTab = TRUE;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
GenSymTab = FALSE;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
warn("Mach RPC traps not fully supported");
|
||||
TestRPCTrap = TRUE;
|
||||
UseRPCTrap = TRUE;
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
UseRPCTrap = FALSE;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (streql(argv[0], "-iheader")) {
|
||||
--argc; ++argv;
|
||||
if (argc == 0)
|
||||
fatal("missing name for -iheader option");
|
||||
InternalHeaderFileName = strmake(argv[0]);
|
||||
}
|
||||
else {
|
||||
--argc; ++argv;
|
||||
if (argc == 0)
|
||||
fatal("missing prefix for -i option");
|
||||
UserFilePrefix = strmake(argv[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if (streql(argv[0], "-user")) {
|
||||
--argc; ++argv;
|
||||
if (argc == 0)
|
||||
fatal("missing name for -user option");
|
||||
UserFileName = strmake(argv[0]);
|
||||
}
|
||||
else
|
||||
fatal("unknown flag: '%s'", argv[0]);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
if (streql(argv[0], "-header")) {
|
||||
--argc; ++argv;
|
||||
if (argc == 0)
|
||||
fatal("missing name for -header option");
|
||||
UserHeaderFileName = strmake(argv[0]);
|
||||
}
|
||||
else
|
||||
fatal("unknown flag: '%s'", argv[0]);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (streql(argv[0], "-dheader")) {
|
||||
--argc; ++argv;
|
||||
if (argc == 0)
|
||||
fatal("missing name for -dheader option");
|
||||
DefinesHeaderFileName = strmake(argv[0]);
|
||||
}
|
||||
else
|
||||
fatal("unknown flag: '%s'", argv[0]);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (streql(argv[0], "-maxonstack")) {
|
||||
--argc; ++argv;
|
||||
if (argc == 0)
|
||||
fatal("missing size for -maxonstack option");
|
||||
MaxMessSizeOnStack = atoi(argv[0]);
|
||||
}
|
||||
else
|
||||
fatal("unknown flag: '%s'", argv[0]);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
ShortCircuit = FALSE;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
ShortCircuit = TRUE;
|
||||
/* fall thru - no longer supported */
|
||||
|
||||
default:
|
||||
fatal("unknown/unsupported flag: '%s'", argv[0]);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
else
|
||||
fatal("bad argument: '%s'", *argv);
|
||||
}
|
||||
|
||||
FILE *uheader, *server, *user;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
FILE *iheader = 0;
|
||||
FILE *sheader = 0;
|
||||
FILE *dheader = 0;
|
||||
time_t loc;
|
||||
extern string_t GenerationDate;
|
||||
|
||||
set_program_name("mig");
|
||||
parseArgs(argc, argv);
|
||||
if (PrintVersion) {
|
||||
printf("%s\n", MIG_VERSION);
|
||||
fflush(stdout);
|
||||
exit(0);
|
||||
}
|
||||
init_global();
|
||||
init_type();
|
||||
loc = time((time_t *)0);
|
||||
GenerationDate = ctime(&loc);
|
||||
|
||||
LookNormal();
|
||||
(void) yyparse();
|
||||
|
||||
if (mig_errors > 0)
|
||||
fatal("%d errors found. Abort.\n", mig_errors);
|
||||
|
||||
more_global();
|
||||
|
||||
uheader = myfopen(UserHeaderFileName, "w");
|
||||
if (!UserFilePrefix)
|
||||
user = myfopen(UserFileName, "w");
|
||||
server = myfopen(ServerFileName, "w");
|
||||
if (ServerHeaderFileName)
|
||||
sheader = myfopen(ServerHeaderFileName, "w");
|
||||
if (IsKernelServer) {
|
||||
iheader = myfopen(InternalHeaderFileName, "w");
|
||||
}
|
||||
if (DefinesHeaderFileName)
|
||||
dheader = myfopen(DefinesHeaderFileName, "w");
|
||||
if (BeVerbose) {
|
||||
printf("Writing %s ... ", UserHeaderFileName);
|
||||
fflush(stdout);
|
||||
}
|
||||
WriteUserHeader(uheader, stats);
|
||||
fclose(uheader);
|
||||
if (ServerHeaderFileName) {
|
||||
if (BeVerbose) {
|
||||
printf ("done.\nWriting %s ...", ServerHeaderFileName);
|
||||
fflush (stdout);
|
||||
}
|
||||
WriteServerHeader(sheader, stats);
|
||||
fclose(sheader);
|
||||
}
|
||||
if (IsKernelServer) {
|
||||
if (BeVerbose) {
|
||||
printf("done.\nWriting %s ... ", InternalHeaderFileName);
|
||||
fflush(stdout);
|
||||
}
|
||||
WriteInternalHeader(iheader, stats);
|
||||
fclose(iheader);
|
||||
}
|
||||
if (DefinesHeaderFileName) {
|
||||
if (BeVerbose) {
|
||||
printf ("done.\nWriting %s ...", DefinesHeaderFileName);
|
||||
fflush (stdout);
|
||||
}
|
||||
WriteDefinesHeader(dheader, stats);
|
||||
fclose(dheader);
|
||||
}
|
||||
if (UserFilePrefix) {
|
||||
if (BeVerbose) {
|
||||
printf("done.\nWriting individual user files ... ");
|
||||
fflush(stdout);
|
||||
}
|
||||
WriteUserIndividual(stats);
|
||||
}
|
||||
else {
|
||||
if (BeVerbose) {
|
||||
printf("done.\nWriting %s ... ", UserFileName);
|
||||
fflush(stdout);
|
||||
}
|
||||
WriteUser(user, stats);
|
||||
fclose(user);
|
||||
}
|
||||
if (BeVerbose) {
|
||||
printf("done.\nWriting %s ... ", ServerFileName);
|
||||
fflush(stdout);
|
||||
}
|
||||
WriteServer(server, stats);
|
||||
fclose(server);
|
||||
if (BeVerbose)
|
||||
printf("done.\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static FILE *
|
||||
myfopen(const char *name, const char *mode)
|
||||
{
|
||||
const char *realname;
|
||||
FILE *file;
|
||||
|
||||
if (name == strNULL)
|
||||
realname = "/dev/null";
|
||||
else
|
||||
realname = name;
|
||||
|
||||
file = fopen(realname, mode);
|
||||
if (file == NULL)
|
||||
fatal("fopen(%s): %s", realname, strerror(errno));
|
||||
|
||||
return file;
|
||||
}
|
||||
218
tools/mig/mig.sh
Normal file
218
tools/mig/mig.sh
Normal file
@@ -0,0 +1,218 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 1999-2008 Apple Inc. All rights reserved.
|
||||
#
|
||||
# @APPLE_LICENSE_HEADER_START@
|
||||
#
|
||||
# "Portions Copyright (c) 1999, 2008 Apple Inc. All Rights
|
||||
# Reserved. This file contains Original Code and/or Modifications of
|
||||
# Original Code as defined in and that are subject to the Apple Public
|
||||
# Source License Version 1.0 (the 'License'). You may not use this file
|
||||
# except in compliance with the License. Please obtain a copy of the
|
||||
# License at http://www.apple.com/publicsource and read it before using
|
||||
# this file.
|
||||
#
|
||||
# The Original Code and all software distributed under the License are
|
||||
# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
|
||||
# License for the specific language governing rights and limitations
|
||||
# under the License."
|
||||
#
|
||||
# @APPLE_LICENSE_HEADER_END@
|
||||
#
|
||||
# Mach Operating System
|
||||
# Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify and distribute this software and its
|
||||
# documentation is hereby granted, provided that both the copyright
|
||||
# notice and this permission notice appear in all copies of the
|
||||
# software, derivative works or modified versions, and any portions
|
||||
# thereof, and that both notices appear in supporting documentation.
|
||||
#
|
||||
# CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
# CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
#
|
||||
# Carnegie Mellon requests users of this software to return to
|
||||
#
|
||||
# Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
# School of Computer Science
|
||||
# Carnegie Mellon University
|
||||
# Pittsburgh PA 15213-3890
|
||||
#
|
||||
# any improvements or extensions that they make and grant Carnegie Mellon
|
||||
# the rights to redistribute these changes.
|
||||
#
|
||||
|
||||
realpath()
|
||||
{
|
||||
local FILE="$1"
|
||||
local PARENT=$(dirname "$FILE")
|
||||
local BASE=$(basename "$FILE")
|
||||
pushd "$PARENT" >/dev/null 2>&1 || return 0
|
||||
local DIR=$(pwd -P)
|
||||
popd >/dev/null
|
||||
if [ "$DIR" == "/" ]; then
|
||||
echo "/$BASE"
|
||||
else
|
||||
echo "$DIR/$BASE"
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
scriptPath=$(realpath "$0")
|
||||
scriptRoot=$(dirname "$scriptPath")
|
||||
migcomPath=$(realpath "${scriptRoot}/../libexec/migcom")
|
||||
|
||||
if [ -n "${SDKROOT}" ]; then
|
||||
sdkRoot="${SDKROOT}";
|
||||
fi
|
||||
|
||||
if [ -z "${MIGCC}" ]; then
|
||||
xcrunPath="/usr/bin/xcrun"
|
||||
if [ -x "${xcrunPath}" ]; then
|
||||
MIGCC=`"${xcrunPath}" -sdk "$sdkRoot" -find cc`
|
||||
else
|
||||
MIGCC=$(realpath "${scriptRoot}/cc")
|
||||
fi
|
||||
fi
|
||||
|
||||
C=${MIGCC}
|
||||
M=${MIGCOM-${migcomPath}}
|
||||
|
||||
if [ $# -eq 1 ] && [ "$1" = "-version" ] ; then
|
||||
"$M" "$@"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
cppflags="-D__MACH30__"
|
||||
|
||||
files=
|
||||
arch=`/usr/bin/arch`
|
||||
|
||||
WORKTMP=`/usr/bin/mktemp -d "${TMPDIR:-/tmp}/mig.XXXXXX"`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failure creating temporary work directory: ${WORKTMP}"
|
||||
echo "Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# parse out the arguments until we hit plain file name(s)
|
||||
|
||||
until [ $# -eq 0 ]
|
||||
do
|
||||
case "$1" in
|
||||
-[dtqkKQvVtTrRsSlLxXnN] ) migflags=( "${migflags[@]}" "$1" ); shift;;
|
||||
-i ) sawI=1; migflags=( "${migflags[@]}" "$1" "$2" ); shift; shift;;
|
||||
-user ) user="$2"; if [ ! "${sawI-}" ]; then migflags=( "${migflags[@]}" "$1" "$2" ); fi; shift; shift;;
|
||||
-server ) server="$2"; migflags=( "${migflags[@]}" "$1" "$2" ); shift; shift;;
|
||||
-header ) header="$2"; migflags=( "${migflags[@]}" "$1" "$2"); shift; shift;;
|
||||
-sheader ) sheader="$2"; migflags=( "${migflags[@]}" "$1" "$2"); shift; shift;;
|
||||
-iheader ) iheader="$2"; migflags=( "${migflags[@]}" "$1" "$2"); shift; shift;;
|
||||
-dheader ) dheader="$2"; migflags=( "${migflags[@]}" "$1" "$2"); shift; shift;;
|
||||
-arch ) arch="$2"; shift; shift;;
|
||||
-target ) target=( "$1" "$2"); shift; shift;;
|
||||
-maxonstack ) migflags=( "${migflags[@]}" "$1" "$2"); shift; shift;;
|
||||
-split ) migflags=( "${migflags[@]}" "$1" ); shift;;
|
||||
-novouchers ) migflags=( "${migflags[@]}" "$1" ); shift;;
|
||||
-MD ) sawMD=1; cppflags=( "${cppflags[@]}" "$1"); shift;;
|
||||
-cpp) shift; shift;;
|
||||
-cc) C="$2"; shift; shift;;
|
||||
-migcom) M="$2"; shift; shift;;
|
||||
-isysroot) sdkRoot=$(realpath "$2"); shift; shift;;
|
||||
-* ) cppflags=( "${cppflags[@]}" "$1"); shift;;
|
||||
* ) break;;
|
||||
esac
|
||||
done
|
||||
|
||||
# process the rest as files
|
||||
until [ $# -eq 0 ]
|
||||
do
|
||||
case "$1" in
|
||||
-[dtqkKQvVtTrRsSlLxXnN] ) echo "warning: option \"$1\" after filename(s) ignored"; shift; continue;;
|
||||
-i ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-user ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-server ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-header ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-sheader ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-iheader ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-dheader ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-arch ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift ; shift; continue;;
|
||||
-target ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift ; shift; continue;;
|
||||
-maxonstack ) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-split ) echo "warning: option \"$1\" after filename(s) ignored"; shift; continue;;
|
||||
-novouchers ) echo "warning: option \"$1\" after filename(s) ignored"; shift; continue;;
|
||||
-MD ) echo "warning: option \"$1\" after filename(s) ignored"; shift; continue;;
|
||||
-cpp) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-cc) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-migcom) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-isysroot) echo "warning: option \"$1 $2\" after filename(s) ignored"; shift; shift; continue;;
|
||||
-* ) echo "warning: option \"$1\" after filename(s) ignored"; shift; continue;;
|
||||
* ) file="$1"; shift;;
|
||||
esac
|
||||
base="$(basename "${file}" .defs)"
|
||||
temp="${WORKTMP}/${base}.$$"
|
||||
sourcedir="$(dirname "${file}")"
|
||||
if [ -n "${sdkRoot}" ]
|
||||
then
|
||||
iSysRootParm=( "-isysroot" "${sdkRoot}" )
|
||||
fi
|
||||
if [ ! -r "${file}" ]
|
||||
then
|
||||
echo "error: cannot read file ${file}"
|
||||
rm -rf ${WORKTMP}
|
||||
exit 1
|
||||
fi
|
||||
rm -f "${temp}.c" "${temp}.d"
|
||||
(echo '#line 1 '\"${file}\" ; cat "${file}" ) > "${temp}.c"
|
||||
"$C" -E -arch ${arch} "${target[@]}" "${cppflags[@]}" -I "${sourcedir}" "${iSysRootParm[@]}" "${temp}.c" | "$M" "${migflags[@]}"
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
rm -rf "${temp}.c" "${temp}.d" "${WORKTMP}"
|
||||
exit 1
|
||||
fi
|
||||
if [ "${sawMD}" -a -f "${temp}.d" ]
|
||||
then
|
||||
deps=
|
||||
s=
|
||||
rheader="${header-${base}.h}"
|
||||
if [ "${rheader}" != /dev/null ]; then
|
||||
deps="${deps}${s}${rheader}"; s=" "
|
||||
fi
|
||||
ruser="${user-${base}User.c}"
|
||||
if [ "${ruser}" != /dev/null ]; then
|
||||
deps="${deps}${s}${ruser}"; s=" "
|
||||
fi
|
||||
rserver="${server-${base}Server.c}"
|
||||
if [ "${rserver}" != /dev/null ]; then
|
||||
deps="${deps}${s}${rserver}"; s=" "
|
||||
fi
|
||||
rsheader="${sheader-/dev/null}"
|
||||
if [ "${rsheader}" != /dev/null ]; then
|
||||
deps="${deps}${s}${rsheader}"; s=" "
|
||||
fi
|
||||
riheader="${iheader-/dev/null}"
|
||||
if [ "${riheader}" != /dev/null ]; then
|
||||
deps="${deps}${s}${riheader}"; s=" "
|
||||
fi
|
||||
rdheader="${dheader-/dev/null}"
|
||||
if [ "${rdheader}" != /dev/null ]; then
|
||||
deps="${deps}${s}${rdheader}"; s=" "
|
||||
fi
|
||||
for target in "${deps}"
|
||||
do
|
||||
sed -e 's;^'"${temp}"'.o[ ]*:;'"${target}"':;' \
|
||||
-e 's;: '"${temp}"'.c;: '"$file"';' \
|
||||
< "${temp}.d" > "${target}.d"
|
||||
done
|
||||
rm -f "${temp}.d"
|
||||
fi
|
||||
rm -f "${temp}.c"
|
||||
done
|
||||
|
||||
/bin/rmdir "${WORKTMP}"
|
||||
exit 0
|
||||
|
||||
84
tools/mig/mig_errors.h
Normal file
84
tools/mig/mig_errors.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1987 Carnegie-Mellon University
|
||||
* All rights reserved. The CMU software License Agreement specifies
|
||||
* the terms and conditions for use and redistribution.
|
||||
*/
|
||||
/*
|
||||
* Mach Interface Generator errors
|
||||
*
|
||||
* $Header: /Users/Shared/bootstrap_cmds/bootstrap_cmds/migcom.tproj/mig_errors.h,v 1.1.1.2 2000/01/11 00:36:18 wsanchez Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Extensive revamping. Added polymorphic arguments.
|
||||
* Allow multiple variable-sized inline arguments in messages.
|
||||
*
|
||||
* 28-Apr-88 Bennet Yee (bsy) at Carnegie-Mellon University
|
||||
* Put mig_symtab back.
|
||||
*
|
||||
* 2-Dec-87 David Golub (dbg) at Carnegie-Mellon University
|
||||
* Added MIG_ARRAY_TOO_LARGE.
|
||||
*
|
||||
* 25-May-87 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Added definition of death_pill_t.
|
||||
*
|
||||
* 31-Jul-86 Michael Young (mwyoung) at Carnegie-Mellon University
|
||||
* Created.
|
||||
*/
|
||||
#ifndef _MIG_ERRORS_H
|
||||
#define _MIG_ERRORS_H
|
||||
|
||||
#include <mach/kern_return.h>
|
||||
#include <mach/message.h>
|
||||
|
||||
#define MIG_TYPE_ERROR -300 /* Type check failure */
|
||||
#define MIG_REPLY_MISMATCH -301 /* Wrong return message ID */
|
||||
#define MIG_REMOTE_ERROR -302 /* Server detected error */
|
||||
#define MIG_BAD_ID -303 /* Bad message ID */
|
||||
#define MIG_BAD_ARGUMENTS -304 /* Server found wrong arguments */
|
||||
#define MIG_NO_REPLY -305 /* Server shouldn't reply */
|
||||
#define MIG_EXCEPTION -306 /* Server raised exception */
|
||||
#define MIG_ARRAY_TOO_LARGE -307 /* User specified array not large enough
|
||||
to hold returned array */
|
||||
|
||||
typedef struct {
|
||||
msg_header_t Head;
|
||||
msg_type_t RetCodeType;
|
||||
kern_return_t RetCode;
|
||||
} death_pill_t;
|
||||
|
||||
typedef struct mig_symtab {
|
||||
char *ms_routine_name;
|
||||
int ms_routine_number;
|
||||
#ifdef hc
|
||||
void
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
(*ms_routine)();
|
||||
} mig_symtab_t;
|
||||
|
||||
#endif _MIG_ERRORS_H
|
||||
16
tools/mig/mig_machine.h
Normal file
16
tools/mig/mig_machine.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#if !defined(_MIG_MACHINE_H)
|
||||
#define _MIG_MACHINE_H
|
||||
|
||||
#define machine_alignment(SZ,ESZ) \
|
||||
(((SZ) = ((SZ) + 3) & ~3), (SZ) += (ESZ))
|
||||
|
||||
#define machine_padding(BYTES) \
|
||||
((BYTES & 3) ? (4 - (BYTES & 3)) : 0)
|
||||
|
||||
#ifndef NBBY
|
||||
#define NBBY 8
|
||||
#endif
|
||||
|
||||
#define PACK_MESSAGES TRUE
|
||||
|
||||
#endif
|
||||
73
tools/mig/migcom.1
Normal file
73
tools/mig/migcom.1
Normal file
@@ -0,0 +1,73 @@
|
||||
.TH MIGCOM 1 "Nov 20, 2009" "Apple Computer, Inc."
|
||||
.SH NAME
|
||||
migcom \- Mach Interface Generator COMpiler
|
||||
.SH SYNOPSIS
|
||||
.B migcom
|
||||
[
|
||||
.I "option \&..."
|
||||
]
|
||||
.I "<file"
|
||||
|
||||
.SH DESCRIPTION
|
||||
.I migcom
|
||||
is the actual compiler used by the
|
||||
.I mig
|
||||
command to generate Remote Procedure Call (RPC) source code for
|
||||
client-server style Mach IPC from specification files. It is not normally
|
||||
used independently. Rather, it is invoked by the
|
||||
.I mig
|
||||
command after pre-processing the provided specifications file with the C
|
||||
preprocessor. It is only documented here for the sake of completeness.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-q/-Q
|
||||
Omit /
|
||||
.I emit
|
||||
warning messages.
|
||||
.TP
|
||||
.B \-v/-V
|
||||
Verbose mode ( on /
|
||||
.I off
|
||||
) will summarize types and routines as they are processed.
|
||||
.TP
|
||||
.B \-l/-L
|
||||
Controls (
|
||||
.I off
|
||||
/ on ) whether or not generated code logs RPC events to system logs.
|
||||
.TP
|
||||
.B \-k/-K
|
||||
Controls (
|
||||
.I on
|
||||
/ off ) whether generated code complies with ANSI C standards.
|
||||
.TP
|
||||
.B \-s/-S
|
||||
Controls ( on /
|
||||
.I off
|
||||
) whether generated server-side code includes a generated symbol table.
|
||||
.TP
|
||||
.BI \-i " prefix"
|
||||
Specify User file prefix.
|
||||
.TP
|
||||
.BI \-user " path"
|
||||
Specify name of user-side RPC generated source file.
|
||||
.TP
|
||||
.BI \-server " path"
|
||||
Specify name of server-side RPC generated source file.
|
||||
.TP
|
||||
.BI \-header " path"
|
||||
Specify name of user-side generated header file.
|
||||
.TP
|
||||
.BI \-sheader " path"
|
||||
Specify name of server-side generated header file.
|
||||
.TP
|
||||
.BI \-iheader " path"
|
||||
Specify internal header file name.
|
||||
.TP
|
||||
.BI \-dheader " path"
|
||||
Specify defines generated header file.
|
||||
.TP
|
||||
.BI \-maxonstack " value"
|
||||
Specify maximum size of message on stack.
|
||||
.TP
|
||||
.B \-split
|
||||
Use split headers.
|
||||
803
tools/mig/parser.y
Normal file
803
tools/mig/parser.y
Normal file
@@ -0,0 +1,803 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
%token sySkip
|
||||
%token syRoutine
|
||||
%token sySimpleRoutine
|
||||
|
||||
%token sySubsystem
|
||||
%token syKernelUser
|
||||
%token syKernelServer
|
||||
|
||||
%token syMsgOption
|
||||
%token syUseSpecialReplyPort
|
||||
%token syConsumeOnSendError
|
||||
%token syMsgSeqno
|
||||
%token syWaitTime
|
||||
%token sySendTime
|
||||
%token syNoWaitTime
|
||||
%token syNoSendTime
|
||||
%token syErrorProc
|
||||
%token syServerPrefix
|
||||
%token syUserPrefix
|
||||
%token syServerDemux
|
||||
%token syRCSId
|
||||
|
||||
%token syImport
|
||||
%token syUImport
|
||||
%token sySImport
|
||||
%token syIImport
|
||||
%token syDImport
|
||||
|
||||
%token syIn
|
||||
%token syOut
|
||||
%token syInOut
|
||||
%token syUserImpl
|
||||
%token syServerImpl
|
||||
%token syRequestPort
|
||||
%token syReplyPort
|
||||
%token sySReplyPort
|
||||
%token syUReplyPort
|
||||
|
||||
%token syType
|
||||
%token syArray
|
||||
%token syStruct
|
||||
%token syOf
|
||||
|
||||
%token syInTran
|
||||
%token syOutTran
|
||||
%token syDestructor
|
||||
%token syCType
|
||||
%token syCUserType
|
||||
%token syUserTypeLimit
|
||||
%token syOnStackLimit
|
||||
%token syCServerType
|
||||
%token syPointerTo
|
||||
%token syPointerToIfNot
|
||||
%token syValueOf
|
||||
|
||||
%token syCString
|
||||
%token sySecToken
|
||||
%token syUserSecToken
|
||||
%token syServerSecToken
|
||||
%token syAuditToken
|
||||
%token syUserAuditToken
|
||||
%token syServerAuditToken
|
||||
%token syServerContextToken
|
||||
|
||||
%token syColon
|
||||
%token sySemi
|
||||
%token syComma
|
||||
%token syPlus
|
||||
%token syMinus
|
||||
%token syStar
|
||||
%token syDiv
|
||||
%token syLParen
|
||||
%token syRParen
|
||||
%token syEqual
|
||||
%token syCaret
|
||||
%token syTilde
|
||||
%token syLAngle
|
||||
%token syRAngle
|
||||
%token syLBrack
|
||||
%token syRBrack
|
||||
%token syBar
|
||||
|
||||
%token syError /* lex error */
|
||||
|
||||
%token <number> syNumber
|
||||
%token <symtype> sySymbolicType
|
||||
%token <identifier> syIdentifier
|
||||
%token <string> syString syQString
|
||||
%token <string> syFileName
|
||||
%token <flag> syIPCFlag
|
||||
|
||||
%left syPlus syMinus
|
||||
%left syStar syDiv
|
||||
|
||||
|
||||
%type <statement_kind> ImportIndicant
|
||||
%type <number> VarArrayHead ArrayHead StructHead IntExp
|
||||
%type <type> NamedTypeSpec TransTypeSpec NativeTypeSpec TypeSpec
|
||||
%type <type> CStringSpec
|
||||
%type <type> BasicTypeSpec PrevTypeSpec ArgumentType
|
||||
%type <identifier> TypePhrase
|
||||
%type <symtype> PrimIPCType IPCType
|
||||
%type <routine> RoutineDecl Routine SimpleRoutine
|
||||
%type <direction> Direction TrImplKeyword
|
||||
%type <argument> Argument Trailer Arguments ArgumentList
|
||||
%type <flag> IPCFlags
|
||||
|
||||
%{
|
||||
|
||||
#include <stdio.h>
|
||||
#include "lexxer.h"
|
||||
#include "strdefs.h"
|
||||
#include "type.h"
|
||||
#include "routine.h"
|
||||
#include "statement.h"
|
||||
#include "global.h"
|
||||
#include "error.h"
|
||||
|
||||
static char *import_name(statement_kind_t sk);
|
||||
extern int yylex(void);
|
||||
|
||||
/* forward declaration */
|
||||
void yyerror(char *s);
|
||||
|
||||
%}
|
||||
|
||||
%union
|
||||
{
|
||||
u_int number;
|
||||
identifier_t identifier;
|
||||
string_t string;
|
||||
statement_kind_t statement_kind;
|
||||
ipc_type_t *type;
|
||||
struct
|
||||
{
|
||||
u_int innumber; /* msgt_name value, when sending */
|
||||
string_t instr;
|
||||
u_int outnumber; /* msgt_name value, when receiving */
|
||||
string_t outstr;
|
||||
u_int size; /* 0 means there is no default size */
|
||||
} symtype;
|
||||
routine_t *routine;
|
||||
arg_kind_t direction;
|
||||
argument_t *argument;
|
||||
ipc_flags_t flag;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
Statements : /* empty */
|
||||
| Statements Statement
|
||||
;
|
||||
|
||||
Statement : Subsystem sySemi
|
||||
| WaitTime sySemi
|
||||
| SendTime sySemi
|
||||
| MsgOption sySemi
|
||||
| UseSpecialReplyPort sySemi
|
||||
| ConsumeOnSendError sySemi
|
||||
| UserTypeLimit sySemi
|
||||
| OnStackLimit sySemi
|
||||
| Error sySemi
|
||||
| ServerPrefix sySemi
|
||||
| UserPrefix sySemi
|
||||
| ServerDemux sySemi
|
||||
| TypeDecl sySemi
|
||||
| RoutineDecl sySemi
|
||||
{
|
||||
statement_t *st = stAlloc();
|
||||
|
||||
st->stKind = skRoutine;
|
||||
st->stRoutine = $1;
|
||||
rtCheckRoutine($1);
|
||||
if (BeVerbose)
|
||||
rtPrintRoutine($1);
|
||||
}
|
||||
| sySkip sySemi
|
||||
{ rtSkip(); }
|
||||
| Import sySemi
|
||||
| RCSDecl sySemi
|
||||
| sySemi
|
||||
| error sySemi
|
||||
{ yyerrok; }
|
||||
;
|
||||
|
||||
Subsystem : SubsystemStart SubsystemMods
|
||||
SubsystemName SubsystemBase
|
||||
{
|
||||
if (BeVerbose) {
|
||||
printf("Subsystem %s: base = %u%s%s\n\n",
|
||||
SubsystemName, SubsystemBase,
|
||||
IsKernelUser ? ", KernelUser" : "",
|
||||
IsKernelServer ? ", KernelServer" : "");
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
SubsystemStart : sySubsystem
|
||||
{
|
||||
if (SubsystemName != strNULL) {
|
||||
warn("previous Subsystem decl (of %s) will be ignored", SubsystemName);
|
||||
IsKernelUser = FALSE;
|
||||
IsKernelServer = FALSE;
|
||||
strfree(SubsystemName);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
SubsystemMods : /* empty */
|
||||
| SubsystemMods SubsystemMod
|
||||
;
|
||||
|
||||
SubsystemMod : syKernelUser
|
||||
{
|
||||
if (IsKernelUser)
|
||||
warn("duplicate KernelUser keyword");
|
||||
if (!UseMsgRPC) {
|
||||
warn("with KernelUser the -R option is meaningless");
|
||||
UseMsgRPC = TRUE;
|
||||
}
|
||||
IsKernelUser = TRUE;
|
||||
}
|
||||
| syKernelServer
|
||||
{
|
||||
if (IsKernelServer)
|
||||
warn("duplicate KernelServer keyword");
|
||||
IsKernelServer = TRUE;
|
||||
}
|
||||
;
|
||||
|
||||
SubsystemName : syIdentifier { SubsystemName = $1; }
|
||||
;
|
||||
|
||||
SubsystemBase : syNumber { SubsystemBase = $1; }
|
||||
;
|
||||
|
||||
MsgOption : LookString syMsgOption syString
|
||||
{
|
||||
if (streql($3, "MACH_MSG_OPTION_NONE")) {
|
||||
MsgOption = strNULL;
|
||||
if (BeVerbose)
|
||||
printf("MsgOption: canceled\n\n");
|
||||
}
|
||||
else {
|
||||
MsgOption = $3;
|
||||
if (BeVerbose)
|
||||
printf("MsgOption %s\n\n",$3);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
UseSpecialReplyPort : syUseSpecialReplyPort syNumber
|
||||
{
|
||||
UseSpecialReplyPort = ($2 != 0);
|
||||
HasUseSpecialReplyPort |= UseSpecialReplyPort;
|
||||
}
|
||||
;
|
||||
|
||||
ConsumeOnSendError : LookString syConsumeOnSendError syString
|
||||
{
|
||||
if (strcasecmp($3, "None") == 0) {
|
||||
ConsumeOnSendError = ConsumeOnSendErrorNone;
|
||||
} else if (strcasecmp($3, "Timeout") == 0) {
|
||||
ConsumeOnSendError = ConsumeOnSendErrorTimeout;
|
||||
HasConsumeOnSendError = TRUE;
|
||||
} else if (strcasecmp($3, "Any") == 0) {
|
||||
ConsumeOnSendError = ConsumeOnSendErrorAny;
|
||||
HasConsumeOnSendError = TRUE;
|
||||
} else {
|
||||
error("syntax error");
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
UserTypeLimit : syUserTypeLimit syNumber
|
||||
{UserTypeLimit = $2; }
|
||||
;
|
||||
OnStackLimit : syOnStackLimit syNumber
|
||||
{MaxMessSizeOnStack = $2; }
|
||||
;
|
||||
|
||||
WaitTime : LookString syWaitTime syString
|
||||
{
|
||||
WaitTime = $3;
|
||||
if (BeVerbose)
|
||||
printf("WaitTime %s\n\n", WaitTime);
|
||||
}
|
||||
| syNoWaitTime
|
||||
{
|
||||
WaitTime = strNULL;
|
||||
if (BeVerbose)
|
||||
printf("NoWaitTime\n\n");
|
||||
}
|
||||
;
|
||||
|
||||
SendTime : LookString sySendTime syString
|
||||
{
|
||||
SendTime = $3;
|
||||
if (BeVerbose)
|
||||
printf("SendTime %s\n\n", SendTime);
|
||||
}
|
||||
| syNoSendTime
|
||||
{
|
||||
SendTime = strNULL;
|
||||
if (BeVerbose)
|
||||
printf("NoSendTime\n\n");
|
||||
}
|
||||
;
|
||||
|
||||
Error : syErrorProc syIdentifier
|
||||
{
|
||||
ErrorProc = $2;
|
||||
if (BeVerbose)
|
||||
printf("ErrorProc %s\n\n", ErrorProc);
|
||||
}
|
||||
;
|
||||
|
||||
ServerPrefix : syServerPrefix syIdentifier
|
||||
{
|
||||
ServerPrefix = $2;
|
||||
if (BeVerbose)
|
||||
printf("ServerPrefix %s\n\n", ServerPrefix);
|
||||
}
|
||||
;
|
||||
|
||||
UserPrefix : syUserPrefix syIdentifier
|
||||
{
|
||||
UserPrefix = $2;
|
||||
if (BeVerbose)
|
||||
printf("UserPrefix %s\n\n", UserPrefix);
|
||||
}
|
||||
;
|
||||
|
||||
ServerDemux : syServerDemux syIdentifier
|
||||
{
|
||||
ServerDemux = $2;
|
||||
if (BeVerbose)
|
||||
printf("ServerDemux %s\n\n", ServerDemux);
|
||||
}
|
||||
;
|
||||
|
||||
Import : LookFileName ImportIndicant syFileName
|
||||
{
|
||||
statement_t *st = stAlloc();
|
||||
st->stKind = $2;
|
||||
st->stFileName = $3;
|
||||
|
||||
if (BeVerbose)
|
||||
printf("%s %s\n\n", import_name($2), $3);
|
||||
}
|
||||
;
|
||||
|
||||
ImportIndicant : syImport { $$ = skImport; }
|
||||
| syUImport { $$ = skUImport; }
|
||||
| sySImport { $$ = skSImport; }
|
||||
| syIImport { $$ = skIImport; }
|
||||
| syDImport { $$ = skDImport; }
|
||||
;
|
||||
|
||||
RCSDecl : LookQString syRCSId syQString
|
||||
{
|
||||
if (RCSId != strNULL)
|
||||
warn("previous RCS decl will be ignored");
|
||||
if (BeVerbose)
|
||||
printf("RCSId %s\n\n", $3);
|
||||
RCSId = $3;
|
||||
}
|
||||
;
|
||||
|
||||
TypeDecl : syType NamedTypeSpec
|
||||
{
|
||||
identifier_t name = $2->itName;
|
||||
|
||||
if (itLookUp(name) != itNULL)
|
||||
warn("overriding previous definition of %s", name);
|
||||
itInsert(name, $2);
|
||||
}
|
||||
;
|
||||
|
||||
NamedTypeSpec : syIdentifier syEqual TransTypeSpec
|
||||
{ itTypeDecl($1, $$ = $3); }
|
||||
;
|
||||
|
||||
TransTypeSpec : TypeSpec
|
||||
{ $$ = itResetType($1); }
|
||||
| TransTypeSpec syInTran syColon syIdentifier
|
||||
syIdentifier syLParen syIdentifier syRParen
|
||||
{
|
||||
$$ = $1;
|
||||
|
||||
if (($$->itTransType != strNULL) && !streql($$->itTransType, $4))
|
||||
warn("conflicting translation types (%s, %s)", $$->itTransType, $4);
|
||||
$$->itTransType = $4;
|
||||
|
||||
if (($$->itInTrans != strNULL) && !streql($$->itInTrans, $5))
|
||||
warn("conflicting in-translation functions (%s, %s)", $$->itInTrans, $5);
|
||||
$$->itInTrans = $5;
|
||||
|
||||
if (($$->itServerType != strNULL) && !streql($$->itServerType, $7))
|
||||
warn("conflicting server types (%s, %s)", $$->itServerType, $7);
|
||||
$$->itServerType = $7;
|
||||
}
|
||||
| TransTypeSpec syOutTran syColon syIdentifier
|
||||
syIdentifier syLParen syIdentifier syRParen
|
||||
{
|
||||
$$ = $1;
|
||||
|
||||
if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
|
||||
warn("conflicting server types (%s, %s)", $$->itServerType, $4);
|
||||
$$->itServerType = $4;
|
||||
|
||||
if (($$->itOutTrans != strNULL) && !streql($$->itOutTrans, $5))
|
||||
warn("conflicting out-translation functions (%s, %s)", $$->itOutTrans, $5);
|
||||
$$->itOutTrans = $5;
|
||||
|
||||
if (($$->itTransType != strNULL) && !streql($$->itTransType, $7))
|
||||
warn("conflicting translation types (%s, %s)", $$->itTransType, $7);
|
||||
$$->itTransType = $7;
|
||||
}
|
||||
| TransTypeSpec syDestructor syColon syIdentifier
|
||||
syLParen syIdentifier syRParen
|
||||
{
|
||||
$$ = $1;
|
||||
|
||||
if (($$->itDestructor != strNULL) && !streql($$->itDestructor, $4))
|
||||
warn("conflicting destructor functions (%s, %s)", $$->itDestructor, $4);
|
||||
$$->itDestructor = $4;
|
||||
|
||||
if (($$->itTransType != strNULL) && !streql($$->itTransType, $6))
|
||||
warn("conflicting translation types (%s, %s)", $$->itTransType, $6);
|
||||
$$->itTransType = $6;
|
||||
}
|
||||
| TransTypeSpec syCType syColon syIdentifier
|
||||
{
|
||||
$$ = $1;
|
||||
|
||||
if (($$->itUserType != strNULL) && !streql($$->itUserType, $4))
|
||||
warn("conflicting user types (%s, %s)", $$->itUserType, $4);
|
||||
$$->itUserType = $4;
|
||||
|
||||
if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
|
||||
warn("conflicting server types (%s, %s)", $$->itServerType, $4);
|
||||
$$->itServerType = $4;
|
||||
}
|
||||
| TransTypeSpec syCUserType syColon syIdentifier
|
||||
{
|
||||
$$ = $1;
|
||||
|
||||
if (($$->itUserType != strNULL) && !streql($$->itUserType, $4))
|
||||
warn("conflicting user types (%s, %s)", $$->itUserType, $4);
|
||||
$$->itUserType = $4;
|
||||
}
|
||||
| TransTypeSpec syCServerType
|
||||
syColon syIdentifier
|
||||
{
|
||||
$$ = $1;
|
||||
|
||||
if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
|
||||
warn("conflicting server types (%s, %s)",
|
||||
$$->itServerType, $4);
|
||||
$$->itServerType = $4;
|
||||
}
|
||||
;
|
||||
|
||||
TypeSpec : BasicTypeSpec
|
||||
{ $$ = $1; }
|
||||
| PrevTypeSpec
|
||||
{ $$ = $1; }
|
||||
| VarArrayHead TypeSpec
|
||||
{ $$ = itVarArrayDecl($1, $2); }
|
||||
| ArrayHead TypeSpec
|
||||
{ $$ = itArrayDecl($1, $2); }
|
||||
| syCaret TypeSpec
|
||||
{ $$ = itPtrDecl($2); }
|
||||
| StructHead TypeSpec
|
||||
{ $$ = itStructDecl($1, $2); }
|
||||
| CStringSpec
|
||||
{ $$ = $1; }
|
||||
| NativeTypeSpec
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
NativeTypeSpec : syPointerTo syLParen TypePhrase syRParen
|
||||
{ $$ = itNativeType($3, TRUE, 0); }
|
||||
| syPointerToIfNot syLParen TypePhrase syComma
|
||||
TypePhrase syRParen
|
||||
{ $$ = itNativeType($3, TRUE, $5); }
|
||||
| syValueOf syLParen TypePhrase syRParen
|
||||
{ $$ = itNativeType($3, FALSE, 0); }
|
||||
;
|
||||
|
||||
BasicTypeSpec : IPCType
|
||||
{
|
||||
$$ = itShortDecl($1.innumber, $1.instr,
|
||||
$1.outnumber, $1.outstr,
|
||||
$1.size);
|
||||
}
|
||||
| syLParen IPCType syComma IntExp
|
||||
IPCFlags syRParen
|
||||
{
|
||||
error("Long form type declarations aren't allowed any longer\n");
|
||||
}
|
||||
;
|
||||
|
||||
PrimIPCType : syNumber
|
||||
{
|
||||
$$.innumber = $$.outnumber = $1;
|
||||
$$.instr = $$.outstr = strNULL;
|
||||
$$.size = 0;
|
||||
}
|
||||
| sySymbolicType
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
IPCType : PrimIPCType
|
||||
{ $$ = $1; }
|
||||
| PrimIPCType syBar PrimIPCType
|
||||
{
|
||||
if ($1.size != $3.size) {
|
||||
if ($1.size == 0)
|
||||
$$.size = $3.size;
|
||||
else if ($3.size == 0)
|
||||
$$.size = $1.size;
|
||||
else {
|
||||
error("sizes in IPCTypes (%d, %d) aren't equal",
|
||||
$1.size, $3.size);
|
||||
$$.size = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
$$.size = $1.size;
|
||||
$$.innumber = $1.innumber;
|
||||
$$.instr = $1.instr;
|
||||
$$.outnumber = $3.outnumber;
|
||||
$$.outstr = $3.outstr;
|
||||
}
|
||||
;
|
||||
|
||||
PrevTypeSpec : syIdentifier
|
||||
{ $$ = itPrevDecl($1); }
|
||||
;
|
||||
|
||||
VarArrayHead : syArray syLBrack syRBrack syOf
|
||||
{ $$ = 0; }
|
||||
| syArray syLBrack syStar syRBrack syOf
|
||||
{ $$ = 0; }
|
||||
| syArray syLBrack syStar syColon IntExp
|
||||
syRBrack syOf
|
||||
{ $$ = $5; }
|
||||
;
|
||||
|
||||
ArrayHead : syArray syLBrack IntExp syRBrack syOf
|
||||
{ $$ = $3; }
|
||||
;
|
||||
|
||||
StructHead : syStruct syLBrack IntExp syRBrack syOf
|
||||
{ $$ = $3; }
|
||||
;
|
||||
|
||||
CStringSpec : syCString syLBrack IntExp syRBrack
|
||||
{ $$ = itCStringDecl($3, FALSE); }
|
||||
| syCString syLBrack syStar syColon
|
||||
IntExp syRBrack
|
||||
{ $$ = itCStringDecl($5, TRUE); }
|
||||
;
|
||||
|
||||
TypePhrase : syIdentifier
|
||||
{ $$ = $1; }
|
||||
| TypePhrase syIdentifier
|
||||
{ $$ = strphrase($1, $2); strfree($2); }
|
||||
;
|
||||
|
||||
IntExp : IntExp syPlus IntExp
|
||||
{ $$ = $1 + $3; }
|
||||
| IntExp syMinus IntExp
|
||||
{ $$ = $1 - $3; }
|
||||
| IntExp syStar IntExp
|
||||
{ $$ = $1 * $3; }
|
||||
| IntExp syDiv IntExp
|
||||
{ $$ = $1 / $3; }
|
||||
| syNumber
|
||||
{ $$ = $1; }
|
||||
| syLParen IntExp syRParen
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
|
||||
RoutineDecl : Routine { $$ = $1; }
|
||||
| SimpleRoutine { $$ = $1; }
|
||||
;
|
||||
|
||||
Routine : syRoutine syIdentifier Arguments
|
||||
{ $$ = rtMakeRoutine($2, $3); }
|
||||
;
|
||||
|
||||
SimpleRoutine : sySimpleRoutine syIdentifier Arguments
|
||||
{ $$ = rtMakeSimpleRoutine($2, $3); }
|
||||
;
|
||||
|
||||
Arguments : syLParen syRParen
|
||||
{ $$ = argNULL; }
|
||||
| syLParen ArgumentList syRParen
|
||||
{ $$ = $2; }
|
||||
|
||||
;
|
||||
|
||||
ArgumentList : Argument
|
||||
{ $$ = $1; }
|
||||
| Trailer
|
||||
{ $$ = $1; }
|
||||
| Argument sySemi ArgumentList
|
||||
{
|
||||
$$ = $1;
|
||||
$$->argNext = $3;
|
||||
}
|
||||
| Trailer sySemi ArgumentList
|
||||
{
|
||||
$$ = $1;
|
||||
$$->argNext = $3;
|
||||
}
|
||||
;
|
||||
|
||||
Argument : Direction syIdentifier ArgumentType IPCFlags
|
||||
{
|
||||
$$ = argAlloc();
|
||||
$$->argKind = $1;
|
||||
$$->argName = $2;
|
||||
$$->argType = $3;
|
||||
$$->argFlags = $4;
|
||||
if ($3 && $3->itNative) {
|
||||
if ($1 != akIn && $1 != akOut && $1 != akInOut)
|
||||
error("Illegal direction specified");
|
||||
|
||||
if (!($3->itNativePointer) && $1 != akIn)
|
||||
error("ValueOf only valid for in");
|
||||
|
||||
if (($3->itBadValue) != NULL && $1 != akIn)
|
||||
error("PointerToIfNot only valid for in");
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
Trailer : TrImplKeyword syIdentifier ArgumentType
|
||||
{
|
||||
$$ = argAlloc();
|
||||
$$->argKind = $1;
|
||||
$$->argName = $2;
|
||||
$$->argType = $3;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
Direction : /* empty */ { $$ = akNone; }
|
||||
| syIn { $$ = akIn; }
|
||||
| syOut { $$ = akOut; }
|
||||
| syInOut { $$ = akInOut; }
|
||||
| syRequestPort { $$ = akRequestPort; }
|
||||
| syReplyPort { $$ = akReplyPort; }
|
||||
| sySReplyPort { $$ = akSReplyPort; }
|
||||
| syUReplyPort { $$ = akUReplyPort; }
|
||||
| syWaitTime { $$ = akWaitTime; }
|
||||
| sySendTime { $$ = akSendTime; }
|
||||
| syMsgOption { $$ = akMsgOption; }
|
||||
| sySecToken { $$ = akSecToken; }
|
||||
| syServerSecToken { $$ = akServerSecToken; }
|
||||
| syUserSecToken { $$ = akUserSecToken; }
|
||||
| syAuditToken { $$ = akAuditToken; }
|
||||
| syServerAuditToken { $$ = akServerAuditToken; }
|
||||
| syUserAuditToken { $$ = akUserAuditToken; }
|
||||
| syServerContextToken { $$ = akServerContextToken; }
|
||||
| syMsgSeqno { $$ = akMsgSeqno; }
|
||||
;
|
||||
|
||||
|
||||
|
||||
TrImplKeyword : syServerImpl { $$ = akServerImpl; }
|
||||
| syUserImpl { $$ = akUserImpl; }
|
||||
;
|
||||
|
||||
|
||||
ArgumentType : syColon syIdentifier
|
||||
{
|
||||
$$ = itLookUp($2);
|
||||
if ($$ == itNULL)
|
||||
error("type '%s' not defined", $2);
|
||||
}
|
||||
| syColon NamedTypeSpec
|
||||
{ $$ = $2; }
|
||||
| syColon NativeTypeSpec
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
IPCFlags : /* empty */
|
||||
{ $$ = flNone; }
|
||||
| IPCFlags syComma syIPCFlag
|
||||
{
|
||||
if ($1 & $3)
|
||||
warn("redundant IPC flag ignored");
|
||||
else
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
| IPCFlags syComma syIPCFlag syLBrack syRBrack
|
||||
{
|
||||
if ($3 != flDealloc)
|
||||
warn("only Dealloc is variable");
|
||||
else
|
||||
$$ = $1 | flMaybeDealloc;
|
||||
}
|
||||
|
||||
LookString : /* empty */
|
||||
{ LookString(); }
|
||||
;
|
||||
|
||||
LookFileName : /* empty */
|
||||
{ LookFileName(); }
|
||||
;
|
||||
|
||||
LookQString : /* empty */
|
||||
{ LookQString(); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
yyerror(char *s)
|
||||
{
|
||||
error(s);
|
||||
}
|
||||
|
||||
static char *
|
||||
import_name(statement_kind_t sk)
|
||||
{
|
||||
switch (sk) {
|
||||
|
||||
case skImport:
|
||||
return "Import";
|
||||
|
||||
case skSImport:
|
||||
return "SImport";
|
||||
|
||||
case skUImport:
|
||||
return "UImport";
|
||||
|
||||
case skIImport:
|
||||
return "IImport";
|
||||
|
||||
case skDImport:
|
||||
return "DImport";
|
||||
|
||||
default:
|
||||
fatal("import_name(%d): not import statement", (int) sk);
|
||||
/*NOTREACHED*/
|
||||
return strNULL;
|
||||
}
|
||||
}
|
||||
1844
tools/mig/routine.c
Normal file
1844
tools/mig/routine.c
Normal file
File diff suppressed because it is too large
Load Diff
549
tools/mig/routine.h
Normal file
549
tools/mig/routine.h
Normal file
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef _ROUTINE_H
|
||||
#define _ROUTINE_H
|
||||
|
||||
#include "type.h"
|
||||
#include <stdio.h>
|
||||
#include <mach/message.h>
|
||||
#include <mach/boolean.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* base kind arg */
|
||||
#define akeNone (0)
|
||||
#define akeNormal (1) /* a normal, user-defined argument */
|
||||
#define akeRequestPort (2) /* pointed at by rtRequestPort */
|
||||
#define akeWaitTime (3) /* pointed at by rtWaitTime */
|
||||
#define akeReplyPort (4) /* pointed at by rtReplyPort */
|
||||
#define akeMsgOption (5) /* pointed at by rtMsgOption */
|
||||
#define akeMsgSeqno (6) /* pointed at by rtMsgSeqno */
|
||||
#define akeRetCode (7) /* pointed at by rtRetCode */
|
||||
#define akeNdrCode (8) /* pointed at by rtNdrCode */
|
||||
#define akeCount (9) /* a count arg for argParent */
|
||||
#define akePoly (10) /* a poly arg for argParent */
|
||||
#define akeDealloc (11) /* a deallocate arg for argParent */
|
||||
#define akeCountInOut (12) /* a count-in-out arg */
|
||||
#define akeSameCount (13) /* a samecount case: in fact, a no count! */
|
||||
#define akeSubCount (14) /* a array of array case: subordinate arrays count */
|
||||
#define akeImplicit (15) /* an implicit argument, from the trailer */
|
||||
#define akeSecToken (16) /* an argument from the trailer: the security token */
|
||||
#define akeAuditToken (17) /* an argument from the trailer: the audit token */
|
||||
#define akeContextToken (18) /* an argument from the trailer: the context token */
|
||||
#define akeSendTime (19) /* pointed at by rtWaitTime */
|
||||
|
||||
#define akeBITS (0x0000003f)
|
||||
#define akbRequest (0x00000040) /* has a msg_type in request */
|
||||
#define akbReply (0x00000080) /* has a msg_type in reply */
|
||||
#define akbUserArg (0x00000100) /* an arg on user-side */
|
||||
#define akbServerArg (0x00000200) /* an arg on server-side */
|
||||
#define akbSend (0x00000400) /* value carried in request */
|
||||
#define akbSendBody (0x00000800) /* value carried in request body */
|
||||
#define akbSendSnd (0x00001000) /* value stuffed into request */
|
||||
#define akbSendRcv (0x00002000) /* value grabbed from request */
|
||||
#define akbReturn (0x00004000) /* value carried in reply */
|
||||
#define akbReturnBody (0x00008000) /* value carried in reply body */
|
||||
#define akbReturnSnd (0x00010000) /* value stuffed into reply */
|
||||
#define akbReturnRcv (0x00020000) /* value grabbed from reply */
|
||||
#define akbReturnNdr (0x00040000) /* needs NDR conversion in reply */
|
||||
#define akbReplyInit (0x00080000) /* reply value doesn't come from target routine */
|
||||
#define akbReplyCopy (0x00200000) /* copy reply value from request */
|
||||
#define akbVarNeeded (0x00400000) /* may need local var in server */
|
||||
#define akbDestroy (0x00800000) /* call destructor function */
|
||||
#define akbVariable (0x01000000) /* variable size inline data */
|
||||
#define akbSendNdr (0x04000000) /* needs NDR conversion in request */
|
||||
#define akbSendKPD (0x08000000) /* the arg is sent in the Kernel Processed Data
|
||||
section of the Request message */
|
||||
#define akbReturnKPD (0x10000000) /* the arg is sent in the Kernel Processed Data
|
||||
section of the Reply message */
|
||||
#define akbUserImplicit (0x20000000) /* the arg is Impl */
|
||||
#define akbServerImplicit (0x40000000) /* the arg is Impl */
|
||||
#define akbOverwrite (0x80000000)
|
||||
/* be careful, there aren't many bits left */
|
||||
|
||||
typedef u_int arg_kind_t;
|
||||
|
||||
/*
|
||||
* akbRequest means msg_type/data fields are allocated in the request
|
||||
* msg. akbReply means msg_type/data fields are allocated in the
|
||||
* reply msg. These bits * control msg structure declarations packing,
|
||||
* and checking of mach_msg_type_t fields.
|
||||
*
|
||||
* akbUserArg means this argument is an argument to the user-side stub.
|
||||
* akbServerArg means this argument is an argument to
|
||||
* the server procedure called by the server-side stub.
|
||||
*
|
||||
* The akbSend* and akbReturn* bits control packing/extracting values
|
||||
* in the request and reply messages.
|
||||
*
|
||||
* akbSend means the argument's value is carried in the request msg.
|
||||
* akbSendBody implies akbSend; the value is carried in the msg body.
|
||||
* akbSendKPD is the equivalent of akbSendBody for Kernel Processed Data.
|
||||
* akbSendSnd implies akbSend; the value is stuffed into the request.
|
||||
* akbSendRcv implies akbSend; the value is pulled out of the request.
|
||||
*
|
||||
* akbReturn, akbReturnBody, akbReturnSnd, akbReturnRcv are defined
|
||||
* similarly but apply to the reply message.
|
||||
*
|
||||
* User-side code generation (header.c, user.c) and associated code
|
||||
* should use akbSendSnd and akbReturnRcv, but not akbSendRcv and
|
||||
* akbReturnSnd. Server-side code generation (server.c) is reversed.
|
||||
* Code generation should use the more specific akb{Send,Return}{Snd,Rcv}
|
||||
* bits when possible, instead of akb{Send,Return}.
|
||||
*
|
||||
* Note that akRetCode and akReturn lack any Return bits, although
|
||||
* there is a value in the msg. These guys are packed/unpacked
|
||||
* with special code, unlike other arguments.
|
||||
*
|
||||
* akbReplyInit implies akbReply. It means the server-side stub
|
||||
* should initialize the field, because its value does not come
|
||||
* from the execution of the target routine: the setting of the
|
||||
* NDR record is the sole example (at the moment) of use of this flag.
|
||||
*
|
||||
* akbVariable means the argument has variable-sized inline data.
|
||||
* It isn't currently used for code generation, but routine.c
|
||||
* does use it internally. It is added in rtAugmentArgKind.
|
||||
*
|
||||
* akbReplyCopy and akbVarNeeded help control code generation in the
|
||||
* server-side stub. The preferred method of handling data in the
|
||||
* server-side stub avoids copying into/out-of local variables. In
|
||||
* arguments get passed directly to the server proc from the request msg.
|
||||
* Out arguments get stuffed directly into the reply msg by the server proc.
|
||||
* For InOut arguments, the server proc gets the address of the data in
|
||||
* the request msg, and the resulting data gets copied to the reply msg.
|
||||
* Some arguments need a local variable in the server-side stub. The
|
||||
* code extracts the data from the request msg into the variable, and
|
||||
* stuff the reply msg from the variable.
|
||||
*
|
||||
* akbReplyCopy implies akbReply. It means the data should get copied
|
||||
* from the request msg to the reply msg after the server proc is called.
|
||||
* It is only used by akInOut. akTid doesn't need it because the tid
|
||||
* data in the reply msg is initialized in the server demux function.
|
||||
*
|
||||
* akbVarNeeded means the argument needs a local variable in the
|
||||
* server-side stub. It is added in rtAugmentArgKind and
|
||||
* rtCheckVariable. An argument shouldn't have all three of
|
||||
* akbReturnSnd, akbVarNeeded and akbReplyCopy, because this indicates
|
||||
* the reply msg should be stuffed both ways.
|
||||
*
|
||||
* akbDestroy helps control code generation in the server-side stub.
|
||||
* It means this argument has a destructor function which should be called.
|
||||
*
|
||||
* akbOverwrite is used to identify the arguments that have to put an entry in
|
||||
* the scatter list (the message-template used by the User stub to specify
|
||||
* where the out-of-line data sent by server has to land).
|
||||
*
|
||||
* akbUserImplicit (akbServerImplicit) is used to mark the arguments that
|
||||
* correspond to implicit data (data generated by the kernel and inserted in
|
||||
* the trailer).
|
||||
*
|
||||
* Header file generation (header.c) uses:
|
||||
* akbUserArg
|
||||
*
|
||||
* User stub generation (user.c) uses:
|
||||
* akbUserArg, akbRequest, akbReply, akbSendSnd,
|
||||
* akbSendBody, akbSendKPD, akbReturnRcv, akbOverwrite, akbUserImplicit
|
||||
*
|
||||
* Server stub generation (server.c) uses:
|
||||
* akbServerArg, akbRequest, akbReply, akbSendRcv, akbReturnSnd,
|
||||
* akbReplyCopy, akbVarNeeded, akbSendBody, akbServerImplicit
|
||||
*
|
||||
*
|
||||
* During code generation, the routine, argument, and type data structures
|
||||
* are read-only. The code generation functions' output is their only
|
||||
* side-effect.
|
||||
*
|
||||
*
|
||||
* Style note:
|
||||
* Code can use logical operators (|, &, ~) on akb values.
|
||||
* ak values should be manipulated with the ak functions.
|
||||
*/
|
||||
|
||||
/* various useful combinations */
|
||||
|
||||
#define akbNone (0)
|
||||
#define akbAll (~akbNone)
|
||||
#define akbAllBits (~akeBITS)
|
||||
|
||||
#define akbSendBits (akbSend|akbSendBody|akbSendSnd|akbSendRcv)
|
||||
#define akbReturnBits (akbReturn|akbReturnBody|akbReturnSnd|akbReturnRcv)
|
||||
#define akbSendReturnBits (akbSendBits|akbReturnBits)
|
||||
|
||||
#define akNone akeNone
|
||||
|
||||
#define akIn akAddFeature(akeNormal, \
|
||||
akbUserArg|akbServerArg|akbRequest|akbSendBits)
|
||||
|
||||
#define akOut akAddFeature(akeNormal, \
|
||||
akbUserArg|akbServerArg|akbReply|akbReturnBits)
|
||||
|
||||
#define akServerImpl akAddFeature(akeImplicit, \
|
||||
akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
|
||||
#define akUserImpl akAddFeature(akeImplicit, \
|
||||
akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
|
||||
|
||||
#define akServerSecToken akAddFeature(akeSecToken, \
|
||||
akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
|
||||
#define akUserSecToken akAddFeature(akeSecToken, \
|
||||
akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
|
||||
#define akSecToken akAddFeature(akeSecToken, \
|
||||
akbServerArg|akbServerImplicit|akbSend|akbSendRcv| \
|
||||
akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
|
||||
|
||||
#define akServerAuditToken akAddFeature(akeAuditToken, \
|
||||
akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
|
||||
#define akUserAuditToken akAddFeature(akeAuditToken, \
|
||||
akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
|
||||
#define akAuditToken akAddFeature(akeAuditToken, \
|
||||
akbServerArg|akbServerImplicit|akbSend|akbSendRcv| \
|
||||
akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
|
||||
|
||||
#define akServerContextToken akAddFeature(akeContextToken, \
|
||||
akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
|
||||
|
||||
#define akMsgSeqno akAddFeature(akeMsgSeqno, \
|
||||
akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
|
||||
|
||||
#define akInOut akAddFeature(akeNormal, \
|
||||
akbUserArg|akbServerArg|akbRequest|akbReply| \
|
||||
akbSendBits|akbReturnBits|akbReplyCopy)
|
||||
|
||||
#define akRequestPort akAddFeature(akeRequestPort, \
|
||||
akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv)
|
||||
|
||||
#define akWaitTime akAddFeature(akeWaitTime, akbUserArg)
|
||||
|
||||
#define akSendTime akAddFeature(akeSendTime, akbUserArg)
|
||||
|
||||
#define akMsgOption akAddFeature(akeMsgOption, akbUserArg)
|
||||
|
||||
#define akReplyPort akAddFeature(akeReplyPort, \
|
||||
akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv)
|
||||
|
||||
#define akUReplyPort akAddFeature(akeReplyPort, \
|
||||
akbUserArg|akbSend|akbSendSnd|akbSendRcv)
|
||||
|
||||
#define akSReplyPort akAddFeature(akeReplyPort, \
|
||||
akbServerArg|akbSend|akbSendSnd|akbSendRcv)
|
||||
|
||||
#define akRetCode akAddFeature(akeRetCode, akbReply|akbReturnBody)
|
||||
|
||||
#define akCount akAddFeature(akeCount, \
|
||||
akbUserArg|akbServerArg)
|
||||
|
||||
#define akPoly akePoly
|
||||
|
||||
#define akDealloc akAddFeature(akeDealloc, akbUserArg)
|
||||
|
||||
#define akCountInOut akAddFeature(akeCountInOut, akbRequest|akbSendBits)
|
||||
|
||||
#define akCheck(ak, bits) ((ak) & (bits))
|
||||
#define akCheckAll(ak, bits) (akCheck(ak, bits) == (bits))
|
||||
#define akAddFeature(ak, bits) ((ak)|(bits))
|
||||
#define akRemFeature(ak, bits) ((ak)&~(bits))
|
||||
#define akIdent(ak) ((ak) & akeBITS)
|
||||
|
||||
#define argIsIn(arg) (akIdent(arg->argKind) == akeNormal && \
|
||||
akCheck(arg->argKind, akbRequest))
|
||||
#define argIsOut(arg) (akIdent(arg->argKind) == akeNormal && \
|
||||
akCheck(arg->argKind, akbReply))
|
||||
|
||||
/*
|
||||
* The arguments to a routine/function are linked in left-to-right order.
|
||||
* argName is used for error messages and pretty-printing,
|
||||
* not code generation. Code generation shouldn't make any assumptions
|
||||
* about the order of arguments, esp. count and poly arguments.
|
||||
* (Unfortunately, code generation for inline variable-sized arguments
|
||||
* does make such assumptions.)
|
||||
*
|
||||
* argVarName is the name used in generated code for function arguments
|
||||
* and local variable names. argMsgField is the name used in generated
|
||||
* code for the field in msgs where the argument's value lives.
|
||||
* argTTName is the name used in generated code for msg-type fields and
|
||||
* static variables used to initialize those fields. argPadName is the
|
||||
* name used in generated code for a padding field in msgs.
|
||||
*
|
||||
* argFlags can be used to override the deallocate bits
|
||||
* in the argument's type. rtProcessArgFlags sets argDeallocate
|
||||
* from it and the type. Code generation shouldn't use
|
||||
* argFlags.
|
||||
*
|
||||
* argCount, argPoly, and argDealloc get to the implicit count, poly,
|
||||
* and dealloc arguments associated with the argument; they should be
|
||||
* used instead of argNext. In these implicit arguments, argParent is
|
||||
* a pointer to the "real" arg.
|
||||
*
|
||||
* In count arguments, argMultiplier is a scaling factor applied to
|
||||
* the count arg's value to get msg-type-number. It is equal to
|
||||
* argParent->argType->itElement->itNumber
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct argument
|
||||
{
|
||||
/* if argKind == akReturn, then argName is name of the function */
|
||||
identifier_t argName;
|
||||
struct argument *argNext;
|
||||
|
||||
arg_kind_t argKind;
|
||||
ipc_type_t *argType;
|
||||
/* Kernel Processed Data */
|
||||
mach_msg_descriptor_type_t argKPD_Type; /* KPD type: port, ool, port+ool */
|
||||
void (* argKPD_Template)(FILE *file, struct argument *arg, boolean_t in); /* KPD discipline for static templates */
|
||||
void (* argKPD_Init)(FILE *file, struct argument *arg); /* KPD discipline for initializing */
|
||||
void (* argKPD_Pack)(FILE *file, struct argument *ar); /* KPD discipline for packing */
|
||||
void (* argKPD_Extract)(FILE *file, struct argument *arg); /* KPD discipline for extracting */
|
||||
void (* argKPD_TypeCheck)(FILE *file, struct argument *ar); /* KPD discipline for type checking */
|
||||
|
||||
string_t argVarName; /* local variable and argument names */
|
||||
string_t argMsgField; /* message field's name */
|
||||
string_t argTTName; /* name for msg_type fields, static vars */
|
||||
string_t argPadName; /* name for pad field in msg */
|
||||
string_t argSuffix; /* name extension for KPDs */
|
||||
|
||||
ipc_flags_t argFlags;
|
||||
dealloc_t argDeallocate; /* overrides argType->itDeallocate */
|
||||
boolean_t argCountInOut;
|
||||
|
||||
struct routine *argRoutine; /* routine we are part of */
|
||||
|
||||
struct argument *argCount; /* our count arg, if present */
|
||||
struct argument *argSubCount; /* our sub-count arg, if present (variable subordinate arrays) */
|
||||
struct argument *argCInOut; /* our CountInOut arg, if present */
|
||||
struct argument *argPoly; /* our poly arg, if present */
|
||||
struct argument *argDealloc; /* our dealloc arg, if present */
|
||||
struct argument *argSameCount; /* the arg to take the count from, if present */
|
||||
struct argument *argParent; /* in a count or poly arg, the base arg */
|
||||
u_int argMultiplier; /* for Count argument: parent is a multiple
|
||||
of a basic IPC type. Argument must be
|
||||
multiplied by Multiplier to get IPC
|
||||
number-of-elements. */
|
||||
|
||||
/* how variable/inline args precede this one, in request and reply */
|
||||
u_int argRequestPos;
|
||||
u_int argReplyPos;
|
||||
/* whether argument is by reference, on user and server side */
|
||||
boolean_t argByReferenceUser;
|
||||
boolean_t argByReferenceServer;
|
||||
|
||||
boolean_t argTempOnStack; /* A temporary for the short-circuiting
|
||||
* code when -maxonstack is used.
|
||||
*/
|
||||
} argument_t;
|
||||
|
||||
/*
|
||||
* The various routine kinds' peculiarities are abstracted by rtCheckRoutine
|
||||
* into attributes like rtOneWay, etc. These are what
|
||||
* code generation should use. It is Bad Form for code generation to
|
||||
* test rtKind.
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
rkRoutine,
|
||||
rkSimpleRoutine
|
||||
} routine_kind_t;
|
||||
|
||||
typedef struct routine
|
||||
{
|
||||
identifier_t rtName;
|
||||
routine_kind_t rtKind;
|
||||
argument_t *rtArgs;
|
||||
u_int rtNumber; /* used for making msg ids */
|
||||
|
||||
identifier_t rtUserName; /* user-visible name (UserPrefix + Name) */
|
||||
identifier_t rtServerName; /* server-side name (ServerPrefix + Name) */
|
||||
|
||||
identifier_t rtErrorName; /* error-handler name */
|
||||
|
||||
boolean_t rtOneWay; /* SimpleRoutine */
|
||||
|
||||
boolean_t rtSimpleRequest;
|
||||
boolean_t rtSimpleReply;
|
||||
boolean_t rtUseSpecialReplyPort;
|
||||
u_int rtConsumeOnSendError;
|
||||
|
||||
u_int rtNumRequestVar; /* number of variable/inline args in request */
|
||||
u_int rtNumReplyVar; /* number of variable/inline args in reply */
|
||||
|
||||
u_int rtMaxRequestPos; /* maximum of argRequestPos */
|
||||
u_int rtMaxReplyPos; /* maximum of argReplyPos */
|
||||
|
||||
u_int rtRequestKPDs; /* number of Kernel Processed Data entries */
|
||||
u_int rtReplyKPDs; /* number of Kernel Processed Data entries */
|
||||
u_int rtOverwrite; /* number of Overwrite entries */
|
||||
u_int rtOverwriteKPDs; /* number of entries in the Overwrite template */
|
||||
|
||||
boolean_t rtNoReplyArgs; /* if so, no reply message arguments beyond
|
||||
what the server dispatch routine inserts */
|
||||
|
||||
boolean_t rtRequestFits; /* Request fits within onstack limit */
|
||||
boolean_t rtReplyFits; /* Reply fits within onstack limit */
|
||||
boolean_t rtRequestUsedLimit;/* User type limit used in deciding whether
|
||||
request fits within onstack limit */
|
||||
boolean_t rtReplyUsedLimit; /* User type limit used in deciding whether
|
||||
reply fits within onstack limit */
|
||||
u_int rtRequestSizeKnown; /* Max size of known portion of request */
|
||||
u_int rtReplySizeKnown; /* Max size of known portion of request */
|
||||
|
||||
u_int rtServerImpl; /* Implicit data requested */
|
||||
u_int rtUserImpl; /* Implicit data requested */
|
||||
|
||||
/* distinguished arguments */
|
||||
argument_t *rtRetCArg; /* the Routine has this argument tagged as RetCode */
|
||||
argument_t *rtRequestPort; /* always non-NULL, defaults to first arg */
|
||||
argument_t *rtReplyPort; /* always non-NULL, defaults to Mig-supplied */
|
||||
argument_t *rtRetCode; /* always non-NULL */
|
||||
argument_t *rtNdrCode; /* always non-NULL */
|
||||
argument_t *rtWaitTime; /* if non-NULL, will use MACH_RCV_TIMEOUT */
|
||||
argument_t *rtMsgOption; /* always non-NULL, defaults to NONE */
|
||||
|
||||
/* more info's used only when UseEventLogger is turned on */
|
||||
u_int rtCountPortsIn; /* how many in-line Ports are sent */
|
||||
u_int rtCountOolPortsIn; /* how many out_of-line Ports are sent */
|
||||
u_int rtCountOolIn; /* how many bytes out_of-line are sent */
|
||||
|
||||
u_int rtCountPortsOut; /* how many in-line Ports are rcv'd */
|
||||
u_int rtCountOolPortsOut; /* how many out_of-line Ports are rcv'd */
|
||||
u_int rtCountOolOut; /* how many bytes out_of-line are rcv'd */
|
||||
|
||||
u_int rtTempBytesOnStack; /* A temporary for the short-circuiting
|
||||
* code when -maxonstack is used.
|
||||
*/
|
||||
|
||||
} routine_t;
|
||||
|
||||
#define rtNULL ((routine_t *) 0)
|
||||
#define argNULL ((argument_t *) 0)
|
||||
#define argKPD_NULL ((mach_msg_descriptor_type_t) -1)
|
||||
|
||||
#define rtMessOnStack(rt) ((rt)->rtRequestFits && (rt)->rtReplyFits)
|
||||
|
||||
/*
|
||||
* These are the ways MiG organizes stub parameters
|
||||
*/
|
||||
#define IS_VARIABLE_SIZED_UNTYPED(x) ((x)->itVarArray && \
|
||||
(x)->itInLine && \
|
||||
!(x)->itPortType)
|
||||
#define IS_KERN_PROC_DATA(x) (!(x)->itInLine || (x)->itPortType)
|
||||
#define IS_OPTIONAL_NATIVE(x) ((x)->itNative && \
|
||||
(x)->itNativePointer && \
|
||||
(x)->itBadValue != NULL)
|
||||
|
||||
/*
|
||||
* I consider the case of fixed/variable bounded arrays of ports or ool or oolport
|
||||
*/
|
||||
#define IS_MULTIPLE_KPD(x) ((x)->itKPD_Number > 1)
|
||||
/*
|
||||
* I consider the case of MiG presenting data as it is inLine, even
|
||||
* if it is sent/rcvd as out-of-line
|
||||
*/
|
||||
#define IS_MIG_INLINE_EMUL(x) ((x)->itMigInLine)
|
||||
|
||||
extern u_int rtNumber;
|
||||
/* rt->rtNumber will be initialized */
|
||||
extern routine_t *rtAlloc(void);
|
||||
/* skip a number */
|
||||
extern void rtSkip(void);
|
||||
|
||||
extern argument_t *argAlloc(void);
|
||||
|
||||
extern boolean_t
|
||||
rtCheckMask(argument_t *args, u_int mask);
|
||||
|
||||
extern boolean_t
|
||||
rtCheckMaskFunction(argument_t *args, u_int mask,
|
||||
boolean_t (*func)(argument_t *arg));
|
||||
|
||||
extern routine_t *
|
||||
rtMakeRoutine(identifier_t name, argument_t *args);
|
||||
extern routine_t *
|
||||
rtMakeSimpleRoutine(identifier_t name, argument_t *args);
|
||||
|
||||
extern void rtPrintRoutine(routine_t *rt);
|
||||
extern void rtCheckRoutine(routine_t *rt);
|
||||
|
||||
extern char *rtRoutineKindToStr(routine_kind_t rk);
|
||||
|
||||
extern int rtCountArgDescriptors(argument_t *args, int *argcount);
|
||||
|
||||
extern void rtMinRequestSize(FILE *file, routine_t *rt, char *str);
|
||||
extern void rtMinReplySize(FILE *file, routine_t *rt, char *str);
|
||||
|
||||
#define RPCUserStruct(arg) (arg->argType->itStruct && arg->argType->itInLine)
|
||||
|
||||
#define RPCString(arg) (arg->argType->itString && arg->argType->itInLine)
|
||||
|
||||
#define RPCOutStruct(arg) (arg->argType->itStruct &&\
|
||||
argIsOut(arg) && (! arg->argType->itVarArray))
|
||||
#define RPCOutWord(arg) (RPCUserStruct(arg) &&\
|
||||
(arg->argType->itSize <= 32) &&\
|
||||
(arg->argType->itNumber == 1) && argIsOut(arg))
|
||||
|
||||
#define RPCPort(arg) (arg->argKPD_Type == MACH_MSG_PORT_DESCRIPTOR)
|
||||
|
||||
#define RPCPortArray(arg) (arg->argKPD_Type == MACH_MSG_OOL_PORTS_DESCRIPTOR)
|
||||
|
||||
#define RPCVariableArray(arg) ((arg->argType->itVarArray) &&\
|
||||
!RPCPort(arg) && !RPCPortArray(arg))
|
||||
|
||||
#define RPCFixedArray(arg) (((! arg->argType->itVarArray) &&\
|
||||
!RPCPort(arg) && !RPCPortArray(arg) &&\
|
||||
(arg->argType->itNumber > 1) &&\
|
||||
!RPCUserStruct(arg)) ||\
|
||||
RPCString(arg) ||\
|
||||
RPCOutWord(arg) ||\
|
||||
RPCOutStruct(arg))
|
||||
|
||||
|
||||
#endif /* _ROUTINE_H */
|
||||
|
||||
|
||||
|
||||
2772
tools/mig/server.c
Normal file
2772
tools/mig/server.c
Normal file
File diff suppressed because it is too large
Load Diff
68
tools/mig/statement.c
Normal file
68
tools/mig/statement.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include "error.h"
|
||||
#include "alloc.h"
|
||||
#include "statement.h"
|
||||
|
||||
statement_t *stats = stNULL;
|
||||
static statement_t **last = &stats;
|
||||
|
||||
statement_t *
|
||||
stAlloc(void)
|
||||
{
|
||||
statement_t *new;
|
||||
|
||||
new = (statement_t *) malloc(sizeof *new);
|
||||
if (new == stNULL)
|
||||
fatal("stAlloc(): %s", strerror(errno));
|
||||
*last = new;
|
||||
last = &new->stNext;
|
||||
new->stNext = stNULL;
|
||||
return new;
|
||||
}
|
||||
98
tools/mig/statement.h
Normal file
98
tools/mig/statement.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
/*
|
||||
* HISTORY
|
||||
* 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Extensive revamping. Added polymorphic arguments.
|
||||
* Allow multiple variable-sized inline arguments in messages.
|
||||
*
|
||||
* 27-May-87 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Created.
|
||||
*/
|
||||
|
||||
#ifndef _STATEMENT_H
|
||||
#define _STATEMENT_H
|
||||
|
||||
#include "routine.h"
|
||||
|
||||
typedef enum statement_kind
|
||||
{
|
||||
skRoutine,
|
||||
skImport,
|
||||
skUImport,
|
||||
skSImport,
|
||||
skDImport,
|
||||
skIImport,
|
||||
skRCSDecl
|
||||
} statement_kind_t;
|
||||
|
||||
typedef struct statement
|
||||
{
|
||||
statement_kind_t stKind;
|
||||
struct statement *stNext;
|
||||
union
|
||||
{
|
||||
/* when stKind == skRoutine */
|
||||
routine_t *_stRoutine;
|
||||
/* when stKind == skImport, skUImport, skSImport, skDImport, skIImport */
|
||||
string_t _stFileName;
|
||||
} data;
|
||||
} statement_t;
|
||||
|
||||
#define stRoutine data._stRoutine
|
||||
#define stFileName data._stFileName
|
||||
|
||||
#define stNULL ((statement_t *) 0)
|
||||
|
||||
/* stNext will be initialized to put the statement in the list */
|
||||
extern statement_t *stAlloc(void);
|
||||
|
||||
/* list of statements, in order they occur in the .defs file */
|
||||
extern statement_t *stats;
|
||||
|
||||
#endif /* _STATEMENT_H */
|
||||
93
tools/mig/strdefs.h
Normal file
93
tools/mig/strdefs.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
/*
|
||||
* 91/02/05 17:55:57 mrt
|
||||
* Changed to new Mach copyright
|
||||
* [91/02/01 17:56:03 mrt]
|
||||
*
|
||||
* 90/06/02 15:05:49 rpd
|
||||
* Created for new IPC.
|
||||
* [90/03/26 21:13:56 rpd]
|
||||
*
|
||||
* 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Extensive revamping. Added polymorphic arguments.
|
||||
* Allow multiple variable-sized inline arguments in messages.
|
||||
*
|
||||
* 15-Jun-87 David Black (dlb) at Carnegie-Mellon University
|
||||
* Fixed strNULL to be the null string instead of the null string
|
||||
* pointer.
|
||||
*
|
||||
* 27-May-87 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Created.
|
||||
*/
|
||||
|
||||
#ifndef STRDEFS_H
|
||||
#define STRDEFS_H
|
||||
|
||||
#include <string.h>
|
||||
#include <mach/boolean.h>
|
||||
|
||||
typedef char *string_t;
|
||||
typedef string_t identifier_t;
|
||||
|
||||
#define MAX_STR_LEN 200
|
||||
|
||||
#define strNULL ((string_t) 0)
|
||||
|
||||
extern string_t strmake( char *string );
|
||||
extern string_t strconcat( string_t left, string_t right );
|
||||
extern string_t strphrase( string_t left, string_t right );
|
||||
extern void strfree( string_t string );
|
||||
|
||||
#define streql(a, b) (strcmp((a), (b)) == 0)
|
||||
|
||||
extern char *strbool( boolean_t bool );
|
||||
extern char *strstring( string_t string );
|
||||
extern char *toupperstr( char *string );
|
||||
|
||||
#endif /* STRDEFS_H */
|
||||
132
tools/mig/string.c
Normal file
132
tools/mig/string.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include <mach/boolean.h>
|
||||
#include <ctype.h>
|
||||
#include "error.h"
|
||||
#include "alloc.h"
|
||||
#include "strdefs.h"
|
||||
|
||||
string_t
|
||||
strmake(char *string)
|
||||
{
|
||||
string_t saved;
|
||||
|
||||
saved = malloc(strlen(string) + 1);
|
||||
if (saved == strNULL)
|
||||
fatal("strmake('%s'): %s", string, strerror(errno));
|
||||
return strcpy(saved, string);
|
||||
}
|
||||
|
||||
string_t
|
||||
strconcat(string_t left, string_t right)
|
||||
{
|
||||
string_t saved;
|
||||
|
||||
saved = malloc(strlen(left) + strlen(right) + 1);
|
||||
if (saved == strNULL)
|
||||
fatal("strconcat('%s', '%s'): %s", left, right, strerror(errno));
|
||||
return strcat(strcpy(saved, left), right);
|
||||
}
|
||||
|
||||
string_t
|
||||
strphrase(string_t left, string_t right)
|
||||
{
|
||||
string_t saved;
|
||||
string_t current;
|
||||
size_t llen;
|
||||
|
||||
llen = strlen(left);
|
||||
saved = malloc(llen + strlen(right) + 2);
|
||||
if (saved == strNULL)
|
||||
fatal("strphrase('%s', '%s'): %s", left, right, strerror(errno));
|
||||
strcpy(saved, left);
|
||||
current = saved + llen;
|
||||
*(current++) = ' ';
|
||||
strcpy(current, right);
|
||||
free(left);
|
||||
return(saved);
|
||||
}
|
||||
|
||||
void
|
||||
strfree(string_t string)
|
||||
{
|
||||
free(string);
|
||||
}
|
||||
|
||||
char *
|
||||
strbool(boolean_t bool)
|
||||
{
|
||||
if (bool)
|
||||
return "TRUE";
|
||||
else
|
||||
return "FALSE";
|
||||
}
|
||||
|
||||
char *
|
||||
strstring(string_t string)
|
||||
{
|
||||
if (string == strNULL)
|
||||
return "NULL";
|
||||
else
|
||||
return string;
|
||||
}
|
||||
|
||||
char *
|
||||
toupperstr(char *p)
|
||||
{
|
||||
char *s = p;
|
||||
char c;
|
||||
|
||||
while ((c = *s)) {
|
||||
if (islower(c))
|
||||
*s = toupper(c);
|
||||
s++;
|
||||
}
|
||||
return(p);
|
||||
}
|
||||
899
tools/mig/type.c
Normal file
899
tools/mig/type.c
Normal file
@@ -0,0 +1,899 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include "type.h"
|
||||
#include <sys/types.h>
|
||||
#include <mach/message.h>
|
||||
#include <mach/std_types.h>
|
||||
#include <mach/ndr.h>
|
||||
#include "mig_machine.h"
|
||||
#include "routine.h"
|
||||
#include "error.h"
|
||||
#include "alloc.h"
|
||||
#include "global.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define PortSize (sizeof (mach_port_t) * NBBY)
|
||||
|
||||
ipc_type_t *itRetCodeType; /* used for return codes */
|
||||
ipc_type_t *itNdrCodeType; /* used for NDR format labels */
|
||||
ipc_type_t *itDummyType; /* used for camelot dummy args */
|
||||
ipc_type_t *itTidType; /* used for camelot tids */
|
||||
ipc_type_t *itRequestPortType; /* used for default Request port arg */
|
||||
ipc_type_t *itZeroReplyPortType;/* used for dummy Reply port arg */
|
||||
ipc_type_t *itRealReplyPortType;/* used for default Reply port arg */
|
||||
ipc_type_t *itWaitTimeType; /* used for dummy WaitTime args */
|
||||
ipc_type_t *itMsgOptionType; /* used for dummy MsgOption args */
|
||||
|
||||
static ipc_type_t *list = itNULL;
|
||||
|
||||
static char *machine_integer_name;
|
||||
static u_int machine_integer_size;
|
||||
static u_int machine_integer_bits;
|
||||
|
||||
/*
|
||||
* Searches for a named type. We use a simple
|
||||
* self-organizing linked list.
|
||||
*/
|
||||
ipc_type_t *
|
||||
itLookUp(identifier_t name)
|
||||
{
|
||||
ipc_type_t *it, **last;
|
||||
|
||||
for (it = *(last = &list); it != itNULL; it = *(last = &it->itNext))
|
||||
if (streql(name, it->itName)) {
|
||||
/* move this type to the front of the list */
|
||||
*last = it->itNext;
|
||||
it->itNext = list;
|
||||
list = it;
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
return itNULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enters a new name-type association into
|
||||
* our self-organizing linked list.
|
||||
*/
|
||||
void
|
||||
itInsert(identifier_t name, ipc_type_t *it)
|
||||
{
|
||||
it->itName = name;
|
||||
it->itNext = list;
|
||||
list = it;
|
||||
}
|
||||
|
||||
static ipc_type_t *
|
||||
itAlloc(void)
|
||||
{
|
||||
static ipc_type_t prototype =
|
||||
{
|
||||
strNULL, /* identifier_t itName */
|
||||
0, /* ipc_type_t *itNext */
|
||||
0, /* u_int itTypeSize */
|
||||
0, /* u_int itPadSize */
|
||||
0, /* u_int itMinTypeSize */
|
||||
0, /* u_int itInName */
|
||||
0, /* u_int itOutName */
|
||||
0, /* u_int itSize */
|
||||
1, /* u_int itNumber */
|
||||
0, /* u_int itKPD_Number */
|
||||
TRUE, /* boolean_t itInLine */
|
||||
FALSE, /* boolean_t itMigInLine */
|
||||
FALSE, /* boolean_t itPortType */
|
||||
strNULL, /* string_t itInNameStr */
|
||||
strNULL, /* string_t itOutNameStr */
|
||||
TRUE, /* boolean_t itStruct */
|
||||
FALSE, /* boolean_t itString */
|
||||
FALSE, /* boolean_t itVarArray */
|
||||
FALSE, /* boolean_t itNoOptArray */
|
||||
FALSE, /* boolean_t itNative */
|
||||
FALSE, /* boolean_t itNativePointer */
|
||||
itNULL, /* ipc_type_t *itElement */
|
||||
strNULL, /* identifier_t itUserType */
|
||||
strNULL, /* identifier_t itServerType */
|
||||
strNULL, /* identifier_t itTransType */
|
||||
strNULL, /* identifier_t itUserKPDType */
|
||||
strNULL, /* identifier_t itServerKPDType */
|
||||
strNULL, /* identifier_t itInTrans */
|
||||
strNULL, /* identifier_t itOutTrans */
|
||||
strNULL, /* identifier_t itDestructor */
|
||||
};
|
||||
ipc_type_t *new;
|
||||
|
||||
new = (ipc_type_t *) malloc(sizeof *new);
|
||||
if (new == itNULL)
|
||||
fatal("itAlloc(): %s", strerror(errno));
|
||||
*new = prototype;
|
||||
return new;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an IPC type-name into a string.
|
||||
*/
|
||||
static char *
|
||||
itNameToString(u_int name)
|
||||
{
|
||||
char buffer[100];
|
||||
|
||||
(void) sprintf(buffer, "%u", name);
|
||||
return strmake(buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate itTypeSize, itPadSize, itMinTypeSize
|
||||
* Every type needs this info; it is recalculated
|
||||
* when itInLine, itNumber, or itSize changes.
|
||||
*/
|
||||
static void
|
||||
itCalculateSizeInfo(ipc_type_t *it)
|
||||
{
|
||||
if (!IS_KERN_PROC_DATA(it))
|
||||
{
|
||||
u_int bytes = (it->itNumber * it->itSize + 7) / 8;
|
||||
u_int padding = machine_padding(bytes);
|
||||
|
||||
it->itTypeSize = bytes;
|
||||
it->itPadSize = padding;
|
||||
if (IS_VARIABLE_SIZED_UNTYPED(it)) {
|
||||
/*
|
||||
* for these arrays, the argCount is not a akbRequest|akbReply,
|
||||
* therefore we need to account here for the space of the count
|
||||
* (itMinTypeSize is used only in rtFindSize)
|
||||
*/
|
||||
it->itMinTypeSize = sizeof (mach_msg_type_number_t);
|
||||
/*
|
||||
* NDR encoded VarString carry the extra offset 4-bytes fields
|
||||
* for MIG, it should be always 0;
|
||||
*/
|
||||
if (it->itString)
|
||||
it->itMinTypeSize += sizeof (mach_msg_type_number_t);
|
||||
}
|
||||
else
|
||||
it->itMinTypeSize = bytes + padding;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* 1) ports 2) OOL 3) ports OOL
|
||||
* all have the same size = sizeof(mach_msg_descriptor_t)
|
||||
*/
|
||||
u_int bytes;
|
||||
if (IS_MULTIPLE_KPD(it))
|
||||
bytes = it->itKPD_Number * 12 /* sizeof(mach_msg_descriptor_t) */;
|
||||
else
|
||||
bytes = 12 /* sizeof(mach_msg_descriptor_t) */;
|
||||
|
||||
it->itTypeSize = bytes;
|
||||
it->itPadSize = 0;
|
||||
it->itMinTypeSize = bytes;
|
||||
}
|
||||
|
||||
/* Unfortunately, these warning messages can't give a type name;
|
||||
we haven't seen a name yet (it might stay anonymous.) */
|
||||
|
||||
if ((it->itTypeSize == 0) && !it->itVarArray && !it->itNative)
|
||||
warn("sizeof(%s) == 0");
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in default values for some fields used in code generation:
|
||||
* itInNameStr, itOutNameStr, itUserType, itServerType, itTransType
|
||||
* Every argument's type should have these values filled in.
|
||||
*/
|
||||
static void
|
||||
itCalculateNameInfo(ipc_type_t *it)
|
||||
{
|
||||
if (it->itInNameStr == strNULL)
|
||||
it->itInNameStr = strmake(itNameToString(it->itInName));
|
||||
if (it->itOutNameStr == strNULL)
|
||||
it->itOutNameStr = strmake(itNameToString(it->itOutName));
|
||||
|
||||
if (it->itUserType == strNULL)
|
||||
it->itUserType = it->itName;
|
||||
if (it->itServerType == strNULL)
|
||||
it->itServerType = it->itName;
|
||||
#if 0
|
||||
/*
|
||||
* KernelServer and KernelUser interfaces get special treatment here.
|
||||
* On the kernel side of the interface, ports are really internal
|
||||
* port pointers (ipc_port_t), not port names (mach_port_t).
|
||||
* At this point, we don't know if the argument is in or out,
|
||||
* so we don't know if we should look at itInName or itOutName.
|
||||
* Looking at both should be OK.
|
||||
*
|
||||
* This is definitely a hack, but I think it is cleaner than
|
||||
* mucking with type declarations throughout the kernel .def files,
|
||||
* hand-conditionalizing on KERNEL_SERVER and KERNEL_USER.
|
||||
*/
|
||||
|
||||
if (IsKernelServer &&
|
||||
streql(it->itServerType, "mach_port_t") &&
|
||||
(((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) &&
|
||||
(it->itOutName == MACH_MSG_TYPE_POLYMORPHIC)) ||
|
||||
MACH_MSG_TYPE_PORT_ANY(it->itInName) ||
|
||||
MACH_MSG_TYPE_PORT_ANY(it->itOutName)))
|
||||
it->itServerType = "ipc_port_t";
|
||||
|
||||
if (IsKernelUser &&
|
||||
streql(it->itUserType, "mach_port_t") &&
|
||||
(((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) &&
|
||||
(it->itOutName == MACH_MSG_TYPE_POLYMORPHIC)) ||
|
||||
MACH_MSG_TYPE_PORT_ANY(it->itInName) ||
|
||||
MACH_MSG_TYPE_PORT_ANY(it->itOutName)))
|
||||
it->itUserType = "ipc_port_t";
|
||||
#endif /* 0 */
|
||||
|
||||
if (it->itTransType == strNULL)
|
||||
it->itTransType = it->itServerType;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* Checks for non-implemented types, conflicting type
|
||||
* flags and whether the long or short form of msg type
|
||||
* descriptor is appropriate. Called after each type statement
|
||||
* is parsed.
|
||||
******************************************************/
|
||||
static void
|
||||
itCheckDecl(identifier_t name, ipc_type_t *it)
|
||||
{
|
||||
it->itName = name;
|
||||
|
||||
itCalculateNameInfo(it);
|
||||
|
||||
/* do a bit of error checking, mostly necessary because of
|
||||
limitations in Mig */
|
||||
|
||||
if (it->itVarArray) {
|
||||
if ((it->itInTrans != strNULL) || (it->itOutTrans != strNULL))
|
||||
error("%s: can't translate variable-sized arrays", name);
|
||||
|
||||
if (it->itDestructor != strNULL)
|
||||
error("%s: can't destroy variable-sized array", name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pretty-prints translation/destruction/type information.
|
||||
*/
|
||||
static void
|
||||
itPrintTrans(ipc_type_t *it)
|
||||
{
|
||||
if (!streql(it->itName, it->itUserType))
|
||||
printf("\tCUserType:\t%s\n", it->itUserType);
|
||||
|
||||
if (!streql(it->itName, it->itServerType))
|
||||
printf("\tCServerType:\t%s\n", it->itServerType);
|
||||
|
||||
if (it->itInTrans != strNULL)
|
||||
printf("\tInTran:\t\t%s %s(%s)\n", it->itTransType, it->itInTrans, it->itServerType);
|
||||
|
||||
if (it->itOutTrans != strNULL)
|
||||
printf("\tOutTran:\t%s %s(%s)\n", it->itServerType, it->itOutTrans, it->itTransType);
|
||||
|
||||
if (it->itDestructor != strNULL)
|
||||
printf("\tDestructor:\t%s(%s)\n", it->itDestructor, it->itTransType);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pretty-prints type declarations.
|
||||
*/
|
||||
static void
|
||||
itPrintDecl(identifier_t name, ipc_type_t *it)
|
||||
{
|
||||
printf("Type %s = ", name);
|
||||
if (!it->itInLine)
|
||||
printf("^ ");
|
||||
if (it->itVarArray)
|
||||
if (it->itNumber == 0 || it->itMigInLine)
|
||||
printf("array [] of ");
|
||||
else
|
||||
printf("array [*:%d] of ", it->itNumber);
|
||||
else if (it->itStruct && ((it->itNumber != 1) ||
|
||||
(it->itInName == MACH_MSG_TYPE_STRING_C)))
|
||||
printf("struct [%d] of ", it->itNumber);
|
||||
else if (it->itNumber != 1)
|
||||
printf("array [%d] of ", it->itNumber);
|
||||
|
||||
if (streql(it->itInNameStr, it->itOutNameStr))
|
||||
printf("(%s,", it->itInNameStr);
|
||||
else
|
||||
printf("(%s|%s", it->itInNameStr, it->itOutNameStr);
|
||||
|
||||
printf(" %d)\n", it->itSize);
|
||||
|
||||
itPrintTrans(it);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles named type-specs, which can occur in type
|
||||
* declarations or in argument lists. For example,
|
||||
* type foo = type-spec; // itInsert will get called later
|
||||
* routine foo(arg : bar = type-spec); // itInsert won't get called
|
||||
*/
|
||||
void
|
||||
itTypeDecl(identifier_t name, ipc_type_t *it)
|
||||
{
|
||||
itCheckDecl(name, it);
|
||||
|
||||
if (BeVerbose)
|
||||
itPrintDecl(name, it);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles declarations like
|
||||
* type new = name;
|
||||
* type new = inname|outname;
|
||||
*/
|
||||
ipc_type_t *
|
||||
itShortDecl(u_int inname, string_t instr, u_int outname, string_t outstr, u_int defsize)
|
||||
{
|
||||
ipc_type_t *it;
|
||||
|
||||
if (defsize == 0)
|
||||
error("must use full IPC type decl");
|
||||
|
||||
it = itAlloc();
|
||||
it->itInName = inname;
|
||||
it->itInNameStr = instr;
|
||||
it->itOutName = outname;
|
||||
it->itOutNameStr = outstr;
|
||||
it->itSize = defsize;
|
||||
if (inname == MACH_MSG_TYPE_STRING_C)
|
||||
{
|
||||
it->itStruct = FALSE;
|
||||
it->itString = TRUE;
|
||||
}
|
||||
/*
|
||||
* I check only inname, because outname
|
||||
* has to be a port as well (polymorphic types
|
||||
* are now restricted to port rights)
|
||||
*/
|
||||
if (MACH_MSG_TYPE_PORT_ANY(inname) ||
|
||||
inname == MACH_MSG_TYPE_POLYMORPHIC) {
|
||||
it->itPortType = TRUE;
|
||||
it->itKPD_Number = 1;
|
||||
}
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
static ipc_type_t *
|
||||
itCopyType(ipc_type_t *old)
|
||||
{
|
||||
ipc_type_t *new = itAlloc();
|
||||
|
||||
*new = *old;
|
||||
new->itName = strNULL;
|
||||
new->itNext = itNULL;
|
||||
new->itElement = old;
|
||||
|
||||
/* size info still valid */
|
||||
return new;
|
||||
}
|
||||
|
||||
/*
|
||||
* A call to itCopyType is almost always followed with itResetType.
|
||||
* The exception is itPrevDecl. Also called before adding any new
|
||||
* translation/destruction/type info (see parser.y).
|
||||
*
|
||||
* type new = old; // new doesn't get old's info
|
||||
* type new = array[*:10] of old;
|
||||
* // new doesn't get old's info, but new->itElement does
|
||||
* type new = array[*:10] of struct[3] of old;
|
||||
* // new and new->itElement don't get old's info
|
||||
*/
|
||||
|
||||
ipc_type_t *
|
||||
itResetType(ipc_type_t *old)
|
||||
{
|
||||
/* reset all special translation/destruction/type info */
|
||||
|
||||
old->itInTrans = strNULL;
|
||||
old->itOutTrans = strNULL;
|
||||
old->itDestructor = strNULL;
|
||||
old->itUserType = strNULL;
|
||||
old->itServerType = strNULL;
|
||||
old->itTransType = strNULL;
|
||||
return old;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the declaration
|
||||
* type new = old;
|
||||
*/
|
||||
ipc_type_t *
|
||||
itPrevDecl(identifier_t name)
|
||||
{
|
||||
ipc_type_t *old;
|
||||
|
||||
old = itLookUp(name);
|
||||
if (old == itNULL) {
|
||||
error("type '%s' not defined", name);
|
||||
return itAlloc();
|
||||
}
|
||||
else
|
||||
return itCopyType(old);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the declarations
|
||||
* type new = array[] of old; // number is oo
|
||||
* type new = array[*] of old; // number is oo
|
||||
* type new = array[*:number] of old;
|
||||
*/
|
||||
ipc_type_t *
|
||||
itVarArrayDecl(u_int number, ipc_type_t *old)
|
||||
{
|
||||
ipc_type_t *it = itResetType(itCopyType(old));
|
||||
|
||||
if (!it->itInLine) {
|
||||
/* already an initialized KPD */
|
||||
if (it->itKPD_Number != 1 || !number)
|
||||
error("IPC type decl is too complicated for Kernel Processed Data");
|
||||
it->itKPD_Number *= number;
|
||||
it->itNumber = 1;
|
||||
it->itInLine = FALSE;
|
||||
it->itStruct = FALSE;
|
||||
it->itOOL_Number = number;
|
||||
}
|
||||
else if (it->itVarArray)
|
||||
error("IPC type decl is too complicated");
|
||||
else if (number) {
|
||||
it->itNumber *= number;
|
||||
/*
|
||||
* Bounded [Scalar, Port] VarArray: in-line!
|
||||
*/
|
||||
it->itInLine = TRUE;
|
||||
it->itStruct = FALSE;
|
||||
if (it->itPortType)
|
||||
it->itKPD_Number *= number;
|
||||
it->itOOL_Number = number;
|
||||
}
|
||||
else {
|
||||
it->itNumber = 0;
|
||||
/*
|
||||
* UnBounded [Scalar, Port] VarArray: always in-line
|
||||
* interface and out-of-line mechanism!
|
||||
*/
|
||||
it->itMigInLine = TRUE;
|
||||
it->itInLine = FALSE;
|
||||
it->itStruct = TRUE;
|
||||
it->itKPD_Number = 1;
|
||||
it->itOOL_Number = 0;
|
||||
}
|
||||
|
||||
it->itVarArray = TRUE;
|
||||
it->itString = FALSE;
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the declaration
|
||||
* type new = array[number] of old;
|
||||
*/
|
||||
ipc_type_t *
|
||||
itArrayDecl(u_int number, ipc_type_t *old)
|
||||
{
|
||||
ipc_type_t *it = itResetType(itCopyType(old));
|
||||
|
||||
if (!it->itInLine) {
|
||||
/* already an initialized KPD */
|
||||
if (it->itKPD_Number != 1)
|
||||
error("IPC type decl is too complicated for Kernel Processed Data");
|
||||
it->itKPD_Number *= number;
|
||||
it->itNumber = 1;
|
||||
it->itStruct = FALSE;
|
||||
it->itString = FALSE;
|
||||
it->itVarArray = FALSE;
|
||||
}
|
||||
else if (it->itVarArray)
|
||||
error("IPC type decl is too complicated");
|
||||
else {
|
||||
it->itNumber *= number;
|
||||
it->itStruct = FALSE;
|
||||
it->itString = FALSE;
|
||||
if (it->itPortType)
|
||||
it->itKPD_Number *= number;
|
||||
}
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the declaration
|
||||
* type new = ^ old;
|
||||
*/
|
||||
ipc_type_t *
|
||||
itPtrDecl(ipc_type_t *it)
|
||||
{
|
||||
if (!it->itInLine && !it->itMigInLine)
|
||||
error("IPC type decl is already defined to be Out-Of-Line");
|
||||
it->itInLine = FALSE;
|
||||
it->itStruct = TRUE;
|
||||
it->itString = FALSE;
|
||||
it->itMigInLine = FALSE;
|
||||
it->itKPD_Number = 1;
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the declaration
|
||||
* type new = struct[number] of old;
|
||||
*/
|
||||
ipc_type_t *
|
||||
itStructDecl(u_int number, ipc_type_t *old)
|
||||
{
|
||||
ipc_type_t *it = itResetType(itCopyType(old));
|
||||
|
||||
if (!it->itInLine || it->itVarArray)
|
||||
error("IPC type decl is too complicated");
|
||||
it->itNumber *= number;
|
||||
it->itStruct = TRUE;
|
||||
it->itString = FALSE;
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
/*
|
||||
* Treat 'c_string[n]' as
|
||||
* 'array[n] of (MSG_TYPE_STRING_C, 8)'
|
||||
*/
|
||||
ipc_type_t *
|
||||
itCStringDecl(int count, boolean_t varying)
|
||||
{
|
||||
ipc_type_t *it;
|
||||
ipc_type_t *itElement;
|
||||
|
||||
itElement = itShortDecl(MACH_MSG_TYPE_STRING_C, "MACH_MSG_TYPE_STRING_C", MACH_MSG_TYPE_STRING_C, "MACH_MSG_TYPE_STRING_C", 8);
|
||||
itCheckDecl("char", itElement);
|
||||
|
||||
it = itResetType(itCopyType(itElement));
|
||||
it->itNumber = count;
|
||||
it->itVarArray = varying;
|
||||
it->itStruct = FALSE;
|
||||
it->itString = TRUE;
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
extern ipc_type_t *
|
||||
itMakeSubCountType(int count, boolean_t varying, string_t name)
|
||||
{
|
||||
ipc_type_t *it;
|
||||
ipc_type_t *itElement;
|
||||
|
||||
itElement = itShortDecl(machine_integer_size, machine_integer_name, machine_integer_size, machine_integer_name, machine_integer_bits);
|
||||
itCheckDecl("mach_msg_type_number_t", itElement);
|
||||
|
||||
it = itResetType(itCopyType(itElement));
|
||||
it->itNumber = count;
|
||||
/*
|
||||
* I cannot consider it as a Fixed array, otherwise MiG will try
|
||||
* to follow the path for efficient copy of arrays
|
||||
*/
|
||||
it->itVarArray = FALSE;
|
||||
it->itStruct = FALSE;
|
||||
it->itString = FALSE;
|
||||
it->itInLine = TRUE;
|
||||
it->itName = "mach_msg_type_number_t *";
|
||||
if (varying)
|
||||
it->itVarArray = TRUE;
|
||||
else
|
||||
/* to skip the optimized copy of fixed array: in fact we need to
|
||||
* reference each element and we also miss a user type for it */
|
||||
it->itNoOptArray = TRUE;
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
itCalculateNameInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
extern ipc_type_t *
|
||||
itMakeCountType(void)
|
||||
{
|
||||
ipc_type_t *it = itAlloc();
|
||||
|
||||
it->itName = "mach_msg_type_number_t";
|
||||
it->itInName = machine_integer_size;
|
||||
it->itInNameStr = machine_integer_name;
|
||||
it->itOutName = machine_integer_size;
|
||||
it->itOutNameStr = machine_integer_name;
|
||||
it->itSize = machine_integer_bits;
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
itCalculateNameInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
extern ipc_type_t *
|
||||
itMakePolyType(void)
|
||||
{
|
||||
ipc_type_t *it = itAlloc();
|
||||
|
||||
it->itName = "mach_msg_type_name_t";
|
||||
it->itInName = machine_integer_size;
|
||||
it->itInNameStr = machine_integer_name;
|
||||
it->itOutName = machine_integer_size;
|
||||
it->itOutNameStr = machine_integer_name;
|
||||
it->itSize = machine_integer_bits;
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
itCalculateNameInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
extern ipc_type_t *
|
||||
itMakeDeallocType(void)
|
||||
{
|
||||
ipc_type_t *it = itAlloc();
|
||||
|
||||
it->itName = "boolean_t";
|
||||
it->itInName = MACH_MSG_TYPE_BOOLEAN;
|
||||
it->itInNameStr = "MACH_MSG_TYPE_BOOLEAN";
|
||||
it->itOutName = MACH_MSG_TYPE_BOOLEAN;
|
||||
it->itOutNameStr = "MACH_MSG_TYPE_BOOLEAN";
|
||||
it->itSize = machine_integer_bits;
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
itCalculateNameInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
extern ipc_type_t *
|
||||
itNativeType(identifier_t id, boolean_t ptr, identifier_t badval)
|
||||
{
|
||||
ipc_type_t *it = itAlloc();
|
||||
|
||||
it->itInName = MACH_MSG_TYPE_BYTE;
|
||||
it->itInNameStr = "MACH_MSG_TYPE_BYTE";
|
||||
it->itOutName = MACH_MSG_TYPE_BYTE;
|
||||
it->itOutNameStr = "MACH_MSG_TYPE_BYTE";
|
||||
it->itInLine = TRUE;
|
||||
it->itNative = TRUE;
|
||||
it->itNativePointer = ptr;
|
||||
it->itServerType = id;
|
||||
it->itUserType = id;
|
||||
it->itTransType = id;
|
||||
it->itBadValue = badval;
|
||||
|
||||
itCalculateSizeInfo(it);
|
||||
itCalculateNameInfo(it);
|
||||
return it;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes the pre-defined types.
|
||||
*/
|
||||
void
|
||||
init_type(void)
|
||||
{
|
||||
u_int size;
|
||||
|
||||
size = NBBY * sizeof (natural_t);
|
||||
if (size == 32) {
|
||||
machine_integer_name = "MACH_MSG_TYPE_INTEGER_32";
|
||||
machine_integer_size = MACH_MSG_TYPE_INTEGER_32;
|
||||
}
|
||||
else if (size == 64) {
|
||||
machine_integer_name = "MACH_MSG_TYPE_INTEGER_64";
|
||||
machine_integer_size = MACH_MSG_TYPE_INTEGER_64;
|
||||
}
|
||||
else
|
||||
error("init_type unknown size %d", size);
|
||||
|
||||
machine_integer_bits = size;
|
||||
|
||||
itRetCodeType = itAlloc();
|
||||
itRetCodeType->itName = "kern_return_t";
|
||||
itRetCodeType->itInName = machine_integer_size;
|
||||
itRetCodeType->itInNameStr = machine_integer_name;
|
||||
itRetCodeType->itOutName = machine_integer_size;
|
||||
itRetCodeType->itOutNameStr = machine_integer_name;
|
||||
itRetCodeType->itSize = machine_integer_bits;
|
||||
itCalculateSizeInfo(itRetCodeType);
|
||||
itCalculateNameInfo(itRetCodeType);
|
||||
|
||||
itNdrCodeType = itAlloc();
|
||||
itNdrCodeType->itName = "NDR_record_t";
|
||||
itNdrCodeType->itInName = 0;
|
||||
itNdrCodeType->itInNameStr = "NDR_record_t";
|
||||
itNdrCodeType->itOutName = 0;
|
||||
itNdrCodeType->itOutNameStr = "NDR_record_t";
|
||||
itNdrCodeType->itSize = sizeof(NDR_record_t) * 8;
|
||||
itCalculateSizeInfo(itNdrCodeType);
|
||||
itCalculateNameInfo(itNdrCodeType);
|
||||
|
||||
itDummyType = itAlloc();
|
||||
itDummyType->itName = "char *";
|
||||
itDummyType->itInName = MACH_MSG_TYPE_UNSTRUCTURED;
|
||||
itDummyType->itInNameStr = "MACH_MSG_TYPE_UNSTRUCTURED";
|
||||
itDummyType->itOutName = MACH_MSG_TYPE_UNSTRUCTURED;
|
||||
itDummyType->itOutNameStr = "MACH_MSG_TYPE_UNSTRUCTURED";
|
||||
itDummyType->itSize = PortSize;
|
||||
itCalculateSizeInfo(itDummyType);
|
||||
itCalculateNameInfo(itDummyType);
|
||||
|
||||
itTidType = itAlloc();
|
||||
itTidType->itName = "tid_t";
|
||||
itTidType->itInName = machine_integer_size;
|
||||
itTidType->itInNameStr = machine_integer_name;
|
||||
itTidType->itOutName = machine_integer_size;
|
||||
itTidType->itOutNameStr = machine_integer_name;
|
||||
itTidType->itSize = machine_integer_bits;
|
||||
itTidType->itNumber = 6;
|
||||
itCalculateSizeInfo(itTidType);
|
||||
itCalculateNameInfo(itTidType);
|
||||
|
||||
itRequestPortType = itAlloc();
|
||||
itRequestPortType->itName = "mach_port_t";
|
||||
itRequestPortType->itInName = MACH_MSG_TYPE_COPY_SEND;
|
||||
itRequestPortType->itInNameStr = "MACH_MSG_TYPE_COPY_SEND";
|
||||
itRequestPortType->itOutName = MACH_MSG_TYPE_PORT_SEND;
|
||||
itRequestPortType->itOutNameStr = "MACH_MSG_TYPE_PORT_SEND";
|
||||
itRequestPortType->itSize = PortSize;
|
||||
itCalculateSizeInfo(itRequestPortType);
|
||||
itCalculateNameInfo(itRequestPortType);
|
||||
|
||||
itZeroReplyPortType = itAlloc();
|
||||
itZeroReplyPortType->itName = "mach_port_t";
|
||||
itZeroReplyPortType->itInName = 0;
|
||||
itZeroReplyPortType->itInNameStr = "0";
|
||||
itZeroReplyPortType->itOutName = 0;
|
||||
itZeroReplyPortType->itOutNameStr = "0";
|
||||
itZeroReplyPortType->itSize = PortSize;
|
||||
itCalculateSizeInfo(itZeroReplyPortType);
|
||||
itCalculateNameInfo(itZeroReplyPortType);
|
||||
|
||||
itRealReplyPortType = itAlloc();
|
||||
itRealReplyPortType->itName = "mach_port_t";
|
||||
itRealReplyPortType->itInName = MACH_MSG_TYPE_MAKE_SEND_ONCE;
|
||||
itRealReplyPortType->itInNameStr = "MACH_MSG_TYPE_MAKE_SEND_ONCE";
|
||||
itRealReplyPortType->itOutName = MACH_MSG_TYPE_PORT_SEND_ONCE;
|
||||
itRealReplyPortType->itOutNameStr = "MACH_MSG_TYPE_PORT_SEND_ONCE";
|
||||
itRealReplyPortType->itSize = PortSize;
|
||||
itCalculateSizeInfo(itRealReplyPortType);
|
||||
itCalculateNameInfo(itRealReplyPortType);
|
||||
|
||||
itWaitTimeType = itMakeCountType();
|
||||
itMsgOptionType = itMakeCountType();
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* Make sure return values of functions are assignable.
|
||||
******************************************************/
|
||||
void
|
||||
itCheckReturnType(identifier_t name, ipc_type_t *it)
|
||||
{
|
||||
if (!it->itStruct)
|
||||
error("type of %s is too complicated", name);
|
||||
if ((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) ||
|
||||
(it->itOutName == MACH_MSG_TYPE_POLYMORPHIC))
|
||||
error("type of %s can't be polymorphic", name);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Called by routine.c to check that request ports are
|
||||
* simple and correct ports with send rights.
|
||||
******************************************************/
|
||||
void
|
||||
itCheckRequestPortType(identifier_t name, ipc_type_t *it)
|
||||
{
|
||||
/* error("Port size = %d %d name = %s\n", PortSize, it->itSize, it->itName);
|
||||
error("server = %s user = %x\n",it->itServerType, it->itUserType);
|
||||
*/
|
||||
if (((it->itOutName != MACH_MSG_TYPE_PORT_SEND) &&
|
||||
(it->itOutName != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
|
||||
(it->itOutName != MACH_MSG_TYPE_POLYMORPHIC)) ||
|
||||
(it->itNumber != 1) ||
|
||||
(it->itSize != PortSize) ||
|
||||
!it->itInLine ||
|
||||
!it->itStruct ||
|
||||
it->itVarArray)
|
||||
error("argument %s isn't a proper request port", name);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Called by routine.c to check that reply ports are
|
||||
* simple and correct ports with send rights.
|
||||
******************************************************/
|
||||
void
|
||||
itCheckReplyPortType(identifier_t name, ipc_type_t *it)
|
||||
{
|
||||
if (((it->itOutName != MACH_MSG_TYPE_PORT_SEND) &&
|
||||
(it->itOutName != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
|
||||
(it->itOutName != MACH_MSG_TYPE_POLYMORPHIC) &&
|
||||
(it->itOutName != 0)) ||
|
||||
(it->itNumber != 1) ||
|
||||
(it->itSize != PortSize) ||
|
||||
!it->itInLine ||
|
||||
!it->itStruct ||
|
||||
it->itVarArray)
|
||||
error("argument %s isn't a proper reply port", name);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Used by routine.c to check that WaitTime is a
|
||||
* simple bit machine_integer_bits integer.
|
||||
******************************************************/
|
||||
void
|
||||
itCheckIntType(identifier_t name, ipc_type_t *it)
|
||||
{
|
||||
if ((it->itInName != machine_integer_size) ||
|
||||
(it->itOutName != machine_integer_size) ||
|
||||
(it->itNumber != 1) ||
|
||||
(it->itSize != machine_integer_bits) ||
|
||||
!it->itInLine ||
|
||||
!it->itStruct ||
|
||||
it->itVarArray)
|
||||
error("argument %s isn't a proper integer", name);
|
||||
}
|
||||
|
||||
void
|
||||
itCheckTokenType(identifier_t name, ipc_type_t *it)
|
||||
{
|
||||
if (it->itMigInLine || it->itNoOptArray || it->itString ||
|
||||
it->itTypeSize != 8 || !it->itInLine || !it->itStruct ||
|
||||
it->itVarArray || it->itPortType)
|
||||
error("argument %s isn't a proper Token", name);
|
||||
|
||||
}
|
||||
270
tools/mig/type.h
Normal file
270
tools/mig/type.h
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/* HISTORY
|
||||
* 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Extensive revamping. Added polymorphic arguments.
|
||||
* Allow multiple variable-sized inline arguments in messages.
|
||||
*
|
||||
* 16-Nov-87 David Golub (dbg) at Carnegie-Mellon University
|
||||
* Changed itVarArrayDecl to take a 'max' parameter.
|
||||
* Added itDestructor.
|
||||
*
|
||||
* 18-Aug-87 Mary Thompson @ Carnegie Mellon
|
||||
* Added itPortType
|
||||
* Added itTidType
|
||||
*/
|
||||
|
||||
#ifndef _TYPE_H
|
||||
#define _TYPE_H
|
||||
|
||||
#include <mach/boolean.h>
|
||||
#include "strdefs.h"
|
||||
|
||||
#ifdef linux
|
||||
#include <linux/types.h>
|
||||
#else /* linux */
|
||||
#include <sys/types.h>
|
||||
#endif /* linux */
|
||||
typedef u_int ipc_flags_t;
|
||||
|
||||
/*
|
||||
* MIG built-in types
|
||||
*/
|
||||
#define MACH_MSG_TYPE_UNSTRUCTURED 0
|
||||
#define MACH_MSG_TYPE_BIT 0
|
||||
#define MACH_MSG_TYPE_BOOLEAN 0
|
||||
#define MACH_MSG_TYPE_INTEGER_8 9
|
||||
#define MACH_MSG_TYPE_INTEGER_16 1
|
||||
#define MACH_MSG_TYPE_INTEGER_32 2
|
||||
#define MACH_MSG_TYPE_INTEGER_64 3
|
||||
#define MACH_MSG_TYPE_CHAR 8
|
||||
#define MACH_MSG_TYPE_BYTE 9
|
||||
#define MACH_MSG_TYPE_REAL_32 10
|
||||
#define MACH_MSG_TYPE_REAL_64 11
|
||||
#define MACH_MSG_TYPE_STRING 12
|
||||
#define MACH_MSG_TYPE_STRING_C 12
|
||||
|
||||
#define flNone (0x00)
|
||||
#define flPhysicalCopy (0x01) /* Physical Copy specified */
|
||||
#define flOverwrite (0x02) /* Overwrite mode specified */
|
||||
#define flDealloc (0x04) /* Dealloc specified */
|
||||
#define flNotDealloc (0x08) /* NotDealloc specified */
|
||||
#define flMaybeDealloc (0x10) /* Dealloc[] specified */
|
||||
#define flSameCount (0x20) /* SamCount specified, used by co-bounded arrays */
|
||||
#define flCountInOut (0x40) /* CountInOut specified */
|
||||
#define flRetCode (0x80) /* RetCode specified */
|
||||
#define flAuto (0x100) /* Will not be referenced by server after RPC */
|
||||
#define flConst (0x200) /* Will not be modified by server during RPC */
|
||||
|
||||
typedef enum dealloc {
|
||||
d_NO, /* do not deallocate */
|
||||
d_YES, /* always deallocate */
|
||||
d_MAYBE /* deallocate according to parameter */
|
||||
} dealloc_t;
|
||||
|
||||
/* Convert dealloc_t to TRUE/FALSE */
|
||||
#define strdealloc(d) (strbool(d == d_YES))
|
||||
|
||||
/*
|
||||
* itName and itNext are internal fields (not used for code generation).
|
||||
* They are only meaningful for types entered into the symbol table.
|
||||
* The symbol table is a simple self-organizing linked list.
|
||||
*
|
||||
* The function itCheckDecl checks & fills in computed information.
|
||||
* Every type actually used (pointed at by argType) is so processed.
|
||||
*
|
||||
* The itInName, itOutName, itSize, itNumber, fields correspond directly
|
||||
* to mach_msg_type_t fields.
|
||||
* For out-of-line variable sized types, itNumber is zero. For
|
||||
* in-line variable sized types, itNumber is the maximum size of the
|
||||
* array. itInName is the name value supplied to the kernel,
|
||||
* and itOutName is the name value received from the kernel.
|
||||
* When the type describes a MACH port, either or both may be
|
||||
* MACH_MSG_TYPE_POLYMORPHIC, indicating a "polymorphic" name.
|
||||
* For itInName, this means the user supplies the value with an argument.
|
||||
* For itOutName, this means the value is returned in an argument.
|
||||
*
|
||||
* The itInNameStr and itOutNameStr fields contain "printing" versions
|
||||
* of the itInName and itOutName values. The mapping from number->string
|
||||
* is not into (eg, MACH_MSG_TYPE_UNSTRUCTURED/MACH_MSG_TYPE_BOOLEAN/
|
||||
* MACH_MSG_TYPE_BIT). These fields are used for code-generation and
|
||||
* pretty-printing.
|
||||
*
|
||||
* itTypeSize is the calculated size of the C type, in bytes.
|
||||
* itPadSize is the size of any padded needed after the data field.
|
||||
* itMinTypeSize is the minimum size of the data field, including padding.
|
||||
* For variable-length inline data, it is zero.
|
||||
*
|
||||
* itUserType, itServerType, itTransType are the C types used in
|
||||
* code generation. itUserType is the C type passed to the user-side stub
|
||||
* and used for msg declarations in the user-side stub. itServerType
|
||||
* is the C type used for msg declarations in the server-side stub.
|
||||
* itTransType is the C type passed to the server function by the
|
||||
* server-side stub. Normally it differs from itServerType only when
|
||||
* translation functions are defined.
|
||||
*
|
||||
* itInTrans and itOutTrans are translation functions. itInTrans
|
||||
* takes itServerType values and returns itTransType values. itOutTrans
|
||||
* takes itTransType vaulues and returns itServerType values.
|
||||
* itDestructor is a finalization function applied to In arguments
|
||||
* after the server-side stub calls the server function. It takes
|
||||
* itTransType values. Any combination of these may be defined.
|
||||
*
|
||||
* The following type specification syntax modifies these values:
|
||||
* type new = old
|
||||
* ctype: name // itUserType and itServerType
|
||||
* cusertype: itUserType
|
||||
* cservertype: itServerType
|
||||
* intran: itTransType itInTrans(itServerType)
|
||||
* outtran: itServerType itOutTrans(itTransType)
|
||||
* destructor: itDestructor(itTransType);
|
||||
*
|
||||
* At most one of itStruct and itString should be TRUE. If both are
|
||||
* false, then this is assumed to be an array type (msg data is passed
|
||||
* by reference). If itStruct is TRUE, then msg data is passed by value
|
||||
* and can be assigned with =. If itString is TRUE, then the msg_data
|
||||
* is a null-terminated string, assigned with strncpy. The itNumber
|
||||
* value is a maximum length for the string; the msg field always
|
||||
* takes up this much space.
|
||||
* NoOptArray has been introduced for the cases where the special
|
||||
* code generated for array assignments would not work (either because
|
||||
* there is not a ctype (array of automagically generated MiG variables)
|
||||
* or because we need to reference the single elements of the array
|
||||
* (array of variable sized ool regions).
|
||||
*
|
||||
* itVarArray means this is a variable-sized array. If it is inline,
|
||||
* then itStruct and itString are FALSE. If it is out-of-line, then
|
||||
* itStruct is TRUE (because pointers can be assigned).
|
||||
*
|
||||
* itMigInLine means this is an indefinite-length array. Although the
|
||||
* argument was not specified as out-of-line, MIG will send it anyway
|
||||
* os an out-of-line.
|
||||
*
|
||||
* itUserKPDType (itServerKPDType) identify the type of Kernel Processed
|
||||
* Data that we must deal with: it can be either "mach_msg_port_descriptor_t"
|
||||
* or "mach_msg_ool_ports_descriptor_t" or "mach_msg_ool_descriptor_t".
|
||||
*
|
||||
* itKPD_Number is used any time a single argument require more than
|
||||
* one Kernel Processed Data entry: i.e., an in-line array of ports, an array
|
||||
* of pointers (out-of-line data)
|
||||
*
|
||||
* itElement points to any substructure that the type may have.
|
||||
* It is only used with variable-sized array types.
|
||||
*/
|
||||
|
||||
typedef struct ipc_type
|
||||
{
|
||||
identifier_t itName; /* Mig's name for this type */
|
||||
struct ipc_type *itNext; /* next type in symbol table */
|
||||
|
||||
u_int itTypeSize; /* size of the C type */
|
||||
u_int itPadSize; /* amount of padding after data */
|
||||
u_int itMinTypeSize; /* minimal amount of space occupied by data */
|
||||
|
||||
u_int itInName; /* name supplied to kernel in sent msg */
|
||||
u_int itOutName; /* name in received msg */
|
||||
u_int itSize;
|
||||
u_int itNumber;
|
||||
u_int itKPD_Number; /* number of Kernel Processed Data entries */
|
||||
boolean_t itInLine;
|
||||
boolean_t itMigInLine; /* MiG presents data as InLine, although it is sent OOL */
|
||||
boolean_t itPortType;
|
||||
|
||||
string_t itInNameStr; /* string form of itInName */
|
||||
string_t itOutNameStr; /* string form of itOutName */
|
||||
|
||||
boolean_t itStruct;
|
||||
boolean_t itString;
|
||||
boolean_t itVarArray;
|
||||
boolean_t itNoOptArray;
|
||||
boolean_t itNative; /* User specified a native (C) type. */
|
||||
boolean_t itNativePointer;/* The user will pass a pointer to the */
|
||||
/* native C type. */
|
||||
|
||||
struct ipc_type *itElement; /* may be NULL */
|
||||
|
||||
identifier_t itUserType;
|
||||
identifier_t itServerType;
|
||||
identifier_t itTransType;
|
||||
|
||||
identifier_t itKPDType; /* descriptors for KPD type of arguments */
|
||||
|
||||
identifier_t itInTrans; /* may be NULL */
|
||||
identifier_t itOutTrans; /* may be NULL */
|
||||
identifier_t itDestructor;/* may be NULL */
|
||||
identifier_t itBadValue; /* Excluded value for PointerToIfNot. May
|
||||
be NULL. */
|
||||
u_int itOOL_Number;
|
||||
} ipc_type_t;
|
||||
|
||||
enum {
|
||||
ConsumeOnSendErrorNone,
|
||||
ConsumeOnSendErrorTimeout,
|
||||
ConsumeOnSendErrorAny,
|
||||
};
|
||||
|
||||
|
||||
#define itNULL ((ipc_type_t *) 0)
|
||||
|
||||
#define itWordAlign sizeof(natural_t)
|
||||
|
||||
extern ipc_type_t *itLookUp(identifier_t name);
|
||||
extern void itInsert(identifier_t name, ipc_type_t *it);
|
||||
extern void itTypeDecl(identifier_t name, ipc_type_t *it);
|
||||
|
||||
extern ipc_type_t *itShortDecl(u_int inname, string_t instr,
|
||||
u_int outname, string_t outstr,
|
||||
u_int dfault);
|
||||
extern ipc_type_t *itPrevDecl(identifier_t name);
|
||||
extern ipc_type_t *itResetType(ipc_type_t *it);
|
||||
extern ipc_type_t *itVarArrayDecl(u_int number, ipc_type_t *it);
|
||||
extern ipc_type_t *itArrayDecl(u_int number, ipc_type_t *it);
|
||||
extern ipc_type_t *itPtrDecl(ipc_type_t *it);
|
||||
extern ipc_type_t *itStructDecl(u_int number, ipc_type_t *it);
|
||||
extern ipc_type_t *itCStringDecl(int count, boolean_t varying);
|
||||
extern ipc_type_t *itNativeType(identifier_t CType, boolean_t pointer,
|
||||
identifier_t NotVal);
|
||||
|
||||
extern ipc_type_t *itRetCodeType;
|
||||
extern ipc_type_t *itNdrCodeType;
|
||||
extern ipc_type_t *itDummyType;
|
||||
extern ipc_type_t *itTidType;
|
||||
extern ipc_type_t *itRequestPortType;
|
||||
extern ipc_type_t *itZeroReplyPortType;
|
||||
extern ipc_type_t *itRealReplyPortType;
|
||||
extern ipc_type_t *itWaitTimeType;
|
||||
extern ipc_type_t *itMsgOptionType;
|
||||
extern ipc_type_t *itMakeCountType(void);
|
||||
extern ipc_type_t *itMakeSubCountType(int count, boolean_t varying, string_t name);
|
||||
extern ipc_type_t *itMakePolyType(void);
|
||||
extern ipc_type_t *itMakeDeallocType(void);
|
||||
|
||||
extern void init_type(void);
|
||||
|
||||
extern void itCheckReturnType(identifier_t name, ipc_type_t *it);
|
||||
extern void itCheckRequestPortType(identifier_t name, ipc_type_t *it);
|
||||
extern void itCheckReplyPortType(identifier_t name, ipc_type_t *it);
|
||||
extern void itCheckIntType(identifier_t name, ipc_type_t *it);
|
||||
extern void itCheckTokenType(identifier_t name, ipc_type_t *it);
|
||||
|
||||
#endif /* _TYPE_H */
|
||||
3224
tools/mig/user.c
Normal file
3224
tools/mig/user.c
Normal file
File diff suppressed because it is too large
Load Diff
1043
tools/mig/utils.c
Normal file
1043
tools/mig/utils.c
Normal file
File diff suppressed because it is too large
Load Diff
140
tools/mig/utils.h
Normal file
140
tools/mig/utils.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2002, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
/*
|
||||
* HISTORY
|
||||
* 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Extensive revamping. Added polymorphic arguments.
|
||||
* Allow multiple variable-sized inline arguments in messages.
|
||||
*
|
||||
* 28-May-87 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Created.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_H
|
||||
#define _UTILS_H
|
||||
|
||||
/* definitions used by the Event Logger */
|
||||
|
||||
#define LOG_USER 0
|
||||
#define LOG_SERVER 1
|
||||
|
||||
#define LOG_REQUEST 0
|
||||
#define LOG_REPLY 1
|
||||
|
||||
/* stuff used by more than one of header.c, user.c, server.c */
|
||||
|
||||
extern void WriteMigExternal(FILE *file);
|
||||
extern void WriteMigInternal(FILE *file);
|
||||
|
||||
extern void WriteImport(FILE *file, string_t filename);
|
||||
extern void WriteRCSDecl( FILE *file, identifier_t name, string_t rcs );
|
||||
extern void WriteBogusDefines( FILE *file );
|
||||
|
||||
extern void WriteList( FILE *file, argument_t *args,
|
||||
void (*func)(FILE *file, argument_t *arg),
|
||||
u_int mask, char *between, char *after );
|
||||
|
||||
extern void WriteReverseList( FILE *file, argument_t *args,
|
||||
void (*func)(FILE *file, argument_t *arg),
|
||||
u_int mask, char *between, char *after );
|
||||
|
||||
/* good as arguments to WriteList */
|
||||
extern void WriteNameDecl( FILE *file, argument_t *arg );
|
||||
extern void WriteUserVarDecl( FILE *file, argument_t *arg );
|
||||
extern void WriteServerVarDecl( FILE *file, argument_t *arg );
|
||||
extern void WriteTemplateDeclIn( FILE *file, argument_t *arg );
|
||||
extern void WriteTemplateDeclOut( FILE *file, argument_t *arg );
|
||||
extern void WriteCheckDecl( FILE *file, argument_t *arg );
|
||||
|
||||
extern char *ReturnTypeStr( routine_t *rt );
|
||||
|
||||
extern char *FetchUserType( ipc_type_t *it );
|
||||
extern char *FetchServerType( ipc_type_t *it );
|
||||
extern char *FetchKPDType( ipc_type_t *it );
|
||||
extern void WriteKPDFieldDecl(FILE *file, argument_t *arg);
|
||||
|
||||
extern void WriteFieldDeclPrim( FILE *file, argument_t *arg, char *(*tfunc)(ipc_type_t *it) );
|
||||
|
||||
extern void WriteStructDecl( FILE *file, argument_t *args,
|
||||
void (*func)(FILE *file, argument_t *arg),
|
||||
u_int mask, char *name,
|
||||
boolean_t simple, boolean_t trailer,
|
||||
boolean_t isuser,
|
||||
boolean_t template_only );
|
||||
|
||||
extern void WriteStaticDecl( FILE *file, argument_t *arg );
|
||||
|
||||
extern void WriteCopyType(FILE *file, ipc_type_t *it, boolean_t mig_allocated_buf, char *left, char *right, ...);
|
||||
|
||||
extern void WriteCopyArg(FILE *file, argument_t *arg, boolean_t mig_allocated_buf, char *left, char *right, ...);
|
||||
|
||||
extern void WriteLogMsg( FILE *file, routine_t *rt, int where, int what );
|
||||
|
||||
extern void WriteCheckTrailerHead( FILE *file, routine_t *rt, boolean_t isuser );
|
||||
|
||||
extern void WriteCheckTrailerSize( FILE *file, boolean_t isuser, argument_t *arg );
|
||||
|
||||
extern void WriteReturnMsgError( FILE *file, routine_t *rt, boolean_t isuser, argument_t *arg, string_t error );
|
||||
|
||||
extern void WriteRPCRoutineDescriptor( FILE *file, routine_t *rt, int arg_count, int descr_count, string_t stub_routine, string_t sig_array );
|
||||
|
||||
extern void WriteRPCRoutineArgDescriptor( FILE *file, routine_t *rt );
|
||||
|
||||
extern void WriteRequestTypes( FILE *file, statement_t *stats);
|
||||
extern void WriteCheckRequests( FILE *file, statement_t *stats);
|
||||
extern void WriteUserRequestUnion( FILE *file, statement_t *stats );
|
||||
extern void WriteServerRequestUnion( FILE *file, statement_t *stats );
|
||||
|
||||
extern void WriteReplyTypes( FILE *file, statement_t *stats);
|
||||
extern void WriteCheckReplies( FILE *file, statement_t *stats);
|
||||
extern void WriteUserReplyUnion( FILE *file, statement_t *stats );
|
||||
extern void WriteServerReplyUnion( FILE *file, statement_t *stats );
|
||||
|
||||
extern void WriteNDRConvertArgDecl( FILE *file, argument_t *arg, char *convert, char *dir);
|
||||
|
||||
#endif /* _UTILS_H */
|
||||
78
tools/mig/write.h
Normal file
78
tools/mig/write.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
/*
|
||||
* HISTORY
|
||||
* 07-Apr-89 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Extensive revamping. Added polymorphic arguments.
|
||||
* Allow multiple variable-sized inline arguments in messages.
|
||||
*
|
||||
* 27-May-87 Richard Draves (rpd) at Carnegie-Mellon University
|
||||
* Created.
|
||||
*/
|
||||
|
||||
#ifndef _WRITE_H
|
||||
#define _WRITE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "statement.h"
|
||||
|
||||
extern void WriteUserHeader( FILE *file, statement_t *stats );
|
||||
extern void WriteServerHeader( FILE *file, statement_t *stats );
|
||||
extern void WriteServerRoutine( FILE *file, routine_t *rt );
|
||||
extern void WriteInternalHeader( FILE *file, statement_t *stats );
|
||||
extern void WriteDefinesHeader( FILE *file, statement_t *stats );
|
||||
extern void WriteUser( FILE *file, statement_t *stats );
|
||||
extern void WriteUserIndividual( statement_t *stats );
|
||||
extern void WriteServer( FILE *file, statement_t *stats );
|
||||
extern void WriteIncludes( FILE *file, boolean_t isuser, boolean_t is_def );
|
||||
extern void WriteImplImports( FILE *file, statement_t *stats, boolean_t isuser );
|
||||
extern void WriteApplDefaults( FILE *file, char *dir );
|
||||
extern void WriteApplMacro( FILE *file, char *dir, char *when, routine_t *rt );
|
||||
extern void WriteBogusServerRoutineAnnotationDefine( FILE *file );
|
||||
|
||||
#endif /* _WRITE_H */
|
||||
Reference in New Issue
Block a user