From: "Ayush Singh" <ayushdevel1325@gmail.com>
To: devel@edk2.groups.io, afish@apple.com
Cc: Mike Kinney <michael.d.kinney@intel.com>,
"mikuback@linux.microsoft.com" <mikuback@linux.microsoft.com>,
"Gaibusab, Jabeena B" <jabeena.b.gaibusab@intel.com>,
"Yao, Jiewen" <jiewen.yao@intel.com>
Subject: Re: [edk2-devel] Casting i128 into f64 in UEFI Rust pagefaults
Date: Wed, 27 Jul 2022 11:31:45 +0530 [thread overview]
Message-ID: <0d7a5edb-5102-de3d-cd1d-fc93d1ac7064@gmail.com> (raw)
In-Reply-To: <6824753D-9F86-400C-ACCE-683A50C29F48@apple.com>
[-- Attachment #1: Type: text/plain, Size: 14842 bytes --]
Thanks, Andrew. I will try it out and add it to UEFI Rust documentation
as well. I will ask more questions in case I get stuck somewhere.
Ayush Singh
On 7/27/22 03:08, Andrew Fish via groups.io wrote:
> Ayush,
>
>
> Well bugs in the runtime are a classic case when have good debugging
> infrastructure pays off and that class of issue is what started this
> email thread.
>
> It is not hard to try out gdb to see what happens if you are using QEMU.
> From the root of the edk2 repo:
> $ OvmfPkg/build.sh qemu -gdb tcp::9000
>
> Then from another terminal
> $ cd BaseTools/Scripts
> $ gdb -ex "target remote localhost:9000" -ex "source efi_gdb.py"
>
> That should get you a symbolicated stack frame.
>
> The QEMU -gdb works like a JTAG debugger. You can put dead loops in
> your code, let it run, and then attach.
>
> Thanks,
>
> Andrew Fish
>
>> On Jul 26, 2022, at 12:15 PM, Ayush Singh <ayushdevel1325@gmail.com>
>> wrote:
>>
>> Hi Andrew. I do agree with having better debugging support for
>> Rust-UEFI. However, I am not much experienced with even the C side of
>> UEFI debugging, so it has been difficult for me to do much on the
>> Rust side either. It isn't like Rust UEFI debugging is not possible.
>> There are some examples ([1]), but as you might guess, they are quite
>> few. Additionally, most of them seem to be concentrated around
>> Windows. Finally, there is actually quite good debugging support in
>> uefi-rs [2], but well, that's licensed under MPL-2.0, so I have
>> stayed clear of it.
>>
>>
>> Another reason I have gone so long without using any actual debugger
>> is because, well, Rust makes it quite explicit where wired errors can
>> occur. Most functions, even inside the std, don't use pointers but
>> rather use `NonNull`, `MaybeUninint` or some other safe abstraction.
>> Even on the worst failure, the program will abort instead of crash.
>> On aborting, Rust also gives a nice message on stderr stating exactly
>> where the error occurred along with all the details of the error.
>> Basically, it was always so clear what caused the error and where it
>> occurred that I simply didn't feel the need to attach a debugger,
>> till now.
>>
>>
>> There is some work going on to actually document using Rust for UEFI
>> in the rustc docs, sponsored by Red Hat [3], so the situation should
>> improve soon. What I do know is that the `.pdb` files generated by
>> Rust (which are always generated) should contain all the symbols for
>> debugging. I can work on debugging once I finish up with solving all
>> other errors which are due to my implementation of std rather than
>> the ones that have been caused by the rust intrinsic.
>>
>>
>> Ayush Singh
>>
>>
>> [1]: https://xitan.me/posts/rust-uefi-runtime-driver/
>>
>> [2]: https://github.com/rust-osdev/uefi-rs
>>
>> [3]: https://github.com/rust-lang/rust/pull/99760
>>
>>
>> On 7/26/22 23:20, Andrew Fish wrote:
>>>> On Jul 25, 2022, at 10:43 PM, Ayush Singh
>>>> <ayushdevel1325@gmail.com> wrote:
>>>>
>>>> Hi Andrew. Thanks for all your work. The more I look at this, the
>>>> more it feels like it might be a problem on the LLVM side instead
>>>> of Rust. I also found some more tests (all related to numbers btw)
>>>> which can cause different types of exceptions, so I think I will
>>>> try filing bugs upstream.
>>>>
>>>
>>> Ayush,
>>>
>>> In general If we want to move to Rust we are going to need a way to
>>> debug issues like this down to the root cause. I think figuring out
>>> how to debug will make it easier to move forward with the Rust port
>>> in general. It will time well spent.
>>>
>>> The best way to get LLVM fixed, if it is even broken, is to provide
>>> a simple test case that reproduces the behavior. I don’t think at
>>> this point we know what is going on. It is very unlikely that some
>>> random LLVM developer is going to invest the time in trying to setup
>>> some UEFI environment to try and root cause this bug. I general find
>>> I have to create a simple at desk example and then I get stuff fixed
>>> quickly. Basically a test case the LLVM developer can compile at
>>> their desk and see the error in assembler, or at least run it at
>>> desk and have bogus output.
>>>
>>> I’m not 100% sure what toolchain you are using. Can you `objdump
>>> -d hello_world_std.efi`and get some symbols with the disassembly?
>>> For VC++ I think it would be `DUMPBIN /DISASM`.
>>>
>>> What are you planning on using for source level debugging Rust? I
>>> wrote some gdb[1] and lldb[2] debugging commands in Python. I’m
>>> guessing loading Rust symbols from PE/COFF images should be similar,
>>> as long as the debugger knows about rust.
>>>
>>> I’m happy to help you figure out stuff related to debugging Rust.
>>>
>>> [1]
>>> https://github.com/tianocore/edk2/blob/master/BaseTools/Scripts/efi_gdb.py
>>> [2]
>>> https://github.com/tianocore/edk2/blob/master/BaseTools/Scripts/efi_lldb.py
>>>
>>> Thanks,
>>>
>>> Andrew Fish
>>>
>>>> Yours Sincerely,
>>>>
>>>> Ayush Singh
>>>>
>>>>
>>>> On 7/26/22 00:24, Andrew Fish wrote:
>>>>> I guess I could at least dump to the end (req)…. Going backwards
>>>>> is a bit painful in x86.
>>>>>
>>>>> (lldb) dis -s 0x0000000140001B60 -b -c 30
>>>>> hello_world_std.efi[0x140001b60]: 48 8b 09
>>>>> movq (%rcx), %rcx
>>>>> hello_world_std.efi[0x140001b63]: 48 01 c1
>>>>> addq %rax, %rcx
>>>>> hello_world_std.efi[0x140001b66]: 4c 89 c2
>>>>> movq %r8, %rdx
>>>>> hello_world_std.efi[0x140001b69]: 48 11 c2
>>>>> adcq %rax, %rdx
>>>>> hello_world_std.efi[0x140001b6c]: 48 31 c1
>>>>> xorq %rax, %rcx
>>>>> hello_world_std.efi[0x140001b6f]: 48 31 c2
>>>>> xorq %rax, %rdx
>>>>> hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80
>>>>> movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000
>>>>> hello_world_std.efi[0x140001b7c]: 4c 21 c6
>>>>> andq %r8, %rsi
>>>>> hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00
>>>>> callq 0x1400070e0
>>>>> hello_world_std.efi[0x140001b84]: 48 09 f0
>>>>> orq %rsi, %rax
>>>>> hello_world_std.efi[0x140001b87]: 48 83 c4 20
>>>>> addq $0x20, %rsp
>>>>> hello_world_std.efi[0x140001b8b]: 5e
>>>>> popq %rsi
>>>>> hello_world_std.efi[0x140001b8c]: c3 retq
>>>>> hello_world_std.efi[0x140001b8d]: cc int3
>>>>> hello_world_std.efi[0x140001b8e]: cc int3
>>>>> hello_world_std.efi[0x140001b8f]: cc int3
>>>>> hello_world_std.efi[0x140001b90]: e9 db 55 00 00
>>>>> jmp 0x140007170
>>>>> hello_world_std.efi[0x140001b95]: cc int3
>>>>> …
>>>>>
>>>>> Then we can guess based on how functions get aligned to find the
>>>>> start….
>>>>>
>>>>> hello_world_std.efi[0x140001b50]: 56 pushq %rsi
>>>>> hello_world_std.efi[0x140001b51]: 48 83 ec 20 subq $0x20, %rsp
>>>>> hello_world_std.efi[0x140001b55]: 4c 8b 41 08 movq 0x8(%rcx), %r8
>>>>> hello_world_std.efi[0x140001b59]: 4c 89 c0 movq %r8, %rax
>>>>> hello_world_std.efi[0x140001b5c]: 48 c1 f8 3f sarq $0x3f, %rax
>>>>> hello_world_std.efi[0x140001b60]: 48 8b 09 movq (%rcx), %rcx
>>>>> hello_world_std.efi[0x140001b63]: 48 01 c1 addq %rax, %rcx
>>>>> hello_world_std.efi[0x140001b66]: 4c 89 c2 movq %r8, %rdx
>>>>> hello_world_std.efi[0x140001b69]: 48 11 c2 adcq %rax, %rdx
>>>>> hello_world_std.efi[0x140001b6c]: 48 31 c1 xorq %rax, %rcx
>>>>> hello_world_std.efi[0x140001b6f]: 48 31 c2 xorq %rax, %rdx
>>>>> hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80
>>>>> movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000
>>>>> hello_world_std.efi[0x140001b7c]: 4c 21 c6 andq %r8, %rsi
>>>>> hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00 callq 0x1400070e0
>>>>> hello_world_std.efi[0x140001b84]: 48 09 f0 orq %rsi, %rax
>>>>> hello_world_std.efi[0x140001b87]: 48 83 c4 20 addq $0x20, %rsp
>>>>> hello_world_std.efi[0x140001b8b]: 5e popq %rsi
>>>>> hello_world_std.efi[0x140001b8c]: c3 retq
>>>>>
>>>>> So the faulting function is getting passed a bad pointer as its
>>>>> 1st arg.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Andrew Fish
>>>>>
>>>>>> On Jul 25, 2022, at 11:45 AM, Andrew Fish <afish@apple.com> wrote:
>>>>>>
>>>>>> Ops… Looks like your PE/COFF is linked at 0x0000000140000000,
>>>>>> so 0x140001b60 is the interesting bit.
>>>>>>
>>>>>> (lldb) dis -s 0x0000000140001B60 -b
>>>>>> hello_world_std.efi[0x140001b60]: 48 8b 09 movq (%rcx), %rcx
>>>>>> hello_world_std.efi[0x140001b63]: 48 01 c1 addq %rax, %rcx
>>>>>> hello_world_std.efi[0x140001b66]: 4c 89 c2 movq %r8, %rdx
>>>>>> hello_world_std.efi[0x140001b69]: 48 11 c2 adcq %rax, %rdx
>>>>>> hello_world_std.efi[0x140001b6c]: 48 31 c1 xorq %rax, %rcx
>>>>>> hello_world_std.efi[0x140001b6f]: 48 31 c2 xorq %rax, %rdx
>>>>>> hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80
>>>>>> movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000
>>>>>> hello_world_std.efi[0x140001b7c]: 4c 21 c6 andq %r8, %rsi
>>>>>>
>>>>>> RCX - FFFFFFFFFFFFFFFF
>>>>>>
>>>>>> So yea that looks like the fault.
>>>>>>
>>>>>> I don’t see that pattern in your .s file….
>>>>>>
>>>>>> Can you figure out what function is @ 0x140001b60 in the PE/COFF
>>>>>> image. Do you have a map file from the linker?
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Andrew Fish
>>>>>>
>>>>>> PS Again sorry I don’t have anything installed to crack PDB files.
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Andrew Fish
>>>>>>
>>>>>>> On Jul 25, 2022, at 10:51 AM, Andrew Fish via groups.io
>>>>>>> <afish=apple.com@groups.io> wrote:
>>>>>>>
>>>>>>> Ayush,
>>>>>>>
>>>>>>> CR2 is the fault address so 0xFFFFFFFFFFFFFFFF. Given for EFI
>>>>>>> Virt == Physical the fault address looks like a bad pointer.
>>>>>>>
>>>>>>> Sorry I’ve not used VC++ in a long time so I don’t know how to
>>>>>>> debug with VC++, but If I was using clang/lldb I’d look at the
>>>>>>> source and assembly for the fault address.
>>>>>>>
>>>>>>> The image base is: 0x000000000603C000
>>>>>>> The fault PC/RIP is: 000000000603DB60
>>>>>>>
>>>>>>> So the faulting code is at 0x1B60 in the image. Given the images
>>>>>>> are linked at zero you should be able to load the build product
>>>>>>> into the debugger and look at what code is at offset 0x1B60. The
>>>>>>> same should work for any tools that dump the binary.
>>>>>>>
>>>>>>> Thanks,
>>>>>>>
>>>>>>> Andrew Fish
>>>>>>>
>>>>>>>> On Jul 25, 2022, at 10:33 AM, Ayush Singh
>>>>>>>> <ayushdevel1325@gmail.com> wrote:
>>>>>>>>
>>>>>>>> Hello everyone.While running Rust tests in UEFI environment, I
>>>>>>>> have come across a numeric test that causes a pagefault. A
>>>>>>>> simple reproducible example for this is given below:
>>>>>>>>
>>>>>>>> ```rust
>>>>>>>>
>>>>>>>> fn main() {
>>>>>>>> use std::hint::black_box as b;
>>>>>>>>
>>>>>>>> let z: i128 = b(1);
>>>>>>>> assert!((-z as f64) < 0.0);
>>>>>>>> }
>>>>>>>>
>>>>>>>> ```
>>>>>>>>
>>>>>>>>
>>>>>>>> The exception output is as follows:
>>>>>>>>
>>>>>>>> ```
>>>>>>>>
>>>>>>>> !!!! X64 Exception Type - 0E(#PF - Page-Fault) CPU Apic ID -
>>>>>>>> 00000000 !!!!
>>>>>>>> ExceptionData - 0000000000000000 I:0 R:0 U:0 W:0 P:0 PK:0 SS:0
>>>>>>>> SGX:0
>>>>>>>> RIP - 000000000603DB60, CS - 0000000000000038, RFLAGS -
>>>>>>>> 0000000000000246
>>>>>>>> RAX - 0000000000000000, RCX - FFFFFFFFFFFFFFFF, RDX -
>>>>>>>> FFFFFFFFFFFFFFFF
>>>>>>>> RBX - 0000000000000000, RSP - 0000000007EDF1D0, RBP -
>>>>>>>> 0000000007EDF4C0
>>>>>>>> RSI - 0000000007EDF360, RDI - 0000000007EDF3C0
>>>>>>>> R8 - 0000000000000000, R9 - 0000000000000038, R10 -
>>>>>>>> 0000000000000000
>>>>>>>> R11 - 0000000000000000, R12 - 00000000060C6018, R13 -
>>>>>>>> 0000000007EDF520
>>>>>>>> R14 - 0000000007EDF6A8, R15 - 0000000005FA9490
>>>>>>>> DS - 0000000000000030, ES - 0000000000000030, FS -
>>>>>>>> 0000000000000030
>>>>>>>> GS - 0000000000000030, SS - 0000000000000030
>>>>>>>> CR0 - 0000000080010033, CR2 - FFFFFFFFFFFFFFFF, CR3 -
>>>>>>>> 0000000007C01000
>>>>>>>> CR4 - 0000000000000668, CR8 - 0000000000000000
>>>>>>>> DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 -
>>>>>>>> 0000000000000000
>>>>>>>> DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 -
>>>>>>>> 0000000000000400
>>>>>>>> GDTR - 00000000079DE000 0000000000000047, LDTR - 0000000000000000
>>>>>>>> IDTR - 0000000007418018 0000000000000FFF, TR - 0000000000000000
>>>>>>>> FXSAVE_STATE - 0000000007EDEE30
>>>>>>>> !!!! Find image based on IP(0x603DB60)
>>>>>>>> /var/home/ayush/Documents/Programming/Rust/uefi/hello_world_std/target/x86_64-unknown-uefi/debug/deps/hello_world_std-338028f9369e2d42.pdb
>>>>>>>> (ImageBase=000000000603C000, EntryPoint=000000000603D8C0) !!!!
>>>>>>>>
>>>>>>>> ```
>>>>>>>>
>>>>>>>>
>>>>>>>> From my testing, the exception only occurs when a few
>>>>>>>> conditions are met.
>>>>>>>>
>>>>>>>> 1. The binary is compiled in Debug mode. No error in Release mode.
>>>>>>>>
>>>>>>>> 2. `i128` is in a black_box [1]. Does not occur if `black_box`
>>>>>>>> is not present.
>>>>>>>>
>>>>>>>> 3. It has to be `i128`. `i64` or something else work fine.
>>>>>>>>
>>>>>>>> 4. The cast has to be done on `-z`. Doing the same with `+z` is
>>>>>>>> fine.
>>>>>>>>
>>>>>>>>
>>>>>>>> I have also been discussing this in the Rust zulipchat [2], so
>>>>>>>> feel free to chime in there.
>>>>>>>>
>>>>>>>>
>>>>>>>> Additionally, here are links for more information about this
>>>>>>>> program:
>>>>>>>>
>>>>>>>> 1.
>>>>>>>> Assembly:https://rust-lang.zulipchat.com/user_uploads/4715/od51Y9Dkfjahcg9HHcOud8Fm/hello_world_std-338028f9369e2d42.s
>>>>>>>>
>>>>>>>> 2. EFI
>>>>>>>> Binary:https://rust-lang.zulipchat.com/user_uploads/4715/CknqtXLR8SaJZmyOnXctQkpL/hello_world_std.efi
>>>>>>>>
>>>>>>>> 3. PDB
>>>>>>>> file:https://rust-lang.zulipchat.com/user_uploads/4715/zV4i6DsjgQXotp_gS1naEsU0/hello_world_std-338028f9369e2d42.pdb
>>>>>>>>
>>>>>>>>
>>>>>>>> Yours Sincerely,
>>>>>>>>
>>>>>>>> Ayush Singh
>>>>>>>>
>>>>>>>>
>>>>>>>> [1]:https://doc.rust-lang.org/std/hint/fn.black_box.html
>>>>>>>>
>>>>>>>> [2]:https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Casting.20i128.20to.20f64.20in.20black_box.20causes.20exception.20in.20UEFI
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>
>
>
[-- Attachment #2: Type: text/html, Size: 312723 bytes --]
next prev parent reply other threads:[~2022-07-27 6:01 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-25 17:33 Casting i128 into f64 in UEFI Rust pagefaults Ayush Singh
2022-07-25 17:51 ` [edk2-devel] " Andrew Fish
[not found] ` <170523E2507C1293.4676@groups.io>
2022-07-25 18:45 ` Andrew Fish
2022-07-25 18:54 ` Andrew Fish
2022-07-26 5:43 ` Ayush Singh
2022-07-26 17:50 ` Andrew Fish
2022-07-26 19:15 ` Ayush Singh
2022-07-26 21:38 ` Andrew Fish
2022-07-27 6:01 ` Ayush Singh [this message]
2022-07-26 19:12 ` Pedro Falcato
2022-07-26 19:24 ` Ayush Singh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0d7a5edb-5102-de3d-cd1d-fc93d1ac7064@gmail.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox