The "graph" binary segfaults on this input: asm(""); with gdb saying (edited for clarity): Program received signal SIGSEGV, Segmentation fault. in graph_ep (ep=0x7ffff7f62010) at graph.c:52 (gdb) p ep->entry $1 = (struct instruction *) 0x0 Sadly, the commit that introduced this crash: 15fa4d60e ("topasm: top-level asm is special") was (part of a bigger series) meant to fix crashes because of such toplevel asm statements. Fix this by partially reversing this commit, adding a few checks in some others places (for tools not using the entrypoint) and disabling output in test-parsing.c Fixes: 15fa4d60ebba3025495bb34f0718764336d3dfe0 Reported-by: Vegard Nossum <vegard.nossum@xxxxxxxxx> Analyzed-by: Vegard Nossum <vegard.nossum@xxxxxxxxx> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- dissect.c | 2 ++ graph.c | 2 ++ linearize.c | 8 ++++---- sparse-llvm.c | 3 +++ test-inspect.c | 2 ++ test-parsing.c | 4 +++- 6 files changed, 16 insertions(+), 5 deletions(-) diff --git a/dissect.c b/dissect.c index 14d57bf5b..70d67ccbd 100644 --- a/dissect.c +++ b/dissect.c @@ -575,6 +575,8 @@ static inline struct symbol *do_symbol(struct symbol *sym) type = base_type(sym); + if (!sym->ident) // toplevel asm + return type; if (reporter->r_symdef) reporter->r_symdef(sym); diff --git a/graph.c b/graph.c index be4cf282c..d8a276e11 100644 --- a/graph.c +++ b/graph.c @@ -182,6 +182,8 @@ int main(int argc, char **argv) concat_symbol_list(fsyms, &all_syms); FOR_EACH_PTR(fsyms, sym) { + if (!sym->ident) // toplevel asm + continue; expand_symbol(sym); linearize_symbol(sym); } END_FOR_EACH_PTR(sym); diff --git a/linearize.c b/linearize.c index 30ed2a302..3d21bafab 100644 --- a/linearize.c +++ b/linearize.c @@ -2471,15 +2471,15 @@ static struct entrypoint *linearize_fn(struct symbol *sym, struct symbol *base_t bb = alloc_basic_block(ep, sym->pos); set_activeblock(ep, bb); + entry = alloc_instruction(OP_ENTRY, 0); + add_one_insn(ep, entry); + ep->entry = entry; + if (stmt->type == STMT_ASM) { // top-level asm linearize_asm_statement(ep, stmt); return ep; } - entry = alloc_instruction(OP_ENTRY, 0); - add_one_insn(ep, entry); - ep->entry = entry; - concat_symbol_list(base_type->arguments, &ep->syms); /* FIXME!! We should do something else about varargs.. */ diff --git a/sparse-llvm.c b/sparse-llvm.c index c7a9fbb7e..69da8d4e8 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -1139,6 +1139,9 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep) int nr_args = 0; int i; + if (!sym->ident) // toplevel asm + return; + function.fn = get_sym_value(module, sym); LLVMSetFunctionCallConv(function.fn, LLVMCCallConv); LLVMSetLinkage(function.fn, function_linkage(sym)); diff --git a/test-inspect.c b/test-inspect.c index 63754cb3c..d9bbebf0e 100644 --- a/test-inspect.c +++ b/test-inspect.c @@ -20,6 +20,8 @@ static void expand_symbols(struct symbol_list *list) { struct symbol *sym; FOR_EACH_PTR(list, sym) { + if (!sym->ident) // toplevel asm + continue; expand_symbol(sym); } END_FOR_EACH_PTR(sym); } diff --git a/test-parsing.c b/test-parsing.c index c5bc42e19..d18342f5f 100644 --- a/test-parsing.c +++ b/test-parsing.c @@ -44,6 +44,8 @@ static void clean_up_symbols(struct symbol_list *list) struct symbol *sym; FOR_EACH_PTR(list, sym) { + if (!sym->ident) // toplevel asm + continue; expand_symbol(sym); } END_FOR_EACH_PTR(sym); } @@ -70,7 +72,7 @@ int main(int argc, char **argv) // Simplification clean_up_symbols(list); -#if 1 +#if 0 // Show the end result. show_symbol_list(list, "\n\n"); printf("\n\n"); -- 2.23.0