// File: /workspace/github_c_makefile_star2_O0/mjosaarinen[P]brutus/src/main.c
// Function: main
int main(int argc, char **argv)
{
    int t, i, *ipt, ciphers;
    char *str;
    caesar_t *aead, *candidate;
    int flag_coherence, flag_speed, flag_fast, flag_xprmt,
        flag_kat, flag_timeout;
    struct sigaction sa;

    // test modes
    brutus_verbose = 1;
    flag_coherence = 0;
    flag_speed = 0;
    flag_fast = 0;
    flag_xprmt = 0;
    flag_kat = 0;
    flag_timeout = 0;

    // no paramets
    if (argc < 2) {
        fprintf(stderr, "%s", brutus_usage);
        return -1;
    }

    // approximate table sizes
    if ((candidate = calloc(argc, sizeof(caesar_t))) == NULL) {
        perror("calloc()");
        return -1;
    }

    ciphers = 0;
    for (i = 1; i < argc; i++) {
        // flag ?
        if (argv[i][0] == '-') {

            if (argv[i][1] != 0) {
                t = argv[i][2];
                if (t >= '0' && t <= '9')
                    t = atoi(&argv[i][2]);
                else
                    t = -1;
            } else {
                fprintf(stderr, "%s: Unknown expression: %s\n",
                    argv[0], argv[i]);
                return -1;
            }

            // for future
            switch(argv[i][1]) {

                case 'c':       // coherence
                    if (t <= 0)
                        flag_coherence = 2;
                    else
                        flag_coherence = t;
                    break;

                case 'f':       // throughput
                    if (t <= 0)
                        flag_fast = 1;
                    else
                        flag_fast = t;
                    break;

                case 'h':       // help to stdout
                    printf("%s", brutus_usage);
                    return 0;

                case 'k':       // known answer tests
                    if (t <= 0)
                        flag_kat = 100;
                    else
                        flag_kat = t;
                    break;

                case 'r':       // random seed
                    if (t < 0)
                        t = time(NULL) & 0x7FFFFFFF;
                    detseq_seed(t);
                    if (brutus_verbose)
                        printf("\tdetseq_seed(%d)\n", t);
                    break;

                case 's':       // speed
                    if (t <= 0)
                        flag_speed = 3;
                    else
                        flag_speed = t;
                    break;

                case 't':       // timeout
                    if (t > 0)
                        flag_timeout = t;
                    else
                        flag_timeout = 0;
                    break;

                case 'q':       // quiet
                    brutus_verbose = 0;
                    break;

                case 'x':       // experiment
                    if (t > 0)
                        flag_xprmt = t;
                    else
                        flag_xprmt = 1;
                    break;

                default:
                    fprintf(stderr, "%s: Unknown flag: %s\n",
                        argv[0], argv[i]);
                return -1;
            }

        } else {

            aead = &candidate[ciphers];
            memset(aead, 0, sizeof(caesar_t));

            aead->dlib = dlopen(argv[i], RTLD_LAZY | RTLD_LOCAL);
            str = dlerror();
            if (str != NULL)
                fprintf(stderr, "%s: %s\n", argv[i], str);

            if (aead->dlib != NULL) {

                // load parameters from the dynamic library
                if ((str = dlsym(aead->dlib, "brutus_name")) != NULL)
                    aead->name = str;
                else
                    aead->name = "<brutus_name>";

                if ((ipt = dlsym(aead->dlib, "brutus_keybytes")) != NULL)
                    aead->keybytes = *ipt;
                if ((ipt = dlsym(aead->dlib, "brutus_nsecbytes")) != NULL)
                    aead->nsecbytes = *ipt;
                if ((ipt = dlsym(aead->dlib, "brutus_npubbytes")) != NULL)
                    aead->npubbytes = *ipt;
                if ((ipt = dlsym(aead->dlib, "brutus_abytes")) != NULL)
                    aead->abytes = *ipt;
                if ((ipt = dlsym(aead->dlib, "brutus_nooverlap")) != NULL)
                    aead->nooverlap = *ipt;

                // these must be present
                aead->encrypt = dlsym(aead->dlib, "crypto_aead_encrypt");
                aead->decrypt = dlsym(aead->dlib, "crypto_aead_decrypt");
                if (aead->encrypt != NULL && aead->decrypt != NULL) {
                    ciphers++;
                } else {
                    str = dlerror();
                    if (str != NULL)
                        fprintf(stderr, "Failed %s\n", str);
                    else
                        fprintf(stderr, "Failed %s\n", argv[i]);
                    dlclose(aead->dlib);
                }
            }
        }
    }

    // banner
    if (brutus_verbose) {
        printf("%s\n",
            "BRUTUS ("__DATE__") by Markku-Juhani O. Saarinen <mjos@iki.fi>");
        fflush(stdout);
    }

    if (ciphers <= 0) {
        fprintf(stderr, "%s: No ciphers specified.\n", argv[0]);
        return 1;
    }

    // set the timeout
    if (flag_timeout > 0) {
        if (brutus_verbose) {
            printf("\tGlobal timeout in %d secs.\n", flag_timeout);
            fflush(stdout);
        }

        memset(&sa, 0, sizeof(sa));
        sigemptyset(&sa.sa_mask);
        sa.sa_handler = timeout_kill;
        sa.sa_flags = 0;
        if (sigaction(SIGALRM, &sa, NULL) != 0)
            perror("sigaction()");

        alarm(flag_timeout);
    }

    // run tests on all ciphers
    for (i = 0; i < ciphers; i++) {
        if (flag_coherence > 0)
            test_harness(test_coherence, &candidate[i], flag_coherence);
        if (flag_speed > 0)
            test_harness(test_speed, &candidate[i], flag_speed);
        if (flag_fast > 0)
            test_harness(test_throughput, &candidate[i], flag_fast);
        if (flag_kat > 0)
            test_harness(test_kat, &candidate[i], flag_kat);
    }

    // loop experiments until timeout, if timeout is specified
    while (flag_xprmt > 0) {
        for (i = 0; i < ciphers; i++)
            test_harness(test_xprmnt, &candidate[i], flag_xprmt);
        if (flag_timeout == 0)
            break;
    }

    // free up the dynamic libraries
    for (i = 0; i < ciphers; i++)
        dlclose(candidate[i].dlib);
    free(candidate);

    return 0;
}

// Assembly:
subq $0xf8, %rsp
movl $0x0, 0xf4(%rsp)
movl %edi, 0xf0(%rsp)
movq %rsi, 0xe8(%rsp)
movl $0x1, 0x4d95(%rip)      # 0x6110
movl $0x0, 0xb4(%rsp)
movl $0x0, 0xb0(%rsp)
movl $0x0, 0xac(%rsp)
movl $0x0, 0xa8(%rsp)
movl $0x0, 0xa4(%rsp)
movl $0x0, 0xa0(%rsp)
cmpl $0x2, 0xf0(%rsp)
jge 0x13f6
movq 0x4c22(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
leaq 0x2df2(%rip), %rsi      # 0x41ca
leaq 0x2c91(%rip), %rdx      # 0x4070
movb $0x0, %al
callq 0x1100
movl $0xffffffff, 0xf4(%rsp) # imm = 0xFFFFFFFF
jmp 0x1d6b
movslq 0xf0(%rsp), %rdi
movl $0x38, %esi
callq 0x10e0
movq %rax, 0xb8(%rsp)
cmpq $0x0, %rax
jne 0x1432
leaq 0x2db0(%rip), %rdi      # 0x41cd
callq 0x1190
movl $0xffffffff, 0xf4(%rsp) # imm = 0xFFFFFFFF
jmp 0x1d6b
movl $0x0, 0xd4(%rsp)
movl $0x1, 0xe0(%rsp)
movl 0xe0(%rsp), %eax
cmpl 0xf0(%rsp), %eax
jge 0x1a82
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x1746
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x1(%rax), %eax
cmpl $0x0, %eax
je 0x14ff
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x2(%rax), %eax
movl %eax, 0xe4(%rsp)
cmpl $0x30, 0xe4(%rsp)
jl 0x14f2
cmpl $0x39, 0xe4(%rsp)
jg 0x14f2
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x2, %rdi
callq 0x11b0
movl %eax, 0xe4(%rsp)
jmp 0x14fd
movl $0xffffffff, 0xe4(%rsp) # imm = 0xFFFFFFFF
jmp 0x1546
movq 0x4aea(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0xe8(%rsp), %rax
movq (%rax), %rdx
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
leaq 0x2ca7(%rip), %rsi      # 0x41d6
movb $0x0, %al
callq 0x1100
movl $0xffffffff, 0xf4(%rsp) # imm = 0xFFFFFFFF
jmp 0x1d6b
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x1(%rax), %eax
addl $-0x63, %eax
movl %eax, %ecx
movq %rcx, (%rsp)
subl $0x15, %eax
ja 0x16fa
movq (%rsp), %rax
leaq 0x2a95(%rip), %rcx      # 0x4010
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x0, 0xe4(%rsp)
jg 0x159b
movl $0x2, 0xb4(%rsp)
jmp 0x15a9
movl 0xe4(%rsp), %eax
movl %eax, 0xb4(%rsp)
jmp 0x1741
cmpl $0x0, 0xe4(%rsp)
jg 0x15c5
movl $0x1, 0xac(%rsp)
jmp 0x15d3
movl 0xe4(%rsp), %eax
movl %eax, 0xac(%rsp)
jmp 0x1741
leaq 0x2beb(%rip), %rdi      # 0x41ca
leaq 0x2a8a(%rip), %rsi      # 0x4070
movb $0x0, %al
callq 0x10a0
movl $0x0, 0xf4(%rsp)
jmp 0x1d6b
cmpl $0x0, 0xe4(%rsp)
jg 0x1614
movl $0x64, 0xa4(%rsp)
jmp 0x1622
movl 0xe4(%rsp), %eax
movl %eax, 0xa4(%rsp)
jmp 0x1741
cmpl $0x0, 0xe4(%rsp)
jge 0x1647
xorl %eax, %eax
movl %eax, %edi
callq 0x1140
andq $0x7fffffff, %rax       # imm = 0x7FFFFFFF
movl %eax, 0xe4(%rsp)
movl 0xe4(%rsp), %edi
callq 0x1d80
cmpl $0x0, 0x4ab6(%rip)      # 0x6110
je 0x1671
movl 0xe4(%rsp), %esi
leaq 0x2b88(%rip), %rdi      # 0x41f2
movb $0x0, %al
callq 0x10a0
jmp 0x1741
cmpl $0x0, 0xe4(%rsp)
jg 0x168d
movl $0x3, 0xb0(%rsp)
jmp 0x169b
movl 0xe4(%rsp), %eax
movl %eax, 0xb0(%rsp)
jmp 0x1741
cmpl $0x0, 0xe4(%rsp)
jle 0x16ba
movl 0xe4(%rsp), %eax
movl %eax, 0xa0(%rsp)
jmp 0x16c5
movl $0x0, 0xa0(%rsp)
jmp 0x1741
movl $0x0, 0x4a3f(%rip)      # 0x6110
jmp 0x1741
cmpl $0x0, 0xe4(%rsp)
jle 0x16ed
movl 0xe4(%rsp), %eax
movl %eax, 0xa8(%rsp)
jmp 0x16f8
movl $0x1, 0xa8(%rsp)
jmp 0x1741
movq 0x48ef(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0xe8(%rsp), %rax
movq (%rax), %rdx
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
leaq 0x2ada(%rip), %rsi      # 0x4204
movb $0x0, %al
callq 0x1100
movl $0xffffffff, 0xf4(%rsp) # imm = 0xFFFFFFFF
jmp 0x1d6b
jmp 0x1a6a
movq 0xb8(%rsp), %rax
movslq 0xd4(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rdi
xorl %esi, %esi
movl $0x38, %edx
callq 0x10b0
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
movl $0x1, %esi
callq 0x10f0
movq %rax, %rcx
movq 0xc0(%rsp), %rax
movq %rcx, (%rax)
callq 0x1030
movq %rax, 0xc8(%rsp)
cmpq $0x0, 0xc8(%rsp)
je 0x17f1
movq 0x482c(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
movq 0xc8(%rsp), %rcx
leaq 0x2a30(%rip), %rsi      # 0x421a
movb $0x0, %al
callq 0x1100
movq 0xc0(%rsp), %rax
cmpq $0x0, (%rax)
je 0x1a68
movq 0xc0(%rsp), %rax
movq (%rax), %rdi
leaq 0x2a0d(%rip), %rsi      # 0x4222
callq 0x11a0
movq %rax, 0xc8(%rsp)
cmpq $0x0, %rax
je 0x183e
movq 0xc8(%rsp), %rcx
movq 0xc0(%rsp), %rax
movq %rcx, 0x8(%rax)
jmp 0x1851
movq 0xc0(%rsp), %rax
leaq 0x29e1(%rip), %rcx      # 0x422e
movq %rcx, 0x8(%rax)
movq 0xc0(%rsp), %rax
movq (%rax), %rdi
leaq 0x29d9(%rip), %rsi      # 0x423c
callq 0x11a0
movq %rax, 0xd8(%rsp)
cmpq $0x0, %rax
je 0x188b
movq 0xd8(%rsp), %rax
movl (%rax), %ecx
movq 0xc0(%rsp), %rax
movl %ecx, 0x10(%rax)
movq 0xc0(%rsp), %rax
movq (%rax), %rdi
leaq 0x29af(%rip), %rsi      # 0x424c
callq 0x11a0
movq %rax, 0xd8(%rsp)
cmpq $0x0, %rax
je 0x18c5
movq 0xd8(%rsp), %rax
movl (%rax), %ecx
movq 0xc0(%rsp), %rax
movl %ecx, 0x14(%rax)
movq 0xc0(%rsp), %rax
movq (%rax), %rdi
leaq 0x2986(%rip), %rsi      # 0x425d
callq 0x11a0
movq %rax, 0xd8(%rsp)
cmpq $0x0, %rax
je 0x18ff
movq 0xd8(%rsp), %rax
movl (%rax), %ecx
movq 0xc0(%rsp), %rax
movl %ecx, 0x18(%rax)
movq 0xc0(%rsp), %rax
movq (%rax), %rdi
leaq 0x295d(%rip), %rsi      # 0x426e
callq 0x11a0
movq %rax, 0xd8(%rsp)
cmpq $0x0, %rax
je 0x1939
movq 0xd8(%rsp), %rax
movl (%rax), %ecx
movq 0xc0(%rsp), %rax
movl %ecx, 0x1c(%rax)
movq 0xc0(%rsp), %rax
movq (%rax), %rdi
leaq 0x2931(%rip), %rsi      # 0x427c
callq 0x11a0
movq %rax, 0xd8(%rsp)
cmpq $0x0, %rax
je 0x1973
movq 0xd8(%rsp), %rax
movl (%rax), %ecx
movq 0xc0(%rsp), %rax
movl %ecx, 0x20(%rax)
movq 0xc0(%rsp), %rax
movq (%rax), %rdi
leaq 0x2908(%rip), %rsi      # 0x428d
callq 0x11a0
movq %rax, %rcx
movq 0xc0(%rsp), %rax
movq %rcx, 0x28(%rax)
movq 0xc0(%rsp), %rax
movq (%rax), %rdi
leaq 0x28f6(%rip), %rsi      # 0x42a1
callq 0x11a0
movq %rax, %rcx
movq 0xc0(%rsp), %rax
movq %rcx, 0x30(%rax)
movq 0xc0(%rsp), %rax
cmpq $0x0, 0x28(%rax)
je 0x19f0
movq 0xc0(%rsp), %rax
cmpq $0x0, 0x30(%rax)
je 0x19f0
movl 0xd4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0x1a66
callq 0x1030
movq %rax, 0xc8(%rsp)
cmpq $0x0, 0xc8(%rsp)
je 0x1a2a
movq 0x45e1(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0xc8(%rsp), %rdx
leaq 0x2894(%rip), %rsi      # 0x42b5
movb $0x0, %al
callq 0x1100
jmp 0x1a56
movq 0x45bf(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0xe8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
leaq 0x2866(%rip), %rsi      # 0x42b5
movb $0x0, %al
callq 0x1100
movq 0xc0(%rsp), %rax
movq (%rax), %rdi
callq 0x11d0
jmp 0x1a68
jmp 0x1a6a
jmp 0x1a6c
movl 0xe0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe0(%rsp)
jmp 0x1448
cmpl $0x0, 0x4687(%rip)      # 0x6110
je 0x1aaf
leaq 0x2784(%rip), %rdi      # 0x4216
leaq 0x2827(%rip), %rsi      # 0x42c0
movb $0x0, %al
callq 0x10a0
movq 0x4529(%rip), %rax      # 0x5fd0
movq (%rax), %rdi
callq 0x1150
cmpl $0x0, 0xd4(%rsp)
jg 0x1aec
movq 0x4530(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0xe8(%rsp), %rax
movq (%rax), %rdx
leaq 0x282b(%rip), %rsi      # 0x4300
movb $0x0, %al
callq 0x1100
movl $0x1, 0xf4(%rsp)
jmp 0x1d6b
cmpl $0x0, 0xa0(%rsp)
jle 0x1b8d
cmpl $0x0, 0x460f(%rip)      # 0x6110
je 0x1b27
movl 0xa0(%rsp), %esi
leaq 0x280a(%rip), %rdi      # 0x431b
movb $0x0, %al
callq 0x10a0
movq 0x44b1(%rip), %rax      # 0x5fd0
movq (%rax), %rdi
callq 0x1150
leaq 0x8(%rsp), %rdi
xorl %esi, %esi
movl $0x98, %edx
callq 0x10b0
leaq 0x8(%rsp), %rdi
addq $0x8, %rdi
callq 0x1110
leaq -0x83d(%rip), %rax      # 0x1310
movq %rax, 0x8(%rsp)
movl $0x0, 0x90(%rsp)
movl $0xe, %edi
leaq 0x8(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x1070
cmpl $0x0, %eax
je 0x1b81
leaq 0x27bc(%rip), %rdi      # 0x4338
callq 0x1190
movl 0xa0(%rsp), %edi
callq 0x10c0
movl $0x0, 0xe0(%rsp)
movl 0xe0(%rsp), %eax
cmpl 0xd4(%rsp), %eax
jge 0x1c94
cmpl $0x0, 0xb4(%rsp)
jle 0x1be0
movq 0xb8(%rsp), %rsi
movslq 0xe0(%rsp), %rax
imulq $0x38, %rax, %rax
addq %rax, %rsi
movl 0xb4(%rsp), %edx
leaq 0xbb5(%rip), %rdi       # 0x2790
callq 0x1f70
cmpl $0x0, 0xb0(%rsp)
jle 0x1c14
movq 0xb8(%rsp), %rsi
movslq 0xe0(%rsp), %rax
imulq $0x38, %rax, %rax
addq %rax, %rsi
movl 0xb0(%rsp), %edx
leaq 0xa31(%rip), %rdi       # 0x2640
callq 0x1f70
cmpl $0x0, 0xac(%rsp)
jle 0x1c48
movq 0xb8(%rsp), %rsi
movslq 0xe0(%rsp), %rax
imulq $0x38, %rax, %rax
addq %rax, %rsi
movl 0xac(%rsp), %edx
leaq 0xacd(%rip), %rdi       # 0x2710
callq 0x1f70
cmpl $0x0, 0xa4(%rsp)
jle 0x1c7c
movq 0xb8(%rsp), %rsi
movslq 0xe0(%rsp), %rax
imulq $0x38, %rax, %rax
addq %rax, %rsi
movl 0xa4(%rsp), %edx
leaq 0x1799(%rip), %rdi      # 0x3410
callq 0x1f70
jmp 0x1c7e
movl 0xe0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe0(%rsp)
jmp 0x1b98
jmp 0x1c96
cmpl $0x0, 0xa8(%rsp)
jle 0x1d06
movl $0x0, 0xe0(%rsp)
movl 0xe0(%rsp), %eax
cmpl 0xd4(%rsp), %eax
jge 0x1cf8
movq 0xb8(%rsp), %rsi
movslq 0xe0(%rsp), %rax
imulq $0x38, %rax, %rax
addq %rax, %rsi
movl 0xa8(%rsp), %edx
leaq 0x1870(%rip), %rdi      # 0x3550
callq 0x1f70
movl 0xe0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe0(%rsp)
jmp 0x1cab
cmpl $0x0, 0xa0(%rsp)
jne 0x1d04
jmp 0x1d06
jmp 0x1c96
movl $0x0, 0xe0(%rsp)
movl 0xe0(%rsp), %eax
cmpl 0xd4(%rsp), %eax
jge 0x1d53
movq 0xb8(%rsp), %rax
movslq 0xe0(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rdi
callq 0x11d0
movl 0xe0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe0(%rsp)
jmp 0x1d11
movq 0xb8(%rsp), %rdi
callq 0x1040
movl $0x0, 0xf4(%rsp)
movl 0xf4(%rsp), %eax
addq $0xf8, %rsp
retq
nopw (%rax,%rax)