From 960ba52a43d1118913a2cfd46ce48cd86aa44551 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 8 Oct 2021 12:29:53 -0700 Subject: [PATCH] kern: put rela in bss NOTE: This saves ~0x4000 of space at the cost of crimes against the linker script. --- mesosphere/build_mesosphere.py | 12 +++++++--- mesosphere/kernel/Makefile | 2 +- mesosphere/kernel/kernel.ld | 22 +++++++++---------- .../kernel_ldr/source/kern_init_loader.cpp | 8 ++++--- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/mesosphere/build_mesosphere.py b/mesosphere/build_mesosphere.py index ed85e3282..be51da4f0 100644 --- a/mesosphere/build_mesosphere.py +++ b/mesosphere/build_mesosphere.py @@ -9,7 +9,6 @@ def align_up(val, algn): val += algn - 1 return val - (val % algn) - def main(argc, argv): if argc != 4: print('Usage: %s kernel_ldr.bin kernel.bin output.bin' % argv[0]) @@ -21,8 +20,15 @@ def main(argc, argv): kernel_metadata_offset = 4 assert (kernel_metadata_offset <= len(kernel) - 0x40) assert (kernel[kernel_metadata_offset:kernel_metadata_offset + 4] == b'MSS0') - kernel_end = up('= len(kernel)) + + bss_start, bss_end, kernel_end = up('= bss_start) + assert (bss_end == kernel_end) + + assert (len(kernel) <= kernel_end) + if len(kernel) < kernel_end: + kernel += b'\x00' * (kernel_end - len(kernel)) + assert (kernel_end == len(kernel)) embedded_ini = b'' try: diff --git a/mesosphere/kernel/Makefile b/mesosphere/kernel/Makefile index d5e3deb68..b73a399b9 100644 --- a/mesosphere/kernel/Makefile +++ b/mesosphere/kernel/Makefile @@ -102,7 +102,7 @@ DEPENDS := $(OFILES:.o=.d) # main targets #--------------------------------------------------------------------------------- $(OUTPUT).bin : $(OUTPUT).elf - $(OBJCOPY) -S -O binary --set-section-flags .bss=alloc,load,contents $< $@ + $(OBJCOPY) -S -O binary $< $@ @echo built ... $(notdir $@) $(OUTPUT).elf : $(OFILES) diff --git a/mesosphere/kernel/kernel.ld b/mesosphere/kernel/kernel.ld index 739fed35e..efbc1c1e9 100644 --- a/mesosphere/kernel/kernel.ld +++ b/mesosphere/kernel/kernel.ld @@ -113,9 +113,6 @@ SECTIONS .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata .dynamic : { *(.dynamic) } :rodata :dyn - .dynsym : { *(.dynsym) } :rodata - .dynstr : { *(.dynstr) } :rodata - .rela.dyn : { *(.rela.*) } :rodata .hash : { *(.hash) } :rodata .gnu.hash : { *(.gnu.hash) } :rodata .gnu.version : { *(.gnu.version) } :rodata @@ -152,18 +149,19 @@ SECTIONS { *(.data .data.* .gnu.linkonce.d.*) SORT(CONSTRUCTORS) + . = ALIGN(8); } :data __bss_start__ = .; - .bss ALIGN(8) : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(8); - } : data - . = ALIGN(0x1000); + .rela.dyn : { *(.rela.*) } :data + + .bss ADDR(.rela.dyn) (NOLOAD) : { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(0x1000); + } __bss_end__ = .; @@ -174,7 +172,7 @@ SECTIONS ================== */ /* Discard sections that difficult post-processing */ - /DISCARD/ : { *(.group .comment .note .interp .fini_array .fini_array.* .text._ZSt23__cmpexch_failure_orderSt12memory_order) } + /DISCARD/ : { *(.group .comment .note .interp .fini_array .fini_array.* .dynsym .dynstr) } /* Stabs debugging sections. */ .stab 0 : { *(.stab) } diff --git a/mesosphere/kernel_ldr/source/kern_init_loader.cpp b/mesosphere/kernel_ldr/source/kern_init_loader.cpp index ad75f04eb..24c21a363 100644 --- a/mesosphere/kernel_ldr/source/kern_init_loader.cpp +++ b/mesosphere/kernel_ldr/source/kern_init_loader.cpp @@ -207,13 +207,15 @@ namespace ams::kern::init::loader { /* NOTE: Nintendo does this only on 10.0.0+ */ init_pt.PhysicallyRandomize(virtual_base_address + rx_offset, bss_end_offset - rx_offset, true); - /* Clear kernel .bss. */ - std::memset(GetVoidPointer(virtual_base_address + bss_offset), 0, bss_end_offset - bss_offset); - /* Apply relocations to the kernel. */ const Elf::Dyn *kernel_dynamic = reinterpret_cast(GetInteger(virtual_base_address) + dynamic_offset); Elf::ApplyRelocations(GetInteger(virtual_base_address), kernel_dynamic); + /* Clear kernel .bss. */ + /* NOTE: The kernel does this before applying relocations, but we do it after. */ + /* This allows us to place our relocations in space overlapping with .bss...and thereby reclaim the memory that would otherwise be wasted. */ + std::memset(GetVoidPointer(virtual_base_address + bss_offset), 0, bss_end_offset - bss_offset); + /* Call the kernel's init array functions. */ /* NOTE: The kernel does this after reprotecting .rodata, but we do it before. */ /* This allows our global constructors to edit .rodata, which is valuable for editing the SVC tables to support older firmwares' ABIs. */