// File: /workspace/github_c_makefile_star2_O1/deplinenoise[P]vlink/linker.c
// Function: linker_join
void linker_join(struct GlobalVars *gv)
/* Join the sections with same name and type, or as defined by a
   linker script. Calculate their virtual address and size. */
{
  struct ObjectUnit *obj;
  struct Section *sec,*nextsec;

  if (gv->trace_file)
    fprintf(gv->trace_file,"Joining selected sections:\n");

  if (gv->use_ldscript) {
    /* Linkage rules are defined by a linker script, which means there */
    /* are predefined LinkedSection structures which can be used. */
    struct LinkedSection *ls,*maxls=NULL;
    char *filepattern,**secpatterns;
    unsigned long maxsize = 0;

    init_secdef_parse(gv);
    /* Handle one section definition after the other from the
       linker script's SECTIONS block. The script parser cares
       for commands, symbol-definitions and address-assignments. */

    while (ls = next_secdef(gv)) {
      /* Phase 1: read file/section patterns and determine which alignment
         and flags are required for the sections to merge with us */
      while (test_pattern(gv,&filepattern,&secpatterns)) {
        for (obj=(struct ObjectUnit *)gv->selobjects.first;
             obj->n.next!=NULL; obj=(struct ObjectUnit *)obj->n.next) {

          if (obj->lnkfile->type != ID_SHAREDOBJ &&
              pattern_match(filepattern,obj->lnkfile->filename)) {
            for (sec=(struct Section *)obj->sections.first;
                 sec->n.next!=NULL; sec=(struct Section *)sec->n.next) {
              if (sec->lnksec==NULL
                  && patternlist_match(secpatterns,sec->name)) {
                /* File name and section name are matching the patterns,
                   so try to merge and check alignments */
                uint8_t f;

                if ((f = cmpsecflags(gv,ls,sec->flags)) == 0xff) {
                  /* no warning, because the linker-script should know... */
                  f = ls->flags ? ls->flags : sec->flags;
                }
                merge_sec_attrs(ls,sec,f&~SF_PORTABLE_MASK);
                sec->lnksec = ls;  /* will be reset for phase 2 */
              }
            }
          }
        }
        free_patterns(filepattern,secpatterns);
      }

      /* align this section to the maximum required alignment */
      align_address(ls->relocmem,ls->destmem,ls->alignment);
      ls->base = ls->relocmem->current;
      ls->copybase = ls->destmem->current;

      /* reset lnksec pointers for phase 2 */
      for (obj=(struct ObjectUnit *)gv->selobjects.first;
           obj->n.next!=NULL; obj=(struct ObjectUnit *)obj->n.next) {
        if (obj->lnkfile->type!=ID_SHAREDOBJ && !listempty(&obj->sections)) {
          for (sec=(struct Section *)obj->sections.first;
               sec->n.next!=NULL; sec=(struct Section *)sec->n.next)
            sec->lnksec = NULL;
        }
      }

      /* Phase 2: read next patterns and merge matching sections for real */
      while (next_pattern(gv,&filepattern,&secpatterns)) {
        for (obj=(struct ObjectUnit *)gv->selobjects.first;
             obj->n.next!=NULL; obj=(struct ObjectUnit *)obj->n.next) {

          if (obj->lnkfile->type != ID_SHAREDOBJ &&
              pattern_match(filepattern,obj->lnkfile->filename)) {
            sec = (struct Section *)obj->sections.first;
            while (nextsec = (struct Section *)sec->n.next) {
              if (sec->lnksec==NULL
                  && patternlist_match(secpatterns,sec->name)) {

                /* File name and section name are matching the patterns,
                   so join it into the current LinkedSection. */
                align_address(ls->relocmem,ls->destmem,sec->alignment);
                sec->filldata = gv->filldata;
                sec->lnksec = ls;
                sec->va = ls->relocmem->current;
                sec->offset = sec->va - ls->base;
                update_address(ls->relocmem,ls->destmem,sec->size);

                /* allocate COMMON symbols, if required */
                if ((!strcmp(sec->name,gv->common_sec_name) ||
                     !strcmp(sec->name,gv->scommon_sec_name)) &&
                    (!gv->dest_object || gv->alloc_common)) {
                  update_address(ls->relocmem,ls->destmem,
                                 allocate_common(gv,sec,
                                                 ls->relocmem->current));
                }

                addtail(&ls->sections,remnode(&sec->n));

                if (!is_ld_script(sec->obj) &&
                    (gv->scriptflags & LDSF_KEEP)) {
                /* @@@ KEEP for one section will prevent all merged
                   sections from being deleted - ok??? */
                  ls->ld_flags |= LSF_PRESERVE;
                  ls->flags |= SF_ALLOC;  /* @@@ keep implies ALLOC? */
                }
              }
              sec = nextsec;
            }
          }
        }
        free_patterns(filepattern,secpatterns);

        /* keep section size up to date */
        ls->size = ls->relocmem->current - ls->base;
        if (sec = last_initialized(ls))
          ls->filesize = (sec->va + sec->size) - ls->base;
        else
          ls->filesize = 0;  /* whole contents is uninitialized */

        if (ls->size>maxsize || maxsize==0) {  /* finds largest section */
          maxsize = ls->size;
          maxls = ls;
        }
      }
    }

    /* Check if there are any sections left, which were not recognized */
    /* by the linker script rules */
    for (obj=(struct ObjectUnit *)gv->selobjects.first;
         obj->n.next!=NULL; obj=(struct ObjectUnit *)obj->n.next) {
      if (obj->lnkfile->type!=ID_SHAREDOBJ && !listempty(&obj->sections)) {
        for (sec=(struct Section *)obj->sections.first; sec->n.next!=NULL;
             sec=(struct Section *)sec->n.next) {
          int i;

          if (sec->size==0 && (*(sec->name)==0 || is_ld_script(sec->obj))) {
            /* @@@ move section without name and contents into biggest
               LinkedSection - might be a dummy or linker script section
               with abs symbols */
            sec->filldata = gv->filldata;
            sec->lnksec = maxls;
            sec->va = maxls->relocmem->current;
            sec->offset = sec->va - maxls->base;
            addtail(&maxls->sections,remnode(&sec->n));
          }
          else {
            /* Section was not recognized by target linker script */
            error(64,getobjname(obj),sec->name);

            /* kill unallocated common symbols */
            for (i=0; i<OBJSYMHTABSIZE; i++) {
              struct Symbol *sym;

              for (sym = sec->obj->objsyms[i]; sym; sym=sym->obj_chain) {
                if (sym->relsect==sec && sym->type==SYM_COMMON)
                  sym->type = SYM_ABS; /* to prevent an internal error */
              }
            }
          }
        }
      }
    }
  }


  else {  /* !gv->use_ldscript */
    /* Default linkage rules. Link all code, all data, all bss. */
    unsigned long va = 0;
    bool baseincr = (fff[gv->dest_format]->flags&FFF_BASEINCR) != 0;
    uint8_t stype;
    struct LinkedSection *ls,*newls;

    /* join sections, beginning with ST_CODE, then ST_DATA and ST_UDATA */
    for (stype=0; stype<=ST_LAST; stype++) {
      struct list seclist;

      /* collect all sections of current type */
      initlist(&seclist);
      for (obj=(struct ObjectUnit *)gv->selobjects.first;
           obj->n.next!=NULL; obj=(struct ObjectUnit *)obj->n.next) {

        if (obj->lnkfile->type != ID_SHAREDOBJ) {
          sec = (struct Section *)obj->sections.first;
          while (nextsec = (struct Section *)sec->n.next) {
            if (sec->type == stype)
              addtail(&seclist,remnode(&sec->n));
            sec = nextsec;
          }
        }
      }

      /* Phase 1: link sec. which fit together, obeying target linking rules*/
      do {
        bool create_allowed = TRUE;

        for (sec=(struct Section *)seclist.first;
             sec->n.next!=NULL; sec=(struct Section *)sec->n.next) {
          ls = get_matching_lnksec(gv,sec,NULL);
          if (!ls && create_allowed) {
            Dprintf("new: %s(%s) -> %s\n",getobjname(sec->obj),
                    sec->name,sec->name);
            ls = create_lnksect(gv,sec->name,sec->type,sec->flags,
                                sec->protection,sec->alignment);
            create_allowed = FALSE;
          }
          if (ls)
            addtail(&ls->sections,remnode(&sec->n));
        }
      }
      while (!(listempty(&seclist)));
    }

    /* Phase 2: resolve dependencies between created LinkedSections */
    do {
      newls = NULL;
      for (ls=(struct LinkedSection *)gv->lnksec.first;
           ls->n.next!=NULL; ls=(struct LinkedSection *)ls->n.next) {
        for (sec=(struct Section *)ls->sections.first;
             sec->n.next!=NULL; sec=(struct Section *)sec->n.next) {
          if (newls = get_matching_lnksec(gv,sec,ls)) {
            /* another LinkedSection matches too - merge them! */
            break;
          }
        }
        if (newls) {
          /* merge with matching LinkedSection, dump the newer one */
          struct Section *firstbss;
          uint8_t tgtfl;

          if (newls->index > ls->index) {
            /* ls is older, so keep it instead of newls */
            struct LinkedSection *dumls = newls;
            newls = ls;
            ls = dumls;
          }
          firstbss = find_first_bss_sec(newls);
          tgtfl = ls->flags & ~SF_PORTABLE_MASK;

          while (sec = (struct Section *)remhead(&ls->sections)) {
            merge_sec_attrs(newls,sec,tgtfl);
            if (!(sec->flags & SF_UNINITIALIZED) && firstbss!=NULL)
              insertbefore(&sec->n,&firstbss->n);
            else
              addtail(&newls->sections,&sec->n);
          }
          remnode(&ls->n);
          free(ls);
          break;
        }
      }
    }
    while (newls);

    /* Phase 3: calculate offsets and sizes for final LinkedSections */
    for (ls=(struct LinkedSection *)gv->lnksec.first;
         ls->n.next!=NULL; ls=(struct LinkedSection *)ls->n.next) {
      ls->base = ls->copybase = va;

      for (sec=(struct Section *)ls->sections.first;
           sec->n.next!=NULL; sec=(struct Section *)sec->n.next) {
        unsigned long abytes = align(ls->base+ls->size,sec->alignment);

        sec->lnksec = ls;
        sec->offset = ls->size + abytes;
        sec->va = ls->base + sec->offset;
        ls->size += sec->size + abytes;
        if (baseincr)
          va += sec->size + abytes;
        if (!(sec->flags & SF_UNINITIALIZED))
          ls->filesize += sec->size + abytes;

        /* allocate COMMON symbols, if required */
        if ((!strcmp(sec->name,gv->common_sec_name) ||
             !strcmp(sec->name,gv->scommon_sec_name)) &&
            (!gv->dest_object || gv->alloc_common)) {
          unsigned long n = allocate_common(gv,sec,ls->base+ls->size);

          ls->size += n;
          if (baseincr)
            va += n;
        }
      }
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %r15
movq 0xa0(%rdi), %rcx
testq %rcx, %rcx
je 0x8326
leaq 0x19f64(%rip), %rdi     # 0x2227b
movl $0x1b, %esi
movl $0x1, %edx
callq 0x5270
cmpl $0x0, 0x244(%r15)
movq %r15, 0x8(%rsp)
je 0x86d5
movq %r15, %rdi
callq 0xed5c
movq %r15, %rdi
callq 0xe94c
testq %rax, %rax
je 0x89f1
movq %rax, %r12
xorl %ebp, %ebp
movq $0x0, 0x20(%rsp)
movq %r15, %rdi
leaq 0x30(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0xd8e2
testl %eax, %eax
je 0x8422
movq 0x138(%r15), %rbx
cmpq $0x0, (%rbx)
je 0x840e
movq 0x10(%rbx), %rax
cmpb $0x4, 0x39(%rax)
je 0x8406
movq 0x30(%rsp), %rdi
movq 0x18(%rax), %rsi
callq 0xff74
testl %eax, %eax
je 0x8406
movq 0x20(%rbx), %r13
cmpq $0x0, (%r13)
je 0x8406
cmpq $0x0, 0x18(%r13)
jne 0x8400
movq 0x10(%rsp), %rdi
movq 0x20(%r13), %rsi
callq 0xff87
testl %eax, %eax
je 0x8400
movzbl 0x2d(%r13), %edx
movq %r15, %rdi
movq %r12, %rsi
callq 0x8b09
cmpb $-0x1, %al
jne 0x83ec
movb 0x21(%r12), %al
testb %al, %al
jne 0x83ec
movb 0x2d(%r13), %al
andb $-0x20, %al
movzbl %al, %edx
movq %r12, %rdi
movq %r13, %rsi
callq 0x8b48
movq %r12, 0x18(%r13)
movq (%r13), %r13
jmp 0x83ab
movq (%rbx), %rbx
jmp 0x8381
movq 0x30(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0xd898
jmp 0x8360
movq 0x28(%r12), %rsi
movq 0x30(%r12), %rdi
movzbl 0x23(%r12), %edx
callq 0xd86d
movq 0x28(%r12), %rax
movq 0x30(%r12), %rcx
movq 0x20(%rcx), %rcx
movq %rcx, 0x40(%r12)
movq 0x20(%rax), %rax
movq %rax, 0x38(%r12)
movq 0x138(%r15), %rax
cmpq $0x0, (%rax)
je 0x8491
movq 0x10(%rax), %rcx
cmpb $0x4, 0x39(%rcx)
je 0x848c
movq 0x20(%rax), %rcx
cmpq $0x0, (%rcx)
je 0x848c
movq (%rcx), %rdx
testq %rdx, %rdx
je 0x848c
movq $0x0, 0x18(%rcx)
movq %rdx, %rcx
movq (%rdx), %rdx
jmp 0x8477
movq (%rax), %rax
jmp 0x845a
movq %r15, %rdi
leaq 0x30(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0xde95
testl %eax, %eax
je 0x86bc
leaq 0x60(%r12), %rax
movq %rax, 0x28(%rsp)
movq %rbp, 0x18(%rsp)
movq 0x138(%r15), %r13
cmpq $0x0, (%r13)
je 0x861d
movq 0x10(%r13), %rax
cmpb $0x4, 0x39(%rax)
je 0x8614
movq 0x30(%rsp), %rdi
movq 0x18(%rax), %rsi
callq 0xff74
testl %eax, %eax
je 0x8614
movq 0x20(%r13), %rbx
movq (%rbx), %rax
testq %rax, %rax
je 0x8614
movq %rbx, %rbp
movq %rax, %rbx
cmpq $0x0, 0x18(%rbp)
jne 0x84f4
movq 0x10(%rsp), %rdi
movq 0x20(%rbp), %rsi
callq 0xff87
testl %eax, %eax
je 0x84f4
movq 0x28(%r12), %rsi
movq 0x30(%r12), %rdi
movzbl 0x2f(%rbp), %edx
callq 0xd86d
movzwl 0x200(%r15), %eax
movw %ax, 0x94(%rbp)
movq %r12, 0x18(%rbp)
movq 0x30(%r12), %rdi
movq 0x20(%rdi), %rax
movq %rax, 0x30(%rbp)
subq 0x40(%r12), %rax
movq %rax, 0x38(%rbp)
movq 0x28(%r12), %rsi
movq 0x48(%rbp), %rdx
callq 0xd7cc
movq 0x20(%rbp), %r14
movq 0x220(%r15), %rsi
movq %r14, %rdi
callq 0x5160
testl %eax, %eax
je 0x8593
movq 0x228(%r15), %rsi
movq %r14, %rdi
callq 0x5160
testl %eax, %eax
jne 0x85cf
cmpl $0x0, 0x54(%r15)
je 0x85a1
cmpl $0x0, 0x64(%r15)
je 0x85cf
movq 0x28(%r12), %r14
movq 0x30(%r12), %r15
movq 0x20(%r15), %rdx
movq 0x8(%rsp), %rdi
movq %rbp, %rsi
callq 0x8ce1
movq %r15, %rdi
movq 0x8(%rsp), %r15
movq %r14, %rsi
movq %rax, %rdx
callq 0xd7cc
movq %rbp, %rdi
callq 0x6789
movq 0x28(%rsp), %rdi
movq %rax, %rsi
callq 0x6759
movq 0x10(%rbp), %rdi
callq 0xd7a0
testl %eax, %eax
jne 0x84f4
testb $0x1, 0x248(%r15)
je 0x84f4
orb $0x2, 0x24(%r12)
orb $0x1, 0x21(%r12)
jmp 0x84f4
movq (%r13), %r13
jmp 0x84c1
movq 0x30(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0xd898
movq 0x30(%r12), %rax
movq 0x40(%r12), %rcx
movq 0x20(%rax), %rax
subq %rcx, %rax
movq %rax, 0x48(%r12)
movq 0x70(%r12), %rsi
movq 0x18(%rsp), %rbp
movq %rsi, %rdx
movq 0x8(%rsi), %rsi
testq %rsi, %rsi
je 0x8660
testb $0x2, 0x2d(%rdx)
jne 0x864c
jmp 0x8662
xorl %edx, %edx
testq %rdx, %rdx
je 0x8679
movq 0x30(%rdx), %rsi
subq %rcx, %rsi
addq 0x48(%rdx), %rsi
movq %rsi, 0x50(%r12)
jmp 0x8682
movq $0x0, 0x50(%r12)
movq 0x20(%rsp), %rsi
cmpq %rsi, %rax
seta %cl
testq %rsi, %rsi
sete %dl
orb %cl, %dl
cmovneq %rax, %rsi
movq %rsi, 0x20(%rsp)
cmovneq %r12, %rbp
movq %r15, %rdi
leaq 0x30(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0xde95
testl %eax, %eax
jne 0x84b5
movq %r15, %rdi
callq 0xe94c
movq %rax, %r12
testq %rax, %rax
jne 0x8360
jmp 0x89f3
movzbl 0x50(%r15), %eax
leaq 0x26a9f(%rip), %rcx     # 0x2f180
movq (%rcx,%rax,8), %rax
movl 0xac(%rax), %eax
movl %eax, 0x28(%rsp)
xorl %r13d, %r13d
leaq 0x30(%rsp), %r14
movq %r14, %rdi
callq 0x670a
movq 0x138(%r15), %rbx
cmpq $0x0, (%rbx)
je 0x8748
movq 0x10(%rbx), %rax
cmpb $0x4, 0x39(%rax)
jne 0x871b
movq (%rbx), %rbx
jmp 0x8706
movq 0x20(%rbx), %rdi
movq (%rdi), %rax
testq %rax, %rax
je 0x8716
movq %rax, %r15
cmpb %r13b, 0x2c(%rdi)
jne 0x8740
callq 0x6789
movq %r14, %rdi
movq %rax, %rsi
callq 0x6759
movq (%r15), %rax
movq %r15, %rdi
jmp 0x8722
movq 0x30(%rsp), %r15
cmpq $0x0, (%r15)
je 0x87c8
movl $0x1, %ebx
movq 0x8(%rsp), %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x8d97
movq %rax, %r12
testq %rax, %rax
sete %al
testl %ebx, %ebx
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x87a3
movq 0x20(%r15), %rsi
movzbl 0x2c(%r15), %edx
movzbl 0x2d(%r15), %ecx
movzbl 0x2e(%r15), %r8d
movzbl 0x2f(%r15), %r9d
movq 0x8(%rsp), %rdi
callq 0xc429
movq %rax, %r12
xorl %ebx, %ebx
testq %r12, %r12
je 0x87bf
addq $0x60, %r12
movq %r15, %rdi
callq 0x6789
movq %r12, %rdi
movq %rax, %rsi
callq 0x6759
movq (%r15), %r15
cmpq $0x0, (%r15)
jne 0x8758
movq 0x30(%rsp), %rax
cmpq $0x0, (%rax)
jne 0x8748
incb %r13b
cmpb $0x5, %r13b
movq 0x8(%rsp), %r15
jne 0x86f7
leaq 0x1c0(%r15), %r12
movq %r12, 0x18(%rsp)
movq (%r12), %r12
cmpq $0x0, (%r12)
je 0x88dc
leaq 0x60(%r12), %r15
movq (%r15), %r15
cmpq $0x0, (%r15)
je 0x882c
movq 0x8(%rsp), %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x8d97
testq %rax, %rax
je 0x8809
movq %rax, %r14
jmp 0x882f
xorl %r14d, %r14d
testq %r14, %r14
je 0x87f5
movl 0x10(%r14), %eax
cmpl 0x10(%r12), %eax
movq %r12, %r13
cmovgq %r14, %r13
cmovgq %r12, %r14
movq %r14, %rdi
callq 0xbe97
movq %rax, %r12
movb 0x21(%r13), %r15b
movq %r13, %rbx
addq $0x60, %r13
movq %r13, %rdi
callq 0x676f
testq %rax, %rax
je 0x88c2
movq %rax, %rbp
andb $-0x20, %r15b
leaq 0x60(%r14), %rax
movq %rax, 0x20(%rsp)
movzbl %r15b, %r15d
movq %r14, %rdi
movq %rbp, %rsi
movl %r15d, %edx
callq 0x8b48
testb $0x2, 0x2d(%rbp)
jne 0x88a5
testq %r12, %r12
je 0x88a5
movq %rbp, %rdi
movq %r12, %rsi
callq 0x671e
jmp 0x88b2
movq 0x20(%rsp), %rdi
movq %rbp, %rsi
callq 0x6759
movq %r13, %rdi
callq 0x676f
movq %rax, %rbp
testq %rax, %rax
jne 0x887f
movq %rbx, %rdi
callq 0x6789
movq %rbx, %rdi
callq 0x5040
movq 0x18(%rsp), %r12
jmp 0x87f5
movq 0x18(%rsp), %rax
movq (%rax), %rbx
cmpq $0x0, (%rbx)
je 0x8afa
xorl %r12d, %r12d
movq 0x8(%rsp), %r13
movq %r12, 0x38(%rbx)
movq %r12, 0x40(%rbx)
movq 0x60(%rbx), %r14
cmpq $0x0, (%r14)
je 0x89d9
movq 0x48(%rbx), %rdi
addq 0x40(%rbx), %rdi
movzbl 0x2f(%r14), %esi
callq 0x6e40
movq %rbx, 0x18(%r14)
movq 0x48(%rbx), %r15
leaq (%r15,%rax), %rcx
movq %rcx, 0x38(%r14)
movq 0x40(%rbx), %rdx
movq %rdx, 0x18(%rsp)
addq %rdx, %rcx
addq 0x48(%r14), %rax
addq %rax, %r15
testb $0x1, 0x28(%rsp)
movq %rcx, 0x30(%r14)
movq %r15, 0x48(%rbx)
movl $0x0, %ebp
cmovneq %rax, %rbp
testb $0x2, 0x2d(%r14)
jne 0x8962
addq %rax, 0x50(%rbx)
movq %r12, 0x20(%rsp)
addq %r12, %rbp
movq 0x20(%r14), %r12
movq 0x220(%r13), %rsi
movq %r12, %rdi
callq 0x5160
testl %eax, %eax
je 0x8994
movq 0x228(%r13), %rsi
movq %r12, %rdi
callq 0x5160
testl %eax, %eax
jne 0x89c7
cmpl $0x0, 0x54(%r13)
je 0x89a2
cmpl $0x0, 0x64(%r13)
je 0x89c7
addq 0x18(%rsp), %r15
movq %r13, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x8ce1
addq %rax, 0x48(%rbx)
addq %rax, %rbp
testb $0x1, 0x28(%rsp)
cmoveq 0x20(%rsp), %rbp
movq (%r14), %r14
cmpq $0x0, (%r14)
movq %rbp, %r12
jne 0x890c
jmp 0x89dc
movq %r12, %rbp
movq (%rbx), %rbx
cmpq $0x0, (%rbx)
movq %rbp, %r12
jne 0x88f6
jmp 0x8afa
xorl %ebp, %ebp
movq 0x138(%r15), %r14
cmpq $0x0, (%r14)
je 0x8afa
leaq 0x60(%rbp), %r15
movq 0x10(%r14), %rax
cmpb $0x4, 0x39(%rax)
je 0x8aed
movq 0x20(%r14), %r12
cmpq $0x0, (%r12)
jne 0x8ae2
jmp 0x8aed
cmpq $0x0, 0x48(%r12)
je 0x8a83
movq %r14, %rdi
callq 0x7174
movq 0x20(%r12), %rdx
movl $0x40, %edi
movq %rax, %rsi
xorl %eax, %eax
callq 0x6f84
movq 0x10(%r12), %rax
movq 0x48(%rax), %rax
xorl %ecx, %ecx
movq (%rax,%rcx,8), %rdx
testq %rdx, %rdx
je 0x8a78
cmpq %r12, 0x38(%rdx)
jne 0x8a72
cmpb $0x3, 0x40(%rdx)
jne 0x8a72
movb $0x1, 0x40(%rdx)
movq 0x18(%rdx), %rdx
jmp 0x8a5d
incq %rcx
cmpq $0x20, %rcx
jne 0x8a59
jmp 0x8ade
movq 0x20(%r12), %rax
cmpb $0x0, (%rax)
je 0x8a9b
movq 0x10(%r12), %rdi
callq 0xd7a0
testl %eax, %eax
je 0x8a32
movq 0x8(%rsp), %rax
movzwl 0x200(%rax), %eax
movw %ax, 0x94(%r12)
movq %rbp, 0x18(%r12)
movq 0x30(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x30(%r12)
subq 0x40(%rbp), %rax
movq %rax, 0x38(%r12)
movq %r12, %rdi
callq 0x6789
movq %r15, %rdi
movq %rax, %rsi
callq 0x6759
movq (%r12), %r12
cmpq $0x0, (%r12)
jne 0x8a2a
movq (%r14), %r14
cmpq $0x0, (%r14)
jne 0x8a08
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq