gensyscalls: alignment fixup for ARM
ARM ABI has different alignment requirements based on parameter size: * parameters not larger than 4 bytes are aligned on 4 bytes * parameters larger than 4 bytes are aligned on 8 bytes see: Procedure Call Standard for the Arm Architecture sections 5.1, Fundamental Data Types and 6.5, Parameter Passing Therefore the following changes are introduced in gensyscalls tool: * new optional define SYSCALL_LONG_PARAMETER_ALIGNMENT_TYPE is introduced * it's defined only on ARM * on other architectures it takes on the value of SYSCALL_PARAMETER_ALIGNMENT_TYPE as a default * constants kLongParameterAlignmentType and kLongParameterAlignmentSize are introduced * Syscall::AddParameter uses this value for aligning parameters larger than 4 bytes Change-Id: I7e766e0ea9d07001643e813722b462b1f044921a Reviewed-on: https://review.haiku-os.org/c/haiku/+/5112 Reviewed-by: Adrien Destugues <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
Jérôme Duval
parent
b24e59ccbb
commit
ab3c8bea07
@@ -1,2 +1,3 @@
|
||||
#define SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE int
|
||||
#define SYSCALL_PARAMETER_ALIGNMENT_TYPE int
|
||||
#define SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE int
|
||||
#define SYSCALL_PARAMETER_ALIGNMENT_TYPE int
|
||||
#define SYSCALL_LONG_PARAMETER_ALIGNMENT_TYPE long long
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include "arch_gensyscalls.h"
|
||||
// for the alignment type macros (only for the type names)
|
||||
|
||||
#ifndef SYSCALL_LONG_PARAMETER_ALIGNMENT_TYPE
|
||||
#define SYSCALL_LONG_PARAMETER_ALIGNMENT_TYPE SYSCALL_PARAMETER_ALIGNMENT_TYPE
|
||||
#endif
|
||||
|
||||
|
||||
// macro trickery to create a string literal
|
||||
#define MAKE_STRING(x) #x
|
||||
@@ -357,10 +361,15 @@ private:
|
||||
file << "const char* const kParameterAlignmentType = \""
|
||||
EVAL_MACRO(MAKE_STRING, SYSCALL_PARAMETER_ALIGNMENT_TYPE)
|
||||
<< "\";" << endl;
|
||||
file << "const char* const kLongParameterAlignmentType = \""
|
||||
EVAL_MACRO(MAKE_STRING, SYSCALL_LONG_PARAMETER_ALIGNMENT_TYPE)
|
||||
<< "\";" << endl;
|
||||
file << "const int kReturnTypeAlignmentSize = "
|
||||
"SYSCALL_RETURN_TYPE_ALIGNMENT_SIZE;" << endl;
|
||||
file << "const int kParameterAlignmentSize = "
|
||||
"SYSCALL_PARAMETER_ALIGNMENT_SIZE;" << endl;
|
||||
file << "const int kLongParameterAlignmentSize = "
|
||||
"SYSCALL_LONG_PARAMETER_ALIGNMENT_SIZE;" << endl;
|
||||
file << endl;
|
||||
|
||||
file << "SyscallVector* create_syscall_vector() {" << endl;
|
||||
@@ -418,12 +427,18 @@ private:
|
||||
file << endl;
|
||||
file << "#include \"arch_gensyscalls.h\"" << endl;
|
||||
file << endl;
|
||||
file << "#ifndef SYSCALL_LONG_PARAMETER_ALIGNMENT_TYPE" << endl;
|
||||
file << "#define SYSCALL_LONG_PARAMETER_ALIGNMENT_TYPE SYSCALL_PARAMETER_ALIGNMENT_TYPE"
|
||||
<< endl;
|
||||
file << "#endif" << 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 << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_LONG_PARAMETER_ALIGNMENT_SIZE, "
|
||||
"sizeof(SYSCALL_LONG_PARAMETER_ALIGNMENT_TYPE));" << endl;
|
||||
file << endl;
|
||||
|
||||
// syscalls
|
||||
|
||||
@@ -166,6 +166,15 @@ Syscall::AddParameter(int size, const char* typeName, const char* parameterName)
|
||||
if (Parameter* previous = LastParameter())
|
||||
offset = previous->Offset() + previous->UsedSize();
|
||||
|
||||
// take care of extra alignment for long parameters
|
||||
// this is needed to sort out parameter offsets on ARM
|
||||
if (size >= kLongParameterAlignmentSize) {
|
||||
if ((offset % kLongParameterAlignmentSize) != 0) {
|
||||
offset += kLongParameterAlignmentSize
|
||||
- offset % kLongParameterAlignmentSize;
|
||||
}
|
||||
}
|
||||
|
||||
int usedSize = (size + kParameterAlignmentSize - 1)
|
||||
/ kParameterAlignmentSize * kParameterAlignmentSize;
|
||||
const char* alignmentType
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
|
||||
extern const char* const kReturnTypeAlignmentType;
|
||||
extern const char* const kParameterAlignmentType;
|
||||
extern const char* const kLongParameterAlignmentType;
|
||||
extern const int kReturnTypeAlignmentSize;
|
||||
extern const int kParameterAlignmentSize;
|
||||
extern const int kLongParameterAlignmentSize;
|
||||
|
||||
|
||||
// Type
|
||||
|
||||
Reference in New Issue
Block a user