dynamic_arm64.mx raw

   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  }
  79