Recent

Author Topic: Does anyone know why my code halts and raise error when in AA64,RV64,LA64 UEFI?  (Read 4215 times)

TYDQ

  • Full Member
  • ***
  • Posts: 104
My full pascal code is in https://github.com/TYDQSoft/UEFIPascalOS/tree/main(Contains my pascal OS code and elf2efi code)
I have used my elf2efi utility (Pascal-based program running on linux,which programmed by me) to converts my elf file to UEFI pecoff executable.To simulate the elf file executation as a pecoff file,all position relation(Not absolute address) will not changed by this program.
This is the my error pascal code segment about where the error occurs in LA64(LoongArch64,due to its error raising is friendly and according the error exception,I positioned this error directly on this code):
Code: Pascal  [Select][+][-]
  1. procedure efi_initialize(InputImageHandle:efi_handle;InputSystemTable:Pefi_system_table);[public,alias:'EFI_INITIALIZE'];
  2. begin
  3.  ParentImageHandle:=InputImageHandle; GlobalSystemTable:=InputSystemTable;
  4. end;
And that is where the error occurs in the main program(Start of the program to where the error occurs):
Code: Pascal  [Select][+][-]
  1. program uefiloader;
  2.  
  3. {$MODE FPC}
  4.  
  5. uses uefi,binarybase,bootconfig,graphics;
  6.    
  7. function efi_main(ImageHandle:efi_handle;systemtable:Pefi_system_table):efi_status;{$ifdef cpux86_64}MS_ABI_Default;{$endif}{$ifdef cpui386}cdecl;{$endif}[public,alias:'_start'];
  8. var {For checking elf file}
  9.     sfsp:Pefi_simple_file_system_protocol;
  10.     fp:Pefi_file_protocol;
  11.     efsl:efi_file_system_list;
  12.     i,j,count,procindex:natuint;
  13.     status:efi_status;
  14.     finfo:efi_file_info;
  15.     finfosize:natuint;
  16.     proccontent:Pointer;
  17.     procsize:natuint;
  18.     partstr:PWideChar;
  19.     gpl:efi_graphics_list;
  20.     isgraphics:boolean;
  21.     loaderscreenconfig:screen_config;
  22.     {For elf structure}
  23.     header:elf64_header;
  24.     program_headers:^elf64_program_header;
  25.     LowAddress,HighAddress:qword;
  26.     PageCount:qword;
  27.     KernelRelocateBase:qword;
  28.     RelocateOffset:qword;
  29.     ZeroStart:^qword;
  30.     SourceStart,DestStart:^byte;
  31.     KernelEntry:Pointer;
  32.     bool:array[1..4] of boolean;
  33.     {For loading elf files}
  34.     initparam:Psys_parameter_item;
  35.     param:sys_parameter;
  36.     func:sys_parameter_function;
  37.     funcandparam:sys_parameter_function_and_parameter;
  38.     res:Pointer;
  39.     {For memory initializtion}
  40.     memorymap:efi_memory_map;
  41.     memoryavailable:efi_memory_result;
  42.     addressoffset:natuint;
  43.     allocaddress:natuint;
  44. begin  
  45.  {Initialize the uefi loader}
  46.  efi_initialize(ImageHandle,systemtable);
I know FPC in other architecture uses default calling convention and UEFI in architecture which is not x64 uses this too,Using default calling convention is not wrong.However,while reading the assembly code generated,I was confused about why my efi_initialize have error after I convert the elf file to UEFI pecoff file.Does anyone know why my code raise the error(It is raised by UEFI internal debugger) and how can I fix it?(Due to my code cannot pass when in Aarch64,LoongArch,RiscV UEFI)
« Last Edit: August 20, 2024, 03:43:56 pm by TYDQ »

TYDQ

  • Full Member
  • ***
  • Posts: 104
Is it too hard for us to respond?
 ;)

Laksen

  • Hero Member
  • *****
  • Posts: 786
    • J-Software
Maybe if you said what failed, and gave examples of the disassembly on the address where it failed?

