PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
symbol.h
Go to the documentation of this file.
1#pragma once
2
3#include <kernel/utils/map.h>
4
5#include <boot/boot_info.h>
6
7#include <sys/elf.h>
8#include <sys/list.h>
9
10/**
11 * @brief Kernel Symbol Resolution and Management.
12 * @defgroup kernel_module_symbol Kernel Symbols
13 * @ingroup kernel_module
14 *
15 * ## What are Symbols?
16 *
17 * All binary files are made up of "symbols", a name associated with an address in the binary, which includes the
18 * kernel. These symbols are usually stored in the binary file of whatever binary we are dealing with, usually the only
19 * purpose of these symbols is linking and debugging.
20 *
21 * ## Runtime Symbol Resolution
22 *
23 * We can take advantage of these symbols to resolve symbol names to addresses ("kmain" -> 0xXXXXXXXX) and addresses to
24 * symbol names (0xXXXXXXXX -> "kmain") at runtime. This is not only massively useful for debugging and logging, but
25 * vital for implementing kernel modules, as the kernel effectively acts as a "runtime linker" for the kernel module
26 * binaries, resolving any kernel symbols (which are stored in the module binary by its name since it cant know the
27 * address beforehand) to their actual addresses in the kernel so that the module can call into the kernel and of course
28 * vice versa. We can also use this to resolve symbols between modules.
29 *
30 * In the end we have a large structure of all currently loaded symbols in the kernel or modules, and we can search this
31 * structure by name or by address.
32 *
33 * ## The Structure
34 *
35 * The kernel stores symbols using three main structures, which when combined form a slightly over optimized way to
36 * retrieve symbols by name or address and to easily remove symbols when a module is unloaded.
37 *
38 * The structures are:
39 * - A id-keyed map of symbol groups (`symbol_group_t`), used to group symbols for easy removal later.
40 * - A name-keyed map of symbol names (`symbol_name_t`), used to resolve names to addresses.
41 * - An addr-sorted array of symbol addresses (`symbol_addr_t`), used to resolve addresses to names using binary search.
42 *
43 * These structures form a kind of circular graph, where from a group we can retrieve the names, from the names we can
44 * retrieve the addresses and from the addresses we can retrieve the group again. Its also possible to go from a address
45 * to its name using the `CONTAINER_OF` macro.
46 *
47 * Note that we cant use a map for the addresses as we need to be able to find non-exact matches when resolving an
48 * address. If a address inside a function is provided we still want to be able to resolve it to the function name, this
49 * is done by finding the closest symbol with an address less than or equal to the provided address.
50 *
51 * @{
52 */
53
54/**
55 * @brief Maximum length of a symbol name.
56 */
57#define SYMBOL_MAX_NAME MAP_KEY_MAX_LENGTH
58
59/**
60 * @brief Symbol group identifier type.
61 * @typedef symbol_group_id_t
62 *
63 * Used to easily group symbols for removal later, mostly used by modules to remove all their symbols when unloaded.
64 *
65 * A value of `0` indicates that its part of the kernel and not a module.
66 */
68
69/**
70 * @brief Symbol group structure.
71 * @typedef symbol_group_t
72 *
73 * Stored in a id-keyed map.
74 */
81
82/**
83 * @brief Symbol name mapping structure.
84 * @struct symbol_name_t
85 *
86 * Stored in a name-keyed map for name to address resolution.
87 */
95
96/**
97 * @brief Symbol address mapping structure.
98 * @struct symbol_addr_t
99 *
100 * Stored in a addr-sorted array for address to name resolution using binary search and in the relevant
101 * `symbol_name_t`'s address list for name to address resolution.
102 */
112
113/**
114 * @brief Symbol information structure.
115 * @struct symbol_info_t
116 *
117 * Used to return symbol information from resolution functions.
118 */
127
128/**
129 * @brief Generate a unique symbol group identifier.
130 *
131 * All identifiers are generated sequentially.
132 *
133 * @return The symbol group identifier.
134 */
136
137/**
138 * @brief Add a symbol to the kernel symbol table.
139 *
140 * Symbols of binding `STB_GLOBAL` must have unique names but can have duplicated addresses, symbols of other bindings
141 * can be duplicated in name, address or both.
142 *
143 * If the symbol is not of type `STT_OBJECT` or `STT_FUNC` the function is a no-op and returns success.
144 *
145 * @param name The name of the symbol.
146 * @param addr The address of the symbol.
147 * @param groupId The group identifier of the symbol.
148 * @param binding The binding of the symbol, specifies visibility and linkage.
149 * @param type The type of the symbol, specifies what the symbol represents.
150 * @return On success, `0`. On failure, `ERR` and `errno` is set.
151 */
152uint64_t symbol_add(const char* name, void* addr, symbol_group_id_t groupId, Elf64_Symbol_Binding binding,
153 Elf64_Symbol_Type type);
154
155/**
156 * @brief Remove all symbols from the kernel symbol table in the given group.
157 *
158 * @param groupId The group identifier of the symbols to remove.
159 */
161
162/**
163 * @brief Resolve a symbol by address.
164 *
165 * The resolved symbol is the closest symbol with an address less than or equal to the given address. The
166 * `outSymbol->addr` will be the address of the symbol, not the given address.
167 *
168 * If multiple symbols exist at the same address, one of them will be returned, but which one is undefined. Dont rely on
169 * this behaviour being predictable.
170 *
171 * @param outSymbol Output pointer to store the resolved symbol information.
172 * @param addr The address of the symbol to resolve.
173 * @return On success, `0`. On failure, `ERR` and `errno` is set.
174 */
175uint64_t symbol_resolve_addr(symbol_info_t* outSymbol, void* addr);
176
177/**
178 * @brief Resolve a symbol by name.
179 *
180 * @param outSymbol Output pointer to store the resolved symbol information.
181 * @param name The name of the symbol to resolve.
182 * @return On success, `0`. On failure, `ERR` and `errno` is set.
183 */
184uint64_t symbol_resolve_name(symbol_info_t* outSymbol, const char* name);
185
186/** @} */
uint64_t symbol_resolve_name(symbol_info_t *outSymbol, const char *name)
Resolve a symbol by name.
Definition symbol.c:352
uint64_t symbol_group_id_t
Symbol group identifier type.
Definition symbol.h:67
uint64_t symbol_resolve_addr(symbol_info_t *outSymbol, void *addr)
Resolve a symbol by address.
Definition symbol.c:346
uint64_t symbol_add(const char *name, void *addr, symbol_group_id_t groupId, Elf64_Symbol_Binding binding, Elf64_Symbol_Type type)
Add a symbol to the kernel symbol table.
Definition symbol.c:166
#define SYMBOL_MAX_NAME
Maximum length of a symbol name.
Definition symbol.h:57
void symbol_remove_group(symbol_group_id_t groupId)
Remove all symbols from the kernel symbol table in the given group.
Definition symbol.c:279
symbol_group_id_t symbol_generate_group_id(void)
Generate a unique symbol group identifier.
Definition symbol.c:24
Elf64_Symbol_Binding
Symbol binding values stored in st_info.
Definition elf.h:565
Elf64_Symbol_Type
Symbol type values stored in st_info.
Definition elf.h:588
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
A entry in a doubly linked list.
Definition list.h:37
A doubly linked list.
Definition list.h:46
Map entry structure.
Definition map.h:69
Symbol address mapping structure.
Definition symbol.h:104
symbol_name_t * name
Definition symbol.h:106
symbol_group_id_t groupId
Definition symbol.h:108
Elf64_Symbol_Binding binding
Definition symbol.h:109
void * addr
Definition symbol.h:107
Elf64_Symbol_Type type
Definition symbol.h:110
list_entry_t nameEntry
Definition symbol.h:105
list_t names
Definition symbol.h:79
map_entry_t mapEntry
Definition symbol.h:77
symbol_group_id_t id
Definition symbol.h:78
Symbol information structure.
Definition symbol.h:120
void * addr
Definition symbol.h:122
symbol_group_id_t groupId
Definition symbol.h:123
Elf64_Symbol_Binding binding
Definition symbol.h:124
Elf64_Symbol_Type type
Definition symbol.h:125
Symbol name mapping structure.
Definition symbol.h:89
list_entry_t groupEntry
Definition symbol.h:90
list_t addrs
Definition symbol.h:92
map_entry_t mapEntry
Definition symbol.h:91