Generate a kernel array kSyscallParametersInfos containing information

about syscall parameters. Particularly interesting is a type_code field
for each parameter. The mechanism isn't very accurate, but we can
classify everything in string, pointer, and integer types.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23618 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2008-01-18 19:25:28 +00:00
parent aba70a8ca2
commit 19101ba0f4
2 changed files with 119 additions and 1 deletions

View File

@ -9,13 +9,30 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#define MAX_SYSCALL_PARAMETERS 16
typedef struct syscall_info { typedef struct syscall_info {
void *function; // pointer to the syscall function void *function; // pointer to the syscall function
int parameter_size; // summed up parameter size int parameter_size; // summed up parameter size
} syscall_info; } syscall_info;
typedef struct syscall_parameter_info {
int offset;
int size;
int used_size;
type_code type;
} syscall_parameter_info;
typedef struct syscall_parameters_info {
int parameter_count;
syscall_parameter_info parameters[MAX_SYSCALL_PARAMETERS];
} syscall_parameters_info;
extern const int kSyscallCount; extern const int kSyscallCount;
extern const syscall_info kSyscallInfos[]; extern const syscall_info kSyscallInfos[];
extern const syscall_parameters_info kSyscallParametersInfos[];
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,4 +1,7 @@
// gensyscalls.cpp /*
* Copyright 2004-2008, 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 // Don't include arch_gensyscalls.h. It's only needed when creating the
// syscall vector. // syscall vector.
@ -402,6 +405,35 @@ public:
// syscall infos array end // syscall infos array end
file << "};" << endl; file << "};" << endl;
file << endl;
// syscall parameters infos array preamble
file << "const syscall_parameters_info kSyscallParametersInfos[] = {"
<< endl;
// the syscall parameters infos
for (int i = 0; i < fSyscallCount; i++) {
const Syscall* syscall = fSyscallVector->SyscallAt(i);
int paramCount = syscall->CountParameters();
file << "\t{" << endl;
file << "\t\t" << paramCount << "," << endl;
file << "\t\t{" << endl;
for (int k = 0; k < paramCount; k++) {
const Parameter* parameter = syscall->ParameterAt(k);
file << "\t\t\t{ " << parameter->Offset() << ", "
<< parameter->Size() << ", "
<< parameter->UsedSize() << ", "
<< _GetTypeCode(parameter) << " }," << endl;
}
file << "\t\t}" << endl;
file << "\t}," << endl;
}
// syscall parameters infos array end
file << "};" << endl;
// assembler guard end // assembler guard end
file << "#endif // _ASSEMBLER" << endl; file << "#endif // _ASSEMBLER" << endl;
@ -486,6 +518,75 @@ public:
return string(type, parenthesis - type) + "*" + parenthesis; return string(type, parenthesis - type) + "*" + parenthesis;
} }
static string _GetTypeCode(const Type* type)
{
const char* typeName = type->TypeName();
if (strchr(typeName, '*')) {
// pointer type
// check, if it is a string constant ("const char *" or
// "char const *")
if (_GetTypeCodeTokenize(typeName) == "const"
&& _GetTypeCodeTokenize(typeName) == "char"
&& _GetTypeCodeTokenize(typeName) == "*"
&& _GetTypeCodeTokenize(typeName) == ""
|| _GetTypeCodeTokenize(typeName) == "char"
&& _GetTypeCodeTokenize(typeName) == "const"
&& _GetTypeCodeTokenize(typeName) == "*"
&& _GetTypeCodeTokenize(typeName) == "") {
return "B_STRING_TYPE";
}
// not a string constant
return "B_POINTER_TYPE";
} else {
// non-pointer type
switch (type->Size()) {
case 1:
return "B_INT8_TYPE";
case 2:
return "B_INT16_TYPE";
case 4:
return "B_INT32_TYPE";
case 8:
return "B_INT64_TYPE";
default:
return "B_RAW_TYPE";
}
}
}
static string _GetTypeCodeTokenize(const char*& type)
{
// skip whitespace
while (*type != '\0' && isspace(*type))
type++;
switch (*type) {
case '\0':
return "";
case '*':
case '(':
case ')':
case '&':
return string(type++, 1);
default:
{
if (*type != '_' && !isalpha(*type)) {
// probably invalid, just return something
return string(type++, 1);
}
// an identifier
const char* start = type;
while (*type == '_' || isalnum(*type))
type++;
return string(start, type - start);
}
}
}
private: private:
SyscallVector* fSyscallVector; SyscallVector* fSyscallVector;
int fSyscallCount; int fSyscallCount;