TYDQ

  • Full Member
  • ***
  • Posts: 104
Maybe if you said what failed, and gave examples of the disassembly on the address where it failed?
This is generated assembly code from fpc,I will mark where the error occurs:
Code: ASM  [Select][+][-]
  1. .section .text.n_uefi_$$_efi_initialize$pointer$pefi_system_table,"ax"
  2.         .balign 8
  3. .globl  UEFI_$$_EFI_INITIALIZE$POINTER$PEFI_SYSTEM_TABLE
  4.         .type   UEFI_$$_EFI_INITIALIZE$POINTER$PEFI_SYSTEM_TABLE,@function
  5. UEFI_$$_EFI_INITIALIZE$POINTER$PEFI_SYSTEM_TABLE:
  6. .globl  EFI_INITIALIZE
  7.         .type   EFI_INITIALIZE,@function
  8. EFI_INITIALIZE:
  9. .Lc14:
  10. # [2874] begin
  11.         addi.$sp,$sp,-32
  12. .Lc15:
  13.         st.d    $fp,$sp,16
  14. .Lc16:
  15.         addi.$fp,$sp,32
  16. .Lc17:
  17. # Var InputImageHandle located at $r3+0, size=OS_64
  18. # Var InputSystemTable located at $r3+8, size=OS_64
  19.         st.d    $a0,$sp,0
  20.         st.d    $a1,$sp,8
  21. # [2875] ParentImageHandle:=InputImageHandle; GlobalSystemTable:=InputSystemTable;
  22.         move    $t0,$sp
  23.         pcalau12i       $t1,%got_pc_hi20(TC_$UEFI_$$_PARENTIMAGEHANDLE)
  24.         ld.d    $t1,$t1,%got_pc_lo12(TC_$UEFI_$$_PARENTIMAGEHANDLE)
  25.         ld.d    $t0,$t0,0
  26.         st.d    $t0,$t1,0 #That is where the error occurs.
  27.         addi.$t1,$sp,8
  28.         pcalau12i       $t0,%got_pc_hi20(TC_$UEFI_$$_GLOBALSYSTEMTABLE)
  29.         ld.d    $t0,$t0,%got_pc_lo12(TC_$UEFI_$$_GLOBALSYSTEMTABLE)
  30.         ld.d    $t1,$t1,0
  31.         st.d    $t1,$t0,0
  32. # [2876] end;
  33.         addi.$sp,$fp,-32
  34.         ld.d    $fp,$sp,16
AArch64 and Riscv64 UEFI internal debugger don't show the ImageBase and EntryPoint address,So I don't have the way to find out where the error occurs in disassembly.

TYDQ

  • Full Member
  • ***
  • Posts: 104
