gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

loader.go (1926B)


      1 //go:build darwin || linux
      2 // +build darwin linux
      3 
      4 /*
      5  * Copyright 2021 ByteDance Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *     http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  */
     19 
     20 package loader
     21 
     22 import (
     23     `fmt`
     24     `os`
     25     `reflect`
     26     `syscall`
     27     `unsafe`
     28 )
     29 
     30 const (
     31     _AP = syscall.MAP_ANON  | syscall.MAP_PRIVATE
     32     _RX = syscall.PROT_READ | syscall.PROT_EXEC
     33     _RW = syscall.PROT_READ | syscall.PROT_WRITE
     34 )
     35 
     36 type Loader   []byte
     37 type Function unsafe.Pointer
     38 
     39 func (self Loader) Load(fn string, fp int, args int, argPtrs []bool, localPtrs []bool) (f Function) {
     40     p := os.Getpagesize()
     41     n := (((len(self) - 1) / p) + 1) * p
     42 
     43     /* register the function */
     44     m := mmap(n)
     45     v := fmt.Sprintf("runtime.__%s_%x", fn, m)
     46     
     47     registerFunction(v, m, uintptr(n), fp, args, uintptr(len(self)), argPtrs, localPtrs)
     48 
     49     /* reference as a slice */
     50     s := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader {
     51         Data : m,
     52         Cap  : n,
     53         Len  : len(self),
     54     }))
     55 
     56     /* copy the machine code, and make it executable */
     57     copy(s, self)
     58     mprotect(m, n)
     59     return Function(&m)
     60 }
     61 
     62 func mmap(nb int) uintptr {
     63     if m, _, e := syscall.RawSyscall6(syscall.SYS_MMAP, 0, uintptr(nb), _RW, _AP, 0, 0); e != 0 {
     64         panic(e)
     65     } else {
     66         return m
     67     }
     68 }
     69 
     70 func mprotect(p uintptr, nb int) {
     71     if _, _, err := syscall.RawSyscall(syscall.SYS_MPROTECT, p, uintptr(nb), _RX); err != 0 {
     72         panic(err)
     73     }
     74 }