这是indexloc提供的服务,不要输入任何密码
Skip to content

Incorrectly typing ints as pointers #486

@sabastiaan

Description

@sabastiaan

While lifting curl compiled with O3 we encountered some results which we think is incorrect.
We have a function that does some simple calculations on two structs passed by value, with each struct containing just two signed 32-bit ints. The lifted code models these as pointers which should be incorrect.

Full cflags used during configuration: -O3 -fno-inline -fno-inline-functions -g

command used to generate the output:
revng artifact cleanup-ir --debug-names --analyze ./curl -o curl.zstd
src:

struct timeval
{
  long int tv_sec;
  long int tv_usec;
};

long tvdiff(struct timeval newer, struct timeval older)
{
  return (long)(newer.tv_sec-older.tv_sec)*1000+
    (long)(newer.tv_usec-older.tv_usec)/1000;
}

Object code:

0000000000021150 <tvdiff>:
   21150:       48 89 f0                mov    %rsi,%rax
   21153:       48 29 d7                sub    %rdx,%rdi
   21156:       48 29 c8                sub    %rcx,%rax
   21159:       48 b9 cf f7 53 e3 a5    movabs $0x20c49ba5e353f7cf,%rcx
   21160:       9b c4 20
   21163:       48 f7 e9                imul   %rcx
   21166:       48 69 cf e8 03 00 00    imul   $0x3e8,%rdi,%rcx
   2116d:       48 89 d0                mov    %rdx,%rax
   21170:       48 c1 e8 3f             shr    $0x3f,%rax
   21174:       48 c1 fa 07             sar    $0x7,%rdx
   21178:       48 01 d0                add    %rdx,%rax
   2117b:       48 01 c8                add    %rcx,%rax
   2117e:       c3                      ret
   2117f:       90                      nop

lifted code:

; Function Attrs: nomerge null_pointer_is_valid
define i64 @local_tvdiff(i64 %0, i64 %1) #0 !revng.tags !10 !revng.function.entry !11 {
newFuncRoot:
  %2 = inttoptr i64 %0 to ptr
  %3 = load i64, ptr %2, align 8
  %4 = add i64 %0, 8
  %5 = inttoptr i64 %4 to ptr
  %6 = load i64, ptr %5, align 8
  %7 = inttoptr i64 %1 to ptr
  %8 = load i64, ptr %7, align 8
  %9 = add i64 %1, 8
  %10 = inttoptr i64 %9 to ptr
  %11 = load i64, ptr %10, align 8
  %12 = sub i64 %3, %8, !dbg !12
  %13 = sub i64 %6, %11, !dbg !18
  %14 = sext i64 %13 to i128, !dbg !20
  %15 = mul nsw i128 %14, 2361183241434822607, !dbg !20
  %16 = lshr i128 %15, 64, !dbg !20
  %17 = trunc i128 %16 to i64, !dbg !20
  %18 = mul i64 %12, 1000, !dbg !22
  %19 = lshr i64 %17, 63, !dbg !24
  %20 = ashr i64 %17, 7, !dbg !26
  %21 = add nsw i64 %19, %20, !dbg !28
  %22 = add i64 %21, %18, !dbg !30
  ret i64 %22, !dbg !32
}

attributes #0 = { nomerge null_pointer_is_valid }
...

Versions:

revng --version rev.ng version c246137
clang --version
Ubuntu clang version 18.1.3 (1ubuntu1)
Target: x86_64-pc-linux-gnu

Artifacts can be found here, including the ELF binary, full revng output and the ir for the function in question:
curl.zip

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions