// File: /workspace/github_c_makefile_star2_O0/fanf2[P]luajit-2/src/buildvm_peobj.c
// Function: emit_peobj
void emit_peobj(BuildCtx *ctx)
{
  PEheader pehdr;
  PEsection pesect[PEOBJ_NSECTIONS];
  uint32_t sofs;
  int i, nrsym;
  union { uint8_t b; uint32_t u; } host_endian;

  host_endian.u = 1;
  if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) {
    fprintf(stderr, "Error: different byte order for host and target\n");
    exit(1);
  }

  sofs = sizeof(PEheader) + PEOBJ_NSECTIONS*sizeof(PEsection);

  /* Fill in PE sections. */
  memset(&pesect, 0, PEOBJ_NSECTIONS*sizeof(PEsection));
  memcpy(pesect[PEOBJ_SECT_TEXT].name, ".text", sizeof(".text")-1);
  pesect[PEOBJ_SECT_TEXT].ofs = sofs;
  sofs += (pesect[PEOBJ_SECT_TEXT].size = (uint32_t)ctx->codesz);
  pesect[PEOBJ_SECT_TEXT].relocofs = sofs;
  sofs += (pesect[PEOBJ_SECT_TEXT].nreloc = (uint16_t)ctx->nreloc) * PEOBJ_RELOC_SIZE;
  /* Flags: 60 = read+execute, 50 = align16, 20 = code. */
  pesect[PEOBJ_SECT_TEXT].flags = 0x60500020;

#if LJ_TARGET_X64
  memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1);
  pesect[PEOBJ_SECT_PDATA].ofs = sofs;
  sofs += (pesect[PEOBJ_SECT_PDATA].size = 3*4);
  pesect[PEOBJ_SECT_PDATA].relocofs = sofs;
  sofs += (pesect[PEOBJ_SECT_PDATA].nreloc = 3) * PEOBJ_RELOC_SIZE;
  /* Flags: 40 = read, 30 = align4, 40 = initialized data. */
  pesect[PEOBJ_SECT_PDATA].flags = 0x40300040;

  memcpy(pesect[PEOBJ_SECT_XDATA].name, ".xdata", sizeof(".xdata")-1);
  pesect[PEOBJ_SECT_XDATA].ofs = sofs;
  sofs += (pesect[PEOBJ_SECT_XDATA].size = 8*2+4);  /* See below. */
  pesect[PEOBJ_SECT_XDATA].relocofs = sofs;
  sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE;
  /* Flags: 40 = read, 30 = align4, 40 = initialized data. */
  pesect[PEOBJ_SECT_XDATA].flags = 0x40300040;
#endif

  memcpy(pesect[PEOBJ_SECT_RDATA_Z].name, ".rdata$Z", sizeof(".rdata$Z")-1);
  pesect[PEOBJ_SECT_RDATA_Z].ofs = sofs;
  sofs += (pesect[PEOBJ_SECT_RDATA_Z].size = (uint32_t)strlen(ctx->dasm_ident)+1);
  /* Flags: 40 = read, 30 = align4, 40 = initialized data. */
  pesect[PEOBJ_SECT_RDATA_Z].flags = 0x40300040;

  /* Fill in PE header. */
  pehdr.arch = PEOBJ_ARCH_TARGET;
  pehdr.nsects = PEOBJ_NSECTIONS;
  pehdr.time = 0;  /* Timestamp is optional. */
  pehdr.symtabofs = sofs;
  pehdr.opthdrsz = 0;
  pehdr.flags = 0;

  /* Compute the size of the symbol table:
  ** @feat.00 + nsections*2
  ** + asm_start + nsym
  ** + nrsym
  */
  nrsym = ctx->nrelocsym;
  pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+ctx->nsym + nrsym;
#if LJ_TARGET_X64
  pehdr.nsyms += 1;  /* Symbol for lj_err_unwind_win64. */
