Changed the way the syscall infos are generated. We no longer include the
preprocessed <syscalls.h> header in sources compiled for the build platform. Instead we're generating macros for the return type and parameter type sizes via the CreateAsmStructOffsetsHeader rule (no template magic anymore) and thus get a clear separation of host and target code, resulting in better portability (although surprisingly enough the build already worked on 64 bit hosts). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34323 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,17 +1,41 @@
|
||||
SubDir HAIKU_TOP src tools gensyscalls ;
|
||||
|
||||
SubDirHdrs [ FDirName $(SUBDIR) arch $(TARGET_ARCH) ] ;
|
||||
|
||||
|
||||
# What want to do here is analyze the <syscalls.h> header and generate headers
|
||||
# and sources containing information about the syscalls (like what parameters
|
||||
# of what sizes and types they take, etc.) which will be used in other places
|
||||
# (e.g. the kernel code or the strace tool).
|
||||
#
|
||||
# The strategy to achieve this is:
|
||||
# * Preprocess the <syscalls.h> header, so that it is easier to parse.
|
||||
# * Feed the preprocessed header to the gensyscallinfos tool. It will generate
|
||||
# a source file, gensyscalls_infos.cpp, which implements a function that
|
||||
# builds a table with all the syscall info information we need. The source
|
||||
# file needs specific infos about sizes of types, which aren't easily
|
||||
# available. That's why gensyscallinfos also generates a source file which
|
||||
# via the CreateAsmStructOffsetsHeader rule is turned into a header with
|
||||
# macro definitions for those type size. The header is included by
|
||||
# gensyscalls_infos.cpp.
|
||||
# * gensyscalls.cpp and the generated gensyscalls_infos.cpp are compiled into
|
||||
# the gensyscalls tool.
|
||||
# * gensyscalls has options to generate the various output files:
|
||||
# - <syscalls>syscalls.S.inc: Used to define the syscall functions in libroot.
|
||||
# - <syscalls>syscall_dispatcher.h: Big "switch" statement for the syscall
|
||||
# dispatcher in the kernel.
|
||||
# - <syscalls>syscall_numbers.h: Macro definitions assigning indices to the
|
||||
# syscalls.
|
||||
# - <syscalls>syscall_table.h: An array with syscall information in the
|
||||
# kernel. Used for dispatching syscalls e.g. for x86.
|
||||
# - <syscalls>strace_syscalls.h: Syscall information needed by strace.
|
||||
|
||||
|
||||
# preprocess the syscalls header
|
||||
|
||||
rule PreprocessSyscalls
|
||||
{
|
||||
# PreprocessSyscalls <preprocessedHeader> : <header> : <parsable> ;
|
||||
#
|
||||
local parsable = $(3) ;
|
||||
local parsableDefine ;
|
||||
|
||||
if $(parsable) {
|
||||
parsableDefine = GEN_SYSCALL_INFOS_PROCESSING ;
|
||||
}
|
||||
# PreprocessSyscalls <preprocessedHeader> : <header> ;
|
||||
|
||||
Depends $(<) : $(>) ;
|
||||
|
||||
@@ -30,7 +54,7 @@ rule PreprocessSyscalls
|
||||
HDRSEARCH on $(>) = $(headers) $(sysHeaders) $(STDHDRS) ;
|
||||
HDRGRIST on $(>) = $(HDRGRIST) ;
|
||||
|
||||
DEFINES on $(<) += $(HAIKU_DEFINES) $(parsableDefine) ;
|
||||
DEFINES on $(<) += $(HAIKU_DEFINES) GEN_SYSCALL_INFOS_PROCESSING ;
|
||||
|
||||
CCFLAGS on $(<) += $(HAIKU_CCFLAGS) $(SUBDIRCCFLAGS) $(OPTIM) ;
|
||||
CCHDRS on $(<) = [ FIncludes $(headers) : $(HAIKU_LOCAL_INCLUDES_OPTION) ]
|
||||
@@ -47,15 +71,11 @@ actions PreprocessSyscalls
|
||||
local syscallsHeader = [ FGristFiles syscalls.h ] ;
|
||||
SEARCH on $(syscallsHeader) = [ FDirName $(HAIKU_TOP) headers private system ] ;
|
||||
|
||||
# We generate two preprocessed headers. One for parsing by gensyscallinfos
|
||||
# (it contains #pragmas) and one for inclusion by the generated
|
||||
# gensyscalls_infos.cpp.
|
||||
# Generate the preprocessed syscalls.h header. It will be parsed by
|
||||
# gensyscallinfos (it contains marker #pragmas).
|
||||
local syscallsHeaderPPParsable = [ FGristFiles syscalls.h.pp.parsable ] ;
|
||||
local syscallsHeaderPP = [ FGristFiles syscalls.h.pp ] ;
|
||||
MakeLocateArch $(syscallsHeaderPPParsable) $(syscallsHeaderPP) ;
|
||||
|
||||
PreprocessSyscalls $(syscallsHeaderPPParsable) : $(syscallsHeader) : true ;
|
||||
PreprocessSyscalls $(syscallsHeaderPP) : $(syscallsHeader) ;
|
||||
MakeLocateArch $(syscallsHeaderPPParsable) ;
|
||||
PreprocessSyscalls $(syscallsHeaderPPParsable) : $(syscallsHeader) ;
|
||||
|
||||
|
||||
# build gensyscallinfos
|
||||
@@ -66,35 +86,45 @@ BuildPlatformMain gensyscallinfos
|
||||
;
|
||||
|
||||
|
||||
# generate the syscall infos source file
|
||||
# generate the syscall infos source file and the source for the header it
|
||||
# includes
|
||||
|
||||
local syscallInfos = [ FGristFiles gensyscalls_infos.cpp ] ;
|
||||
MakeLocateArch $(syscallInfos) ;
|
||||
local syscallTypesSizesSource = [ FGristFiles syscall_types_sizes.h.cpp ] ;
|
||||
local syscallTypesSizes = [ FGristFiles syscall_types_sizes.h ] ;
|
||||
MakeLocateArch $(syscallInfos) $(syscallTypesSizesSource) $(syscallTypesSizes) ;
|
||||
|
||||
rule GenSyscallInfos {
|
||||
rule GenSyscallInfos
|
||||
{
|
||||
Depends $(1) : gensyscallinfos $(2) ;
|
||||
GenSyscallInfos1 $(1) : gensyscallinfos $(2) ;
|
||||
}
|
||||
|
||||
actions GenSyscallInfos1 {
|
||||
actions GenSyscallInfos1
|
||||
{
|
||||
$(2[1]) $(2[2]) $(1)
|
||||
}
|
||||
|
||||
GenSyscallInfos $(syscallInfos) : $(syscallsHeaderPPParsable) ;
|
||||
GenSyscallInfos $(syscallInfos) $(syscallTypesSizesSource)
|
||||
: $(syscallsHeaderPPParsable) ;
|
||||
|
||||
SubDirHdrs [ FDirName $(SUBDIR) arch $(TARGET_ARCH) ] ;
|
||||
TARGET_HDRS on $(syscallTypesSizes)
|
||||
= [ on $(syscallTypesSizes) return $(TARGET_HDRS) ]
|
||||
$(TARGET_PRIVATE_SYSTEM_HEADERS) ;
|
||||
CreateAsmStructOffsetsHeader $(syscallTypesSizes) : $(syscallTypesSizesSource) ;
|
||||
|
||||
#Includes $(syscallInfos) : $(syscallTypesSizes) ;
|
||||
# explicitly tell jam about the inclusion of the generated header
|
||||
Depends $(syscallInfos:S=$(SUFOBJ)) : $(syscallTypesSizes) ;
|
||||
# NOTE: Jam messes up the "Includes" declaration, so we have to declare
|
||||
# the dependency more directly.
|
||||
|
||||
|
||||
# build gensyscalls
|
||||
|
||||
ObjectDefines $(syscallInfos) : HAIKU_BUILD_COMPATIBILITY_H ;
|
||||
# Prevent the inclusion of HaikuBuildCompatibility.h. TODO: Very hacky!
|
||||
BuildPlatformMain gensyscalls : gensyscalls.cpp $(syscallInfos) ;
|
||||
LinkAgainst gensyscalls : $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) ;
|
||||
|
||||
# Explicitly tell jam that gensyscalls.cpp includes the generated header.
|
||||
Includes [ FGristFiles gensyscalls.cpp ] : $(syscallsHeaderPP) ;
|
||||
|
||||
|
||||
# generate the output files
|
||||
|
||||
@@ -106,53 +136,20 @@ MakeLocate <syscalls>syscall_numbers.h : [ FDirName $(dir) system kernel ] ;
|
||||
MakeLocate <syscalls>syscall_table.h : [ FDirName $(dir) system kernel ] ;
|
||||
MakeLocate <syscalls>strace_syscalls.h : [ FDirName $(dir) bin debug strace ] ;
|
||||
|
||||
rule GenSyscallsFile {
|
||||
Depends $(1) : gensyscalls ;
|
||||
GenSyscallsFile1 $(1) : gensyscalls ;
|
||||
rule GenSyscallsFile file : option
|
||||
{
|
||||
GENSYSCALLS_FILE_OPTION on $(file) = $(option) ;
|
||||
Depends $(file) : gensyscalls ;
|
||||
GenSyscallsFile1 $(file) : gensyscalls ;
|
||||
}
|
||||
|
||||
actions GenSyscallsFile1 {
|
||||
$(2[1]) -c $(1)
|
||||
actions GenSyscallsFile1
|
||||
{
|
||||
$(2[1]) $(GENSYSCALLS_FILE_OPTION) $(1)
|
||||
}
|
||||
|
||||
rule GenSyscallsDispatcher {
|
||||
Depends $(1) : gensyscalls ;
|
||||
GenSyscallsDispatcher1 $(1) : gensyscalls ;
|
||||
}
|
||||
|
||||
actions GenSyscallsDispatcher1 {
|
||||
$(2[1]) -d $(1)
|
||||
}
|
||||
|
||||
rule GenSyscallsNumbers {
|
||||
Depends $(1) : gensyscalls ;
|
||||
GenSyscallsNumbers1 $(1) : gensyscalls ;
|
||||
}
|
||||
|
||||
actions GenSyscallsNumbers1 {
|
||||
$(2[1]) -n $(1)
|
||||
}
|
||||
|
||||
rule GenSyscallsTable {
|
||||
Depends $(1) : gensyscalls ;
|
||||
GenSyscallsTable1 $(1) : gensyscalls ;
|
||||
}
|
||||
|
||||
actions GenSyscallsTable1 {
|
||||
$(2[1]) -t $(1)
|
||||
}
|
||||
|
||||
rule GenSyscallsSTrace {
|
||||
Depends $(1) : gensyscalls ;
|
||||
GenSyscallsSTrace1 $(1) : gensyscalls ;
|
||||
}
|
||||
|
||||
actions GenSyscallsSTrace1 {
|
||||
$(2[1]) -s $(1)
|
||||
}
|
||||
|
||||
GenSyscallsFile <syscalls>syscalls.S.inc ;
|
||||
GenSyscallsDispatcher <syscalls>syscall_dispatcher.h ;
|
||||
GenSyscallsNumbers <syscalls>syscall_numbers.h ;
|
||||
GenSyscallsTable <syscalls>syscall_table.h ;
|
||||
GenSyscallsSTrace <syscalls>strace_syscalls.h ;
|
||||
GenSyscallsFile <syscalls>syscalls.S.inc : -c ;
|
||||
GenSyscallsFile <syscalls>syscall_dispatcher.h : -d ;
|
||||
GenSyscallsFile <syscalls>syscall_numbers.h : -n ;
|
||||
GenSyscallsFile <syscalls>syscall_table.h : -t ;
|
||||
GenSyscallsFile <syscalls>strace_syscalls.h : -s ;
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#include "arch/generic/generic_gensyscalls.h"
|
||||
#define SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE int
|
||||
#define SYSCALL_PARAMETER_ALIGNMENT_TYPE int
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// Included by gensyscalls.
|
||||
|
||||
typedef int AlignmentType;
|
||||
static const char* kAlignmentType = "int";
|
||||
static const int kAlignment = sizeof(AlignmentType);
|
||||
|
||||
// ReturnTypeCreator
|
||||
template<typename T>
|
||||
class ReturnTypeCreator {
|
||||
public:
|
||||
static void Create(Syscall* syscall, const char* name)
|
||||
{
|
||||
int size = sizeof(T);
|
||||
int usedSize = align_to_type<AlignmentType>(size);
|
||||
const char* alignmentType
|
||||
= (size != usedSize && size < kAlignment ? kAlignmentType : 0);
|
||||
|
||||
syscall->SetReturnType(name, size, usedSize, alignmentType);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class ReturnTypeCreator<void> {
|
||||
public:
|
||||
static void Create(Syscall* syscall, const char* name)
|
||||
{
|
||||
syscall->SetReturnType(name, 0, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
// ParameterCreator
|
||||
template<typename T>
|
||||
class ParameterCreator {
|
||||
public:
|
||||
static void Create(Syscall* syscall, const char* typeName,
|
||||
const char* parameterName)
|
||||
{
|
||||
// compute offset
|
||||
int offset = 0;
|
||||
if (Parameter* previous = syscall->LastParameter())
|
||||
offset = previous->Offset() + previous->UsedSize();
|
||||
|
||||
int size = sizeof(T);
|
||||
int usedSize = align_to_type<AlignmentType>(size);
|
||||
const char* alignmentType
|
||||
= (size != usedSize && size < kAlignment ? kAlignmentType : 0);
|
||||
|
||||
syscall->AddParameter(typeName, parameterName, size, usedSize, offset,
|
||||
alignmentType);
|
||||
}
|
||||
};
|
||||
@@ -1 +1,2 @@
|
||||
#include "arch/generic/generic_gensyscalls.h"
|
||||
#define SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE int
|
||||
#define SYSCALL_PARAMETER_ALIGNMENT_TYPE int
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#include "arch/generic/generic_gensyscalls.h"
|
||||
#define SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE int
|
||||
#define SYSCALL_PARAMETER_ALIGNMENT_TYPE int
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#include "arch/generic/generic_gensyscalls.h"
|
||||
#define SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE int
|
||||
#define SYSCALL_PARAMETER_ALIGNMENT_TYPE int
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#include "arch/generic/generic_gensyscalls.h"
|
||||
#define SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE int
|
||||
#define SYSCALL_PARAMETER_ALIGNMENT_TYPE int
|
||||
|
||||
@@ -15,9 +15,17 @@
|
||||
|
||||
#include "gensyscalls_common.h"
|
||||
|
||||
#include "arch_gensyscalls.h"
|
||||
// for the alignment type macros (only for the type names)
|
||||
|
||||
|
||||
// macro trickery to create a string literal
|
||||
#define MAKE_STRING(x) #x
|
||||
#define EVAL_MACRO(macro, x) macro(x)
|
||||
|
||||
|
||||
const char* kUsage =
|
||||
"Usage: gensyscallinfos <header> <syscall infos>\n"
|
||||
"Usage: gensyscallinfos <header> <syscall infos> <syscall types sizes>\n"
|
||||
"\n"
|
||||
"Given the (preprocessed) header file that defines the syscall prototypes "
|
||||
"the\n"
|
||||
@@ -30,7 +38,11 @@ const char* kUsage =
|
||||
" syscall prototypes.\n"
|
||||
" <syscall infos> - Output: The syscall infos source file needed "
|
||||
"to\n"
|
||||
" build gensyscalls.";
|
||||
" build gensyscalls.\n"
|
||||
" <syscall types sizes> - Output: A source file that will by another "
|
||||
"build\n"
|
||||
" step turned into a header file included by\n"
|
||||
" <syscall infos>.\n";
|
||||
|
||||
|
||||
static void
|
||||
@@ -285,12 +297,13 @@ public:
|
||||
print_usage(false);
|
||||
return 0;
|
||||
}
|
||||
if (argc != 3) {
|
||||
if (argc != 4) {
|
||||
print_usage(true);
|
||||
return 1;
|
||||
}
|
||||
_ParseSyscalls(argv[1]);
|
||||
_WriteSyscallInfoFile(argv[2]);
|
||||
_WriteSyscallTypeSizes(argv[3]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -335,7 +348,19 @@ private:
|
||||
|
||||
// write preamble
|
||||
file << "#include \"gensyscalls.h\"" << endl;
|
||||
file << "#include \"syscalls.h.pp\"" << endl;
|
||||
file << "#include \"syscall_types_sizes.h\"" << endl;
|
||||
file << endl;
|
||||
|
||||
file << "const char* const kReturnTypeAlignmentType = \""
|
||||
EVAL_MACRO(MAKE_STRING, SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE)
|
||||
<< "\";" << endl;
|
||||
file << "const char* const kParameterAlignmentType = \""
|
||||
EVAL_MACRO(MAKE_STRING, SYSCALL_PARAMETER_ALIGNMENT_TYPE)
|
||||
<< "\";" << endl;
|
||||
file << "const int kReturnTypeAlignmentSize = "
|
||||
"SYSCALL_RETURN_TYPE_ALIGNMENT_SIZE;" << endl;
|
||||
file << "const int kParameterAlignmentSize = "
|
||||
"SYSCALL_PARAMETER_ALIGNMENT_SIZE;" << endl;
|
||||
file << endl;
|
||||
|
||||
file << "SyscallVector* create_syscall_vector() {" << endl;
|
||||
@@ -355,20 +380,22 @@ private:
|
||||
|
||||
const Type& returnType = syscall.GetReturnType();
|
||||
|
||||
// syscall->SetReturnType<ReturnType>("returnType");
|
||||
file << "\tsyscall->SetReturnType<" << returnType.type
|
||||
<< ">(\"" << returnType.type << "\");" << endl;
|
||||
// syscall->SetReturnType<(SYSCALL_RETURN_TYPE_SIZE_<i>,
|
||||
// "returnType");
|
||||
file << "\tsyscall->SetReturnType("
|
||||
<< "SYSCALL_RETURN_TYPE_SIZE_" << i << ", \""
|
||||
<< returnType.type << "\");" << endl;
|
||||
|
||||
// parameters
|
||||
int paramCount = syscall.CountParameters();
|
||||
for (int k = 0; k < paramCount; k++) {
|
||||
const NamedType& param = syscall.ParameterAt(k);
|
||||
// syscall->AddParameter<ParameterType>("parameterTypeName",
|
||||
// "parameterName");
|
||||
file << "\tsyscall->AddParameter<"
|
||||
<< param.type << ">(\""
|
||||
<< param.type << "\", \""
|
||||
<< param.name << "\");" << endl;
|
||||
// syscall->AddParameter(SYSCALL_PARAMETER_SIZE_<i>_<k>,
|
||||
// "parameterTypeName", "parameterName");
|
||||
file << "\tsyscall->AddParameter("
|
||||
<< "SYSCALL_PARAMETER_SIZE_" << i << "_" << k
|
||||
<< ", \"" << param.type << "\", \"" << param.name << "\");"
|
||||
<< endl;
|
||||
}
|
||||
file << endl;
|
||||
}
|
||||
@@ -378,6 +405,54 @@ private:
|
||||
file << "}" << endl;
|
||||
}
|
||||
|
||||
void _WriteSyscallTypeSizes(const char* filename)
|
||||
{
|
||||
// open the syscall info file
|
||||
ofstream file(filename, ofstream::out | ofstream::trunc);
|
||||
if (!file.is_open())
|
||||
throw new IOException(string("Failed to open `") + filename + "'.");
|
||||
|
||||
// write preamble
|
||||
file << "#include <computed_asm_macros.h>" << endl;
|
||||
file << "#include <syscalls.h>" << endl;
|
||||
file << endl;
|
||||
file << "#include \"arch_gensyscalls.h\"" << endl;
|
||||
file << endl;
|
||||
file << "void dummy() {" << endl;
|
||||
|
||||
file << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_RETURN_TYPE_ALIGNMENT_SIZE, "
|
||||
"sizeof(SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE));" << endl;
|
||||
file << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_PARAMETER_ALIGNMENT_SIZE, "
|
||||
"sizeof(SYSCALL_PARAMETER_ALIGNMENT_TYPE));" << endl;
|
||||
file << endl;
|
||||
|
||||
// syscalls
|
||||
for (int i = 0; i < (int)fSyscalls.size(); i++) {
|
||||
const Syscall& syscall = fSyscalls[i];
|
||||
const Type& returnType = syscall.GetReturnType();
|
||||
|
||||
if (returnType.type == "void") {
|
||||
file << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_RETURN_TYPE_SIZE_"
|
||||
<< i << ", 0);" << endl;
|
||||
} else {
|
||||
file << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_RETURN_TYPE_SIZE_"
|
||||
<< i << ", sizeof(" << returnType.type << "));" << endl;
|
||||
}
|
||||
|
||||
// parameters
|
||||
int paramCount = syscall.CountParameters();
|
||||
for (int k = 0; k < paramCount; k++) {
|
||||
const NamedType& param = syscall.ParameterAt(k);
|
||||
file << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_PARAMETER_SIZE_" << i
|
||||
<< "_" << k << ", sizeof(" << param.type << "));" << endl;
|
||||
}
|
||||
file << endl;
|
||||
}
|
||||
|
||||
// postamble
|
||||
file << "}" << endl;
|
||||
}
|
||||
|
||||
void _ParseSyscall(Tokenizer& tokenizer, Syscall& syscall)
|
||||
{
|
||||
// get return type and function name
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
/*
|
||||
* Copyright 2004-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2004-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
// Don't include arch_gensyscalls.h. It's only needed when creating the
|
||||
// syscall vector.
|
||||
#define DONT_INCLUDE_ARCH_GENSYSCALLS_H 1
|
||||
|
||||
#include "gensyscalls.h"
|
||||
|
||||
#include <cstdio>
|
||||
@@ -130,6 +126,19 @@ Syscall::LastParameter() const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Syscall::SetReturnType(int size, const char* name)
|
||||
{
|
||||
int usedSize = (size + kReturnTypeAlignmentSize - 1)
|
||||
/ kReturnTypeAlignmentSize * kReturnTypeAlignmentSize;
|
||||
const char* alignmentType
|
||||
= size != usedSize && size < kReturnTypeAlignmentSize
|
||||
? kReturnTypeAlignmentType : 0;
|
||||
|
||||
SetReturnType(name, size, usedSize, alignmentType);
|
||||
}
|
||||
|
||||
|
||||
Type*
|
||||
Syscall::SetReturnType(const char* name, int size, int usedSize,
|
||||
const char* alignmentTypeName)
|
||||
@@ -149,6 +158,24 @@ Syscall::AddParameter(const char* typeName, const char* parameterName,
|
||||
return parameter;
|
||||
}
|
||||
|
||||
void
|
||||
Syscall::AddParameter(int size, const char* typeName, const char* parameterName)
|
||||
{
|
||||
// compute offset
|
||||
int offset = 0;
|
||||
if (Parameter* previous = LastParameter())
|
||||
offset = previous->Offset() + previous->UsedSize();
|
||||
|
||||
int usedSize = (size + kParameterAlignmentSize - 1)
|
||||
/ kParameterAlignmentSize * kParameterAlignmentSize;
|
||||
const char* alignmentType
|
||||
= size != usedSize && size < kParameterAlignmentSize
|
||||
? kParameterAlignmentType : 0;
|
||||
|
||||
AddParameter(typeName, parameterName, size, usedSize, offset,
|
||||
alignmentType);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - SyscallVector
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
/*
|
||||
* Copyright 2004-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef GENSYSCALLS_H
|
||||
#define GENSYSCALLS_H
|
||||
|
||||
// TODO: <syscalls.h> is pre-processed with the cross-compiler, but the
|
||||
// pre-processed header is compiled with the native compiler. Unfortunately
|
||||
// <stdarg.h> is included indirectly, which results in a missing typedef when
|
||||
// the host compiler is gcc 2 and the native compiler gcc 4. The type is never
|
||||
// really used, so this doesn't really matter what it is defined to. The better
|
||||
// solution would be to remove the <stdarg.h> dependency, though.
|
||||
#if __GNUC__ == 2
|
||||
typedef void *__builtin_va_list;
|
||||
#endif
|
||||
|
||||
extern const char* const kReturnTypeAlignmentType;
|
||||
extern const char* const kParameterAlignmentType;
|
||||
extern const int kReturnTypeAlignmentSize;
|
||||
extern const int kParameterAlignmentSize;
|
||||
|
||||
|
||||
// Type
|
||||
class Type {
|
||||
@@ -64,13 +65,12 @@ public:
|
||||
Parameter* ParameterAt(int index) const;
|
||||
Parameter* LastParameter() const;
|
||||
|
||||
template<typename T> void SetReturnType(const char* name);
|
||||
template<typename T> void AddParameter(const char* typeName,
|
||||
const char* parameterName);
|
||||
|
||||
void SetReturnType(int size, const char* name);
|
||||
Type* SetReturnType(const char* name, int size,
|
||||
int usedSize,
|
||||
const char* alignmentTypeName);
|
||||
void AddParameter(int size, const char* typeName,
|
||||
const char* parameterName);
|
||||
Parameter* AddParameter(const char* typeName,
|
||||
const char* parameterName, int size,
|
||||
int usedSize, int offset,
|
||||
@@ -108,34 +108,4 @@ private:
|
||||
extern SyscallVector* create_syscall_vector();
|
||||
|
||||
|
||||
#ifndef DONT_INCLUDE_ARCH_GENSYSCALLS_H
|
||||
|
||||
// align_to_type
|
||||
template<typename T>
|
||||
int
|
||||
align_to_type(int size)
|
||||
{
|
||||
return (size + sizeof(T) - 1) / sizeof(T) * sizeof(T);
|
||||
}
|
||||
|
||||
#include "arch_gensyscalls.h"
|
||||
|
||||
// SetReturnType
|
||||
template<typename T>
|
||||
void
|
||||
Syscall::SetReturnType(const char* name)
|
||||
{
|
||||
ReturnTypeCreator<T>::Create(this, name);
|
||||
}
|
||||
|
||||
// AddParameter
|
||||
template<typename T>
|
||||
void
|
||||
Syscall::AddParameter(const char* typeName, const char* parameterName)
|
||||
{
|
||||
ParameterCreator<T>::Create(this, typeName, parameterName);
|
||||
}
|
||||
|
||||
#endif // !DONT_INCLUDE_ARCH_GENSYSCALLS_H
|
||||
|
||||
#endif // GENSYSCALLS_H
|
||||
|
||||
Reference in New Issue
Block a user