Signed bitcode values emitted as unsigned C
Rellic will sometimes forget signedess and emit unsigned casts for signed integers. Simple example below:
signed.c:
#include <stdbool.h>
bool signed_less_than_1(signed short v) {
return v < 1;
}
Compile:
clang-11 -O1 -std=c99 -emit-llvm -c -o signed.bc signed.c
Rellic:
rellic-decomp-11.0 --input signed.bc --output signed_decomp.c
Output:
unsigned char signed_less_than_1(unsigned short arg0);
unsigned char signed_less_than_1(unsigned short arg0) {
return (arg0 < (unsigned short)1U);
}
The bitcode in question performs a signed compare, and rellic should emit a signed compare as well:
define dso_local zeroext i1 @signed_less_than_1(i16 signext %0) local_unnamed_addr #0 {
%2 = icmp slt i16 %0, 1
ret i1 %2
}
Resolved by #121
Unfortunately I haven't found a good way of regression testing this one using our executable roundtrip tests, because we don't have type inference.
I might just be out of the loop, but it seems that the issue still exists; after building 356ecb16bc7a1eb4e34989b5765e3a011fdcbc0e and reproducing the test case, the LLVM IR is identical to before:
define dso_local zeroext i1 @signed_less_than_1(i16 signext %0) local_unnamed_addr #0 {
%2 = icmp slt i16 %0, 1
ret i1 %2
}
while the produced roundtrip code is slightly different, but still with the wrong type signature:
unsigned char signed_less_than_1(unsigned short arg0);
unsigned char signed_less_than_1(unsigned short arg0) {
return (short)arg0 < 1;
}