#endif

  /* Write PE object header and all sections. */
  owrite(ctx, &pehdr, sizeof(PEheader));
  owrite(ctx, &pesect, sizeof(PEsection)*PEOBJ_NSECTIONS);

  /* Write .text section. */
  owrite(ctx, ctx->code, ctx->codesz);
  for (i = 0; i < ctx->nreloc; i++) {
    PEreloc reloc;
    reloc.vaddr = (uint32_t)ctx->reloc[i].ofs;
    reloc.symidx = 1+2+ctx->reloc[i].sym;  /* Reloc syms are after .text sym. */
    reloc.type = ctx->reloc[i].type ? PEOBJ_RELOC_REL32 : PEOBJ_RELOC_DIR32;
    owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
  }

#if LJ_TARGET_X64
  { /* Write .pdata section. */
    uint32_t pdata[3];  /* Start of .text, end of .text and .xdata. */
    PEreloc reloc;
    pdata[0] = 0; pdata[1] = (uint32_t)ctx->codesz; pdata[2] = 0;
    owrite(ctx, &pdata, sizeof(pdata));
    reloc.vaddr = 0; reloc.symidx = 1+2+nrsym+2+2+1;
    reloc.type = PEOBJ_RELOC_ADDR32NB;
    owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
    reloc.vaddr = 4; reloc.symidx = 1+2+nrsym+2+2+1;
    reloc.type = PEOBJ_RELOC_ADDR32NB;
    owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
    reloc.vaddr = 8; reloc.symidx = 1+2+nrsym+2;
    reloc.type = PEOBJ_RELOC_ADDR32NB;
    owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
  }
  { /* Write .xdata section. */
    uint16_t xdata[8+2];
    PEreloc reloc;
    xdata[0] = 0x01|0x08|0x10;  /* Ver. 1, uhander/ehandler, prolog size 0. */
    xdata[1] = 5;  /* Number of unwind codes, no frame pointer. */
    xdata[2] = 0x4200;  /* Stack offset 4*8+8 = aword*5. */
    xdata[3] = 0x3000;  /* Push rbx. */
    xdata[4] = 0x6000;  /* Push rsi. */
    xdata[5] = 0x7000;  /* Push rdi. */
    xdata[6] = 0x5000;  /* Push rbp. */
    xdata[7] = 0;  /* Alignment. */
    xdata[8] = xdata[9] = 0;  /* Relocated address of exception handler. */
    owrite(ctx, &xdata, sizeof(xdata));
    reloc.vaddr = sizeof(xdata)-4; reloc.symidx = 1+2+nrsym+2+2;
    reloc.type = PEOBJ_RELOC_ADDR32NB;
    owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
  }
#endif

  /* Write .rdata$Z section. */
  owrite(ctx, ctx->dasm_ident, strlen(ctx->dasm_ident)+1);

  /* Write symbol table. */
  strtab = NULL;  /* 1st pass: collect string sizes. */
  for (;;) {
    strtabofs = 4;
    /* Mark as SafeSEH compliant. */
    emit_peobj_sym(ctx, "@feat.00", 1,
		   PEOBJ_SECT_ABS, PEOBJ_TYPE_NULL, PEOBJ_SCL_STATIC);

    emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_TEXT);
    for (i = 0; i < nrsym; i++)
      emit_peobj_sym(ctx, ctx->relocsym[i], 0,
		     PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);

