Wrong LLVM IR parameters after decompilation
- Dominant language
- C++
- Stars
- 8.6k
- Forks
- 1k
- PR merge metrics
- No merged PRs in 30d
Description
I noticed a problem while decompiling simple functions in different files (I pulled and build RetDec an hour before creating the issue for being certain to have the latest version).
Here is the code I tried to decompile:
**simple.c**
```c
uint32_t simple_add(uint32_t *a, uint32_t *b) {
return *a + *b;
}
```
**main.c**
```c
#include "simple.h"
int main(int argc, char** argv) {
uint32_t a, b;
a = atoi(argv[1]);
b = atoi(argv[2]);
return simple_add(&a, &b);
}
```
The code was compiled with the command (GCC 6.3.0 20170516):
```bash
gcc -std=c99 -Wall -Werror -pedantic -m32 main.c simple.c -o main
```
Then I invoked the following command to decompile the binary:
```bash
./retdec-decompiler.sh --stop-after bin2llvmir --select-functions simple_add ./main
```
Here's the LLVM IR output code after decompilation:
**main.c.backend.ll**
```LLVM
source_filename = "test"
target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
define i32 @simple_add(i32* %arg1, i32 %arg2) local_unnamed_addr {
entry:
%v0_593 = call i32 @__x86.get_pc_thunk.ax()
%v2_5a0 = load i32, i32* %arg1, align 4
%v1_5a5 = inttoptr i32 %arg2 to i32*
%v2_5a5 = load i32, i32* %v1_5a5, align 4
%v2_5a7 = add i32 %v2_5a5, %v2_5a0
ret i32 %v2_5a7
}
declare i32 @__x86.get_pc_thunk.ax() local_unnamed_addr
declare i32 @__decompiler_undefined_function_0() local_unnamed_addr
```
As you can see, the decompiler interpreted the first parameter as an `i32*`, which is ok but the second one is interpreted as an `i32` and then is cast to an `i32*` in the method's body. I also tried with three parameters and the result is the same: only the first parameter is interpreted correctly.
Did I miss something or is it a bug?
Thanks in advance for your time.
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the issue with simple.c and main.c using the shown GCC and retdec-decompiler.sh --stop-after bin2llvmir command, then inspect main.c.backend.ll. Start at the bin2llvmir parameter-recovery path and compare the recovered types for simple_add; done means each pointer argument is represented as a pointer in the function signature without an incorrect integer-to-pointer cast.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cpp
- Domain
- compilers, reverse-engineering
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100