英文:
Where does LLVM translate UnreachableInst into abort function call?
问题
I am searching where is UnreachableInst translated into _abort call.
Below is the story.
I'm currently trying for Rust to be available for Renesas RL78 target. To end this, I got LLVM source code from Open Source Tools for Renesas and used it as a backend for the rustc compiler.
First, I wrote code with only the main function. This code compiled without errors and had no problems as far as I could see in the binary content.
Note that this is a partial code; the actual code has attributes like #![no_main]
and essential components like a panic handler.
#[no_mangle]
pub unsafe extern "C" fn main() -> ! {
loop {}
}
However, if I write and use the #[entry]
proc macro like the cortex-m crate has, I get 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 added a dummy abort function and added a .plt
section to a linker script because the linker requires it too. I retried compilation, and it succeeded.
I investigated the binary and found that the _abort
call is placed after the rust main call, as shown below.
00000085 _main:
85: fc 81 00 00 call !!__ZN15renesas_program11__rl78_main17h608e5bb48d9d4215E
89: fd 80 00 call !_abort
I also investigated the LLVM IR that rustc generated and found an 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, the _abort
call is already inserted. This is why I suspect that LLVM translates Unreachable into an abort call, and the linker and Rustc do not do anything.
00000000 _main:
0: fc 00 00 00 call !!0x0
4: fd 00 00 call !0x0
As I mentioned above, this LLVM is a custom version of LLVM 10 for Renesas RL78, so this problem may be from the custom version. However, I cannot find the cause from the diff between the original and custom versions.
I know it is the best and a good chance to study LLVM internals, so I am currently learning it now. However, I want to know where the problem is.
Please tell me what is the problem.
英文:
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
答案1
得分: 2
SelectionDAGBuilder::visitUnreachable
是 UnreachableInst
被转化为 ISD::TRAP
的地方。SelectionDAGLegalize::ConvertNodeToLibcall
是 ISD::TRAP
被降低为 abort()
的地方。
英文:
SelectionDAGBuilder::visitUnreachable
is where UnreachableInst
turns into ISD::TRAP
. SelectionDAGLegalize::ConvertNodeToLibcall
is where ISD::TRAP
is lowered as abort().
答案2
得分: 1
可能不会。
每个LLVM基本块都必须以终结指令结尾,unreachable
是其中之一,这一要求经常被检查并严格执行。另一方面,call
不是终结指令。因此,创建一个调用abort()的代码通常会在该call
之后跟随一个unreachable
。
英文:
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论