#if LJ_TARGET_X64
    emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA);
    emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA);
    emit_peobj_sym(ctx, "lj_err_unwind_win64", 0,
		   PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
#endif

    emit_peobj_sym(ctx, ctx->beginsym, 0,
		   PEOBJ_SECT_TEXT, PEOBJ_TYPE_NULL, PEOBJ_SCL_EXTERN);
    for (i = 0; i < ctx->nsym; i++)
      emit_peobj_sym(ctx, ctx->sym[i].name, (uint32_t)ctx->sym[i].ofs,
		     PEOBJ_SECT_TEXT, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);

    emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_RDATA_Z);

    if (strtab)
      break;
    /* 2nd pass: alloc strtab, write syms and copy strings. */
    strtab = (char *)malloc(strtabofs);
    *(uint32_t *)strtab = (uint32_t)strtabofs;
  }

  /* Write string table. */
  owrite(ctx, strtab, strtabofs);
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x130(%rsp)
movl $0x1, 0x60(%rsp)
movzbl 0x60(%rsp), %eax
cmpl $0x1, %eax
je 0xc223
movq 0xbdf0(%rip), %rax      # 0x17ff8
movq (%rax), %rdi
leaq 0x8742(%rip), %rsi      # 0x14954
movb $0x0, %al
callq 0x4110
movl $0x1, %edi
callq 0x4190
movl $0xb4, 0x6c(%rsp)
leaq 0x70(%rsp), %rdi
xorl %esi, %esi
movl $0xa0, %edx
callq 0x40c0
movl 0x8743(%rip), %eax      # 0x14985
movl %eax, 0x70(%rsp)
movb 0x873d(%rip), %al       # 0x14989
movb %al, 0x74(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0x130(%rsp), %rax
movq 0x30(%rax), %rax
movl %eax, 0x80(%rsp)
addl 0x6c(%rsp), %eax
movl %eax, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0x88(%rsp)
movq 0x130(%rsp), %rax
movl 0x44(%rax), %eax
movw %ax, 0x90(%rsp)
movzwl %ax, %eax
imull $0xa, %eax, %eax
addl 0x6c(%rsp), %eax
movl %eax, 0x6c(%rsp)
movl $0x60500020, 0x94(%rsp) # imm = 0x60500020
movl 0x86d8(%rip), %eax      # 0x1498b
movl %eax, 0x98(%rsp)
movw 0x86ce(%rip), %ax       # 0x1498f
movw %ax, 0x9c(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0xac(%rsp)
movl $0xc, 0xa8(%rsp)
movl 0x6c(%rsp), %eax
addl $0xc, %eax
movl %eax, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0xb0(%rsp)
movw $0x3, 0xb8(%rsp)
movl 0x6c(%rsp), %eax
addl $0x1e, %eax
movl %eax, 0x6c(%rsp)
movl $0x40300040, 0xbc(%rsp) # imm = 0x40300040
movl 0x8677(%rip), %eax      # 0x14992
movl %eax, 0xc0(%rsp)
movw 0x866d(%rip), %ax       # 0x14996
movw %ax, 0xc4(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0xd4(%rsp)
movl $0x14, 0xd0(%rsp)
movl 0x6c(%rsp), %eax
addl $0x14, %eax
movl %eax, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0xd8(%rsp)
movw $0x1, 0xe0(%rsp)
movl 0x6c(%rsp), %eax
addl $0xa, %eax
movl %eax, 0x6c(%rsp)
movl $0x40300040, 0xe4(%rsp) # imm = 0x40300040
movq 0x8615(%rip), %rax      # 0x14999
movq %rax, 0xe8(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0xfc(%rsp)
movq 0x130(%rsp), %rax
movq 0x80(%rax), %rdi
callq 0x40a0
addl $0x1, %eax
movl %eax, 0xf8(%rsp)
addl 0x6c(%rsp), %eax
movl %eax, 0x6c(%rsp)
movl $0x40300040, 0x10c(%rsp) # imm = 0x40300040
movw $0x8664, 0x11c(%rsp)    # imm = 0x8664
movw $0x4, 0x11e(%rsp)
movl $0x0, 0x120(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0x124(%rsp)
movw $0x0, 0x12c(%rsp)
movw $0x0, 0x12e(%rsp)
movq 0x130(%rsp), %rax
movl 0x48(%rax), %eax
movl %eax, 0x64(%rsp)
movq 0x130(%rsp), %rax
movl 0x40(%rax), %eax
addl $0xa, %eax
addl 0x64(%rsp), %eax
movl %eax, 0x128(%rsp)
movl 0x128(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x128(%rsp)
movq 0x130(%rsp), %rdi
leaq 0x11c(%rsp), %rsi
movl $0x14, %edx
callq 0x64b0
movq 0x130(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movl $0xa0, %edx
callq 0x64b0
movq 0x130(%rsp), %rdi
movq 0x130(%rsp), %rax
movq 0x28(%rax), %rsi
movq 0x130(%rsp), %rax
movq 0x30(%rax), %rdx
callq 0x64b0
movl $0x0, 0x68(%rsp)
movl 0x68(%rsp), %eax
movq 0x130(%rsp), %rcx
cmpl 0x44(%rcx), %eax
jge 0xc54f
movq 0x130(%rsp), %rax
addq $0x90, %rax
movslq 0x68(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, 0x54(%rsp)
movq 0x130(%rsp), %rax
addq $0x90, %rax
movslq 0x68(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
addl $0x3, %eax
movl %eax, 0x58(%rsp)
movq 0x130(%rsp), %rax
addq $0x90, %rax
movslq 0x68(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl 0x8(%rax), %edx
movl $0x2, %eax
movl $0x4, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movw %ax, 0x5c(%rsp)
movq 0x130(%rsp), %rdi
leaq 0x54(%rsp), %rsi
movl $0xa, %edx
callq 0x64b0
movl 0x68(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x68(%rsp)
jmp 0xc49d
movl $0x0, 0x48(%rsp)
movq 0x130(%rsp), %rax
movq 0x30(%rax), %rax
movl %eax, 0x4c(%rsp)
movl $0x0, 0x50(%rsp)
movq 0x130(%rsp), %rdi
leaq 0x48(%rsp), %rsi
movl $0xc, %edx
callq 0x64b0
movl $0x0, 0x3c(%rsp)
movl 0x64(%rsp), %eax
addl $0x3, %eax
addl $0x2, %eax
addl $0x2, %eax
addl $0x1, %eax
movl %eax, 0x40(%rsp)
movw $0x3, 0x44(%rsp)
movq 0x130(%rsp), %rdi
leaq 0x3c(%rsp), %rsi
movl $0xa, %edx
callq 0x64b0
movl $0x4, 0x3c(%rsp)
movl 0x64(%rsp), %eax
addl $0x3, %eax
addl $0x2, %eax
addl $0x2, %eax
addl $0x1, %eax
movl %eax, 0x40(%rsp)
movw $0x3, 0x44(%rsp)
movq 0x130(%rsp), %rdi
leaq 0x3c(%rsp), %rsi
movl $0xa, %edx
callq 0x64b0
movl $0x8, 0x3c(%rsp)
movl 0x64(%rsp), %eax
addl $0x3, %eax
addl $0x2, %eax
movl %eax, 0x40(%rsp)
movw $0x3, 0x44(%rsp)
movq 0x130(%rsp), %rdi
leaq 0x3c(%rsp), %rsi
movl $0xa, %edx
callq 0x64b0
movw $0x19, 0x20(%rsp)
movw $0x5, 0x22(%rsp)
movw $0x4200, 0x24(%rsp)     # imm = 0x4200
movw $0x3000, 0x26(%rsp)     # imm = 0x3000
movw $0x6000, 0x28(%rsp)     # imm = 0x6000
movw $0x7000, 0x2a(%rsp)     # imm = 0x7000
movw $0x5000, 0x2c(%rsp)     # imm = 0x5000
movw $0x0, 0x2e(%rsp)
movw $0x0, 0x32(%rsp)
movw $0x0, 0x30(%rsp)
movq 0x130(%rsp), %rdi
leaq 0x20(%rsp), %rsi
movl $0x14, %edx
callq 0x64b0
movl $0x10, 0x14(%rsp)
movl 0x64(%rsp), %eax
addl $0x3, %eax
addl $0x2, %eax
addl $0x2, %eax
movl %eax, 0x18(%rsp)
movw $0x3, 0x1c(%rsp)
movq 0x130(%rsp), %rdi
leaq 0x14(%rsp), %rsi
movl $0xa, %edx
callq 0x64b0
movq 0x130(%rsp), %rax
movq %rax, (%rsp)
movq 0x130(%rsp), %rax
movq 0x80(%rax), %rax
movq %rax, 0x8(%rsp)
movq 0x130(%rsp), %rax
movq 0x80(%rax), %rdi
callq 0x40a0
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
movq %rax, %rdx
addq $0x1, %rdx
callq 0x64b0
movq $0x0, 0xba82(%rip) # 0x18198
movq $0x4, 0xba7f(%rip) # 0x181a0
movq 0x130(%rsp), %rdi
leaq 0x8272(%rip), %rsi      # 0x149a2
movl $0x1, %edx
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
xorl %r8d, %r8d
movl $0x3, %r9d
callq 0xc920
movq 0x130(%rsp), %rdi
leaq 0x70(%rsp), %rsi
xorl %edx, %edx
callq 0xca60
movl $0x0, 0x68(%rsp)
movl 0x68(%rsp), %eax
cmpl 0x64(%rsp), %eax
jge 0xc7b0
movq 0x130(%rsp), %rdi
movq 0x130(%rsp), %rax
movq 0x60(%rax), %rax
movslq 0x68(%rsp), %rcx
movq (%rax,%rcx,8), %rsi
xorl %edx, %edx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movl $0x20, %r8d
movl $0x2, %r9d
callq 0xc920
movl 0x68(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x68(%rsp)
jmp 0xc764
movq 0x130(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movl $0x1, %edx
callq 0xca60
movq 0x130(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movl $0x2, %edx
callq 0xca60
movq 0x130(%rsp), %rdi
leaq 0x81be(%rip), %rsi      # 0x149ab
xorl %edx, %edx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movl $0x20, %r8d
movl $0x2, %r9d
callq 0xc920
movq 0x130(%rsp), %rdi
movq 0x130(%rsp), %rax
movq 0x70(%rax), %rsi
xorl %r8d, %r8d
movl $0x2, %r9d
movl %r8d, %edx
movl %r8d, %ecx
callq 0xc920
movl $0x0, 0x68(%rsp)
movl 0x68(%rsp), %eax
movq 0x130(%rsp), %rcx
cmpl 0x40(%rcx), %eax
jge 0xc8a4
movq 0x130(%rsp), %rdi
movq 0x130(%rsp), %rax
movq 0x58(%rax), %rax
movslq 0x68(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rsi
movq 0x130(%rsp), %rax
movq 0x58(%rax), %rax
movslq 0x68(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %edx
xorl %ecx, %ecx
movl $0x20, %r8d
movl $0x2, %r9d
callq 0xc920
movl 0x68(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x68(%rsp)
jmp 0xc835
movq 0x130(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movl $0x3, %edx
callq 0xca60
cmpq $0x0, 0xb8d5(%rip)      # 0x18198
je 0xc8c7
jmp 0xc8f1
movq 0xb8d2(%rip), %rdi      # 0x181a0
callq 0x4130
movq %rax, 0xb8be(%rip)      # 0x18198
movq 0xb8bf(%rip), %rax      # 0x181a0
movl %eax, %ecx
movq 0xb8ae(%rip), %rax      # 0x18198
movl %ecx, (%rax)
jmp 0xc716
movq 0x130(%rsp), %rdi
movq 0xb898(%rip), %rsi      # 0x18198
movq 0xb899(%rip), %rdx      # 0x181a0
callq 0x64b0
addq $0x138, %rsp            # imm = 0x138
retq
nopw %cs:(%rax,%rax)