Description
I've found that u128 division is not working on the x86_64-unknown-uefi
target. Depending on the exact code I've seen it give either incorrect results or fail with an invalid opcode error.
Fairly minimal example:
#![no_std]
#![no_main]
#![feature(abi_efiapi)]
use log::info;
use uefi::prelude::*;
#[inline(never)]
fn hide_u128(n: u128) -> u128 {
n
}
#[entry]
fn efi_main(_image: Handle, st: SystemTable<Boot>) -> Status {
uefi_services::init(&st).unwrap().unwrap();
let a = hide_u128(2);
let b = hide_u128(1);
info!("a/b={}", a / b);
todo!();
}
The easiest way to actually run this is with QEMU; I've set up a example in this repo: https://github.com/nicholasbishop/uefi-div-bug. The run.py
script will build it and run it under a QEMU UEFI environment.
With this particular example I get this error:
!!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!!
With less minimal examples I've also seen it not fail with an invalid opcode, but instead just give a bogus result. Other u128 operations I tried (add, sub, mul) work fine.
My not-very-informed guess is that there's a bug in the __udivti3
implementation in compiler_builtins. I was curious if perhaps rust-lang/compiler-builtins#332 was related, but I couldn't figure out how to alter the version of compiler-builtins I tested against.
$ rustc +nightly --version
rustc 1.55.0-nightly (150fad30e 2021-06-19)