Files
raddebugger/src/linker/lnk_symbol_table.h
T
2024-11-08 11:43:05 -08:00

222 lines
7.8 KiB
C

// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#pragma once
typedef enum
{
LNK_SymbolScopeIndex_Defined,
LNK_SymbolScopeIndex_Internal, // symbols defined by linker
LNK_SymbolScopeIndex_Weak,
LNK_SymbolScopeIndex_Lib,
LNK_SymbolScopeIndex_Count
} LNK_SymbolScopeIndex;
enum
{
LNK_SymbolScopeFlag_Defined = 1,
LNK_SymbolScopeFlag_Internal = 2,
LNK_SymbolScopeFlag_Weak = 4,
LNK_SymbolScopeFlag_Lib = 8,
LNK_SymbolScopeFlag_Main = LNK_SymbolScopeFlag_Defined | LNK_SymbolScopeFlag_Weak,
LNK_SymbolScopeFlag_All = LNK_SymbolScopeFlag_Defined | LNK_SymbolScopeFlag_Weak | LNK_SymbolScopeFlag_Lib | LNK_SymbolScopeFlag_Internal
};
typedef U64 LNK_SymbolScopeFlags;
typedef enum
{
LNK_DefinedSymbolVisibility_Static,
LNK_DefinedSymbolVisibility_Extern,
LNK_DefinedSymbolVisibility_Internal,
} LNK_DefinedSymbolVisibility;
enum
{
LNK_DefinedSymbolFlag_IsFunc = (1 << 0),
LNK_DefinedSymbolFlag_IsThunk = (1 << 1),
};
typedef U64 LNK_DefinedSymbolFlags;
typedef enum
{
LNK_DefinedSymbolValue_Null,
LNK_DefinedSymbolValue_Chunk,
LNK_DefinedSymbolValue_VA
} LNK_DefinedSymbolValueType;
typedef struct LNK_DefinedSymbol
{
LNK_DefinedSymbolFlags flags;
LNK_DefinedSymbolValueType value_type;
union {
struct {
LNK_Chunk *chunk;
U64 chunk_offset;
U32 check_sum;
COFF_ComdatSelectType selection;
};
U64 va;
} u;
} LNK_DefinedSymbol;
typedef struct LNK_WeakSymbol
{
LNK_SymbolScopeFlags scope_flags;
COFF_WeakExtType lookup_type;
struct LNK_Symbol *fallback_symbol;
} LNK_WeakSymbol;
typedef struct LNK_UndefinedSymbol
{
LNK_SymbolScopeFlags scope_flags;
} LNK_UndefinedSymbol;
typedef struct LNK_LazySymbol
{
struct LNK_Lib *lib;
U64 member_offset;
} LNK_LazySymbol;
#define LNK_Symbol_IsDefined(type) ((type) == LNK_Symbol_DefinedStatic || (type) == LNK_Symbol_DefinedExtern || (type) == LNK_Symbol_DefinedInternal)
typedef enum
{
LNK_Symbol_Null,
LNK_Symbol_DefinedStatic,
LNK_Symbol_DefinedExtern,
LNK_Symbol_DefinedInternal,
LNK_Symbol_Weak,
LNK_Symbol_Lazy,
LNK_Symbol_Undefined,
} LNK_SymbolType;
typedef struct LNK_Symbol
{
String8 name;
LNK_SymbolType type;
struct LNK_Obj *obj;
union {
LNK_DefinedSymbol defined;
LNK_WeakSymbol weak;
LNK_UndefinedSymbol undefined;
LNK_LazySymbol lazy;
} u;
} LNK_Symbol;
typedef struct LNK_SymbolNode
{
struct LNK_SymbolNode *next;
LNK_Symbol *data;
} LNK_SymbolNode;
typedef struct LNK_SymbolList
{
U64 count;
LNK_SymbolNode *first;
LNK_SymbolNode *last;
} LNK_SymbolList;
typedef struct LNK_SymbolNodeArray
{
U64 count;
LNK_SymbolNode **v;
} LNK_SymbolNodeArray;
typedef struct LNK_SymbolArray
{
U64 count;
LNK_Symbol *v;
} LNK_SymbolArray;
typedef struct LNK_SymbolHashTrie
{
String8 *name;
LNK_Symbol *symbol;
struct LNK_SymbolHashTrie *child[4];
} LNK_SymbolHashTrie;
typedef struct LNK_SymbolHashTrieChunk
{
struct LNK_SymbolHashTrieChunk *next;
U64 count;
U64 cap;
LNK_SymbolHashTrie *v;
} LNK_SymbolHashTrieChunk;
typedef struct LNK_SymbolHashTrieChunkList
{
U64 count;
LNK_SymbolHashTrieChunk *first;
LNK_SymbolHashTrieChunk *last;
} LNK_SymbolHashTrieChunkList;
typedef struct LNK_SymbolTable
{
TP_Arena *arena;
LNK_SymbolHashTrie *scopes[LNK_SymbolScopeIndex_Count];
LNK_SymbolHashTrieChunkList *chunk_lists[LNK_SymbolScopeIndex_Count];
} LNK_SymbolTable;
////////////////////////////////
// parallel for wrappers
typedef struct
{
LNK_SymbolTable *symtab;
Rng1U64 *ranges;
LNK_Symbol *arr;
} LNK_LazySymbolInserter;
////////////////////////////////
global read_only LNK_Symbol g_null_symbol = { str8_lit_comp("NULL"), LNK_Symbol_DefinedStatic };
global read_only LNK_Symbol *g_null_symbol_ptr = &g_null_symbol;
////////////////////////////////
internal void lnk_init_symbol(LNK_Symbol *symbol, String8 name, LNK_SymbolType type);
internal void lnk_init_defined_symbol(LNK_Symbol *symbol, String8 name, LNK_DefinedSymbolVisibility visibility, LNK_DefinedSymbolFlags flags);
internal void lnk_init_defined_symbol_chunk(LNK_Symbol *symbol, String8 name, LNK_DefinedSymbolVisibility visibility, LNK_DefinedSymbolFlags flags, LNK_Chunk *chunk, U64 offset, COFF_ComdatSelectType selection, U32 check_sum);
internal void lnk_init_defined_symbol_va(LNK_Symbol *symbol, String8 name, LNK_DefinedSymbolVisibility visibility, LNK_DefinedSymbolFlags flags, U64 va);
internal void lnk_init_undefined_symbol(LNK_Symbol *symbol, String8 name, LNK_SymbolScopeFlags scope_flags);
internal void lnk_init_weak_symbol(LNK_Symbol *symbol, String8 name, COFF_WeakExtType lookup, LNK_Symbol *fallback);
internal LNK_Symbol * lnk_make_defined_symbol(Arena *arena, String8 name, LNK_DefinedSymbolVisibility visibility, LNK_DefinedSymbolFlags flags);
internal LNK_Symbol * lnk_make_defined_symbol_chunk(Arena *arena, String8 name, LNK_DefinedSymbolVisibility visibility, LNK_DefinedSymbolFlags flags, LNK_Chunk *chunk, U64 offset, COFF_ComdatSelectType selection, U32 check_sum);
internal LNK_Symbol * lnk_make_defined_symbol_va(Arena *arena, String8 name, LNK_DefinedSymbolVisibility visibility, LNK_DefinedSymbolFlags flags, U64 va);
internal LNK_Symbol * lnk_make_undefined_symbol(Arena *arena, String8 name, LNK_SymbolScopeFlags scope_flags);
internal LNK_Symbol * lnk_make_weak_symbol(Arena *arena, String8 name, COFF_WeakExtType lookup, LNK_Symbol *fallback);
internal LNK_Symbol * lnk_make_lazy_symbol(Arena *arena, String8 name, struct LNK_Lib *lib, U64 member_offset);
internal LNK_Chunk * lnk_chunk_from_symbol(LNK_Symbol *symbol);
////////////////////////////////
internal void lnk_symbol_list_push_node(LNK_SymbolList *list, LNK_SymbolNode *node);
internal LNK_SymbolNode * lnk_symbol_list_push(Arena *arena, LNK_SymbolList *list, LNK_Symbol *symbol);
internal void lnk_symbol_list_concat_in_place(LNK_SymbolList *list, LNK_SymbolList *to_concat);
internal LNK_SymbolList lnk_symbol_list_from_array(Arena *arena, LNK_SymbolArray arr);
internal LNK_SymbolNodeArray lnk_symbol_node_array_from_list(Arena *arena, LNK_SymbolList list);
internal LNK_SymbolArray lnk_symbol_array_from_list(Arena *arena, LNK_SymbolList list);
////////////////////////////////
internal void lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunk_list, LNK_SymbolHashTrie **trie, U64 hash, LNK_Symbol *new_symbol);
internal LNK_SymbolHashTrie * lnk_symbol_hash_trie_search(LNK_SymbolHashTrie *trie, U64 hash, String8 name);
internal void lnk_symbol_hash_trie_remove(LNK_SymbolHashTrie *trie);
////////////////////////////////
internal U64 lnk_symbol_hash(String8 string);
internal LNK_SymbolTable * lnk_symbol_table_init(TP_Arena *arena);
internal LNK_Symbol * lnk_symbol_table_search_hash(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope, U64 hash, String8 name);
internal LNK_Symbol * lnk_symbol_table_search(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope, String8 name);
internal LNK_Symbol * lnk_symbol_table_searchf(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope, char *fmt, ...);
internal void lnk_symbol_table_push_hash(LNK_SymbolTable *symtab, U64 hash, LNK_Symbol *symbol);
internal void lnk_symbol_table_push(LNK_SymbolTable *symtab, LNK_Symbol *symbol);
internal void lnk_symbol_table_remove(LNK_SymbolTable *symtab, LNK_SymbolScopeIndex scope, String8 name);
internal LNK_Symbol * lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_Symbol *resolve_symbol);