---
# System prepended metadata

title: Untitled

---

For some context, here is the original C++ function:
```C++
struct Dummy {
    long i;
    long j;
    long k;
};

void dummy_function(struct Dummy& dummy, long i, long j, long k) {
    dummy.i = i; 
    dummy.j = j; 
    dummy.k = k;
}
```

Decompiled Ouput:
```
; Function Attrs: noinline nounwind ssp
define void @"dummy_function(Dummy&, long, long, long)"({ i64, i64, i64 }* nocapture %dummy, i64 %i, i64 %j, i64 %k) local_unnamed_addr #0 {
  %1 = tail call i8* @llvm.returnaddress(i32 0)
  %2 = ptrtoint i8* %1 to i64
  %3 = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* %dummy, i64 0, i32 0
  store i64 %k, i64* %3, align 8
  %4 = tail call %struct.Memory* @__remill_function_return(%struct.State* nonnull undef, i64 %2, %struct.Memory* null) #3
  ret void
}
```

Reference Output:
```
; Function Attrs: noinline norecurse nounwind ssp uwtable writeonly
define void @_Z14dummy_functionR5Dummylll(%struct.Dummy* nocapture dereferenceable(24), i64, i64, i64) local_unnamed_addr #5 !dbg !2476 {
  call void @llvm.dbg.value(metadata %struct.Dummy* %0, metadata !2486, metadata !DIExpression()), !dbg !2490
  call void @llvm.dbg.value(metadata i64 %1, metadata !2487, metadata !DIExpression()), !dbg !2491
  call void @llvm.dbg.value(metadata i64 %2, metadata !2488, metadata !DIExpression()), !dbg !2492
  call void @llvm.dbg.value(metadata i64 %3, metadata !2489, metadata !DIExpression()), !dbg !2493
  %5 = getelementptr inbounds %struct.Dummy, %struct.Dummy* %0, i64 0, i32 0, !dbg !2494
  store i64 %1, i64* %5, align 8, !dbg !2495, !tbaa !2496
  %6 = getelementptr inbounds %struct.Dummy, %struct.Dummy* %0, i64 0, i32 1, !dbg !2498
  store i64 %2, i64* %6, align 8, !dbg !2499, !tbaa !2500
  %7 = getelementptr inbounds %struct.Dummy, %struct.Dummy* %0, i64 0, i32 2, !dbg !2501
  store i64 %3, i64* %7, align 8, !dbg !2502, !tbaa !2503
  ret void, !dbg !2504
}
```

This might be just me but it doesn't look right. In the decompiled case, it seems like we are only assigning the third element of the struct. In fact, there are no references to `%i` and `%j` which makes me wonder. Here is the full command and full json file if you want to reproduce my result:

```bash
anvill-decompile-json-9.0 --spec test.json --bc_out test.bc --ir_out test.ll
```

hello.json:
```json=
{
    "arch": "amd64",
    "functions": [
        {
            "name": "dummy_function(Dummy&, long, long, long)",
            "address": 0,
            "parameters": [
                {
                    "name": "dummy",
                    "register": "RDI",
                    "type": "*{lll}"
                },
                {
                    "name": "i",
                    "register": "RSI",
                    "type": "l"
                },
                {
                    "name": "j",
                    "register": "RDX",
                    "type": "l"
                },
                {
                    "name": "k",
                    "register": "RCX",
                    "type": "l"
                }
            ],
            "return_stack_pointer": {
                "offset": 8,
                "register": "RSP",
                "type": "l"
            },
            "return_address": {
                "memory": {
                    "register": "RSP"
                },
                "type": "I"
            },
            "return_values": []
        }
    ],
    "memory": [
        {
            "address": 0,
            "data": "554889E54889374889570848894F105DC3",
            "is_readable": true,
            "is_executable": true
        }
    ],
    "stack": {
        "address": 12288,
        "size": 24576,
        "start_offset": 4096
    },
    "os": "macos"
}
```

But the good news is that if I use the decompiled bitcode file as input to my bitcode specifier, I get back the same JSON specification file :smile:, so at least that works. But I don't think the lifting is correct in this case. The opcodes for the function are in the data section of the json at line 46. Here is the binja disassembly for convenience:

```
dummy_function:
100000cd0  55                 push    rbp {__saved_rbp}
100000cd1  4889e5             mov     rbp, rsp {__saved_rbp}
100000cd4  488937             mov     qword [rdi], rsi
100000cd7  48895708           mov     qword [rdi+0x8], rdx
100000cdb  48894f10           mov     qword [rdi+0x10], rcx
100000cdf  5d                 pop     rbp {__saved_rbp}
100000ce0  c3                 retn     {__return_addr}
```

P.S. I used bad values for the "stack" element on line 51, not sure if that matters or not. It seemed to me like it didn't matter so I used the values from the example.

---

