mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
The rt0_64 code reserves space for _rt0_redirect_table using the output from the redirect tool's "count" command as a hint to the size of the table. The table itself is located in the .goredirectstbl section which the linker moves to a dedicated section in the final ELF image. When the kernel boots, the _rt0_install_redirect_trampolines function iterates the _rt0_redirect_table entries (populated as a post-link step) and overwrite the original function code with a trampoline that redirects control to the destination function. The trampoline is implemented as a 14-byte instruction that exploits rip-relative addressing to ensure that no registers are made dirty. The actual trampoline code looks like this: jmp [rip+0] ; 6-bytes dq abs_address_to_jump_to ; 8-bytes The _rt0_install_redirect_trampolines function sets up the abs_address to "dst" for each (src, dst) tuple and then copies the trampoline to "src". After the trampoline is installed, any calls to "src" will be transparently redirected to "dst". This hack (modifying code in the .text section) is only possible because the code runs in supervisor mode before memory protection is enabled.
53 lines
1.0 KiB
Plaintext
53 lines
1.0 KiB
Plaintext
VMA = PAGE_OFFSET + LOAD_ADDRESS;
|
|
|
|
ENTRY(_rt0_32_entry)
|
|
|
|
SECTIONS {
|
|
/* Set the kernel VMA at PAGE_OFFSET + 1M
|
|
* but load it at physical address 1M */
|
|
. = VMA;
|
|
|
|
_kernel_start = .;
|
|
|
|
.text BLOCK(4K) : AT(ADDR(.text) - PAGE_OFFSET)
|
|
{
|
|
/* The multiboot header must be present in the first 4K of the kernel
|
|
* image so that the bootloader can find it */
|
|
*(.multiboot_header)
|
|
|
|
*(.rt0)
|
|
|
|
*(.text)
|
|
}
|
|
|
|
/* Read-only data. */
|
|
.rodata ALIGN(4K) : AT(ADDR(.rodata) - PAGE_OFFSET)
|
|
{
|
|
*(.rodata)
|
|
}
|
|
|
|
/* Read-write data (initialized) */
|
|
.data ALIGN(4K) : AT(ADDR(.data) - PAGE_OFFSET)
|
|
{
|
|
*(.data)
|
|
}
|
|
|
|
/* Read-write data (zeroed) */
|
|
.bss ALIGN(4K) : AT(ADDR(.bss) - PAGE_OFFSET)
|
|
{
|
|
*(COMMON)
|
|
*(.bss)
|
|
}
|
|
|
|
/* Go function redirection table. This table is used for hooking
|
|
* Go runtime function symbols so that calls to them are redirected to
|
|
* functions provided by the kernel.
|
|
*/
|
|
.goredirectstbl ALIGN(4K): AT(ADDR(.goredirectstbl) - PAGE_OFFSET)
|
|
{
|
|
*(.goredirectstbl)
|
|
}
|
|
|
|
_kernel_end = ALIGN(4K);
|
|
}
|