@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
2
2
3
3
use serde_json:: Value as JsonValue ;
4
4
5
- use crate :: { AbiFromJsonErr , ArmCall , CanonAbi , ExternAbi , InterruptKind } ;
5
+ use crate :: { AbiFromJsonErr , ArmCall , CanonAbi , ExternAbi , InterruptKind , X86Call } ;
6
6
7
7
#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
8
8
pub struct AbiMap {
@@ -15,14 +15,16 @@ pub struct AbiMap {
15
15
/// ABI used for `extern "rust-cold"`
16
16
pub rust_cold : CanonAbi ,
17
17
18
- // optional abstract ABIs
18
+ // optional architecture-specific ABIs, should always answer a certain way per-arch
19
19
pub efiapi : Option < CanonAbi > ,
20
+ pub win64 : Option < CanonAbi > ,
21
+ pub sysv64 : Option < CanonAbi > ,
22
+
23
+ // optional abstract ABIs, these can be very weird
20
24
pub stdcall : Option < CanonAbi > ,
21
25
pub fastcall : Option < CanonAbi > ,
22
26
pub thiscall : Option < CanonAbi > ,
23
27
pub vectorcall : Option < CanonAbi > ,
24
- pub win64 : Option < CanonAbi > ,
25
- pub sysv64 : Option < CanonAbi > ,
26
28
27
29
// optional concrete ABIs
28
30
// arm
@@ -204,6 +206,39 @@ impl AbiMap {
204
206
}
205
207
}
206
208
209
+ // construction
210
+
211
+ impl AbiMap {
212
+ pub fn base_for_arch ( arch : & str ) -> AbiMap {
213
+ match arch {
214
+ "aarch64" => AbiMap { efiapi : Some ( CanonAbi :: C ) , ..Default :: default ( ) } ,
215
+ "amdgpu" => AbiMap { gpu_kernel : true , ..Default :: default ( ) } ,
216
+ "arm" => AbiMap {
217
+ aapcs : true ,
218
+ efiapi : Some ( CanonAbi :: Arm ( ArmCall :: Aapcs ) ) ,
219
+ ..Default :: default ( )
220
+ } ,
221
+ "avr" => AbiMap { avr_interrupt : true , ..Default :: default ( ) } ,
222
+ "msp430" => AbiMap { msp430_interrupt : true , ..Default :: default ( ) } ,
223
+ "nvptx64" => AbiMap { ptx_kernel : true , gpu_kernel : true , ..Default :: default ( ) } ,
224
+ "riscv32" | "riscv64" => {
225
+ AbiMap { efiapi : Some ( CanonAbi :: C ) , riscv_interrupt : true , ..Default :: default ( ) }
226
+ }
227
+ "x86" => {
228
+ AbiMap { efiapi : Some ( CanonAbi :: C ) , x86_interrupt : true , ..Default :: default ( ) }
229
+ }
230
+ "x86_64" => AbiMap {
231
+ efiapi : Some ( CanonAbi :: X86 ( X86Call :: Win64 ) ) ,
232
+ sysv64 : Some ( CanonAbi :: X86 ( X86Call :: SysV64 ) ) ,
233
+ win64 : Some ( CanonAbi :: X86 ( X86Call :: Win64 ) ) ,
234
+ x86_interrupt : true ,
235
+ ..Default :: default ( )
236
+ } ,
237
+ _ => Default :: default ( ) ,
238
+ }
239
+ }
240
+ }
241
+
207
242
// deserialization
208
243
209
244
type JsonObject = serde_json:: Map < String , JsonValue > ;
@@ -241,31 +276,19 @@ fn extract_bool_abi(
241
276
}
242
277
243
278
impl AbiMap {
244
- pub fn from_json_object (
279
+ pub fn from_arch_and_json (
280
+ arch : & str ,
245
281
mut json : JsonObject ,
246
- ) -> Result < Self , BTreeMap < String , AbiFromJsonErr > > {
282
+ ) -> ( Self , BTreeMap < String , AbiFromJsonErr > ) {
247
283
// extract all keys we are interested in
248
284
let required_c_abis =
249
285
[ "C" , "system" , "system-varargs" ] . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
250
286
let rust_cold = extract_abi_str ( & mut json, "rust-cold" ) ;
251
- let bool_abis = [
252
- // arm...
253
- "aapcs" ,
254
- "cmse-nonsecure-entry" ,
255
- // ...gpu...
256
- "gpu-kernel" ,
257
- "ptx-kernel" ,
258
- // ...interrupt
259
- "avr-interrupt" ,
260
- "msp430-interrupt" ,
261
- "riscv-interrupt" ,
262
- "x86-interrupt" ,
263
- ]
264
- . map ( |abi_str| extract_bool_abi ( & mut json, abi_str) ) ;
265
- // x86ish
266
- let optional_abis =
267
- [ "efiapi" , "stdcall" , "fastcall" , "thiscall" , "vectorcall" , "win64" , "sysv64" ]
268
- . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
287
+ let bool_abis =
288
+ [ "aapcs" , "cmse-nonsecure-entry" ] . map ( |abi_str| extract_bool_abi ( & mut json, abi_str) ) ;
289
+ // x86ish optional ABIs
290
+ let optional_abis = [ "stdcall" , "fastcall" , "thiscall" , "vectorcall" ]
291
+ . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
269
292
270
293
// accumulate errors
271
294
// create an iterator of invalid types and bad parses
@@ -283,28 +306,22 @@ impl AbiMap {
283
306
. chain ( errs. cloned ( ) )
284
307
. collect :: < BTreeMap < _ , _ > > ( ) ;
285
308
286
- if error_map. len ( ) > 0 {
287
- Err ( error_map)
288
- } else {
289
- // oh? success? merry giftmas! time to unwrap your presents
290
- // these have default ABIs to select
291
- let [ c_proper, system, system_varargs] =
292
- required_c_abis. map ( |result| result. unwrap ( ) . unwrap_or ( CanonAbi :: C ) ) ;
293
- let rust_cold = rust_cold. unwrap ( ) . unwrap_or ( CanonAbi :: RustCold ) ;
294
-
295
- // these stay options, but shell the Result
296
- let [ efiapi, stdcall, fastcall, thiscall, vectorcall, win64, sysv64] =
297
- optional_abis. map ( |result| result. unwrap ( ) ) ;
298
-
299
- // these simplify to booleans
300
- let bool_abis = bool_abis. map ( |result| result. unwrap ( ) . unwrap_or ( false ) ) ;
301
- // repeat the mantra: arm...
302
- let [ aapcs, cmse_nonsecure_entry, bool_abis @ ..] = bool_abis;
303
- // ...gpu...
304
- let [ gpu_kernel, ptx_kernel, bool_abis @ ..] = bool_abis;
305
- // ...interrupt
306
- let [ avr_interrupt, msp430_interrupt, riscv_interrupt, x86_interrupt] = bool_abis;
307
- Ok ( AbiMap {
309
+ // oh? success? merry giftmas! time to unwrap your presents
310
+ // start with the architectural defaults
311
+ let arch_map = AbiMap :: base_for_arch ( arch) ;
312
+ // these have default ABIs to select
313
+ let [ c_proper, system, system_varargs] =
314
+ required_c_abis. map ( |result| result. unwrap ( ) . unwrap_or ( CanonAbi :: C ) ) ;
315
+ let rust_cold = rust_cold. unwrap ( ) . unwrap_or ( CanonAbi :: RustCold ) ;
316
+
317
+ // these stay options, but shell the Result
318
+ let [ stdcall, fastcall, thiscall, vectorcall] = optional_abis. map ( |result| result. unwrap ( ) ) ;
319
+
320
+ // these simplify to booleans
321
+ let bool_abis = bool_abis. map ( |result| result. unwrap ( ) . unwrap_or ( false ) ) ;
322
+ let [ aapcs, cmse_nonsecure_entry] = bool_abis;
323
+ (
324
+ AbiMap {
308
325
c_proper,
309
326
system,
310
327
system_varargs,
@@ -314,26 +331,16 @@ impl AbiMap {
314
331
aapcs,
315
332
cmse_nonsecure_entry,
316
333
317
- // ...gpu...
318
- gpu_kernel,
319
- ptx_kernel,
320
-
321
- // ...interrupt
322
- avr_interrupt,
323
- msp430_interrupt,
324
- riscv_interrupt,
325
- x86_interrupt,
326
-
327
334
// x86-ish
328
- efiapi,
329
335
stdcall,
330
336
fastcall,
331
337
thiscall,
332
338
vectorcall,
333
- win64,
334
- sysv64,
335
- } )
336
- }
339
+
340
+ ..arch_map
341
+ } ,
342
+ error_map,
343
+ )
337
344
}
338
345
339
346
// serialization
0 commit comments