gemstone/src/link/lldc/lldc.c

104 lines
2.9 KiB
C

//
// Created by servostar on 8/11/24.
//
#include "lldc.h"
#include <io/files.h>
#include <mem/cache.h>
#include <stdio.h>
extern int lld_main(int Argc, const char **Argv, const char **outstr);
const char* FLAGS[] = {
"--fatal-warnings"
};
const char* get_optimization_level_string(TargetConfig* config)
{
char* buffer = mem_alloc(MemoryNamespaceLld, 6);
sprintf(buffer, "-O%d", config->optimization_level);
return buffer;
}
bool lldc_link(TargetConfig* target_config, TargetLinkConfig* link_config) {
GArray* arguments = mem_new_g_array(MemoryNamespaceLld, sizeof(char*));
char* linker = "ld.lld";
g_array_append_val(arguments, linker);
const char* optimization_level = get_optimization_level_string(target_config);
g_array_append_val(arguments, optimization_level);
// enable dynamic linker on linux
if (extract_sys_from_triple(target_config->triple) == SYS_LINUX)
{
if (target_has_shared_dependency(link_config))
{
// add dynamic linker
print_message(Info, "Enabling dynamic linker for build");
const char* enable_dynamic_linker = "--Bdynamic";
g_array_append_val(arguments, enable_dynamic_linker);
const char* default_dynamic_linker_path = "/usr/bin/ld.so";
const char* dynamic_linker_option = "--dynamic-linker=";
char* buffer = mem_alloc(MemoryNamespaceLld, strlen(dynamic_linker_option) + strlen(default_dynamic_linker_path) + 1);
sprintf(buffer, "%s%s", dynamic_linker_option, default_dynamic_linker_path);
g_array_append_val(arguments, buffer);
}
}
for (int i = 0; i < sizeof(FLAGS)/sizeof(char*); i++) {
char* flag = (char*) FLAGS[i];
g_array_append_val(arguments, flag);
}
for (guint i = 0; i < link_config->object_file_names->len; i++) {
char* obj = g_array_index(link_config->object_file_names, char*, i);
g_array_append_val(arguments, obj);
}
char* output_flag = "-o";
g_array_append_val(arguments, output_flag);
g_array_append_val(arguments, link_config->output_file);
size_t chars = 0;
for (guint i = 0; i < arguments->len; i++) {
chars += strlen(g_array_index(arguments, char*, i)) + 1;
}
char* buffer = mem_alloc(MemoryNamespaceLld, chars + 1);
size_t offset = 0;
for (guint i = 0; i < arguments->len; i++) {
offset += sprintf(buffer + offset, "%s ", g_array_index(arguments, char*, i));
}
print_message(Info, buffer);
const char* message = NULL;
const bool code = lld_main(arguments->len, (const char**) arguments->data, &message);
if (!code) {
print_message(Error, message);
free((void*) message);
}
return code;
}
BinaryDriver* lldc_get_driver() {
BinaryDriver* driver = mem_alloc(MemoryNamespaceLld, sizeof(BinaryDriver));
driver->name = "ld.lld";
driver->link_func = &lldc_link;
return driver;
}