public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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 --]

  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