// File: /workspace/github_c_makefile_star2_O2/FH0[P]tun_direct/lwip-2.1.2/src/core/pbuf.c
// Function: pbuf_alloc
struct pbuf *
pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
{
  struct pbuf *p;
  u16_t offset = (u16_t)layer;
  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length));

  switch (type) {
    case PBUF_REF: /* fall through */
    case PBUF_ROM:
      p = pbuf_alloc_reference(NULL, length, type);
      break;
    case PBUF_POOL: {
      struct pbuf *q, *last;
      u16_t rem_len; /* remaining length */
      p = NULL;
      last = NULL;
      rem_len = length;
      do {
        u16_t qlen;
        q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);
        if (q == NULL) {
          PBUF_POOL_IS_EMPTY();
          /* free chain so far allocated */
          if (p) {
            pbuf_free(p);
          }
          /* bail out unsuccessfully */
          return NULL;
        }
        qlen = LWIP_MIN(rem_len, (u16_t)(PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)));
        pbuf_init_alloced_pbuf(q, LWIP_MEM_ALIGN((void *)((u8_t *)q + SIZEOF_STRUCT_PBUF + offset)),
                               rem_len, qlen, type, 0);
        LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
                    ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
        LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT",
                    (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 );
        if (p == NULL) {
          /* allocated head of pbuf chain (into p) */
          p = q;
        } else {
          /* make previous pbuf point to this pbuf */
          last->next = q;
        }
        last = q;
        rem_len = (u16_t)(rem_len - qlen);
        offset = 0;
      } while (rem_len > 0);
      break;
    }
    case PBUF_RAM: {
      u16_t payload_len = (u16_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length));
      mem_size_t alloc_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len);

      /* bug #50040: Check for integer overflow when calculating alloc_len */
      if ((payload_len < LWIP_MEM_ALIGN_SIZE(length)) ||
          (alloc_len < LWIP_MEM_ALIGN_SIZE(length))) {
        return NULL;
      }

      /* If pbuf is to be allocated in RAM, allocate memory for it. */
      p = (struct pbuf *)mem_malloc(alloc_len);
      if (p == NULL) {
        return NULL;
      }
      pbuf_init_alloced_pbuf(p, LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)),
                             length, length, type, 0);
      LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
                  ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
      break;
    }
    default:
      LWIP_ASSERT("pbuf_alloc: erroneous type", 0);
      return NULL;
  }
  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
  return p;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %esi, %ebx
cmpl $0x1, %edx
je 0x4c75
movl %edi, %ebp
cmpl $0x280, %edx            # imm = 0x280
je 0x4d00
cmpl $0x182, %edx            # imm = 0x182
je 0x4c87
cmpl $0x41, %edx
jne 0x4d89
movzwl %bx, %esi
xorl %edi, %edi
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x4da5
xorl %r12d, %r12d
pushq $0xb
popq %r14
xorl %r15d, %r15d
movl %r14d, %edi
callq 0x3b4a
testq %rax, %rax
je 0x4d3d
movq %rax, %rcx
movzwl %bx, %eax
movzwl %bp, %esi
movl $0x5ea, %edi            # imm = 0x5EA
subl %esi, %edi
movzwl %di, %edx
cmpl %eax, %edx
movl %eax, %edx
cmovbel %edi, %edx
leaq (%rcx,%rsi), %rdi
addq $0x18, %rdi
andq $0x0, (%rcx)
movq %rdi, 0x8(%rcx)
movw %ax, 0x10(%rcx)
movw %dx, 0x12(%rcx)
movl $0x10082, 0x14(%rcx)    # imm = 0x10082
cmpw $0x5ea, %si             # imm = 0x5EA
je 0x4d5c
movq %rcx, %rax
testq %r15, %r15
je 0x4cf1
movq %rcx, (%r12)
movq %r15, %rax
xorl %ebp, %ebp
movq %rcx, %r12
movq %rax, %r15
subw %dx, %bx
jne 0x4c91
jmp 0x4d53
movl %ebp, %eax
addw %bx, %ax
jb 0x4d51
movzwl %ax, %edi
addq $0x18, %rdi
callq 0x3ac9
testq %rax, %rax
je 0x4d51
movzwl %bp, %ecx
movl %ecx, %ecx
addq %rax, %rcx
addq $0x18, %rcx
andq $0x0, (%rax)
movq %rcx, 0x8(%rax)
movw %bx, 0x10(%rax)
movw %bx, 0x12(%rax)
movl $0x10080, 0x14(%rax)    # imm = 0x10080
jmp 0x4d53
movb $0x1, 0x18ba4(%rip)     # 0x1d8e8
testq %r15, %r15
je 0x4d51
movq %r15, %rdi
callq 0x4e16
xorl %eax, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0xf569(%rip), %rdi      # 0x142cc
leaq 0xfada(%rip), %rsi      # 0x14844
leaq 0xfab8(%rip), %rcx      # 0x14829
movl $0x103, %edx            # imm = 0x103
xorl %eax, %eax
callq 0x20d0
xorl %edi, %edi
callq 0x21b0
callq 0x2050
leaq 0xf53c(%rip), %rdi      # 0x142cc
leaq 0xfae1(%rip), %rsi      # 0x14878
leaq 0xfa8b(%rip), %rcx      # 0x14829
movl $0x127, %edx            # imm = 0x127
jmp 0x4d76