// File: /workspace/github_c_makefile_star2_O1/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, %rbx
movzbl 0x50(%rdi), %eax
leaq 0x17fb8(%rip), %rcx     # 0x2f180
movq (%rcx,%rax,8), %rax
callq *0x18(%rax)
movq 0x1f8(%rbx), %r12
testq %r12, %r12
je 0x171f1
testb $0x10, 0x24(%r12)
je 0x171eb
cmpl $0x6, 0x20(%r12)
je 0x171f4
movq (%r12), %r12
jmp 0x171d6
xorl %r12d, %r12d
movq 0x1f8(%rbx), %r13
testq %r13, %r13
je 0x1749c
xorl %r9d, %r9d
movq %rax, (%rsp)
movq %rbx, 0x20(%rsp)
cmpl $0x1, 0x20(%r13)
jne 0x1748d
movzwl 0x24(%r13), %esi
testb $0x10, %sil
je 0x1748d
movq 0x30(%r13), %r8
cmpq $-0x1, %r8
je 0x1748d
movq 0x28(%r13), %rdx
cmpq $-0x1, %rdx
je 0x1748d
testq %r12, %r12
sete %dil
movb 0x26(%r13), %cl
movq $-0x1, %r11
shlq %cl, %r11
andl $0xfff0, %esi           # imm = 0xFFF0
leal 0x4(%rsi), %ecx
movw %cx, 0x24(%r13)
testq %r9, %r9
cmoveq %r13, %r9
setne %cl
cmoveq %rax, %r10
orb %dil, %cl
jne 0x172b6
orl $0xc04, %esi            # imm = 0xC04
movw %si, 0x24(%r13)
movq %r8, %rcx
subq %rax, %rcx
andq %r11, %rcx
subq %rax, %r8
subq %rcx, %r8
movq %r8, 0x1c663(%rip)      # 0x33900
movq %rcx, 0x30(%r13)
testq %rdx, %rdx
je 0x172b0
addq %rax, %r8
subq %r8, %rdx
movq %rdx, 0x28(%r13)
movq %r13, %r9
xorl %r10d, %r10d
movq 0x1c0(%rbx), %rbp
cmpq $0x0, (%rbp)
je 0x1743c
xorl %ebx, %ebx
xorl %r14d, %r14d
xorl %r15d, %r15d
movq %r10, 0x10(%rsp)
movq %r11, 0x8(%rsp)
movq 0x38(%rbp), %rdx
cmpq 0x30(%r13), %rdx
jb 0x1742b
movq 0x48(%rbp), %rcx
testq %rcx, %rcx
je 0x1742b
addq %rdx, %rcx
cmpq 0x40(%r13), %rcx
ja 0x1742b
movb 0x21(%rbp), %dil
testb $0x1, %dil
je 0x1742b
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 0x1734f
movb %cl, 0x26(%r13)
testb $0x2, %dil
jne 0x173bc
testq %r15, %r15
je 0x173c5
movq %r9, 0x18(%rsp)
cmpq %rbp, %r15
je 0x17388
movq %r15, %rax
andb $-0x3, 0x21(%rax)
cmpb $0x3, 0x20(%rax)
jne 0x17375
movb $0x2, 0x20(%rax)
movq (%rax), %rcx
movq 0x48(%rax), %rdx
movq %rdx, 0x50(%rax)
movq %rcx, %rax
cmpq %rbp, %rcx
jne 0x17367
movq 0x8(%r13), %rsi
movq 0x18(%r15), %rdx
movq 0x8(%rbp), %rax
movq 0x18(%rax), %rcx
movl $0x52, %edi
xorl %eax, %eax
callq 0x6f84
xorl %r15d, %r15d
movq (%rsp), %rax
movq 0x18(%rsp), %r9
movq 0x10(%rsp), %r10
movq 0x8(%rsp), %r11
jmp 0x173c8
testq %r15, %r15
cmoveq %rbp, %r15
jmp 0x173c8
xorl %r15d, %r15d
testq %rbx, %rbx
je 0x1741a
testq %r15, %r15
jne 0x1741a
movq 0x38(%rbp), %r8
movq 0x38(%rbx), %rdx
movq 0x50(%rbx), %rcx
addq %rdx, %rcx
movq %r8, %rsi
subq %rcx, %rsi
jae 0x17416
testq %r8, %r8
je 0x1741a
movq 0x18(%rbx), %rsi
leaq 0xc35c(%rip), %rdi      # 0x23755
xorl %eax, %eax
movq %r9, %rbx
callq 0x52b0
movq 0x8(%rsp), %r11
movq 0x10(%rsp), %r10
movq %rbx, %r9
movq (%rsp), %rax
jmp 0x1741a
movq %rsi, 0x58(%rbx)
testq %r14, %r14
cmoveq %rbp, %r14
testq %r15, %r15
cmoveq %rbp, %r14
movq %rbp, %rbx
movq (%rbp), %rbp
cmpq $0x0, (%rbp)
jne 0x172da
jmp 0x1743f
xorl %r14d, %r14d
movq %r11, %rdx
notq %rdx
movq 0x30(%r13), %rcx
movq %rcx, %rsi
andq %rdx, %rsi
andq %r10, %rdx
subq %rdx, %rsi
movq %rsi, %rdx
sarq $0x3f, %rdx
andq %r11, %rdx
subq %rdx, %rsi
movq %rsi, 0x50(%r13)
testq %r14, %r14
je 0x17477
movq 0x50(%r14), %rdx
addq 0x38(%r14), %rdx
movq %rdx, 0x38(%r13)
addq %r10, %rsi
movq %rsi, 0x48(%r13)
subq %rcx, %rsi
addq 0x38(%r13), %rsi
movq %rsi, %r10
movq 0x20(%rsp), %rbx
movq (%r13), %r13
testq %r13, %r13
jne 0x17210
jmp 0x1749f
xorl %r9d, %r9d
testq %r12, %r12
je 0x174e2
testq %r9, %r9
je 0x174e2
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(%rbx), %rcx
xorl %eax, %eax
testq %rcx, %rcx
je 0x175d8
movl $0x43, %edx
movzwl 0x24(%rcx), %edi
testb $0x10, %dil
je 0x175cc
movq 0x30(%rcx), %rsi
cmpq $-0x1, %rsi
je 0x175cc
cmpq $-0x1, 0x28(%rcx)
je 0x175cc
incl %eax
movl 0x20(%rcx), %r8d
cmpl $0x6, %r8d
ja 0x17536
btl %r8d, %edx
jb 0x175cc
andl $0xfff0, %edi           # imm = 0xFFF0
movw %di, 0x24(%rcx)
movq 0x1c0(%rbx), %r8
movq (%r8), %r10
testq %r10, %r10
je 0x175c0
movq %r8, %rdi
movq %rdi, %r9
movq %r10, %rdi
movq 0x38(%r9), %r10
cmpq %rsi, %r10
jb 0x175b8
movq 0x48(%r9), %r11
testq %r11, %r11
je 0x175b8
addq %r10, %r11
cmpq 0x40(%rcx), %r11
ja 0x175b8
testb $0x1, 0x21(%r9)
je 0x175b8
movb 0x22(%r9), %r8b
rolb $0x4, %r8b
movl %r8d, %r10d
shrb $0x2, %r10b
movl %r8d, %r11d
andb $0x10, %r11b
shlb $0x2, %r11b
orb %r10b, %r11b
andb $0x50, %r11b
addb %r11b, %r11b
addb %r8b, %r8b
andb $0x40, %r8b
orb %r11b, %r8b
shrb $0x5, %r8b
movzbl %r8b, %r8d
orw %r8w, 0x24(%rcx)
movq %r9, %r8
movq (%rdi), %r10
testq %r10, %r10
jne 0x17552
movq 0x50(%r8), %rsi
addq 0x38(%r8), %rsi
movq %rsi, 0x38(%rcx)
movq (%rcx), %rcx
testq %rcx, %rcx
jne 0x174f9
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq