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_RETURN_TYPE_ALIGNMENT_TYPE int
|
||||||
#define SYSCALL_PARAMETER_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"
|
#include "arch_gensyscalls.h"
|
||||||
// for the alignment type macros (only for the type names)
|
// 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
|
// macro trickery to create a string literal
|
||||||
#define MAKE_STRING(x) #x
|
#define MAKE_STRING(x) #x
|
||||||
@@ -357,10 +361,15 @@ private:
|
|||||||
file << "const char* const kParameterAlignmentType = \""
|
file << "const char* const kParameterAlignmentType = \""
|
||||||
EVAL_MACRO(MAKE_STRING, SYSCALL_PARAMETER_ALIGNMENT_TYPE)
|
EVAL_MACRO(MAKE_STRING, SYSCALL_PARAMETER_ALIGNMENT_TYPE)
|
||||||
<< "\";" << endl;
|
<< "\";" << endl;
|
||||||
|
file << "const char* const kLongParameterAlignmentType = \""
|
||||||
|
EVAL_MACRO(MAKE_STRING, SYSCALL_LONG_PARAMETER_ALIGNMENT_TYPE)
|
||||||
|
<< "\";" << endl;
|
||||||
file << "const int kReturnTypeAlignmentSize = "
|
file << "const int kReturnTypeAlignmentSize = "
|
||||||
"SYSCALL_RETURN_TYPE_ALIGNMENT_SIZE;" << endl;
|
"SYSCALL_RETURN_TYPE_ALIGNMENT_SIZE;" << endl;
|
||||||
file << "const int kParameterAlignmentSize = "
|
file << "const int kParameterAlignmentSize = "
|
||||||
"SYSCALL_PARAMETER_ALIGNMENT_SIZE;" << endl;
|
"SYSCALL_PARAMETER_ALIGNMENT_SIZE;" << endl;
|
||||||
|
file << "const int kLongParameterAlignmentSize = "
|
||||||
|
"SYSCALL_LONG_PARAMETER_ALIGNMENT_SIZE;" << endl;
|
||||||
file << endl;
|
file << endl;
|
||||||
|
|
||||||
file << "SyscallVector* create_syscall_vector() {" << endl;
|
file << "SyscallVector* create_syscall_vector() {" << endl;
|
||||||
@@ -418,12 +427,18 @@ private:
|
|||||||
file << endl;
|
file << endl;
|
||||||
file << "#include \"arch_gensyscalls.h\"" << endl;
|
file << "#include \"arch_gensyscalls.h\"" << endl;
|
||||||
file << 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 << "void dummy() {" << endl;
|
||||||
|
|
||||||
file << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_RETURN_TYPE_ALIGNMENT_SIZE, "
|
file << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_RETURN_TYPE_ALIGNMENT_SIZE, "
|
||||||
"sizeof(SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE));" << endl;
|
"sizeof(SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE));" << endl;
|
||||||
file << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_PARAMETER_ALIGNMENT_SIZE, "
|
file << "DEFINE_COMPUTED_ASM_MACRO(SYSCALL_PARAMETER_ALIGNMENT_SIZE, "
|
||||||
"sizeof(SYSCALL_PARAMETER_ALIGNMENT_TYPE));" << endl;
|
"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;
|
file << endl;
|
||||||
|
|
||||||
// syscalls
|
// syscalls
|
||||||
|
|||||||
@@ -166,6 +166,15 @@ Syscall::AddParameter(int size, const char* typeName, const char* parameterName)
|
|||||||
if (Parameter* previous = LastParameter())
|
if (Parameter* previous = LastParameter())
|
||||||
offset = previous->Offset() + previous->UsedSize();
|
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)
|
int usedSize = (size + kParameterAlignmentSize - 1)
|
||||||
/ kParameterAlignmentSize * kParameterAlignmentSize;
|
/ kParameterAlignmentSize * kParameterAlignmentSize;
|
||||||
const char* alignmentType
|
const char* alignmentType
|
||||||
|
|||||||
@@ -8,8 +8,10 @@
|
|||||||
|
|
||||||
extern const char* const kReturnTypeAlignmentType;
|
extern const char* const kReturnTypeAlignmentType;
|
||||||
extern const char* const kParameterAlignmentType;
|
extern const char* const kParameterAlignmentType;
|
||||||
|
extern const char* const kLongParameterAlignmentType;
|
||||||
extern const int kReturnTypeAlignmentSize;
|
extern const int kReturnTypeAlignmentSize;
|
||||||
extern const int kParameterAlignmentSize;
|
extern const int kParameterAlignmentSize;
|
||||||
|
extern const int kLongParameterAlignmentSize;
|
||||||
|
|
||||||
|
|
||||||
// Type
|
// Type
|
||||||
|
|||||||
Reference in New Issue
Block a user