Skip to content

Commit f2e3436

Browse files
authored
Merge pull request #115 from maelgui/mael.51_use_asm_macro
Resolve #51, use new asm! macro
2 parents 61d35ce + 6711887 commit f2e3436

File tree

9 files changed

+147
-105
lines changed

9 files changed

+147
-105
lines changed

mythril/src/error.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,12 @@ pub fn check_vm_insruction(rflags: u64, error: String) -> Result<()> {
5252
} else if rflags.contains(RFlags::FLAGS_ZF) {
5353
let errno = unsafe {
5454
let value: u64;
55-
llvm_asm!("vmread %rax, %rdx;"
56-
: "={rdx}"(value)
57-
: "{rax}"(vmcs::VmcsField::VmInstructionError as u64)
58-
: "rflags"
59-
: "volatile");
55+
asm!(
56+
"vmread rdx, rax",
57+
in("rax") vmcs::VmcsField::VmInstructionError as u64,
58+
out("rdx") value,
59+
options(nostack)
60+
);
6061
value
6162
};
6263
let vm_error = VmInstructionError::try_from(errno)
@@ -137,7 +138,7 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
137138
loop {
138139
unsafe {
139140
// Try to at least keep CPU from running at 100%
140-
llvm_asm!("hlt" :::: "volatile");
141+
asm!("hlt", options(nostack, nomem));
141142
}
142143
}
143144
}

mythril/src/interrupt/idt.rs

+46-39
Original file line numberDiff line numberDiff line change
@@ -79,43 +79,47 @@ pub struct FaultState {
7979
}
8080

8181
macro_rules! push_regs {
82-
() => (llvm_asm!(
83-
"push rax
84-
push rbx
85-
push rcx
86-
push rdx
87-
push rdi
88-
push rsi
89-
push r8
90-
push r9
91-
push r10
92-
push r11
93-
push r12
94-
push r13
95-
push r14
96-
push r15"
97-
: : : : "intel", "volatile"
98-
));
82+
() => {
83+
#[rustfmt::skip]
84+
asm!(
85+
"push rax",
86+
"push rbx",
87+
"push rcx",
88+
"push rdx",
89+
"push rdi",
90+
"push rsi",
91+
"push r8",
92+
"push r9",
93+
"push r10",
94+
"push r11",
95+
"push r12",
96+
"push r13",
97+
"push r14",
98+
"push r15",
99+
)
100+
};
99101
}
100102

101103
macro_rules! pop_regs {
102-
() => (llvm_asm!(
103-
"pop r15
104-
pop r14
105-
pop r13
106-
pop r12
107-
pop r11
108-
pop r10
109-
pop r9
110-
pop r8
111-
pop rsi
112-
pop rdi
113-
pop rdx
114-
pop rcx
115-
pop rbx
116-
pop rax"
117-
: : : : "intel", "volatile"
118-
));
104+
() => {
105+
#[rustfmt::skip]
106+
asm!(
107+
"pop r15",
108+
"pop r14",
109+
"pop r13",
110+
"pop r12",
111+
"pop r11",
112+
"pop r10",
113+
"pop r9",
114+
"pop r8",
115+
"pop rsi",
116+
"pop rdi",
117+
"pop rdx",
118+
"pop rcx",
119+
"pop rbx",
120+
"pop rax",
121+
)
122+
};
119123
}
120124

121125
macro_rules! interrupt_fn_impl {
@@ -129,7 +133,11 @@ macro_rules! interrupt_fn_impl {
129133
push_regs!();
130134

131135
let rbp: usize;
132-
llvm_asm!("" : "={rbp}"(rbp) : : : "volatile");
136+
asm!(
137+
"mov {}, rbp",
138+
out(reg) rbp,
139+
options(nomem, nostack)
140+
);
133141

134142
// Plus usize to skip the old rpb value pushed in the preamble
135143
let stack = &*( (rbp + core::mem::size_of::<usize>()) as *const $type);
@@ -139,10 +147,9 @@ macro_rules! interrupt_fn_impl {
139147

140148
// Remove this stack frame before the iretq. This should work
141149
// whether the above 'rbp' local variable is stack allocated or not.
142-
llvm_asm!("mov rsp, rbp
143-
pop rbp
144-
iretq"
145-
: : : : "intel", "volatile");
150+
asm!("mov rsp, rbp",
151+
"pop rbp",
152+
"iretq");
146153
}
147154
}
148155
}

mythril/src/interrupt/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ pub mod gsi {
1212
}
1313

1414
pub unsafe fn enable_interrupts() {
15-
llvm_asm!("sti" :::: "volatile");
15+
asm!("sti", options(nomem, nostack));
1616
}
1717

1818
pub unsafe fn disable_interrupts() {
19-
llvm_asm!("cli" :::: "volatile");
19+
asm!("cli", options(nomem, nostack));
2020
}

mythril/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![cfg_attr(not(std), no_std)]
2-
#![feature(llvm_asm)]
2+
#![feature(asm)]
33
#![feature(never_type)]
44
#![feature(const_fn)]
55
#![feature(get_mut_unchecked)]

mythril/src/lock/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ pub mod ro_after_init;
44
#[inline(always)]
55
pub fn relax_cpu() {
66
unsafe {
7-
llvm_asm!("rep; nop" ::: "memory");
7+
asm!("rep", "nop");
88
}
99
}

mythril/src/logger.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,14 @@ pub unsafe fn raw_write_console(s: impl AsRef<str>) {
8383
let len = s.as_ref().len();
8484
let ptr = s.as_ref().as_ptr();
8585

86-
llvm_asm!("cld; rep outsb"
87-
:
88-
:"{rdx}"(0x3f8), "{rcx}"(len as u64), "{rsi}"(ptr as u64)
89-
: "rflags", "rsi"
90-
: "volatile");
86+
asm!(
87+
"cld",
88+
"rep outsb",
89+
in("rdx") 0x3f8,
90+
in("rcx") len as u64,
91+
inout("rsi") ptr as u64 => _,
92+
options(nostack)
93+
);
9194
}
9295

9396
pub struct VgaWriter {

mythril/src/registers.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ impl IdtrBase {
1313
limit: 0,
1414
base_addr: 0,
1515
};
16-
llvm_asm!("sidt ($0)"
17-
:
18-
: "r"(&mut info)
19-
: "memory"
20-
: "volatile");
16+
asm!(
17+
"sidt fword ptr [{0}]",
18+
in(reg) &mut info,
19+
options(nostack)
20+
);
2121
info.base_addr
2222
}
2323
}
@@ -35,11 +35,11 @@ impl GdtrBase {
3535
pub fn read() -> u64 {
3636
unsafe {
3737
let mut info = GdtInfo { size: 0, offset: 0 };
38-
llvm_asm!("sgdtq ($0)"
39-
:
40-
: "r"(&mut info)
41-
: "memory"
42-
: "volatile");
38+
asm!(
39+
"sgdt fword ptr [{0}]",
40+
in(reg) &mut info,
41+
options(nostack)
42+
);
4343
info.offset
4444
}
4545
}

mythril/src/vmcs.rs

+27-19
Original file line numberDiff line numberDiff line change
@@ -326,11 +326,14 @@ fn vmcs_write_with_fixed(
326326
fn vmcs_write(field: VmcsField, value: u64) -> Result<()> {
327327
let rflags = unsafe {
328328
let rflags: u64;
329-
llvm_asm!("vmwrite %rdx, %rax; pushfq; popq $0"
330-
: "=r"(rflags)
331-
: "{rdx}"(value), "{rax}"(field as u64)
332-
: "rflags"
333-
: "volatile");
329+
asm!(
330+
"vmwrite rax, rdx",
331+
"pushf",
332+
"pop {}",
333+
lateout(reg) rflags,
334+
in("rdx") value,
335+
in("rax") field as u64,
336+
);
334337
rflags
335338
};
336339

@@ -343,11 +346,11 @@ fn vmcs_write(field: VmcsField, value: u64) -> Result<()> {
343346
fn vmcs_read(field: VmcsField) -> Result<u64> {
344347
let value = unsafe {
345348
let value: u64;
346-
llvm_asm!("vmreadq %rdx, %rax"
347-
: "={rax}"(value)
348-
: "{rdx}"(field as u64)
349-
: "rflags"
350-
: "volatile");
349+
asm!(
350+
"vmread rax, rdx",
351+
out("rax") value,
352+
in("rdx") field as u64
353+
);
351354
value
352355
};
353356

@@ -363,10 +366,13 @@ fn vmcs_activate(vmcs: &mut Vmcs, _vmx: &vmx::Vmx) -> Result<()> {
363366
}
364367
let rflags = unsafe {
365368
let rflags: u64;
366-
llvm_asm!("vmptrld $1; pushfq; popq $0"
367-
: "=r"(rflags)
368-
: "m"(vmcs_region_addr)
369-
: "rflags");
369+
asm!(
370+
"vmptrld [{}]",
371+
"pushf",
372+
"pop {}",
373+
in(reg) &vmcs_region_addr,
374+
lateout(reg) rflags
375+
);
370376
rflags
371377
};
372378

@@ -376,11 +382,13 @@ fn vmcs_activate(vmcs: &mut Vmcs, _vmx: &vmx::Vmx) -> Result<()> {
376382
fn vmcs_clear(vmcs_page: &mut Raw4kPage) -> Result<()> {
377383
let rflags = unsafe {
378384
let rflags: u64;
379-
llvm_asm!("vmclear $1; pushfq; popq $0"
380-
: "=r"(rflags)
381-
: "m"(vmcs_page as *const _ as u64)
382-
: "rflags"
383-
: "volatile");
385+
asm!(
386+
"vmclear [{}]",
387+
"pushf",
388+
"pop {}",
389+
in(reg) &(vmcs_page as *const _ as u64),
390+
lateout(reg) rflags
391+
);
384392
rflags
385393
};
386394
error::check_vm_insruction(rflags, "Failed to clear VMCS".into())

mythril/src/vmx.rs

+45-22
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,24 @@ impl Vmx {
2020

2121
unsafe {
2222
// Enable NE in CR0, This is fixed bit in VMX CR0
23-
llvm_asm!("movq %cr0, %rax; orq %rdx, %rax; movq %rax, %cr0;"
24-
:
25-
: "{rdx}"(0x20)
26-
: "rax");
23+
asm!(
24+
"mov rax, cr0",
25+
"or rax, rdx",
26+
"mov cr0, rax",
27+
in("rdx") 0x20,
28+
lateout("rax") _,
29+
options(nomem, nostack)
30+
);
2731

2832
// Enable vmx in CR4
29-
llvm_asm!("movq %cr4, %rax; orq %rdx, %rax; movq %rax, %cr4;"
30-
:
31-
: "{rdx}"(VMX_ENABLE_FLAG)
32-
: "rax");
33+
asm!(
34+
"mov rax, cr4",
35+
"or rax, rdx",
36+
"mov cr4, rax",
37+
in("rdx") VMX_ENABLE_FLAG,
38+
lateout("rax") _,
39+
options(nomem, nostack)
40+
);
3341
}
3442

3543
let revision_id = Self::revision();
@@ -45,10 +53,13 @@ impl Vmx {
4553

4654
let rflags = unsafe {
4755
let rflags: u64;
48-
llvm_asm!("vmxon $1; pushfq; popq $0"
49-
: "=r"(rflags)
50-
: "m"(vmxon_region_addr)
51-
: "rflags");
56+
asm!(
57+
"vmxon [{}]",
58+
"pushf",
59+
"pop {}",
60+
in(reg) &vmxon_region_addr,
61+
lateout(reg) rflags,
62+
);
5263
rflags
5364
};
5465

@@ -63,10 +74,12 @@ impl Vmx {
6374
// was originally activated from
6475
let rflags = unsafe {
6576
let rflags: u64;
66-
llvm_asm!("vmxoff; pushfq; popq $0"
67-
: "=r"(rflags)
68-
:
69-
: "rflags");
77+
asm!(
78+
"vmxoff",
79+
"pushf",
80+
"pop {}",
81+
lateout(reg) rflags,
82+
);
7083
rflags
7184
};
7285

@@ -85,9 +98,14 @@ impl Vmx {
8598

8699
let rflags = unsafe {
87100
let rflags: u64;
88-
llvm_asm!("invept $1, $2; pushfq; popq $0"
89-
: "=r"(rflags)
90-
: "m"(val), "r"(t));
101+
asm!(
102+
"invept {}, [{}]",
103+
"pushfq",
104+
"pop {}",
105+
in(reg) t,
106+
in(reg) &val,
107+
lateout(reg) rflags
108+
);
91109
rflags
92110
};
93111
error::check_vm_insruction(rflags, "Failed to execute invept".into())
@@ -107,9 +125,14 @@ impl Vmx {
107125

108126
let rflags = unsafe {
109127
let rflags: u64;
110-
llvm_asm!("invvpid $1, $2; pushfq; popq $0"
111-
: "=r"(rflags)
112-
: "m"(val), "r"(t));
128+
asm!(
129+
"invvpid {}, [{}]",
130+
"pushfq",
131+
"pop {}",
132+
in(reg) t,
133+
in(reg) &val,
134+
lateout(reg) rflags
135+
);
113136
rflags
114137
};
115138
error::check_vm_insruction(rflags, "Failed to execute invvpid".into())

0 commit comments

Comments
 (0)