blob: a9a3956feadecd671e03bea990fc6376549b8103 [file] [log] [blame]
# Copyright Microsoft and CHERIoT Contributors.
# SPDX-License-Identifier: MIT
@mmio@
SECTIONS
{
. = @code_start@;
_start = .;
.loader_start :
{
*(.loader_start);
}
@thread_trusted_stacks@
__stack_space_start = .;
@thread_stacks@
__stack_space_end = .;
.compartment_export_tables : ALIGN(8)
{
# The scheduler and allocator's export tables are at the start.
.scheduler_export_table = .;
*.scheduler.compartment(.compartment_export_table);
.scheduler_export_table_end = .;
.allocator_export_table = ALIGN(8);
*/cheriot.allocator.compartment(.compartment_export_table);
.allocator_export_table_end = .;
@compartment_exports@
}
__compart_pccs = .;
compartment_switcher_code : CAPALIGN
{
.compartment_switcher_start = .;
*/switcher/entry.S.o(.text);
}
.compartment_switcher_end = .;
scheduler_code : CAPALIGN
{
.scheduler_start = .;
*.scheduler.compartment(.compartment_sealing_keys);
.scheduler_import_start = .;
*.scheduler.compartment(.compartment_import_table);
.scheduler_import_end = .;
*.scheduler.compartment(.text .text.* .rodata .rodata.* .data.rel.ro);
}
.scheduler_end = .;
allocator_code : CAPALIGN
{
.allocator_start = .;
*/cheriot.allocator.compartment(.compartment_sealing_keys);
.allocator_import_start = .;
*/cheriot.allocator.compartment(.compartment_import_table);
.allocator_import_end = .;
allocator.compartment(.text .text.* .rodata .rodata.* .data.rel.ro);
*/cheriot.allocator.compartment(.text .text.* .rodata .rodata.* .data.rel.ro);
}
.allocator_end = .;
token_library_code : CAPALIGN
{
.token_library_start = .;
*/cheriot.token_library.library(.compartment_sealing_keys);
.token_library_import_start = .;
*/cheriot.token_library.library(.compartment_import_table);
.token_library_import_end = .;
token_library.library(.text .text.* .rodata .rodata.* .data.rel.ro);
*/cheriot.token_library.library(.text .text.* .rodata .rodata.* .data.rel.ro);
}
.token_library_end = .;
@software_revoker_code@
@pcc_ld@
__compart_pccs_end = .;
__compart_cgps = ALIGN(64);
.scheduler_globals : CAPALIGN
{
.scheduler_globals = .;
*.scheduler.compartment(.data .data.* .sdata .sdata.*);
.scheduler_bss_start = .;
*.scheduler.compartment(.sbss .sbss.* .bss .bss.*)
}
.scheduler_globals_end = .;
.allocator_sealed_objects : CAPALIGN
{
.allocator_sealed_objects = .;
*/cheriot.allocator.compartment(.sealed_objects)
}
.allocator_sealed_objects_end = .;
.allocator_globals : CAPALIGN
{
.allocator_globals = .;
*/cheriot.allocator.compartment(.data .data.* .sdata .sdata.*);
.allocator_bss_start = .;
*/cheriot.allocator.compartment(.sbss .sbss.* .bss .bss.*);
}
.allocator_globals_end = .;
@software_revoker_globals@
@gdc_ld@
__compart_cgps_end = .;
.sealed_objects :
{
@sealed_objects@
}
__shared_objects_start = .;
@shared_objects@
__shared_objects_end = .;
. = ALIGN(64);
# Everything after this point can be discarded after the loader has
# finished.
__export_mem_heap = @heap_start@;
__cap_relocs :
{
__cap_relocs = .;
# FIXME: This currently doesn't do anything. The linker creates this
# entire section. The linker script needs to be modified to create
# separate caprelocs sections for each section.
@cap_relocs@
}
__cap_relocs_end = .;
# Collect all compartment headers
.compartment_headers : ALIGN(4)
{
__compart_headers = .;
# Loader code start
LONG(.loader_code_start);
# Loader code length
SHORT(.loader_code_end - .loader_code_start);
# Loader data start
LONG(.loader_data_start);
# Loader data length
SHORT(.loader_data_end - .loader_data_start);
# Compartment switcher start address
LONG(.compartment_switcher_start);
# Compartment switcher end
SHORT(.compartment_switcher_end - .compartment_switcher_start);
# Cross-compartment call return path
SHORT(switcher_skip_compartment_call - .compartment_switcher_start);
# Compartment switcher sealing key
SHORT(compartment_switcher_sealing_key - .compartment_switcher_start);
# Switcher's copy of the scheduler's PCC.
SHORT(switcher_scheduler_entry_pcc - .compartment_switcher_start);
# Switcher's copy of the scheduler's CGP
SHORT(switcher_scheduler_entry_cgp - .compartment_switcher_start);
# Switcher's copy of the scheduler's CSP
SHORT(switcher_scheduler_entry_csp - .compartment_switcher_start);
# Address of switcher export table
LONG(.switcher_export_table);
# Size of the switcher export table
SHORT(.switcher_export_table_end - .switcher_export_table);
# sdk/core/loader/types.h:/PrivilegedCompartment
# Scheduler code start address
LONG(.scheduler_start);
# Scheduler code end
SHORT(.scheduler_end - .scheduler_start);
# Scheduler globals start address
LONG(.scheduler_globals);
# Scheduler globals end size
SHORT(SIZEOF(.scheduler_globals));
# Start of the scheduler's import table
LONG(.scheduler_import_start);
# Size of the scheduler import table
SHORT(.scheduler_import_end - .scheduler_import_start);
# Address of scheduler export table
LONG(.scheduler_export_table);
# Size of the scheduler export table
SHORT(.scheduler_export_table_end - .scheduler_export_table);
# No sealed objects
LONG(0);
SHORT(0);
# sdk/core/loader/types.h:/PrivilegedCompartment
# Allocator code start address
LONG(.allocator_start);
# Allocator code end
SHORT(.allocator_end - .allocator_start);
# Allocator globals start address
LONG(.allocator_globals);
# Allocator globals end
SHORT(SIZEOF(.allocator_globals));
# Start of the allocator's import table
LONG(.allocator_import_start);
# Size of the allocator import table
SHORT(.allocator_import_end - .allocator_import_start);
# Address of allocator export table
LONG(.allocator_export_table);
# Size of the allocator export table
SHORT(.allocator_export_table_end - .allocator_export_table);
# The allocator may have sealed objects
LONG(.allocator_sealed_objects);
SHORT(SIZEOF(.allocator_sealed_objects));
# sdk/core/loader/types.h:/PrivilegedCompartment
# Token server compartment header
# Code
LONG(.token_library_start);
SHORT(.token_library_end - .token_library_start);
# No data segment
LONG(0);
SHORT(0);
# Start of the token_library's import table
LONG(.token_library_import_start);
# Size of the token server import table
SHORT(.token_library_import_end - .token_library_import_start);
# Address of the token server export table
LONG(.token_library_export_table);
# Size of the token server export table
SHORT(.token_library_export_table_end - .token_library_export_table);
# No sealed objects
LONG(0);
SHORT(0);
@software_revoker_header@
# sdk/core/loader/types.h:/is_magic_valid
# Magic number, used to detect mismatches between linker script and
# loader versions.
# New versions of this can be generated with:
# head /dev/random | shasum | cut -c 0-8
LONG(0xca2b63de);
# Number of library headers.
SHORT(@library_count@);
# Number of compartment headers.
SHORT(@compartment_count@);
@compartment_headers@
}
# Thread configuration. This follows the compartment headers but is in a
# separate section to make auditing easier.
# This section holds a `class ThreadInfo` (loader/types.h)
.thread_config :
{
.thread_config_start = .;
# Number of threads
__thread_count = .;
SHORT(@thread_count@);
# The thread structures
@thread_headers@
__compart_headers_end = .;
}
.loader_code : CAPALIGN
{
.loader_code_start = .;
*/loader/boot.cc.o(.text .text.* .rodata .rodata.* .data.rel.ro);
}
.loader_code_end = .;
.loader_data : CAPALIGN
{
.loader_data_start = .;
*/loader/boot.cc.o(.data .data.* .sdata .sdata.* .sbss .sbss.* .bss .bss.*);
}
.loader_data_end = .;
.library_export_tables : ALIGN(8)
{
.token_library_export_table = ALIGN(8);
*/cheriot.token_library.library(.compartment_export_table);
.token_library_export_table_end = .;
.switcher_export_table = ALIGN(8);
*/switcher/entry.S.o(.compartment_export_table);
.switcher_export_table_end = .;
@library_exports@
}
}
# No symbols should be exported
VERSION {
VERSION_1 {
local: *;
};
};