// File: /workspace/github_c_makefile_star2_O3/deplinenoise[P]vlink/t_elf32.c
// Function: elf32_segmentcheck
uint32_t elf32_segmentcheck(struct GlobalVars *gv)
/* 1. checks the PT_LOAD segments for intermediate uninitialized sections,
      which will be turned into initialized PROGBITS data sections
   2. sets segment permissions from contained sections
   3. calculates bytes to insert at beginning of segment to meet
      page-alignment restrictions
   4. initializes PT_PHDR segment
   Returns number of segments in list */
{
  unsigned long headersize = fff[gv->dest_format]->headersize(gv);
  struct Phdr *p,*phdrs,*first=NULL;
  struct LinkedSection *ls,*bss_start,*seg_lastdat,*seg_lastsec,*prg_lastdat;
  unsigned long foffs;
  uint32_t segcnt;

  /* find PHDR segment */
  for (phdrs=NULL,p=gv->phdrlist; p; p=p->next) {
    if ((p->flags&PHDR_USED) && p->type==PT_PHDR) {
      phdrs = p;
      break;
    }
  }

  for (p=gv->phdrlist,prg_lastdat=NULL; p; p=p->next) {
    if (p->type==PT_LOAD && (p->flags&PHDR_USED) &&
        p->start!=ADDR_NONE && p->start_vma!=ADDR_NONE) {
      unsigned long amask = (1L << p->alignment) - 1;
      long gapsize;

      bss_start = seg_lastsec = NULL;
      p->flags &= ~PHDR_PFMASK;
      p->flags |= PF_R;  /* at least 'read' should be allowed */

      /* determine initial file offset for first segment */
      if (!first) {
        first = p;
        if (phdrs) {  /* header is included in first segment */
          p->flags |= PHDR_PHDRS | PHDR_FILEHDR;
          foffs = 0;
          file_hdr_gap = (unsigned long)p->start
                          - ((unsigned long)(p->start - headersize) & ~amask)
                          - headersize;
          p->start -= headersize + file_hdr_gap;
          if (p->start_vma)
            p->start_vma -= headersize + file_hdr_gap;
        }
        else
          foffs = headersize;  /* first segment starts after header */
      }

      for (ls=(struct LinkedSection *)gv->lnksec.first,
            seg_lastdat=NULL,seg_lastsec=NULL;
           ls->n.next!=NULL;
           ls=(struct LinkedSection *)ls->n.next) {

        if (ls->copybase>=(unsigned long)p->start && ls->size &&
            (ls->copybase+ls->size)<=(unsigned long)p->mem_end &&
            (ls->flags & SF_ALLOC)) {

          p->flags |= conv_perm_to_elf(ls->protection);
          if (ls->alignment > p->alignment)
            p->alignment = ls->alignment;

          if (ls->flags & SF_UNINITIALIZED) {
            if (!bss_start)
              bss_start = ls;
          }
          else {
            if (bss_start) {
              struct LinkedSection *bssls;

              for (bssls=bss_start; bssls!=ls;
                   bssls=(struct LinkedSection *)bssls->n.next) {
                bssls->flags &= ~SF_UNINITIALIZED;
                if (bssls->type == ST_UDATA)
                  bssls->type = ST_DATA;
                bssls->filesize = bssls->size;
              }
              /* Warning: Intermediate uninitialized sections in ELF
                 segment will be turned into initialized */
              error(82,p->name,bss_start->name,
                    ((struct LinkedSection *)ls->n.pred)->name);
              bss_start = NULL;
            }
          }

          if (seg_lastsec && !bss_start) {
            if (ls->copybase >= seg_lastsec->copybase+seg_lastsec->filesize) {
              seg_lastsec->gapsize = ls->copybase - (seg_lastsec->copybase +
                                                     seg_lastsec->filesize);
            }
            else if (ls->copybase > 0) {
              ierror("elf32_segmentcheck(): overlapping sections "
                     "%s(%lx-%lx) followed by %s(%lx)",
                     seg_lastsec->name,seg_lastsec->copybase,
                     seg_lastsec->copybase + seg_lastsec->filesize,
                     ls->copybase);
            }
          }
          seg_lastsec = ls;
          if (!bss_start || !seg_lastdat)
            prg_lastdat = seg_lastdat = ls;
        }
      }

      /* calculate alignment gap for segment */
      /* @@@ do we align on LMA or VMA? */
      gapsize = (p->start & amask) - (foffs & amask);
      p->alignment_gap = gapsize<0 ? gapsize+amask+1 : gapsize;

      if (seg_lastdat)
        p->file_end = seg_lastdat->copybase + seg_lastdat->filesize;

      foffs += p->alignment_gap;
      p->offset = foffs;
      foffs += p->file_end - p->start;
    }
  }

  if (phdrs!=NULL && first!=NULL) {
    /* init PHDR segment using the first LOAD seg. which directly follows */
    phdrs->flags &= ~PHDR_PFMASK;
    phdrs->flags |= PF_R | PF_X;
    phdrs->start = first->start + sizeof(struct Elf32_Ehdr);
    phdrs->start_vma = phdrs->start;
    phdrs->mem_end = phdrs->start + headersize - sizeof(struct Elf32_Ehdr);
    phdrs->file_end = phdrs->mem_end;
    phdrs->offset = sizeof(struct Elf32_Ehdr);
  }

  for (p=gv->phdrlist,segcnt=0; p; p=p->next) {
    if ((p->flags&PHDR_USED)
        && p->start!=ADDR_NONE && p->start_vma!=ADDR_NONE) {
      segcnt++;

      if (p->type!=PT_LOAD && p->type!=PT_PHDR && p->type!=PT_NULL) {
        /* set segment permissions for remaining segment types */
        p->flags &= ~PHDR_PFMASK;
        for (ls=seg_lastdat=(struct LinkedSection *)gv->lnksec.first;
             ls->n.next!=NULL; ls=(struct LinkedSection *)ls->n.next) {
          if (ls->copybase>=(unsigned long)p->start && ls->size &&
              (ls->copybase+ls->size)<=(unsigned long)p->mem_end &&
              (ls->flags & SF_ALLOC)) {
            p->flags |= conv_perm_to_elf(ls->protection);
            seg_lastdat = ls;
          }
        }
        p->file_end = seg_lastdat->copybase + seg_lastdat->filesize;
      }
    }
  }

  return segcnt;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %r14
movzbl 0x50(%rdi), %eax
leaq 0x18173(%rip), %rcx     # 0x2f180
movq (%rcx,%rax,8), %rax
callq *0x18(%rax)
movq 0x1f8(%r14), %r13
testq %r13, %r13
je 0x17426
movq %r13, %r12
testb $0x10, 0x24(%r12)
je 0x17037
cmpl $0x6, 0x20(%r12)
je 0x17043
movq (%r12), %r12
testq %r12, %r12
jne 0x17027
xorl %r12d, %r12d
testq %r13, %r13
je 0x17326
xorl %r9d, %r9d
movq %rax, (%rsp)
movq %r14, 0x8(%rsp)
cmpl $0x1, 0x20(%r13)
jne 0x172d6
movzwl 0x24(%r13), %r8d
testb $0x10, %r8b
je 0x172d6
movq 0x30(%r13), %rdx
cmpq $-0x1, %rdx
je 0x172d6
movq 0x28(%r13), %rsi
cmpq $-0x1, %rsi
je 0x172d6
testq %r12, %r12
sete %dil
movb 0x26(%r13), %cl
movq $-0x1, %r11
shlq %cl, %r11
andl $0xfff0, %r8d           # imm = 0xFFF0
leal 0x4(%r8), %ecx
movw %cx, 0x24(%r13)
testq %r9, %r9
cmoveq %r13, %r9
setne %cl
cmoveq %rax, %r10
orb %dil, %cl
je 0x170cb
movq %rdx, %rdi
jmp 0x17106
orl $0xc04, %r8d            # imm = 0xC04
movw %r8w, 0x24(%r13)
movq %rdx, %rdi
subq %rax, %rdi
andq %r11, %rdi
subq %rax, %rdx
subq %rdi, %rdx
movq %rdx, 0x1c813(%rip)     # 0x33900
movq %rdi, 0x30(%r13)
testq %rsi, %rsi
je 0x17100
addq %rax, %rdx
subq %rdx, %rsi
movq %rsi, 0x28(%r13)
movq %r13, %r9
xorl %r10d, %r10d
movq 0x1c0(%r14), %rbp
movq (%rbp), %rcx
testq %rcx, %rcx
je 0x1728a
movq %r11, 0x18(%rsp)
movq %r10, 0x20(%rsp)
xorl %r14d, %r14d
xorl %ebx, %ebx
xorl %r15d, %r15d
movq 0x38(%rbp), %rsi
cmpq 0x30(%r13), %rsi
jb 0x17152
movq 0x48(%rbp), %rdx
testq %rdx, %rdx
je 0x17152
addq %rsi, %rdx
cmpq 0x40(%r13), %rdx
ja 0x17152
movb 0x21(%rbp), %dil
testb $0x1, %dil
jne 0x17168
movq %r14, %rbp
movq %rbp, %r14
movq %rcx, %rbp
movq (%rcx), %rcx
testq %rcx, %rcx
jne 0x1712c
jmp 0x17275
movb 0x22(%rbp), %cl
rolb $0x4, %cl
movl %ecx, %edx
shrb $0x2, %dl
movl %ecx, %esi
andb $0x10, %sil
shlb $0x2, %sil
orb %dl, %sil
andb $0x50, %sil
addb %sil, %sil
addb %cl, %cl
andb $0x40, %cl
orb %sil, %cl
shrb $0x5, %cl
movzbl %cl, %ecx
orw %cx, 0x24(%r13)
movb 0x23(%rbp), %cl
cmpb 0x26(%r13), %cl
jbe 0x171a7
movb %cl, 0x26(%r13)
testb $0x2, %dil
jne 0x1720a
testq %r15, %r15
je 0x17213
movq %r9, 0x10(%rsp)
cmpq %rbp, %r15
je 0x171e0
movq %r15, %rax
andb $-0x3, 0x21(%rax)
cmpb $0x3, 0x20(%rax)
jne 0x171cd
movb $0x2, 0x20(%rax)
movq (%rax), %rcx
movq 0x48(%rax), %rdx
movq %rdx, 0x50(%rax)
movq %rcx, %rax
cmpq %rbp, %rcx
jne 0x171bf
movq 0x8(%r13), %rsi
movq 0x18(%r15), %rdx
movq 0x8(%rbp), %rax
movq 0x18(%rax), %rcx
movl $0x52, %edi
xorl %eax, %eax
callq 0x6f14
xorl %r15d, %r15d
movq (%rsp), %rax
movq 0x10(%rsp), %r9
jmp 0x17216
testq %r15, %r15
cmoveq %rbp, %r15
jmp 0x17216
xorl %r15d, %r15d
testq %r14, %r14
je 0x1725e
testq %r15, %r15
jne 0x1725e
movq 0x38(%rbp), %r8
movq 0x38(%r14), %rdx
movq 0x50(%r14), %rcx
addq %rdx, %rcx
movq %r8, %rsi
subq %rcx, %rsi
jae 0x1725a
testq %r8, %r8
je 0x1725e
movq 0x18(%r14), %rsi
leaq 0xc4ee(%rip), %rdi      # 0x23735
xorl %eax, %eax
movq %r9, %r14
callq 0x52b0
movq %r14, %r9
movq (%rsp), %rax
jmp 0x1725e
movq %rsi, 0x58(%r14)
testq %rbx, %rbx
cmoveq %rbp, %rbx
testq %r15, %r15
cmoveq %rbp, %rbx
movq (%rbp), %rcx
jmp 0x17155
movq 0x30(%r13), %rdi
movq 0x8(%rsp), %r14
movq 0x20(%rsp), %r10
movq 0x18(%rsp), %r11
jmp 0x1728c
xorl %ebx, %ebx
movq %r11, %rdx
notq %rdx
movq %rdi, %rcx
andq %rdx, %rcx
andq %r10, %rdx
subq %rdx, %rcx
movq %rcx, %rdx
sarq $0x3f, %rdx
andq %r11, %rdx
subq %rdx, %rcx
movq %rcx, 0x50(%r13)
testq %rbx, %rbx
je 0x172c2
movq 0x50(%rbx), %rdx
addq 0x38(%rbx), %rdx
movq %rdx, 0x38(%r13)
jmp 0x172c6
movq 0x38(%r13), %rdx
addq %r10, %rcx
movq %rcx, 0x48(%r13)
subq %rdi, %rcx
addq %rdx, %rcx
movq %rcx, %r10
movq (%r13), %r13
testq %r13, %r13
jne 0x17058
testq %r12, %r12
je 0x17326
testq %r9, %r9
je 0x17326
movl 0x24(%r12), %ecx
andl $-0x10, %ecx
orl $0x5, %ecx
movw %cx, 0x24(%r12)
movq 0x30(%r9), %rdx
leaq 0x34(%rdx), %rcx
movq %rcx, 0x30(%r12)
movq %rcx, 0x28(%r12)
addq %rdx, %rax
movq %rax, 0x40(%r12)
movq %rax, 0x38(%r12)
movq $0x34, 0x48(%r12)
movq 0x1f8(%r14), %rcx
testq %rcx, %rcx
je 0x17426
xorl %eax, %eax
movl $0x43, %edx
movzwl 0x24(%rcx), %esi
testb $0x10, %sil
je 0x17418
movq 0x30(%rcx), %rdi
cmpq $-0x1, %rdi
je 0x17418
cmpq $-0x1, 0x28(%rcx)
je 0x17418
incl %eax
movl 0x20(%rcx), %r8d
cmpl $0x6, %r8d
ja 0x1737a
btl %r8d, %edx
jb 0x17418
andl $0xfff0, %esi           # imm = 0xFFF0
movw %si, 0x24(%rcx)
movq 0x1c0(%r14), %r10
movq (%r10), %r11
testq %r11, %r11
je 0x17409
movq %r10, %r8
movq %r8, %r9
movq %r11, %r8
movq 0x38(%r9), %r11
cmpq %rdi, %r11
jb 0x173be
movq 0x48(%r9), %rbx
testq %rbx, %rbx
je 0x173be
addq %r11, %rbx
cmpq 0x40(%rcx), %rbx
ja 0x173be
testb $0x1, 0x21(%r9)
jne 0x173ce
movq %r10, %r9
movq (%r8), %r11
movq %r9, %r10
testq %r11, %r11
jne 0x17396
jmp 0x1740c
movb 0x22(%r9), %r10b
rolb $0x4, %r10b
movl %r10d, %r11d
shrb $0x2, %r11b
movl %r10d, %ebx
andb $0x10, %bl
shlb $0x2, %bl
orb %r11b, %bl
andb $0x50, %bl
addb %bl, %bl
addb %r10b, %r10b
andb $0x40, %r10b
orb %bl, %r10b
shrb $0x5, %r10b
movzbl %r10b, %r10d
orl %r10d, %esi
movw %si, 0x24(%rcx)
jmp 0x173c1
movq %r10, %r9
movq 0x50(%r9), %rsi
addq 0x38(%r9), %rsi
movq %rsi, 0x38(%rcx)
movq (%rcx), %rcx
testq %rcx, %rcx
jne 0x1733d
jmp 0x17428
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq