kern: put rela in bss

NOTE: This saves ~0x4000 of space at the cost of crimes against the linker script.
This commit is contained in:
Michael Scire 2021-10-08 12:29:53 -07:00
parent fba962ef11
commit 960ba52a43
4 changed files with 25 additions and 19 deletions

View file

@ -9,7 +9,6 @@ def align_up(val, algn):
val += algn - 1 val += algn - 1
return val - (val % algn) return val - (val % algn)
def main(argc, argv): def main(argc, argv):
if argc != 4: if argc != 4:
print('Usage: %s kernel_ldr.bin kernel.bin output.bin' % argv[0]) print('Usage: %s kernel_ldr.bin kernel.bin output.bin' % argv[0])
@ -21,8 +20,15 @@ def main(argc, argv):
kernel_metadata_offset = 4 kernel_metadata_offset = 4
assert (kernel_metadata_offset <= len(kernel) - 0x40) assert (kernel_metadata_offset <= len(kernel) - 0x40)
assert (kernel[kernel_metadata_offset:kernel_metadata_offset + 4] == b'MSS0') assert (kernel[kernel_metadata_offset:kernel_metadata_offset + 4] == b'MSS0')
kernel_end = up('<I', kernel[kernel_metadata_offset + 0x38:kernel_metadata_offset + 0x3C])[0]
assert (kernel_end >= len(kernel)) bss_start, bss_end, kernel_end = up('<III', kernel[kernel_metadata_offset + 0x30:kernel_metadata_offset + 0x3C])
assert (bss_end >= 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'' embedded_ini = b''
try: try:

View file

@ -102,7 +102,7 @@ DEPENDS := $(OFILES:.o=.d)
# main targets # main targets
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
$(OUTPUT).bin : $(OUTPUT).elf $(OUTPUT).bin : $(OUTPUT).elf
$(OBJCOPY) -S -O binary --set-section-flags .bss=alloc,load,contents $< $@ $(OBJCOPY) -S -O binary $< $@
@echo built ... $(notdir $@) @echo built ... $(notdir $@)
$(OUTPUT).elf : $(OFILES) $(OUTPUT).elf : $(OFILES)

View file

@ -113,9 +113,6 @@ SECTIONS
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata
.dynamic : { *(.dynamic) } :rodata :dyn .dynamic : { *(.dynamic) } :rodata :dyn
.dynsym : { *(.dynsym) } :rodata
.dynstr : { *(.dynstr) } :rodata
.rela.dyn : { *(.rela.*) } :rodata
.hash : { *(.hash) } :rodata .hash : { *(.hash) } :rodata
.gnu.hash : { *(.gnu.hash) } :rodata .gnu.hash : { *(.gnu.hash) } :rodata
.gnu.version : { *(.gnu.version) } :rodata .gnu.version : { *(.gnu.version) } :rodata
@ -152,18 +149,19 @@ SECTIONS
{ {
*(.data .data.* .gnu.linkonce.d.*) *(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS) SORT(CONSTRUCTORS)
. = ALIGN(8);
} :data } :data
__bss_start__ = .; __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__ = .; __bss_end__ = .;
@ -174,7 +172,7 @@ SECTIONS
================== */ ================== */
/* Discard sections that difficult post-processing */ /* 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. */ /* Stabs debugging sections. */
.stab 0 : { *(.stab) } .stab 0 : { *(.stab) }

View file

@ -207,13 +207,15 @@ namespace ams::kern::init::loader {
/* NOTE: Nintendo does this only on 10.0.0+ */ /* NOTE: Nintendo does this only on 10.0.0+ */
init_pt.PhysicallyRandomize(virtual_base_address + rx_offset, bss_end_offset - rx_offset, true); 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. */ /* Apply relocations to the kernel. */
const Elf::Dyn *kernel_dynamic = reinterpret_cast<const Elf::Dyn *>(GetInteger(virtual_base_address) + dynamic_offset); const Elf::Dyn *kernel_dynamic = reinterpret_cast<const Elf::Dyn *>(GetInteger(virtual_base_address) + dynamic_offset);
Elf::ApplyRelocations(GetInteger(virtual_base_address), kernel_dynamic); 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. */ /* Call the kernel's init array functions. */
/* NOTE: The kernel does this after reprotecting .rodata, but we do it before. */ /* 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. */ /* This allows our global constructors to edit .rodata, which is valuable for editing the SVC tables to support older firmwares' ABIs. */