Reworked the way how the gensyscalls stuff finds out about
the sizes and alignments of syscall parameters. It no longer generates and compiles functions with the same signature as the syscalls. This simply doesn't generally work for cross-compilation. Instead we provide a bit of architecture-specific code that knows how things work for the target architecture. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15196 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,20 +1,74 @@
|
|||||||
SubDir HAIKU_TOP src tools gensyscalls ;
|
SubDir HAIKU_TOP src tools gensyscalls ;
|
||||||
|
|
||||||
# build gensyscallinfos
|
# preprocess the syscalls header
|
||||||
|
|
||||||
BuildPlatformMain gensyscallinfos : gensyscallinfos.cpp ;
|
rule PreprocessSyscalls
|
||||||
LinkAgainst gensyscallinfos : $(HOST_LIBSTDC++) ;
|
{
|
||||||
|
# PreprocessSyscalls <preprocessedHeader> : <header> : <parsable> ;
|
||||||
|
#
|
||||||
|
local parsable = $(3) ;
|
||||||
|
local parsableDefine ;
|
||||||
|
|
||||||
|
if $(parsable) {
|
||||||
|
parsableDefine = GEN_SYSCALL_INFOS_PROCESSING ;
|
||||||
|
}
|
||||||
|
|
||||||
# generate the syscall infos source file
|
Depends $(<) : $(>) ;
|
||||||
|
|
||||||
|
local headers = [ on $(1) return $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
|
||||||
|
local sysHeaders =
|
||||||
|
[ PrivateHeaders kernel ]
|
||||||
|
[ ArchHeaders $(TARGET_ARCH) ]
|
||||||
|
[ on $(1) return $(SUBDIRSYSHDRS) $(SYSHDRS) ]
|
||||||
|
$(HAIKU_HDRS) ;
|
||||||
|
|
||||||
|
HDRS on $(<) = $(headers) ;
|
||||||
|
SYSHDRS on $(<) = $(sysHeaders) ;
|
||||||
|
|
||||||
|
HDRRULE on $(>) = HdrRule ;
|
||||||
|
HDRSCAN on $(>) = $(HDRPATTERN) ;
|
||||||
|
HDRSEARCH on $(>) = $(headers) $(sysHeaders) $(STDHDRS) ;
|
||||||
|
HDRGRIST on $(>) = $(HDRGRIST) ;
|
||||||
|
|
||||||
|
DEFINES on $(<) += $(HAIKU_DEFINES) $(parsableDefine) ;
|
||||||
|
|
||||||
|
CCFLAGS on $(<) += $(HAIKU_CCFLAGS) $(SUBDIRCCFLAGS) $(OPTIM) ;
|
||||||
|
CCHDRS on $(<) = [ FIncludes $(headers) : $(HAIKU_LOCAL_INCLUDES_OPTION) ]
|
||||||
|
$(HAIKU_INCLUDES_SEPARATOR)
|
||||||
|
[ FSysIncludes $(sysHeaders) : $(HAIKU_SYSTEM_INCLUDES_OPTION) ] ;
|
||||||
|
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
||||||
|
}
|
||||||
|
|
||||||
|
actions PreprocessSyscalls
|
||||||
|
{
|
||||||
|
$(HAIKU_C++) -xc++ -E "$(2)" $(CCFLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
|
||||||
|
}
|
||||||
|
|
||||||
local syscallsHeader = [ FGristFiles syscalls.h ] ;
|
local syscallsHeader = [ FGristFiles syscalls.h ] ;
|
||||||
SEARCH on $(syscallsHeader) = [ FDirName $(HAIKU_TOP) headers private kernel ] ;
|
SEARCH on $(syscallsHeader) = [ FDirName $(HAIKU_TOP) headers private kernel ] ;
|
||||||
|
|
||||||
|
# We generate two preprocessed headers. One for parsing by gensyscallinfos
|
||||||
|
# (it contains #pragmas) and one for inclusion by the generated
|
||||||
|
# gensyscalls_infos.cpp.
|
||||||
|
local syscallsHeaderPPParsable = [ FGristFiles syscalls.h.pp.parsable ] ;
|
||||||
local syscallsHeaderPP = [ FGristFiles syscalls.h.pp ] ;
|
local syscallsHeaderPP = [ FGristFiles syscalls.h.pp ] ;
|
||||||
MakeLocateArch $(syscallsHeaderPP) ;
|
MakeLocateArch $(syscallsHeaderPPParsable) $(syscallsHeaderPP) ;
|
||||||
|
|
||||||
local syscallInfos = [ FGristFiles gensyscalls_infos.c ] ;
|
PreprocessSyscalls $(syscallsHeaderPPParsable) : $(syscallsHeader) : true ;
|
||||||
|
PreprocessSyscalls $(syscallsHeaderPP) : $(syscallsHeader) ;
|
||||||
|
|
||||||
|
|
||||||
|
# build gensyscallinfos
|
||||||
|
|
||||||
|
BuildPlatformMain gensyscallinfos
|
||||||
|
: gensyscallinfos.cpp
|
||||||
|
: $(HOST_LIBSTDC++)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
# generate the syscall infos source file
|
||||||
|
|
||||||
|
local syscallInfos = [ FGristFiles gensyscalls_infos.cpp ] ;
|
||||||
MakeLocateArch $(syscallInfos) ;
|
MakeLocateArch $(syscallInfos) ;
|
||||||
|
|
||||||
rule GenSyscallInfos {
|
rule GenSyscallInfos {
|
||||||
@@ -26,20 +80,23 @@ actions GenSyscallInfos1 {
|
|||||||
$(2[1]) $(2[2]) $(1)
|
$(2[1]) $(2[2]) $(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
GenSyscallInfos $(syscallInfos) : $(syscallsHeaderPP) ;
|
GenSyscallInfos $(syscallInfos) : $(syscallsHeaderPPParsable) ;
|
||||||
|
|
||||||
|
SubDirHdrs [ FDirName $(SUBDIR) arch $(TARGET_ARCH) ] ;
|
||||||
|
|
||||||
|
|
||||||
# build gensyscalls
|
# build gensyscalls
|
||||||
|
|
||||||
BuildPlatformMain gensyscalls : gensyscalls.cpp $(syscallInfos:S=$(SUFOBJ)) ;
|
BuildPlatformMain gensyscalls : gensyscalls.cpp $(syscallInfos) ;
|
||||||
LinkAgainst gensyscalls : $(HOST_LIBSTDC++) ;
|
LinkAgainst gensyscalls : $(HOST_LIBSTDC++) ;
|
||||||
UsePrivateObjectHeaders gensyscalls.cpp : kernel ;
|
|
||||||
UseArchObjectHeaders gensyscalls.cpp : $(TARGET_ARCH) ;
|
# Explicitly tell jam that gensyscalls.cpp includes the generated header.
|
||||||
|
Includes [ FGristFiles gensyscalls.cpp ] : $(syscallsHeaderPP) ;
|
||||||
|
|
||||||
|
|
||||||
# generate the output files
|
# generate the output files
|
||||||
|
|
||||||
# place them where there are needed
|
# place them where they are needed
|
||||||
local dir = $(HAIKU_COMMON_DEBUG_OBJECT_DIR) ;
|
local dir = $(HAIKU_COMMON_DEBUG_OBJECT_DIR) ;
|
||||||
MakeLocate <syscalls>syscalls.S.inc : [ FDirName $(dir) system libroot os ] ;
|
MakeLocate <syscalls>syscalls.S.inc : [ FDirName $(dir) system libroot os ] ;
|
||||||
MakeLocate <syscalls>syscall_dispatcher.h : [ FDirName $(dir) system kernel ] ;
|
MakeLocate <syscalls>syscall_dispatcher.h : [ FDirName $(dir) system kernel ] ;
|
||||||
@@ -47,7 +104,6 @@ MakeLocate <syscalls>syscall_numbers.h : [ FDirName $(dir) system kernel ] ;
|
|||||||
MakeLocate <syscalls>syscall_table.h : [ FDirName $(dir) system kernel ] ;
|
MakeLocate <syscalls>syscall_table.h : [ FDirName $(dir) system kernel ] ;
|
||||||
MakeLocate <syscalls>strace_syscalls.h : [ FDirName $(dir) bin strace ] ;
|
MakeLocate <syscalls>strace_syscalls.h : [ FDirName $(dir) bin strace ] ;
|
||||||
|
|
||||||
|
|
||||||
rule GenSyscallsFile {
|
rule GenSyscallsFile {
|
||||||
Depends $(1) : gensyscalls ;
|
Depends $(1) : gensyscalls ;
|
||||||
GenSyscallsFile1 $(1) : gensyscalls ;
|
GenSyscallsFile1 $(1) : gensyscalls ;
|
||||||
@@ -98,49 +154,3 @@ GenSyscallsDispatcher <syscalls>syscall_dispatcher.h ;
|
|||||||
GenSyscallsNumbers <syscalls>syscall_numbers.h ;
|
GenSyscallsNumbers <syscalls>syscall_numbers.h ;
|
||||||
GenSyscallsTable <syscalls>syscall_table.h ;
|
GenSyscallsTable <syscalls>syscall_table.h ;
|
||||||
GenSyscallsSTrace <syscalls>strace_syscalls.h ;
|
GenSyscallsSTrace <syscalls>strace_syscalls.h ;
|
||||||
|
|
||||||
|
|
||||||
# preprocess the syscalls header
|
|
||||||
|
|
||||||
UsePrivateHeaders kernel ;
|
|
||||||
UseArchHeaders $(TARGET_ARCH) ;
|
|
||||||
|
|
||||||
rule PreprocessSyscalls
|
|
||||||
{
|
|
||||||
Depends $(<) : $(>) ;
|
|
||||||
|
|
||||||
local headers = [ on $(1) return $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
|
|
||||||
local sysHeaders = [ on $(1) return $(SUBDIRSYSHDRS) $(SYSHDRS) ]
|
|
||||||
$(HAIKU_HDRS) ;
|
|
||||||
|
|
||||||
HDRS on $(<) = $(headers) ;
|
|
||||||
SYSHDRS on $(<) = $(sysHeaders) ;
|
|
||||||
|
|
||||||
HDRRULE on $(>) = HdrRule ;
|
|
||||||
HDRSCAN on $(>) = $(HDRPATTERN) ;
|
|
||||||
HDRSEARCH on $(>) = $(headers) $(sysHeaders) $(STDHDRS) ;
|
|
||||||
HDRGRIST on $(>) = $(HDRGRIST) ;
|
|
||||||
|
|
||||||
DEFINES on $(<) += $(HAIKU_DEFINES) GEN_SYSCALL_INFOS_PROCESSING ;
|
|
||||||
|
|
||||||
CCFLAGS on $(<) += $(HAIKU_CCFLAGS) $(SUBDIRCCFLAGS) $(OPTIM) ;
|
|
||||||
CCHDRS on $(<) = [ FIncludes $(headers) : $(HAIKU_LOCAL_INCLUDES_OPTION) ]
|
|
||||||
$(HAIKU_INCLUDES_SEPARATOR)
|
|
||||||
[ FSysIncludes $(sysHeaders) : $(HAIKU_SYSTEM_INCLUDES_OPTION) ] ;
|
|
||||||
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
|
||||||
}
|
|
||||||
|
|
||||||
actions PreprocessSyscalls
|
|
||||||
{
|
|
||||||
$(HAIKU_C++) -xc++ -E "$(2)" $(CCFLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
|
|
||||||
}
|
|
||||||
|
|
||||||
PreprocessSyscalls $(syscallsHeaderPP) : $(syscallsHeader) ;
|
|
||||||
|
|
||||||
|
|
||||||
# compile the syscall infos source file
|
|
||||||
|
|
||||||
# TODO: Clean this mess up!
|
|
||||||
SYSHDRS on $(syscallInfos:S=$(SUFOBJ)) = $(HAIKU_HDRS) ;
|
|
||||||
Object $(syscallInfos:S=$(SUFOBJ)) : $(syscallInfos) ;
|
|
||||||
CCFLAGS on $(syscallInfos:S=$(SUFOBJ)) += -nostdinc ;
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
// usage
|
// usage
|
||||||
const char *kUsage =
|
const char *kUsage =
|
||||||
"Usage: gensyscallinfos <header> <calls> <dispatcher>\n"
|
"Usage: gensyscallinfos <header> <syscall infos>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Given the (preprocessed) header file that defines the syscall prototypes the\n"
|
"Given the (preprocessed) header file that defines the syscall prototypes the\n"
|
||||||
"command generates a source file consisting of syscall infos, which is needed\n"
|
"command generates a source file consisting of syscall infos, which is needed\n"
|
||||||
@@ -322,16 +322,6 @@ private:
|
|||||||
tokenizer.ExpectNextToken("pragma");
|
tokenizer.ExpectNextToken("pragma");
|
||||||
tokenizer.ExpectNextToken("syscalls");
|
tokenizer.ExpectNextToken("syscalls");
|
||||||
tokenizer.ExpectNextToken("end");
|
tokenizer.ExpectNextToken("end");
|
||||||
|
|
||||||
// for (int i = 0; i < (int)fSyscalls.size(); i++) {
|
|
||||||
// const Syscall &syscall = fSyscalls[i];
|
|
||||||
// printf("syscall: `%s'\n", syscall.GetName().c_str());
|
|
||||||
// for (int k = 0; k < (int)syscall.CountParameters(); k++)
|
|
||||||
// printf(" arg: `%s'\n", syscall.ParameterAt(k).type.c_str());
|
|
||||||
// printf(" return type: `%s'\n",
|
|
||||||
// syscall.GetReturnType().type.c_str());
|
|
||||||
// }
|
|
||||||
// printf("Found %lu syscalls.\n", fSyscalls.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _WriteSyscallInfoFile(const char *filename)
|
void _WriteSyscallInfoFile(const char *filename)
|
||||||
@@ -340,86 +330,49 @@ private:
|
|||||||
ofstream file(filename, ofstream::out | ofstream::trunc);
|
ofstream file(filename, ofstream::out | ofstream::trunc);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
throw new IOException(string("Failed to open `") + filename + "'.");
|
throw new IOException(string("Failed to open `") + filename + "'.");
|
||||||
|
|
||||||
// write preamble
|
// write preamble
|
||||||
file << "#include \"gensyscalls.h\"" << endl;
|
file << "#include \"gensyscalls.h\"" << endl;
|
||||||
file << "#include \"syscalls.h\"" << endl;
|
file << "#include \"syscalls.h.pp\"" << endl;
|
||||||
file << endl;
|
file << endl;
|
||||||
// output the case statements
|
|
||||||
|
file << "SyscallVector* create_syscall_vector() {" << endl;
|
||||||
|
file << "\tSyscallVector* syscallVector = SyscallVector::Create();"
|
||||||
|
<< endl;
|
||||||
|
file << "\tSyscall* syscall;" << endl;
|
||||||
|
|
||||||
|
// syscalls
|
||||||
for (int i = 0; i < (int)fSyscalls.size(); i++) {
|
for (int i = 0; i < (int)fSyscalls.size(); i++) {
|
||||||
const Syscall &syscall = fSyscalls[i];
|
const Syscall &syscall = fSyscalls[i];
|
||||||
string name = string("gensyscall_") + syscall.GetName();
|
|
||||||
string paramInfoName = name + "_parameter_info";
|
// syscall = syscallVector->CreateSyscall("syscallName",
|
||||||
|
// "syscallKernelName");
|
||||||
|
file << "\tsyscall = syscallVector->CreateSyscall(\""
|
||||||
|
<< syscall.GetName() << "\", \""
|
||||||
|
<< syscall.GetKernelName() << "\");" << endl;
|
||||||
|
|
||||||
|
const Type &returnType = syscall.GetReturnType();
|
||||||
|
|
||||||
|
// syscall->SetReturnType<ReturnType>("returnType");
|
||||||
|
file << "\tsyscall->SetReturnType<" << returnType.type
|
||||||
|
<< ">(\"" << returnType.type << "\");" << endl;
|
||||||
|
|
||||||
|
// parameters
|
||||||
int paramCount = syscall.CountParameters();
|
int paramCount = syscall.CountParameters();
|
||||||
// write the parameter infos
|
|
||||||
file << "static gensyscall_parameter_info " << paramInfoName
|
|
||||||
<< "[] = {" << endl;
|
|
||||||
for (int k = 0; k < paramCount; k++) {
|
for (int k = 0; k < paramCount; k++) {
|
||||||
const NamedType ¶m = syscall.ParameterAt(k);
|
const NamedType ¶m = syscall.ParameterAt(k);
|
||||||
file << "\t{ \"" << param.type << "\", \"" << param.name
|
// syscall->AddParameter<ParameterType>("parameterTypeName",
|
||||||
<< "\", 0, " << "sizeof(" << syscall.ParameterAt(k).type
|
// "parameterName");
|
||||||
<< "), 0 }," << endl;
|
file << "\tsyscall->AddParameter<"
|
||||||
|
<< param.type << ">(\""
|
||||||
|
<< param.type << "\", \""
|
||||||
|
<< param.name << "\");" << endl;
|
||||||
}
|
}
|
||||||
file << "};" << endl;
|
|
||||||
file << endl;
|
|
||||||
// write the initialization function
|
|
||||||
file << "static void " << name << "(";
|
|
||||||
for (int k = 0; k < paramCount; k++) {
|
|
||||||
if (k > 0)
|
|
||||||
file << ", ";
|
|
||||||
string type = syscall.ParameterAt(k).type;
|
|
||||||
string::size_type pos = type.find(")");
|
|
||||||
if (pos == string::npos) {
|
|
||||||
file << type << " arg" << k;
|
|
||||||
} else {
|
|
||||||
// function pointer
|
|
||||||
file << string(type, 0, pos) << " arg" << k
|
|
||||||
<< string(type, pos, type.length() - pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (paramCount > 0)
|
|
||||||
file << ", ";
|
|
||||||
file << "int arg" << paramCount << ") {" << endl;
|
|
||||||
for (int k = 0; k < paramCount; k++) {
|
|
||||||
file << "\t" << paramInfoName << "[" << k << "].offset = "
|
|
||||||
<< "(char*)&arg" << k << " - (char*)&arg0;" << endl;
|
|
||||||
file << "\t" << paramInfoName << "[" << k << "].actual_size = "
|
|
||||||
<< "(char*)&arg" << (k + 1) << " - (char*)&arg" << k << ";"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
file << "}" << endl;
|
|
||||||
file << endl;
|
file << endl;
|
||||||
}
|
}
|
||||||
// write the syscall infos
|
|
||||||
file << "static gensyscall_syscall_info "
|
// postamble
|
||||||
"gensyscall_syscall_infos[] = {" << endl;
|
file << "\treturn syscallVector;" << endl;
|
||||||
for (int i = 0; i < (int)fSyscalls.size(); i++) {
|
|
||||||
const Syscall &syscall = fSyscalls[i];
|
|
||||||
string name = string("gensyscall_") + syscall.GetName();
|
|
||||||
string paramInfoName = name + "_parameter_info";
|
|
||||||
file << "\t{ \"" << syscall.GetName() << "\", "
|
|
||||||
<< "\"" << syscall.GetKernelName() << "\", "
|
|
||||||
<< "\"" << syscall.GetReturnType().type << "\", "
|
|
||||||
<< syscall.CountParameters() << ", "
|
|
||||||
<< paramInfoName << " }," << endl;
|
|
||||||
}
|
|
||||||
file << "};" << endl;
|
|
||||||
file << endl;
|
|
||||||
// write the initialization function
|
|
||||||
file << "gensyscall_syscall_info *gensyscall_get_infos(int *count);";
|
|
||||||
file << "gensyscall_syscall_info *gensyscall_get_infos(int *count) {"
|
|
||||||
<< endl;
|
|
||||||
for (int i = 0; i < (int)fSyscalls.size(); i++) {
|
|
||||||
const Syscall &syscall = fSyscalls[i];
|
|
||||||
string name = string("gensyscall_") + syscall.GetName();
|
|
||||||
file << "\t" << name << "(";
|
|
||||||
int paramCount = syscall.CountParameters();
|
|
||||||
// write the dummy parameters
|
|
||||||
for (int k = 0; k < paramCount; k++)
|
|
||||||
file << "(" << syscall.ParameterAt(k).type << ")0, ";
|
|
||||||
file << "0);" << endl;
|
|
||||||
}
|
|
||||||
file << "\t*count = " << fSyscalls.size() << ";" << endl;
|
|
||||||
file << "\treturn gensyscall_syscall_infos;" << endl;
|
|
||||||
file << "}" << endl;
|
file << "}" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
// gensyscalls.cpp
|
// gensyscalls.cpp
|
||||||
|
|
||||||
|
// Don't include arch_gensyscalls.h. It's only needed when creating the
|
||||||
|
// syscall vector.
|
||||||
|
#define DONT_INCLUDE_ARCH_GENSYSCALLS_H 1
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include "arch_config.h"
|
|
||||||
|
|
||||||
#include "gensyscalls.h"
|
#include "gensyscalls.h"
|
||||||
#include "gensyscalls_common.h"
|
#include "gensyscalls_common.h"
|
||||||
|
|
||||||
extern "C" gensyscall_syscall_info *gensyscall_get_infos(int *count);
|
using std::vector;
|
||||||
|
|
||||||
// usage
|
// usage
|
||||||
const char *kUsage =
|
const char *kUsage =
|
||||||
@@ -38,10 +41,160 @@ print_usage(bool error)
|
|||||||
fprintf((error ? stderr : stdout), kUsage);
|
fprintf((error ? stderr : stdout), kUsage);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
|
||||||
PARAMETER_ALIGNMENT = sizeof(FUNCTION_CALL_PARAMETER_ALIGNMENT_TYPE)
|
// Type
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
Type::Type(const char* name, int size, int usedSize,
|
||||||
|
const char* alignmentTypeName)
|
||||||
|
: fName(name),
|
||||||
|
fSize(size),
|
||||||
|
fUsedSize(usedSize),
|
||||||
|
fAlignmentType(alignmentTypeName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parameter
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
Parameter::Parameter(const char* typeName, const char* parameterName,
|
||||||
|
int size, int usedSize, int offset, const char* alignmentTypeName)
|
||||||
|
: Type(typeName, size, usedSize, alignmentTypeName),
|
||||||
|
fParameterName(parameterName),
|
||||||
|
fOffset(offset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Syscall
|
||||||
|
|
||||||
|
// ParameterVector
|
||||||
|
struct Syscall::ParameterVector : public vector<Parameter*> {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
Syscall::Syscall(const char* name, const char* kernelName)
|
||||||
|
: fName(name),
|
||||||
|
fKernelName(kernelName),
|
||||||
|
fReturnType(NULL),
|
||||||
|
fParameters(new ParameterVector)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
Syscall::~Syscall()
|
||||||
|
{
|
||||||
|
delete fReturnType;
|
||||||
|
|
||||||
|
int count = CountParameters();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
delete ParameterAt(i);
|
||||||
|
delete fParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParameterAt
|
||||||
|
int
|
||||||
|
Syscall::CountParameters() const
|
||||||
|
{
|
||||||
|
return fParameters->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParameterAt
|
||||||
|
Parameter*
|
||||||
|
Syscall::ParameterAt(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= CountParameters())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (*fParameters)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// LastParameter
|
||||||
|
Parameter*
|
||||||
|
Syscall::LastParameter() const
|
||||||
|
{
|
||||||
|
return ParameterAt(CountParameters() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReturnType
|
||||||
|
Type*
|
||||||
|
Syscall::SetReturnType(const char* name, int size, int usedSize,
|
||||||
|
const char* alignmentTypeName)
|
||||||
|
{
|
||||||
|
delete fReturnType;
|
||||||
|
return fReturnType = new Type(name, size, usedSize, alignmentTypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddParameter
|
||||||
|
Parameter*
|
||||||
|
Syscall::AddParameter(const char* typeName, const char* parameterName,
|
||||||
|
int size, int usedSize, int offset, const char* alignmentTypeName)
|
||||||
|
{
|
||||||
|
Parameter* parameter = new Parameter(typeName, parameterName, size,
|
||||||
|
usedSize, offset, alignmentTypeName);
|
||||||
|
fParameters->push_back(parameter);
|
||||||
|
return parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SyscallVector
|
||||||
|
|
||||||
|
struct SyscallVector::_SyscallVector : public vector<Syscall*> {
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
SyscallVector::SyscallVector()
|
||||||
|
: fSyscalls(new _SyscallVector)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
SyscallVector::~SyscallVector()
|
||||||
|
{
|
||||||
|
int count = CountSyscalls();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
delete SyscallAt(i);
|
||||||
|
delete fSyscalls;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create
|
||||||
|
SyscallVector*
|
||||||
|
SyscallVector::Create()
|
||||||
|
{
|
||||||
|
return new SyscallVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountSyscalls
|
||||||
|
int
|
||||||
|
SyscallVector::CountSyscalls() const
|
||||||
|
{
|
||||||
|
return fSyscalls->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyscallAt
|
||||||
|
Syscall*
|
||||||
|
SyscallVector::SyscallAt(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= CountSyscalls())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (*fSyscalls)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSyscall
|
||||||
|
Syscall*
|
||||||
|
SyscallVector::CreateSyscall(const char* name, const char* kernelName)
|
||||||
|
{
|
||||||
|
Syscall* syscall = new Syscall(name, kernelName);
|
||||||
|
fSyscalls->push_back(syscall);
|
||||||
|
return syscall;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
// Main
|
// Main
|
||||||
class Main {
|
class Main {
|
||||||
public:
|
public:
|
||||||
@@ -94,8 +247,8 @@ public:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fSyscallInfos = gensyscall_get_infos(&fSyscallCount);
|
fSyscallVector = create_syscall_vector();
|
||||||
_UpdateSyscallInfos();
|
fSyscallCount = fSyscallVector->CountSyscalls();
|
||||||
if (!syscallsFile && !dispatcherFile && !numbersFile && !tableFile
|
if (!syscallsFile && !dispatcherFile && !numbersFile && !tableFile
|
||||||
&& !straceFile) {
|
&& !straceFile) {
|
||||||
printf("Found %d syscalls.\n", fSyscallCount);
|
printf("Found %d syscalls.\n", fSyscallCount);
|
||||||
@@ -121,20 +274,21 @@ public:
|
|||||||
ofstream file(filename, ofstream::out | ofstream::trunc);
|
ofstream file(filename, ofstream::out | ofstream::trunc);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
throw IOException(string("Failed to open `") + filename + "'.");
|
throw IOException(string("Failed to open `") + filename + "'.");
|
||||||
|
|
||||||
// output the syscalls definitions
|
// output the syscalls definitions
|
||||||
for (int i = 0; i < fSyscallCount; i++) {
|
for (int i = 0; i < fSyscallCount; i++) {
|
||||||
const gensyscall_syscall_info &syscall = fSyscallInfos[i];
|
const Syscall* syscall = fSyscallVector->SyscallAt(i);
|
||||||
int paramCount = syscall.parameter_count;
|
int paramCount = syscall->CountParameters();
|
||||||
int paramSize = 0;
|
int paramSize = 0;
|
||||||
gensyscall_parameter_info* parameters = syscall.parameters;
|
|
||||||
// XXX: Currently the SYSCALL macros support 4 byte aligned
|
// XXX: Currently the SYSCALL macros support 4 byte aligned
|
||||||
// parameters only. This has to change, of course.
|
// parameters only. This has to change, of course.
|
||||||
for (int k = 0; k < paramCount; k++) {
|
for (int k = 0; k < paramCount; k++) {
|
||||||
int size = parameters[k].actual_size;
|
const Parameter* parameter = syscall->ParameterAt(k);
|
||||||
|
int size = parameter->UsedSize();
|
||||||
paramSize += (size + 3) / 4 * 4;
|
paramSize += (size + 3) / 4 * 4;
|
||||||
}
|
}
|
||||||
file << "SYSCALL" << (paramSize / 4) << "("
|
file << "SYSCALL" << (paramSize / 4) << "("
|
||||||
<< syscall.name << ", " << i << ")" << endl;
|
<< syscall->Name() << ", " << i << ")" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,34 +298,36 @@ public:
|
|||||||
ofstream file(filename, ofstream::out | ofstream::trunc);
|
ofstream file(filename, ofstream::out | ofstream::trunc);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
throw IOException(string("Failed to open `") + filename + "'.");
|
throw IOException(string("Failed to open `") + filename + "'.");
|
||||||
|
|
||||||
// output the case statements
|
// output the case statements
|
||||||
for (int i = 0; i < fSyscallCount; i++) {
|
for (int i = 0; i < fSyscallCount; i++) {
|
||||||
const gensyscall_syscall_info &syscall = fSyscallInfos[i];
|
const Syscall* syscall = fSyscallVector->SyscallAt(i);
|
||||||
file << "case " << i << ":" << endl;
|
file << "case " << i << ":" << endl;
|
||||||
file << "\t";
|
file << "\t";
|
||||||
if (string(syscall.return_type) != "void")
|
if (string(syscall->ReturnType()->TypeName()) != "void")
|
||||||
file << "*call_ret = ";
|
file << "*call_ret = ";
|
||||||
file << syscall.kernel_name << "(";
|
file << syscall->KernelName() << "(";
|
||||||
int paramCount = syscall.parameter_count;
|
int paramCount = syscall->CountParameters();
|
||||||
if (paramCount > 0) {
|
if (paramCount > 0) {
|
||||||
gensyscall_parameter_info* parameters = syscall.parameters;
|
Parameter* parameter = syscall->ParameterAt(0);
|
||||||
if (parameters[0].size < PARAMETER_ALIGNMENT) {
|
if (parameter->AlignmentTypeName()) {
|
||||||
file << "(" << parameters[0].type << ")*("
|
file << "(" << parameter->TypeName() << ")*("
|
||||||
<< "FUNCTION_CALL_PARAMETER_ALIGNMENT_TYPE"
|
<< parameter->AlignmentTypeName()
|
||||||
<< "*)args";
|
<< "*)args";
|
||||||
} else {
|
} else {
|
||||||
file << "*(" << _GetPointerType(parameters[0].type)
|
file << "*(" << _GetPointerType(parameter->TypeName())
|
||||||
<< ")args";
|
<< ")args";
|
||||||
}
|
}
|
||||||
for (int k = 1; k < paramCount; k++) {
|
for (int k = 1; k < paramCount; k++) {
|
||||||
if (parameters[k].size < PARAMETER_ALIGNMENT) {
|
parameter = syscall->ParameterAt(k);
|
||||||
file << ", (" << parameters[k].type << ")*("
|
if (parameter->AlignmentTypeName()) {
|
||||||
<< "FUNCTION_CALL_PARAMETER_ALIGNMENT_TYPE"
|
file << ", (" << parameter->TypeName() << ")*("
|
||||||
<< "*)((char*)args + " << parameters[k].offset
|
<< parameter->AlignmentTypeName()
|
||||||
|
<< "*)((char*)args + " << parameter->Offset()
|
||||||
<< ")";
|
<< ")";
|
||||||
} else {
|
} else {
|
||||||
file << ", *(" << _GetPointerType(parameters[k].type)
|
file << ", *(" << _GetPointerType(parameter->TypeName())
|
||||||
<< ")((char*)args + " << parameters[k].offset
|
<< ")((char*)args + " << parameter->Offset()
|
||||||
<< ")";
|
<< ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,16 +343,19 @@ public:
|
|||||||
ofstream file(filename, ofstream::out | ofstream::trunc);
|
ofstream file(filename, ofstream::out | ofstream::trunc);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
throw IOException(string("Failed to open `") + filename + "'.");
|
throw IOException(string("Failed to open `") + filename + "'.");
|
||||||
|
|
||||||
// output the defines
|
// output the defines
|
||||||
const char *prefix = "_user_";
|
const char *prefix = "_user_";
|
||||||
size_t prefixLen = strlen(prefix);
|
size_t prefixLen = strlen(prefix);
|
||||||
for (int i = 0; i < fSyscallCount; i++) {
|
for (int i = 0; i < fSyscallCount; i++) {
|
||||||
const gensyscall_syscall_info &syscall = fSyscallInfos[i];
|
const Syscall* syscall = fSyscallVector->SyscallAt(i);
|
||||||
string name(syscall.kernel_name);
|
string name(syscall->KernelName());
|
||||||
|
|
||||||
// drop the leading "_user_" prefix
|
// drop the leading "_user_" prefix
|
||||||
if (name.find(prefix) != 0)
|
if (name.find(prefix) != 0)
|
||||||
throw Exception(string("Bad kernel name: `") + name + "'.");
|
throw Exception(string("Bad kernel name: `") + name + "'.");
|
||||||
name = string(name, prefixLen);
|
name = string(name, prefixLen);
|
||||||
|
|
||||||
// convert to upper case (is there no function for that?)
|
// convert to upper case (is there no function for that?)
|
||||||
string defineName;
|
string defineName;
|
||||||
for (int k = 0; k < (int)name.length(); k++)
|
for (int k = 0; k < (int)name.length(); k++)
|
||||||
@@ -221,18 +380,15 @@ public:
|
|||||||
|
|
||||||
// the syscall infos
|
// the syscall infos
|
||||||
for (int i = 0; i < fSyscallCount; i++) {
|
for (int i = 0; i < fSyscallCount; i++) {
|
||||||
const gensyscall_syscall_info &syscall = fSyscallInfos[i];
|
const Syscall* syscall = fSyscallVector->SyscallAt(i);
|
||||||
|
|
||||||
// get the parameter size
|
// get the parameter size
|
||||||
int paramSize = 0;
|
int paramSize = 0;
|
||||||
if (syscall.parameter_count > 0) {
|
if (Parameter* parameter = syscall->LastParameter())
|
||||||
const gensyscall_parameter_info &lastParam
|
paramSize = parameter->Offset() + parameter->UsedSize();
|
||||||
= syscall.parameters[syscall.parameter_count - 1];
|
|
||||||
paramSize = lastParam.offset + lastParam.actual_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// output the info for the syscall
|
// output the info for the syscall
|
||||||
file << "\t{ " << syscall.kernel_name << ", "
|
file << "\t{ " << syscall->KernelName() << ", "
|
||||||
<< paramSize << " }," << endl;
|
<< paramSize << " }," << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +416,7 @@ public:
|
|||||||
|
|
||||||
// iterate through the syscalls
|
// iterate through the syscalls
|
||||||
for (int i = 0; i < fSyscallCount; i++) {
|
for (int i = 0; i < fSyscallCount; i++) {
|
||||||
const gensyscall_syscall_info &syscall = fSyscallInfos[i];
|
const Syscall* syscall = fSyscallVector->SyscallAt(i);
|
||||||
|
|
||||||
if (i % chunkSize == 0) {
|
if (i % chunkSize == 0) {
|
||||||
// chunk end
|
// chunk end
|
||||||
@@ -273,29 +429,32 @@ public:
|
|||||||
|
|
||||||
// spacing, comment
|
// spacing, comment
|
||||||
file << endl;
|
file << endl;
|
||||||
file << "\t// " << syscall.name << endl;
|
file << "\t// " << syscall->Name() << endl;
|
||||||
|
|
||||||
// create the return type handler
|
// create the return type handler
|
||||||
file << "\thandler = TypeHandlerFactory<" << syscall.return_type
|
const char* returnType = syscall->ReturnType()->TypeName();
|
||||||
|
file << "\thandler = TypeHandlerFactory<"
|
||||||
|
<< returnType
|
||||||
<< ">::Create();" << endl;
|
<< ">::Create();" << endl;
|
||||||
|
|
||||||
// create the syscall
|
// create the syscall
|
||||||
file << "\tsyscall = new Syscall(\"" << syscall.name << "\", "
|
file << "\tsyscall = new Syscall(\"" << syscall->Name() << "\", "
|
||||||
<< "\"" << syscall.return_type << "\", "<< "handler);" << endl;
|
<< "\"" << returnType << "\", "<< "handler);" << endl;
|
||||||
file << "\tsyscalls.push_back(syscall);" << endl;
|
file << "\tsyscalls.push_back(syscall);" << endl;
|
||||||
|
|
||||||
// add the parameters
|
// add the parameters
|
||||||
for (int k = 0; k < syscall.parameter_count; k++) {
|
int paramCount = syscall->CountParameters();
|
||||||
const gensyscall_parameter_info ¶meter
|
for (int k = 0; k < paramCount; k++) {
|
||||||
= syscall.parameters[k];
|
const Parameter* parameter = syscall->ParameterAt(k);
|
||||||
|
|
||||||
// create the parameter type handler
|
// create the parameter type handler
|
||||||
file << "\thandler = TypeHandlerFactory<"
|
file << "\thandler = TypeHandlerFactory<"
|
||||||
<< parameter.type << ">::Create();" << endl;
|
<< parameter->TypeName() << ">::Create();" << endl;
|
||||||
|
|
||||||
// add the parameter
|
// add the parameter
|
||||||
file << "\tsyscall->AddParameter(\"" << parameter.name << "\", "
|
file << "\tsyscall->AddParameter(\""
|
||||||
<< parameter.offset << ", \"" << parameter.type
|
<< parameter->ParameterName() << "\", "
|
||||||
|
<< parameter->Offset() << ", \"" << parameter->TypeName()
|
||||||
<< "\", handler);" << endl;
|
<< "\", handler);" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -316,29 +475,8 @@ public:
|
|||||||
return string(type, parenthesis - type) + "*" + parenthesis;
|
return string(type, parenthesis - type) + "*" + parenthesis;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _UpdateSyscallInfos()
|
|
||||||
{
|
|
||||||
// Since getting the parameter offsets and actual sizes doesn't work
|
|
||||||
// as it is now, we overwrite them with values computed using the
|
|
||||||
// parameter alignment type.
|
|
||||||
for (int i = 0; i < fSyscallCount; i++) {
|
|
||||||
gensyscall_syscall_info &syscall = fSyscallInfos[i];
|
|
||||||
int paramCount = syscall.parameter_count;
|
|
||||||
gensyscall_parameter_info* parameters = syscall.parameters;
|
|
||||||
int offset = 0;
|
|
||||||
for (int k = 0; k < paramCount; k++) {
|
|
||||||
if (parameters[k].size < PARAMETER_ALIGNMENT)
|
|
||||||
parameters[k].actual_size = PARAMETER_ALIGNMENT;
|
|
||||||
else
|
|
||||||
parameters[k].actual_size = parameters[k].size;
|
|
||||||
parameters[k].offset = offset;
|
|
||||||
offset += parameters[k].actual_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gensyscall_syscall_info *fSyscallInfos;
|
SyscallVector* fSyscallVector;
|
||||||
int fSyscallCount;
|
int fSyscallCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,131 @@
|
|||||||
// gensyscalls.h
|
#ifndef GENSYSCALLS_H
|
||||||
|
#define GENSYSCALLS_H
|
||||||
|
|
||||||
#ifndef _GEN_SYSCALLS_H
|
// Type
|
||||||
#define _GEN_SYSCALLS_H
|
class Type {
|
||||||
|
public:
|
||||||
|
Type(const char* name, int size,
|
||||||
|
int usedSize,
|
||||||
|
const char* alignmentTypeName);
|
||||||
|
~Type() {}
|
||||||
|
|
||||||
typedef struct gensyscall_parameter_info {
|
const char* TypeName() const { return fName; }
|
||||||
const char *type;
|
int Size() const { return fSize; }
|
||||||
const char *name;
|
int UsedSize() const { return fUsedSize; }
|
||||||
int offset;
|
const char* AlignmentTypeName() const
|
||||||
int size;
|
{ return fAlignmentType; }
|
||||||
int actual_size;
|
|
||||||
} gensyscall_parameter_info;
|
|
||||||
|
|
||||||
typedef struct gensyscall_syscall_info {
|
private:
|
||||||
const char *name;
|
const char* fName;
|
||||||
const char *kernel_name;
|
int fSize;
|
||||||
const char *return_type;
|
int fUsedSize;
|
||||||
int parameter_count;
|
const char* fAlignmentType;
|
||||||
gensyscall_parameter_info *parameters;
|
};
|
||||||
} gensyscall_syscall_info;
|
|
||||||
|
|
||||||
#endif // _GEN_SYSCALLS_H
|
// Parameter
|
||||||
|
class Parameter : public Type {
|
||||||
|
public:
|
||||||
|
Parameter(const char* typeName,
|
||||||
|
const char* parameterName, int size,
|
||||||
|
int usedSize, int offset,
|
||||||
|
const char* alignmentTypeName);
|
||||||
|
~Parameter() {}
|
||||||
|
|
||||||
|
const char* ParameterName() const { return fParameterName; }
|
||||||
|
int Offset() const { return fOffset; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* fParameterName;
|
||||||
|
int fOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Syscall
|
||||||
|
class Syscall {
|
||||||
|
public:
|
||||||
|
Syscall(const char* name,
|
||||||
|
const char* kernelName);
|
||||||
|
~Syscall();
|
||||||
|
|
||||||
|
const char* Name() const { return fName; }
|
||||||
|
const char* KernelName() const { return fKernelName; }
|
||||||
|
Type* ReturnType() const { return fReturnType; }
|
||||||
|
|
||||||
|
int CountParameters() const;
|
||||||
|
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);
|
||||||
|
|
||||||
|
Type* SetReturnType(const char* name, int size,
|
||||||
|
int usedSize,
|
||||||
|
const char* alignmentTypeName);
|
||||||
|
Parameter* AddParameter(const char* typeName,
|
||||||
|
const char* parameterName, int size,
|
||||||
|
int usedSize, int offset,
|
||||||
|
const char* alignmentTypeName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ParameterVector;
|
||||||
|
|
||||||
|
const char* fName;
|
||||||
|
const char* fKernelName;
|
||||||
|
Type* fReturnType;
|
||||||
|
ParameterVector* fParameters;
|
||||||
|
};
|
||||||
|
|
||||||
|
// SyscallVector
|
||||||
|
class SyscallVector {
|
||||||
|
public:
|
||||||
|
SyscallVector();
|
||||||
|
~SyscallVector();
|
||||||
|
|
||||||
|
static SyscallVector* Create();
|
||||||
|
|
||||||
|
int CountSyscalls() const;
|
||||||
|
Syscall* SyscallAt(int index) const;
|
||||||
|
|
||||||
|
Syscall* CreateSyscall(const char* name,
|
||||||
|
const char* kernelName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct _SyscallVector;
|
||||||
|
|
||||||
|
_SyscallVector* fSyscalls;
|
||||||
|
};
|
||||||
|
|
||||||
|
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