package  runtimeimport  "unsafe" const  (	_AT_SYSINFO_EHDR  = 33 	_PT_LOAD     = 1  	_PT_DYNAMIC  = 2  	_DT_NULL      = 0           	_DT_HASH      = 4           	_DT_STRTAB    = 5           	_DT_SYMTAB    = 6           	_DT_GNU_HASH  = 0x6ffffef5  	_DT_VERSYM    = 0x6ffffff0 	_DT_VERDEF    = 0x6ffffffc 	_VER_FLG_BASE  = 0x1  	_SHN_UNDEF  = 0  	_SHT_DYNSYM  = 11  	_STT_FUNC  = 2  	_STT_NOTYPE  = 0  	_STB_GLOBAL  = 1  	_STB_WEAK    = 2  	_EI_NIDENT  = 16 		vdsoSymTabSize      = vdsoArrayMax  / unsafe .Sizeof (elfSym {})	vdsoDynSize         = vdsoArrayMax  / unsafe .Sizeof (elfDyn {})	vdsoSymStringsSize  = vdsoArrayMax      	vdsoVerSymSize      = vdsoArrayMax  / 2  	vdsoHashSize        = vdsoArrayMax  / 4  		vdsoBloomSizeScale  = unsafe .Sizeof (uintptr (0 )) / 4  )func  _ELF_ST_BIND val  byte ) byte  { return  val  >> 4  }func  _ELF_ST_TYPE val  byte ) byte  { return  val  & 0xf  }type  vdsoSymbolKey  struct  {	name     string 	symHash  uint32 	gnuHash  uint32 	ptr      *uintptr }type  vdsoVersionKey  struct  {	version  string 	verHash  uint32 }type  vdsoInfo  struct  {	valid  bool 		loadAddr    uintptr 	loadOffset  uintptr  		symtab      *[vdsoSymTabSize ]elfSym 	symstrings  *[vdsoSymStringsSize ]byte 	chain       []uint32 	bucket      []uint32 	symOff      uint32 	isGNUHash   bool 		versym  *[vdsoVerSymSize ]uint16 	verdef  *elfVerdef }func  vdsoInitFromSysinfoEhdr info  *vdsoInfo , hdr  *elfEhdr ) {	info .valid  = false 	info .loadAddr  = uintptr (unsafe .Pointer (hdr ))	pt  := unsafe .Pointer (info .loadAddr  + uintptr (hdr .e_phoff ))		var  foundVaddr  bool 	var  dyn  *[vdsoDynSize ]elfDyn 	for  i  := uint16 (0 ); i  < hdr .e_phnum ; i ++ {		pt  := (*elfPhdr )(add (pt , uintptr (i )*unsafe .Sizeof (elfPhdr {})))		switch  pt .p_type  {		case  _PT_LOAD :			if  !foundVaddr  {				foundVaddr  = true 				info .loadOffset  = info .loadAddr  + uintptr (pt .p_offset -pt .p_vaddr )			}		case  _PT_DYNAMIC :			dyn  = (*[vdsoDynSize ]elfDyn )(unsafe .Pointer (info .loadAddr  + uintptr (pt .p_offset )))		}	}	if  !foundVaddr  || dyn  == nil  {		return  	}		var  hash , gnuhash  *[vdsoHashSize ]uint32 	info .symstrings  = nil 	info .symtab  = nil 	info .versym  = nil 	info .verdef  = nil 	for  i  := 0 ; dyn [i ].d_tag  != _DT_NULL ; i ++ {		dt  := &dyn [i ]		p  := info .loadOffset  + uintptr (dt .d_val )		switch  dt .d_tag  {		case  _DT_STRTAB :			info .symstrings  = (*[vdsoSymStringsSize ]byte )(unsafe .Pointer (p ))		case  _DT_SYMTAB :			info .symtab  = (*[vdsoSymTabSize ]elfSym )(unsafe .Pointer (p ))		case  _DT_HASH :			hash  = (*[vdsoHashSize ]uint32 )(unsafe .Pointer (p ))		case  _DT_GNU_HASH :			gnuhash  = (*[vdsoHashSize ]uint32 )(unsafe .Pointer (p ))		case  _DT_VERSYM :			info .versym  = (*[vdsoVerSymSize ]uint16 )(unsafe .Pointer (p ))		case  _DT_VERDEF :			info .verdef  = (*elfVerdef )(unsafe .Pointer (p ))		}	}	if  info .symstrings  == nil  || info .symtab  == nil  || (hash  == nil  && gnuhash  == nil ) {		return  	}	if  info .verdef  == nil  {		info .versym  = nil 	}	if  gnuhash  != nil  {				nbucket  := gnuhash [0 ]		info .symOff  = gnuhash [1 ]		bloomSize  := gnuhash [2 ]		info .bucket  = gnuhash [4 +bloomSize *uint32 (vdsoBloomSizeScale ):][:nbucket ]		info .chain  = gnuhash [4 +bloomSize *uint32 (vdsoBloomSizeScale )+nbucket :]		info .isGNUHash  = true 	} else  {				nbucket  := hash [0 ]		nchain  := hash [1 ]		info .bucket  = hash [2  : 2 +nbucket ]		info .chain  = hash [2 +nbucket  : 2 +nbucket +nchain ]	}		info .valid  = true }func  vdsoFindVersion info  *vdsoInfo , ver  *vdsoVersionKey ) int32  {	if  !info .valid  {		return  0 	}	def  := info .verdef 	for  {		if  def .vd_flags &_VER_FLG_BASE  == 0  {			aux  := (*elfVerdaux )(add (unsafe .Pointer (def ), uintptr (def .vd_aux )))			if  def .vd_hash  == ver .verHash  && ver .version  == gostringnocopy (&info .symstrings [aux .vda_name ]) {				return  int32 (def .vd_ndx  & 0x7fff )			}		}		if  def .vd_next  == 0  {			break 		}		def  = (*elfVerdef )(add (unsafe .Pointer (def ), uintptr (def .vd_next )))	}	return  -1  }func  vdsoParseSymbols info  *vdsoInfo , version  int32 ) {	if  !info .valid  {		return 	}	apply  := func (symIndex  uint32 , k  vdsoSymbolKey ) bool  {		sym  := &info .symtab [symIndex ]		typ  := _ELF_ST_TYPE (sym .st_info )		bind  := _ELF_ST_BIND (sym .st_info )				if  typ  != _STT_FUNC  && typ  != _STT_NOTYPE  || bind  != _STB_GLOBAL  && bind  != _STB_WEAK  || sym .st_shndx  == _SHN_UNDEF  {			return  false 		}		if  k .name  != gostringnocopy (&info .symstrings [sym .st_name ]) {			return  false 		}				if  info .versym  != nil  && version  != 0  && int32 (info .versym [symIndex ]&0x7fff ) != version  {			return  false 		}		*k .ptr  = info .loadOffset  + uintptr (sym .st_value )		return  true 	}	if  !info .isGNUHash  {				for  _ , k  := range  vdsoSymbolKeys  {			if  len (info .bucket ) > 0  {				for  chain  := info .bucket [k .symHash %uint32 (len (info .bucket ))]; chain  != 0 ; chain  = info .chain [chain ] {					if  apply (chain , k ) {						break 					}				}			}		}		return 	}		for  _ , k  := range  vdsoSymbolKeys  {		symIndex  := info .bucket [k .gnuHash %uint32 (len (info .bucket ))]		if  symIndex  < info .symOff  {			continue 		}		for  ; ; symIndex ++ {			hash  := info .chain [symIndex -info .symOff ]			if  hash |1  == k .gnuHash |1  {								if  apply (symIndex , k ) {					break 				}			}			if  hash &1  != 0  {								break 			}		}	}}func  vdsoauxv tag , val  uintptr ) {	switch  tag  {	case  _AT_SYSINFO_EHDR :		if  val  == 0  {						return 		}		var  info  vdsoInfo 				info1  := (*vdsoInfo )(noescape (unsafe .Pointer (&info )))		vdsoInitFromSysinfoEhdr (info1 , (*elfEhdr )(unsafe .Pointer (val )))		vdsoParseSymbols (info1 , vdsoFindVersion (info1 , &vdsoLinuxVersion ))	}}func  inVDSOPage pc  uintptr ) bool  {	for  _ , k  := range  vdsoSymbolKeys  {		if  *k .ptr  != 0  {			page  := *k .ptr  &^ (physPageSize  - 1 )			return  pc  >= page  && pc  < page +physPageSize 		}	}	return  false } The pages are generated with Golds v0.7.6 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .