mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-26 01:13:44 +00:00
pass over COFF layer
- updated naming convention on structs, enums, and macros to conform with code base style - moved related structs closer to each other - moved parser code to separate file
This commit is contained in:
+113
-111
@@ -36,6 +36,7 @@
|
||||
#include "path/path.h"
|
||||
#include "coff/coff.h"
|
||||
#include "coff/coff_enum.h"
|
||||
#include "coff/coff_parse.h"
|
||||
#include "pe/pe.h"
|
||||
#include "codeview/codeview.h"
|
||||
#include "codeview/codeview_parse.h"
|
||||
@@ -50,6 +51,7 @@
|
||||
#include "path/path.c"
|
||||
#include "coff/coff.c"
|
||||
#include "coff/coff_enum.c"
|
||||
#include "coff/coff_parse.c"
|
||||
#include "pe/pe.c"
|
||||
#include "codeview/codeview.c"
|
||||
#include "codeview/codeview_enum.c"
|
||||
@@ -391,8 +393,8 @@ lnk_res_string_id_is_before(void *raw_a, void *raw_b)
|
||||
{
|
||||
PE_Resource *a = raw_a;
|
||||
PE_Resource *b = raw_b;
|
||||
Assert(a->id.type == COFF_ResourceIDType_STRING);
|
||||
Assert(b->id.type == COFF_ResourceIDType_STRING);
|
||||
Assert(a->id.type == COFF_ResourceIDType_String);
|
||||
Assert(b->id.type == COFF_ResourceIDType_String);
|
||||
int is_before = str8_is_before_case_sensitive(&a->id.u.string, &b->id.u.string);
|
||||
return is_before;
|
||||
}
|
||||
@@ -402,8 +404,8 @@ lnk_res_number_id_is_before(void *raw_a, void *raw_b)
|
||||
{
|
||||
PE_Resource *a = raw_a;
|
||||
PE_Resource *b = raw_b;
|
||||
Assert(a->id.type == COFF_ResourceIDType_NUMBER);
|
||||
Assert(b->id.type == COFF_ResourceIDType_NUMBER);
|
||||
Assert(a->id.type == COFF_ResourceIDType_Number);
|
||||
Assert(b->id.type == COFF_ResourceIDType_Number);
|
||||
int is_before = u16_is_before(&a->id.u.number, &b->id.u.number);
|
||||
return is_before;
|
||||
}
|
||||
@@ -426,7 +428,7 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
|
||||
dir_data_chunk->sort_idx = str8_lit("c");
|
||||
|
||||
PE_Resource root_wrapper = {0};
|
||||
root_wrapper.id.type = COFF_ResourceIDType_NUMBER;
|
||||
root_wrapper.id.type = COFF_ResourceIDType_Number;
|
||||
root_wrapper.id.u.number = 0;
|
||||
root_wrapper.kind = PE_ResDataKind_DIR;
|
||||
root_wrapper.u.dir = root_dir;
|
||||
@@ -460,11 +462,11 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
|
||||
stack->coff_entry_chunk = lnk_section_push_chunk_data(dir_sect, stack->coff_entry_array_chunk, str8_struct(entry), str8_zero());
|
||||
|
||||
switch (res->id.type) {
|
||||
case COFF_ResourceIDType_NUMBER: {
|
||||
case COFF_ResourceIDType_Number: {
|
||||
entry->name.id = res->id.u.number;
|
||||
} break;
|
||||
|
||||
case COFF_ResourceIDType_STRING: {
|
||||
case COFF_ResourceIDType_String: {
|
||||
// TODO: we can make string table smaller by reusing offsets for same strings
|
||||
|
||||
// not sure why high bit has to be turned on here since number id and string id entries are
|
||||
@@ -480,7 +482,7 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
|
||||
lnk_section_push_reloc(dir_sect, stack->coff_entry_chunk, LNK_Reloc_SECT_REL, OffsetOf(COFF_ResourceDirEntry, name.offset), name_symbol);
|
||||
} break;
|
||||
|
||||
case COFF_ResourceIDType_NULL: break;
|
||||
case COFF_ResourceIDType_Null: break;
|
||||
|
||||
default: InvalidPath;
|
||||
}
|
||||
@@ -499,14 +501,14 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
|
||||
|
||||
// push sub directory chunk layout
|
||||
LNK_Chunk *dir_node_chunk = lnk_section_push_chunk_list(dir_sect, dir_tree_chunk, str8_zero());
|
||||
dir_node_chunk->align = COFF_RES_ALIGN;
|
||||
dir_node_chunk->align = COFF_ResourceAlign;
|
||||
LNK_Chunk *dir_header_chunk = lnk_section_push_chunk_data(dir_sect, dir_node_chunk, str8_struct(dir_header), str8_zero());
|
||||
LNK_Chunk *entry_array_chunk = lnk_section_push_chunk_list(dir_sect, dir_node_chunk, str8_zero());
|
||||
lnk_chunk_set_debugf(dir_sect->arena, dir_header_chunk, "DIR_HEADER_CHUNK");
|
||||
lnk_chunk_set_debugf(dir_sect->arena, entry_array_chunk, "DIR_ENTRY_ARRAY_CHUNK");
|
||||
|
||||
// push symbols to patch coff entry
|
||||
LNK_Symbol *flag_symbol = lnk_make_defined_symbol_va(symtab->arena->v[0], flag_name, LNK_DefinedSymbolVisibility_Internal, 0, COFF_RESOURCE_SUB_DIR_FLAG);
|
||||
LNK_Symbol *flag_symbol = lnk_make_defined_symbol_va(symtab->arena->v[0], flag_name, LNK_DefinedSymbolVisibility_Internal, 0, COFF_Resource_SubDirFlag);
|
||||
LNK_Symbol *offset_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], offset_name, LNK_DefinedSymbolVisibility_Internal, 0, dir_header_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, flag_symbol); // set high bit to indicate directory
|
||||
lnk_symbol_table_push(symtab, offset_symbol); // write offset for this directory
|
||||
@@ -542,8 +544,8 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
|
||||
LNK_Chunk *resource_data_chunk = lnk_section_push_chunk_data(data_sect, data_sect->root, res->u.coff_res.data, str8_zero());
|
||||
|
||||
// windows errors out on unaligned data
|
||||
coff_resource_data_entry_chunk->align = COFF_RES_ALIGN;
|
||||
resource_data_chunk->align = COFF_RES_ALIGN;
|
||||
coff_resource_data_entry_chunk->align = COFF_ResourceAlign;
|
||||
resource_data_chunk->align = COFF_ResourceAlign;
|
||||
|
||||
// relocate data
|
||||
String8 resource_data_symbol_name = push_str8f(symtab->arena->v[0], "$R%06X", total_res_count);
|
||||
@@ -725,8 +727,8 @@ lnk_make_res_obj(TP_Context *tp,
|
||||
COFF_Symbol16 coff_feat00 = {0};
|
||||
MemoryCopyStr8(&coff_feat00.name, str8_lit("@feat.00"));
|
||||
coff_feat00.value = MSCRT_FeatFlag_HAS_SAFE_SEH|MSCRT_FeatFlag_UNKNOWN_4;
|
||||
coff_feat00.section_number = COFF_SYMBOL_ABS_SECTION_16;
|
||||
coff_feat00.storage_class = COFF_SymStorageClass_STATIC;
|
||||
coff_feat00.section_number = COFF_Symbol_AbsSection16;
|
||||
coff_feat00.storage_class = COFF_SymStorageClass_Static;
|
||||
coff_symbol16_list_push(scratch.arena, &coff_symbol_list, coff_feat00);
|
||||
|
||||
// emit coff symbols for section definitions
|
||||
@@ -749,7 +751,7 @@ lnk_make_res_obj(TP_Context *tp,
|
||||
coff_sect_symbol.value = 0;
|
||||
coff_sect_symbol.section_number = sect->isect;
|
||||
coff_sect_symbol.aux_symbol_count = 1;
|
||||
coff_sect_symbol.storage_class = COFF_SymStorageClass_STATIC;
|
||||
coff_sect_symbol.storage_class = COFF_SymStorageClass_Static;
|
||||
|
||||
Assert(sect->isect <= max_U16);
|
||||
COFF_SymbolSecDef secdef = {0};
|
||||
@@ -805,7 +807,7 @@ lnk_make_res_obj(TP_Context *tp,
|
||||
MemoryCopyStr8(&coff_symbol.name, symbol_name);
|
||||
coff_symbol.value = symbol_offset;
|
||||
coff_symbol.section_number = symbol_sect->isect;
|
||||
coff_symbol.storage_class = COFF_SymStorageClass_STATIC;
|
||||
coff_symbol.storage_class = COFF_SymStorageClass_Static;
|
||||
coff_symbol16_list_push(scratch.arena, &coff_symbol_list, coff_symbol);
|
||||
|
||||
// push coff reloc
|
||||
@@ -843,7 +845,7 @@ lnk_make_res_obj(TP_Context *tp,
|
||||
}
|
||||
}
|
||||
|
||||
LNK_Section *misc_sect = lnk_section_table_push(st, str8_lit(".misc"), COFF_SectionFlag_LNK_INFO|COFF_SectionFlag_LNK_REMOVE);
|
||||
LNK_Section *misc_sect = lnk_section_table_push(st, str8_lit(".misc"), COFF_SectionFlag_LnkInfo|COFF_SectionFlag_LnkRemove);
|
||||
misc_sect->emit_header = 0;
|
||||
|
||||
// serialize coff symbol list
|
||||
@@ -863,27 +865,27 @@ lnk_make_res_obj(TP_Context *tp,
|
||||
// build obj header
|
||||
{
|
||||
// init header
|
||||
COFF_Header *coff_header = push_array(header_sect->arena, COFF_Header, 1);
|
||||
coff_header->machine = machine;
|
||||
coff_header->section_count = 0; // relocated
|
||||
coff_header->time_stamp = time_stamp;
|
||||
coff_header->symbol_table_foff = 0; // relocated
|
||||
coff_header->symbol_count = 0; // relocated
|
||||
coff_header->optional_header_size = 0; // no PE header in obj
|
||||
coff_header->flags = COFF_Flag_32BIT_MACHINE;
|
||||
COFF_FileHeader *file_header = push_array(header_sect->arena, COFF_FileHeader, 1);
|
||||
file_header->machine = machine;
|
||||
file_header->section_count = 0; // relocated
|
||||
file_header->time_stamp = time_stamp;
|
||||
file_header->symbol_table_foff = 0; // relocated
|
||||
file_header->symbol_count = 0; // relocated
|
||||
file_header->optional_header_size = 0; // no PE header in obj
|
||||
file_header->flags = COFF_FileHeaderFlag_32BitMachine;
|
||||
|
||||
// push coff header chunk
|
||||
String8 coff_header_data = str8_struct(coff_header);
|
||||
LNK_Chunk *coff_header_chunk = lnk_section_push_chunk_data(header_sect, header_sect->root, coff_header_data, str8_zero());
|
||||
String8 file_header_data = str8_struct(file_header);
|
||||
LNK_Chunk *file_header_chunk = lnk_section_push_chunk_data(header_sect, header_sect->root, file_header_data, str8_zero());
|
||||
|
||||
// relocate coff header fields
|
||||
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc(header_sect, coff_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_Header, symbol_table_foff), coff_symbol_table_symbol);
|
||||
lnk_section_push_reloc(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, symbol_count), coff_symbol_count_symbol);
|
||||
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_FileHeader, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc(header_sect, file_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_FileHeader, symbol_table_foff), coff_symbol_table_symbol);
|
||||
lnk_section_push_reloc(header_sect, file_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_FileHeader, symbol_count), coff_symbol_count_symbol);
|
||||
|
||||
// push coff header symbol
|
||||
LNK_Symbol *coff_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], str8_lit(LNK_COFF_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_header_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, coff_header_symbol);
|
||||
LNK_Symbol *file_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], str8_lit(LNK_COFF_FILE_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, file_header_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, file_header_symbol);
|
||||
}
|
||||
|
||||
// build section headers
|
||||
@@ -923,7 +925,7 @@ lnk_make_res_obj(TP_Context *tp,
|
||||
}
|
||||
|
||||
// patch file fields
|
||||
if (~sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
|
||||
if (~sect->flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
LNK_Symbol *sect_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, sect->name);
|
||||
lnk_section_push_reloc(header_sect, coff_sect_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect_symbol);
|
||||
lnk_section_push_reloc(header_sect, coff_sect_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect_symbol);
|
||||
@@ -1034,13 +1036,13 @@ lnk_make_linker_coff_obj(TP_Context *tp,
|
||||
header_sect->emit_header = 0;
|
||||
|
||||
{
|
||||
COFF_Header *coff_header = push_array(header_sect->arena, COFF_Header, 1);
|
||||
coff_header->machine = machine;
|
||||
coff_header->section_count = 0;
|
||||
coff_header->time_stamp = time_stamp;
|
||||
COFF_FileHeader *file_header = push_array(header_sect->arena, COFF_FileHeader, 1);
|
||||
file_header->machine = machine;
|
||||
file_header->section_count = 0;
|
||||
file_header->time_stamp = time_stamp;
|
||||
|
||||
LNK_Chunk *coff_header_chunk = lnk_section_push_chunk_raw(header_sect, header_sect->root, coff_header, sizeof(*coff_header), str8_zero());
|
||||
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
LNK_Chunk *file_header_chunk = lnk_section_push_chunk_raw(header_sect, header_sect->root, file_header, sizeof(*file_header), str8_zero());
|
||||
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_FileHeader, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1139,7 +1141,7 @@ lnk_make_linker_coff_obj(TP_Context *tp,
|
||||
}
|
||||
|
||||
// emit relocs for file fields
|
||||
if (~sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
|
||||
if (~sect->flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
LNK_Symbol *sect_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, sect->name);
|
||||
lnk_section_push_reloc(header_sect, coff_sect_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect_symbol);
|
||||
lnk_section_push_reloc(header_sect, coff_sect_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect_symbol);
|
||||
@@ -1232,12 +1234,12 @@ lnk_push_input_from_lazy(Arena *arena, PathStyle path_style, LNK_LazySymbol *laz
|
||||
COFF_DataType member_type = coff_data_type_from_data(member_info.data);
|
||||
|
||||
switch (member_type) {
|
||||
case COFF_DataType_IMPORT: {
|
||||
case COFF_DataType_Import: {
|
||||
LNK_InputImport *input = lnk_input_import_list_push(arena, input_import_list);
|
||||
input->import_header = coff_archive_import_from_data(member_info.data);
|
||||
} break;
|
||||
case COFF_DataType_BIG_OBJ:
|
||||
case COFF_DataType_OBJ: {
|
||||
case COFF_DataType_BigObj:
|
||||
case COFF_DataType_Obj: {
|
||||
String8 obj_path = coff_parse_long_name(lazy->lib->long_names, member_info.header.name);
|
||||
|
||||
// obj path in thin archive has slash appended which screws up
|
||||
@@ -1279,12 +1281,12 @@ lnk_push_linker_symbols(LNK_SymbolTable *symtab, COFF_MachineType machine)
|
||||
// passing it around as a function argument.
|
||||
//
|
||||
// 100h: lea rax, [rip + ffffff00h] ; -100h
|
||||
LNK_Symbol *image_base = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("__ImageBase"), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_ANY, 0);
|
||||
LNK_Symbol *image_base = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("__ImageBase"), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelect_Any, 0);
|
||||
|
||||
{ // load config symbols
|
||||
if (machine == COFF_MachineType_X86) {
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
|
||||
if (machine == COFF_Machine_X86) {
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelect_NoDuplicates, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelect_NoDuplicates, 0);
|
||||
}
|
||||
|
||||
// TODO: investigate IMAGE_ENCLAVE_CONFIG 32/64
|
||||
@@ -1409,7 +1411,7 @@ lnk_build_debug_rdi(LNK_SectionTable *st,
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
LNK_Section *rdi_sect = lnk_section_table_push(st, str8_lit(".raddbg"), COFF_SectionFlag_CNT_INITIALIZED_DATA|COFF_SectionFlag_MEM_READ);
|
||||
LNK_Section *rdi_sect = lnk_section_table_push(st, str8_lit(".raddbg"), COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead);
|
||||
|
||||
// push chunks
|
||||
String8 debug_rdi = pe_make_debug_header_rdi(rdi_sect->arena, guid, rdi_path);
|
||||
@@ -1488,7 +1490,7 @@ lnk_build_guard_tables(TP_Context *tp,
|
||||
if (lnk_chunk_is_discarded(chunk)) {
|
||||
continue;
|
||||
}
|
||||
if (~chunk->flags & COFF_SectionFlag_CNT_CODE) {
|
||||
if (~chunk->flags & COFF_SectionFlag_CntCode) {
|
||||
continue;
|
||||
}
|
||||
Assert(chunk->type == LNK_Chunk_Leaf);
|
||||
@@ -1508,7 +1510,7 @@ lnk_build_guard_tables(TP_Context *tp,
|
||||
if (symbol_chunk->type != LNK_Chunk_Leaf) {
|
||||
continue;
|
||||
}
|
||||
if (~symbol_chunk->flags & COFF_SectionFlag_CNT_CODE) {
|
||||
if (~symbol_chunk->flags & COFF_SectionFlag_CntCode) {
|
||||
continue;
|
||||
}
|
||||
lnk_symbol_list_push(scratch.arena, &guard_symbol_list_table[GUARD_FIDS], symbol);
|
||||
@@ -1603,7 +1605,7 @@ lnk_build_guard_tables(TP_Context *tp,
|
||||
}
|
||||
|
||||
// TODO: emit table for SEH on X86
|
||||
if (machine == COFF_MachineType_X86) {
|
||||
if (machine == COFF_Machine_X86) {
|
||||
lnk_not_implemented("__safe_se_handler_table");
|
||||
lnk_not_implemented("__safe_se_handler_count");
|
||||
}
|
||||
@@ -2078,7 +2080,7 @@ internal LNK_Chunk *
|
||||
lnk_build_coff_file_header(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_Chunk *parent,
|
||||
COFF_MachineType machine, COFF_TimeStamp time_stamp, PE_ImageFileCharacteristics file_characteristics)
|
||||
{
|
||||
COFF_Header *file_header = push_array_no_zero(header_sect->arena, COFF_Header, 1);
|
||||
COFF_FileHeader *file_header = push_array_no_zero(header_sect->arena, COFF_FileHeader, 1);
|
||||
file_header->machine = machine;
|
||||
file_header->time_stamp = time_stamp;
|
||||
file_header->symbol_table_foff = 0;
|
||||
@@ -2088,16 +2090,16 @@ lnk_build_coff_file_header(LNK_SymbolTable *symtab, LNK_Section *header_sect, LN
|
||||
file_header->flags = file_characteristics;
|
||||
|
||||
LNK_Chunk *file_header_chunk = lnk_section_push_chunk_raw(header_sect, parent, file_header, sizeof(*file_header), str8_zero());
|
||||
lnk_chunk_set_debugf(header_sect->arena, file_header_chunk, LNK_COFF_HEADER_SYMBOL_NAME);
|
||||
lnk_chunk_set_debugf(header_sect->arena, file_header_chunk, LNK_COFF_FILE_HEADER_SYMBOL_NAME);
|
||||
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, file_header_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_FILE_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, file_header_chunk, 0, 0, 0);
|
||||
|
||||
// :section_count
|
||||
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_16, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_16, OffsetOf(COFF_FileHeader, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
|
||||
// :optional_header_size
|
||||
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_16, OffsetOf(COFF_Header, optional_header_size), str8_lit(LNK_PE_OPT_HEADER_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_16, OffsetOf(COFF_Header, optional_header_size), str8_lit(LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_16, OffsetOf(COFF_FileHeader, optional_header_size), str8_lit(LNK_PE_OPT_HEADER_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_16, OffsetOf(COFF_FileHeader, optional_header_size), str8_lit(LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
|
||||
return file_header_chunk;
|
||||
}
|
||||
@@ -2173,17 +2175,17 @@ lnk_build_pe_optional_header_x64(LNK_SymbolTable *symtab,
|
||||
continue;
|
||||
}
|
||||
// :sizeof_uninited_data
|
||||
if (sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
|
||||
if (sect->flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_CHUNK_SIZE_VIRT_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_uninited_data), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
}
|
||||
|
||||
// :sizeof_inited_data
|
||||
if (sect->flags & COFF_SectionFlag_CNT_INITIALIZED_DATA) {
|
||||
if (sect->flags & COFF_SectionFlag_CntInitializedData) {
|
||||
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_inited_data), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
}
|
||||
|
||||
// :sizeof_code
|
||||
if (sect->flags & COFF_SectionFlag_CNT_CODE) {
|
||||
if (sect->flags & COFF_SectionFlag_CntCode) {
|
||||
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_code), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
}
|
||||
|
||||
@@ -2202,7 +2204,7 @@ lnk_build_pe_optional_header_x64(LNK_SymbolTable *symtab,
|
||||
lnk_section_push_reloc(header_sect, opt_header_chunk, LNK_Reloc_FILE_ALIGN_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_headers), &g_null_symbol);
|
||||
|
||||
// :check_sum
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_CHECKSUM_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, opt_header_chunk, OffsetOf(PE_OptionalHeader32Plus, check_sum), COFF_ComdatSelectType_NODUPLICATES, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_CHECKSUM_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, opt_header_chunk, OffsetOf(PE_OptionalHeader32Plus, check_sum), COFF_ComdatSelect_NoDuplicates, 0);
|
||||
|
||||
// :data_dir_count
|
||||
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(PE_OptionalHeader32Plus, data_dir_count), str8_lit(LNK_PE_DIRECTORY_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
|
||||
@@ -2272,11 +2274,11 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect,
|
||||
}
|
||||
|
||||
// push COFF header array chunk
|
||||
LNK_Chunk *coff_header_array_chunk = lnk_section_push_chunk_list(header_sect, parent_chunk, str8_zero());
|
||||
lnk_chunk_set_debugf(header_sect->arena, coff_header_array_chunk, LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME);
|
||||
LNK_Chunk *COFF_FileHeader_array_chunk = lnk_section_push_chunk_list(header_sect, parent_chunk, str8_zero());
|
||||
lnk_chunk_set_debugf(header_sect->arena, COFF_FileHeader_array_chunk, LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME);
|
||||
|
||||
// define symbol for COFF header array
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_header_array_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, COFF_FileHeader_array_chunk, 0, 0, 0);
|
||||
|
||||
// push headers
|
||||
for (LNK_Section *sect = §_arr.v[0], *sect_opl = sect + sect_arr.count; sect < sect_opl; sect += 1) {
|
||||
@@ -2286,38 +2288,38 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect,
|
||||
if (!sect->has_layout) {
|
||||
continue;
|
||||
}
|
||||
COFF_SectionHeader *coff_header = push_array_no_zero(header_sect->arena, COFF_SectionHeader, 1);
|
||||
COFF_SectionHeader *COFF_FileHeader = push_array_no_zero(header_sect->arena, COFF_SectionHeader, 1);
|
||||
|
||||
// TODO: for objs we can store long name in string table and write here /offset
|
||||
if (sect->name.size > sizeof(coff_header->name)) {
|
||||
if (sect->name.size > sizeof(COFF_FileHeader->name)) {
|
||||
lnk_error(LNK_Warning_LongSectionName, "not enough space in COFF section header to store entire name \"%S\"", sect->name);
|
||||
}
|
||||
|
||||
MemorySet(&coff_header->name[0], 0, sizeof(coff_header->name));
|
||||
MemoryCopy(&coff_header->name[0], sect->name.str, Min(sect->name.size, sizeof(coff_header->name)));
|
||||
coff_header->vsize = 0; // :vsize
|
||||
coff_header->voff = 0; // :voff
|
||||
coff_header->fsize = 0; // :fsize
|
||||
coff_header->foff = 0; // :foff
|
||||
coff_header->relocs_foff = 0; // :relocs_foff
|
||||
coff_header->lines_foff = 0; // obsolete
|
||||
coff_header->reloc_count = 0; // :reloc_count
|
||||
coff_header->line_count = 0; // obsolete
|
||||
coff_header->flags = sect->flags;
|
||||
MemorySet(&COFF_FileHeader->name[0], 0, sizeof(COFF_FileHeader->name));
|
||||
MemoryCopy(&COFF_FileHeader->name[0], sect->name.str, Min(sect->name.size, sizeof(COFF_FileHeader->name)));
|
||||
COFF_FileHeader->vsize = 0; // :vsize
|
||||
COFF_FileHeader->voff = 0; // :voff
|
||||
COFF_FileHeader->fsize = 0; // :fsize
|
||||
COFF_FileHeader->foff = 0; // :foff
|
||||
COFF_FileHeader->relocs_foff = 0; // :relocs_foff
|
||||
COFF_FileHeader->lines_foff = 0; // obsolete
|
||||
COFF_FileHeader->reloc_count = 0; // :reloc_count
|
||||
COFF_FileHeader->line_count = 0; // obsolete
|
||||
COFF_FileHeader->flags = sect->flags;
|
||||
|
||||
// push chunk
|
||||
LNK_Chunk *coff_header_chunk = lnk_section_push_chunk_raw(header_sect, coff_header_array_chunk, coff_header, sizeof(*coff_header), str8_zero());
|
||||
LNK_Chunk *COFF_FileHeader_chunk = lnk_section_push_chunk_raw(header_sect, COFF_FileHeader_array_chunk, COFF_FileHeader, sizeof(*COFF_FileHeader), str8_zero());
|
||||
|
||||
// :vsize
|
||||
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_CHUNK_SIZE_VIRT_32, OffsetOf(COFF_SectionHeader, vsize), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_CHUNK_SIZE_VIRT_32, OffsetOf(COFF_SectionHeader, vsize), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
// :voff
|
||||
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(COFF_SectionHeader, voff), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(COFF_SectionHeader, voff), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
|
||||
if (~sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
|
||||
if (~sect->flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
// :fsize
|
||||
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
// :foff
|
||||
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect->name, LNK_SymbolScopeFlag_Internal);
|
||||
}
|
||||
|
||||
// TODO: :reloc_off
|
||||
@@ -2325,10 +2327,10 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect,
|
||||
}
|
||||
|
||||
// push symbol for section header count
|
||||
U64 header_count = coff_header_array_chunk->u.list->count;
|
||||
U64 header_count = COFF_FileHeader_array_chunk->u.list->count;
|
||||
lnk_symbol_table_push_defined_va(symtab, str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, header_count);
|
||||
|
||||
return coff_header_array_chunk;
|
||||
return COFF_FileHeader_array_chunk;
|
||||
}
|
||||
|
||||
internal LNK_Chunk *
|
||||
@@ -2371,7 +2373,7 @@ lnk_build_win32_image_header(LNK_SymbolTable *symtab,
|
||||
lnk_build_pe_magic(symtab, header_sect, pe_magic_chunk);
|
||||
lnk_build_coff_file_header(symtab, header_sect, coff_file_header_chunk, config->machine, config->time_stamp, config->file_characteristics);
|
||||
switch (config->machine) {
|
||||
case COFF_MachineType_X64: {
|
||||
case COFF_Machine_X64: {
|
||||
lnk_build_pe_optional_header_x64(symtab,
|
||||
header_sect,
|
||||
pe_optional_chunk,
|
||||
@@ -2455,13 +2457,13 @@ THREAD_POOL_TASK_FUNC(lnk_weak_symbol_finder)
|
||||
|
||||
LNK_Symbol *lazy = 0;
|
||||
switch (weak->lookup_type) {
|
||||
case COFF_WeakExtType_NOLIBRARY: {
|
||||
case COFF_WeakExt_NoLibrary: {
|
||||
// NOLIBRARY means weak symbol should be resolved in case where strong definition pulls in lib member.
|
||||
} break;
|
||||
case COFF_WeakExtType_SEARCH_LIBRARY: {
|
||||
case COFF_WeakExt_SearchLibrary: {
|
||||
lazy = lnk_symbol_table_search(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name);
|
||||
} break;
|
||||
case COFF_WeakExtType_SEARCH_ALIAS: {
|
||||
case COFF_WeakExt_SearchAlias: {
|
||||
lazy = lnk_symbol_table_search(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name);
|
||||
if (!lazy) {
|
||||
if (str8_match_lit(".weak.", symbol->name, StringMatchFlag_RightSideSloppy)) {
|
||||
@@ -2964,9 +2966,9 @@ lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab)
|
||||
LNK_Section *sect = §_node->data;
|
||||
if (sect->has_layout) {
|
||||
U64 sect_size = lnk_file_size_from_chunk_ref(sect_id_map, sect->root->ref);
|
||||
if (sect->flags & COFF_SectionFlag_CNT_CODE) {
|
||||
if (sect->flags & COFF_SectionFlag_CntCode) {
|
||||
code_size += sect_size;
|
||||
} else if (sect->flags & COFF_SectionFlag_CNT_INITIALIZED_DATA) {
|
||||
} else if (sect->flags & COFF_SectionFlag_CntInitializedData) {
|
||||
data_size += sect_size;
|
||||
}
|
||||
}
|
||||
@@ -2974,21 +2976,21 @@ lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab)
|
||||
|
||||
LNK_Symbol *dos_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_DOS_HEADER_SYMBOL_NAME));
|
||||
LNK_Symbol *dos_program_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_DOS_PROGRAM_SYMBOL_NAME));
|
||||
LNK_Symbol *coff_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_COFF_HEADER_SYMBOL_NAME));
|
||||
LNK_Symbol *COFF_FileHeader_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_COFF_FILE_HEADER_SYMBOL_NAME));
|
||||
LNK_Symbol *coff_section_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME));
|
||||
LNK_Symbol *pe_opt_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_PE_OPT_HEADER_SYMBOL_NAME));
|
||||
LNK_Symbol *pe_directories_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME));
|
||||
|
||||
LNK_Chunk *dos_header_chunk = dos_header_symbol->u.defined.u.chunk;
|
||||
LNK_Chunk *dos_program_chunk = dos_program_symbol->u.defined.u.chunk;
|
||||
LNK_Chunk *coff_header_chunk = coff_header_symbol->u.defined.u.chunk;
|
||||
LNK_Chunk *COFF_FileHeader_chunk = COFF_FileHeader_symbol->u.defined.u.chunk;
|
||||
LNK_Chunk *coff_section_header_chunk = coff_section_header_symbol->u.defined.u.chunk;
|
||||
LNK_Chunk *pe_opt_header_chunk = pe_opt_header_symbol->u.defined.u.chunk;
|
||||
LNK_Chunk *pe_directories_chunk = pe_directories_symbol->u.defined.u.chunk;
|
||||
|
||||
U64 dos_header_size = lnk_file_size_from_chunk_ref(sect_id_map, dos_header_chunk->ref);
|
||||
U64 dos_program_size = lnk_file_size_from_chunk_ref(sect_id_map, dos_program_chunk->ref);
|
||||
U64 coff_header_size = lnk_file_size_from_chunk_ref(sect_id_map, coff_header_chunk->ref);
|
||||
U64 COFF_FileHeader_size = lnk_file_size_from_chunk_ref(sect_id_map, COFF_FileHeader_chunk->ref);
|
||||
U64 coff_section_header_size = lnk_file_size_from_chunk_ref(sect_id_map, coff_section_header_chunk->ref);
|
||||
U64 pe_opt_header_size = lnk_file_size_from_chunk_ref(sect_id_map, pe_opt_header_chunk->ref);
|
||||
U64 pe_directories_size = lnk_file_size_from_chunk_ref(sect_id_map, pe_directories_chunk->ref);
|
||||
@@ -2997,7 +2999,7 @@ lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab)
|
||||
str8_list_pushf(scratch.arena, &output_list, "--- Image Size Breakdown -------------------------------------------------------");
|
||||
str8_list_pushf(scratch.arena, &output_list, " DOS Header: %M", dos_header_size);
|
||||
str8_list_pushf(scratch.arena, &output_list, " DOS Program Stub: %M", dos_program_size);
|
||||
str8_list_pushf(scratch.arena, &output_list, " COFF Header: %M", coff_header_size);
|
||||
str8_list_pushf(scratch.arena, &output_list, " COFF Header: %M", COFF_FileHeader_size);
|
||||
str8_list_pushf(scratch.arena, &output_list, " COFF Section Headers: %M", coff_section_header_size);
|
||||
str8_list_pushf(scratch.arena, &output_list, " PE Header: %M", pe_opt_header_size);
|
||||
str8_list_pushf(scratch.arena, &output_list, " Directories: %M", pe_directories_size);
|
||||
@@ -3403,8 +3405,8 @@ lnk_run(int argc, char **argv)
|
||||
|
||||
String8 delay_helper_name = str8_zero();
|
||||
switch (config->machine) {
|
||||
case COFF_MachineType_X86: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_X86_SYMBOL_NAME); break;
|
||||
case COFF_MachineType_X64: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME); break;
|
||||
case COFF_Machine_X86: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_X86_SYMBOL_NAME); break;
|
||||
case COFF_Machine_X64: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME); break;
|
||||
default: NotImplemented;
|
||||
}
|
||||
|
||||
@@ -3438,7 +3440,7 @@ lnk_run(int argc, char **argv)
|
||||
for (String8Node *from_node = alt_name_list.from_list.first, *to_node = alt_name_list.to_list.first;
|
||||
from_node != 0;
|
||||
from_node = from_node->next, to_node = to_node->next) {
|
||||
LNK_Symbol *weak = lnk_symbol_table_push_weak(symtab, from_node->string, COFF_WeakExtType_SEARCH_ALIAS, to_node->string);
|
||||
LNK_Symbol *weak = lnk_symbol_table_push_weak(symtab, from_node->string, COFF_WeakExt_SearchAlias, to_node->string);
|
||||
lnk_symbol_list_push(scratch.arena, &input_weak_list, weak);
|
||||
}
|
||||
ProfEnd();
|
||||
@@ -3458,12 +3460,12 @@ lnk_run(int argc, char **argv)
|
||||
case State_InputImports: {
|
||||
ProfBegin("Input Imports");
|
||||
for (LNK_InputImport *input = input_import_list.first; input != 0; input = input->next) {
|
||||
COFF_ImportHeader *import_header = &input->import_header;
|
||||
COFF_ParsedArchiveImportHeader *import_header = &input->import_header;
|
||||
KeyValuePair *is_delayed = hash_table_search_path(delay_load_dll_ht, import_header->dll_name);
|
||||
|
||||
if (is_delayed) {
|
||||
if (!imptab_delayed) {
|
||||
Assert(config->machine != COFF_MachineType_UNKNOWN);
|
||||
Assert(config->machine != COFF_Machine_Unknown);
|
||||
B32 is_unloadable = !!(config->flags & LNK_ConfigFlag_DelayUnload);
|
||||
B32 is_bindable = !!(config->flags & LNK_ConfigFlag_DelayBind);
|
||||
imptab_delayed = lnk_import_table_alloc_delayed(st, symtab, config->machine, is_unloadable, is_bindable);
|
||||
@@ -3478,7 +3480,7 @@ lnk_run(int argc, char **argv)
|
||||
}
|
||||
} else {
|
||||
if (!imptab_static) {
|
||||
Assert(config->machine != COFF_MachineType_UNKNOWN);
|
||||
Assert(config->machine != COFF_Machine_Unknown);
|
||||
imptab_static = lnk_import_table_alloc_static(st, symtab, config->machine);
|
||||
}
|
||||
LNK_ImportDLL *dll = lnk_import_table_search_dll(imptab_static, import_header->dll_name);
|
||||
@@ -3560,14 +3562,14 @@ lnk_run(int argc, char **argv)
|
||||
LNK_Obj *obj = &obj_node_arr.v[obj_idx].data;
|
||||
|
||||
// derive machine from obj
|
||||
if (config->machine == COFF_MachineType_UNKNOWN) {
|
||||
if (config->machine == COFF_Machine_Unknown) {
|
||||
config->machine = obj->machine;
|
||||
} else if (config->machine != COFF_MachineType_X64) {
|
||||
} else if (config->machine != COFF_Machine_X64) {
|
||||
lnk_error_with_loc(LNK_Error_UnsupportedMachine, obj->path, obj->lib_path, "%S machine is supported", coff_string_from_machine_type(obj->machine));
|
||||
} else {
|
||||
// is obj machine compatible?
|
||||
if (config->machine != obj->machine &&
|
||||
obj->machine != COFF_MachineType_UNKNOWN) { // obj with unknown machine type is compatible with any other machine type
|
||||
obj->machine != COFF_Machine_Unknown) { // obj with unknown machine type is compatible with any other machine type
|
||||
lnk_error_obj(LNK_Error_IncompatibleObj, obj,
|
||||
"conflicting machine types expected %S but got %S",
|
||||
coff_string_from_machine_type(config->machine),
|
||||
@@ -3989,18 +3991,18 @@ lnk_run(int argc, char **argv)
|
||||
if (pdata_symbol) {
|
||||
String8 pdata = lnk_data_from_chunk_ref_no_pad(sect_id_map, image_data, pdata_symbol->u.defined.u.chunk->ref);
|
||||
switch (config->machine) {
|
||||
case COFF_MachineType_X86:
|
||||
case COFF_MachineType_X64: {
|
||||
case COFF_Machine_X86:
|
||||
case COFF_Machine_X64: {
|
||||
U64 count = pdata.size / sizeof(PE_IntelPdata);
|
||||
radsort((PE_IntelPdata *)pdata.str, count, lnk_pdata_is_before_x8664);
|
||||
} break;
|
||||
case COFF_MachineType_ARM64:
|
||||
case COFF_MachineType_ARM: {
|
||||
case COFF_Machine_Arm64:
|
||||
case COFF_Machine_Arm: {
|
||||
AssertAlways(!"TOOD: ARM");
|
||||
} break;
|
||||
case COFF_MachineType_MIPSFPU:
|
||||
case COFF_MachineType_MIPS16:
|
||||
case COFF_MachineType_MIPSFPU16: {
|
||||
case COFF_Machine_MipsFpu:
|
||||
case COFF_Machine_Mips16:
|
||||
case COFF_Machine_MipsFpu16: {
|
||||
AssertAlways(!"TODO: MIPS");
|
||||
} break;
|
||||
}
|
||||
|
||||
+8
-8
@@ -49,7 +49,7 @@
|
||||
#define LNK_DOS_HEADER_SYMBOL_NAME "DOS_HEADER"
|
||||
#define LNK_DOS_PROGRAM_SYMBOL_NAME "DOS_PROGRAM"
|
||||
#define LNK_PE_MAGIC_SYMBOL_NAME "PE_MAGIC"
|
||||
#define LNK_COFF_HEADER_SYMBOL_NAME "COFF_HEADER"
|
||||
#define LNK_COFF_FILE_HEADER_SYMBOL_NAME "COFF_FILE_HEADER"
|
||||
#define LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME "PE_DIRECTORY_ARRAY"
|
||||
#define LNK_PE_DIRECTORY_COUNT_SYMBOL_NAME "PE_DIRECTORY_COUNT"
|
||||
#define LNK_PE_OPT_HEADER_SYMBOL_NAME "PE_OPTIONAL_HEADER"
|
||||
@@ -82,10 +82,10 @@
|
||||
#define LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME "__delayLoadHelper2"
|
||||
#define LNK_DELAY_LOAD_HELPER2_X86_SYMBOL_NAME "___delayLoadHelper2@8"
|
||||
|
||||
#define LNK_TEXT_SECTION_FLAGS (COFF_SectionFlag_CNT_CODE|COFF_SectionFlag_MEM_EXECUTE|COFF_SectionFlag_MEM_READ)
|
||||
#define LNK_DATA_SECTION_FLAGS (COFF_SectionFlag_CNT_INITIALIZED_DATA|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE)
|
||||
#define LNK_RDATA_SECTION_FLAGS (COFF_SectionFlag_CNT_INITIALIZED_DATA|COFF_SectionFlag_MEM_READ)
|
||||
#define LNK_BSS_SECTION_FLAGS (COFF_SectionFlag_CNT_UNINITIALIZED_DATA|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE)
|
||||
#define LNK_TEXT_SECTION_FLAGS (COFF_SectionFlag_CntCode|COFF_SectionFlag_MemExecute|COFF_SectionFlag_MemRead)
|
||||
#define LNK_DATA_SECTION_FLAGS (COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite)
|
||||
#define LNK_RDATA_SECTION_FLAGS (COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead)
|
||||
#define LNK_BSS_SECTION_FLAGS (COFF_SectionFlag_CntUninitializedData|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite)
|
||||
#define LNK_IDATA_SECTION_FLAGS LNK_DATA_SECTION_FLAGS
|
||||
#define LNK_DEBUG_DIR_SECTION_FLAGS LNK_DATA_SECTION_FLAGS
|
||||
#define LNK_RSRC_SECTION_FLAGS LNK_DATA_SECTION_FLAGS
|
||||
@@ -96,8 +96,8 @@
|
||||
#define LNK_GIATS_SECTION_FLAGS LNK_RDATA_SECTION_FLAGS
|
||||
#define LNK_GLJMP_SECTION_FLAGS LNK_RDATA_SECTION_FLAGS
|
||||
#define LNK_GEHCONT_SECTION_FLAGS LNK_RDATA_SECTION_FLAGS
|
||||
#define LNK_RELOC_SECTION_FLAGS (LNK_RDATA_SECTION_FLAGS | COFF_SectionFlag_MEM_DISCARDABLE)
|
||||
#define LNK_DEBUG_SECTION_FLAGS (LNK_RDATA_SECTION_FLAGS | COFF_SectionFlag_MEM_DISCARDABLE)
|
||||
#define LNK_RELOC_SECTION_FLAGS (LNK_RDATA_SECTION_FLAGS | COFF_SectionFlag_MemDiscardable)
|
||||
#define LNK_DEBUG_SECTION_FLAGS (LNK_RDATA_SECTION_FLAGS | COFF_SectionFlag_MemDiscardable)
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -114,7 +114,7 @@ typedef String8List LNK_InputLibList;
|
||||
|
||||
typedef struct LNK_InputImport
|
||||
{
|
||||
COFF_ImportHeader import_header;
|
||||
COFF_ParsedArchiveImportHeader import_header;
|
||||
struct LNK_InputImport *next;
|
||||
} LNK_InputImport;
|
||||
|
||||
|
||||
+25
-25
@@ -352,11 +352,11 @@ lnk_get_default_function_pad_min(COFF_MachineType machine)
|
||||
{
|
||||
U64 function_pad_min = 0;
|
||||
switch (machine) {
|
||||
case COFF_MachineType_UNKNOWN: break;
|
||||
case COFF_MachineType_X86: {
|
||||
case COFF_Machine_Unknown: break;
|
||||
case COFF_Machine_X86: {
|
||||
function_pad_min = 5;
|
||||
} break;
|
||||
case COFF_MachineType_X64: {
|
||||
case COFF_Machine_X64: {
|
||||
function_pad_min = 6;
|
||||
} break;
|
||||
default: {
|
||||
@@ -396,12 +396,12 @@ lnk_get_default_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineTyp
|
||||
|
||||
case PE_WindowsSubsystem_WINDOWS_CUI: {
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X64:
|
||||
case COFF_MachineType_X86: ver = make_version(6,0); break;
|
||||
case COFF_Machine_X64:
|
||||
case COFF_Machine_X86: ver = make_version(6,0); break;
|
||||
|
||||
case COFF_MachineType_ARMNT:
|
||||
case COFF_MachineType_ARM64:
|
||||
case COFF_MachineType_ARM: ver = make_version(6,2); break;
|
||||
case COFF_Machine_ArmNt:
|
||||
case COFF_Machine_Arm64:
|
||||
case COFF_Machine_Arm: ver = make_version(6,2); break;
|
||||
|
||||
default: lnk_not_implemented("define subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break;
|
||||
}
|
||||
@@ -409,12 +409,12 @@ lnk_get_default_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineTyp
|
||||
|
||||
case PE_WindowsSubsystem_WINDOWS_GUI: {
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X64:
|
||||
case COFF_MachineType_X86: ver = make_version(6,0); break;
|
||||
case COFF_Machine_X64:
|
||||
case COFF_Machine_X86: ver = make_version(6,0); break;
|
||||
|
||||
case COFF_MachineType_ARMNT:
|
||||
case COFF_MachineType_ARM64:
|
||||
case COFF_MachineType_ARM: ver = make_version(6,2); break;
|
||||
case COFF_Machine_ArmNt:
|
||||
case COFF_Machine_Arm64:
|
||||
case COFF_Machine_Arm: ver = make_version(6,2); break;
|
||||
|
||||
default: lnk_not_implemented("define subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break;
|
||||
}
|
||||
@@ -444,13 +444,13 @@ lnk_get_min_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineType ma
|
||||
|
||||
case PE_WindowsSubsystem_WINDOWS_CUI: {
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X86: ver = make_version(5,1); break;
|
||||
case COFF_Machine_X86: ver = make_version(5,1); break;
|
||||
|
||||
case COFF_MachineType_X64: ver = make_version(5,2); break;
|
||||
case COFF_Machine_X64: ver = make_version(5,2); break;
|
||||
|
||||
case COFF_MachineType_ARMNT:
|
||||
case COFF_MachineType_ARM64:
|
||||
case COFF_MachineType_ARM: ver = make_version(6,2); break;
|
||||
case COFF_Machine_ArmNt:
|
||||
case COFF_Machine_Arm64:
|
||||
case COFF_Machine_Arm: ver = make_version(6,2); break;
|
||||
|
||||
default: lnk_not_implemented("define min subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break;
|
||||
}
|
||||
@@ -458,13 +458,13 @@ lnk_get_min_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineType ma
|
||||
|
||||
case PE_WindowsSubsystem_WINDOWS_GUI: {
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X86: ver = make_version(5,1); break;
|
||||
case COFF_Machine_X86: ver = make_version(5,1); break;
|
||||
|
||||
case COFF_MachineType_X64: ver = make_version(5,2); break;
|
||||
case COFF_Machine_X64: ver = make_version(5,2); break;
|
||||
|
||||
case COFF_MachineType_ARMNT:
|
||||
case COFF_MachineType_ARM64:
|
||||
case COFF_MachineType_ARM: ver = make_version(6,2); break;
|
||||
case COFF_Machine_ArmNt:
|
||||
case COFF_Machine_Arm64:
|
||||
case COFF_Machine_Arm: ver = make_version(6,2); break;
|
||||
|
||||
default: lnk_not_implemented("define min subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break;
|
||||
}
|
||||
@@ -784,7 +784,7 @@ lnk_parse_export_directive(Arena *arena, LNK_ExportParseList *list, String8List
|
||||
// parse directive
|
||||
String8 name = str8_zero();
|
||||
String8 alias = str8_zero();
|
||||
String8 type = coff_string_from_import_header_type(COFF_ImportHeaderType_CODE);
|
||||
String8 type = coff_string_from_import_header_type(COFF_ImportHeader_Code);
|
||||
if (value_list.node_count > 0) {
|
||||
String8List dir_split = str8_split_by_string_chars(scratch.arena, value_list.first->string, str8_lit("="), 0);
|
||||
B32 is_export_valid = value_list.node_count <= 2 && value_list.node_count > 0;
|
||||
@@ -1193,7 +1193,7 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam
|
||||
case LNK_CmdSwitch_Machine: {
|
||||
if (value_strings.node_count == 1) {
|
||||
COFF_MachineType machine = coff_machine_from_string(value_strings.first->string);
|
||||
if (machine != COFF_MachineType_UNKNOWN) {
|
||||
if (machine != COFF_Machine_Unknown) {
|
||||
config->machine = machine;
|
||||
} else {
|
||||
lnk_error_cmd_switch(LNK_Error_Cmdl, obj_path, lib_path, cmd_switch, "unknown parameter \"%S\"", value_strings.first->string);
|
||||
|
||||
@@ -3025,7 +3025,7 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
|
||||
// Mod1::fUpdateSecContrib
|
||||
if (sc_count > 0) {
|
||||
for (U64 sc_idx = 0; sc_idx < sc_count; ++sc_idx) {
|
||||
if (sc_arr[sc_idx].data.base.flags & COFF_SectionFlag_CNT_CODE) {
|
||||
if (sc_arr[sc_idx].data.base.flags & COFF_SectionFlag_CntCode) {
|
||||
mod->first_sc = sc_arr[sc_idx].data;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -82,22 +82,22 @@ lnk_export_table_push_export(LNK_ExportTable *exptab, LNK_SymbolTable *symtab, L
|
||||
// to CODE instead of DATA. But if you try export global variable with:
|
||||
// #pragma comment(linker, "/export:global_bar,CODE")
|
||||
// MSVC and LLD issue an error. For compatibility sake we do the same thing too.
|
||||
COFF_ImportHeaderType type = coff_import_header_type_from_string(exp_parse->type);
|
||||
COFF_ImportType type = coff_import_header_type_from_string(exp_parse->type);
|
||||
switch (type) {
|
||||
case COFF_ImportHeaderType_CODE: {
|
||||
case COFF_ImportHeader_Code: {
|
||||
B32 is_export_data = !(def->flags & (LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk));
|
||||
if (is_export_data) {
|
||||
lnk_error(LNK_Error_IllExport, "export \"%S\" is DATA but has specifier CODE", exp_parse->name);
|
||||
}
|
||||
} break;
|
||||
case COFF_ImportHeaderType_DATA: {
|
||||
case COFF_ImportHeader_Data: {
|
||||
B32 is_export_code = !!(def->flags & (LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk));
|
||||
if (is_export_code) {
|
||||
lnk_error(LNK_Error_IllExport, "export \"%S\" is CODE but has specifier DATA", exp_parse->name);
|
||||
}
|
||||
} break;
|
||||
case COFF_ImportHeaderType_CONST: {
|
||||
lnk_not_implemented("TODO: COFF_ImportHeaderType_CONST");
|
||||
case COFF_ImportHeader_Const: {
|
||||
lnk_not_implemented("TODO: COFF_ImportHeader_Const");
|
||||
} break;
|
||||
default: {
|
||||
if (exp_parse->type.size) {
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
typedef struct LNK_Export
|
||||
{
|
||||
struct LNK_Export *next;
|
||||
String8 name;
|
||||
LNK_Symbol *symbol;
|
||||
U32 id;
|
||||
U16 ordinal;
|
||||
COFF_ImportHeaderType type;
|
||||
B32 is_private;
|
||||
struct LNK_Export *next;
|
||||
String8 name;
|
||||
LNK_Symbol *symbol;
|
||||
U32 id;
|
||||
U16 ordinal;
|
||||
COFF_ImportType type;
|
||||
B32 is_private;
|
||||
} LNK_Export;
|
||||
|
||||
typedef struct LNK_ExportList
|
||||
|
||||
@@ -345,7 +345,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
// emit tail merge
|
||||
LNK_Chunk *tail_merge_chunk = 0;
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X64: {
|
||||
case COFF_Machine_X64: {
|
||||
LNK_Symbol *delay_load_helper_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], str8_lit(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME), LNK_SymbolScopeFlag_Main);
|
||||
tail_merge_chunk = lnk_emit_tail_merge_thunk_x64(code_sect, code_chunk, imp_desc_symbol, delay_load_helper_symbol);
|
||||
} break;
|
||||
@@ -375,7 +375,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
}
|
||||
|
||||
internal LNK_ImportFunc *
|
||||
lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ImportHeader *header)
|
||||
lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ParsedArchiveImportHeader *header)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
@@ -395,20 +395,20 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
U64 import_size = coff_word_size_from_machine(dll->machine);
|
||||
|
||||
// generate sort index (optional)
|
||||
String8 sort_index = str8_from_bits_u32(data_sect->arena, header->hint);
|
||||
String8 sort_index = str8_from_bits_u32(data_sect->arena, header->hint_or_ordinal);
|
||||
|
||||
switch (header->name_type) {
|
||||
case COFF_ImportHeaderNameType_ORDINAL: {
|
||||
String8 ordinal_data = lnk_ordinal_data_from_hint(data_sect->arena, dll->machine, header->hint);
|
||||
switch (header->import_by) {
|
||||
case COFF_ImportBy_Ordinal: {
|
||||
String8 ordinal_data = lnk_ordinal_data_from_hint(data_sect->arena, dll->machine, header->hint_or_ordinal);
|
||||
ilt_chunk = lnk_section_push_chunk_data(data_sect, ilt_table_chunk, ordinal_data, sort_index);
|
||||
iat_chunk = lnk_section_push_chunk_data(data_sect, iat_table_chunk, ordinal_data, sort_index);
|
||||
|
||||
// associate chunks
|
||||
lnk_section_associate_chunks(data_sect, iat_chunk, ilt_chunk);
|
||||
} break;
|
||||
case COFF_ImportHeaderNameType_NAME: {
|
||||
case COFF_ImportBy_Name: {
|
||||
// put together name look up entry
|
||||
String8 int_data = coff_make_import_lookup(data_sect->arena, header->hint, header->func_name);
|
||||
String8 int_data = coff_make_import_lookup(data_sect->arena, header->hint_or_ordinal, header->func_name);
|
||||
LNK_Chunk *int_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, int_data, str8_zero());
|
||||
|
||||
// create symbol for lookup chunk
|
||||
@@ -429,11 +429,11 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
lnk_section_push_reloc(data_sect, ilt_chunk, LNK_Reloc_VIRT_OFF_32, 0, int_symbol);
|
||||
lnk_section_push_reloc(data_sect, iat_chunk, LNK_Reloc_VIRT_OFF_32, 0, int_symbol);
|
||||
} break;
|
||||
case COFF_ImportHeaderNameType_UNDECORATE: {
|
||||
lnk_not_implemented("TODO: COFF_ImportHeaderNameType_UNDECORATE");
|
||||
case COFF_ImportBy_Undecorate: {
|
||||
lnk_not_implemented("TODO: COFF_ImportBy_Undecorate");
|
||||
} break;
|
||||
case COFF_ImportHeaderNameType_NAME_NOPREFIX: {
|
||||
lnk_not_implemented("TODO: COFF_ImportHeaderNameType_NAME_NOPREFIX");
|
||||
case COFF_ImportBy_NameNoPrefix: {
|
||||
lnk_not_implemented("TODO: COFF_ImportBy_NameNoPrefix");
|
||||
} break;
|
||||
}
|
||||
|
||||
@@ -444,9 +444,9 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
|
||||
// generate thunks
|
||||
LNK_Symbol *jmp_thunk_symbol = g_null_symbol_ptr;
|
||||
if (header->type == COFF_ImportHeaderType_CODE) {
|
||||
if (header->type == COFF_ImportHeader_Code) {
|
||||
switch (dll->machine) {
|
||||
case COFF_MachineType_X64: {
|
||||
case COFF_Machine_X64: {
|
||||
// generate jump thunk
|
||||
LNK_Chunk *jmp_thunk_chunk = lnk_emit_indirect_jump_thunk_x64(code_sect, code_table_chunk, iat_symbol);
|
||||
lnk_section_associate_chunks(data_sect, iat_chunk, jmp_thunk_chunk);
|
||||
@@ -472,7 +472,7 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
}
|
||||
|
||||
internal LNK_ImportFunc *
|
||||
lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ImportHeader *header)
|
||||
lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ParsedArchiveImportHeader *header)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
@@ -498,16 +498,16 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
|
||||
LNK_Symbol *int_symbol = 0;
|
||||
|
||||
// generate sort index (optional)
|
||||
String8 sort_index = str8_from_bits_u32(data_sect->arena, header->hint);
|
||||
String8 sort_index = str8_from_bits_u32(data_sect->arena, header->hint_or_ordinal);
|
||||
|
||||
// generate thunks
|
||||
LNK_Symbol *jmp_thunk_symbol = g_null_symbol_ptr;
|
||||
LNK_Symbol *load_thunk_symbol = g_null_symbol_ptr;
|
||||
LNK_Chunk *jmp_thunk_chunk = 0;
|
||||
LNK_Chunk *load_thunk_chunk = 0;
|
||||
if (header->type == COFF_ImportHeaderType_CODE) {
|
||||
if (header->type == COFF_ImportHeader_Code) {
|
||||
switch (dll->machine) {
|
||||
case COFF_MachineType_X64: {
|
||||
case COFF_Machine_X64: {
|
||||
String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "__imp_%S", header->func_name);
|
||||
LNK_Symbol *iat_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], iat_symbol_name, LNK_SymbolScopeFlag_Main);
|
||||
|
||||
@@ -523,9 +523,9 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
|
||||
}
|
||||
}
|
||||
|
||||
switch (header->name_type) {
|
||||
case COFF_ImportHeaderNameType_ORDINAL: {
|
||||
String8 ordinal_data = lnk_ordinal_data_from_hint(data_sect->arena, dll->machine, header->hint);
|
||||
switch (header->import_by) {
|
||||
case COFF_ImportBy_Ordinal: {
|
||||
String8 ordinal_data = lnk_ordinal_data_from_hint(data_sect->arena, dll->machine, header->hint_or_ordinal);
|
||||
Assert(ordinal_data.size == import_size);
|
||||
ilt_chunk = lnk_section_push_chunk_data(data_sect, ilt_table_chunk, ordinal_data, sort_index);
|
||||
iat_chunk = lnk_section_push_chunk_bss(data_sect, iat_table_chunk, import_size, sort_index);
|
||||
@@ -543,9 +543,9 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
|
||||
lnk_section_associate_chunks(data_sect, iat_chunk, uiat_chunk);
|
||||
}
|
||||
} break;
|
||||
case COFF_ImportHeaderNameType_NAME: {
|
||||
case COFF_ImportBy_Name: {
|
||||
// put together name look up entry
|
||||
String8 int_data = coff_make_import_lookup(data_sect->arena, header->hint, header->func_name);
|
||||
String8 int_data = coff_make_import_lookup(data_sect->arena, header->hint_or_ordinal, header->func_name);
|
||||
LNK_Chunk *int_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, int_data, str8_zero());
|
||||
|
||||
// create symbol for lookup chunk
|
||||
@@ -586,11 +586,11 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
|
||||
lnk_section_push_reloc(data_sect, uiat_chunk, LNK_Reloc_ADDR_64, 0, load_thunk_symbol);
|
||||
}
|
||||
} break;
|
||||
case COFF_ImportHeaderNameType_UNDECORATE: {
|
||||
lnk_not_implemented("TODO: COFF_ImportHeaderNameType_UNDECORATE");
|
||||
case COFF_ImportBy_Undecorate: {
|
||||
lnk_not_implemented("TODO: COFF_ImportBy_Undecorate");
|
||||
} break;
|
||||
case COFF_ImportHeaderNameType_NAME_NOPREFIX: {
|
||||
lnk_not_implemented("TODO: COFF_ImportHeaderNameType_NAME_NOPREFIX");
|
||||
case COFF_ImportBy_NameNoPrefix: {
|
||||
lnk_not_implemented("TODO: COFF_ImportBy_NameNoPrefix");
|
||||
} break;
|
||||
}
|
||||
|
||||
@@ -624,14 +624,14 @@ lnk_ordinal_data_from_hint(Arena *arena, COFF_MachineType machine, U16 hint)
|
||||
{
|
||||
String8 ordinal_data = str8_zero();
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X64: {
|
||||
case COFF_Machine_X64: {
|
||||
U64 *ordinal = push_array(arena, U64, 1);
|
||||
*ordinal = coff_make_ordinal_64(hint);
|
||||
*ordinal = coff_make_ordinal64(hint);
|
||||
ordinal_data = str8_struct(ordinal);
|
||||
} break;
|
||||
case COFF_MachineType_X86: {
|
||||
case COFF_Machine_X86: {
|
||||
U32 *ordinal = push_array(arena, U32, 1);
|
||||
*ordinal = coff_make_ordinal_32(hint);
|
||||
*ordinal = coff_make_ordinal32(hint);
|
||||
ordinal_data = str8_struct(ordinal);
|
||||
} break;
|
||||
default: lnk_not_implemented("TODO: support for machine 0x%x", machine);
|
||||
@@ -736,7 +736,7 @@ lnk_emit_load_thunk_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 fu
|
||||
ProfBeginFunction();
|
||||
// emit load thunk symbol
|
||||
String8 load_thunk_name = push_str8f(symtab->arena->v[0], "__imp_load_%S", func_name);
|
||||
LNK_Symbol *load_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, load_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
|
||||
LNK_Symbol *load_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, load_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelect_NoDuplicates, 0);
|
||||
ProfEnd();
|
||||
return load_thunk_symbol;
|
||||
}
|
||||
@@ -746,7 +746,7 @@ lnk_emit_jmp_thunk_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 fun
|
||||
{
|
||||
ProfBeginFunction();
|
||||
String8 jmp_thunk_name = push_str8f(symtab->arena->v[0], "%S", func_name);
|
||||
LNK_Symbol *jmp_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, jmp_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelectType_ANY, 0);
|
||||
LNK_Symbol *jmp_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, jmp_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelect_Any, 0);
|
||||
ProfEnd();
|
||||
return jmp_thunk_symbol;
|
||||
}
|
||||
@@ -756,7 +756,7 @@ lnk_emit_tail_merge_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 fu
|
||||
{
|
||||
ProfBeginFunction();
|
||||
String8 tail_merge_name = push_str8f(symtab->arena->v[0], "__tailMerge_%S", func_name);
|
||||
LNK_Symbol *tail_merge_symbol = lnk_symbol_table_push_defined_chunk(symtab, tail_merge_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
|
||||
LNK_Symbol *tail_merge_symbol = lnk_symbol_table_push_defined_chunk(symtab, tail_merge_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelect_NoDuplicates, 0);
|
||||
ProfEnd();
|
||||
return tail_merge_symbol;
|
||||
}
|
||||
|
||||
@@ -64,8 +64,8 @@ internal LNK_ImportTable * lnk_import_table_alloc_delayed(LNK_SectionTable *st,
|
||||
internal void lnk_import_table_release(LNK_ImportTable **imptab);
|
||||
internal LNK_ImportDLL * lnk_import_table_push_dll_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, String8 dll_name, COFF_MachineType machine);
|
||||
internal LNK_ImportDLL * lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, String8 dll_name, COFF_MachineType machine);
|
||||
internal LNK_ImportFunc * lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ImportHeader *header);
|
||||
internal LNK_ImportFunc * lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ImportHeader *header);
|
||||
internal LNK_ImportFunc * lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ParsedArchiveImportHeader *header);
|
||||
internal LNK_ImportFunc * lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ParsedArchiveImportHeader *header);
|
||||
internal LNK_ImportDLL * lnk_import_table_search_dll(LNK_ImportTable *imptab, String8 name);
|
||||
internal LNK_ImportFunc * lnk_import_table_search_func(LNK_ImportDLL *dll, String8 name);
|
||||
|
||||
|
||||
+49
-49
@@ -303,19 +303,19 @@ lnk_lib_writer_push_export(LNK_LibWriter *writer, COFF_MachineType machine, U64
|
||||
lnk_lib_member_list_push(writer->arena, &writer->member_list, member);
|
||||
|
||||
switch (exp->type) {
|
||||
case COFF_ImportHeaderType_CODE: {
|
||||
case COFF_ImportHeader_Code: {
|
||||
LNK_LibSymbol def_symbol = {0};
|
||||
def_symbol.name = push_str8_copy(writer->arena, exp->name);
|
||||
def_symbol.member_idx = member_idx;
|
||||
lnk_lib_symbol_list_push(writer->arena, &writer->symbol_list, def_symbol);
|
||||
}
|
||||
case COFF_ImportHeaderType_DATA: {
|
||||
case COFF_ImportHeader_Data: {
|
||||
LNK_LibSymbol imp_symbol = {0};
|
||||
imp_symbol.name = push_str8f(writer->arena, "__imp_%S", exp->name);
|
||||
imp_symbol.member_idx = member_idx;
|
||||
lnk_lib_symbol_list_push(writer->arena, &writer->symbol_list, imp_symbol);
|
||||
} break;
|
||||
case COFF_ImportHeaderType_CONST: {
|
||||
case COFF_ImportHeader_Const: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
default: InvalidPath;
|
||||
@@ -361,7 +361,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
|
||||
// make member name
|
||||
String8 name;
|
||||
U64 name_with_slash_size = member->name.size + 1;
|
||||
if (name_with_slash_size > COFF_ARCHIVE_MAX_SHORT_NAME_SIZE) {
|
||||
if (name_with_slash_size > COFF_Archive_MaxShortNameSize) {
|
||||
// have we seen this member name before?
|
||||
KeyValuePair *is_present = hash_table_search_string(name_ht, member->name);
|
||||
if (is_present) {
|
||||
@@ -382,7 +382,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
|
||||
|
||||
str8_list_push(arena, &member_data_list, member_header);
|
||||
str8_list_push(arena, &member_data_list, member_data);
|
||||
str8_list_push_pad(arena, &member_data_list, member_data_list.total_size, COFF_ARCHIVE_ALIGN);
|
||||
str8_list_push_pad(arena, &member_data_list, member_data_list.total_size, COFF_Archive_MemberAlign);
|
||||
}
|
||||
|
||||
// long names member
|
||||
@@ -390,7 +390,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
|
||||
String8 header = lnk_build_lib_member_header(arena, str8_lit("//"), time_stamp, 0, 0, mode, long_names_list.total_size);
|
||||
String8 data = str8_list_join(arena, &long_names_list, 0);
|
||||
U64 member_offset = member_data_list.total_size + data.size + header.size;
|
||||
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_ARCHIVE_ALIGN);
|
||||
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_Archive_MemberAlign);
|
||||
str8_list_push_front(arena, &member_data_list, data);
|
||||
str8_list_push_front(arena, &member_data_list, header);
|
||||
}
|
||||
@@ -415,13 +415,13 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
|
||||
|
||||
U64 member_base_off;
|
||||
{
|
||||
U64 sizeof_first_header = COFF_ARCHIVE_MEMBER_HEADER_SIZE + sizeof(U32) + sizeof(U32) * symbol_count + name_buffer_size;
|
||||
U64 sizeof_second_header = COFF_ARCHIVE_MEMBER_HEADER_SIZE + sizeof(U32) + sizeof(U32) * lib->member_count + sizeof(U32) + sizeof(U16) * symbol_count + name_buffer_size;
|
||||
U64 sizeof_long_names = COFF_ARCHIVE_MEMBER_HEADER_SIZE + long_names_list.total_size;
|
||||
U64 sizeof_first_header = sizeof(COFF_ArchiveMemberHeader) + sizeof(U32) + sizeof(U32) * symbol_count + name_buffer_size;
|
||||
U64 sizeof_second_header = sizeof(COFF_ArchiveMemberHeader) + sizeof(U32) + sizeof(U32) * lib->member_count + sizeof(U32) + sizeof(U16) * symbol_count + name_buffer_size;
|
||||
U64 sizeof_long_names = sizeof(COFF_ArchiveMemberHeader) + long_names_list.total_size;
|
||||
|
||||
sizeof_first_header = AlignPow2(sizeof_first_header, COFF_ARCHIVE_ALIGN);
|
||||
sizeof_second_header = AlignPow2(sizeof_second_header, COFF_ARCHIVE_ALIGN);
|
||||
sizeof_long_names = AlignPow2(sizeof_long_names, COFF_ARCHIVE_ALIGN);
|
||||
sizeof_first_header = AlignPow2(sizeof_first_header, COFF_Archive_MemberAlign);
|
||||
sizeof_second_header = AlignPow2(sizeof_second_header, COFF_Archive_MemberAlign);
|
||||
sizeof_long_names = AlignPow2(sizeof_long_names, COFF_Archive_MemberAlign);
|
||||
|
||||
member_base_off = sizeof(g_coff_archive_sig);
|
||||
member_base_off += sizeof_first_header;
|
||||
@@ -468,7 +468,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
|
||||
String8 member_header = lnk_build_lib_member_header(arena, str8_lit("/"), time_stamp, 0, 0, mode, member_data.size);
|
||||
|
||||
U64 member_offset = member_data_list.total_size + member_data.size + member_header.size;
|
||||
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_ARCHIVE_ALIGN);
|
||||
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_Archive_MemberAlign);
|
||||
str8_list_push_front(arena, &member_data_list, member_data);
|
||||
str8_list_push_front(arena, &member_data_list, member_header);
|
||||
}
|
||||
@@ -497,7 +497,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
|
||||
String8 member_header = lnk_build_lib_member_header(arena, str8_lit("/"), time_stamp, 0, 0, mode, member_data.size);
|
||||
|
||||
U64 member_offset = sizeof(g_coff_archive_sig) + member_header.size + member_data.size;
|
||||
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_ARCHIVE_ALIGN);
|
||||
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_Archive_MemberAlign);
|
||||
str8_list_push_front(arena, &member_data_list, member_data);
|
||||
str8_list_push_front(arena, &member_data_list, member_header);
|
||||
}
|
||||
@@ -541,18 +541,18 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
Assert(machine == COFF_MachineType_X64);
|
||||
Assert(machine == COFF_Machine_X64);
|
||||
Assert(str8_match_lit("dll", str8_skip_last_dot(dll_name), StringMatchFlag_CaseInsensitive|StringMatchFlag_RightSideSloppy));
|
||||
|
||||
String8List list = {0};
|
||||
|
||||
COFF_Header *coff_header = push_array(arena, COFF_Header, 1);
|
||||
coff_header->machine = machine;
|
||||
str8_list_push(arena, &list, str8_struct(coff_header));
|
||||
COFF_FileHeader *file_header = push_array(arena, COFF_FileHeader, 1);
|
||||
file_header->machine = machine;
|
||||
str8_list_push(arena, &list, str8_struct(file_header));
|
||||
|
||||
coff_header->section_count = 2;
|
||||
COFF_SectionHeader *coff_sect_header_array = push_array(arena, COFF_SectionHeader, coff_header->section_count);
|
||||
str8_list_push(arena, &list, str8_array(coff_sect_header_array, coff_header->section_count));
|
||||
file_header->section_count = 2;
|
||||
COFF_SectionHeader *coff_sect_header_array = push_array(arena, COFF_SectionHeader, file_header->section_count);
|
||||
str8_list_push(arena, &list, str8_array(coff_sect_header_array, file_header->section_count));
|
||||
|
||||
PE_ImportEntry *import_entry = push_array(arena, PE_ImportEntry, 1);
|
||||
U64 import_entry_off = list.total_size;
|
||||
@@ -567,10 +567,10 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
U64 import_entry_reloc_off = list.total_size;
|
||||
str8_list_push(arena, &list, str8_array(import_entry_reloc_array, import_entry_reloc_count));
|
||||
|
||||
coff_header->symbol_count = 7;
|
||||
COFF_Symbol16 *symbol_array = push_array(arena, COFF_Symbol16, coff_header->symbol_count);
|
||||
coff_header->symbol_table_foff = safe_cast_u32(list.total_size);
|
||||
str8_list_push(arena, &list, str8_array(symbol_array, coff_header->symbol_count));
|
||||
file_header->symbol_count = 7;
|
||||
COFF_Symbol16 *symbol_array = push_array(arena, COFF_Symbol16, file_header->symbol_count);
|
||||
file_header->symbol_table_foff = safe_cast_u32(list.total_size);
|
||||
str8_list_push(arena, &list, str8_array(symbol_array, file_header->symbol_count));
|
||||
|
||||
U64 string_table_base = list.total_size;
|
||||
U32 *string_table_size_ptr = push_array(arena, U32, 1);
|
||||
@@ -591,23 +591,23 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
sect->foff = import_entry_off;
|
||||
sect->reloc_count = import_entry_reloc_count;
|
||||
sect->relocs_foff = import_entry_reloc_off;
|
||||
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_4BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
|
||||
sect->flags = COFF_SectionFlag_CntInitializedData|(COFF_SectionAlign_4Bytes << COFF_SectionFlag_AlignShift)|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite;
|
||||
}
|
||||
{
|
||||
COFF_Reloc *lookup_table_voff_reloc = &import_entry_reloc_array[0];
|
||||
lookup_table_voff_reloc->apply_off = OffsetOf(PE_ImportEntry, lookup_table_voff);
|
||||
lookup_table_voff_reloc->isymbol = 3;
|
||||
lookup_table_voff_reloc->type = COFF_RelocTypeX64_ADDR32NB;
|
||||
lookup_table_voff_reloc->type = COFF_Reloc_X64_Addr32Nb;
|
||||
|
||||
COFF_Reloc *name_voff_reloc = &import_entry_reloc_array[1];
|
||||
name_voff_reloc->apply_off = OffsetOf(PE_ImportEntry, name_voff);
|
||||
name_voff_reloc->isymbol = 2;
|
||||
name_voff_reloc->type = COFF_RelocTypeX64_ADDR32NB;
|
||||
name_voff_reloc->type = COFF_Reloc_X64_Addr32Nb;
|
||||
|
||||
COFF_Reloc *import_addr_table_voff = &import_entry_reloc_array[2];
|
||||
import_addr_table_voff->apply_off = OffsetOf(PE_ImportEntry, import_addr_table_voff);
|
||||
import_addr_table_voff->isymbol = 4;
|
||||
import_addr_table_voff->type = COFF_RelocTypeX64_ADDR32NB;
|
||||
import_addr_table_voff->type = COFF_Reloc_X64_Addr32Nb;
|
||||
}
|
||||
|
||||
// dll name
|
||||
@@ -623,7 +623,7 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
sect->name[7] = '6';
|
||||
sect->fsize = dll_name_cstr.size;
|
||||
sect->foff = dll_name_off;
|
||||
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_2BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
|
||||
sect->flags = COFF_SectionFlag_CntInitializedData|(COFF_SectionAlign_2Bytes << COFF_SectionFlag_AlignShift)|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite;
|
||||
}
|
||||
|
||||
// import descriptor
|
||||
@@ -638,7 +638,7 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
symbol->name.long_name.zeroes = 0;
|
||||
symbol->name.long_name.string_table_offset = symbol_name_off;
|
||||
symbol->section_number = 1;
|
||||
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
|
||||
symbol->storage_class = COFF_SymStorageClass_External;
|
||||
}
|
||||
|
||||
// .idata$2
|
||||
@@ -653,7 +653,7 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
symbol->name.short_name[6] = '$';
|
||||
symbol->name.short_name[7] = '2';
|
||||
symbol->section_number = 1;
|
||||
symbol->storage_class = COFF_SymStorageClass_SECTION;
|
||||
symbol->storage_class = COFF_SymStorageClass_Section;
|
||||
}
|
||||
|
||||
// .idata$6
|
||||
@@ -668,7 +668,7 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
symbol->name.short_name[6] = '$';
|
||||
symbol->name.short_name[7] = '6';
|
||||
symbol->section_number = 2;
|
||||
symbol->storage_class = COFF_SymStorageClass_STATIC;
|
||||
symbol->storage_class = COFF_SymStorageClass_Static;
|
||||
}
|
||||
|
||||
// .idata$4
|
||||
@@ -682,8 +682,8 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
symbol->name.short_name[5] = 'a';
|
||||
symbol->name.short_name[6] = '$';
|
||||
symbol->name.short_name[7] = '4';
|
||||
symbol->section_number = COFF_SYMBOL_UNDEFINED_SECTION;
|
||||
symbol->storage_class = COFF_SymStorageClass_SECTION;
|
||||
symbol->section_number = COFF_Symbol_UndefinedSection;
|
||||
symbol->storage_class = COFF_SymStorageClass_Section;
|
||||
}
|
||||
|
||||
// .idata$5
|
||||
@@ -697,8 +697,8 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
symbol->name.short_name[5] = 'a';
|
||||
symbol->name.short_name[6] = '$';
|
||||
symbol->name.short_name[7] = '5';
|
||||
symbol->section_number = COFF_SYMBOL_UNDEFINED_SECTION;
|
||||
symbol->storage_class = COFF_SymStorageClass_SECTION;
|
||||
symbol->section_number = COFF_Symbol_UndefinedSection;
|
||||
symbol->storage_class = COFF_SymStorageClass_Section;
|
||||
}
|
||||
|
||||
// __NULL_IMPORT_DESCRIPTOR
|
||||
@@ -709,8 +709,8 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
COFF_Symbol16 *symbol = &symbol_array[5];
|
||||
symbol->name.long_name.zeroes = 0;
|
||||
symbol->name.long_name.string_table_offset = symbol_name_off;
|
||||
symbol->section_number = COFF_SYMBOL_UNDEFINED_SECTION;
|
||||
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
|
||||
symbol->section_number = COFF_Symbol_UndefinedSection;
|
||||
symbol->storage_class = COFF_SymStorageClass_External;
|
||||
}
|
||||
|
||||
// NULL_THUNK_DATA
|
||||
@@ -724,8 +724,8 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
|
||||
COFF_Symbol16 *symbol = &symbol_array[6];
|
||||
symbol->name.long_name.zeroes = 0;
|
||||
symbol->name.long_name.string_table_offset = symbol_name_off;
|
||||
symbol->section_number = COFF_SYMBOL_UNDEFINED_SECTION;
|
||||
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
|
||||
symbol->section_number = COFF_Symbol_UndefinedSection;
|
||||
symbol->storage_class = COFF_SymStorageClass_External;
|
||||
}
|
||||
|
||||
// update string table size
|
||||
@@ -742,7 +742,7 @@ lnk_build_null_import_descriptor_obj(Arena *arena, COFF_MachineType machine)
|
||||
|
||||
String8List list = {0};
|
||||
|
||||
COFF_Header *coff_header = push_array(arena, COFF_Header, 1);
|
||||
COFF_FileHeader *coff_header = push_array(arena, COFF_FileHeader, 1);
|
||||
coff_header->machine = machine;
|
||||
str8_list_push(arena, &list, str8_struct(coff_header));
|
||||
|
||||
@@ -776,7 +776,7 @@ lnk_build_null_import_descriptor_obj(Arena *arena, COFF_MachineType machine)
|
||||
sect->name[7] = '3';
|
||||
sect->fsize = null_import_data_size;
|
||||
sect->foff = null_import_data_off;
|
||||
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_4BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
|
||||
sect->flags = COFF_SectionFlag_CntInitializedData|(COFF_SectionAlign_4Bytes << COFF_SectionFlag_AlignShift)|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -787,7 +787,7 @@ lnk_build_null_import_descriptor_obj(Arena *arena, COFF_MachineType machine)
|
||||
symbol->name.long_name.zeroes = 0;
|
||||
symbol->name.long_name.string_table_offset = symbol_name_off;
|
||||
symbol->section_number = 1;
|
||||
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
|
||||
symbol->storage_class = COFF_SymStorageClass_External;
|
||||
}
|
||||
|
||||
// update string table size
|
||||
@@ -806,7 +806,7 @@ lnk_build_null_thunk_data_obj(Arena *arena, String8 dll_name, COFF_MachineType m
|
||||
|
||||
String8List list = {0};
|
||||
|
||||
COFF_Header *coff_header = push_array(arena, COFF_Header, 1);
|
||||
COFF_FileHeader *coff_header = push_array(arena, COFF_FileHeader, 1);
|
||||
coff_header->machine = machine;
|
||||
str8_list_push(arena, &list, str8_struct(coff_header));
|
||||
|
||||
@@ -845,7 +845,7 @@ lnk_build_null_thunk_data_obj(Arena *arena, String8 dll_name, COFF_MachineType m
|
||||
sect->name[7] = '5';
|
||||
sect->fsize = lookup_entry_data_size;
|
||||
sect->foff = lookup_entry_data_off;
|
||||
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_8BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
|
||||
sect->flags = COFF_SectionFlag_CntInitializedData | (COFF_SectionAlign_8Bytes << COFF_SectionFlag_AlignShift)|(COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -860,7 +860,7 @@ lnk_build_null_thunk_data_obj(Arena *arena, String8 dll_name, COFF_MachineType m
|
||||
sect->name[7] = '4';
|
||||
sect->fsize = null_thunk_data_size;
|
||||
sect->foff = null_thunk_data_off;
|
||||
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_8BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
|
||||
sect->flags = COFF_SectionFlag_CntInitializedData|(COFF_SectionAlign_8Bytes << COFF_SectionFlag_AlignShift)|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -874,7 +874,7 @@ lnk_build_null_thunk_data_obj(Arena *arena, String8 dll_name, COFF_MachineType m
|
||||
symbol->name.long_name.zeroes = 0;
|
||||
symbol->name.long_name.string_table_offset = symbol_name_off;
|
||||
symbol->section_number = 1;
|
||||
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
|
||||
symbol->storage_class = COFF_SymStorageClass_External;
|
||||
}
|
||||
|
||||
// update string table size
|
||||
@@ -908,7 +908,7 @@ lnk_build_lib_member_header(Arena *arena, String8 name, COFF_TimeStamp time_stam
|
||||
str8_list_pushf(scratch.arena, &list, "`\n");
|
||||
String8 result = str8_list_join(arena, &list, 0);
|
||||
|
||||
Assert(result.size == COFF_ARCHIVE_MEMBER_HEADER_SIZE);
|
||||
Assert(result.size == sizeof(COFF_ArchiveMemberHeader));
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
return result;
|
||||
|
||||
+26
-27
@@ -327,7 +327,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
String8 cached_lib_path = push_str8_copy(arena, input->lib_path);
|
||||
|
||||
// parse coff obj
|
||||
COFF_HeaderInfo coff_info = coff_header_info_from_data(input->data);
|
||||
COFF_FileHeaderInfo coff_info = coff_file_header_info_from_data(input->data);
|
||||
Rng1U64 coff_file_header_range = rng_1u64(0, coff_info.header_size);
|
||||
Rng1U64 coff_sect_arr_range = rng_1u64(coff_info.section_array_off, coff_info.section_array_off + coff_info.section_count_no_null * sizeof(COFF_SectionHeader));
|
||||
Rng1U64 coff_symbols_range = rng_1u64(coff_info.symbol_off, coff_info.symbol_off + coff_info.symbol_count * coff_info.symbol_size);
|
||||
@@ -368,13 +368,13 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
COFF_SectionHeader *coff_sect = &coff_sect_arr[sect_idx];
|
||||
|
||||
// read name
|
||||
String8 sect_name = coff_name_from_section_header(coff_sect, input->data, coff_info.string_table_off);
|
||||
String8 sect_name = coff_name_from_section_header(input->data, coff_sect, coff_info.string_table_off);
|
||||
|
||||
// parse section name
|
||||
coff_parse_section_name(sect_name, §_name_arr[sect_idx], §_sort_arr[sect_idx]);
|
||||
|
||||
String8 data;
|
||||
if (coff_sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
|
||||
if (coff_sect->flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
data = str8(0, coff_sect->fsize);
|
||||
} else {
|
||||
if (coff_sect->fsize > 0) {
|
||||
@@ -403,7 +403,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
|
||||
LNK_Chunk *chunk = &chunk_arr[sect_idx];
|
||||
chunk->align = coff_align_size_from_section_flags(coff_sect->flags);
|
||||
chunk->is_discarded = !!(coff_sect->flags & COFF_SectionFlag_LNK_REMOVE);
|
||||
chunk->is_discarded = !!(coff_sect->flags & COFF_SectionFlag_LnkRemove);
|
||||
chunk->sort_chunk = 1;
|
||||
chunk->type = LNK_Chunk_Leaf;
|
||||
chunk->sort_idx = sect_sort_arr[sect_idx];
|
||||
@@ -433,8 +433,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
}
|
||||
|
||||
// convert from coff
|
||||
B32 is_big_obj = coff_info.type == COFF_DataType_BIG_OBJ;
|
||||
LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, cached_lib_path, is_big_obj, function_pad_min, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_info.symbol_count, coff_symbols, chunk_ptr_arr, master_common_block);
|
||||
LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, cached_lib_path, coff_info.is_big_obj, function_pad_min, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_info.symbol_count, coff_symbols, chunk_ptr_arr, master_common_block);
|
||||
LNK_SymbolList symbol_list = lnk_symbol_list_from_array(arena, symbol_arr);
|
||||
LNK_RelocList *reloc_list_arr = lnk_reloc_list_array_from_coff(arena, coff_info.machine, input->data, coff_info.section_count_no_null, coff_sect_arr, chunk_ptr_arr, symbol_arr);
|
||||
LNK_DirectiveInfo directive_info = lnk_directive_info_from_sections(arena, cached_path, cached_lib_path, coff_info.section_count_no_null, reloc_list_arr, sect_name_arr, chunk_arr);
|
||||
@@ -495,7 +494,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_new_sect_scanner)
|
||||
|
||||
for (U64 chunk_idx = 0; chunk_idx < obj->chunk_count; chunk_idx += 1) {
|
||||
String8 sect_name = obj->sect_name_arr[chunk_idx];
|
||||
COFF_SectionFlags sect_flags = obj->chunk_arr[chunk_idx]->flags & ~COFF_SectionFlags_LNK_FLAGS;
|
||||
COFF_SectionFlags sect_flags = obj->chunk_arr[chunk_idx]->flags & ~COFF_SectionFlags_LnkFlags;
|
||||
|
||||
KeyValuePair *is_present = hash_table_search_string(ht, sect_name);
|
||||
if (is_present) {
|
||||
@@ -675,7 +674,7 @@ lnk_obj_list_push_parallel(TP_Context *tp,
|
||||
|
||||
// push new sections for :find_chunk_section
|
||||
for (LNK_SectDefn *curr = new_list.first; curr != 0; curr = curr->next) {
|
||||
lnk_section_table_push(st, curr->name, curr->flags & ~COFF_SectionFlags_LNK_FLAGS);
|
||||
lnk_section_table_push(st, curr->name, curr->flags & ~COFF_SectionFlags_LnkFlags);
|
||||
}
|
||||
|
||||
tp_temp_end(temp);
|
||||
@@ -763,7 +762,7 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
|
||||
// is this a function symbol?
|
||||
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
||||
if (interp == COFF_SymbolValueInterp_REGULAR && COFF_SymbolType_IsFunc(symbol.type)) {
|
||||
if (interp == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) {
|
||||
if (symbol.section_number == 0 || symbol.section_number > sect_count) {
|
||||
lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "out ouf bounds section index in symbol \"%S (%u)\"", symbol.name, symbol.section_number);
|
||||
}
|
||||
@@ -879,7 +878,7 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
|
||||
COFF_SymbolValueInterpType interp = coff_interp_symbol(parsed_symbol.section_number, parsed_symbol.value, parsed_symbol.storage_class);
|
||||
switch (interp) {
|
||||
case COFF_SymbolValueInterp_REGULAR: {
|
||||
case COFF_SymbolValueInterp_Regular: {
|
||||
if (parsed_symbol.section_number == 0 || parsed_symbol.section_number > sect_count) {
|
||||
lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "symbol %S (No. %llx) has out ouf bounds section index %x", parsed_symbol.name, symbol_idx, parsed_symbol.section_number);
|
||||
}
|
||||
@@ -889,7 +888,7 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
|
||||
|
||||
LNK_DefinedSymbolVisibility visibility = LNK_DefinedSymbolVisibility_Static;
|
||||
if (parsed_symbol.storage_class == COFF_SymStorageClass_EXTERNAL) {
|
||||
if (parsed_symbol.storage_class == COFF_SymStorageClass_External) {
|
||||
visibility = LNK_DefinedSymbolVisibility_Extern;
|
||||
}
|
||||
LNK_DefinedSymbolFlags flags = 0;
|
||||
@@ -900,15 +899,15 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
|
||||
LNK_Chunk *chunk = chunk_ptr_arr[parsed_symbol.section_number-1];
|
||||
U64 offset = parsed_symbol.value;
|
||||
COFF_ComdatSelectType selection = COFF_ComdatSelectType_ANY;
|
||||
COFF_ComdatSelectType selection = COFF_ComdatSelect_Any;
|
||||
U64 check_sum = 0;
|
||||
|
||||
|
||||
B32 is_comdat = (coff_sect_arr[parsed_symbol.section_number-1].flags & COFF_SectionFlag_LNK_COMDAT) &&
|
||||
B32 is_comdat = (coff_sect_arr[parsed_symbol.section_number-1].flags & COFF_SectionFlag_LnkCOMDAT) &&
|
||||
parsed_symbol.value == 0 &&
|
||||
parsed_symbol.aux_symbol_count > 0 &&
|
||||
parsed_symbol.type.u.lsb == COFF_SymType_NULL &&
|
||||
parsed_symbol.storage_class == COFF_SymStorageClass_STATIC;
|
||||
parsed_symbol.type.u.lsb == COFF_SymType_Null &&
|
||||
parsed_symbol.storage_class == COFF_SymStorageClass_Static;
|
||||
if (is_comdat) {
|
||||
COFF_SymbolSecDef *secdef = aux_symbols;
|
||||
|
||||
@@ -916,7 +915,7 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
check_sum = secdef->check_sum;
|
||||
|
||||
// create association link between chunks
|
||||
if (secdef->selection == COFF_ComdatSelectType_ASSOCIATIVE) {
|
||||
if (secdef->selection == COFF_ComdatSelect_Associative) {
|
||||
U32 secdef_number = secdef->number_lo;
|
||||
|
||||
// promote secdef number to 32 bits
|
||||
@@ -955,7 +954,7 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
lnk_init_defined_symbol_chunk(&symbol_array.v[symbol_idx], parsed_symbol.name, visibility, flags, chunk, offset, selection, check_sum);
|
||||
symbol_array.v[symbol_idx].obj = obj;
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_WEAK: {
|
||||
case COFF_SymbolValueInterp_Weak: {
|
||||
if (parsed_symbol.aux_symbol_count == 0) {
|
||||
lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "weak symbol \"%S (%u)\" must at least one aux symbol", parsed_symbol.name, symbol_idx);
|
||||
}
|
||||
@@ -972,12 +971,12 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
symbol->obj = obj;
|
||||
fallback_symbol->obj = obj;
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_UNDEFINED: {
|
||||
case COFF_SymbolValueInterp_Undefined: {
|
||||
LNK_Symbol *symbol = &symbol_array.v[symbol_idx];
|
||||
lnk_init_undefined_symbol(symbol, parsed_symbol.name, LNK_SymbolScopeFlag_Main);
|
||||
symbol->obj = obj;
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_COMMON: {
|
||||
case COFF_SymbolValueInterp_Common: {
|
||||
// :common_block
|
||||
//
|
||||
// TODO: sort chunks on size to reduce bss usage
|
||||
@@ -995,16 +994,16 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
}
|
||||
|
||||
LNK_Symbol *symbol = &symbol_array.v[symbol_idx];
|
||||
lnk_init_defined_symbol_chunk(symbol, parsed_symbol.name, LNK_DefinedSymbolVisibility_Extern, flags, chunk, 0, COFF_ComdatSelectType_LARGEST, 0);
|
||||
lnk_init_defined_symbol_chunk(symbol, parsed_symbol.name, LNK_DefinedSymbolVisibility_Extern, flags, chunk, 0, COFF_ComdatSelect_Largest, 0);
|
||||
symbol->obj = obj;
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_ABS: {
|
||||
case COFF_SymbolValueInterp_Abs: {
|
||||
// Never code or data, synthetic symbol. COFF spec says bits in value are used
|
||||
// as flags in symbol @feat.00, other symbols like @comp.id and @vol.md are undocumented.
|
||||
// LLVM uses undocumented mask 0x4800 on @feat.00 to tell if object was compiled with /guard:cf.
|
||||
|
||||
LNK_DefinedSymbolVisibility visibility = LNK_DefinedSymbolVisibility_Static;
|
||||
if (parsed_symbol.storage_class == COFF_SymStorageClass_EXTERNAL) {
|
||||
if (parsed_symbol.storage_class == COFF_SymStorageClass_External) {
|
||||
visibility = LNK_DefinedSymbolVisibility_Extern;
|
||||
}
|
||||
|
||||
@@ -1012,7 +1011,7 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
lnk_init_defined_symbol_va(symbol, parsed_symbol.name, visibility, 0, parsed_symbol.value);
|
||||
symbol->obj = obj;
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_DEBUG: {
|
||||
case COFF_SymbolValueInterp_Debug: {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@@ -1025,8 +1024,8 @@ lnk_reloc_list_array_from_coff(Arena *arena, COFF_MachineType machine, String8 c
|
||||
{
|
||||
LNK_RelocList *reloc_list_arr = push_array_no_zero(arena, LNK_RelocList, sect_count);
|
||||
for (U64 sect_idx = 0; sect_idx < sect_count; ++sect_idx) {
|
||||
COFF_SectionHeader *coff_header = &coff_sect_arr[sect_idx];
|
||||
COFF_RelocInfo coff_reloc_info = coff_reloc_info_from_section_header(coff_data, coff_header);
|
||||
COFF_SectionHeader *COFF_FileHeader = &coff_sect_arr[sect_idx];
|
||||
COFF_RelocInfo coff_reloc_info = coff_reloc_info_from_section_header(coff_data, COFF_FileHeader);
|
||||
COFF_Reloc *coff_reloc_v = (COFF_Reloc *)(coff_data.str + coff_reloc_info.array_off);
|
||||
LNK_Chunk *sect_chunk = chunk_ptr_arr[sect_idx];
|
||||
reloc_list_arr[sect_idx] = lnk_reloc_list_from_coff_reloc_array(arena, machine, sect_chunk, symbol_array, coff_reloc_v, coff_reloc_info.count);
|
||||
@@ -1122,8 +1121,8 @@ lnk_directive_info_from_sections(Arena *arena,
|
||||
if (str8_match_lit(".drectve", sect_name, 0)) {
|
||||
if (sect_chunk->type == LNK_Chunk_Leaf) {
|
||||
if (sect_chunk->u.leaf.size >= 3) {
|
||||
if (~sect_chunk->flags & COFF_SectionFlag_LNK_INFO) {
|
||||
lnk_error_with_loc(LNK_Warning_IllData, obj_path, lib_path, "%S missing COFF_SectionFlag_LNK_INFO", sect_name);
|
||||
if (~sect_chunk->flags & COFF_SectionFlag_LnkInfo) {
|
||||
lnk_error_with_loc(LNK_Warning_IllData, obj_path, lib_path, "%S missing COFF_SectionFlag_LnkInfo", sect_name);
|
||||
}
|
||||
if (reloc_list_arr[chunk_idx].count > 0) {
|
||||
lnk_error_with_loc(LNK_Warning_DirectiveSectionWithRelocs, obj_path, lib_path, "directive section %S(%#x) has relocations", sect_name, (chunk_idx+1));
|
||||
|
||||
+32
-32
@@ -117,26 +117,26 @@ lnk_ext_reloc_type_from_coff(COFF_MachineType machine, U32 type)
|
||||
{
|
||||
LNK_RelocType result = LNK_Reloc_NULL;
|
||||
switch (machine) {
|
||||
case COFF_MachineType_UNKNOWN: break;
|
||||
case COFF_MachineType_X64: {
|
||||
case COFF_Machine_Unknown: break;
|
||||
case COFF_Machine_X64: {
|
||||
switch (type) {
|
||||
case COFF_RelocTypeX64_ABS: result = LNK_Reloc_NULL; break;
|
||||
case COFF_RelocTypeX64_ADDR64: result = LNK_Reloc_ADDR_64; break;
|
||||
case COFF_RelocTypeX64_ADDR32: result = LNK_Reloc_ADDR_32; break;
|
||||
case COFF_RelocTypeX64_ADDR32NB: result = LNK_Reloc_VIRT_OFF_32; break;
|
||||
case COFF_RelocTypeX64_REL32: result = LNK_Reloc_REL32; break;
|
||||
case COFF_RelocTypeX64_REL32_1: result = LNK_Reloc_REL32_1; break;
|
||||
case COFF_RelocTypeX64_REL32_2: result = LNK_Reloc_REL32_2; break;
|
||||
case COFF_RelocTypeX64_REL32_3: result = LNK_Reloc_REL32_3; break;
|
||||
case COFF_RelocTypeX64_REL32_4: result = LNK_Reloc_REL32_4; break;
|
||||
case COFF_RelocTypeX64_REL32_5: result = LNK_Reloc_REL32_5; break;
|
||||
case COFF_RelocTypeX64_SECTION: result = LNK_Reloc_SECT_IDX; break;
|
||||
case COFF_RelocTypeX64_SECREL: result = LNK_Reloc_SECT_REL; break;
|
||||
case COFF_RelocTypeX64_SECREL7: lnk_not_implemented("TODO: COFF_RelocTypeX64_SECREL7"); break;
|
||||
case COFF_RelocTypeX64_TOKEN: lnk_not_implemented("TODO: COFF_RelocTypeX64_TOKEN"); break;
|
||||
case COFF_RelocTypeX64_SREL32: lnk_not_implemented("TODO: COFF_RelocTypeX64_SREL32"); break;
|
||||
case COFF_RelocTypeX64_PAIR: lnk_not_implemented("TODO: COFF_RelocTypeX64_PAIR"); break;
|
||||
case COFF_RelocTypeX64_SSPAN32: lnk_not_implemented("TODO: COFF_RelocTypeX64_SSPAN32"); break;
|
||||
case COFF_Reloc_X64_Abs: result = LNK_Reloc_NULL; break;
|
||||
case COFF_Reloc_X64_Addr64: result = LNK_Reloc_ADDR_64; break;
|
||||
case COFF_Reloc_X64_Addr32: result = LNK_Reloc_ADDR_32; break;
|
||||
case COFF_Reloc_X64_Addr32Nb: result = LNK_Reloc_VIRT_OFF_32; break;
|
||||
case COFF_Reloc_X64_Rel32: result = LNK_Reloc_REL32; break;
|
||||
case COFF_Reloc_X64_Rel32_1: result = LNK_Reloc_REL32_1; break;
|
||||
case COFF_Reloc_X64_Rel32_2: result = LNK_Reloc_REL32_2; break;
|
||||
case COFF_Reloc_X64_Rel32_3: result = LNK_Reloc_REL32_3; break;
|
||||
case COFF_Reloc_X64_Rel32_4: result = LNK_Reloc_REL32_4; break;
|
||||
case COFF_Reloc_X64_Rel32_5: result = LNK_Reloc_REL32_5; break;
|
||||
case COFF_Reloc_X64_Section: result = LNK_Reloc_SECT_IDX; break;
|
||||
case COFF_Reloc_X64_SecRel: result = LNK_Reloc_SECT_REL; break;
|
||||
case COFF_Reloc_X64_SecRel7: lnk_not_implemented("TODO: COFF_Reloc_X64_SecRel7"); break;
|
||||
case COFF_Reloc_X64_Token: lnk_not_implemented("TODO: COFF_Reloc_X64_Token"); break;
|
||||
case COFF_Reloc_X64_SRel32: lnk_not_implemented("TODO: COFF_Reloc_X64_SRel32"); break;
|
||||
case COFF_Reloc_X64_Pair: lnk_not_implemented("TODO: COFF_Reloc_X64_Pair"); break;
|
||||
case COFF_Reloc_X64_SSpan32: lnk_not_implemented("TODO: COFF_Reloc_X64_SSpan32"); break;
|
||||
default: lnk_invalid_path("unknown relocation type 0x%X", type);
|
||||
}
|
||||
} break;
|
||||
@@ -150,20 +150,20 @@ lnk_ext_reloc_type_to_coff(COFF_MachineType machine, LNK_RelocType type)
|
||||
{
|
||||
U32 result = 0;
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X64: {
|
||||
case COFF_Machine_X64: {
|
||||
switch (type) {
|
||||
case LNK_Reloc_NULL: result = COFF_RelocTypeX64_ABS; break;
|
||||
case LNK_Reloc_ADDR_64: result = COFF_RelocTypeX64_ADDR64; break;
|
||||
case LNK_Reloc_ADDR_32: result = COFF_RelocTypeX64_ADDR32; break;
|
||||
case LNK_Reloc_VIRT_OFF_32: result = COFF_RelocTypeX64_ADDR32NB; break;
|
||||
case LNK_Reloc_REL32: result = COFF_RelocTypeX64_REL32; break;
|
||||
case LNK_Reloc_REL32_1: result = COFF_RelocTypeX64_REL32_1; break;
|
||||
case LNK_Reloc_REL32_2: result = COFF_RelocTypeX64_REL32_2; break;
|
||||
case LNK_Reloc_REL32_3: result = COFF_RelocTypeX64_REL32_3; break;
|
||||
case LNK_Reloc_REL32_4: result = COFF_RelocTypeX64_REL32_4; break;
|
||||
case LNK_Reloc_REL32_5: result = COFF_RelocTypeX64_REL32_5; break;
|
||||
case LNK_Reloc_SECT_IDX: result = COFF_RelocTypeX64_SECTION; break;
|
||||
case LNK_Reloc_SECT_REL: result = COFF_RelocTypeX64_SECREL; break;
|
||||
case LNK_Reloc_NULL: result = COFF_Reloc_X64_Abs; break;
|
||||
case LNK_Reloc_ADDR_64: result = COFF_Reloc_X64_Addr64; break;
|
||||
case LNK_Reloc_ADDR_32: result = COFF_Reloc_X64_Addr32; break;
|
||||
case LNK_Reloc_VIRT_OFF_32: result = COFF_Reloc_X64_Addr32Nb; break;
|
||||
case LNK_Reloc_REL32: result = COFF_Reloc_X64_Rel32; break;
|
||||
case LNK_Reloc_REL32_1: result = COFF_Reloc_X64_Rel32_1; break;
|
||||
case LNK_Reloc_REL32_2: result = COFF_Reloc_X64_Rel32_2; break;
|
||||
case LNK_Reloc_REL32_3: result = COFF_Reloc_X64_Rel32_3; break;
|
||||
case LNK_Reloc_REL32_4: result = COFF_Reloc_X64_Rel32_4; break;
|
||||
case LNK_Reloc_REL32_5: result = COFF_Reloc_X64_Rel32_5; break;
|
||||
case LNK_Reloc_SECT_IDX: result = COFF_Reloc_X64_Section; break;
|
||||
case LNK_Reloc_SECT_REL: result = COFF_Reloc_X64_SecRel; break;
|
||||
default: InvalidPath;
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -85,7 +85,7 @@ lnk_make_section_sort_index(Arena *arena, String8 name, COFF_SectionFlags flags,
|
||||
|
||||
// pack sections with run-time data closer
|
||||
String8List sort_index_list = {0};
|
||||
if (flags & COFF_SectionFlag_MEM_DISCARDABLE) {
|
||||
if (flags & COFF_SectionFlag_MemDiscardable) {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "b");
|
||||
} else {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "a");
|
||||
@@ -102,14 +102,14 @@ lnk_make_section_sort_index(Arena *arena, String8 name, COFF_SectionFlags flags,
|
||||
}
|
||||
|
||||
// sort sections based on the contents
|
||||
if (flags & COFF_SectionFlag_CNT_CODE) {
|
||||
if (flags & COFF_SectionFlag_CntCode) {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "a");
|
||||
if (str8_match_lit(".text", name, 0)) {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "a");
|
||||
} else {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "b");
|
||||
}
|
||||
} else if (flags & COFF_SectionFlag_CNT_INITIALIZED_DATA) {
|
||||
} else if (flags & COFF_SectionFlag_CntInitializedData) {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "b");
|
||||
if (str8_match_lit(".data", name, 0)) {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "a");
|
||||
@@ -120,14 +120,14 @@ lnk_make_section_sort_index(Arena *arena, String8 name, COFF_SectionFlags flags,
|
||||
} else {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "d");
|
||||
}
|
||||
} else if (flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
|
||||
} else if (flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "c");
|
||||
} else {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "d");
|
||||
}
|
||||
|
||||
// sort sections based on read/write access so final section layout looks cleaner
|
||||
if (flags & COFF_SectionFlag_MEM_READ && ~flags & COFF_SectionFlag_MEM_WRITE) {
|
||||
if (flags & COFF_SectionFlag_MemRead && ~flags & COFF_SectionFlag_MemWrite) {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "a");
|
||||
} else {
|
||||
str8_list_pushf(scratch.arena, &sort_index_list, "b");
|
||||
@@ -236,8 +236,8 @@ lnk_code_align_byte_from_machine(COFF_MachineType machine)
|
||||
{
|
||||
U8 align_byte = 0;
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X64:
|
||||
case COFF_MachineType_X86: {
|
||||
case COFF_Machine_X64:
|
||||
case COFF_Machine_X86: {
|
||||
align_byte = 0xCC;
|
||||
} break;
|
||||
default: {
|
||||
@@ -570,7 +570,7 @@ lnk_section_table_assign_file_offsets(LNK_SectionTable *st)
|
||||
U64 cursor = 0;
|
||||
for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) {
|
||||
LNK_Section *sect = §_node->data;
|
||||
if (sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
|
||||
if (sect->flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
continue;
|
||||
}
|
||||
if (!sect->has_layout) continue;
|
||||
@@ -617,7 +617,7 @@ lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *st,
|
||||
for (LNK_SectionNode *sect_n = st->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
LNK_Section *sect = §_n->data;
|
||||
if (sect->has_layout) {
|
||||
if (sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
|
||||
if (sect->flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -625,7 +625,7 @@ lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *st,
|
||||
String8 sect_data = str8_substr(image, rng_1u64(image_cursor, image_cursor + sect_size));
|
||||
|
||||
U8 fill_byte = 0;
|
||||
if (sect->flags & COFF_SectionFlag_CNT_CODE) {
|
||||
if (sect->flags & COFF_SectionFlag_CntCode) {
|
||||
fill_byte = lnk_code_align_byte_from_machine(machine);
|
||||
}
|
||||
|
||||
|
||||
@@ -271,17 +271,17 @@ lnk_can_replace_symbol(const LNK_Symbol *dst, const LNK_Symbol *src)
|
||||
COFF_ComdatSelectType src_select = src_defn->u.selection;
|
||||
|
||||
// handle objs compiled with /GR- and /GR
|
||||
if ((src_select == COFF_ComdatSelectType_ANY && dst_select == COFF_ComdatSelectType_LARGEST) ||
|
||||
(src_select == COFF_ComdatSelectType_LARGEST && dst_select == COFF_ComdatSelectType_ANY)) {
|
||||
dst_select = COFF_ComdatSelectType_LARGEST;
|
||||
src_select = COFF_ComdatSelectType_LARGEST;
|
||||
if ((src_select == COFF_ComdatSelect_Any && dst_select == COFF_ComdatSelect_Largest) ||
|
||||
(src_select == COFF_ComdatSelect_Largest && dst_select == COFF_ComdatSelect_Any)) {
|
||||
dst_select = COFF_ComdatSelect_Largest;
|
||||
src_select = COFF_ComdatSelect_Largest;
|
||||
}
|
||||
|
||||
if (src_select == dst_select) {
|
||||
switch (src_select) {
|
||||
default: InvalidPath;
|
||||
case COFF_ComdatSelectType_NULL:
|
||||
case COFF_ComdatSelectType_ANY: {
|
||||
case COFF_ComdatSelect_Null:
|
||||
case COFF_ComdatSelect_Any: {
|
||||
LNK_Chunk *dst_chunk = dst_defn->u.chunk;
|
||||
LNK_Chunk *src_chunk = src_defn->u.chunk;
|
||||
U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk);
|
||||
@@ -293,10 +293,10 @@ lnk_can_replace_symbol(const LNK_Symbol *dst, const LNK_Symbol *src)
|
||||
can_replace = src_chunk_size < dst_chunk_size;
|
||||
}
|
||||
} break;
|
||||
case COFF_ComdatSelectType_NODUPLICATES: {
|
||||
case COFF_ComdatSelect_NoDuplicates: {
|
||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path);
|
||||
} break;
|
||||
case COFF_ComdatSelectType_SAME_SIZE: {
|
||||
case COFF_ComdatSelect_SameSize: {
|
||||
LNK_Chunk *dst_chunk = dst_defn->u.chunk;
|
||||
LNK_Chunk *src_chunk = src_defn->u.chunk;
|
||||
U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk);
|
||||
@@ -306,13 +306,13 @@ lnk_can_replace_symbol(const LNK_Symbol *dst, const LNK_Symbol *src)
|
||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path);
|
||||
}
|
||||
} break;
|
||||
case COFF_ComdatSelectType_EXACT_MATCH: {
|
||||
case COFF_ComdatSelect_ExactMatch: {
|
||||
B32 is_exact_match = (dst_defn->u.check_sum == src_defn->u.check_sum);
|
||||
if (!is_exact_match) {
|
||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path);
|
||||
}
|
||||
} break;
|
||||
case COFF_ComdatSelectType_LARGEST: {
|
||||
case COFF_ComdatSelect_Largest: {
|
||||
LNK_Chunk *dst_chunk = dst_defn->u.chunk;
|
||||
LNK_Chunk *src_chunk = src_defn->u.chunk;
|
||||
U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk);
|
||||
@@ -330,7 +330,7 @@ lnk_can_replace_symbol(const LNK_Symbol *dst, const LNK_Symbol *src)
|
||||
can_replace = dst_chunk_size < src_chunk_size;
|
||||
}
|
||||
} break;
|
||||
case COFF_ComdatSelectType_ASSOCIATIVE: {
|
||||
case COFF_ComdatSelect_Associative: {
|
||||
// ignore
|
||||
} break;
|
||||
}
|
||||
@@ -630,7 +630,7 @@ lnk_symbol_table_push_weak(LNK_SymbolTable *symtab, String8 weak_name, COFF_Weak
|
||||
weak_name = push_str8_copy(symtab->arena->v[0], weak_name);
|
||||
strong_name = push_str8_copy(symtab->arena->v[0], strong_name);
|
||||
LNK_Symbol *strong_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], strong_name, LNK_SymbolScopeFlag_Main);
|
||||
LNK_Symbol *weak_symbol = lnk_make_weak_symbol(symtab->arena->v[0], weak_name, COFF_WeakExtType_SEARCH_ALIAS, strong_symbol);
|
||||
LNK_Symbol *weak_symbol = lnk_make_weak_symbol(symtab->arena->v[0], weak_name, COFF_WeakExt_SearchAlias, strong_symbol);
|
||||
lnk_symbol_table_push(symtab, weak_symbol);
|
||||
return weak_symbol;
|
||||
}
|
||||
|
||||
@@ -3270,21 +3270,21 @@ dbi_build_sec_map(Arena *arena, PDB_DbiContext *dbi)
|
||||
U64 isect = 0;
|
||||
for (PDB_DbiSectionNode *sect = dbi->section_list.first; sect; sect = sect->next, ++isect) {
|
||||
PDB_DbiSecMapEntry *s = &entry_array[isect];
|
||||
COFF_SectionHeader *coff_header = §->data;
|
||||
if (coff_header->flags & COFF_SectionFlag_MEM_READ) {
|
||||
COFF_SectionHeader *section_header = §->data;
|
||||
if (section_header->flags & COFF_SectionFlag_MemRead) {
|
||||
s->flags |= PDB_DbiOMF_READ;
|
||||
}
|
||||
if (coff_header->flags & COFF_SectionFlag_MEM_WRITE) {
|
||||
if (section_header->flags & COFF_SectionFlag_MemWrite) {
|
||||
s->flags |= PDB_DbiOMF_WRITE;
|
||||
}
|
||||
if (coff_header->flags & COFF_SectionFlag_MEM_EXECUTE) {
|
||||
if (section_header->flags & COFF_SectionFlag_MemExecute) {
|
||||
s->flags |= PDB_DbiOMF_EXEC;
|
||||
}
|
||||
if (~coff_header->flags & COFF_SectionFlag_MEM_16BIT) {
|
||||
if (~section_header->flags & COFF_SectionFlag_Mem16Bit) {
|
||||
s->flags |= PDB_DbiOMF_IS_32BIT_ADDR;
|
||||
}
|
||||
s->flags |= PDB_DbiOMF_IS_SELECTOR; // always set
|
||||
s->sec_size = coff_header->vsize;
|
||||
s->sec_size = section_header->vsize;
|
||||
s->frame = isect + 1;
|
||||
s->sec_name = max_U16;
|
||||
s->class_name = max_U16;
|
||||
@@ -3444,7 +3444,7 @@ dbi_module_push_section_contrib(PDB_DbiContext *dbi,
|
||||
|
||||
// Mod1::fUpdateSecContrib
|
||||
if (mod->first_sc.base.mod == 0) {
|
||||
if (flags & COFF_SectionFlag_CNT_CODE) {
|
||||
if (flags & COFF_SectionFlag_CntCode) {
|
||||
mod->first_sc = sc;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-27
@@ -5,31 +5,31 @@ internal RDI_Arch
|
||||
rdi_arch_from_coff_machine(COFF_MachineType machine)
|
||||
{
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X86: return RDI_Arch_X86;
|
||||
case COFF_MachineType_X64: return RDI_Arch_X64;
|
||||
case COFF_Machine_X86: return RDI_Arch_X86;
|
||||
case COFF_Machine_X64: return RDI_Arch_X64;
|
||||
|
||||
case COFF_MachineType_UNKNOWN:
|
||||
case COFF_MachineType_AM33:
|
||||
case COFF_MachineType_ARM:
|
||||
case COFF_MachineType_ARM64:
|
||||
case COFF_MachineType_ARMNT:
|
||||
case COFF_MachineType_EBC:
|
||||
case COFF_MachineType_IA64:
|
||||
case COFF_MachineType_M32R:
|
||||
case COFF_MachineType_MIPS16:
|
||||
case COFF_MachineType_MIPSFPU:
|
||||
case COFF_MachineType_MIPSFPU16:
|
||||
case COFF_MachineType_POWERPC:
|
||||
case COFF_MachineType_POWERPCFP:
|
||||
case COFF_MachineType_R4000:
|
||||
case COFF_MachineType_RISCV32:
|
||||
case COFF_MachineType_RISCV64:
|
||||
case COFF_MachineType_SH3:
|
||||
case COFF_MachineType_SH3DSP:
|
||||
case COFF_MachineType_SH4:
|
||||
case COFF_MachineType_SH5:
|
||||
case COFF_MachineType_THUMB:
|
||||
case COFF_MachineType_WCEMIPSV2:
|
||||
case COFF_Machine_Unknown:
|
||||
case COFF_Machine_Am33:
|
||||
case COFF_Machine_Arm:
|
||||
case COFF_Machine_Arm64:
|
||||
case COFF_Machine_ArmNt:
|
||||
case COFF_Machine_Ebc:
|
||||
case COFF_Machine_Ia64:
|
||||
case COFF_Machine_M32R:
|
||||
case COFF_Machine_Mips16:
|
||||
case COFF_Machine_MipsFpu:
|
||||
case COFF_Machine_MipsFpu16:
|
||||
case COFF_Machine_PowerPc:
|
||||
case COFF_Machine_PowerPcFp:
|
||||
case COFF_Machine_R4000:
|
||||
case COFF_Machine_RiscV32:
|
||||
case COFF_Machine_RiscV64:
|
||||
case COFF_Machine_Sh3:
|
||||
case COFF_Machine_Sh3Dsp:
|
||||
case COFF_Machine_Sh4:
|
||||
case COFF_Machine_Sh5:
|
||||
case COFF_Machine_Thumb:
|
||||
case COFF_Machine_WceMipsV2:
|
||||
NotImplemented;
|
||||
default:
|
||||
return RDI_Arch_NULL;
|
||||
@@ -40,13 +40,13 @@ internal RDI_BinarySectionFlags
|
||||
rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags)
|
||||
{
|
||||
RDI_BinarySectionFlags result = 0;
|
||||
if (flags & COFF_SectionFlag_MEM_READ) {
|
||||
if (flags & COFF_SectionFlag_MemRead) {
|
||||
result |= RDI_BinarySectionFlag_Read;
|
||||
}
|
||||
if (flags & COFF_SectionFlag_MEM_WRITE) {
|
||||
if (flags & COFF_SectionFlag_MemWrite) {
|
||||
result |= RDI_BinarySectionFlag_Write;
|
||||
}
|
||||
if (flags & COFF_SectionFlag_MEM_EXECUTE) {
|
||||
if (flags & COFF_SectionFlag_MemExecute) {
|
||||
result |= RDI_BinarySectionFlag_Execute;
|
||||
}
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user