A very informative article on exceptions handling design and implications for code optimizations.
C++ Exception Handling for IA-64
C++ Exception Handling for IA-64
[1266874889.709] 00000.00000> Available physical memory: 2032dMB
[1266874889.709] 00000.00000>
welcome to lk/MP
[1266874889.709] 00000.00000> INIT: cpu 0, calling hook 0xffffffff8006e2d4 (global_prng_seed) at level 0x30000, flags 0x1
[1266874889.709] 00000.00000> WARNING: System has insufficient randomness. It is completely unsafe to use this system for any cryptographic applications.
[1266874889.709] 00000.00000> INIT: cpu 0, calling hook 0xffffffff800386b0 (elf_build_id) at level 0x3fffe, flags 0x1
[1266874889.709] 00000.00000> INIT: cpu 0, calling hook 0xffffffff800385f0 (version) at level 0x3ffff, flags 0x1
[1266874889.709] 00000.00000> version:
[1266874889.709] 00000.00000> arch: RISCV
[1266874889.709] 00000.00000> platform: RISCV_RV64
[1266874889.709] 00000.00000> target: QEMU_RISCV_RV64
[1266874889.709] 00000.00000> project: MAGENTA_QEMU_RISCV_RV64
[1266874889.709] 00000.00000> buildid: GIT_0FBB50D3A8FC1D242E1D7A2921674579C9192D66_DIRTY_LOCAL
[1266874889.709] 00000.00000> ELF build ID: be2909891fc4cce74084f5fa3f14d6e98903d3bb
[1266874889.709] 00000.00000> INIT: cpu 0, calling hook 0xffffffff80042f0c (vm_preheap) at level 0x3ffff, flags 0x1
[1266874889.709] 00000.00000> initializing heap
[1266874889.709] 00000.00000> INIT: cpu 0, calling hook 0xffffffff8004305c (vm) at level 0x50000, flags 0x1
[1266874889.709] 00000.00000> VM: reserving kernel region [ffffffff80000000, ffffffff800f7000) flags 0x28 name 'kernel_code'
[1266874889.709] 00000.00000> VM: reserving kernel region [ffffffff800f7000, ffffffff80139000) flags 0x8 name 'kernel_rodata'
[1266874889.709] 00000.00000> VM: reserving kernel region [ffffffff80139000, ffffffff8013c000) flags 0x18 name 'kernel_data'
[1266874889.709] 00000.00000> VM: reserving kernel region [ffffffff8013c000, ffffffff80166000) flags 0x18 name 'kernel_bss'
[1266874889.709] 00000.00000> VM: reserving kernel region [ffffffff8016a000, ffffffff8114b000) flags 0x18 name 'kernel_bootalloc'
[1266874889.709] 00000.00000> INIT: cpu 0, calling hook 0xffffffff8000197c (timer) at level 0x50003, flags 0x1
[00003.966] 00000.00000> initializing mp
[00003.966] 00000.00000> initializing threads
[00003.967] 00000.00000> initializing timers
[00003.967] 00000.00000> INIT: cpu 0, calling hook 0xffffffff800132d4 (debuglog) at level 0x6ffff, flags 0x1
[00003.970] 00000.00000> INIT: cpu 0, calling hook 0xffffffff8006e448 (global_prng_thread_safe) at level 0x6ffff, flags 0x1
[00003.971] 00000.00000> creating bootstrap completion thread
[00004.057] 00000.00000> top of bootstrap2()
[00004.058] 00000.00000> INIT: cpu 0, calling hook 0xffffffff80070c9c (dpc) at level 0x70000, flags 0x1
[00004.064] 00000.00000> INIT: cpu 0, calling hook 0xffffffff8009158c (magenta) at level 0x70000, flags 0x1
[00004.078] 00000.00000> initializing platform
[00004.078] 00000.00000> initializing target
[00004.078] 00000.00000> calling apps_init()
[00004.078] 00000.00000> INIT: cpu 0, calling hook 0xffffffff80014464 (ktrace) at level 0xaffff, flags 0x1
[00005.091] 00000.00000> ktrace: buffer at 0xffffffc000e01000 (33554432 bytes)
[00005.094] 00000.00000> INIT: cpu 0, calling hook 0xffffffff800384bc (userboot) at level 0xaffff, flags 0x1
[00005.161] 00000.00000> userboot: userboot rodata 0 @ [0x292f043000,0x292f045000)
[00005.163] 00000.00000> userboot: userboot code 0x2000 @ [0x292f045000,0x292f05a000)
[00005.165] 00000.00000> userboot: vdso/full rodata 0 @ [0x292f05a000,0x292f05f000)
[00005.167] 00000.00000> userboot: vdso/full code 0x5000 @ [0x292f05f000,0x292f061000)
[00005.193] 00000.00000> userboot: entry point @ 0x292f046da0
[00005.293] 00000.00000> starting app shell
] [00005.296] 00000.00000> entering main console loop
static inline void riscv_switch_to(struct riscv_thread_state * prev,
struct riscv_thread_state * next)
{
__switch_to_aux(prev, next);
__switch_to(prev, next);
assert(get_current());
}
riscv_thread_state
structure./*
* Integer register context switch
* The callee-saved registers must be saved and restored.
*
* a0: previous task_struct (must be preserved across the switch)
* a1: next task_struct
*/
.section .text
FUNCTION(__switch_to)
/*
* $a0 == &prev->arch.stat
* $a1 == &next->arch.stat
*/
/* Save context into prev->arch.state */
REG_S ra, THREAD_RA(a0)
REG_S sp, THREAD_SP(a0)
REG_S s0, THREAD_S0(a0)
REG_S s1, THREAD_S1(a0)
REG_S s2, THREAD_S2(a0)
REG_S s3, THREAD_S3(a0)
REG_S s4, THREAD_S4(a0)
REG_S s5, THREAD_S5(a0)
REG_S s6, THREAD_S6(a0)
REG_S s7, THREAD_S7(a0)
REG_S s8, THREAD_S8(a0)
REG_S s9, THREAD_S9(a0)
REG_S s10, THREAD_S10(a0)
REG_S s11, THREAD_S11(a0)
/* Restore context from next->arch.state */
REG_L ra, THREAD_RA(a1)
REG_L sp, THREAD_SP(a1)
REG_L s0, THREAD_S0(a1)
REG_L s1, THREAD_S1(a1)
REG_L s2, THREAD_S2(a1)
REG_L s3, THREAD_S3(a1)
REG_L s4, THREAD_S4(a1)
REG_L s5, THREAD_S5(a1)
REG_L s6, THREAD_S6(a1)
REG_L s7, THREAD_S7(a1)
REG_L s8, THREAD_S8(a1)
REG_L s9, THREAD_S9(a1)
REG_L s10, THREAD_S10(a1)
REG_L s11, THREAD_S11(a1)
REG_L tp, THREAD_TI(a1) /* Next thread_info pointer */
/*return to $ra, the new $sp has been set*/
ret
END(__switch_to)
$ra
points to the next instruction after a call to __switch_to
inside riscv_switch_to
(gdb) p/x newthread->arch.state
$137 = {ra = 0xffffffff80002f3c, sp = 0xffffffff8114cc80, s = {0xffffffff8114ccb0, 0xffffffff800031c4, 0x1, 0xffffffff800347f8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, fstate = {f = {
0x0 <repeats 32 times>}, fcsr = 0x0}, ti = 0xffffffff8114ae80}
ret
instruction at the end of __switch_to
resumes a thread at this address.$ra
pointing to same address.(gdb) p/x oldthread->arch.state
$138 = {ra = 0xffffffff8000b3f8, sp = 0xffffffc002e04000, s = {0x0 <repeats 12 times>}, fstate = {f = {0x0 <repeats 32 times>}, fcsr = 0x0}, ti = 0xffffffff8116a9d8}
riscv_switch_to
disassembled listing is(gdb) disassem 0xffffffff80002f3c
Dump of assembler code for function riscv_switch_to:
0xffffffff80002f04 <+0>: addi sp,sp,-48
0xffffffff80002f08 <+4>: sd ra,40(sp)
0xffffffff80002f0c <+8>: sd s0,32(sp)
0xffffffff80002f10 <+12>: sd s1,24(sp)
0xffffffff80002f14 <+16>: addi s0,sp,48
0xffffffff80002f18 <+20>: mv s1,ra
0xffffffff80002f1c <+24>: sd a0,-40(s0)
0xffffffff80002f20 <+28>: sd a1,-48(s0)
0xffffffff80002f24 <+32>: ld a1,-48(s0)
0xffffffff80002f28 <+36>: ld a0,-40(s0)
0xffffffff80002f2c <+40>: jal ra,0xffffffff80002ee0 <__switch_to_aux>
0xffffffff80002f30 <+44>: ld a1,-48(s0)
0xffffffff80002f34 <+48>: ld a0,-40(s0)
0xffffffff80002f38 <+52>: jal ra,0xffffffff800003a8 <__switch_to>
0xffffffff80002f3c <+56>: jal ra,0xffffffff80002e70 <get_current>
0xffffffff80002f40 <+60>: mv a5,a0
0xffffffff80002f44 <+64>: seqz a5,a5
0xffffffff80002f48 <+68>: andi a5,a5,255
0xffffffff80002f4c <+72>: beqz a5,0xffffffff80002f78 <riscv_switch_to+116>
0xffffffff80002f50 <+76>: mv a0,s1
0xffffffff80002f54 <+80>: mv a1,s0
0xffffffff80002f58 <+84>: lui a5,0x800f2
0xffffffff80002f5c <+88>: addi a5,a5,1880 # 0xffffffff800f2758
0xffffffff80002f60 <+92>: li a4,34
0xffffffff80002f64 <+96>: lui a3,0x800f2
0xffffffff80002f68 <+100>: addi a3,a3,1896 # 0xffffffff800f2768
0xffffffff80002f6c <+104>: lui a2,0x800f2
0xffffffff80002f70 <+108>: addi a2,a2,1840 # 0xffffffff800f2730
0xffffffff80002f74 <+112>: jal ra,0xffffffff8006b9f0 <_panic>
0xffffffff80002f78 <+116>: nop
0xffffffff80002f7c <+120>: ld ra,40(sp)
0xffffffff80002f80 <+124>: ld s0,32(sp)
0xffffffff80002f84 <+128>: ld s1,24(sp)
0xffffffff80002f88 <+132>: addi sp,sp,48
0xffffffff80002f8c <+136>: ret
0xffffffff80002f3c
is an address of a call to get_current
which is a parameter to the assert
check after a call to __switch_to
.#2 0xffffffff80004690 in arch_mmu_init_aspace (aspace=0xffffffff81168310, base=16777216, size=274861125632, flags=0) at kernel/arch/riscv/mmu.cpp:73
#3 0xffffffff8004bb64 in VmAspace::Init (this=0xffffffff811681c0) at kernel/kernel/vm/vm_aspace.cpp:142
#4 0xffffffff8004bdb0 in VmAspace::Create (flags=0, name=0x0) at kernel/kernel/vm/vm_aspace.cpp:180
#5 0xffffffff8008f7e0 in ProcessDispatcher::Initialize (this=0xffffffff81167eb0) at kernel/lib/magenta/process_dispatcher.cpp:147
#6 0xffffffff8008ef30 in ProcessDispatcher::Create (job=..., name=..., flags=0, dispatcher=0xffffffff81146e48, rights=0xffffffff81146e3c, root_vmar_disp=0xffffffff81146e40,
root_vmar_rights=0xffffffff81146e38) at kernel/lib/magenta/process_dispatcher.cpp:73
#7 0xffffffff80032b84 in attempt_userboot () at kernel/lib/userboot/userboot.cpp:283
#8 0xffffffff800330ec in userboot_init (level=720895) at kernel/lib/userboot/userboot.cpp:357
#9 0xffffffff80005da8 in lk_init_level (required_flag=LK_INIT_FLAG_PRIMARY_CPU, start_level=655360, stop_level=720895) at kernel/top/init.c:86
#10 0xffffffff80005e4c in lk_primary_cpu_init_level (start_level=655360, stop_level=720895) at kernel/include/lk/init.h:51
#11 0xffffffff800060fc in bootstrap2 (arg=0x0) at kernel/top/main.c:136
#12 0xffffffff8000a78c in initial_thread_func () at kernel/kernel/thread.c:84
#13 0xffffffff8000a74c in init_thread_struct (t=0xffffffff81144be0, name=0x0) at kernel/kernel/thread.c:72