Output from remill-lift:
```
; ModuleID = 'lifted_code'
source_filename = "lifted_code"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx-macho"

%struct.State = type { %struct.ArchState, [32 x %union.VectorReg], %struct.ArithFlags, %union.anon, %struct.Segments, %struct.AddressSpace, %struct.GPR, %struct.X87Stack, %struct.MMX, %struct.FPUStatusFlags, %union.anon, %union.FPU, %struct.SegmentCaches }
%struct.ArchState = type { i32, i32, %union.anon }
%union.VectorReg = type { %union.vec512_t }
%union.vec512_t = type { %struct.uint64v8_t }
%struct.uint64v8_t = type { [8 x i64] }
%struct.ArithFlags = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 }
%struct.Segments = type { i16, %union.SegmentSelector, i16, %union.SegmentSelector, i16, %union.SegmentSelector, i16, %union.SegmentSelector, i16, %union.SegmentSelector, i16, %union.SegmentSelector }
%union.SegmentSelector = type { i16 }
%struct.AddressSpace = type { i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg }
%struct.Reg = type { %union.anon }
%struct.GPR = type { i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg, i64, %struct.Reg }
%struct.X87Stack = type { [8 x %struct.anon.3] }
%struct.anon.3 = type { i64, double }
%struct.MMX = type { [8 x %struct.anon.4] }
%struct.anon.4 = type { i64, %union.vec64_t }
%union.vec64_t = type { %struct.uint64v1_t }
%struct.uint64v1_t = type { [1 x i64] }
%struct.FPUStatusFlags = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, [4 x i8] }
%union.anon = type { i64 }
%union.FPU = type { %struct.anon.13 }
%struct.anon.13 = type { %struct.FpuFXSAVE, [96 x i8] }
%struct.FpuFXSAVE = type { %union.SegmentSelector, %union.SegmentSelector, %union.FPUAbridgedTagWord, i8, i16, i32, %union.SegmentSelector, i16, i32, %union.SegmentSelector, i16, %union.FPUControlStatus, %union.FPUControlStatus, [8 x %struct.FPUStackElem], [16 x %union.vec128_t] }
%union.FPUAbridgedTagWord = type { i8 }
%union.FPUControlStatus = type { i32 }
%struct.FPUStackElem = type { %union.anon.11, [6 x i8] }
%union.anon.11 = type { %struct.float80_t }
%struct.float80_t = type { [10 x i8] }
%union.vec128_t = type { %struct.uint128v1_t }
%struct.uint128v1_t = type { [1 x i128] }
%struct.SegmentCaches = type { %struct.SegmentShadow, %struct.SegmentShadow, %struct.SegmentShadow, %struct.SegmentShadow, %struct.SegmentShadow, %struct.SegmentShadow }
%struct.SegmentShadow = type { %union.anon, i32, i32 }
%struct.Memory = type opaque

; Function Attrs: noinline nounwind ssp
define dso_local %struct.Memory* @sub_0(%struct.State* noalias dereferenceable(3376), i64, %struct.Memory* noalias) local_unnamed_addr #0 {
  %4 = getelementptr inbounds %struct.State, %struct.State* %0, i64 0, i32 6, i32 5, i32 0, i32 0
  %5 = getelementptr inbounds %struct.State, %struct.State* %0, i64 0, i32 6, i32 7, i32 0, i32 0
  %6 = getelementptr inbounds %struct.State, %struct.State* %0, i64 0, i32 6, i32 9, i32 0, i32 0
  %7 = getelementptr inbounds %struct.State, %struct.State* %0, i64 0, i32 6, i32 11, i32 0, i32 0
  %8 = getelementptr inbounds %struct.State, %struct.State* %0, i64 0, i32 6, i32 13, i32 0, i32 0
  %9 = getelementptr inbounds %struct.State, %struct.State* %0, i64 0, i32 6, i32 15, i32 0, i32 0
  %10 = getelementptr inbounds %struct.State, %struct.State* %0, i64 0, i32 6, i32 33, i32 0, i32 0
  %11 = load i64, i64* %9, align 8
  %12 = load i64, i64* %8, align 8, !tbaa !0
  %13 = add i64 %12, -8
  %14 = tail call %struct.Memory* @__remill_write_memory_64(%struct.Memory* %2, i64 %13, i64 %11) #3
  %15 = load i64, i64* %7, align 8
  %16 = load i64, i64* %6, align 8
  %17 = tail call %struct.Memory* @__remill_write_memory_64(%struct.Memory* %14, i64 %15, i64 %16) #3
  %18 = add i64 %15, 8
  %19 = load i64, i64* %5, align 8
  %20 = tail call %struct.Memory* @__remill_write_memory_64(%struct.Memory* %17, i64 %18, i64 %19) #3
  %21 = add i64 %15, 16
  %22 = load i64, i64* %4, align 8
  %23 = tail call %struct.Memory* @__remill_write_memory_64(%struct.Memory* %20, i64 %21, i64 %22) #3
  %24 = tail call i64 @__remill_read_memory_64(%struct.Memory* %23, i64 %13) #3
  store i64 %24, i64* %9, align 8, !tbaa !3
  %25 = tail call i64 @__remill_read_memory_64(%struct.Memory* %23, i64 %12) #3
  store i64 %25, i64* %10, align 8, !tbaa !3
  %26 = add i64 %12, 8
  store i64 %26, i64* %8, align 8, !tbaa !3
  %27 = tail call %struct.Memory* @__remill_function_return(%struct.State* nonnull %0, i64 %25, %struct.Memory* %23)
  ret %struct.Memory* %27
}

; Function Attrs: noduplicate noinline nounwind optnone readnone
declare %struct.Memory* @__remill_write_memory_64(%struct.Memory*, i64, i64) #1

; Function Attrs: noduplicate noinline nounwind optnone readnone
declare i64 @__remill_read_memory_64(%struct.Memory*, i64) #1

; Function Attrs: noduplicate noinline nounwind optnone
declare %struct.Memory* @__remill_function_return(%struct.State* dereferenceable(3376), i64, %struct.Memory*) #2

attributes #0 = { noinline nounwind ssp "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { noduplicate noinline nounwind optnone readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { noduplicate noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #3 = { nobuiltin nounwind readnone }

!0 = !{!1, !1, i64 0}
!1 = !{!"omnipotent char", !2, i64 0}
!2 = !{!"Simple C++ TBAA"}
!3 = !{!4, !4, i64 0}
!4 = !{!"long long", !1, i64 0}
```