Maybe if you said what failed, and gave examples of the disassembly on the address where it failed?
I have read the assembly in aarch64 target:
Code: ASM  [Select][+][-]
  1. .section .text.n_uefi_$$_efi_console_get_max_row_and_max_column,"ax"
  2.         .balign 8
  3. .globl  UEFI_$$_EFI_CONSOLE_GET_MAX_ROW_AND_MAX_COLUMN
  4.         .type   UEFI_$$_EFI_CONSOLE_GET_MAX_ROW_AND_MAX_COLUMN,@function
  5. UEFI_$$_EFI_CONSOLE_GET_MAX_ROW_AND_MAX_COLUMN:
  6. .globl  EFI_CONSOLE_GET_MAX_ROW_AND_MAX_COLUMN
  7.         .type   EFI_CONSOLE_GET_MAX_ROW_AND_MAX_COLUMN,@function
  8. EFI_CONSOLE_GET_MAX_ROW_AND_MAX_COLUMN:
  9. .Lc90:
  10. // [3330] begin
  11.         stp     x29,x30,[sp, #-16]!
  12. .Lc91:
  13.         mov     x29,sp
  14. .Lc92:
  15.         sub     sp,sp,#64
  16. // Var maxc located at sp+0, size=OS_64
  17. // Var maxr located at sp+8, size=OS_64
  18. // Var maxcharsize located at sp+16, size=OS_64
  19. // Var rescolumn located at sp+24, size=OS_64
  20. // Var resrow located at sp+32, size=OS_64
  21. // Var maxcharindex located at sp+40, size=OS_64
  22. // Var status located at sp+48, size=OS_S64
  23. // Var i located at sp+56, size=OS_8
  24. // [3331] i:=0; status:=efi_success; maxcharsize:=2000; maxcharindex:=1; rescolumn:=80; resrow:=25;
  25.         strb    wzr,[sp, #56]
  26.         str     xzr,[sp, #48]
  27.         movz    x0,#2000
  28.         str     x0,[sp, #16]
  29.         movz    x0,#1
  30.         str     x0,[sp, #40]
  31.         movz    x0,#80
  32.         str     x0,[sp, #24]
  33.         movz    x0,#25
  34.         str     x0,[sp, #32]
  35. // [3332] GlobalSystemTable^.ConOut^.SetMode(GlobalSystemTable^.ConOut,0);
  36.         adrp    x0,TC_$UEFI_$$_GLOBALSYSTEMTABLE
  37.         add     x0,x0,:lo12:TC_$UEFI_$$_GLOBALSYSTEMTABLE
  38.         ldr     x0,[x0]
  39.         ldr     x0,[x0, #64] #that is where error occurs in assembly
  40.         movz    x1,#0
  41.         adrp    x2,TC_$UEFI_$$_GLOBALSYSTEMTABLE
  42.         add     x2,x2,:lo12:TC_$UEFI_$$_GLOBALSYSTEMTABLE
  43.         ldr     x2,[x2]
  44.         ldr     x2,[x2, #64]
  45.         ldr     x2,[x2, #32]
  46.         blr     x2

Laksen

  • Hero Member
  • *****
  • Posts: 786
    • J-Software
On la64, what's the value of $t1 when it crashes? Does it match the value you have updated in the .got?

TYDQ

  • Full Member
  • ***
  • Posts: 104
On la64, what's the value of $t1 when it crashes? Does it match the value you have updated in the .got?
I don't know,the LoongArch UEFI internal debugger don't show me this.It show me just:
PROGRESS CODE: V03058001 I0
CRMD   0xB0
PRMD   0x4
ECFG  0x800
ESTAT   0x40000
ERA    0xD85C458(The error position)
BADV    0x0(The fault address)
BADI 0x29C00184(The error machine code)
PC 0x00000D85C458(The error position)


Laksen

  • Hero Member
  • *****
  • Posts: 786
    • J-Software
Attach a debugger and break on that address?

TYDQ

  • Full Member
  • ***
  • Posts: 104
Attach a debugger and break on that address?
UEFI has its internal debugger,but its function doesn't abundant.

Laksen

  • Hero Member
  • *****
  • Posts: 786
    • J-Software
If you are using QEMU you can easily use gdb

TYDQ

  • Full Member
  • ***
  • Posts: 104
If you are using QEMU you can easily use gdb
I'm using libvirt and QEMU.

Laksen

  • Hero Member
  • *****
  • Posts: 786
    • J-Software
Okay that should work fine I guess. Try and search for how to use gdb with QEMU

TYDQ

  • Full Member
  • ***
  • Posts: 104
Okay that should work fine I guess. Try and search for how to use gdb with QEMU
However,after I edited my elf2efi,the error still occurs in RV64(Risc-V 64),other three platforms are running successfully.
UEFI internal debugger told me this and this is where error occurs:
Code: ASM  [Select][+][-]
  1. .section .text.n_uefi_$$_efi_initialize$pointer$pefi_system_table,"ax"
  2.         .balign 8
  3. .globl  UEFI_$$_EFI_INITIALIZE$POINTER$PEFI_SYSTEM_TABLE
  4.         .type   UEFI_$$_EFI_INITIALIZE$POINTER$PEFI_SYSTEM_TABLE,@function
  5. UEFI_$$_EFI_INITIALIZE$POINTER$PEFI_SYSTEM_TABLE:
  6. .globl  EFI_INITIALIZE
  7.         .type   EFI_INITIALIZE,@function
  8. EFI_INITIALIZE:
  9. .Lc8:
  10. # [2858] begin
  11.         addi    x2,x2,-16
  12.         sd      x1,8(x2)
  13.         sd      x8,0(x2)
  14.         addi    x8,x2,16
  15.         addi    x2,x2,-104
  16. # Var InputImageHandle located in register x10
  17. # Var InputSystemTable located in register x11
  18. # Var InputImageHandle located in register x10
  19. .La1:
  20. # [2859] ParentImageHandle:=InputImageHandle; GlobalSystemTable:=InputSystemTable;
  21.         auipc   x12,%got_pcrel_hi(TC_$UEFI_$$_PARENTIMAGEHANDLE)
  22.         ld      x12,%pcrel_lo(.La1)(x12)
  23.         sd      x10,0(x12) # where the error occurs
  24. # Var InputSystemTable located in register x11
  25. .La2:
  26.         auipc   x10,%got_pcrel_hi(TC_$UEFI_$$_GLOBALSYSTEMTABLE)
  27.         ld      x10,%pcrel_lo(.La2)(x10)
  28.         sd      x11,0(x10)
  29. # [2860] end;
  30.         ld      x8,104(x2)
  31.         ld      x1,112(x2)
  32.         addi    x2,x2,120
  33.         jalr    x0,x1
  34. .Lc7:
  35. .Le3:
  36.         .size   UEFI_$$_EFI_INITIALIZE$POINTER$PEFI_SYSTEM_TABLE, .Le3 - UEFI_$$_EFI_INITIALIZE$POINTER$PEFI_SYSTEM_TABLE
  37.  
This is the error type:
!!!! RISCV64 Exception Type - 000000000000000F(EXCEPT_RISCV_STORE_ACCESS_PAGE_FAULT) !!!!
     t0 = 0x00000000000001000        t1 = 0x00000000083FFF620
                                                                  t2 = 0x00000000000001000        t3 = 0x0FFFFFFFFBC62157E
                                                  t4 = 0x00000000000003E33        t5 = 0x00000000000004FEC
                                 t6 = 0x00000000000000004        s0 = 0x00000000083FFF610
                  s1 = 0x00000000000000013        s2 = 0x00000000000000000
                                                                                  s3 = 0x00000000000000000        s4 = 0x000000000BFE00000
                                                                  s5 = 0x0000000017FFFE018        s6 = 0x08000000A00006800
                                                  s7 = 0x00000000000000004        s8 = 0x00000000000002000
                                 s9 = 0x00000000080043710       s10 = 0x00000000000000000
                 s11 = 0x00000000000000000        a0 = 0x0000000017F2AB998
                                                                                  a1 = 0x0000000017FFFE018        a2 = 0x00000000000000000
                                                                  a3 = 0x00000000000000000        a4 = 0x0000000017FFFE018
                                                  a5 = 0x0000000017E2DFA88        a6 = 0x00000000000000006
                                 a7 = 0x0000000000000000E      zero = 0x00000000000000000
                  ra = 0x0000000017E2DFAD0        sp = 0x0000000017FE14D78
                                                                                  gp = 0x00000000000000000        tp = 0x0000000008004E000
                                                                sepc = 0x0000000017E2E06BC   sstatus = 0x08000000200006120
                                               stval = 0x00000000000000000

Laksen

  • Hero Member
  • *****
  • Posts: 786
    • J-Software
x12 is 0

Looks like there's a mix of pcrel and got_pcrel

Laksen

  • Hero Member
  • *****
  • Posts: 786
    • J-Software
Nevermind, that's probably not the issue. You need to dig deeper. I would advice setting a breakpoint with GDB. It sounds like that inbuilt debugger is quite tedious to work with

 

TinyPortal © 2005-2018