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:
David Karoly
2022-04-08 15:30:06 +00:00
committed by Jérôme Duval
parent b24e59ccbb
commit ab3c8bea07
4 changed files with 29 additions and 2 deletions
@@ -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
+15
View File
@@ -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
+9
View File
@@ -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
+2
View File
@@ -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