I am searching where is UnreachableInst translated into _abort call.
Below is the story.
I'm currenly trying for Rust to be avaiable for Renesas RL78 target. To end this, I got a LLVM source code from Open Source Tools for Renesas, and use that as a backend of rustc compiler.
First, I wrote code with only main function. This code is compiled without errors and no problems as far as I look the binary content.
Note that this is a partial code, actual code has attributes like #![no_main]
and essential components like panic handler.
#[no_mangle]
pub unsafe extern "C" fn main() -> ! {
loop {}
}
However, If I write and use #[entry]
proc macro like cortex-m crate has, I got an error below.
#[rl78_macros::entry]
fn main() -> ! {
loop {}
}
lld: error: undefined symbol: _abort
>>> referenced by main.rs:26 (src/main.rs:26)
>>> /home/vmuser/Documents/renesas/renesas-program/target/rl78/debug/deps/renesas_program-916d6430e40e98ae.3a31hiwjtkbq95rf.rcgu.o:(_main)
I add dummy abort function and add .plt
section to a linker script because linker requires it too.
I retried compile and it successed.
I investigate the binary and I found that _abort call put after rust main call as I show below.
00000085 _main:
85: fc 81 00 00 call !!__ZN15renesas_program11__rl78_main17h608e5bb48d9d4215E
89: fd 80 00 call !_abort
I also investigated llvm ir rustc generated, and there is unreachable statement.
define dso_local void @main() unnamed_addr addrspace(2) #0 !dbg !183 {
start:
; call renesas_program::__rl78_main
call addrspace(2) void @_ZN15renesas_program11__rl78_main17h608e5bb48d9d4215E() #4, !dbg !184
unreachable, !dbg !184
}
In the object file rustc generated, _abort call is already inserted. This is why, I suspect that LLVM translate Unreachable into abort call, and Linker and Rustc do not anything.
00000000 _main:
0: fc 00 00 00 call !!0x0
4: fd 00 00 call !0x0
Like I said above, this LLVM is custom version of LLVM 10 for Renesas RL78, so this problem may be from a custom, but I cannot find the cause from diff of original and custom one.
I know it is the best and a good chance to study llvm internal, so I currently learn it now. However, I want to know where is the problem also.
Please tell me what is the problem
It probably doesn't.
Every LLVM basic block has to end with a terminator instruction, unreachable
is one of those, and that requirement is checked often and enforced mercilessly. A call
, on the other hand, is not a terminator. Because of this, code that creates a call to abort() will typically follow that call
with an unreachable
.