From 266477c956a805004f2613485ea6209d853bf681 Mon Sep 17 00:00:00 2001 From: servostar Date: Mon, 10 Jun 2024 00:11:53 +0200 Subject: [PATCH] fixed: linker crashing --- dep/lldcl/lldcl.cpp | 4 ++-- src/cfg/opt.h | 1 + src/compiler.c | 4 ++-- src/llvm/link/lld.c | 42 +++++++++++++++++++++++++++++++++++------- src/llvm/parser.c | 14 ++++++-------- 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/dep/lldcl/lldcl.cpp b/dep/lldcl/lldcl.cpp index 30f0c4e..5591dc3 100644 --- a/dep/lldcl/lldcl.cpp +++ b/dep/lldcl/lldcl.cpp @@ -42,9 +42,9 @@ int lld_main(int Argc, const char **Argv, const char **outstr) { lld::Result result = lld::lldMain(Args, stdout_stream, stderr_stream, LLD_COFF_ELF_MINGW_DRIVER); - *outstr = strdup(stdout.c_str()); + *outstr = strdup(stderr.append(stdout).c_str()); - return !result.retCode && result.canRunAgain; + return result.retCode; } } // extern "C" diff --git a/src/cfg/opt.h b/src/cfg/opt.h index 1d1c67e..53fe5f6 100644 --- a/src/cfg/opt.h +++ b/src/cfg/opt.h @@ -23,6 +23,7 @@ typedef struct TargetLinkConfig_t { gboolean fatal_warnings; // colorize linker output bool colorize; + char* output_file; } TargetLinkConfig; typedef enum TargetCompilationMode_t { diff --git a/src/compiler.c b/src/compiler.c index ff9eaa0..9dcad1b 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -57,14 +57,14 @@ static int compile_file_to_ast(AST_NODE_PTR ast, ModuleFile *file) { yyrestart(yyin); lex_reset(); - yyparse(); + int status = yyparse(); // clean up global state // current_file = NULL; root = NULL; yyin = NULL; - return EXIT_SUCCESS; + return status; } /** diff --git a/src/llvm/link/lld.c b/src/llvm/link/lld.c index 1ccc31b..a14c9bf 100644 --- a/src/llvm/link/lld.c +++ b/src/llvm/link/lld.c @@ -59,6 +59,14 @@ TargetLinkConfig* lld_create_link_config(const Target* target, const TargetConfi return NULL; } + { + // output file after linking + gchar* basename = g_strjoin(".", target_config->name, "out", NULL); + gchar* filename = g_build_filename(target_config->output_directory, basename, NULL); + + config->output_file = filename; + } + g_array_append_val(config->object_file_names, target_object); INFO("resolved path of target object: %s", target_object); @@ -83,20 +91,30 @@ TargetLinkConfig* lld_create_link_config(const Target* target, const TargetConfi } GArray* lld_create_lld_arguments(TargetLinkConfig* config) { - GArray* argv = g_array_new(FALSE, FALSE, sizeof(char*)); + GArray* argv = g_array_new(TRUE, FALSE, sizeof(char*)); + + gchar* arg = g_strdup("ld.lld"); + g_array_append_val(argv, arg); if (config->fatal_warnings) { - g_array_append_val(argv, "--fatal-warnings"); + arg = g_strdup("--fatal-warnings"); + g_array_append_val(argv, arg); } if (config->colorize) { - g_array_append_val(argv, "--color-diagnostics=always"); + arg = g_strdup("--color-diagnostics=always"); + g_array_append_val(argv, arg); + } + + { + arg = g_strjoin("", "-o", config->output_file, NULL); + g_array_append_val(argv, arg); } for (guint i = 0; i < config->object_file_names->len; i++) { char* object_file_path = g_array_index(config->object_file_names, char*, i); - char* argument = g_strjoin("", "-l", object_file_path, NULL); - g_array_append_val(argv, argument); + arg = g_strjoin("", object_file_path, NULL); + g_array_append_val(argv, arg); } return argv; @@ -110,6 +128,10 @@ BackendError lld_link_target(TargetLinkConfig* config) { INFO("Linking target..."); + char* arguments = g_strjoinv(" ", (char**) argv->data); + print_message(Info, "%s", arguments); + g_free(arguments); + const char* message = NULL; int status = lld_main((int) argv->len, (const char**) argv->data, &message); @@ -118,12 +140,18 @@ BackendError lld_link_target(TargetLinkConfig* config) { g_array_free(argv, TRUE); if (message != NULL) { - print_message(Warning, "Message from LLD: %s", message); + if (strcmp("", message) != 0) { + print_message(Error, "%s", message); + } + free((void*) message); } - if (status != 0) { + if (status) { err = new_backend_impl_error(Implementation, NULL, "failed to link target"); + print_message(Error, "Linker exited with: %d", status); + } else { + print_message(Info, "Successfully linked target to: %s", config->output_file); } return err; diff --git a/src/llvm/parser.c b/src/llvm/parser.c index bd37eaf..c1f9f23 100644 --- a/src/llvm/parser.c +++ b/src/llvm/parser.c @@ -83,8 +83,6 @@ BackendError emit_module_to_file(LLVMBackendCompileUnit* unit, "invalid codegen file"); } - // TODO: add custom link libraries - INFO("export to file: %s", filename); if (LLVMTargetMachineEmitToFile(target_machine, unit->module, filename, @@ -208,7 +206,6 @@ static BackendError build_module(LLVMBackendCompileUnit* unit, return err; } - // TODO: implement functions err = impl_functions(unit, global_scope, module->functions); char* error = NULL; @@ -245,13 +242,14 @@ BackendError parse_module(const Module* module, const TargetConfig* config) { INFO("Module build successfully..."); Target target = create_target_from_config(config); - export_module(unit, &target, config); + err = export_module(unit, &target, config); + if (err.kind == Success) { + TargetLinkConfig* link_config = lld_create_link_config(&target, config, module); - TargetLinkConfig* link_config = lld_create_link_config(&target, config, module); + lld_link_target(link_config); - lld_link_target(link_config); - - lld_delete_link_config(link_config); + lld_delete_link_config(link_config); + } delete_target(target); }