nintendoswitch: Add dynamic loader for runtime loading PIE sections

This commit is contained in:
Lucas Teske
2020-09-13 21:10:27 -03:00
committed by Ron Evans
parent 490e377bba
commit fb1fc267ab
6 changed files with 148 additions and 35 deletions
+55
View File
@@ -0,0 +1,55 @@
package runtime
import (
"debug/elf"
"unsafe"
)
const debugLoader = false
//export __dynamic_loader
func dynamicLoader(base uintptr, dyn *elf.Dyn64) {
var rela *elf.Rela64
relasz := uint64(0)
if debugLoader {
println("ASLR Base: ", base)
}
for dyn.Tag != int64(elf.DT_NULL) {
switch elf.DynTag(dyn.Tag) {
case elf.DT_RELA:
rela = (*elf.Rela64)(unsafe.Pointer(base + uintptr(dyn.Val)))
case elf.DT_RELASZ:
relasz = uint64(dyn.Val) / uint64(unsafe.Sizeof(elf.Rela64{}))
}
ptr := uintptr(unsafe.Pointer(dyn))
ptr += unsafe.Sizeof(elf.Dyn64{})
dyn = (*elf.Dyn64)(unsafe.Pointer(ptr))
}
if rela == nil {
runtimePanic("bad reloc")
}
if rela == nil {
runtimePanic("bad reloc")
}
if debugLoader {
println("Sections to load: ", relasz)
}
for relasz > 0 && rela != nil {
switch elf.R_AARCH64(rela.Info) {
case elf.R_AARCH64_RELATIVE:
ptr := (*uint64)(unsafe.Pointer(base + uintptr(rela.Off)))
*ptr = uint64(base + uintptr(rela.Addend))
}
rptr := uintptr(unsafe.Pointer(rela))
rptr += unsafe.Sizeof(elf.Rela64{})
rela = (*elf.Rela64)(unsafe.Pointer(rptr))
relasz--
}
}
+12
View File
@@ -2,6 +2,8 @@
package runtime
import "unsafe"
type timeUnit int64
const asyncScheduler = false
@@ -60,6 +62,16 @@ func abort() {
}
}
//export write
func write(fd int32, buf *byte, count int) int {
// TODO: Proper handling write
for i := 0; i < count; i++ {
putchar(*buf)
buf = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(buf)) + 1))
}
return count
}
//export sleepThread
func sleepThread(nanos uint64)