102 lines
2.8 KiB
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);
|
|
}
|