mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: faster & safer hash function
Uses AES hardware instructions on 386/amd64 to implement a fast hash function. Incorporates a random key to thwart hash collision DOS attacks. Depends on CL#7548043 for new assembly instructions. Update #3885 Helps some by making hashing faster. Go time drops from 0.65s to 0.51s. R=rsc, r, bradfitz, remyoudompheng, khr, dsymonds, minux.ma, elias.naur CC=golang-dev https://golang.org/cl/7543043
This commit is contained in:
parent
4e032ce301
commit
a5d4024139
23 changed files with 891 additions and 8 deletions
|
|
@ -467,6 +467,41 @@ runtime·algarray[] =
|
|||
|
||||
// Runtime helpers.
|
||||
|
||||
// used in asm_{386,amd64}.s
|
||||
byte runtime·aeskeysched[HashRandomBytes];
|
||||
|
||||
void
|
||||
runtime·hashinit(void)
|
||||
{
|
||||
// Install aes hash algorithm if we have the instructions we need
|
||||
if((runtime·cpuid_ecx & (1 << 25)) != 0 && // aes (aesenc)
|
||||
(runtime·cpuid_ecx & (1 << 9)) != 0 && // sse3 (pshufb)
|
||||
(runtime·cpuid_ecx & (1 << 19)) != 0) { // sse4.1 (pinsr{d,q})
|
||||
byte *rnd;
|
||||
int32 n;
|
||||
runtime·algarray[AMEM].hash = runtime·aeshash;
|
||||
runtime·algarray[AMEM8].hash = runtime·aeshash;
|
||||
runtime·algarray[AMEM16].hash = runtime·aeshash;
|
||||
runtime·algarray[AMEM32].hash = runtime·aeshash32;
|
||||
runtime·algarray[AMEM64].hash = runtime·aeshash64;
|
||||
runtime·algarray[AMEM128].hash = runtime·aeshash;
|
||||
runtime·algarray[ASTRING].hash = runtime·aeshashstr;
|
||||
|
||||
// Initialize with random data so hash collisions will be hard to engineer.
|
||||
runtime·get_random_data(&rnd, &n);
|
||||
if(n > HashRandomBytes)
|
||||
n = HashRandomBytes;
|
||||
runtime·memmove(runtime·aeskeysched, rnd, n);
|
||||
if(n < HashRandomBytes) {
|
||||
// Not very random, but better than nothing.
|
||||
int64 t = runtime·nanotime();
|
||||
while (n < HashRandomBytes) {
|
||||
runtime·aeskeysched[n++] = (int8)(t >> (8 * (n % 8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// func equal(t *Type, x T, y T) (ret bool)
|
||||
#pragma textflag 7
|
||||
void
|
||||
|
|
|
|||
|
|
@ -20,6 +20,17 @@ TEXT _rt0_386(SB),7,$0
|
|||
MOVL BX, g_stackguard(BP)
|
||||
MOVL SP, g_stackbase(BP)
|
||||
|
||||
// find out information about the processor we're on
|
||||
MOVL $0, AX
|
||||
CPUID
|
||||
CMPL AX, $0
|
||||
JE nocpuinfo
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
MOVL CX, runtime·cpuid_ecx(SB)
|
||||
MOVL DX, runtime·cpuid_edx(SB)
|
||||
nocpuinfo:
|
||||
|
||||
// if there is an _cgo_init, call it to let it
|
||||
// initialize and to set up GS. if not,
|
||||
// we set up GS ourselves.
|
||||
|
|
@ -71,6 +82,7 @@ ok:
|
|||
MOVL AX, 4(SP)
|
||||
CALL runtime·args(SB)
|
||||
CALL runtime·osinit(SB)
|
||||
CALL runtime·hashinit(SB)
|
||||
CALL runtime·schedinit(SB)
|
||||
|
||||
// create a new goroutine to start program
|
||||
|
|
@ -709,3 +721,261 @@ TEXT runtime·stackguard(SB),7,$0
|
|||
RET
|
||||
|
||||
GLOBL runtime·tls0(SB), $32
|
||||
|
||||
// hash function using AES hardware instructions
|
||||
TEXT runtime·aeshash(SB),7,$0
|
||||
MOVL 4(SP), DX // ptr to hash value
|
||||
MOVL 8(SP), CX // size
|
||||
MOVL 12(SP), AX // ptr to data
|
||||
JMP runtime·aeshashbody(SB)
|
||||
|
||||
TEXT runtime·aeshashstr(SB),7,$0
|
||||
MOVL 4(SP), DX // ptr to hash value
|
||||
MOVL 12(SP), AX // ptr to string struct
|
||||
MOVL 4(AX), CX // length of string
|
||||
MOVL (AX), AX // string data
|
||||
JMP runtime·aeshashbody(SB)
|
||||
|
||||
// AX: data
|
||||
// CX: length
|
||||
// DX: ptr to seed input / hash output
|
||||
TEXT runtime·aeshashbody(SB),7,$0
|
||||
MOVL (DX), X0 // seed to low 32 bits of xmm0
|
||||
PINSRD $1, CX, X0 // size to next 32 bits of xmm0
|
||||
MOVOU runtime·aeskeysched+0(SB), X2
|
||||
MOVOU runtime·aeskeysched+16(SB), X3
|
||||
aesloop:
|
||||
CMPL CX, $16
|
||||
JB aesloopend
|
||||
MOVOU (AX), X1
|
||||
AESENC X2, X0
|
||||
AESENC X1, X0
|
||||
SUBL $16, CX
|
||||
ADDL $16, AX
|
||||
JMP aesloop
|
||||
aesloopend:
|
||||
TESTL CX, CX
|
||||
JE finalize // no partial block
|
||||
|
||||
TESTL $16, AX
|
||||
JNE highpartial
|
||||
|
||||
// address ends in 0xxxx. 16 bytes loaded
|
||||
// at this address won't cross a page boundary, so
|
||||
// we can load it directly.
|
||||
MOVOU (AX), X1
|
||||
ADDL CX, CX
|
||||
PAND masks(SB)(CX*8), X1
|
||||
JMP partial
|
||||
highpartial:
|
||||
// address ends in 1xxxx. Might be up against
|
||||
// a page boundary, so load ending at last byte.
|
||||
// Then shift bytes down using pshufb.
|
||||
MOVOU -16(AX)(CX*1), X1
|
||||
ADDL CX, CX
|
||||
PSHUFB shifts(SB)(CX*8), X1
|
||||
partial:
|
||||
// incorporate partial block into hash
|
||||
AESENC X3, X0
|
||||
AESENC X1, X0
|
||||
finalize:
|
||||
// finalize hash
|
||||
AESENC X2, X0
|
||||
AESENC X3, X0
|
||||
AESENC X2, X0
|
||||
MOVL X0, (DX)
|
||||
RET
|
||||
|
||||
TEXT runtime·aeshash32(SB),7,$0
|
||||
MOVL 4(SP), DX // ptr to hash value
|
||||
MOVL 12(SP), AX // ptr to data
|
||||
MOVL (DX), X0 // seed
|
||||
PINSRD $1, (AX), X0 // data
|
||||
MOVOU runtime·aeskeysched+0(SB), X2
|
||||
MOVOU runtime·aeskeysched+16(SB), X3
|
||||
AESENC X2, X0
|
||||
AESENC X3, X0
|
||||
AESENC X2, X0
|
||||
MOVL X0, (DX)
|
||||
RET
|
||||
|
||||
TEXT runtime·aeshash64(SB),7,$0
|
||||
MOVL 4(SP), DX // ptr to hash value
|
||||
MOVL 12(SP), AX // ptr to data
|
||||
MOVQ (AX), X0 // data
|
||||
PINSRD $2, (DX), X0 // seed
|
||||
MOVOU runtime·aeskeysched+0(SB), X2
|
||||
MOVOU runtime·aeskeysched+16(SB), X3
|
||||
AESENC X2, X0
|
||||
AESENC X3, X0
|
||||
AESENC X2, X0
|
||||
MOVL X0, (DX)
|
||||
RET
|
||||
|
||||
|
||||
// simple mask to get rid of data in the high part of the register.
|
||||
TEXT masks(SB),7,$0
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0x000000ff
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0x0000ffff
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0x00ffffff
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0x000000ff
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0x0000ffff
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0x00ffffff
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0x000000ff
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0x0000ffff
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0x00ffffff
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0x000000ff
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0x0000ffff
|
||||
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0x00ffffff
|
||||
|
||||
// these are arguments to pshufb. They move data down from
|
||||
// the high bytes of the register to the low bytes of the register.
|
||||
// index is how many bytes to move.
|
||||
TEXT shifts(SB),7,$0
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
LONG $0x00000000
|
||||
|
||||
LONG $0xffffff0f
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0xffff0f0e
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0xff0f0e0d
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x0f0e0d0c
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x0e0d0c0b
|
||||
LONG $0xffffff0f
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x0d0c0b0a
|
||||
LONG $0xffff0f0e
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x0c0b0a09
|
||||
LONG $0xff0f0e0d
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x0b0a0908
|
||||
LONG $0x0f0e0d0c
|
||||
LONG $0xffffffff
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x0a090807
|
||||
LONG $0x0e0d0c0b
|
||||
LONG $0xffffff0f
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x09080706
|
||||
LONG $0x0d0c0b0a
|
||||
LONG $0xffff0f0e
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x08070605
|
||||
LONG $0x0c0b0a09
|
||||
LONG $0xff0f0e0d
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x07060504
|
||||
LONG $0x0b0a0908
|
||||
LONG $0x0f0e0d0c
|
||||
LONG $0xffffffff
|
||||
|
||||
LONG $0x06050403
|
||||
LONG $0x0a090807
|
||||
LONG $0x0e0d0c0b
|
||||
LONG $0xffffff0f
|
||||
|
||||
LONG $0x05040302
|
||||
LONG $0x09080706
|
||||
LONG $0x0d0c0b0a
|
||||
LONG $0xffff0f0e
|
||||
|
||||
LONG $0x04030201
|
||||
LONG $0x08070605
|
||||
LONG $0x0c0b0a09
|
||||
LONG $0xff0f0e0d
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,17 @@ TEXT _rt0_amd64(SB),7,$-8
|
|||
MOVQ BX, g_stackguard(DI)
|
||||
MOVQ SP, g_stackbase(DI)
|
||||
|
||||
// find out information about the processor we're on
|
||||
MOVQ $0, AX
|
||||
CPUID
|
||||
CMPQ AX, $0
|
||||
JE nocpuinfo
|
||||
MOVQ $1, AX
|
||||
CPUID
|
||||
MOVL CX, runtime·cpuid_ecx(SB)
|
||||
MOVL DX, runtime·cpuid_edx(SB)
|
||||
nocpuinfo:
|
||||
|
||||
// if there is an _cgo_init, call it.
|
||||
MOVQ _cgo_init(SB), AX
|
||||
TESTQ AX, AX
|
||||
|
|
@ -65,6 +76,7 @@ ok:
|
|||
MOVQ AX, 8(SP)
|
||||
CALL runtime·args(SB)
|
||||
CALL runtime·osinit(SB)
|
||||
CALL runtime·hashinit(SB)
|
||||
CALL runtime·schedinit(SB)
|
||||
|
||||
// create a new goroutine to start program
|
||||
|
|
@ -729,3 +741,165 @@ TEXT runtime·stackguard(SB),7,$0
|
|||
RET
|
||||
|
||||
GLOBL runtime·tls0(SB), $64
|
||||
|
||||
// hash function using AES hardware instructions
|
||||
TEXT runtime·aeshash(SB),7,$0
|
||||
MOVQ 8(SP), DX // ptr to hash value
|
||||
MOVQ 16(SP), CX // size
|
||||
MOVQ 24(SP), AX // ptr to data
|
||||
JMP runtime·aeshashbody(SB)
|
||||
|
||||
TEXT runtime·aeshashstr(SB),7,$0
|
||||
MOVQ 8(SP), DX // ptr to hash value
|
||||
MOVQ 24(SP), AX // ptr to string struct
|
||||
MOVQ 8(AX), CX // length of string
|
||||
MOVQ (AX), AX // string data
|
||||
JMP runtime·aeshashbody(SB)
|
||||
|
||||
// AX: data
|
||||
// CX: length
|
||||
// DX: ptr to seed input / hash output
|
||||
TEXT runtime·aeshashbody(SB),7,$0
|
||||
MOVQ (DX), X0 // seed to low 64 bits of xmm0
|
||||
PINSRQ $1, CX, X0 // size to high 64 bits of xmm0
|
||||
MOVOU runtime·aeskeysched+0(SB), X2
|
||||
MOVOU runtime·aeskeysched+16(SB), X3
|
||||
aesloop:
|
||||
CMPQ CX, $16
|
||||
JB aesloopend
|
||||
MOVOU (AX), X1
|
||||
AESENC X2, X0
|
||||
AESENC X1, X0
|
||||
SUBQ $16, CX
|
||||
ADDQ $16, AX
|
||||
JMP aesloop
|
||||
aesloopend:
|
||||
TESTQ CX, CX
|
||||
JE finalize // no partial block
|
||||
|
||||
TESTQ $16, AX
|
||||
JNE highpartial
|
||||
|
||||
// address ends in 0xxxx. 16 bytes loaded
|
||||
// at this address won't cross a page boundary, so
|
||||
// we can load it directly.
|
||||
MOVOU (AX), X1
|
||||
ADDQ CX, CX
|
||||
PAND masks(SB)(CX*8), X1
|
||||
JMP partial
|
||||
highpartial:
|
||||
// address ends in 1xxxx. Might be up against
|
||||
// a page boundary, so load ending at last byte.
|
||||
// Then shift bytes down using pshufb.
|
||||
MOVOU -16(AX)(CX*1), X1
|
||||
ADDQ CX, CX
|
||||
PSHUFB shifts(SB)(CX*8), X1
|
||||
partial:
|
||||
// incorporate partial block into hash
|
||||
AESENC X3, X0
|
||||
AESENC X1, X0
|
||||
finalize:
|
||||
// finalize hash
|
||||
AESENC X2, X0
|
||||
AESENC X3, X0
|
||||
AESENC X2, X0
|
||||
MOVQ X0, (DX)
|
||||
RET
|
||||
|
||||
TEXT runtime·aeshash32(SB),7,$0
|
||||
MOVQ 8(SP), DX // ptr to hash value
|
||||
MOVQ 24(SP), AX // ptr to data
|
||||
MOVQ (DX), X0 // seed
|
||||
PINSRD $2, (AX), X0 // data
|
||||
MOVOU runtime·aeskeysched+0(SB), X2
|
||||
MOVOU runtime·aeskeysched+16(SB), X3
|
||||
AESENC X2, X0
|
||||
AESENC X3, X0
|
||||
AESENC X2, X0
|
||||
MOVQ X0, (DX)
|
||||
RET
|
||||
|
||||
TEXT runtime·aeshash64(SB),7,$0
|
||||
MOVQ 8(SP), DX // ptr to hash value
|
||||
MOVQ 24(SP), AX // ptr to data
|
||||
MOVQ (DX), X0 // seed
|
||||
PINSRQ $1, (AX), X0 // data
|
||||
MOVOU runtime·aeskeysched+0(SB), X2
|
||||
MOVOU runtime·aeskeysched+16(SB), X3
|
||||
AESENC X2, X0
|
||||
AESENC X3, X0
|
||||
AESENC X2, X0
|
||||
MOVQ X0, (DX)
|
||||
RET
|
||||
|
||||
// simple mask to get rid of data in the high part of the register.
|
||||
TEXT masks(SB),7,$0
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0x00000000000000ff
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0x000000000000ffff
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0x0000000000ffffff
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0x00000000ffffffff
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0x000000ffffffffff
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0x0000ffffffffffff
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0x00ffffffffffffff
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x00000000000000ff
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x000000000000ffff
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x0000000000ffffff
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x00000000ffffffff
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x000000ffffffffff
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x0000ffffffffffff
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x00ffffffffffffff
|
||||
|
||||
// these are arguments to pshufb. They move data down from
|
||||
// the high bytes of the register to the low bytes of the register.
|
||||
// index is how many bytes to move.
|
||||
TEXT shifts(SB),7,$0
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0x0000000000000000
|
||||
QUAD $0xffffffffffffff0f
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0xffffffffffff0f0e
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0xffffffffff0f0e0d
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0xffffffff0f0e0d0c
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0xffffff0f0e0d0c0b
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0xffff0f0e0d0c0b0a
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0xff0f0e0d0c0b0a09
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x0f0e0d0c0b0a0908
|
||||
QUAD $0xffffffffffffffff
|
||||
QUAD $0x0e0d0c0b0a090807
|
||||
QUAD $0xffffffffffffff0f
|
||||
QUAD $0x0d0c0b0a09080706
|
||||
QUAD $0xffffffffffff0f0e
|
||||
QUAD $0x0c0b0a0908070605
|
||||
QUAD $0xffffffffff0f0e0d
|
||||
QUAD $0x0b0a090807060504
|
||||
QUAD $0xffffffff0f0e0d0c
|
||||
QUAD $0x0a09080706050403
|
||||
QUAD $0xffffff0f0e0d0c0b
|
||||
QUAD $0x0908070605040302
|
||||
QUAD $0xffff0f0e0d0c0b0a
|
||||
QUAD $0x0807060504030201
|
||||
QUAD $0xff0f0e0d0c0b0a09
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ TEXT _rt0_arm(SB),7,$-4
|
|||
MOVW R1, 8(R13)
|
||||
BL runtime·args(SB)
|
||||
BL runtime·osinit(SB)
|
||||
BL runtime·hashinit(SB)
|
||||
BL runtime·schedinit(SB)
|
||||
|
||||
// create a new goroutine to start program
|
||||
|
|
@ -489,3 +490,17 @@ TEXT runtime·stackguard(SB),7,$0
|
|||
MOVW R1, sp+0(FP)
|
||||
MOVW R2, limit+4(FP)
|
||||
RET
|
||||
|
||||
// not implemented for ARM
|
||||
TEXT runtime·aeshash(SB),7,$-4
|
||||
MOVW $0, R0
|
||||
MOVW (R0), R1
|
||||
TEXT runtime·aeshash32(SB),7,$-4
|
||||
MOVW $0, R0
|
||||
MOVW (R0), R1
|
||||
TEXT runtime·aeshash64(SB),7,$-4
|
||||
MOVW $0, R0
|
||||
MOVW (R0), R1
|
||||
TEXT runtime·aeshashstr(SB),7,$-4
|
||||
MOVW $0, R0
|
||||
MOVW (R0), R1
|
||||
|
|
|
|||
96
src/pkg/runtime/mapspeed_test.go
Normal file
96
src/pkg/runtime/mapspeed_test.go
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const size = 10
|
||||
|
||||
func BenchmarkHashStringSpeed(b *testing.B) {
|
||||
strings := make([]string, size)
|
||||
for i := 0; i < size; i++ {
|
||||
strings[i] = fmt.Sprintf("string#%d", i)
|
||||
}
|
||||
sum := 0
|
||||
m := make(map[string]int, size)
|
||||
for i := 0; i < size; i++ {
|
||||
m[strings[i]] = 0
|
||||
}
|
||||
idx := 0
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sum += m[strings[idx]]
|
||||
idx++
|
||||
if idx == size {
|
||||
idx = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHashInt32Speed(b *testing.B) {
|
||||
ints := make([]int32, size)
|
||||
for i := 0; i < size; i++ {
|
||||
ints[i] = int32(i)
|
||||
}
|
||||
sum := 0
|
||||
m := make(map[int32]int, size)
|
||||
for i := 0; i < size; i++ {
|
||||
m[ints[i]] = 0
|
||||
}
|
||||
idx := 0
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sum += m[ints[idx]]
|
||||
idx++
|
||||
if idx == size {
|
||||
idx = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHashInt64Speed(b *testing.B) {
|
||||
ints := make([]int64, size)
|
||||
for i := 0; i < size; i++ {
|
||||
ints[i] = int64(i)
|
||||
}
|
||||
sum := 0
|
||||
m := make(map[int64]int, size)
|
||||
for i := 0; i < size; i++ {
|
||||
m[ints[i]] = 0
|
||||
}
|
||||
idx := 0
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sum += m[ints[idx]]
|
||||
idx++
|
||||
if idx == size {
|
||||
idx = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
func BenchmarkHashStringArraySpeed(b *testing.B) {
|
||||
stringpairs := make([][2]string, size)
|
||||
for i := 0; i < size; i++ {
|
||||
for j := 0; j < 2; j++ {
|
||||
stringpairs[i][j] = fmt.Sprintf("string#%d/%d", i, j)
|
||||
}
|
||||
}
|
||||
sum := 0
|
||||
m := make(map[[2]string]int, size)
|
||||
for i := 0; i < size; i++ {
|
||||
m[stringpairs[i]] = 0
|
||||
}
|
||||
idx := 0
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sum += m[stringpairs[idx]]
|
||||
idx++
|
||||
if idx == size {
|
||||
idx = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -75,6 +75,11 @@ runtime·args(int32 c, uint8 **v)
|
|||
int32 runtime·isplan9;
|
||||
int32 runtime·iswindows;
|
||||
|
||||
// Information about what cpu features are available.
|
||||
// Set on startup in asm_{x86/amd64}.s.
|
||||
uint32 runtime·cpuid_ecx;
|
||||
uint32 runtime·cpuid_edx;
|
||||
|
||||
void
|
||||
runtime·goargs(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -558,11 +558,25 @@ struct Alg
|
|||
|
||||
extern Alg runtime·algarray[Amax];
|
||||
|
||||
byte* runtime·startup_random_data;
|
||||
uint32 runtime·startup_random_data_len;
|
||||
void runtime·get_random_data(byte**, int32*);
|
||||
|
||||
enum {
|
||||
// hashinit wants this many random bytes
|
||||
HashRandomBytes = 32
|
||||
};
|
||||
void runtime·hashinit(void);
|
||||
|
||||
void runtime·memhash(uintptr*, uintptr, void*);
|
||||
void runtime·nohash(uintptr*, uintptr, void*);
|
||||
void runtime·strhash(uintptr*, uintptr, void*);
|
||||
void runtime·interhash(uintptr*, uintptr, void*);
|
||||
void runtime·nilinterhash(uintptr*, uintptr, void*);
|
||||
void runtime·aeshash(uintptr*, uintptr, void*);
|
||||
void runtime·aeshash32(uintptr*, uintptr, void*);
|
||||
void runtime·aeshash64(uintptr*, uintptr, void*);
|
||||
void runtime·aeshashstr(uintptr*, uintptr, void*);
|
||||
|
||||
void runtime·memequal(bool*, uintptr, void*, void*);
|
||||
void runtime·noequal(bool*, uintptr, void*, void*);
|
||||
|
|
@ -581,7 +595,6 @@ void runtime·memcopy16(uintptr, void*, void*);
|
|||
void runtime·memcopy32(uintptr, void*, void*);
|
||||
void runtime·memcopy64(uintptr, void*, void*);
|
||||
void runtime·memcopy128(uintptr, void*, void*);
|
||||
void runtime·memcopy(uintptr, void*, void*);
|
||||
void runtime·strcopy(uintptr, void*, void*);
|
||||
void runtime·algslicecopy(uintptr, void*, void*);
|
||||
void runtime·intercopy(uintptr, void*, void*);
|
||||
|
|
@ -638,6 +651,8 @@ extern bool runtime·iscgo;
|
|||
extern void (*runtime·sysargs)(int32, uint8**);
|
||||
extern uint32 runtime·maxstring;
|
||||
extern uint32 runtime·Hchansize;
|
||||
extern uint32 runtime·cpuid_ecx;
|
||||
extern uint32 runtime·cpuid_edx;
|
||||
|
||||
/*
|
||||
* common functions and data
|
||||
|
|
@ -684,7 +699,10 @@ int32 runtime·gotraceback(void);
|
|||
void runtime·goroutineheader(G*);
|
||||
void runtime·traceback(uint8 *pc, uint8 *sp, uint8 *lr, G* gp);
|
||||
void runtime·tracebackothers(G*);
|
||||
int32 runtime·open(int8*, int32, int32);
|
||||
int32 runtime·read(int32, void*, int32);
|
||||
int32 runtime·write(int32, void*, int32);
|
||||
int32 runtime·close(int32);
|
||||
int32 runtime·mincore(void*, uintptr, byte*);
|
||||
bool runtime·cas(uint32*, uint32, uint32);
|
||||
bool runtime·cas64(uint64*, uint64*, uint64);
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
|
|||
}
|
||||
|
||||
#define AT_NULL 0
|
||||
#define AT_RANDOM 25
|
||||
#define AT_SYSINFO 32
|
||||
extern uint32 runtime·_vdso;
|
||||
|
||||
|
|
@ -168,7 +169,12 @@ runtime·linux_setup_vdso(int32 argc, byte **argv)
|
|||
for(auxv=(uint32*)envp; auxv[0] != AT_NULL; auxv += 2) {
|
||||
if(auxv[0] == AT_SYSINFO) {
|
||||
runtime·_vdso = auxv[1];
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if(auxv[0] == AT_RANDOM) {
|
||||
runtime·startup_random_data = (byte*)auxv[1];
|
||||
runtime·startup_random_data_len = 16;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,21 @@ TEXT runtime·exit1(SB),7,$0
|
|||
MOVL $0xf1, 0xf1 // crash
|
||||
RET
|
||||
|
||||
TEXT runtime·open(SB),7,$0
|
||||
MOVL $5, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·close(SB),7,$0
|
||||
MOVL $6, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·read(SB),7,$0
|
||||
MOVL $3, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$0
|
||||
MOVL $4, AX
|
||||
INT $0x80
|
||||
|
|
|
|||
|
|
@ -30,6 +30,28 @@ TEXT runtime·exit1(SB),7,$0
|
|||
MOVL $0xf1, 0xf1 // crash
|
||||
RET
|
||||
|
||||
TEXT runtime·open(SB),7,$0
|
||||
MOVQ 8(SP), DI // arg 1 pathname
|
||||
MOVL 16(SP), SI // arg 2 flags
|
||||
MOVL 20(SP), DX // arg 3 mode
|
||||
MOVL $(0x2000000+5), AX // syscall entry
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·close(SB),7,$0
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVL $(0x2000000+6), AX // syscall entry
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·read(SB),7,$0
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVQ 16(SP), SI // arg 2 buf
|
||||
MOVL 24(SP), DX // arg 3 count
|
||||
MOVL $(0x2000000+3), AX // syscall entry
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$0
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVQ 16(SP), SI // arg 2 buf
|
||||
|
|
|
|||
|
|
@ -56,6 +56,21 @@ TEXT runtime·exit1(SB),7,$-4
|
|||
MOVL $0xf1, 0xf1 // crash
|
||||
RET
|
||||
|
||||
TEXT runtime·open(SB),7,$-4
|
||||
MOVL $5, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·close(SB),7,$-4
|
||||
MOVL $6, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·read(SB),7,$-4
|
||||
MOVL $3, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$-4
|
||||
MOVL $4, AX
|
||||
INT $0x80
|
||||
|
|
|
|||
|
|
@ -58,6 +58,28 @@ TEXT runtime·exit1(SB),7,$-8
|
|||
MOVL $0xf1, 0xf1 // crash
|
||||
RET
|
||||
|
||||
TEXT runtime·open(SB),7,$-8
|
||||
MOVQ 8(SP), DI // arg 1 pathname
|
||||
MOVL 16(SP), SI // arg 2 flags
|
||||
MOVL 20(SP), DX // arg 3 mode
|
||||
MOVL $5, AX
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·close(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVL $6, AX
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·read(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVQ 16(SP), SI // arg 2 buf
|
||||
MOVL 24(SP), DX // arg 3 count
|
||||
MOVL $3, AX
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVQ 16(SP), SI // arg 2 buf
|
||||
|
|
|
|||
|
|
@ -22,6 +22,21 @@ TEXT runtime·exit1(SB),7,$-4
|
|||
MOVL $0xf1, 0xf1 // crash
|
||||
RET
|
||||
|
||||
TEXT runtime·open(SB),7,$-4
|
||||
MOVL $5, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·close(SB),7,$-4
|
||||
MOVL $6, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·read(SB),7,$-4
|
||||
MOVL $3, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$-4
|
||||
MOVL $4, AX // sys_write
|
||||
INT $0x80
|
||||
|
|
|
|||
|
|
@ -79,6 +79,28 @@ TEXT runtime·exit1(SB),7,$-8
|
|||
MOVL $0xf1, 0xf1 // crash
|
||||
RET
|
||||
|
||||
TEXT runtime·open(SB),7,$-8
|
||||
MOVQ 8(SP), DI // arg 1 pathname
|
||||
MOVL 16(SP), SI // arg 2 flags
|
||||
MOVL 20(SP), DX // arg 3 mode
|
||||
MOVL $5, AX
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·close(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVL $6, AX
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·read(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVQ 16(SP), SI // arg 2 buf
|
||||
MOVL 24(SP), DX // arg 3 count
|
||||
MOVL $3, AX
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 - fd
|
||||
MOVQ 16(SP), SI // arg 2 - buf
|
||||
|
|
|
|||
|
|
@ -24,6 +24,21 @@ TEXT runtime·exit1(SB),7,$8
|
|||
MOVL $0xf1, 0xf1 // crash
|
||||
RET
|
||||
|
||||
TEXT runtime·open(SB),7,$-4
|
||||
MOVL $5, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·close(SB),7,$-4
|
||||
MOVL $6, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·read(SB),7,$-4
|
||||
MOVL $3, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$-4
|
||||
MOVL $4, AX // sys_write
|
||||
INT $0x80
|
||||
|
|
|
|||
|
|
@ -87,6 +87,28 @@ TEXT runtime·exit1(SB),7,$-8
|
|||
MOVL $0xf1, 0xf1 // crash
|
||||
RET
|
||||
|
||||
TEXT runtime·open(SB),7,$-8
|
||||
MOVQ 8(SP), DI // arg 1 pathname
|
||||
MOVL 16(SP), SI // arg 2 flags
|
||||
MOVL 20(SP), DX // arg 3 mode
|
||||
MOVL $5, AX
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·close(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVL $6, AX
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·read(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 fd
|
||||
MOVQ 16(SP), SI // arg 2 buf
|
||||
MOVL 24(SP), DX // arg 3 count
|
||||
MOVL $3, AX
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 - fd
|
||||
MOVQ 16(SP), SI // arg 2 - buf
|
||||
|
|
|
|||
|
|
@ -68,6 +68,22 @@ runtime·osinit(void)
|
|||
runtime·ncpu = out;
|
||||
}
|
||||
|
||||
void
|
||||
runtime·get_random_data(byte **rnd, int32 *rnd_len)
|
||||
{
|
||||
static byte urandom_data[HashRandomBytes];
|
||||
int32 fd;
|
||||
fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
|
||||
if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
|
||||
*rnd = urandom_data;
|
||||
*rnd_len = HashRandomBytes;
|
||||
} else {
|
||||
*rnd = nil;
|
||||
*rnd_len = 0;
|
||||
}
|
||||
runtime·close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·goenvs(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -115,6 +115,22 @@ runtime·osinit(void)
|
|||
runtime·ncpu = getncpu();
|
||||
}
|
||||
|
||||
void
|
||||
runtime·get_random_data(byte **rnd, int32 *rnd_len)
|
||||
{
|
||||
static byte urandom_data[HashRandomBytes];
|
||||
int32 fd;
|
||||
fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
|
||||
if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
|
||||
*rnd = urandom_data;
|
||||
*rnd_len = HashRandomBytes;
|
||||
} else {
|
||||
*rnd = nil;
|
||||
*rnd_len = 0;
|
||||
}
|
||||
runtime·close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·goenvs(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@
|
|||
|
||||
extern SigTab runtime·sigtab[];
|
||||
|
||||
int32 runtime·open(uint8*, int32, int32);
|
||||
int32 runtime·close(int32);
|
||||
int32 runtime·read(int32, void*, int32);
|
||||
|
||||
static Sigset sigset_none;
|
||||
static Sigset sigset_all = { ~(uint32)0, ~(uint32)0 };
|
||||
|
||||
|
|
@ -164,6 +160,32 @@ runtime·osinit(void)
|
|||
runtime·ncpu = getproccount();
|
||||
}
|
||||
|
||||
// Random bytes initialized at startup. These come
|
||||
// from the ELF AT_RANDOM auxiliary vector (vdso_linux_amd64.c).
|
||||
byte* runtime·startup_random_data;
|
||||
uint32 runtime·startup_random_data_len;
|
||||
|
||||
void
|
||||
runtime·get_random_data(byte **rnd, int32 *rnd_len)
|
||||
{
|
||||
if(runtime·startup_random_data != nil) {
|
||||
*rnd = runtime·startup_random_data;
|
||||
*rnd_len = runtime·startup_random_data_len;
|
||||
} else {
|
||||
static byte urandom_data[HashRandomBytes];
|
||||
int32 fd;
|
||||
fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
|
||||
if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
|
||||
*rnd = urandom_data;
|
||||
*rnd_len = HashRandomBytes;
|
||||
} else {
|
||||
*rnd = nil;
|
||||
*rnd_len = 0;
|
||||
}
|
||||
runtime·close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
runtime·goenvs(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -180,6 +180,22 @@ runtime·osinit(void)
|
|||
runtime·ncpu = getncpu();
|
||||
}
|
||||
|
||||
void
|
||||
runtime·get_random_data(byte **rnd, int32 *rnd_len)
|
||||
{
|
||||
static byte urandom_data[HashRandomBytes];
|
||||
int32 fd;
|
||||
fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
|
||||
if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
|
||||
*rnd = urandom_data;
|
||||
*rnd_len = HashRandomBytes;
|
||||
} else {
|
||||
*rnd = nil;
|
||||
*rnd_len = 0;
|
||||
}
|
||||
runtime·close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·goenvs(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -159,6 +159,22 @@ runtime·osinit(void)
|
|||
runtime·ncpu = getncpu();
|
||||
}
|
||||
|
||||
void
|
||||
runtime·get_random_data(byte **rnd, int32 *rnd_len)
|
||||
{
|
||||
static byte urandom_data[HashRandomBytes];
|
||||
int32 fd;
|
||||
fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
|
||||
if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
|
||||
*rnd = urandom_data;
|
||||
*rnd_len = HashRandomBytes;
|
||||
} else {
|
||||
*rnd = nil;
|
||||
*rnd_len = 0;
|
||||
}
|
||||
runtime·close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·goenvs(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@
|
|||
#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
|
||||
#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
|
||||
#pragma dynimport runtime·CreateWaitableTimer CreateWaitableTimerA "kernel32.dll"
|
||||
#pragma dynimport runtime·CryptAcquireContextW CryptAcquireContextW "advapi32.dll"
|
||||
#pragma dynimport runtime·CryptGenRandom CryptGenRandom "advapi32.dll"
|
||||
#pragma dynimport runtime·CryptReleaseContext CryptReleaseContext "advapi32.dll"
|
||||
#pragma dynimport runtime·DuplicateHandle DuplicateHandle "kernel32.dll"
|
||||
#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
|
||||
#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
|
||||
|
|
@ -39,6 +42,9 @@ extern void *runtime·CloseHandle;
|
|||
extern void *runtime·CreateEvent;
|
||||
extern void *runtime·CreateThread;
|
||||
extern void *runtime·CreateWaitableTimer;
|
||||
extern void *runtime·CryptAcquireContextW;
|
||||
extern void *runtime·CryptGenRandom;
|
||||
extern void *runtime·CryptReleaseContext;
|
||||
extern void *runtime·DuplicateHandle;
|
||||
extern void *runtime·ExitProcess;
|
||||
extern void *runtime·FreeEnvironmentStringsW;
|
||||
|
|
@ -81,6 +87,24 @@ runtime·osinit(void)
|
|||
runtime·ncpu = getproccount();
|
||||
}
|
||||
|
||||
void
|
||||
runtime·get_random_data(byte **rnd, int32 *rnd_len)
|
||||
{
|
||||
uintptr handle;
|
||||
*rnd = nil;
|
||||
*rnd_len = 0;
|
||||
if(runtime·stdcall(runtime·CryptAcquireContextW, 5, &handle, nil, nil,
|
||||
(uintptr)1 /* PROV_RSA_FULL */,
|
||||
(uintptr)0xf0000000U /* CRYPT_VERIFYCONTEXT */) != 0) {
|
||||
static byte random_data[HashRandomBytes];
|
||||
if(runtime·stdcall(runtime·CryptGenRandom, 3, handle, (uintptr)HashRandomBytes, random_data)) {
|
||||
*rnd = random_data;
|
||||
*rnd_len = HashRandomBytes;
|
||||
}
|
||||
runtime·stdcall(runtime·CryptReleaseContext, 2, handle, (uintptr)0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
runtime·goenvs(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "runtime.h"
|
||||
|
||||
#define AT_RANDOM 25
|
||||
#define AT_SYSINFO_EHDR 33
|
||||
#define AT_NULL 0 /* End of vector */
|
||||
#define PT_LOAD 1 /* Loadable program segment */
|
||||
|
|
@ -319,11 +320,16 @@ runtime·linux_setup_vdso(int32 argc, uint8** argv)
|
|||
if(elf_auxv[i].a_type == AT_SYSINFO_EHDR) {
|
||||
if(elf_auxv[i].a_un.a_val == 0) {
|
||||
// Something went wrong
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
vdso_init_from_sysinfo_ehdr(&vdso_info, (Elf64_Ehdr*)elf_auxv[i].a_un.a_val);
|
||||
vdso_parse_symbols(&vdso_info, vdso_find_version(&vdso_info, &linux26));
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if(elf_auxv[i].a_type == AT_RANDOM) {
|
||||
runtime·startup_random_data = (byte*)elf_auxv[i].a_un.a_val;
|
||||
runtime·startup_random_data_len = 16;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue