diff options
| author | rajdakin <rajdakin@gmail.com> | 2024-09-20 17:06:25 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-20 17:06:25 +0200 |
| commit | e18846fac57c6b75fe9d918034159415e73c20cd (patch) | |
| tree | 68513d9973e59ec2a606ab0acd0a8b980ac105f9 /wrapperhelper/src | |
| parent | 4aeb8ea1b037f8db84837f723253133277d0995b (diff) | |
| download | box64-e18846fac57c6b75fe9d918034159415e73c20cd.tar.gz box64-e18846fac57c6b75fe9d918034159415e73c20cd.zip | |
[WRAPPERHELPER] Fixed some bugs, added partial multiarch support (#1847)
Diffstat (limited to 'wrapperhelper/src')
| -rw-r--r-- | wrapperhelper/src/generator.c | 83 | ||||
| -rw-r--r-- | wrapperhelper/src/generator.h | 6 | ||||
| -rw-r--r-- | wrapperhelper/src/lang.c | 1 | ||||
| -rw-r--r-- | wrapperhelper/src/machine.c | 94 | ||||
| -rw-r--r-- | wrapperhelper/src/machine.h | 9 | ||||
| -rw-r--r-- | wrapperhelper/src/parse.c | 65 |
6 files changed, 189 insertions, 69 deletions
diff --git a/wrapperhelper/src/generator.c b/wrapperhelper/src/generator.c index 8839f484..cf4d1851 100644 --- a/wrapperhelper/src/generator.c +++ b/wrapperhelper/src/generator.c @@ -964,8 +964,12 @@ static int convert_type_post(string_t *dest, type_t *typ, string_t *obj_name) { } } -int solve_request(request_t *req, type_t *typ, khash_t(conv_map) *conv_map) { - if (typ->typ == TYPE_FUNCTION) { +int solve_request(request_t *req, type_t *emu_typ, type_t *target_typ, khash_t(conv_map) *conv_map) { + if (!type_t_equal(emu_typ, target_typ)) { + printf("Error: TODO: %s: emulated and target types are different\n", string_content(req->obj_name)); + return 0; + } + if (emu_typ->typ == TYPE_FUNCTION) { int needs_D = 0, needs_my = req->def.fun.typ && (req->def.rty == RQT_FUN_MY), needs_2 = 0; int convert_post; size_t idx_conv; @@ -974,15 +978,15 @@ int solve_request(request_t *req, type_t *typ, khash_t(conv_map) *conv_map) { printf("Error: failed to create function type string\n"); return 0; } - if (!convert_type(req->val.fun.typ, typ->val.fun.ret, 1, &needs_D, &needs_my, conv_map, req->obj_name)) goto fun_fail; + if (!convert_type(req->val.fun.typ, emu_typ->val.fun.ret, 1, &needs_D, &needs_my, conv_map, req->obj_name)) goto fun_fail; idx_conv = string_len(req->val.fun.typ); if (!string_add_char(req->val.fun.typ, 'F')) { printf("Error: failed to add convention char\n"); goto fun_fail; } - convert_post = convert_type_post(req->val.fun.typ, typ->val.fun.ret, req->obj_name); + convert_post = convert_type_post(req->val.fun.typ, emu_typ->val.fun.ret, req->obj_name); if (!convert_post) goto fun_fail; - if (typ->val.fun.nargs == (size_t)-1) { + if (emu_typ->val.fun.nargs == (size_t)-1) { printf("Warning: assuming empty specification is void specification\n"); if (convert_post == 1) { if (!string_add_char(req->val.fun.typ, 'v')) { @@ -990,7 +994,7 @@ int solve_request(request_t *req, type_t *typ, khash_t(conv_map) *conv_map) { goto fun_fail; } } - } else if (!typ->val.fun.nargs && !typ->val.fun.has_varargs) { + } else if (!emu_typ->val.fun.nargs && !emu_typ->val.fun.has_varargs) { if (convert_post == 1) { if (!string_add_char(req->val.fun.typ, 'v')) { printf("Error: failed to add void specification char\n"); @@ -998,10 +1002,10 @@ int solve_request(request_t *req, type_t *typ, khash_t(conv_map) *conv_map) { } } } else { - for (size_t i = 0; i < typ->val.fun.nargs; ++i) { - if (!convert_type(req->val.fun.typ, typ->val.fun.args[i], 0, &needs_D, &needs_my, conv_map, req->obj_name)) goto fun_fail; + for (size_t i = 0; i < emu_typ->val.fun.nargs; ++i) { + if (!convert_type(req->val.fun.typ, emu_typ->val.fun.args[i], 0, &needs_D, &needs_my, conv_map, req->obj_name)) goto fun_fail; } - if (typ->val.fun.has_varargs) { + if (emu_typ->val.fun.has_varargs) { if (req->def.fun.typ && (string_len(req->def.fun.typ) == string_len(req->val.fun.typ) + 1) && !strncmp(string_content(req->def.fun.typ), string_content(req->val.fun.typ), string_len(req->val.fun.typ)) @@ -1010,13 +1014,13 @@ int solve_request(request_t *req, type_t *typ, khash_t(conv_map) *conv_map) { if (!string_add_char(req->val.fun.typ, string_content(req->def.fun.typ)[string_len(req->val.fun.typ)])) { printf("Error: failed to add type char '%c' for %s\n", string_content(req->def.fun.typ)[string_len(req->val.fun.typ)], - builtin2str[typ->val.builtin]); + builtin2str[emu_typ->val.builtin]); goto fun_fail; } } else { needs_my = 1; if (!string_add_char(req->val.fun.typ, 'V')) { - printf("Error: failed to add type char 'V' for %s\n", builtin2str[typ->val.builtin]); + printf("Error: failed to add type char 'V' for %s\n", builtin2str[emu_typ->val.builtin]); goto fun_fail; } } @@ -1024,8 +1028,10 @@ int solve_request(request_t *req, type_t *typ, khash_t(conv_map) *conv_map) { } // fun_succ: - // Add 'E' by default - if (needs_my) { + // Add 'E' by default, unless we have the same function as before + if (needs_my && (req->default_comment + || (req->def.rty != RQT_FUN_MY) + || strcmp(string_content(req->def.fun.typ), string_content(req->val.fun.typ)))) { if (!string_add_char_at(req->val.fun.typ, 'E', idx_conv + 1)) { printf("Error: failed to add emu char\n"); goto fun_fail; @@ -1064,45 +1070,62 @@ int solve_request(request_t *req, type_t *typ, khash_t(conv_map) *conv_map) { return 0; } else { int needs_D = 0, needs_my = req->def.dat.has_size && (req->def.rty == RQT_DATAM); - if (is_simple_type(typ, &needs_D, &needs_my, conv_map)) { + if (is_simple_type(emu_typ, &needs_D, &needs_my, conv_map)) { // TODO: Hmm... req->val.rty = needs_my ? RQT_DATAM : req->def.rty; req->val.dat.has_size = 1; - req->val.dat.sz = typ->szinfo.size; + req->val.dat.sz = emu_typ->szinfo.size; req->has_val = 1; return 1; } else { printf("Error: TODO: solve_request for data %s with non-simple type ", string_content(req->obj_name)); - type_print(typ); + type_print(emu_typ); printf("\n"); return 0; } } } -int solve_request_map(request_t *req, khash_t(decl_map) *decl_map, khash_t(conv_map) *conv_map) { - khiter_t it = kh_get(decl_map, decl_map, string_content(req->obj_name)); - if (it == kh_end(decl_map)) { - if (string_content(req->obj_name)[0] != '_') { - printf("Error: %s was not declared\n", string_content(req->obj_name)); - } - return 0; +int solve_request_map(request_t *req, khash_t(decl_map) *emu_decl_map, khash_t(decl_map) *target_decl_map, khash_t(conv_map) *conv_map) { + int hasemu = 0, hastarget = 0; + khiter_t emuit, targetit; + emuit = kh_get(decl_map, emu_decl_map, string_content(req->obj_name)); + if (emuit == kh_end(emu_decl_map)) { + goto failed; + } + if ((kh_val(emu_decl_map, emuit)->storage == STORAGE_STATIC) || (kh_val(emu_decl_map, emuit)->storage == STORAGE_TLS_STATIC)) { + goto failed; + } + targetit = kh_get(decl_map, target_decl_map, string_content(req->obj_name)); + if (targetit == kh_end(target_decl_map)) { + goto failed; } - if ((kh_val(decl_map, it)->storage == STORAGE_STATIC) || (kh_val(decl_map, it)->storage == STORAGE_TLS_STATIC)) { - if (string_content(req->obj_name)[0] != '_') { - printf("Error: %s was not declared\n", string_content(req->obj_name)); + if ((kh_val(target_decl_map, targetit)->storage == STORAGE_STATIC) || (kh_val(target_decl_map, targetit)->storage == STORAGE_TLS_STATIC)) { + goto failed; + } + return solve_request(req, kh_val(emu_decl_map, emuit)->typ, kh_val(target_decl_map, targetit)->typ, conv_map); + +failed: + if (string_content(req->obj_name)[0] != '_') { + if (!hasemu && !hastarget) { + printf("Error: %s was not declared in the emulated and target architectures\n", string_content(req->obj_name)); + } else if (!hasemu) { + printf("Error: %s was not declared only in the emulated architecture\n", string_content(req->obj_name)); + } else if (!hastarget) { + printf("Error: %s was not declared only in the target architecture\n", string_content(req->obj_name)); + } else { + printf("Error: internal error: failed but found for %s\n", string_content(req->obj_name)); } - return 0; } - return solve_request(req, kh_val(decl_map, it)->typ, conv_map); + return 0; } -int solve_references(VECTOR(references) *refs, khash_t(decl_map) *decl_map, khash_t(conv_map) *conv_map) { +int solve_references(VECTOR(references) *refs, khash_t(decl_map) *emu_decl_map, khash_t(decl_map) *target_decl_map, khash_t(conv_map) *conv_map) { int ret = 1; int cond_depth = 0, ok_depth = 0; vector_for(references, ref, refs) { switch (ref->typ) { case REF_REQ: if (ok_depth == cond_depth) { - if (!solve_request_map(&ref->req, decl_map, conv_map)) ret = 0; + if (!solve_request_map(&ref->req, emu_decl_map, target_decl_map, conv_map)) ret = 0; } else { ref->req.ignored = 1; } diff --git a/wrapperhelper/src/generator.h b/wrapperhelper/src/generator.h index 59115eb0..4d8ef120 100644 --- a/wrapperhelper/src/generator.h +++ b/wrapperhelper/src/generator.h @@ -57,8 +57,8 @@ void references_print_check(const VECTOR(references) *refs); void output_from_references(FILE *f, const VECTOR(references) *reqs); VECTOR(references) *references_from_file(const char *filename, FILE *f); // Takes ownership of f -int solve_request(request_t *req, type_t *typ, khash_t(conv_map) *conv_map); -int solve_request_map(request_t *req, khash_t(decl_map) *decl_map, khash_t(conv_map) *conv_map); -int solve_references(VECTOR(references) *reqs, khash_t(decl_map) *decl_map, khash_t(conv_map) *conv_map); +int solve_request(request_t *req, type_t *emu_typ, type_t *target_typ, khash_t(conv_map) *conv_map); +int solve_request_map(request_t *req, khash_t(decl_map) *emu_decl_map, khash_t(decl_map) *target_decl_map, khash_t(conv_map) *conv_map); +int solve_references(VECTOR(references) *reqs, khash_t(decl_map) *emu_decl_map, khash_t(decl_map) *target_decl_map, khash_t(conv_map) *conv_map); #endif // GENERATOR_H diff --git a/wrapperhelper/src/lang.c b/wrapperhelper/src/lang.c index 8aaacc36..c3b5ca19 100644 --- a/wrapperhelper/src/lang.c +++ b/wrapperhelper/src/lang.c @@ -783,6 +783,7 @@ struct_t *struct_new(int is_struct, string_t *tag) { ret->is_struct = is_struct; ret->tag = tag; ret->is_defined = 0; + ret->is_simple = 0; ret->nrefs = 1; return ret; } diff --git a/wrapperhelper/src/machine.c b/wrapperhelper/src/machine.c index 9b54df7a..b89a64ae 100644 --- a/wrapperhelper/src/machine.c +++ b/wrapperhelper/src/machine.c @@ -6,33 +6,34 @@ machine_t machine_x86_64; // machine_t machine_x86; -// machine_t machine_arm64; +machine_t machine_aarch64; #define PASTE2(a, b) a ## b #define PASTE(a, b) PASTE2(a, b) #define STRINGIFY2(a) #a #define STRINGIFY(a) STRINGIFY2(a) #define MACHINE_STR STRINGIFY(CUR_MACHINE) +#define MACHINE_VAL PASTE(machine_, CUR_MACHINE) #define PATHS_OFFSET_PRE 2 // There are two paths that are always included before any other #define ADD_PATH(path) \ - if (!(PASTE(machine_, CUR_MACHINE).include_path[failure_id] = strdup(path))) { \ - printf("Failed to add include path to " MACHINE_STR " platform\n"); \ - goto PASTE(failed_, PASTE(CUR_MACHINE, _paths)); \ - } \ + if (!(MACHINE_VAL.include_path[failure_id] = strdup(path))) { \ + printf("Failed to add include path to " MACHINE_STR " platform\n"); \ + goto PASTE(failed_, PASTE(CUR_MACHINE, _paths)); \ + } \ ++failure_id; #define INIT_PATHS \ - PASTE(machine_, CUR_MACHINE).npaths = PATHS_OFFSET_PRE + npaths + paths_offset_post; \ - if (!(PASTE(machine_, CUR_MACHINE).include_path = \ - malloc(PASTE(machine_, CUR_MACHINE).npaths * sizeof *PASTE(machine_, CUR_MACHINE).include_path))) { \ - printf("Failed to add include path to " MACHINE_STR " platform\n"); \ - goto PASTE(failed_, PASTE(CUR_MACHINE, _nopath)); \ - } \ - failure_id = 0; \ - ADD_PATH("include-override/" MACHINE_STR) \ - ADD_PATH("include-override/common") \ - while (failure_id < PATHS_OFFSET_PRE + npaths) { \ - ADD_PATH(extra_include_path[failure_id - PATHS_OFFSET_PRE]) \ + MACHINE_VAL.npaths = PATHS_OFFSET_PRE + npaths + paths_offset_post; \ + if (!(MACHINE_VAL.include_path = \ + malloc(MACHINE_VAL.npaths * sizeof *MACHINE_VAL.include_path))) { \ + printf("Failed to add include path to " MACHINE_STR " platform\n"); \ + goto PASTE(failed_, PASTE(CUR_MACHINE, _nopath)); \ + } \ + failure_id = 0; \ + ADD_PATH("include-override/" MACHINE_STR) \ + ADD_PATH("include-override/common") \ + while (failure_id < PATHS_OFFSET_PRE + npaths) { \ + ADD_PATH(extra_include_path[failure_id - PATHS_OFFSET_PRE]) \ } int init_machines(size_t npaths, const char *const *extra_include_path) { @@ -49,6 +50,23 @@ int init_machines(size_t npaths, const char *const *extra_include_path) { machine_x86_64.size_long = 8; machine_x86_64.align_valist = 8; machine_x86_64.size_valist = 24; + machine_x86_64.unsigned_char = 1; + machine_x86_64.unnamed_bitfield_aligns = 0; + INIT_PATHS +#define DO_PATH ADD_PATH +#include "machine.gen" +#undef DO_PATH +#undef CUR_MACHINE +#pragma GCC diagnostic pop + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" +#define CUR_MACHINE aarch64 + machine_aarch64.size_long = 8; + machine_aarch64.align_valist = 8; + machine_aarch64.size_valist = 32; + machine_aarch64.unsigned_char = 0; + machine_aarch64.unnamed_bitfield_aligns = 1; INIT_PATHS #define DO_PATH ADD_PATH #include "machine.gen" @@ -58,6 +76,13 @@ int init_machines(size_t npaths, const char *const *extra_include_path) { return 1; +failed_aarch64_paths: + while (failure_id--) { + free(machine_aarch64.include_path[failure_id]); + } + free(machine_aarch64.include_path); +failed_aarch64_nopath: + failure_id = machine_x86_64.npaths; failed_x86_64_paths: while (failure_id--) { free(machine_x86_64.include_path[failure_id]); @@ -71,10 +96,19 @@ static void machine_del(machine_t *m) { for (size_t path_no = m->npaths; path_no--;) { free(m->include_path[path_no]); } - free(machine_x86_64.include_path); + free(m->include_path); } void del_machines(void) { machine_del(&machine_x86_64); + machine_del(&machine_aarch64); +} + +machine_t *convert_machine_name(const char *archname) { + if (!strcmp(archname, "x86_64")) + return &machine_x86_64; + if (!strcmp(archname, "aarch64")) + return &machine_aarch64; + return NULL; } int validate_type(machine_t *target, type_t *typ) { @@ -238,17 +272,33 @@ int validate_type(machine_t *target, type_t *typ) { 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)) { + if ((mem->typ->val.builtin != BTT_BOOL) && (mem->typ->val.builtin != BTT_CHAR) + && (mem->typ->val.builtin != BTT_SHORT) && (mem->typ->val.builtin != BTT_INT) + && (mem->typ->val.builtin != BTT_LONG) && (mem->typ->val.builtin != BTT_LONGLONG) + && (mem->typ->val.builtin != BTT_SCHAR) && (mem->typ->val.builtin != BTT_UCHAR) + && (mem->typ->val.builtin != BTT_SSHORT) && (mem->typ->val.builtin != BTT_USHORT) + && (mem->typ->val.builtin != BTT_SINT) && (mem->typ->val.builtin != BTT_UINT) + && (mem->typ->val.builtin != BTT_SLONG) && (mem->typ->val.builtin != BTT_ULONG) + && (mem->typ->val.builtin != BTT_S8) && (mem->typ->val.builtin != BTT_U8) + && (mem->typ->val.builtin != BTT_S16) && (mem->typ->val.builtin != BTT_U16) + && (mem->typ->val.builtin != BTT_S32) && (mem->typ->val.builtin != BTT_U32) + && (mem->typ->val.builtin != BTT_S64) && (mem->typ->val.builtin != BTT_U64)) { + // C standard: allow _Bool, (s/u)int + // Implementation: also allow (u/s)char, (u/s)short, (u/s)long, (u/s)long long, [u]intx_t 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); + if (mem->typ->szinfo.size < mem->bitfield_width / 8) { + printf("Error: bitfield member %c%s%c has width (%zu) greater than its container size (%zu * 8)\n", + mem->name ? '\'' : '<', + mem->name ? string_content(mem->name) : "unnamed", + mem->name ? '\'' : '>', + mem->bitfield_width, + mem->typ->szinfo.size); return 0; } if (mem->bitfield_width) { - if (mem->name && (max_align < mem->typ->szinfo.align)) max_align = mem->typ->szinfo.align; + if ((target->unnamed_bitfield_aligns || 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) { diff --git a/wrapperhelper/src/machine.h b/wrapperhelper/src/machine.h index b5a5b0ea..566f1d43 100644 --- a/wrapperhelper/src/machine.h +++ b/wrapperhelper/src/machine.h @@ -17,15 +17,14 @@ typedef struct machine_s { // Parsing size_t size_long; size_t align_valist, size_valist; - // TODO: also have info on unnamed bitfields, etc + _Bool unsigned_char; + // Structure parsing + _Bool unnamed_bitfield_aligns; } machine_t; -extern machine_t machine_x86_64; -// extern machine_t machine_x86; -// extern machine_t machine_arm64; - int init_machines(size_t npaths, const char *const *extra_include_path); void del_machines(void); +machine_t *convert_machine_name(const char *archname); int validate_type(machine_t *target, struct type_s *typ); diff --git a/wrapperhelper/src/parse.c b/wrapperhelper/src/parse.c index 4b5b90b9..0254d8df 100644 --- a/wrapperhelper/src/parse.c +++ b/wrapperhelper/src/parse.c @@ -735,7 +735,7 @@ expr_new_token: // expr2 ::= sizeof expr2 // which includes expr2 ::= sizeof ( expr16 ) // expr2 ::= sizeof ( type-name ) - if ((has_level == -1) && (expr_level >= 2) && (tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw = KW_SIZEOF)) { + if ((has_level == -1) && (expr_level >= 2) && (tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_SIZEOF)) { *tok = proc_next_token(prep); if ((tok->tokt != PTOK_SYM) || (tok->tokv.sym != SYM_LPAREN)) { struct expr_partial_op pop = { @@ -765,8 +765,8 @@ expr_new_token: if (!parse_type_name(target, struct_map, type_map, enum_map, builtins, const_map, type_set, prep, tok, SYM_RPAREN, &typ)) { goto failed; } - if (!typ->is_validated || typ->is_incomplete) { - printf("Error: cannot get the size of an incomplete type\n"); + if (!typ->is_validated || typ->is_incomplete || (typ->typ == TYPE_FUNCTION)) { + printf("Error: cannot get the size of a function or incomplete type\n"); type_del(typ); proc_token_del(tok); goto failed; @@ -817,6 +817,51 @@ expr_new_token: goto pushed_expr; } } + // expr2 ::= _Alignof ( type-name ) + if ((has_level == -1) && (expr_level >= 2) && (tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_ALIGNOF)) { + *tok = proc_next_token(prep); + if ((tok->tokt != PTOK_SYM) || (tok->tokv.sym != SYM_LPAREN)) { + printf("Error: invalid _Alignof expression\n"); + proc_token_del(tok); + goto failed; + } + // Empty destructor + *tok = proc_next_token(prep); + type_t *typ = type_new(); + if (!typ) { + printf("Error: failed to create new type info structure\n"); + proc_token_del(tok); + goto failed; + } + if (!parse_type_name(target, struct_map, type_map, enum_map, builtins, const_map, type_set, prep, tok, SYM_RPAREN, &typ)) { + goto failed; + } + if (!typ->is_validated || typ->is_incomplete || (typ->typ == TYPE_FUNCTION)) { + printf("Error: cannot get the alignment of a function or incomplete type\n"); + type_del(typ); + proc_token_del(tok); + goto failed; + } + e = malloc(sizeof *e); + if (!e) { + printf("Error: failed to create new expression atom\n"); + type_del(typ); + proc_token_del(tok); + goto failed; + } + e->typ = ETY_CONST; + e->val.cst.typ = NCT_UINT64; + e->val.cst.val.u64 = typ->szinfo.align; + has_level = 2; + type_del(typ); + if (!e->val.cst.val.u64) { + proc_token_del(tok); + goto failed; + } + // Empty destructor + *tok = proc_next_token(prep); + goto expr_new_token; + } // expr0 ::= ( expr16 ) // expr1 ::= expr1 ( ) @@ -1327,7 +1372,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan return 1; case BTT_VOID: case BTT_BOOL: - case BTT_CHAR: + case BTT_CHAR: // May be signed or unsigned depending on the machine case BTT_SCHAR: case BTT_SHORT: case BTT_SSHORT: @@ -1960,6 +2005,7 @@ parse_cur_token_decl: } typ->is_incomplete = 0; + typ->is_validated = 0; typ->val.st->has_incomplete = 0; // Filled by the validate_type step typ->val.st->nmembers = vector_size(st_members, members); typ->val.st->members = vector_steal(st_members, members); @@ -3178,14 +3224,14 @@ failed0: return 0; } -int finalize_file(file_t *file) { +static int finalize_file(machine_t *target, file_t *file) { #define MARK_SIMPLE(sname) \ it = kh_get(struct_map, file->struct_map, #sname); \ if (it != kh_end(file->struct_map)) { \ kh_val(file->struct_map, it)->is_simple = 1; \ } else { \ it = kh_get(type_map, file->type_map, #sname); \ - if (it != kh_end(file->struct_map)) { \ + if (it != kh_end(file->type_map)) { \ type_t *typ2 = kh_val(file->type_map, it); \ if (typ2->typ != TYPE_STRUCT_UNION) { \ printf("Error: invalid typedef " #sname ": not a structure\n"); \ @@ -3195,6 +3241,7 @@ int finalize_file(file_t *file) { } \ } #define SET_WEAK(converted) \ + validate_type(target, typ); \ typ = type_try_merge(typ, file->type_set); \ it = kh_put(conv_map, file->relaxed_type_conversion, typ, &iret); \ if (iret < 0) { \ @@ -3206,8 +3253,7 @@ int finalize_file(file_t *file) { type_del(typ); \ return 0; \ } \ - kh_val(file->relaxed_type_conversion, it) = string_new_cstr(#converted); \ - type_del(typ); + kh_val(file->relaxed_type_conversion, it) = string_new_cstr(#converted); #define SET_WEAK_PTR_TO(to_typ, converted) \ it = kh_get(type_map, file->type_map, #to_typ); \ if (it != kh_end(file->type_map)) { \ @@ -3216,6 +3262,7 @@ int finalize_file(file_t *file) { printf("Failed to create type " #to_typ "*\n"); \ return 0; \ } \ + ++kh_val(file->type_map, it)->nrefs; \ SET_WEAK(converted) \ } @@ -3417,7 +3464,7 @@ file_t *parse_file(machine_t *target, const char *filename, FILE *file) { success: preproc_del(prep); type_del(typ); - if (!finalize_file(ret)) { + if (!finalize_file(target, ret)) { printf("Error: failed to add builtin aliases\n"); file_del(ret); return NULL; |