#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
struct sockaddr_ll {
  int /*<<< orphan*/ sll_protocol;
  int /*<<< orphan*/ sll_family;
  int /*<<< orphan*/ sll_ifindex;
  struct ifaddrs *sll_addr;
};
struct sockaddr {
  int dummy;
};
struct ifaddrs {
  struct ifaddrs *ifa_dstaddr;
  struct ifaddrs *ifa_name;
  struct ifaddrs *ifa_addr;
};

/* Variables and functions */
int /*<<< orphan*/ AF_PACKET;
int /*<<< orphan*/ ETH_P_ARP;
struct ifaddrs *find_mac_addr(struct ifaddrs *, struct ifaddrs *);
int /*<<< orphan*/ htons(int /*<<< orphan*/);
int /*<<< orphan*/ if_nametoindex(struct ifaddrs *);
void *malloc(int);
int /*<<< orphan*/ memcpy(struct ifaddrs *, struct ifaddrs *, int);
int strlen(struct ifaddrs *);
int init_ifaddr(struct ifaddrs *ifaddr, struct ifaddrs *local,
                struct ifaddrs *ifa) {
  memcpy(local, ifa, sizeof(struct ifaddrs));
  local->ifa_addr = malloc(sizeof(struct sockaddr_ll));
  memcpy(local->ifa_addr, ifa->ifa_addr, sizeof(struct sockaddr));
  int ifa_name_len = strlen(ifa->ifa_name) + 1;
  local->ifa_name = malloc(ifa_name_len);
  memcpy(local->ifa_name, ifa->ifa_name, ifa_name_len);
  local->ifa_dstaddr = malloc(sizeof(struct sockaddr_ll));
  memcpy(local->ifa_dstaddr, local->ifa_addr, sizeof(struct sockaddr));
  struct ifaddrs *mac_ifaddr = find_mac_addr(ifaddr, ifa);
  if (mac_ifaddr)
    memcpy(((struct sockaddr_ll *)((local)->ifa_addr))->sll_addr,
           ((struct sockaddr_ll *)((mac_ifaddr)->ifa_addr))->sll_addr, 6);
  ((struct sockaddr_ll *)local->ifa_dstaddr)->sll_ifindex =
      if_nametoindex(local->ifa_name);
  ((struct sockaddr_ll *)local->ifa_dstaddr)->sll_family = AF_PACKET;
  ((struct sockaddr_ll *)local->ifa_dstaddr)->sll_protocol = htons(ETH_P_ARP);
  return 1;
}


