// File: /workspace/github_c_makefile_star2_O0/ataradov[P]edbg/dbg_lin.c
// Function: parse_descriptors
static void parse_descriptors(debugger_t *debugger, int fd, uint8_t *desc, int size)
{
  memset(debugger, 0, sizeof(debugger_t));

  struct usb_device_descriptor *device = find_descriptor(&desc, &size, USB_DT_DEVICE, USB_DT_DEVICE_SIZE);
  if (!device)
    return;

  debugger->serial       = get_string(fd, device->iSerialNumber);
  debugger->manufacturer = get_string(fd, device->iManufacturer);
  debugger->product      = get_string(fd, device->iProduct);
  debugger->vid          = device->idVendor;
  debugger->pid          = device->idProduct;

  while (1)
  {
    struct usb_interface_descriptor *interface = find_descriptor(&desc, &size, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE);

    if (!interface)
      break;

    if (interface->bNumEndpoints != 2 || interface->bInterfaceSubClass != 0 || interface->bInterfaceProtocol != 0)
      continue;

    if (USB_CLASS_HID != interface->bInterfaceClass && USB_CLASS_VENDOR_SPEC != interface->bInterfaceClass)
      continue;

    if (!is_dap_str(debugger->product) && !is_dap_str(get_string(fd, interface->iInterface)))
      continue;

    struct usb_endpoint_descriptor *ep0 = find_descriptor(&desc, &size, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE);
    struct usb_endpoint_descriptor *ep1 = find_descriptor(&desc, &size, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE);

    if (!ep0 || !ep1)
      break;

    if (ep0->wMaxPacketSize != ep1->wMaxPacketSize)
      continue;

    if (64 != ep0->wMaxPacketSize && 512 != ep0->wMaxPacketSize && 1024 != ep0->wMaxPacketSize)
      continue;

    if ((ep0->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == (ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK))
      continue;

    if (USB_CLASS_HID == interface->bInterfaceClass)
    {
      if (!usb_endpoint_xfer_int(ep0) || !usb_endpoint_xfer_int(ep1))
        continue;

      if (usb_endpoint_dir_in(ep0))
      {
        debugger->v1_tx_ep = ep1->bEndpointAddress;
        debugger->v1_rx_ep = ep0->bEndpointAddress;
      }
      else
      {
        debugger->v1_tx_ep = ep0->bEndpointAddress;
        debugger->v1_rx_ep = ep1->bEndpointAddress;
      }

      debugger->v1_ep_size   = ep0->wMaxPacketSize;
      debugger->v1_interface = interface->bInterfaceNumber;

      debugger->versions |= DBG_CMSIS_DAP_V1;
    }

    if (USB_CLASS_VENDOR_SPEC == interface->bInterfaceClass)
    {
      if (!usb_endpoint_xfer_bulk(ep0) || !usb_endpoint_xfer_bulk(ep1))
        continue;

      if (usb_endpoint_dir_in(ep0))
        continue;

      debugger->v2_tx_ep     = ep0->bEndpointAddress;
      debugger->v2_rx_ep     = ep1->bEndpointAddress;
      debugger->v2_ep_size   = ep0->wMaxPacketSize;
      debugger->v2_interface = interface->bInterfaceNumber;

      debugger->versions |= DBG_CMSIS_DAP_V2;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq -0x8(%rbp), %rdi
xorl %esi, %esi
movl $0x68, %edx
callq 0x60f0
leaq -0x18(%rbp), %rdi
leaq -0x1c(%rbp), %rsi
movl $0x1, %edx
movl $0x12, %ecx
callq 0x13430
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x12b6d
jmp 0x12e80
movl -0xc(%rbp), %edi
movq -0x28(%rbp), %rax
movzbl 0x10(%rax), %esi
callq 0x134b0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
movl -0xc(%rbp), %edi
movq -0x28(%rbp), %rax
movzbl 0xe(%rax), %esi
callq 0x134b0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x18(%rax)
movl -0xc(%rbp), %edi
movq -0x28(%rbp), %rax
movzbl 0xf(%rax), %esi
callq 0x134b0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rax
movzwl 0x8(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x28(%rax)
movq -0x28(%rbp), %rax
movzwl 0xa(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x2c(%rax)
leaq -0x18(%rbp), %rdi
leaq -0x1c(%rbp), %rsi
movl $0x4, %edx
movl $0x9, %ecx
callq 0x13430
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x12c03
jmp 0x12e80
movq -0x30(%rbp), %rax
movzbl 0x4(%rax), %eax
cmpl $0x2, %eax
jne 0x12c2a
movq -0x30(%rbp), %rax
movzbl 0x6(%rax), %eax
cmpl $0x0, %eax
jne 0x12c2a
movq -0x30(%rbp), %rax
movzbl 0x7(%rax), %eax
cmpl $0x0, %eax
je 0x12c2c
jmp 0x12bdc
movq -0x30(%rbp), %rax
movzbl 0x5(%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
je 0x12c50
movq -0x30(%rbp), %rax
movzbl 0x5(%rax), %ecx
movl $0xff, %eax
cmpl %ecx, %eax
je 0x12c50
jmp 0x12bdc
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x13680
testb $0x1, %al
jne 0x12c82
movl -0xc(%rbp), %edi
movq -0x30(%rbp), %rax
movzbl 0x8(%rax), %esi
callq 0x134b0
movq %rax, %rdi
callq 0x13680
testb $0x1, %al
jne 0x12c82
jmp 0x12bdc
leaq -0x18(%rbp), %rdi
leaq -0x1c(%rbp), %rsi
movl $0x5, %edx
movl $0x7, %ecx
callq 0x13430
movq %rax, -0x38(%rbp)
leaq -0x18(%rbp), %rdi
leaq -0x1c(%rbp), %rsi
movl $0x5, %edx
movl $0x7, %ecx
callq 0x13430
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x12cc6
cmpq $0x0, -0x40(%rbp)
jne 0x12ccb
jmp 0x12e80
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %eax
movq -0x40(%rbp), %rcx
movzwl 0x4(%rcx), %ecx
cmpl %ecx, %eax
je 0x12ce4
jmp 0x12bdc
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %ecx
movl $0x40, %eax
cmpl %ecx, %eax
je 0x12d1c
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %ecx
movl $0x200, %eax            # imm = 0x200
cmpl %ecx, %eax
je 0x12d1c
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %ecx
movl $0x400, %eax            # imm = 0x400
cmpl %ecx, %eax
je 0x12d1c
jmp 0x12bdc
movq -0x38(%rbp), %rax
movzbl 0x2(%rax), %eax
andl $0x80, %eax
movq -0x40(%rbp), %rcx
movzbl 0x2(%rcx), %ecx
andl $0x80, %ecx
cmpl %ecx, %eax
jne 0x12d40
jmp 0x12bdc
movq -0x30(%rbp), %rax
movzbl 0x5(%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jne 0x12ded
movq -0x38(%rbp), %rdi
callq 0x136b0
cmpl $0x0, %eax
je 0x12d71
movq -0x40(%rbp), %rdi
callq 0x136b0
cmpl $0x0, %eax
jne 0x12d76
jmp 0x12bdc
movq -0x38(%rbp), %rdi
callq 0x136d0
cmpl $0x0, %eax
je 0x12da4
movq -0x40(%rbp), %rax
movzbl 0x2(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x48(%rax)
movq -0x38(%rbp), %rax
movzbl 0x2(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x4c(%rax)
jmp 0x12dc2
movq -0x38(%rbp), %rax
movzbl 0x2(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x48(%rax)
movq -0x40(%rbp), %rax
movzbl 0x2(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x4c(%rax)
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x44(%rax)
movq -0x30(%rbp), %rax
movzbl 0x2(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x40(%rax)
movq -0x8(%rbp), %rax
movl 0x30(%rax), %ecx
orl $0x2, %ecx
movl %ecx, 0x30(%rax)
movq -0x30(%rbp), %rax
movzbl 0x5(%rax), %ecx
movl $0xff, %eax
cmpl %ecx, %eax
jne 0x12e7b
movq -0x38(%rbp), %rdi
callq 0x13700
cmpl $0x0, %eax
je 0x12e1a
movq -0x40(%rbp), %rdi
callq 0x13700
cmpl $0x0, %eax
jne 0x12e1f
jmp 0x12bdc
movq -0x38(%rbp), %rdi
callq 0x136d0
cmpl $0x0, %eax
je 0x12e32
jmp 0x12bdc
movq -0x38(%rbp), %rax
movzbl 0x2(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x60(%rax)
movq -0x40(%rbp), %rax
movzbl 0x2(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x64(%rax)
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x5c(%rax)
movq -0x30(%rbp), %rax
movzbl 0x2(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x58(%rax)
movq -0x8(%rbp), %rax
movl 0x30(%rax), %ecx
orl $0x4, %ecx
movl %ecx, 0x30(%rax)
jmp 0x12bdc
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)