mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
kern: put rela in bss (EXPERIMENTAL)
NOTE: This does some really gross things. It saves ~0x4000 of space, but at the cost of crimes against the linker script. We should consider/evaluate whether this is worth doing for real.
This commit is contained in:
parent
fba962ef11
commit
cfc54dbc88
3 changed files with 46 additions and 17 deletions
|
@ -9,6 +9,22 @@ def align_up(val, algn):
|
||||||
val += algn - 1
|
val += algn - 1
|
||||||
return val - (val % algn)
|
return val - (val % algn)
|
||||||
|
|
||||||
|
def find_rela(kernel, dynamic):
|
||||||
|
rela_offset, rela_size = (None, None)
|
||||||
|
while True:
|
||||||
|
dyn_type, dyn_val = up('<QQ', kernel[dynamic:dynamic+0x10])
|
||||||
|
if dyn_type == 0:
|
||||||
|
break
|
||||||
|
elif dyn_type == 7:
|
||||||
|
assert (rela_offset is None)
|
||||||
|
rela_offset = dyn_val
|
||||||
|
elif dyn_type == 8:
|
||||||
|
assert (rela_size is None)
|
||||||
|
rela_size = dyn_val
|
||||||
|
dynamic += 0x10
|
||||||
|
assert (rela_offset is not None)
|
||||||
|
assert (rela_size is not None)
|
||||||
|
return (rela_offset, rela_size)
|
||||||
|
|
||||||
def main(argc, argv):
|
def main(argc, argv):
|
||||||
if argc != 4:
|
if argc != 4:
|
||||||
|
@ -21,8 +37,19 @@ 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]
|
bss_start, bss_end, kernel_end, dynamic = up('<IIII', kernel[kernel_metadata_offset + 0x30:kernel_metadata_offset + 0x40])
|
||||||
assert (kernel_end >= len(kernel))
|
assert (bss_end >= bss_start)
|
||||||
|
bss_size = bss_end - bss_start
|
||||||
|
assert (bss_end == kernel_end)
|
||||||
|
assert (kernel_end <= len(kernel))
|
||||||
|
|
||||||
|
rela_offset, rela_size = find_rela(kernel, dynamic)
|
||||||
|
assert (rela_size == len(kernel) - kernel_end)
|
||||||
|
assert (bss_start <= rela_offset and rela_offset + rela_size <= bss_end)
|
||||||
|
assert (kernel[bss_start:bss_end] == (b'\x00'* bss_size))
|
||||||
|
|
||||||
|
kernel = kernel[:rela_offset] + kernel[bss_end:] + (b'\x00' * (bss_size - (rela_size + (rela_offset - bss_start))))
|
||||||
|
assert (kernel_end == len(kernel))
|
||||||
|
|
||||||
embedded_ini = b''
|
embedded_ini = b''
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -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,21 @@ 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);
|
OVERLAY : NOCROSSREFS {
|
||||||
|
.bss {
|
||||||
|
*(.dynbss)
|
||||||
|
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
}
|
||||||
|
.rela.dyn { *(.rela.*) }
|
||||||
|
} :data
|
||||||
|
|
||||||
|
|
||||||
__bss_end__ = .;
|
__bss_end__ = .;
|
||||||
|
|
||||||
|
@ -174,7 +174,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) }
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
Loading…
Reference in a new issue