diff options
| author | rajdakin <rajdakin@gmail.com> | 2024-09-08 22:26:35 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-08 22:26:35 +0200 |
| commit | 26b7a49d8279984a01ea5dc19b05cefff0693e35 (patch) | |
| tree | 3ff9f05a2fb11b0e21ad7cf1829c5a9992ce7728 /wrapperhelper/src/machine.c | |
| parent | fa8a5a20336a64e5b53ea9a151c23941073381c4 (diff) | |
| download | box64-26b7a49d8279984a01ea5dc19b05cefff0693e35.tar.gz box64-26b7a49d8279984a01ea5dc19b05cefff0693e35.zip | |
[WRAPPERHELPER] Fixed preprocessor logic, moved type validation to machine (#1808)
Diffstat (limited to 'wrapperhelper/src/machine.c')
| -rw-r--r-- | wrapperhelper/src/machine.c | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/wrapperhelper/src/machine.c b/wrapperhelper/src/machine.c index 7637a5d3..d20c3e1f 100644 --- a/wrapperhelper/src/machine.c +++ b/wrapperhelper/src/machine.c @@ -102,6 +102,8 @@ int init_machines(size_t npaths, const char *const *extra_include_path) { #pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" #define CUR_MACHINE x86_64 machine_x86_64.size_long = 8; + machine_x86_64.align_valist = 8; + machine_x86_64.size_valist = 24; INIT_PATHS #define DO_PATH INCR_NPATHS #include "machine.gen" @@ -182,3 +184,215 @@ static void machine_del(machine_t *m) { void del_machines(void) { machine_del(&machine_x86_64); } + +int validate_type(machine_t *target, type_t *typ) { + if (typ->is_validated) return 1; + typ->is_validated = 1; + if (typ->is_restrict) { + if (typ->typ != TYPE_PTR) { + printf("Error: only pointers to object types may be restrict-qualified\n"); + return 0; + } + if (typ->val.typ->typ == TYPE_FUNCTION) { + printf("Error: only pointers to object types may be restrict-qualified\n"); + return 0; + } + } + if (typ->is_atomic) { + if ((typ->typ == TYPE_ARRAY) || (typ->typ == TYPE_FUNCTION)) { + printf("Error: array types and function types may not be atomic-qualified\n"); + return 0; + } + } + switch (typ->typ) { + case TYPE_BUILTIN: + switch (typ->val.builtin) { + case BTT_VOID: typ->szinfo.align = typ->szinfo.size = 0; break; + case BTT_BOOL: typ->szinfo.align = typ->szinfo.size = 1; break; + case BTT_CHAR: typ->szinfo.align = typ->szinfo.size = 1; break; + case BTT_SCHAR: typ->szinfo.align = typ->szinfo.size = 1; break; + case BTT_UCHAR: typ->szinfo.align = typ->szinfo.size = 1; break; + case BTT_SHORT: typ->szinfo.align = typ->szinfo.size = 2; break; + case BTT_SSHORT: typ->szinfo.align = typ->szinfo.size = 2; break; + case BTT_USHORT: typ->szinfo.align = typ->szinfo.size = 2; break; + case BTT_INT: typ->szinfo.align = typ->szinfo.size = 4; break; + case BTT_SINT: typ->szinfo.align = typ->szinfo.size = 4; break; + case BTT_UINT: typ->szinfo.align = typ->szinfo.size = 4; break; + case BTT_LONG: typ->szinfo.align = typ->szinfo.size = target->size_long; break; + case BTT_SLONG: typ->szinfo.align = typ->szinfo.size = target->size_long; break; + case BTT_ULONG: typ->szinfo.align = typ->szinfo.size = target->size_long; break; + case BTT_LONGLONG: typ->szinfo.align = typ->szinfo.size = 8; break; + case BTT_SLONGLONG: typ->szinfo.align = typ->szinfo.size = 8; break; + case BTT_ULONGLONG: typ->szinfo.align = typ->szinfo.size = 8; break; + case BTT_INT128: typ->szinfo.align = typ->szinfo.size = 16; break; + case BTT_SINT128: typ->szinfo.align = typ->szinfo.size = 16; break; + case BTT_UINT128: typ->szinfo.align = typ->szinfo.size = 16; break; + case BTT_S8: typ->szinfo.align = typ->szinfo.size = 1; break; + case BTT_U8: typ->szinfo.align = typ->szinfo.size = 1; break; + case BTT_S16: typ->szinfo.align = typ->szinfo.size = 2; break; + case BTT_U16: typ->szinfo.align = typ->szinfo.size = 2; break; + case BTT_S32: typ->szinfo.align = typ->szinfo.size = 4; break; + case BTT_U32: typ->szinfo.align = typ->szinfo.size = 4; break; + case BTT_S64: typ->szinfo.align = typ->szinfo.size = 8; break; + case BTT_U64: typ->szinfo.align = typ->szinfo.size = 8; break; + case BTT_FLOAT: typ->szinfo.align = typ->szinfo.size = 4; break; + case BTT_CFLOAT: typ->szinfo.align = typ->szinfo.size = 8; break; + case BTT_IFLOAT: typ->szinfo.align = typ->szinfo.size = 4; break; + case BTT_DOUBLE: typ->szinfo.align = typ->szinfo.size = 8; break; + case BTT_CDOUBLE: typ->szinfo.align = typ->szinfo.size = 16; break; + case BTT_IDOUBLE: typ->szinfo.align = typ->szinfo.size = 8; break; + case BTT_LONGDOUBLE: typ->szinfo.align = typ->szinfo.size = 16; break; + case BTT_CLONGDOUBLE: typ->szinfo.align = typ->szinfo.size = 32; break; + case BTT_ILONGDOUBLE: typ->szinfo.align = typ->szinfo.size = 16; break; + case BTT_VA_LIST: typ->szinfo.align = target->align_valist; typ->szinfo.size = target->size_valist; break; + default: + printf("Unknown builtin %u, cannot fill size info\n", typ->val.builtin); + return 0; + } + return 1; + case TYPE_ARRAY: + if (typ->val.array.typ->is_incomplete || (typ->val.array.typ->typ == TYPE_FUNCTION)) { + printf("Error: array types must point to complete object types\n"); + return 0; + } + if ((typ->val.array.typ->typ == TYPE_STRUCT_UNION) && typ->val.array.typ->val.st->has_incomplete) { + printf("Error: array types may not (inductively) point to structures which last element is incomplete\n"); + return 0; + } + if ((typ->is_atomic) || (typ->is_const) || (typ->is_restrict) || (typ->is_volatile)) { + // qualifier-type-list in array declaration is only allowed in function argument declaration under certain circumstances + printf("Error: array types may not be qualified\n"); + return 0; + } + if (!validate_type(target, typ->val.array.typ)) return 0; + if (typ->val.array.array_sz == (size_t)-1) { + typ->szinfo.size = 0; + typ->szinfo.align = (typ->val.array.typ->szinfo.align < 16) ? 16 : typ->val.array.typ->szinfo.align; + } else { + typ->szinfo.size = typ->val.array.array_sz * typ->val.array.typ->szinfo.size; + typ->szinfo.align = + ((typ->szinfo.size >= 16) && (typ->val.array.typ->szinfo.align < 16)) ? + 16 : + typ->val.array.typ->szinfo.align; + } + return 1; + case TYPE_PTR: + typ->szinfo.size = target->size_long; + typ->szinfo.align = target->size_long; + return validate_type(target, typ->val.typ); + case TYPE_FUNCTION: + if ((typ->val.fun.ret->typ == TYPE_FUNCTION) || (typ->val.fun.ret->typ == TYPE_ARRAY)) { + printf("Error: function types may not return function or array types\n"); + return 0; + } + if (typ->val.fun.nargs != (size_t)-1) { + for (size_t i = 0; i < typ->val.fun.nargs; ++i) { + // Adjust the argument if necessary + if (typ->val.fun.args[i]->typ == TYPE_ARRAY) { + // Adjustment to pointer + typ->val.fun.args[i]->typ = TYPE_PTR; + typ->val.fun.args[i]->val.typ = typ->val.fun.args[i]->val.array.typ; + } else if (typ->val.fun.args[i]->typ == TYPE_FUNCTION) { + // Adjustment to pointer + type_t *t2 = type_new_ptr(typ->val.fun.args[i]); + if (!t2) { + printf("Error: failed to adjust type of argument from function to pointer\n"); + return 0; + } + typ->val.fun.args[i] = t2; + } + if (!validate_type(target, typ->val.fun.args[i])) return 0; + } + } + typ->szinfo.size = 0; + typ->szinfo.align = 0; + return validate_type(target, typ->val.fun.ret); + case TYPE_STRUCT_UNION: { + if (!typ->val.st->is_defined) return typ->is_incomplete; + size_t max_align = 1, cur_sz = 0, cur_bit = 0; + for (size_t i = 0; i < typ->val.st->nmembers; ++i) { + // Adjust the argument if necessary + st_member_t *mem = &typ->val.st->members[i]; + if (mem->typ->typ == TYPE_FUNCTION) { + printf("Error: structures may not contain function members\n"); + return 0; + } + if (mem->typ->is_incomplete) { + if ((i != typ->val.st->nmembers - 1) || !typ->val.st->is_struct || (mem->typ->typ != TYPE_ARRAY)) { + // The last element of a structure may be a VLA + printf("Error: structures may not contain incomplete members\n"); + return 0; + } + typ->val.st->has_incomplete = 1; + } + if (!validate_type(target, mem->typ)) return 0; + if (!typ->val.st->is_struct && (mem->typ->typ == TYPE_STRUCT_UNION)) { + typ->val.st->has_incomplete |= mem->typ->val.st->has_incomplete; + } + if (mem->is_bitfield) { + if (!typ->val.st->is_struct) { + printf("Error: TODO: bitfield in union\n"); + return 0; + } + if (mem->typ->is_atomic) { + printf("Error: atomic bitfields are not supported\n"); + return 0; + } + if (mem->typ->typ != TYPE_BUILTIN) { + printf("Error: bitfields can only have a specific subset of types\n"); + return 0; + } + if ((mem->typ->val.builtin != BTT_BOOL) && (mem->typ->val.builtin != BTT_INT) + && (mem->typ->val.builtin != BTT_SINT) && (mem->typ->val.builtin != BTT_UINT)) { + printf("Error: bitfields can only have a specific subset of types\n"); + return 0; + } + if (!mem->name && (mem->typ->szinfo.align > max_align)) { + printf("Error: TODO: unnamed bitfield member with greater alignment (width=%zu)\n", mem->bitfield_width); + return 0; + } + if (mem->bitfield_width) { + if (mem->name && (max_align < mem->typ->szinfo.align)) max_align = mem->typ->szinfo.align; + size_t cur_block = cur_sz / mem->typ->szinfo.align; + size_t end_block = (cur_sz + (cur_bit + mem->bitfield_width - 1) / 8) / mem->typ->szinfo.align; + if (cur_block == end_block) { + cur_bit += mem->bitfield_width; + cur_sz += cur_bit / 8; + cur_bit %= 8; + } else { + cur_sz = ((cur_sz + mem->typ->szinfo.align - 1) & ~(mem->typ->szinfo.align - 1)) + (mem->bitfield_width / 8); + cur_bit = mem->bitfield_width % 8; + } + } else { + if (max_align < mem->typ->szinfo.align) max_align = mem->typ->szinfo.align; + cur_sz = ((cur_sz + mem->typ->szinfo.align - 1) & ~(mem->typ->szinfo.align - 1)) + mem->typ->szinfo.size; + printf("Error: TODO: unnamed zero-width bitfield member\n"); + return 0; + } + } else { + if (max_align < mem->typ->szinfo.align) max_align = mem->typ->szinfo.align; + if (typ->val.st->is_struct) { + if (cur_bit) { + cur_bit = 0; + ++cur_sz; + } + cur_sz = ((cur_sz + mem->typ->szinfo.align - 1) & ~(mem->typ->szinfo.align - 1)) + mem->typ->szinfo.size; + } else { + if (cur_sz < mem->typ->szinfo.size) cur_sz = mem->typ->szinfo.size; + } + } + } + if (cur_bit) { + cur_bit = 0; + ++cur_sz; + } + typ->szinfo.align = max_align; + typ->szinfo.size = (cur_sz + max_align - 1) & ~(max_align - 1); + return 1; } + case TYPE_ENUM: + if (typ->val.typ->typ != TYPE_BUILTIN) return 0; + typ->szinfo = typ->val.typ->szinfo; + return 1; + } + return 0; +} |