Call to function disappeared in decompiled code
- Dominant language
- C++
- Stars
- 8.6k
- Forks
- 1k
- PR merge metrics
- No merged PRs in 30d
Description
The reproducing steps:
save the code below:
```cpp
#include
#include
void test1() {
printf("1");
exit(1);
}
void test2() {
printf("2");
}
int main(int argc, char *argv[]) {
test2();
return 0;
}
```
compile it and strip (strip is required otherwise retdec can correctly infer test2 as a function in early stages):
```shell
g++ bug.cpp -o bug_test && strip bug_test
```
use retdec-compiler:
```shell
./retdec-decompiler bug_test
```
In the result bug_test.c:
```cpp
// Address range: 0x1149 - 0x1161
// this is test1
int64_t function_1149(void) {
// 0x1149
putchar(49);
exit(1);
// UNREACHABLE
}
// Address range: 0x1161 - 0x1172
// this is test2
int64_t function_1161(void) {
// 0x1161
return putchar(50);
}
// Address range: 0x1172 - 0x118d
// this is main
int64_t function_1172(int64_t a1, int64_t a2) {
// 0x1172
return 0;
}
```
You can see the call to test2(function_1161) disappeared from main(function_1172).
After tracing the bug, it probably comes from:
https://github.com/avast/retdec/blob/18b434f02b64bfb85232525ca10a6026b5d1f54f/src/bin2llvmir/optimizations/decoder/decoder.cpp#L514-L544
The debugger says that tFnc and tTb are null pointers. It comes from:
https://github.com/avast/retdec/blob/18b434f02b64bfb85232525ca10a6026b5d1f54f/src/bin2llvmir/optimizations/decoder/ir_modifications.cpp#L211-L216
Where the code thinks it is in the middle of a basic block and not splitting it. The debug output says:
```
processing : 0x1172 (LEFTOVER) (CS_MODE_LITTLE_ENDIAN, CS_MODE_64)
found range = <0x1172, 0x1205)
S: createFunction() @ 0x1172
F: splitFunctionOn() @ 0x1172
translating = 0x1172
translating = 0x1173
translating = 0x1176
translating = 0x117a
translating = 0x117d
translating = 0x1181
S: ASM @ 0x1161
F: getBasicBlockContainingAddress() @ 0x1161
translating = 0x1186
translating = 0x118b
translating = 0x118c
```
The basic block map for reference:
```
(gdb) p/x _addr2bb
$5 = std::map with 30 elements = {[{address = 0x1003}] = 0x55555cbdfc70, [{address = 0x1014}] = 0x55555a7aa6c0, [{
address = 0x1016}] = 0x55555a781dd0, [{address = 0x1030}] = 0x55555cbdc650, [{address = 0x1040}] = 0x55555cbd68d0, [{
address = 0x1050}] = 0x555558984210, [{address = 0x1053}] = 0x55555a7adc20, [{address = 0x1093}] = 0x55555a7ae270, [{
address = 0x109f}] = 0x55555cbdff50, [{address = 0x10a8}] = 0x55555a7aa7a0, [{address = 0x10b0}] = 0x55555cbde840, [{
address = 0x10d4}] = 0x55555cbdfb00, [{address = 0x10e0}] = 0x55555a7ac860, [{address = 0x10e8}] = 0x55555a7ae220, [{
address = 0x10f3}] = 0x55555cbdfc20, [{address = 0x10fd}] = 0x55555cbdffa0, [{address = 0x110b}] = 0x55555cbd04f0, [{
address = 0x1118}] = 0x55555cbcc4d0, [{address = 0x111d}] = 0x55555cbd0770, [{address = 0x1130}] = 0x55555a78a880, [{
address = 0x1143}] = 0x55555cbd60c0, [{address = 0x1149}] = 0x55555cbd6110, [{address = 0x1172}] = 0x55555cbde770, [{
address = 0x3fd8}] = 0x55555a781e20, [{address = 0x3fe0}] = 0x55555a7aa2d0, [{address = 0x3fe8}] = 0x55555a7ab190, [{
address = 0x3ff0}] = 0x55555a7ad4f0, [{address = 0x3ff8}] = 0x55555cbdf9e0, [{address = 0x4018}] = 0x55555cbdfe30, [{
address = 0x4020}] = 0x55555a78a410}
```
FWIW function_1149 is placed right before function_1161 in assembly:
```asm
// test1
1149: 55 push %rbp
114a: 48 89 e5 mov %rsp,%rbp
114d: bf 31 00 00 00 mov $0x31,%edi
1152: e8 e9 fe ff ff call 1040
1157: bf 01 00 00 00 mov $0x1,%edi
115c: e8 cf fe ff ff call 1030
// test2
1161: 55 push %rbp
1162: 48 89 e5 mov %rsp,%rbp
1165: bf 32 00 00 00 mov $0x32,%edi
116a: e8 d1 fe ff ff call 1040
116f: 90 nop
1170: 5d pop %rbp
1171: c3 ret
// main
1172: 55 push %rbp
1173: 48 89 e5 mov %rsp,%rbp
1176: 48 83 ec 10 sub $0x10,%rsp
117a: 89 7d fc mov %edi,-0x4(%rbp)
117d: 48 89 75 f0 mov %rsi,-0x10(%rbp)
1181: e8 db ff ff ff call 1161
1186: b8 00 00 00 00 mov $0x0,%eax
118b: c9 leave
118c: c3 ret
```
The function at 1149 ends with an unreachable call instead of ret. And retdec is not recognizing 0x1161 as a basic block. Thus retdec is not working properly.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.