github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/dynamic_arm64.go (about) 1 package runtime 2 3 import ( 4 "unsafe" 5 ) 6 7 const debugLoader = false 8 9 const ( 10 rAARCH64_RELATIVE = 1027 11 dtNULL = 0 /* Terminating entry. */ 12 dtRELA = 7 /* Address of ElfNN_Rela relocations. */ 13 dtRELASZ = 8 /* Total size of ElfNN_Rela relocations. */ 14 ) 15 16 /* ELF64 relocations that need an addend field. */ 17 type rela64 struct { 18 Off uint64 /* Location to be relocated. */ 19 Info uint64 /* Relocation type and symbol index. */ 20 Addend int64 /* Addend. */ 21 } 22 23 // ELF64 Dynamic structure. The ".dynamic" section contains an array of them. 24 type dyn64 struct { 25 Tag int64 /* Entry type. */ 26 Val uint64 /* Integer/address value */ 27 } 28 29 //export __dynamic_loader 30 func dynamicLoader(base uintptr, dyn *dyn64) { 31 var rela *rela64 32 relasz := uint64(0) 33 34 if debugLoader { 35 println("ASLR Base: ", base) 36 } 37 38 for dyn.Tag != dtNULL { 39 switch dyn.Tag { 40 case dtRELA: 41 rela = (*rela64)(unsafe.Pointer(base + uintptr(dyn.Val))) 42 case dtRELASZ: 43 relasz = uint64(dyn.Val) / uint64(unsafe.Sizeof(rela64{})) 44 } 45 46 ptr := unsafe.Pointer(dyn) 47 ptr = unsafe.Add(ptr, unsafe.Sizeof(dyn64{})) 48 dyn = (*dyn64)(ptr) 49 } 50 51 if rela == nil { 52 runtimePanic("bad reloc") 53 } 54 55 if debugLoader { 56 println("Sections to load: ", relasz) 57 } 58 59 for relasz > 0 && rela != nil { 60 switch rela.Info { 61 case rAARCH64_RELATIVE: 62 if debugLoader { 63 println("relocating ", uintptr(rela.Addend), " to ", base+uintptr(rela.Addend)) 64 } 65 ptr := (*uint64)(unsafe.Pointer(base + uintptr(rela.Off))) 66 *ptr = uint64(base + uintptr(rela.Addend)) 67 default: 68 if debugLoader { 69 println("unknown section to load:", rela.Info) 70 } 71 } 72 73 rptr := unsafe.Pointer(rela) 74 rptr = unsafe.Add(rptr, unsafe.Sizeof(rela64{})) 75 rela = (*rela64)(rptr) 76 relasz-- 77 } 78 }