rand/rand-x86ish.S: Establish GOT pointer before making an i386 PLT call.
[catacomb] / rand / rand-x86ish.S
1 /// -*- mode: asm; asm-comment-char: ?/ -*-
2 ///
3 /// Random-number support for x86
4 ///
5 /// (c) 2019 Straylight/Edgeware
6 ///
7
8 ///----- Licensing notice ---------------------------------------------------
9 ///
10 /// This file is part of Catacomb.
11 ///
12 /// Catacomb is free software: you can redistribute it and/or modify it
13 /// under the terms of the GNU Library General Public License as published
14 /// by the Free Software Foundation; either version 2 of the License, or
15 /// (at your option) any later version.
16 ///
17 /// Catacomb is distributed in the hope that it will be useful, but
18 /// WITHOUT ANY WARRANTY; without even the implied warranty of
19 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 /// Library General Public License for more details.
21 ///
22 /// You should have received a copy of the GNU Library General Public
23 /// License along with Catacomb. If not, write to the Free Software
24 /// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 /// USA.
26
27 ///--------------------------------------------------------------------------
28 /// Preliminaries.
29
30 #include "config.h"
31 #include "asm-common.h"
32
33 .extern F(rand_add)
34
35 .text
36
37 ///--------------------------------------------------------------------------
38 /// Quick random generation.
39
40 // Common register allocation.
41 #if CPUFAM_X86
42 # define COUNT ecx
43 #endif
44 #if CPUFAM_AMD64 && ABI_SYSV
45 # define COUNT ecx
46 #endif
47 #if CPUFAM_AMD64 && ABI_WIN
48 # define COUNT r8d
49 #endif
50
51 FUNC(rand_quick_x86ish_rdrand)
52 // Enter with a pointer to the random context in the first argument.
53 // Return zero on success, or -1 on error.
54
55 #if CPUFAM_X86
56 mov edx, [SP + 4]
57 push ebx
58 stalloc 24
59 #endif
60 #if CPUFAM_AMD64 && ABI_SYSV
61 stalloc 8
62 #endif
63 #if CPUFAM_AMD64 && ABI_WIN
64 stalloc 40
65 #endif
66 endprologue
67
68 // Try to fetch a random number.
69 mov COUNT, 16
70 0: rdrand AX
71 jc 1f
72 dec COUNT
73 jnz 0b
74
75 // Failed.
76 mov eax, -1
77 jmp 9f
78 ENDFUNC
79
80 FUNC(rand_quick_x86ish_rdseed)
81 // Enter with a pointer to the random context in the first argument.
82 // Return zero on success, or -1 on error.
83
84 #if CPUFAM_X86
85 mov edx, [SP + 4]
86 push ebx
87 stalloc 24
88 #endif
89 #if CPUFAM_AMD64 && ABI_SYSV
90 stalloc 8
91 #endif
92 #if CPUFAM_AMD64 && ABI_WIN
93 stalloc 40
94 #endif
95 endprologue
96
97 // Try to fetch a random number.
98 mov COUNT, 16
99 0: rdseed AX
100 jc 1f
101 dec COUNT
102 jnz 0b
103
104 // Failed.
105 mov eax, -1
106 jmp 9f
107
108 // Success.
109 1:
110 #if CPUFAM_X86
111 ldgot ebx
112 mov [SP + 16], AX
113 lea ecx, [SP + 16]
114 mov dword ptr [SP + 12], 32
115 mov dword ptr [SP + 8], 4
116 mov [SP + 4], ecx
117 mov [SP + 0], edx
118 #endif
119 #if CPUFAM_AMD64 && ABI_SYSV
120 mov [SP + 0], AX
121 mov rsi, SP
122 mov edx, 8
123 mov ecx, 64
124 #endif
125 #if CPUFAM_AMD64 && ABI_WIN
126 mov [SP + 32], AX
127 lea rdx, [SP + 32]
128 mov r8d, 8
129 mov r9d, 64
130 #endif
131 callext F(rand_add)
132 xor eax, eax
133
134 // Done.
135 9:
136 #if CPUFAM_X86
137 stfree 24
138 pop ebx
139 #endif
140 #if CPUFAM_AMD64 && ABI_SYSV
141 stfree 8
142 #endif
143 #if CPUFAM_AMD64 && ABI_WIN
144 stfree 40
145 #endif
146 ret
147 ENDFUNC
148
149 #undef COUNT
150
151 ///----- That's all, folks --------------------------------------------------