x86 assembly (clang, -O0):
<init_ifaddr>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    $0x18,%edx
call   1070 <memcpy@plt>
mov    $0x18,%edi
call   1080 <malloc@plt>
mov    %rax,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,0x10(%rax)
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rdi
mov    -0x18(%rbp),%rax
mov    0x10(%rax),%rsi
mov    $0x4,%edx
call   1070 <memcpy@plt>
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%rdi
call   1040 <strlen@plt>
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%edi
call   1080 <malloc@plt>
mov    %rax,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,0x8(%rax)
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%rsi
mov    -0x1c(%rbp),%edx
call   1070 <memcpy@plt>
mov    $0x18,%edi
call   1080 <malloc@plt>
mov    %rax,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x10(%rbp),%rax
mov    (%rax),%rdi
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rsi
mov    $0x4,%edx
call   1070 <memcpy@plt>
mov    -0x8(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1030 <find_mac_addr@plt>
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     125e <init_ifaddr+0xfe>
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rax
mov    0x10(%rax),%rdi
mov    -0x28(%rbp),%rax
mov    0x10(%rax),%rax
mov    0x10(%rax),%rsi
mov    $0x6,%edx
call   1070 <memcpy@plt>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   1060 <if_nametoindex@plt>
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %ecx,0x8(%rax)
mov    0x2d62(%rip),%rax
mov    (%rax),%ecx
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %ecx,0x4(%rax)
mov    0x2d47(%rip),%rax
mov    (%rax),%edi
call   1050 <htons@plt>
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %ecx,(%rax)
mov    $0x1,%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<init_ifaddr>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %rdx,%r14
mov    %rsi,%rbx
mov    %rdi,%r15
mov    %rsi,%rdi
mov    %rdx,%rsi
mov    $0x18,%edx
call   1070 <memcpy@plt>
mov    $0x18,%edi
call   1080 <malloc@plt>
mov    %rax,0x10(%rbx)
mov    0x10(%r14),%rsi
mov    %rax,%rdi
mov    $0x4,%edx
call   1070 <memcpy@plt>
mov    0x8(%r14),%rdi
call   1040 <strlen@plt>
lea    0x1(%rax),%ebp
mov    %ebp,%edi
call   1080 <malloc@plt>
mov    %rax,0x8(%rbx)
mov    0x8(%r14),%rsi
mov    %rax,%rdi
mov    %ebp,%edx
call   1070 <memcpy@plt>
mov    $0x18,%edi
call   1080 <malloc@plt>
mov    %rax,(%rbx)
mov    0x10(%rbx),%rsi
mov    %rax,%rdi
mov    $0x4,%edx
call   1070 <memcpy@plt>
mov    %r15,%rdi
mov    %r14,%rsi
call   1030 <find_mac_addr@plt>
test   %rax,%rax
je     120c <init_ifaddr+0xac>
mov    0x10(%rbx),%rcx
mov    0x10(%rcx),%rdi
mov    0x10(%rax),%rax
mov    0x10(%rax),%rsi
mov    $0x6,%edx
call   1070 <memcpy@plt>
mov    0x8(%rbx),%rdi
call   1060 <if_nametoindex@plt>
mov    (%rbx),%rcx
mov    %eax,0x8(%rcx)
mov    0x2dbe(%rip),%rax
mov    (%rax),%eax
mov    %eax,0x4(%rcx)
mov    0x2daa(%rip),%rax
mov    (%rax),%edi
call   1050 <htons@plt>
mov    (%rbx),%rcx
mov    %eax,(%rcx)
mov    $0x1,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.ifaddrs = type { %struct.ifaddrs*, %struct.ifaddrs*, %struct.ifaddrs* }
%struct.sockaddr_ll = type { i32, i32, i32, %struct.ifaddrs* }
@AF_PACKET = global i32 0
@ETH_P_ARP = global i32 0
define i32 @init_ifaddr(%struct.ifaddrs* %0, %struct.ifaddrs* %1, %struct.ifaddrs* %2) {
%4 = alloca %struct.ifaddrs*
%5 = alloca %struct.ifaddrs*
%6 = alloca %struct.ifaddrs*
%7 = alloca i32
%8 = alloca %struct.ifaddrs*
store %struct.ifaddrs* %0, %struct.ifaddrs** %4
store %struct.ifaddrs* %1, %struct.ifaddrs** %5
store %struct.ifaddrs* %2, %struct.ifaddrs** %6
%9 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%10 = load %struct.ifaddrs*, %struct.ifaddrs** %6
%11 = call i32 @memcpy(%struct.ifaddrs* %9, %struct.ifaddrs* %10, i32 24)
%12 = call i8* @malloc(i32 24)
%13 = bitcast i8* %12 to %struct.ifaddrs*
%14 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%15 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %14, i32 0, i32 2
store %struct.ifaddrs* %13, %struct.ifaddrs** %15
%16 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%17 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %16, i32 0, i32 2
%18 = load %struct.ifaddrs*, %struct.ifaddrs** %17
%19 = load %struct.ifaddrs*, %struct.ifaddrs** %6
%20 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %19, i32 0, i32 2
%21 = load %struct.ifaddrs*, %struct.ifaddrs** %20
%22 = call i32 @memcpy(%struct.ifaddrs* %18, %struct.ifaddrs* %21, i32 4)
%23 = load %struct.ifaddrs*, %struct.ifaddrs** %6
%24 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %23, i32 0, i32 1
%25 = load %struct.ifaddrs*, %struct.ifaddrs** %24
%26 = call i32 @strlen(%struct.ifaddrs* %25)
%27 = add nsw i32 %26, 1
store i32 %27, i32* %7
%28 = load i32, i32* %7
%29 = call i8* @malloc(i32 %28)
%30 = bitcast i8* %29 to %struct.ifaddrs*
%31 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%32 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %31, i32 0, i32 1
store %struct.ifaddrs* %30, %struct.ifaddrs** %32
%33 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%34 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %33, i32 0, i32 1
%35 = load %struct.ifaddrs*, %struct.ifaddrs** %34
%36 = load %struct.ifaddrs*, %struct.ifaddrs** %6
%37 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %36, i32 0, i32 1
%38 = load %struct.ifaddrs*, %struct.ifaddrs** %37
%39 = load i32, i32* %7
%40 = call i32 @memcpy(%struct.ifaddrs* %35, %struct.ifaddrs* %38, i32 %39)
%41 = call i8* @malloc(i32 24)
%42 = bitcast i8* %41 to %struct.ifaddrs*
%43 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%44 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %43, i32 0, i32 0
store %struct.ifaddrs* %42, %struct.ifaddrs** %44
%45 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%46 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %45, i32 0, i32 0
%47 = load %struct.ifaddrs*, %struct.ifaddrs** %46
%48 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%49 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %48, i32 0, i32 2
%50 = load %struct.ifaddrs*, %struct.ifaddrs** %49
%51 = call i32 @memcpy(%struct.ifaddrs* %47, %struct.ifaddrs* %50, i32 4)
%52 = load %struct.ifaddrs*, %struct.ifaddrs** %4
%53 = load %struct.ifaddrs*, %struct.ifaddrs** %6
%54 = call %struct.ifaddrs* @find_mac_addr(%struct.ifaddrs* %52, %struct.ifaddrs* %53)
store %struct.ifaddrs* %54, %struct.ifaddrs** %8
%55 = load %struct.ifaddrs*, %struct.ifaddrs** %8
%56 = icmp ne %struct.ifaddrs* %55, null
br i1 %56, label %57, label %71
57: ; preds = %3
%58 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%59 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %58, i32 0, i32 2
%60 = load %struct.ifaddrs*, %struct.ifaddrs** %59
%61 = bitcast %struct.ifaddrs* %60 to %struct.sockaddr_ll*
%62 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %61, i32 0, i32 3
%63 = load %struct.ifaddrs*, %struct.ifaddrs** %62
%64 = load %struct.ifaddrs*, %struct.ifaddrs** %8
%65 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %64, i32 0, i32 2
%66 = load %struct.ifaddrs*, %struct.ifaddrs** %65
%67 = bitcast %struct.ifaddrs* %66 to %struct.sockaddr_ll*
%68 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %67, i32 0, i32 3
%69 = load %struct.ifaddrs*, %struct.ifaddrs** %68
%70 = call i32 @memcpy(%struct.ifaddrs* %63, %struct.ifaddrs* %69, i32 6)
br label %71
71: ; preds = %57, %3
%72 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%73 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %72, i32 0, i32 1
%74 = load %struct.ifaddrs*, %struct.ifaddrs** %73
%75 = call i32 @if_nametoindex(%struct.ifaddrs* %74)
%76 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%77 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %76, i32 0, i32 0
%78 = load %struct.ifaddrs*, %struct.ifaddrs** %77
%79 = bitcast %struct.ifaddrs* %78 to %struct.sockaddr_ll*
%80 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %79, i32 0, i32 2
store i32 %75, i32* %80
%81 = load i32, i32* @AF_PACKET
%82 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%83 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %82, i32 0, i32 0
%84 = load %struct.ifaddrs*, %struct.ifaddrs** %83
%85 = bitcast %struct.ifaddrs* %84 to %struct.sockaddr_ll*
%86 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %85, i32 0, i32 1
store i32 %81, i32* %86
%87 = load i32, i32* @ETH_P_ARP
%88 = call i32 @htons(i32 %87)
%89 = load %struct.ifaddrs*, %struct.ifaddrs** %5
%90 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %89, i32 0, i32 0
%91 = load %struct.ifaddrs*, %struct.ifaddrs** %90
%92 = bitcast %struct.ifaddrs* %91 to %struct.sockaddr_ll*
%93 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %92, i32 0, i32 0
store i32 %88, i32* %93
ret i32 1
}

LLVM IR (-O2):
%struct.ifaddrs = type { %struct.ifaddrs*, %struct.ifaddrs*, %struct.ifaddrs* }
%struct.sockaddr_ll = type { i32, i32, i32, %struct.ifaddrs* }
@AF_PACKET = global i32 0
@ETH_P_ARP = global i32 0
define i32 @init_ifaddr(%struct.ifaddrs* %0, %struct.ifaddrs* %1, %struct.ifaddrs* %2) {
%4 = tail call i32 @memcpy(%struct.ifaddrs* %1, %struct.ifaddrs* %2, i32 24)
%5 = tail call dereferenceable_or_null(24) i8* @malloc(i32 24)
%6 = bitcast i8* %5 to %struct.ifaddrs*
%7 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %1, i64 0, i32 2
%8 = bitcast %struct.ifaddrs** %7 to i8**
store i8* %5, i8** %8
%9 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %2, i64 0, i32 2
%10 = load %struct.ifaddrs*, %struct.ifaddrs** %9
%11 = tail call i32 @memcpy(%struct.ifaddrs* %6, %struct.ifaddrs* %10, i32 4)
%12 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %2, i64 0, i32 1
%13 = load %struct.ifaddrs*, %struct.ifaddrs** %12
%14 = tail call i32 @strlen(%struct.ifaddrs* %13)
%15 = add nsw i32 %14, 1
%16 = tail call i8* @malloc(i32 %15)
%17 = bitcast i8* %16 to %struct.ifaddrs*
%18 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %1, i64 0, i32 1
%19 = bitcast %struct.ifaddrs** %18 to i8**
store i8* %16, i8** %19
%20 = load %struct.ifaddrs*, %struct.ifaddrs** %12
%21 = tail call i32 @memcpy(%struct.ifaddrs* %17, %struct.ifaddrs* %20, i32 %15)
%22 = tail call dereferenceable_or_null(24) i8* @malloc(i32 24)
%23 = bitcast i8* %22 to %struct.ifaddrs*
%24 = bitcast %struct.ifaddrs* %1 to i8**
store i8* %22, i8** %24
%25 = load %struct.ifaddrs*, %struct.ifaddrs** %7
%26 = tail call i32 @memcpy(%struct.ifaddrs* %23, %struct.ifaddrs* %25, i32 4)
%27 = tail call %struct.ifaddrs* @find_mac_addr(%struct.ifaddrs* %0, %struct.ifaddrs* %2)
%28 = icmp eq %struct.ifaddrs* %27, null
br i1 %28, label %40, label %29
29: ; preds = %3
%30 = bitcast %struct.ifaddrs** %7 to %struct.sockaddr_ll**
%31 = load %struct.sockaddr_ll*, %struct.sockaddr_ll** %30
%32 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %31, i64 0, i32 3
%33 = load %struct.ifaddrs*, %struct.ifaddrs** %32
%34 = getelementptr inbounds %struct.ifaddrs, %struct.ifaddrs* %27, i64 0, i32 2
%35 = bitcast %struct.ifaddrs** %34 to %struct.sockaddr_ll**
%36 = load %struct.sockaddr_ll*, %struct.sockaddr_ll** %35
%37 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %36, i64 0, i32 3
%38 = load %struct.ifaddrs*, %struct.ifaddrs** %37
%39 = tail call i32 @memcpy(%struct.ifaddrs* %33, %struct.ifaddrs* %38, i32 6)
br label %40
40: ; preds = %29, %3
%41 = load %struct.ifaddrs*, %struct.ifaddrs** %18
%42 = tail call i32 @if_nametoindex(%struct.ifaddrs* %41)
%43 = bitcast %struct.ifaddrs* %1 to %struct.sockaddr_ll**
%44 = load %struct.sockaddr_ll*, %struct.sockaddr_ll** %43
%45 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %44, i64 0, i32 2
store i32 %42, i32* %45
%46 = load i32, i32* @AF_PACKET
%47 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %44, i64 0, i32 1
store i32 %46, i32* %47
%48 = load i32, i32* @ETH_P_ARP
%49 = tail call i32 @htons(i32 %48)
%50 = load %struct.sockaddr_ll*, %struct.sockaddr_ll** %43
%51 = getelementptr inbounds %struct.sockaddr_ll, %struct.sockaddr_ll* %50, i64 0, i32 0
store i32 %49, i32* %51
ret i32 1
}