c-scripting/symbol_set.ld_meta.c

102 lines
2.8 KiB
C

/*
** Symbol Set Link Script Generator for ld
*/
#include "mr4th_base.h"
#include "mr4th_cmdln.h"
#include "mr4th_elf.h"
#include "mr4th_elf.parse.h"
#include "mr4th_base.c"
#include "mr4th_cmdln.c"
#include "mr4th_elf.c"
#include "mr4th_elf.parse.c"
////////////////////////////////
// Entry Point
int main(int argc, char **argv){
os_main_init(argc, argv);
Arena *arena = arena_alloc();
// arguments
String8List command_line_args = os_command_line_arguments();
CMDLN *cmdln = cmdln_from_args(arena, &command_line_args);
String8 output_file_name = cmdln_get_str8(cmdln, str8_lit("out"), 'o');
if (output_file_name.size == 0){
output_file_name = str8_lit("sy.ld");
}
// symbol set names
String8List symbol_set_names = {0};
BUFFER buckets;
buffer_alloc(&buckets, GB(64));
hash_buckets_init(&buckets, 512);
for (U32 input_idx = 0;; input_idx += 1){
// load input file
String8 input_file_name = cmdln_input_from_idx(cmdln, input_idx);
if (input_file_name.size == 0){
break;
}
String8 input_data = os_file_read(arena, input_file_name);
// parse
ELF_Parse *parse = elfp_begin(arena, input_data);
// insert symbol sets inot symbol_set_names
U32 section_count = elfp_section_count(parse);
for (U32 i = 0; i < section_count; i += 1){
String8 secname = elfp_section_name(parse, i);
if (secname.size >= 4 &&
str8_match(secname, str8_lit(".sy."), StringMatchFlag_PrefixMatch)){
String8 syname = str8_skip(secname, 4);
U64 hash = str8_hash(syname);
B32 match = 0;
for (HASH_Node *hash_node = hash_buckets_first(&buckets, hash);
hash_node != 0;
hash_node = hash_node->next){
if (hash_node->hash == hash){
String8Node *node = (String8Node*)PtrFromInt(hash_node->val);
if (str8_match(node->string, syname, 0)){
match = 1;
break;
}
}
}
if (!match){
str8_list_push(arena, &symbol_set_names, syname);
hash_buckets_expand(&buckets, symbol_set_names.node_count);
hash_buckets_insert(arena, &buckets, hash, IntFromPtr(symbol_set_names.last));
}
}
}
}
// print output linker script
STREAM *stream = stream_new();
stream_printf(stream,
"SECTIONS {\n"
" .sy : {\n");
for (String8Node *node = symbol_set_names.first;
node != 0; node = node->next){
stream_printf(stream, " syfirst__%S = .; *(.sy.%S); syopl__%S = .;\n",
&node->string, &node->string, &node->string);
}
stream_printf(stream,
" }\n"
"}\n"
"INSERT AFTER .data;\n");
os_file_write_stream(output_file_name, stream);
return(0);
}