ok  	github.com/google/syzkaller/dashboard/app	(cached)
?   	github.com/google/syzkaller/dashboard/dashapi	[no test files]
?   	github.com/google/syzkaller/executor	[no test files]
ok  	github.com/google/syzkaller/pkg/ast	(cached)
ok  	github.com/google/syzkaller/pkg/bisect	(cached)
ok  	github.com/google/syzkaller/pkg/build	(cached)
?   	github.com/google/syzkaller/pkg/cmdprof	[no test files]
ok  	github.com/google/syzkaller/pkg/compiler	(cached)
ok  	github.com/google/syzkaller/pkg/config	(cached)
?   	github.com/google/syzkaller/pkg/cover	[no test files]
--- FAIL: TestGenerate (1.39s)
    --- FAIL: TestGenerate/netbsd/amd64 (0.04s)
    	csource_test.go:67: seed=1590075587526028224
        --- FAIL: TestGenerate/netbsd/amd64/3 (0.33s)
        	csource_test.go:123: opts: {Threaded:true Collide:false Repeat:false RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:false Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <endian.h>
        		#include <errno.h>
        		#include <fcntl.h>
        		#include <pthread.h>
        		#include <pwd.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/resource.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void thread_start(void* (*fn)(void*), void* arg)
        		{
        			pthread_t th;
        			pthread_attr_t attr;
        			pthread_attr_init(&attr);
        			pthread_attr_setstacksize(&attr, 128 << 10);
        			int i;
        			for (i = 0; i < 100; i++) {
        				if (pthread_create(&th, &attr, fn, arg) == 0) {
        					pthread_attr_destroy(&attr);
        					return;
        				}
        				if (errno == EAGAIN) {
        					usleep(50);
        					continue;
        				}
        				break;
        			}
        			exit(1);
        		}
        		
        		typedef struct {
        			pthread_mutex_t mu;
        			pthread_cond_t cv;
        			int state;
        		} event_t;
        		
        		static void event_init(event_t* ev)
        		{
        			if (pthread_mutex_init(&ev->mu, 0))
        			exit(1);
        			if (pthread_cond_init(&ev->cv, 0))
        			exit(1);
        			ev->state = 0;
        		}
        		
        		static void event_reset(event_t* ev)
        		{
        			ev->state = 0;
        		}
        		
        		static void event_set(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			if (ev->state)
        			exit(1);
        			ev->state = 1;
        			pthread_mutex_unlock(&ev->mu);
        			pthread_cond_broadcast(&ev->cv);
        		}
        		
        		static void event_wait(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			while (!ev->state)
        				pthread_cond_wait(&ev->cv, &ev->mu);
        			pthread_mutex_unlock(&ev->mu);
        		}
        		
        		static int event_isset(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		static int event_timedwait(event_t* ev, uint64_t timeout)
        		{
        			uint64_t start = current_time_ms();
        			uint64_t now = start;
        			pthread_mutex_lock(&ev->mu);
        			for (;;) {
        				if (ev->state)
        					break;
        				uint64_t remain = timeout - (now - start);
        				struct timespec ts;
        				ts.tv_sec = remain / 1000;
        				ts.tv_nsec = (remain % 1000) * 1000 * 1000;
        				pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
        				now = current_time_ms();
        				if (now - start > timeout)
        					break;
        			}
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static void sandbox_common()
        		{
        			if (setsid() == -1)
        			exit(1);
        			struct rlimit rlim;
        			rlim.rlim_cur = rlim.rlim_max = 8 << 20;
        			setrlimit(RLIMIT_MEMLOCK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_FSIZE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_STACK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 0;
        			setrlimit(RLIMIT_CORE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 256;
        			setrlimit(RLIMIT_NOFILE, &rlim);
        		}
        		
        		static void loop();
        		
        		static int do_sandbox_none(void)
        		{
        			sandbox_common();
        			loop();
        			return 0;
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		struct thread_t {
        			int created, call;
        			event_t ready, done;
        		};
        		
        		static struct thread_t threads[16];
        		static void execute_call(int call);
        		static int running;
        		
        		static void* thr(void* arg)
        		{
        			struct thread_t* th = (struct thread_t*)arg;
        			for (;;) {
        				event_wait(&th->ready);
        				event_reset(&th->ready);
        				execute_call(th->call);
        				__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
        				event_set(&th->done);
        			}
        			return 0;
        		}
        		
        		static void loop(void)
        		{
        			int i, call, thread;
        			for (call = 0; call < 16; call++) {
        				for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
        					struct thread_t* th = &threads[thread];
        					if (!th->created) {
        						th->created = 1;
        						event_init(&th->ready);
        						event_init(&th->done);
        						event_set(&th->done);
        						thread_start(thr, th);
        					}
        					if (!event_isset(&th->done))
        						continue;
        					event_reset(&th->done);
        					th->call = call;
        					__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
        					event_set(&th->ready);
        					event_timedwait(&th->done, 45 + (call == 13 ? 3000 : 0) + (call == 14 ? 3000 : 0) + (call == 15 ? 300 : 0));
        					break;
        				}
        			}
        			for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
        				sleep_ms(1);
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_call(int call)
        		{
        				intptr_t res = 0;
        			switch (call) {
        			case 0:
        				syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        				break;
        			case 1:
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        				syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        				break;
        			case 2:
        		*(uint32_t*)0x20000080 = 0;
        				res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        				if (res != -1)
        						r[0] = res;
        				break;
        			case 3:
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        				break;
        			case 4:
        				res = syscall(SYS_getpgrp);
        				if (res != -1)
        						r[1] = res;
        				break;
        			case 5:
        				res = syscall(SYS_geteuid);
        				if (res != -1)
        						r[2] = res;
        				break;
        			case 6:
        				res = syscall(SYS_getegid);
        				if (res != -1)
        						r[3] = res;
        				break;
        			case 7:
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        				break;
        			case 8:
        				syscall(SYS_setgid, r[3]);
        				break;
        			case 9:
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        				syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        				break;
        			case 10:
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        				break;
        			case 11:
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        				syz_execute_func(0x200000c0);
        				break;
        			case 12:
        				break;
        			case 13:
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        				syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        				break;
        			case 14:
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        				res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        				if (res != -1)
        						r[4] = res;
        				break;
        			case 15:
        				syz_usb_disconnect(r[4]);
        				break;
        			}
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        					use_temporary_dir();
        					do_sandbox_none();
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:599:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:604:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor663032051 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/1 (0.33s)
        	csource_test.go:123: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:false Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <dirent.h>
        		#include <endian.h>
        		#include <errno.h>
        		#include <fcntl.h>
        		#include <pthread.h>
        		#include <pwd.h>
        		#include <signal.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/resource.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <sys/types.h>
        		#include <sys/wait.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void kill_and_wait(int pid, int* status)
        		{
        			kill(pid, SIGKILL);
        			while (waitpid(-1, status, 0) != pid) {
        			}
        		}
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void remove_dir(const char* dir)
        		{
        			DIR* dp;
        			struct dirent* ep;
        			dp = opendir(dir);
        			if (dp == NULL)
        			exit(1);
        			while ((ep = readdir(dp))) {
        				if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
        					continue;
        				char filename[FILENAME_MAX];
        				snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
        				struct stat st;
        				if (lstat(filename, &st))
        			exit(1);
        				if (S_ISDIR(st.st_mode)) {
        					remove_dir(filename);
        					continue;
        				}
        				if (unlink(filename))
        			exit(1);
        			}
        			closedir(dp);
        			if (rmdir(dir))
        			exit(1);
        		}
        		
        		static void thread_start(void* (*fn)(void*), void* arg)
        		{
        			pthread_t th;
        			pthread_attr_t attr;
        			pthread_attr_init(&attr);
        			pthread_attr_setstacksize(&attr, 128 << 10);
        			int i;
        			for (i = 0; i < 100; i++) {
        				if (pthread_create(&th, &attr, fn, arg) == 0) {
        					pthread_attr_destroy(&attr);
        					return;
        				}
        				if (errno == EAGAIN) {
        					usleep(50);
        					continue;
        				}
        				break;
        			}
        			exit(1);
        		}
        		
        		typedef struct {
        			pthread_mutex_t mu;
        			pthread_cond_t cv;
        			int state;
        		} event_t;
        		
        		static void event_init(event_t* ev)
        		{
        			if (pthread_mutex_init(&ev->mu, 0))
        			exit(1);
        			if (pthread_cond_init(&ev->cv, 0))
        			exit(1);
        			ev->state = 0;
        		}
        		
        		static void event_reset(event_t* ev)
        		{
        			ev->state = 0;
        		}
        		
        		static void event_set(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			if (ev->state)
        			exit(1);
        			ev->state = 1;
        			pthread_mutex_unlock(&ev->mu);
        			pthread_cond_broadcast(&ev->cv);
        		}
        		
        		static void event_wait(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			while (!ev->state)
        				pthread_cond_wait(&ev->cv, &ev->mu);
        			pthread_mutex_unlock(&ev->mu);
        		}
        		
        		static int event_isset(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		static int event_timedwait(event_t* ev, uint64_t timeout)
        		{
        			uint64_t start = current_time_ms();
        			uint64_t now = start;
        			pthread_mutex_lock(&ev->mu);
        			for (;;) {
        				if (ev->state)
        					break;
        				uint64_t remain = timeout - (now - start);
        				struct timespec ts;
        				ts.tv_sec = remain / 1000;
        				ts.tv_nsec = (remain % 1000) * 1000 * 1000;
        				pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
        				now = current_time_ms();
        				if (now - start > timeout)
        					break;
        			}
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static void sandbox_common()
        		{
        			if (setsid() == -1)
        			exit(1);
        			struct rlimit rlim;
        			rlim.rlim_cur = rlim.rlim_max = 8 << 20;
        			setrlimit(RLIMIT_MEMLOCK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_FSIZE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_STACK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 0;
        			setrlimit(RLIMIT_CORE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 256;
        			setrlimit(RLIMIT_NOFILE, &rlim);
        		}
        		
        		static void loop();
        		
        		static int do_sandbox_none(void)
        		{
        			sandbox_common();
        			loop();
        			return 0;
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		struct thread_t {
        			int created, call;
        			event_t ready, done;
        		};
        		
        		static struct thread_t threads[16];
        		static void execute_call(int call);
        		static int running;
        		
        		static void* thr(void* arg)
        		{
        			struct thread_t* th = (struct thread_t*)arg;
        			for (;;) {
        				event_wait(&th->ready);
        				event_reset(&th->ready);
        				execute_call(th->call);
        				__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
        				event_set(&th->done);
        			}
        			return 0;
        		}
        		
        		static void execute_one(void)
        		{
        			int i, call, thread;
        			for (call = 0; call < 16; call++) {
        				for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
        					struct thread_t* th = &threads[thread];
        					if (!th->created) {
        						th->created = 1;
        						event_init(&th->ready);
        						event_init(&th->done);
        						event_set(&th->done);
        						thread_start(thr, th);
        					}
        					if (!event_isset(&th->done))
        						continue;
        					event_reset(&th->done);
        					th->call = call;
        					__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
        					event_set(&th->ready);
        					event_timedwait(&th->done, 45 + (call == 13 ? 3000 : 0) + (call == 14 ? 3000 : 0) + (call == 15 ? 300 : 0));
        					break;
        				}
        			}
        			for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
        				sleep_ms(1);
        		}
        		
        		static void execute_one(void);
        		
        		#define WAIT_FLAGS 0
        		
        		static void loop(void)
        		{
        			int iter;
        			for (iter = 0;; iter++) {
        				char cwdbuf[32];
        				sprintf(cwdbuf, "./%d", iter);
        				if (mkdir(cwdbuf, 0777))
        			exit(1);
        				int pid = fork();
        				if (pid < 0)
        			exit(1);
        				if (pid == 0) {
        					if (chdir(cwdbuf))
        			exit(1);
        					execute_one();
        					exit(0);
        				}
        				int status = 0;
        				uint64_t start = current_time_ms();
        				for (;;) {
        					if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
        						break;
        					sleep_ms(1);
        					if (current_time_ms() - start < 5 * 1000)
        						continue;
        					kill_and_wait(pid, &status);
        					break;
        				}
        				remove_dir(cwdbuf);
        			}
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_call(int call)
        		{
        				intptr_t res = 0;
        			switch (call) {
        			case 0:
        				syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        				break;
        			case 1:
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        				syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        				break;
        			case 2:
        		*(uint32_t*)0x20000080 = 0;
        				res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        				if (res != -1)
        						r[0] = res;
        				break;
        			case 3:
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        				break;
        			case 4:
        				res = syscall(SYS_getpgrp);
        				if (res != -1)
        						r[1] = res;
        				break;
        			case 5:
        				res = syscall(SYS_geteuid);
        				if (res != -1)
        						r[2] = res;
        				break;
        			case 6:
        				res = syscall(SYS_getegid);
        				if (res != -1)
        						r[3] = res;
        				break;
        			case 7:
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        				break;
        			case 8:
        				syscall(SYS_setgid, r[3]);
        				break;
        			case 9:
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        				syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        				break;
        			case 10:
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        				break;
        			case 11:
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        				syz_execute_func(0x200000c0);
        				break;
        			case 12:
        				break;
        			case 13:
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        				syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        				break;
        			case 14:
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        				res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        				if (res != -1)
        						r[4] = res;
        				break;
        			case 15:
        				syz_usb_disconnect(r[4]);
        				break;
        			}
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        					use_temporary_dir();
        					do_sandbox_none();
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:637:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:642:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor001366244 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/0 (0.40s)
        	csource_test.go:123: opts: {Threaded:false Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:false Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <dirent.h>
        		#include <endian.h>
        		#include <fcntl.h>
        		#include <pwd.h>
        		#include <signal.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/resource.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <sys/types.h>
        		#include <sys/wait.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void kill_and_wait(int pid, int* status)
        		{
        			kill(pid, SIGKILL);
        			while (waitpid(-1, status, 0) != pid) {
        			}
        		}
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void remove_dir(const char* dir)
        		{
        			DIR* dp;
        			struct dirent* ep;
        			dp = opendir(dir);
        			if (dp == NULL)
        			exit(1);
        			while ((ep = readdir(dp))) {
        				if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
        					continue;
        				char filename[FILENAME_MAX];
        				snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
        				struct stat st;
        				if (lstat(filename, &st))
        			exit(1);
        				if (S_ISDIR(st.st_mode)) {
        					remove_dir(filename);
        					continue;
        				}
        				if (unlink(filename))
        			exit(1);
        			}
        			closedir(dp);
        			if (rmdir(dir))
        			exit(1);
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static void sandbox_common()
        		{
        			if (setsid() == -1)
        			exit(1);
        			struct rlimit rlim;
        			rlim.rlim_cur = rlim.rlim_max = 8 << 20;
        			setrlimit(RLIMIT_MEMLOCK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_FSIZE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_STACK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 0;
        			setrlimit(RLIMIT_CORE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 256;
        			setrlimit(RLIMIT_NOFILE, &rlim);
        		}
        		
        		static void loop();
        		
        		static int do_sandbox_none(void)
        		{
        			sandbox_common();
        			loop();
        			return 0;
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		static void execute_one(void);
        		
        		#define WAIT_FLAGS 0
        		
        		static void loop(void)
        		{
        			int iter;
        			for (iter = 0;; iter++) {
        				char cwdbuf[32];
        				sprintf(cwdbuf, "./%d", iter);
        				if (mkdir(cwdbuf, 0777))
        			exit(1);
        				int pid = fork();
        				if (pid < 0)
        			exit(1);
        				if (pid == 0) {
        					if (chdir(cwdbuf))
        			exit(1);
        					execute_one();
        					exit(0);
        				}
        				int status = 0;
        				uint64_t start = current_time_ms();
        				for (;;) {
        					if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
        						break;
        					sleep_ms(1);
        					if (current_time_ms() - start < 5 * 1000)
        						continue;
        					kill_and_wait(pid, &status);
        					break;
        				}
        				remove_dir(cwdbuf);
        			}
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_one(void)
        		{
        				intptr_t res = 0;
        			syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        			syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        		*(uint32_t*)0x20000080 = 0;
        			res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        			if (res != -1)
        				r[0] = res;
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        			syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        			res = syscall(SYS_getpgrp);
        			if (res != -1)
        				r[1] = res;
        			res = syscall(SYS_geteuid);
        			if (res != -1)
        				r[2] = res;
        			res = syscall(SYS_getegid);
        			if (res != -1)
        				r[3] = res;
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        			syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        			syscall(SYS_setgid, r[3]);
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        			syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        			syz_execute_func(0x200000c0);
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        			syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        			res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        			if (res != -1)
        				r[4] = res;
        			syz_usb_disconnect(r[4]);
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        					use_temporary_dir();
        					do_sandbox_none();
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:546:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:551:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor127356829 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/4 (0.41s)
        	csource_test.go:123: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:10 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:false Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <dirent.h>
        		#include <endian.h>
        		#include <errno.h>
        		#include <fcntl.h>
        		#include <pthread.h>
        		#include <pwd.h>
        		#include <signal.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/resource.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <sys/types.h>
        		#include <sys/wait.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void kill_and_wait(int pid, int* status)
        		{
        			kill(pid, SIGKILL);
        			while (waitpid(-1, status, 0) != pid) {
        			}
        		}
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void remove_dir(const char* dir)
        		{
        			DIR* dp;
        			struct dirent* ep;
        			dp = opendir(dir);
        			if (dp == NULL)
        			exit(1);
        			while ((ep = readdir(dp))) {
        				if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
        					continue;
        				char filename[FILENAME_MAX];
        				snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
        				struct stat st;
        				if (lstat(filename, &st))
        			exit(1);
        				if (S_ISDIR(st.st_mode)) {
        					remove_dir(filename);
        					continue;
        				}
        				if (unlink(filename))
        			exit(1);
        			}
        			closedir(dp);
        			if (rmdir(dir))
        			exit(1);
        		}
        		
        		static void thread_start(void* (*fn)(void*), void* arg)
        		{
        			pthread_t th;
        			pthread_attr_t attr;
        			pthread_attr_init(&attr);
        			pthread_attr_setstacksize(&attr, 128 << 10);
        			int i;
        			for (i = 0; i < 100; i++) {
        				if (pthread_create(&th, &attr, fn, arg) == 0) {
        					pthread_attr_destroy(&attr);
        					return;
        				}
        				if (errno == EAGAIN) {
        					usleep(50);
        					continue;
        				}
        				break;
        			}
        			exit(1);
        		}
        		
        		typedef struct {
        			pthread_mutex_t mu;
        			pthread_cond_t cv;
        			int state;
        		} event_t;
        		
        		static void event_init(event_t* ev)
        		{
        			if (pthread_mutex_init(&ev->mu, 0))
        			exit(1);
        			if (pthread_cond_init(&ev->cv, 0))
        			exit(1);
        			ev->state = 0;
        		}
        		
        		static void event_reset(event_t* ev)
        		{
        			ev->state = 0;
        		}
        		
        		static void event_set(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			if (ev->state)
        			exit(1);
        			ev->state = 1;
        			pthread_mutex_unlock(&ev->mu);
        			pthread_cond_broadcast(&ev->cv);
        		}
        		
        		static void event_wait(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			while (!ev->state)
        				pthread_cond_wait(&ev->cv, &ev->mu);
        			pthread_mutex_unlock(&ev->mu);
        		}
        		
        		static int event_isset(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		static int event_timedwait(event_t* ev, uint64_t timeout)
        		{
        			uint64_t start = current_time_ms();
        			uint64_t now = start;
        			pthread_mutex_lock(&ev->mu);
        			for (;;) {
        				if (ev->state)
        					break;
        				uint64_t remain = timeout - (now - start);
        				struct timespec ts;
        				ts.tv_sec = remain / 1000;
        				ts.tv_nsec = (remain % 1000) * 1000 * 1000;
        				pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
        				now = current_time_ms();
        				if (now - start > timeout)
        					break;
        			}
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static void sandbox_common()
        		{
        			if (setsid() == -1)
        			exit(1);
        			struct rlimit rlim;
        			rlim.rlim_cur = rlim.rlim_max = 8 << 20;
        			setrlimit(RLIMIT_MEMLOCK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_FSIZE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_STACK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 0;
        			setrlimit(RLIMIT_CORE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 256;
        			setrlimit(RLIMIT_NOFILE, &rlim);
        		}
        		
        		static void loop();
        		
        		static int do_sandbox_none(void)
        		{
        			sandbox_common();
        			loop();
        			return 0;
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		struct thread_t {
        			int created, call;
        			event_t ready, done;
        		};
        		
        		static struct thread_t threads[16];
        		static void execute_call(int call);
        		static int running;
        		
        		static void* thr(void* arg)
        		{
        			struct thread_t* th = (struct thread_t*)arg;
        			for (;;) {
        				event_wait(&th->ready);
        				event_reset(&th->ready);
        				execute_call(th->call);
        				__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
        				event_set(&th->done);
        			}
        			return 0;
        		}
        		
        		static void execute_one(void)
        		{
        			int i, call, thread;
        			for (call = 0; call < 16; call++) {
        				for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
        					struct thread_t* th = &threads[thread];
        					if (!th->created) {
        						th->created = 1;
        						event_init(&th->ready);
        						event_init(&th->done);
        						event_set(&th->done);
        						thread_start(thr, th);
        					}
        					if (!event_isset(&th->done))
        						continue;
        					event_reset(&th->done);
        					th->call = call;
        					__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
        					event_set(&th->ready);
        					event_timedwait(&th->done, 45 + (call == 13 ? 3000 : 0) + (call == 14 ? 3000 : 0) + (call == 15 ? 300 : 0));
        					break;
        				}
        			}
        			for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
        				sleep_ms(1);
        		}
        		
        		static void execute_one(void);
        		
        		#define WAIT_FLAGS 0
        		
        		static void loop(void)
        		{
        			int iter;
        			for (iter = 0; iter < 10; iter++) {
        				char cwdbuf[32];
        				sprintf(cwdbuf, "./%d", iter);
        				if (mkdir(cwdbuf, 0777))
        			exit(1);
        				int pid = fork();
        				if (pid < 0)
        			exit(1);
        				if (pid == 0) {
        					if (chdir(cwdbuf))
        			exit(1);
        					execute_one();
        					exit(0);
        				}
        				int status = 0;
        				uint64_t start = current_time_ms();
        				for (;;) {
        					if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
        						break;
        					sleep_ms(1);
        					if (current_time_ms() - start < 5 * 1000)
        						continue;
        					kill_and_wait(pid, &status);
        					break;
        				}
        				remove_dir(cwdbuf);
        			}
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_call(int call)
        		{
        				intptr_t res = 0;
        			switch (call) {
        			case 0:
        				syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        				break;
        			case 1:
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        				syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        				break;
        			case 2:
        		*(uint32_t*)0x20000080 = 0;
        				res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        				if (res != -1)
        						r[0] = res;
        				break;
        			case 3:
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        				break;
        			case 4:
        				res = syscall(SYS_getpgrp);
        				if (res != -1)
        						r[1] = res;
        				break;
        			case 5:
        				res = syscall(SYS_geteuid);
        				if (res != -1)
        						r[2] = res;
        				break;
        			case 6:
        				res = syscall(SYS_getegid);
        				if (res != -1)
        						r[3] = res;
        				break;
        			case 7:
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        				break;
        			case 8:
        				syscall(SYS_setgid, r[3]);
        				break;
        			case 9:
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        				syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        				break;
        			case 10:
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        				break;
        			case 11:
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        				syz_execute_func(0x200000c0);
        				break;
        			case 12:
        				break;
        			case 13:
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        				syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        				break;
        			case 14:
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        				res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        				if (res != -1)
        						r[4] = res;
        				break;
        			case 15:
        				syz_usb_disconnect(r[4]);
        				break;
        			}
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        					use_temporary_dir();
        					do_sandbox_none();
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:637:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:642:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor937182134 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/2 (0.42s)
        	csource_test.go:123: opts: {Threaded:true Collide:true Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:false Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <dirent.h>
        		#include <endian.h>
        		#include <errno.h>
        		#include <fcntl.h>
        		#include <pthread.h>
        		#include <pwd.h>
        		#include <signal.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/resource.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <sys/types.h>
        		#include <sys/wait.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void kill_and_wait(int pid, int* status)
        		{
        			kill(pid, SIGKILL);
        			while (waitpid(-1, status, 0) != pid) {
        			}
        		}
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void remove_dir(const char* dir)
        		{
        			DIR* dp;
        			struct dirent* ep;
        			dp = opendir(dir);
        			if (dp == NULL)
        			exit(1);
        			while ((ep = readdir(dp))) {
        				if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
        					continue;
        				char filename[FILENAME_MAX];
        				snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
        				struct stat st;
        				if (lstat(filename, &st))
        			exit(1);
        				if (S_ISDIR(st.st_mode)) {
        					remove_dir(filename);
        					continue;
        				}
        				if (unlink(filename))
        			exit(1);
        			}
        			closedir(dp);
        			if (rmdir(dir))
        			exit(1);
        		}
        		
        		static void thread_start(void* (*fn)(void*), void* arg)
        		{
        			pthread_t th;
        			pthread_attr_t attr;
        			pthread_attr_init(&attr);
        			pthread_attr_setstacksize(&attr, 128 << 10);
        			int i;
        			for (i = 0; i < 100; i++) {
        				if (pthread_create(&th, &attr, fn, arg) == 0) {
        					pthread_attr_destroy(&attr);
        					return;
        				}
        				if (errno == EAGAIN) {
        					usleep(50);
        					continue;
        				}
        				break;
        			}
        			exit(1);
        		}
        		
        		typedef struct {
        			pthread_mutex_t mu;
        			pthread_cond_t cv;
        			int state;
        		} event_t;
        		
        		static void event_init(event_t* ev)
        		{
        			if (pthread_mutex_init(&ev->mu, 0))
        			exit(1);
        			if (pthread_cond_init(&ev->cv, 0))
        			exit(1);
        			ev->state = 0;
        		}
        		
        		static void event_reset(event_t* ev)
        		{
        			ev->state = 0;
        		}
        		
        		static void event_set(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			if (ev->state)
        			exit(1);
        			ev->state = 1;
        			pthread_mutex_unlock(&ev->mu);
        			pthread_cond_broadcast(&ev->cv);
        		}
        		
        		static void event_wait(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			while (!ev->state)
        				pthread_cond_wait(&ev->cv, &ev->mu);
        			pthread_mutex_unlock(&ev->mu);
        		}
        		
        		static int event_isset(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		static int event_timedwait(event_t* ev, uint64_t timeout)
        		{
        			uint64_t start = current_time_ms();
        			uint64_t now = start;
        			pthread_mutex_lock(&ev->mu);
        			for (;;) {
        				if (ev->state)
        					break;
        				uint64_t remain = timeout - (now - start);
        				struct timespec ts;
        				ts.tv_sec = remain / 1000;
        				ts.tv_nsec = (remain % 1000) * 1000 * 1000;
        				pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
        				now = current_time_ms();
        				if (now - start > timeout)
        					break;
        			}
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static void sandbox_common()
        		{
        			if (setsid() == -1)
        			exit(1);
        			struct rlimit rlim;
        			rlim.rlim_cur = rlim.rlim_max = 8 << 20;
        			setrlimit(RLIMIT_MEMLOCK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_FSIZE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_STACK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 0;
        			setrlimit(RLIMIT_CORE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 256;
        			setrlimit(RLIMIT_NOFILE, &rlim);
        		}
        		
        		static void loop();
        		
        		static int do_sandbox_none(void)
        		{
        			sandbox_common();
        			loop();
        			return 0;
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		struct thread_t {
        			int created, call;
        			event_t ready, done;
        		};
        		
        		static struct thread_t threads[16];
        		static void execute_call(int call);
        		static int running;
        		
        		static void* thr(void* arg)
        		{
        			struct thread_t* th = (struct thread_t*)arg;
        			for (;;) {
        				event_wait(&th->ready);
        				event_reset(&th->ready);
        				execute_call(th->call);
        				__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
        				event_set(&th->done);
        			}
        			return 0;
        		}
        		
        		static void execute_one(void)
        		{
        			int i, call, thread;
        			int collide = 0;
        		again:
        			for (call = 0; call < 16; call++) {
        				for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
        					struct thread_t* th = &threads[thread];
        					if (!th->created) {
        						th->created = 1;
        						event_init(&th->ready);
        						event_init(&th->done);
        						event_set(&th->done);
        						thread_start(thr, th);
        					}
        					if (!event_isset(&th->done))
        						continue;
        					event_reset(&th->done);
        					th->call = call;
        					__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
        					event_set(&th->ready);
        					if (collide && (call % 2) == 0)
        						break;
        					event_timedwait(&th->done, 45 + (call == 13 ? 3000 : 0) + (call == 14 ? 3000 : 0) + (call == 15 ? 300 : 0));
        					break;
        				}
        			}
        			for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
        				sleep_ms(1);
        			if (!collide) {
        				collide = 1;
        				goto again;
        			}
        		}
        		
        		static void execute_one(void);
        		
        		#define WAIT_FLAGS 0
        		
        		static void loop(void)
        		{
        			int iter;
        			for (iter = 0;; iter++) {
        				char cwdbuf[32];
        				sprintf(cwdbuf, "./%d", iter);
        				if (mkdir(cwdbuf, 0777))
        			exit(1);
        				int pid = fork();
        				if (pid < 0)
        			exit(1);
        				if (pid == 0) {
        					if (chdir(cwdbuf))
        			exit(1);
        					execute_one();
        					exit(0);
        				}
        				int status = 0;
        				uint64_t start = current_time_ms();
        				for (;;) {
        					if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
        						break;
        					sleep_ms(1);
        					if (current_time_ms() - start < 5 * 1000)
        						continue;
        					kill_and_wait(pid, &status);
        					break;
        				}
        				remove_dir(cwdbuf);
        			}
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_call(int call)
        		{
        				intptr_t res = 0;
        			switch (call) {
        			case 0:
        				syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        				break;
        			case 1:
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        				syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        				break;
        			case 2:
        		*(uint32_t*)0x20000080 = 0;
        				res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        				if (res != -1)
        						r[0] = res;
        				break;
        			case 3:
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        				break;
        			case 4:
        				res = syscall(SYS_getpgrp);
        				if (res != -1)
        						r[1] = res;
        				break;
        			case 5:
        				res = syscall(SYS_geteuid);
        				if (res != -1)
        						r[2] = res;
        				break;
        			case 6:
        				res = syscall(SYS_getegid);
        				if (res != -1)
        						r[3] = res;
        				break;
        			case 7:
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        				break;
        			case 8:
        				syscall(SYS_setgid, r[3]);
        				break;
        			case 9:
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        				syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        				break;
        			case 10:
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        				break;
        			case 11:
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        				syz_execute_func(0x200000c0);
        				break;
        			case 12:
        				break;
        			case 13:
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        				syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        				break;
        			case 14:
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        				res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        				if (res != -1)
        						r[4] = res;
        				break;
        			case 15:
        				syz_usb_disconnect(r[4]);
        				break;
        			}
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        					use_temporary_dir();
        					do_sandbox_none();
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:637:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:642:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor910728663 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/8 (0.42s)
        	csource_test.go:123: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:setuid Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:false Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <dirent.h>
        		#include <endian.h>
        		#include <errno.h>
        		#include <fcntl.h>
        		#include <pthread.h>
        		#include <pwd.h>
        		#include <signal.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/resource.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <sys/types.h>
        		#include <sys/wait.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void kill_and_wait(int pid, int* status)
        		{
        			kill(pid, SIGKILL);
        			while (waitpid(-1, status, 0) != pid) {
        			}
        		}
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void remove_dir(const char* dir)
        		{
        			DIR* dp;
        			struct dirent* ep;
        			dp = opendir(dir);
        			if (dp == NULL)
        			exit(1);
        			while ((ep = readdir(dp))) {
        				if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
        					continue;
        				char filename[FILENAME_MAX];
        				snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
        				struct stat st;
        				if (lstat(filename, &st))
        			exit(1);
        				if (S_ISDIR(st.st_mode)) {
        					remove_dir(filename);
        					continue;
        				}
        				if (unlink(filename))
        			exit(1);
        			}
        			closedir(dp);
        			if (rmdir(dir))
        			exit(1);
        		}
        		
        		static void thread_start(void* (*fn)(void*), void* arg)
        		{
        			pthread_t th;
        			pthread_attr_t attr;
        			pthread_attr_init(&attr);
        			pthread_attr_setstacksize(&attr, 128 << 10);
        			int i;
        			for (i = 0; i < 100; i++) {
        				if (pthread_create(&th, &attr, fn, arg) == 0) {
        					pthread_attr_destroy(&attr);
        					return;
        				}
        				if (errno == EAGAIN) {
        					usleep(50);
        					continue;
        				}
        				break;
        			}
        			exit(1);
        		}
        		
        		typedef struct {
        			pthread_mutex_t mu;
        			pthread_cond_t cv;
        			int state;
        		} event_t;
        		
        		static void event_init(event_t* ev)
        		{
        			if (pthread_mutex_init(&ev->mu, 0))
        			exit(1);
        			if (pthread_cond_init(&ev->cv, 0))
        			exit(1);
        			ev->state = 0;
        		}
        		
        		static void event_reset(event_t* ev)
        		{
        			ev->state = 0;
        		}
        		
        		static void event_set(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			if (ev->state)
        			exit(1);
        			ev->state = 1;
        			pthread_mutex_unlock(&ev->mu);
        			pthread_cond_broadcast(&ev->cv);
        		}
        		
        		static void event_wait(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			while (!ev->state)
        				pthread_cond_wait(&ev->cv, &ev->mu);
        			pthread_mutex_unlock(&ev->mu);
        		}
        		
        		static int event_isset(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		static int event_timedwait(event_t* ev, uint64_t timeout)
        		{
        			uint64_t start = current_time_ms();
        			uint64_t now = start;
        			pthread_mutex_lock(&ev->mu);
        			for (;;) {
        				if (ev->state)
        					break;
        				uint64_t remain = timeout - (now - start);
        				struct timespec ts;
        				ts.tv_sec = remain / 1000;
        				ts.tv_nsec = (remain % 1000) * 1000 * 1000;
        				pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
        				now = current_time_ms();
        				if (now - start > timeout)
        					break;
        			}
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static void sandbox_common()
        		{
        			if (setsid() == -1)
        			exit(1);
        			struct rlimit rlim;
        			rlim.rlim_cur = rlim.rlim_max = 8 << 20;
        			setrlimit(RLIMIT_MEMLOCK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_FSIZE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_STACK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 0;
        			setrlimit(RLIMIT_CORE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 256;
        			setrlimit(RLIMIT_NOFILE, &rlim);
        		}
        		
        		static void loop();
        		
        		static int wait_for_loop(int pid)
        		{
        			if (pid < 0)
        			exit(1);
        			int status = 0;
        			while (waitpid(-1, &status, WUNTRACED) != pid) {
        			}
        			return WEXITSTATUS(status);
        		}
        		
        		static int do_sandbox_setuid(void)
        		{
        			int pid = fork();
        			if (pid != 0)
        				return wait_for_loop(pid);
        			sandbox_common();
        			char pwbuf[1024];
        			struct passwd *pw, pwres;
        			if (getpwnam_r("nobody", &pwres, pwbuf, sizeof(pwbuf), &pw) != 0 || !pw)
        			exit(1);
        			if (setgroups(0, NULL))
        			exit(1);
        			if (setgid(pw->pw_gid))
        			exit(1);
        			if (setuid(pw->pw_uid))
        			exit(1);
        			loop();
        			exit(1);
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		struct thread_t {
        			int created, call;
        			event_t ready, done;
        		};
        		
        		static struct thread_t threads[16];
        		static void execute_call(int call);
        		static int running;
        		
        		static void* thr(void* arg)
        		{
        			struct thread_t* th = (struct thread_t*)arg;
        			for (;;) {
        				event_wait(&th->ready);
        				event_reset(&th->ready);
        				execute_call(th->call);
        				__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
        				event_set(&th->done);
        			}
        			return 0;
        		}
        		
        		static void execute_one(void)
        		{
        			int i, call, thread;
        			for (call = 0; call < 16; call++) {
        				for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
        					struct thread_t* th = &threads[thread];
        					if (!th->created) {
        						th->created = 1;
        						event_init(&th->ready);
        						event_init(&th->done);
        						event_set(&th->done);
        						thread_start(thr, th);
        					}
        					if (!event_isset(&th->done))
        						continue;
        					event_reset(&th->done);
        					th->call = call;
        					__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
        					event_set(&th->ready);
        					event_timedwait(&th->done, 45 + (call == 13 ? 3000 : 0) + (call == 14 ? 3000 : 0) + (call == 15 ? 300 : 0));
        					break;
        				}
        			}
        			for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
        				sleep_ms(1);
        		}
        		
        		static void execute_one(void);
        		
        		#define WAIT_FLAGS 0
        		
        		static void loop(void)
        		{
        			int iter;
        			for (iter = 0;; iter++) {
        				char cwdbuf[32];
        				sprintf(cwdbuf, "./%d", iter);
        				if (mkdir(cwdbuf, 0777))
        			exit(1);
        				int pid = fork();
        				if (pid < 0)
        			exit(1);
        				if (pid == 0) {
        					if (chdir(cwdbuf))
        			exit(1);
        					execute_one();
        					exit(0);
        				}
        				int status = 0;
        				uint64_t start = current_time_ms();
        				for (;;) {
        					if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
        						break;
        					sleep_ms(1);
        					if (current_time_ms() - start < 5 * 1000)
        						continue;
        					kill_and_wait(pid, &status);
        					break;
        				}
        				remove_dir(cwdbuf);
        			}
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_call(int call)
        		{
        				intptr_t res = 0;
        			switch (call) {
        			case 0:
        				syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        				break;
        			case 1:
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        				syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        				break;
        			case 2:
        		*(uint32_t*)0x20000080 = 0;
        				res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        				if (res != -1)
        						r[0] = res;
        				break;
        			case 3:
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        				break;
        			case 4:
        				res = syscall(SYS_getpgrp);
        				if (res != -1)
        						r[1] = res;
        				break;
        			case 5:
        				res = syscall(SYS_geteuid);
        				if (res != -1)
        						r[2] = res;
        				break;
        			case 6:
        				res = syscall(SYS_getegid);
        				if (res != -1)
        						r[3] = res;
        				break;
        			case 7:
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        				break;
        			case 8:
        				syscall(SYS_setgid, r[3]);
        				break;
        			case 9:
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        				syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        				break;
        			case 10:
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        				break;
        			case 11:
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        				syz_execute_func(0x200000c0);
        				break;
        			case 12:
        				break;
        			case 13:
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        				syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        				break;
        			case 14:
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        				res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        				if (res != -1)
        						r[4] = res;
        				break;
        			case 15:
        				syz_usb_disconnect(r[4]);
        				break;
        			}
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        					use_temporary_dir();
        					do_sandbox_setuid();
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:637:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:642:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor147401304 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/6 (0.26s)
        	csource_test.go:123: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:4 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:false Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <dirent.h>
        		#include <endian.h>
        		#include <errno.h>
        		#include <fcntl.h>
        		#include <pthread.h>
        		#include <pwd.h>
        		#include <signal.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/resource.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <sys/types.h>
        		#include <sys/wait.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void kill_and_wait(int pid, int* status)
        		{
        			kill(pid, SIGKILL);
        			while (waitpid(-1, status, 0) != pid) {
        			}
        		}
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void remove_dir(const char* dir)
        		{
        			DIR* dp;
        			struct dirent* ep;
        			dp = opendir(dir);
        			if (dp == NULL)
        			exit(1);
        			while ((ep = readdir(dp))) {
        				if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
        					continue;
        				char filename[FILENAME_MAX];
        				snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
        				struct stat st;
        				if (lstat(filename, &st))
        			exit(1);
        				if (S_ISDIR(st.st_mode)) {
        					remove_dir(filename);
        					continue;
        				}
        				if (unlink(filename))
        			exit(1);
        			}
        			closedir(dp);
        			if (rmdir(dir))
        			exit(1);
        		}
        		
        		static void thread_start(void* (*fn)(void*), void* arg)
        		{
        			pthread_t th;
        			pthread_attr_t attr;
        			pthread_attr_init(&attr);
        			pthread_attr_setstacksize(&attr, 128 << 10);
        			int i;
        			for (i = 0; i < 100; i++) {
        				if (pthread_create(&th, &attr, fn, arg) == 0) {
        					pthread_attr_destroy(&attr);
        					return;
        				}
        				if (errno == EAGAIN) {
        					usleep(50);
        					continue;
        				}
        				break;
        			}
        			exit(1);
        		}
        		
        		typedef struct {
        			pthread_mutex_t mu;
        			pthread_cond_t cv;
        			int state;
        		} event_t;
        		
        		static void event_init(event_t* ev)
        		{
        			if (pthread_mutex_init(&ev->mu, 0))
        			exit(1);
        			if (pthread_cond_init(&ev->cv, 0))
        			exit(1);
        			ev->state = 0;
        		}
        		
        		static void event_reset(event_t* ev)
        		{
        			ev->state = 0;
        		}
        		
        		static void event_set(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			if (ev->state)
        			exit(1);
        			ev->state = 1;
        			pthread_mutex_unlock(&ev->mu);
        			pthread_cond_broadcast(&ev->cv);
        		}
        		
        		static void event_wait(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			while (!ev->state)
        				pthread_cond_wait(&ev->cv, &ev->mu);
        			pthread_mutex_unlock(&ev->mu);
        		}
        		
        		static int event_isset(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		static int event_timedwait(event_t* ev, uint64_t timeout)
        		{
        			uint64_t start = current_time_ms();
        			uint64_t now = start;
        			pthread_mutex_lock(&ev->mu);
        			for (;;) {
        				if (ev->state)
        					break;
        				uint64_t remain = timeout - (now - start);
        				struct timespec ts;
        				ts.tv_sec = remain / 1000;
        				ts.tv_nsec = (remain % 1000) * 1000 * 1000;
        				pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
        				now = current_time_ms();
        				if (now - start > timeout)
        					break;
        			}
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static void sandbox_common()
        		{
        			if (setsid() == -1)
        			exit(1);
        			struct rlimit rlim;
        			rlim.rlim_cur = rlim.rlim_max = 8 << 20;
        			setrlimit(RLIMIT_MEMLOCK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_FSIZE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_STACK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 0;
        			setrlimit(RLIMIT_CORE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 256;
        			setrlimit(RLIMIT_NOFILE, &rlim);
        		}
        		
        		static void loop();
        		
        		static int do_sandbox_none(void)
        		{
        			sandbox_common();
        			loop();
        			return 0;
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		struct thread_t {
        			int created, call;
        			event_t ready, done;
        		};
        		
        		static struct thread_t threads[16];
        		static void execute_call(int call);
        		static int running;
        		
        		static void* thr(void* arg)
        		{
        			struct thread_t* th = (struct thread_t*)arg;
        			for (;;) {
        				event_wait(&th->ready);
        				event_reset(&th->ready);
        				execute_call(th->call);
        				__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
        				event_set(&th->done);
        			}
        			return 0;
        		}
        		
        		static void execute_one(void)
        		{
        			int i, call, thread;
        			for (call = 0; call < 16; call++) {
        				for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
        					struct thread_t* th = &threads[thread];
        					if (!th->created) {
        						th->created = 1;
        						event_init(&th->ready);
        						event_init(&th->done);
        						event_set(&th->done);
        						thread_start(thr, th);
        					}
        					if (!event_isset(&th->done))
        						continue;
        					event_reset(&th->done);
        					th->call = call;
        					__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
        					event_set(&th->ready);
        					event_timedwait(&th->done, 45 + (call == 13 ? 3000 : 0) + (call == 14 ? 3000 : 0) + (call == 15 ? 300 : 0));
        					break;
        				}
        			}
        			for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
        				sleep_ms(1);
        		}
        		
        		static void execute_one(void);
        		
        		#define WAIT_FLAGS 0
        		
        		static void loop(void)
        		{
        			int iter;
        			for (iter = 0;; iter++) {
        				char cwdbuf[32];
        				sprintf(cwdbuf, "./%d", iter);
        				if (mkdir(cwdbuf, 0777))
        			exit(1);
        				int pid = fork();
        				if (pid < 0)
        			exit(1);
        				if (pid == 0) {
        					if (chdir(cwdbuf))
        			exit(1);
        					execute_one();
        					exit(0);
        				}
        				int status = 0;
        				uint64_t start = current_time_ms();
        				for (;;) {
        					if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
        						break;
        					sleep_ms(1);
        					if (current_time_ms() - start < 5 * 1000)
        						continue;
        					kill_and_wait(pid, &status);
        					break;
        				}
        				remove_dir(cwdbuf);
        			}
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_call(int call)
        		{
        				intptr_t res = 0;
        			switch (call) {
        			case 0:
        				syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        				break;
        			case 1:
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        				syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        				break;
        			case 2:
        		*(uint32_t*)0x20000080 = 0;
        				res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        				if (res != -1)
        						r[0] = res;
        				break;
        			case 3:
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        				break;
        			case 4:
        				res = syscall(SYS_getpgrp);
        				if (res != -1)
        						r[1] = res;
        				break;
        			case 5:
        				res = syscall(SYS_geteuid);
        				if (res != -1)
        						r[2] = res;
        				break;
        			case 6:
        				res = syscall(SYS_getegid);
        				if (res != -1)
        						r[3] = res;
        				break;
        			case 7:
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        				break;
        			case 8:
        				syscall(SYS_setgid, r[3]);
        				break;
        			case 9:
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        				syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        				break;
        			case 10:
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        				break;
        			case 11:
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        				syz_execute_func(0x200000c0);
        				break;
        			case 12:
        				break;
        			case 13:
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        				syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        				break;
        			case 14:
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        				res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        				if (res != -1)
        						r[4] = res;
        				break;
        			case 15:
        				syz_usb_disconnect(r[4]);
        				break;
        			}
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        			for (procid = 0; procid < 4; procid++) {
        				if (fork() == 0) {
        					use_temporary_dir();
        					do_sandbox_none();
        				}
        			}
        			sleep(1000000);
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:637:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:642:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor833758538 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/5 (0.26s)
        	csource_test.go:123: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:1 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:false Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <dirent.h>
        		#include <endian.h>
        		#include <errno.h>
        		#include <fcntl.h>
        		#include <pthread.h>
        		#include <pwd.h>
        		#include <signal.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/resource.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <sys/types.h>
        		#include <sys/wait.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void kill_and_wait(int pid, int* status)
        		{
        			kill(pid, SIGKILL);
        			while (waitpid(-1, status, 0) != pid) {
        			}
        		}
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void remove_dir(const char* dir)
        		{
        			DIR* dp;
        			struct dirent* ep;
        			dp = opendir(dir);
        			if (dp == NULL)
        			exit(1);
        			while ((ep = readdir(dp))) {
        				if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
        					continue;
        				char filename[FILENAME_MAX];
        				snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
        				struct stat st;
        				if (lstat(filename, &st))
        			exit(1);
        				if (S_ISDIR(st.st_mode)) {
        					remove_dir(filename);
        					continue;
        				}
        				if (unlink(filename))
        			exit(1);
        			}
        			closedir(dp);
        			if (rmdir(dir))
        			exit(1);
        		}
        		
        		static void thread_start(void* (*fn)(void*), void* arg)
        		{
        			pthread_t th;
        			pthread_attr_t attr;
        			pthread_attr_init(&attr);
        			pthread_attr_setstacksize(&attr, 128 << 10);
        			int i;
        			for (i = 0; i < 100; i++) {
        				if (pthread_create(&th, &attr, fn, arg) == 0) {
        					pthread_attr_destroy(&attr);
        					return;
        				}
        				if (errno == EAGAIN) {
        					usleep(50);
        					continue;
        				}
        				break;
        			}
        			exit(1);
        		}
        		
        		typedef struct {
        			pthread_mutex_t mu;
        			pthread_cond_t cv;
        			int state;
        		} event_t;
        		
        		static void event_init(event_t* ev)
        		{
        			if (pthread_mutex_init(&ev->mu, 0))
        			exit(1);
        			if (pthread_cond_init(&ev->cv, 0))
        			exit(1);
        			ev->state = 0;
        		}
        		
        		static void event_reset(event_t* ev)
        		{
        			ev->state = 0;
        		}
        		
        		static void event_set(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			if (ev->state)
        			exit(1);
        			ev->state = 1;
        			pthread_mutex_unlock(&ev->mu);
        			pthread_cond_broadcast(&ev->cv);
        		}
        		
        		static void event_wait(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			while (!ev->state)
        				pthread_cond_wait(&ev->cv, &ev->mu);
        			pthread_mutex_unlock(&ev->mu);
        		}
        		
        		static int event_isset(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		static int event_timedwait(event_t* ev, uint64_t timeout)
        		{
        			uint64_t start = current_time_ms();
        			uint64_t now = start;
        			pthread_mutex_lock(&ev->mu);
        			for (;;) {
        				if (ev->state)
        					break;
        				uint64_t remain = timeout - (now - start);
        				struct timespec ts;
        				ts.tv_sec = remain / 1000;
        				ts.tv_nsec = (remain % 1000) * 1000 * 1000;
        				pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
        				now = current_time_ms();
        				if (now - start > timeout)
        					break;
        			}
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static void sandbox_common()
        		{
        			if (setsid() == -1)
        			exit(1);
        			struct rlimit rlim;
        			rlim.rlim_cur = rlim.rlim_max = 8 << 20;
        			setrlimit(RLIMIT_MEMLOCK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_FSIZE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_STACK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 0;
        			setrlimit(RLIMIT_CORE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 256;
        			setrlimit(RLIMIT_NOFILE, &rlim);
        		}
        		
        		static void loop();
        		
        		static int do_sandbox_none(void)
        		{
        			sandbox_common();
        			loop();
        			return 0;
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		struct thread_t {
        			int created, call;
        			event_t ready, done;
        		};
        		
        		static struct thread_t threads[16];
        		static void execute_call(int call);
        		static int running;
        		
        		static void* thr(void* arg)
        		{
        			struct thread_t* th = (struct thread_t*)arg;
        			for (;;) {
        				event_wait(&th->ready);
        				event_reset(&th->ready);
        				execute_call(th->call);
        				__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
        				event_set(&th->done);
        			}
        			return 0;
        		}
        		
        		static void execute_one(void)
        		{
        			int i, call, thread;
        			for (call = 0; call < 16; call++) {
        				for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
        					struct thread_t* th = &threads[thread];
        					if (!th->created) {
        						th->created = 1;
        						event_init(&th->ready);
        						event_init(&th->done);
        						event_set(&th->done);
        						thread_start(thr, th);
        					}
        					if (!event_isset(&th->done))
        						continue;
        					event_reset(&th->done);
        					th->call = call;
        					__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
        					event_set(&th->ready);
        					event_timedwait(&th->done, 45 + (call == 13 ? 3000 : 0) + (call == 14 ? 3000 : 0) + (call == 15 ? 300 : 0));
        					break;
        				}
        			}
        			for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
        				sleep_ms(1);
        		}
        		
        		static void execute_one(void);
        		
        		#define WAIT_FLAGS 0
        		
        		static void loop(void)
        		{
        			int iter;
        			for (iter = 0;; iter++) {
        				char cwdbuf[32];
        				sprintf(cwdbuf, "./%d", iter);
        				if (mkdir(cwdbuf, 0777))
        			exit(1);
        				int pid = fork();
        				if (pid < 0)
        			exit(1);
        				if (pid == 0) {
        					if (chdir(cwdbuf))
        			exit(1);
        					execute_one();
        					exit(0);
        				}
        				int status = 0;
        				uint64_t start = current_time_ms();
        				for (;;) {
        					if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
        						break;
        					sleep_ms(1);
        					if (current_time_ms() - start < 5 * 1000)
        						continue;
        					kill_and_wait(pid, &status);
        					break;
        				}
        				remove_dir(cwdbuf);
        			}
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_call(int call)
        		{
        				intptr_t res = 0;
        			switch (call) {
        			case 0:
        				syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        				break;
        			case 1:
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        				syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        				break;
        			case 2:
        		*(uint32_t*)0x20000080 = 0;
        				res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        				if (res != -1)
        						r[0] = res;
        				break;
        			case 3:
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        				break;
        			case 4:
        				res = syscall(SYS_getpgrp);
        				if (res != -1)
        						r[1] = res;
        				break;
        			case 5:
        				res = syscall(SYS_geteuid);
        				if (res != -1)
        						r[2] = res;
        				break;
        			case 6:
        				res = syscall(SYS_getegid);
        				if (res != -1)
        						r[3] = res;
        				break;
        			case 7:
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        				break;
        			case 8:
        				syscall(SYS_setgid, r[3]);
        				break;
        			case 9:
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        				syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        				break;
        			case 10:
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        				break;
        			case 11:
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        				syz_execute_func(0x200000c0);
        				break;
        			case 12:
        				break;
        			case 13:
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        				syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        				break;
        			case 14:
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        				res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        				if (res != -1)
        						r[4] = res;
        				break;
        			case 15:
        				syz_usb_disconnect(r[4]);
        				break;
        			}
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        					use_temporary_dir();
        					do_sandbox_none();
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:637:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:642:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor917569804 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/7 (0.27s)
        	csource_test.go:123: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox: Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:false Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <dirent.h>
        		#include <endian.h>
        		#include <errno.h>
        		#include <fcntl.h>
        		#include <pthread.h>
        		#include <pwd.h>
        		#include <signal.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <sys/types.h>
        		#include <sys/wait.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void kill_and_wait(int pid, int* status)
        		{
        			kill(pid, SIGKILL);
        			while (waitpid(-1, status, 0) != pid) {
        			}
        		}
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void remove_dir(const char* dir)
        		{
        			DIR* dp;
        			struct dirent* ep;
        			dp = opendir(dir);
        			if (dp == NULL)
        			exit(1);
        			while ((ep = readdir(dp))) {
        				if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
        					continue;
        				char filename[FILENAME_MAX];
        				snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
        				struct stat st;
        				if (lstat(filename, &st))
        			exit(1);
        				if (S_ISDIR(st.st_mode)) {
        					remove_dir(filename);
        					continue;
        				}
        				if (unlink(filename))
        			exit(1);
        			}
        			closedir(dp);
        			if (rmdir(dir))
        			exit(1);
        		}
        		
        		static void thread_start(void* (*fn)(void*), void* arg)
        		{
        			pthread_t th;
        			pthread_attr_t attr;
        			pthread_attr_init(&attr);
        			pthread_attr_setstacksize(&attr, 128 << 10);
        			int i;
        			for (i = 0; i < 100; i++) {
        				if (pthread_create(&th, &attr, fn, arg) == 0) {
        					pthread_attr_destroy(&attr);
        					return;
        				}
        				if (errno == EAGAIN) {
        					usleep(50);
        					continue;
        				}
        				break;
        			}
        			exit(1);
        		}
        		
        		typedef struct {
        			pthread_mutex_t mu;
        			pthread_cond_t cv;
        			int state;
        		} event_t;
        		
        		static void event_init(event_t* ev)
        		{
        			if (pthread_mutex_init(&ev->mu, 0))
        			exit(1);
        			if (pthread_cond_init(&ev->cv, 0))
        			exit(1);
        			ev->state = 0;
        		}
        		
        		static void event_reset(event_t* ev)
        		{
        			ev->state = 0;
        		}
        		
        		static void event_set(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			if (ev->state)
        			exit(1);
        			ev->state = 1;
        			pthread_mutex_unlock(&ev->mu);
        			pthread_cond_broadcast(&ev->cv);
        		}
        		
        		static void event_wait(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			while (!ev->state)
        				pthread_cond_wait(&ev->cv, &ev->mu);
        			pthread_mutex_unlock(&ev->mu);
        		}
        		
        		static int event_isset(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		static int event_timedwait(event_t* ev, uint64_t timeout)
        		{
        			uint64_t start = current_time_ms();
        			uint64_t now = start;
        			pthread_mutex_lock(&ev->mu);
        			for (;;) {
        				if (ev->state)
        					break;
        				uint64_t remain = timeout - (now - start);
        				struct timespec ts;
        				ts.tv_sec = remain / 1000;
        				ts.tv_nsec = (remain % 1000) * 1000 * 1000;
        				pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
        				now = current_time_ms();
        				if (now - start > timeout)
        					break;
        			}
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		struct thread_t {
        			int created, call;
        			event_t ready, done;
        		};
        		
        		static struct thread_t threads[16];
        		static void execute_call(int call);
        		static int running;
        		
        		static void* thr(void* arg)
        		{
        			struct thread_t* th = (struct thread_t*)arg;
        			for (;;) {
        				event_wait(&th->ready);
        				event_reset(&th->ready);
        				execute_call(th->call);
        				__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
        				event_set(&th->done);
        			}
        			return 0;
        		}
        		
        		static void execute_one(void)
        		{
        			int i, call, thread;
        			for (call = 0; call < 16; call++) {
        				for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
        					struct thread_t* th = &threads[thread];
        					if (!th->created) {
        						th->created = 1;
        						event_init(&th->ready);
        						event_init(&th->done);
        						event_set(&th->done);
        						thread_start(thr, th);
        					}
        					if (!event_isset(&th->done))
        						continue;
        					event_reset(&th->done);
        					th->call = call;
        					__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
        					event_set(&th->ready);
        					event_timedwait(&th->done, 45 + (call == 13 ? 3000 : 0) + (call == 14 ? 3000 : 0) + (call == 15 ? 300 : 0));
        					break;
        				}
        			}
        			for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
        				sleep_ms(1);
        		}
        		
        		static void execute_one(void);
        		
        		#define WAIT_FLAGS 0
        		
        		static void loop(void)
        		{
        			int iter;
        			for (iter = 0;; iter++) {
        				char cwdbuf[32];
        				sprintf(cwdbuf, "./%d", iter);
        				if (mkdir(cwdbuf, 0777))
        			exit(1);
        				int pid = fork();
        				if (pid < 0)
        			exit(1);
        				if (pid == 0) {
        					if (chdir(cwdbuf))
        			exit(1);
        					execute_one();
        					exit(0);
        				}
        				int status = 0;
        				uint64_t start = current_time_ms();
        				for (;;) {
        					if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
        						break;
        					sleep_ms(1);
        					if (current_time_ms() - start < 5 * 1000)
        						continue;
        					kill_and_wait(pid, &status);
        					break;
        				}
        				remove_dir(cwdbuf);
        			}
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_call(int call)
        		{
        				intptr_t res = 0;
        			switch (call) {
        			case 0:
        				syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        				break;
        			case 1:
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        				syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        				break;
        			case 2:
        		*(uint32_t*)0x20000080 = 0;
        				res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        				if (res != -1)
        						r[0] = res;
        				break;
        			case 3:
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        				break;
        			case 4:
        				res = syscall(SYS_getpgrp);
        				if (res != -1)
        						r[1] = res;
        				break;
        			case 5:
        				res = syscall(SYS_geteuid);
        				if (res != -1)
        						r[2] = res;
        				break;
        			case 6:
        				res = syscall(SYS_getegid);
        				if (res != -1)
        						r[3] = res;
        				break;
        			case 7:
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        				break;
        			case 8:
        				syscall(SYS_setgid, r[3]);
        				break;
        			case 9:
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        				syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        				break;
        			case 10:
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        				break;
        			case 11:
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        				syz_execute_func(0x200000c0);
        				break;
        			case 12:
        				break;
        			case 13:
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        				syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        				break;
        			case 14:
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        				res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        				if (res != -1)
        						r[4] = res;
        				break;
        			case 15:
        				syz_usb_disconnect(r[4]);
        				break;
        			}
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        					use_temporary_dir();
        					loop();
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:636:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:641:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor636848673 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/12 (0.22s)
        	csource_test.go:123: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false UseTmpDir:true HandleSegv:false Repro:true Trace:false}
        		program:
        		shmget$private(0x0, 0x1000, 0x204, &(0x7f0000fff000/0x1000)=nil)
        		clock_nanosleep(0x40000000, 0x1, &(0x7f0000000000)={0x3, 0x7}, &(0x7f0000000040))
        		r0 = paccept(0xffffffffffffff9c, 0x0, &(0x7f0000000080), 0x30000000)
        		setsockopt$sock_linger(r0, 0xffff, 0x80, &(0x7f00000000c0)={0x8357, 0x7ff}, 0x8)
        		r1 = getpgrp()
        		r2 = geteuid()
        		r3 = getegid()
        		setsockopt$sock_cred(r0, 0xffff, 0x11, &(0x7f0000000100)={r1, r2, r3}, 0xc)
        		setgid(r3)
        		_lwp_ctl(0x7a513cdc, &(0x7f0000000180)=&(0x7f0000000140)={0x5, 0x7})
        		syz_emit_ethernet(0xbf, &(0x7f0000000000)="e5132cca36eb50095742833abff468856182fc0af4bdca80fd274a83bbfceb50229b33b64f402b8dfa0425ac0999dc4fde46da7ec136e899cdb6e86682151238858cc5724f94101e60442933ef18ae699f3d1008b583a35295b72b882ae075de87616d9efbe3a2a5e57f3080984442b38eae39f5cad56f1bee40c41c95a83322a3d4e84c753131903961edff1d2542b5291923f1a8ff98bc69b2b6d651273ae64425c36b352ca40341b66072a684680d9ba2aceb2d5f1292f676697567b980")
        		syz_execute_func(&(0x7f00000000c0)="0f0dbee6e1e739c4c2b1bec6c403f9170e00c4a3154a2eff0f0f219a8f4878c03700c402c1989100000080f083560077c481fc53549500f3ab")
        		syz_extract_tcp_res(&(0x7f0000000100), 0x8, 0x6)
        		syz_usb_connect(0x17, 0x94, &(0x7f0000000140)="398475b574b6a3a321e19f0e03d46f486b2cab991a2b323460aeacf5a03482d1989a1054b61b2e7fba3c413b97e271f48673e7328ca965f6470879527a747b2dab77c10cd2782d8bf0ab9e8eabcae819cb4cfbc1b16ff8045f46155d86076295015be84eef4437ca842e2f0533780a004f9bca0a7bc3d00c52102e123588eab68284f797a456b6395e0e4b5f0301d86b673a12c4", &(0x7f0000000200)="d89b4503ed45151c555c4015c53fbdba2e24d33827b3bf3c7b62a40360d9d7205d106312fc34b378e11635ea03982ba256af4a74c77ed7a950ff7d66eb2fc94bc72088941ee4e259b46573badf54244381ac8d43f1fe270f03f049e1bfc7c8e7142d351f5d4e9a9edc8fb732c3")
        		r4 = syz_usb_connect(0x3, 0x1a, &(0x7f0000000280)="7a4cb140ec5f07adfb6465dacdf73cf5aaee28b68dd8f6b33287", &(0x7f00000002c0)="9d1fd2f333cdc7a3f646bc7abe61ed4431bfc0d2cd4d66f4c392ffc4fdf1dfd49087b4b2383d345c67894beb34d4d17dc37851b9085c047734134b9916719d87667c401d62c88649d3e7dcb0035eaf9e78babe8ffed4c0d45032ecfa93d54aa8debc0c5a566c440cd5884773c0fb4b7d28448d94815e046cd3ae29414dfcd93e6d4f039a820480fb6b61be6fdb33aacd37274a170550ee8e39eab25486cd8863ee3431f22f0681f1a15496dc1df525ac48")
        		syz_usb_disconnect(r4)
        		
        	csource_test.go:124: failed to build program:
        		// autogenerated by syzkaller (https://github.com/google/syzkaller)
        		
        		#define _GNU_SOURCE 
        		
        		#include <dev/usb/usb.h>
        		#include <dev/usb/usbhid.h>
        		#include <dev/usb/vhci.h>
        		#include <dirent.h>
        		#include <endian.h>
        		#include <errno.h>
        		#include <fcntl.h>
        		#include <pthread.h>
        		#include <pwd.h>
        		#include <signal.h>
        		#include <stdarg.h>
        		#include <stdbool.h>
        		#include <stdint.h>
        		#include <stdio.h>
        		#include <stdlib.h>
        		#include <string.h>
        		#include <sys/ioctl.h>
        		#include <sys/resource.h>
        		#include <sys/stat.h>
        		#include <sys/syscall.h>
        		#include <sys/types.h>
        		#include <sys/wait.h>
        		#include <time.h>
        		#include <unistd.h>
        		
        		static unsigned long long procid;
        		
        		static void kill_and_wait(int pid, int* status)
        		{
        			kill(pid, SIGKILL);
        			while (waitpid(-1, status, 0) != pid) {
        			}
        		}
        		
        		static void sleep_ms(uint64_t ms)
        		{
        			usleep(ms * 1000);
        		}
        		
        		static uint64_t current_time_ms(void)
        		{
        			struct timespec ts;
        			if (clock_gettime(CLOCK_MONOTONIC, &ts))
        			exit(1);
        			return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
        		}
        		
        		static void use_temporary_dir(void)
        		{
        			char tmpdir_template[] = "./syzkaller.XXXXXX";
        			char* tmpdir = mkdtemp(tmpdir_template);
        			if (!tmpdir)
        			exit(1);
        			if (chmod(tmpdir, 0777))
        			exit(1);
        			if (chdir(tmpdir))
        			exit(1);
        		}
        		
        		static void remove_dir(const char* dir)
        		{
        			DIR* dp;
        			struct dirent* ep;
        			dp = opendir(dir);
        			if (dp == NULL)
        			exit(1);
        			while ((ep = readdir(dp))) {
        				if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
        					continue;
        				char filename[FILENAME_MAX];
        				snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
        				struct stat st;
        				if (lstat(filename, &st))
        			exit(1);
        				if (S_ISDIR(st.st_mode)) {
        					remove_dir(filename);
        					continue;
        				}
        				if (unlink(filename))
        			exit(1);
        			}
        			closedir(dp);
        			if (rmdir(dir))
        			exit(1);
        		}
        		
        		static void thread_start(void* (*fn)(void*), void* arg)
        		{
        			pthread_t th;
        			pthread_attr_t attr;
        			pthread_attr_init(&attr);
        			pthread_attr_setstacksize(&attr, 128 << 10);
        			int i;
        			for (i = 0; i < 100; i++) {
        				if (pthread_create(&th, &attr, fn, arg) == 0) {
        					pthread_attr_destroy(&attr);
        					return;
        				}
        				if (errno == EAGAIN) {
        					usleep(50);
        					continue;
        				}
        				break;
        			}
        			exit(1);
        		}
        		
        		typedef struct {
        			pthread_mutex_t mu;
        			pthread_cond_t cv;
        			int state;
        		} event_t;
        		
        		static void event_init(event_t* ev)
        		{
        			if (pthread_mutex_init(&ev->mu, 0))
        			exit(1);
        			if (pthread_cond_init(&ev->cv, 0))
        			exit(1);
        			ev->state = 0;
        		}
        		
        		static void event_reset(event_t* ev)
        		{
        			ev->state = 0;
        		}
        		
        		static void event_set(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			if (ev->state)
        			exit(1);
        			ev->state = 1;
        			pthread_mutex_unlock(&ev->mu);
        			pthread_cond_broadcast(&ev->cv);
        		}
        		
        		static void event_wait(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			while (!ev->state)
        				pthread_cond_wait(&ev->cv, &ev->mu);
        			pthread_mutex_unlock(&ev->mu);
        		}
        		
        		static int event_isset(event_t* ev)
        		{
        			pthread_mutex_lock(&ev->mu);
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		static int event_timedwait(event_t* ev, uint64_t timeout)
        		{
        			uint64_t start = current_time_ms();
        			uint64_t now = start;
        			pthread_mutex_lock(&ev->mu);
        			for (;;) {
        				if (ev->state)
        					break;
        				uint64_t remain = timeout - (now - start);
        				struct timespec ts;
        				ts.tv_sec = remain / 1000;
        				ts.tv_nsec = (remain % 1000) * 1000 * 1000;
        				pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
        				now = current_time_ms();
        				if (now - start > timeout)
        					break;
        			}
        			int res = ev->state;
        			pthread_mutex_unlock(&ev->mu);
        			return res;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		/*
        		 * Redefinitions to match the linux types used in common_usb.h.
        		 */
        		
        		struct usb_endpoint_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bEndpointAddress;
        			uint8_t bmAttributes;
        			uint16_t wMaxPacketSize;
        			uint8_t bInterval;
        			uint8_t bRefresh;
        			uint8_t bSynchAddress;
        		} __attribute__((packed));
        		
        		struct usb_device_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint16_t idVendor;
        			uint16_t idProduct;
        			uint16_t bcdDevice;
        			uint8_t iManufacturer;
        			uint8_t iProduct;
        			uint8_t iSerialNumber;
        			uint8_t bNumConfigurations;
        		} __attribute__((packed));
        		
        		struct usb_config_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t wTotalLength;
        			uint8_t bNumInterfaces;
        			uint8_t bConfigurationValue;
        			uint8_t iConfiguration;
        			uint8_t bmAttributes;
        			uint8_t bMaxPower;
        		} __attribute__((packed));
        		
        		struct usb_interface_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bNumEndpoints;
        			uint8_t bInterfaceClass;
        			uint8_t bInterfaceSubClass;
        			uint8_t bInterfaceProtocol;
        			uint8_t iInterface;
        		} __attribute__((packed));
        		
        		struct usb_ctrlrequest {
        			uint8_t bRequestType;
        			uint8_t bRequest;
        			uint16_t wValue;
        			uint16_t wIndex;
        			uint16_t wLength;
        		} __attribute__((packed));
        		
        		struct usb_qualifier_descriptor {
        			uint8_t bLength;
        			uint8_t bDescriptorType;
        			uint16_t bcdUSB;
        			uint8_t bDeviceClass;
        			uint8_t bDeviceSubClass;
        			uint8_t bDeviceProtocol;
        			uint8_t bMaxPacketSize0;
        			uint8_t bNumConfigurations;
        			uint8_t bRESERVED;
        		} __attribute__((packed));
        		
        		#define USB_TYPE_MASK (0x03 << 5)
        		#define USB_TYPE_STANDARD (0x00 << 5)
        		#define USB_TYPE_CLASS (0x01 << 5)
        		#define USB_TYPE_VENDOR (0x02 << 5)
        		#define USB_TYPE_RESERVED (0x03 << 5)
        		
        		#define USB_DT_DEVICE 0x01
        		#define USB_DT_CONFIG 0x02
        		#define USB_DT_STRING 0x03
        		#define USB_DT_INTERFACE 0x04
        		#define USB_DT_ENDPOINT 0x05
        		#define USB_DT_DEVICE_QUALIFIER 0x06
        		#define USB_DT_OTHER_SPEED_CONFIG 0x07
        		#define USB_DT_INTERFACE_POWER 0x08
        		#define USB_DT_OTG 0x09
        		#define USB_DT_DEBUG 0x0a
        		#define USB_DT_INTERFACE_ASSOCIATION 0x0b
        		#define USB_DT_SECURITY 0x0c
        		#define USB_DT_KEY 0x0d
        		#define USB_DT_ENCRYPTION_TYPE 0x0e
        		#define USB_DT_BOS 0x0f
        		#define USB_DT_DEVICE_CAPABILITY 0x10
        		#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
        		#define USB_DT_WIRE_ADAPTER 0x21
        		#define USB_DT_RPIPE 0x22
        		#define USB_DT_CS_RADIO_CONTROL 0x23
        		#define USB_DT_PIPE_USAGE 0x24
        		#define USB_DT_SS_ENDPOINT_COMP 0x30
        		#define USB_DT_SSP_ISOC_ENDPOINT_COMP 0x31
        		
        		#define USB_REQ_GET_STATUS 0x00
        		#define USB_REQ_CLEAR_FEATURE 0x01
        		#define USB_REQ_SET_FEATURE 0x03
        		#define USB_REQ_SET_ADDRESS 0x05
        		#define USB_REQ_GET_DESCRIPTOR 0x06
        		#define USB_REQ_SET_DESCRIPTOR 0x07
        		#define USB_REQ_GET_CONFIGURATION 0x08
        		#define USB_REQ_SET_CONFIGURATION 0x09
        		#define USB_REQ_GET_INTERFACE 0x0A
        		#define USB_REQ_SET_INTERFACE 0x0B
        		#define USB_REQ_SYNCH_FRAME 0x0C
        		#define USB_REQ_SET_SEL 0x30
        		#define USB_REQ_SET_ISOCH_DELAY 0x31
        		
        		#define USB_REQ_SET_ENCRYPTION 0x0D
        		#define USB_REQ_GET_ENCRYPTION 0x0E
        		#define USB_REQ_RPIPE_ABORT 0x0E
        		#define USB_REQ_SET_HANDSHAKE 0x0F
        		#define USB_REQ_RPIPE_RESET 0x0F
        		#define USB_REQ_GET_HANDSHAKE 0x10
        		#define USB_REQ_SET_CONNECTION 0x11
        		#define USB_REQ_SET_SECURITY_DATA 0x12
        		#define USB_REQ_GET_SECURITY_DATA 0x13
        		#define USB_REQ_SET_WUSB_DATA 0x14
        		#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
        		#define USB_REQ_LOOPBACK_DATA_READ 0x16
        		#define USB_REQ_SET_INTERFACE_DS 0x17
        		
        		#define USB_REQ_GET_PARTNER_PDO 20
        		#define USB_REQ_GET_BATTERY_STATUS 21
        		#define USB_REQ_SET_PDO 22
        		#define USB_REQ_GET_VDM 23
        		#define USB_REQ_SEND_VDM 24
        		
        		#define USB_MAX_IFACE_NUM 4
        		#define USB_MAX_EP_NUM 32
        		#define USB_MAX_FDS 6
        		
        		struct usb_endpoint_index {
        			struct usb_endpoint_descriptor desc;
        			int handle;
        		};
        		
        		struct usb_iface_index {
        			struct usb_interface_descriptor* iface;
        			uint8_t bInterfaceNumber;
        			uint8_t bAlternateSetting;
        			uint8_t bInterfaceClass;
        			struct usb_endpoint_index eps[USB_MAX_EP_NUM];
        			int eps_num;
        		};
        		
        		struct usb_device_index {
        			struct usb_device_descriptor* dev;
        			struct usb_config_descriptor* config;
        			uint8_t bDeviceClass;
        			uint8_t bMaxPower;
        			int config_length;
        			struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
        			int ifaces_num;
        			int iface_cur;
        		};
        		
        		struct usb_info {
        			int fd;
        			struct usb_device_index index;
        		};
        		
        		static struct usb_info usb_devices[USB_MAX_FDS];
        		static int usb_devices_num;
        		
        		static bool parse_usb_descriptor(const char* buffer, size_t length, struct usb_device_index* index)
        		{
        			if (length < sizeof(*index->dev) + sizeof(*index->config))
        				return false;
        			memset(index, 0, sizeof(*index));
        			index->dev = (struct usb_device_descriptor*)buffer;
        			index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
        			index->bDeviceClass = index->dev->bDeviceClass;
        			index->bMaxPower = index->config->bMaxPower;
        			index->config_length = length - sizeof(*index->dev);
        			index->iface_cur = -1;
        			size_t offset = 0;
        			while (true) {
        				if (offset + 1 >= length)
        					break;
        				uint8_t desc_length = buffer[offset];
        				uint8_t desc_type = buffer[offset + 1];
        				if (desc_length <= 2)
        					break;
        				if (offset + desc_length > length)
        					break;
        				if (desc_type == USB_DT_INTERFACE && index->ifaces_num < USB_MAX_IFACE_NUM) {
        					struct usb_interface_descriptor* iface = (struct usb_interface_descriptor*)(buffer + offset);
        					index->ifaces[index->ifaces_num].iface = iface;
        					index->ifaces[index->ifaces_num].bInterfaceNumber = iface->bInterfaceNumber;
        					index->ifaces[index->ifaces_num].bAlternateSetting = iface->bAlternateSetting;
        					index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
        					index->ifaces_num++;
        				}
        				if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
        					struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
        					if (iface->eps_num < USB_MAX_EP_NUM) {
        						memcpy(&iface->eps[iface->eps_num].desc, buffer + offset, sizeof(iface->eps[iface->eps_num].desc));
        						iface->eps_num++;
        					}
        				}
        				offset += desc_length;
        			}
        			return true;
        		}
        		
        		static struct usb_device_index* add_usb_index(int fd, const char* dev, size_t dev_len)
        		{
        			int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
        			if (i >= USB_MAX_FDS)
        				return NULL;
        			int rv = 0;
        		rv = parse_usb_descriptor(dev, dev_len, &usb_devices[i].index);
        			if (!rv)
        				return NULL;
        			__atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
        			return &usb_devices[i].index;
        		}
        		
        		static struct usb_device_index* lookup_usb_index(int fd)
        		{
        			int i;
        			for (i = 0; i < USB_MAX_FDS; i++) {
        				if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd) {
        					return &usb_devices[i].index;
        				}
        			}
        			return NULL;
        		}
        		
        		struct vusb_connect_string_descriptor {
        			uint32_t len;
        			char* str;
        		} __attribute__((packed));
        		
        		struct vusb_connect_descriptors {
        			uint32_t qual_len;
        			char* qual;
        			uint32_t bos_len;
        			char* bos;
        			uint32_t strs_len;
        			struct vusb_connect_string_descriptor strs[0];
        		} __attribute__((packed));
        		
        		static const char default_string[] = {
        		    8, USB_DT_STRING,
        		    's', 0, 'y', 0, 'z', 0
        		};
        		
        		static const char default_lang_id[] = {
        		    4, USB_DT_STRING,
        		    0x09, 0x04
        		};
        		
        		static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
        						       const struct usb_ctrlrequest* ctrl,
        						       char** response_data, uint32_t* response_length)
        		{
        			struct usb_device_index* index = lookup_usb_index(fd);
        			uint8_t str_idx;
        			if (!index)
        				return false;
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_GET_DESCRIPTOR:
        					switch (ctrl->wValue >> 8) {
        					case USB_DT_DEVICE:
        						*response_data = (char*)index->dev;
        						*response_length = sizeof(*index->dev);
        						return true;
        					case USB_DT_CONFIG:
        						*response_data = (char*)index->config;
        						*response_length = index->config_length;
        						return true;
        					case USB_DT_STRING:
        						str_idx = (uint8_t)ctrl->wValue;
        						if (descs && str_idx < descs->strs_len) {
        							*response_data = descs->strs[str_idx].str;
        							*response_length = descs->strs[str_idx].len;
        							return true;
        						}
        						if (str_idx == 0) {
        							*response_data = (char*)&default_lang_id[0];
        							*response_length = default_lang_id[0];
        							return true;
        						}
        						*response_data = (char*)&default_string[0];
        						*response_length = default_string[0];
        						return true;
        					case USB_DT_BOS:
        						*response_data = descs->bos;
        						*response_length = descs->bos_len;
        						return true;
        					case USB_DT_DEVICE_QUALIFIER:
        						if (!descs->qual) {
        							struct usb_qualifier_descriptor* qual =
        							    (struct usb_qualifier_descriptor*)response_data;
        							qual->bLength = sizeof(*qual);
        							qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
        							qual->bcdUSB = index->dev->bcdUSB;
        							qual->bDeviceClass = index->dev->bDeviceClass;
        							qual->bDeviceSubClass = index->dev->bDeviceSubClass;
        							qual->bDeviceProtocol = index->dev->bDeviceProtocol;
        							qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
        							qual->bNumConfigurations = index->dev->bNumConfigurations;
        							qual->bRESERVED = 0;
        							*response_length = sizeof(*qual);
        							return true;
        						}
        						*response_data = descs->qual;
        						*response_length = descs->qual_len;
        						return true;
        					default:
        						break;
        					}
        					break;
        				default:
        					break;
        				}
        				break;
        			default:
        				break;
        			}
        			return false;
        		}
        		
        		typedef bool (*lookup_connect_out_response_t)(int fd, const struct vusb_connect_descriptors* descs,
        							      const struct usb_ctrlrequest* ctrl, bool* done);
        		
        		static bool lookup_connect_response_out_generic(int fd, const struct vusb_connect_descriptors* descs,
        								const struct usb_ctrlrequest* ctrl, bool* done)
        		{
        			switch (ctrl->bRequestType & USB_TYPE_MASK) {
        			case USB_TYPE_STANDARD:
        				switch (ctrl->bRequest) {
        				case USB_REQ_SET_CONFIGURATION:
        					*done = true;
        					return true;
        				default:
        					break;
        				}
        				break;
        			}
        			return false;
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static int vhci_open(void)
        		{
        			return open("/dev/vhci", O_RDWR);
        		}
        		
        		static int vhci_setport(int fd, u_int port)
        		{
        			struct vhci_ioc_set_port args;
        			args.port = port;
        			return ioctl(fd, VHCI_IOC_SET_PORT, &args);
        		}
        		
        		static int vhci_usb_attach(int fd)
        		{
        			return ioctl(fd, VHCI_IOC_USB_ATTACH, NULL);
        		}
        		
        		static int vhci_usb_recv(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = read(fd, ptr, size);
        				if (done < 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		static int vhci_usb_send(int fd, void* buf, size_t size)
        		{
        			uint8_t* ptr = (uint8_t*)buf;
        			ssize_t done;
        			while (1) {
        				done = write(fd, ptr, size);
        				if (done <= 0)
        					return -1;
        				if ((size_t)done == size)
        					return 0;
        				size -= done;
        				ptr += done;
        			}
        		}
        		
        		/* -------------------------------------------------------------------------- */
        		
        		static volatile long syz_usb_connect_impl(uint64_t speed, uint64_t dev_len,
        							  const char* dev, const struct vusb_connect_descriptors* descs,
        							  lookup_connect_out_response_t lookup_connect_response_out)
        		{
        			struct usb_device_index* index;
        			int portnum, fd, rv;
        			bool done;
        			portnum = procid + 1;
        			if (!dev) {
        				return -1;
        			}
        			if (portnum != 1) {
        				/* For now, we support only one proc. */
        				return -1;
        			}
        			fd = vhci_open();
        			if (fd < 0) {
        				return -1;
        			}
        			index = add_usb_index(fd, dev, dev_len);
        			if (!index) {
        				goto err;
        			}
        			rv = vhci_setport(fd, portnum);
        			if (rv != 0) {
        				goto err;
        			}
        			rv = vhci_usb_attach(fd);
        			if (rv != 0) {
        				goto err;
        			}
        			done = false;
        			while (!done) {
        				vhci_request_t req;
        				rv = vhci_usb_recv(fd, &req, sizeof(req));
        				if (rv != 0) {
        					goto err;
        				}
        				if (req.type != VHCI_REQ_CTRL) {
        					goto err;
        				}
        				char* response_data = NULL;
        				uint32_t response_length = 0;
        				char data[4096];
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					bool response_found = false;
        		response_found = lookup_connect_response_in(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length);
        					if (!response_found) {
        						goto err;
        					}
        				} else {
        					if (!lookup_connect_response_out(fd, descs, (const usb_ctrlrequest*)&req.u.ctrl, &done)) {
        						goto err;
        					}
        					response_data = NULL;
        					response_length = UGETW(req.u.ctrl.wLength);
        				}
        				if ((req.u.ctrl.bmRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        				    req.u.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
        					/* TODO: possibly revisit */
        				}
        				if (response_length > sizeof(data))
        					response_length = 0;
        				if ((uint32_t)UGETW(req.u.ctrl.wLength) < response_length)
        					response_length = UGETW(req.u.ctrl.wLength);
        				if (response_data)
        					memcpy(data, response_data, response_length);
        				else
        					memset(data, 0, response_length);
        				if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
        					if (response_length > 0) {
        						vhci_response_t res;
        						res.size = response_length;
        						rv = vhci_usb_send(fd, &res, sizeof(res));
        						if (rv == 0)
        							rv = vhci_usb_send(fd, data, response_length);
        					}
        				} else {
        					rv = vhci_usb_recv(fd, data, response_length);
        				}
        				if (rv < 0) {
        					goto err;
        				}
        			}
        			sleep_ms(200);
        			return fd;
        		
        		err:
        			close(fd);
        			return -1;
        		}
        		
        		static volatile long syz_usb_connect(volatile long a0, volatile long a1,
        						     volatile long a2, volatile long a3)
        		{
        			uint64_t speed = a0;
        			uint64_t dev_len = a1;
        			const char* dev = (const char*)a2;
        			const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3;
        			return syz_usb_connect_impl(speed, dev_len, dev, descs,
        						    &lookup_connect_response_out_generic);
        		}
        		
        		static volatile long syz_usb_disconnect(volatile long a0)
        		{
        			int fd = a0;
        			int rv = close(fd);
        			sleep_ms(200);
        			return rv;
        		}
        		
        		static void sandbox_common()
        		{
        			if (setsid() == -1)
        			exit(1);
        			struct rlimit rlim;
        			rlim.rlim_cur = rlim.rlim_max = 8 << 20;
        			setrlimit(RLIMIT_MEMLOCK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_FSIZE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 1 << 20;
        			setrlimit(RLIMIT_STACK, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 0;
        			setrlimit(RLIMIT_CORE, &rlim);
        			rlim.rlim_cur = rlim.rlim_max = 256;
        			setrlimit(RLIMIT_NOFILE, &rlim);
        		}
        		
        		static void loop();
        		
        		static int do_sandbox_none(void)
        		{
        			sandbox_common();
        			loop();
        			return 0;
        		}
        		
        		static long syz_execute_func(volatile long text)
        		{
        			volatile long p[8] = {0};
        			(void)p;
        			asm volatile("" ::"r"(0l), "r"(1l), "r"(2l), "r"(3l), "r"(4l), "r"(5l), "r"(6l),
        				     "r"(7l), "r"(8l), "r"(9l), "r"(10l), "r"(11l), "r"(12l), "r"(13l));
        		((void (*)(void))(text))();
        			return 0;
        		}
        		
        		struct thread_t {
        			int created, call;
        			event_t ready, done;
        		};
        		
        		static struct thread_t threads[16];
        		static void execute_call(int call);
        		static int running;
        		
        		static void* thr(void* arg)
        		{
        			struct thread_t* th = (struct thread_t*)arg;
        			for (;;) {
        				event_wait(&th->ready);
        				event_reset(&th->ready);
        				execute_call(th->call);
        				__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
        				event_set(&th->done);
        			}
        			return 0;
        		}
        		
        		static void execute_one(void)
        		{
        			if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
        			}
        			int i, call, thread;
        			for (call = 0; call < 16; call++) {
        				for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); thread++) {
        					struct thread_t* th = &threads[thread];
        					if (!th->created) {
        						th->created = 1;
        						event_init(&th->ready);
        						event_init(&th->done);
        						event_set(&th->done);
        						thread_start(thr, th);
        					}
        					if (!event_isset(&th->done))
        						continue;
        					event_reset(&th->done);
        					th->call = call;
        					__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
        					event_set(&th->ready);
        					event_timedwait(&th->done, 45 + (call == 13 ? 3000 : 0) + (call == 14 ? 3000 : 0) + (call == 15 ? 300 : 0));
        					break;
        				}
        			}
        			for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
        				sleep_ms(1);
        		}
        		
        		static void execute_one(void);
        		
        		#define WAIT_FLAGS 0
        		
        		static void loop(void)
        		{
        			int iter;
        			for (iter = 0;; iter++) {
        				char cwdbuf[32];
        				sprintf(cwdbuf, "./%d", iter);
        				if (mkdir(cwdbuf, 0777))
        			exit(1);
        				int pid = fork();
        				if (pid < 0)
        			exit(1);
        				if (pid == 0) {
        					if (chdir(cwdbuf))
        			exit(1);
        					execute_one();
        					exit(0);
        				}
        				int status = 0;
        				uint64_t start = current_time_ms();
        				for (;;) {
        					if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
        						break;
        					sleep_ms(1);
        					if (current_time_ms() - start < 5 * 1000)
        						continue;
        					kill_and_wait(pid, &status);
        					break;
        				}
        				remove_dir(cwdbuf);
        			}
        		}
        		
        		#ifndef SYS__lwp_ctl
        		#define SYS__lwp_ctl 325
        		#endif
        		#ifndef SYS_clock_nanosleep
        		#define SYS_clock_nanosleep 477
        		#endif
        		#ifndef SYS_getegid
        		#define SYS_getegid 43
        		#endif
        		#ifndef SYS_geteuid
        		#define SYS_geteuid 25
        		#endif
        		#ifndef SYS_getpgrp
        		#define SYS_getpgrp 81
        		#endif
        		#ifndef SYS_mmap
        		#define SYS_mmap 197
        		#endif
        		#ifndef SYS_paccept
        		#define SYS_paccept 456
        		#endif
        		#ifndef SYS_setgid
        		#define SYS_setgid 181
        		#endif
        		#ifndef SYS_setsockopt
        		#define SYS_setsockopt 105
        		#endif
        		#ifndef SYS_shmget
        		#define SYS_shmget 231
        		#endif
        		
        		uint64_t r[5] = {0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffffffffffffffff};
        		
        		void execute_call(int call)
        		{
        				intptr_t res = 0;
        			switch (call) {
        			case 0:
        				syscall(SYS_shmget, 0ul, 0x1000ul, 0x204ul, 0x20fff000ul);
        				break;
        			case 1:
        		*(uint64_t*)0x20000000 = 3;
        		*(uint64_t*)0x20000008 = 7;
        				syscall(SYS_clock_nanosleep, 0x40000000ul, 1ul, 0x20000000ul, 0x20000040ul);
        				break;
        			case 2:
        		*(uint32_t*)0x20000080 = 0;
        				res = syscall(SYS_paccept, 0xffffff9c, 0ul, 0x20000080ul, 0x30000000ul);
        				if (res != -1)
        						r[0] = res;
        				break;
        			case 3:
        		*(uint32_t*)0x200000c0 = 0x8357;
        		*(uint32_t*)0x200000c4 = 0x7ff;
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x80, 0x200000c0ul, 8ul);
        				break;
        			case 4:
        				res = syscall(SYS_getpgrp);
        				if (res != -1)
        						r[1] = res;
        				break;
        			case 5:
        				res = syscall(SYS_geteuid);
        				if (res != -1)
        						r[2] = res;
        				break;
        			case 6:
        				res = syscall(SYS_getegid);
        				if (res != -1)
        						r[3] = res;
        				break;
        			case 7:
        		*(uint32_t*)0x20000100 = r[1];
        		*(uint32_t*)0x20000104 = r[2];
        		*(uint32_t*)0x20000108 = r[3];
        				syscall(SYS_setsockopt, r[0], 0xffff, 0x11, 0x20000100ul, 0xcul);
        				break;
        			case 8:
        				syscall(SYS_setgid, r[3]);
        				break;
        			case 9:
        		*(uint64_t*)0x20000180 = 0x20000140;
        		*(uint32_t*)0x20000140 = 5;
        		*(uint32_t*)0x20000144 = 7;
        				syscall(SYS__lwp_ctl, 0x7a513cdc, 0x20000180ul);
        				break;
        			case 10:
        		memcpy((void*)0x20000000, "\xe5\x13\x2c\xca\x36\xeb\x50\x09\x57\x42\x83\x3a\xbf\xf4\x68\x85\x61\x82\xfc\x0a\xf4\xbd\xca\x80\xfd\x27\x4a\x83\xbb\xfc\xeb\x50\x22\x9b\x33\xb6\x4f\x40\x2b\x8d\xfa\x04\x25\xac\x09\x99\xdc\x4f\xde\x46\xda\x7e\xc1\x36\xe8\x99\xcd\xb6\xe8\x66\x82\x15\x12\x38\x85\x8c\xc5\x72\x4f\x94\x10\x1e\x60\x44\x29\x33\xef\x18\xae\x69\x9f\x3d\x10\x08\xb5\x83\xa3\x52\x95\xb7\x2b\x88\x2a\xe0\x75\xde\x87\x61\x6d\x9e\xfb\xe3\xa2\xa5\xe5\x7f\x30\x80\x98\x44\x42\xb3\x8e\xae\x39\xf5\xca\xd5\x6f\x1b\xee\x40\xc4\x1c\x95\xa8\x33\x22\xa3\xd4\xe8\x4c\x75\x31\x31\x90\x39\x61\xed\xff\x1d\x25\x42\xb5\x29\x19\x23\xf1\xa8\xff\x98\xbc\x69\xb2\xb6\xd6\x51\x27\x3a\xe6\x44\x25\xc3\x6b\x35\x2c\xa4\x03\x41\xb6\x60\x72\xa6\x84\x68\x0d\x9b\xa2\xac\xeb\x2d\x5f\x12\x92\xf6\x76\x69\x75\x67\xb9\x80", 191);
        				break;
        			case 11:
        		memcpy((void*)0x200000c0, "\x0f\x0d\xbe\xe6\xe1\xe7\x39\xc4\xc2\xb1\xbe\xc6\xc4\x03\xf9\x17\x0e\x00\xc4\xa3\x15\x4a\x2e\xff\x0f\x0f\x21\x9a\x8f\x48\x78\xc0\x37\x00\xc4\x02\xc1\x98\x91\x00\x00\x00\x80\xf0\x83\x56\x00\x77\xc4\x81\xfc\x53\x54\x95\x00\xf3\xab", 57);
        				syz_execute_func(0x200000c0);
        				break;
        			case 12:
        				break;
        			case 13:
        		memcpy((void*)0x20000140, "\x39\x84\x75\xb5\x74\xb6\xa3\xa3\x21\xe1\x9f\x0e\x03\xd4\x6f\x48\x6b\x2c\xab\x99\x1a\x2b\x32\x34\x60\xae\xac\xf5\xa0\x34\x82\xd1\x98\x9a\x10\x54\xb6\x1b\x2e\x7f\xba\x3c\x41\x3b\x97\xe2\x71\xf4\x86\x73\xe7\x32\x8c\xa9\x65\xf6\x47\x08\x79\x52\x7a\x74\x7b\x2d\xab\x77\xc1\x0c\xd2\x78\x2d\x8b\xf0\xab\x9e\x8e\xab\xca\xe8\x19\xcb\x4c\xfb\xc1\xb1\x6f\xf8\x04\x5f\x46\x15\x5d\x86\x07\x62\x95\x01\x5b\xe8\x4e\xef\x44\x37\xca\x84\x2e\x2f\x05\x33\x78\x0a\x00\x4f\x9b\xca\x0a\x7b\xc3\xd0\x0c\x52\x10\x2e\x12\x35\x88\xea\xb6\x82\x84\xf7\x97\xa4\x56\xb6\x39\x5e\x0e\x4b\x5f\x03\x01\xd8\x6b\x67\x3a\x12\xc4", 148);
        		memcpy((void*)0x20000200, "\xd8\x9b\x45\x03\xed\x45\x15\x1c\x55\x5c\x40\x15\xc5\x3f\xbd\xba\x2e\x24\xd3\x38\x27\xb3\xbf\x3c\x7b\x62\xa4\x03\x60\xd9\xd7\x20\x5d\x10\x63\x12\xfc\x34\xb3\x78\xe1\x16\x35\xea\x03\x98\x2b\xa2\x56\xaf\x4a\x74\xc7\x7e\xd7\xa9\x50\xff\x7d\x66\xeb\x2f\xc9\x4b\xc7\x20\x88\x94\x1e\xe4\xe2\x59\xb4\x65\x73\xba\xdf\x54\x24\x43\x81\xac\x8d\x43\xf1\xfe\x27\x0f\x03\xf0\x49\xe1\xbf\xc7\xc8\xe7\x14\x2d\x35\x1f\x5d\x4e\x9a\x9e\xdc\x8f\xb7\x32\xc3", 109);
        				syz_usb_connect(0x17, 0x94, 0x20000140, 0x20000200);
        				break;
        			case 14:
        		memcpy((void*)0x20000280, "\x7a\x4c\xb1\x40\xec\x5f\x07\xad\xfb\x64\x65\xda\xcd\xf7\x3c\xf5\xaa\xee\x28\xb6\x8d\xd8\xf6\xb3\x32\x87", 26);
        		memcpy((void*)0x200002c0, "\x9d\x1f\xd2\xf3\x33\xcd\xc7\xa3\xf6\x46\xbc\x7a\xbe\x61\xed\x44\x31\xbf\xc0\xd2\xcd\x4d\x66\xf4\xc3\x92\xff\xc4\xfd\xf1\xdf\xd4\x90\x87\xb4\xb2\x38\x3d\x34\x5c\x67\x89\x4b\xeb\x34\xd4\xd1\x7d\xc3\x78\x51\xb9\x08\x5c\x04\x77\x34\x13\x4b\x99\x16\x71\x9d\x87\x66\x7c\x40\x1d\x62\xc8\x86\x49\xd3\xe7\xdc\xb0\x03\x5e\xaf\x9e\x78\xba\xbe\x8f\xfe\xd4\xc0\xd4\x50\x32\xec\xfa\x93\xd5\x4a\xa8\xde\xbc\x0c\x5a\x56\x6c\x44\x0c\xd5\x88\x47\x73\xc0\xfb\x4b\x7d\x28\x44\x8d\x94\x81\x5e\x04\x6c\xd3\xae\x29\x41\x4d\xfc\xd9\x3e\x6d\x4f\x03\x9a\x82\x04\x80\xfb\x6b\x61\xbe\x6f\xdb\x33\xaa\xcd\x37\x27\x4a\x17\x05\x50\xee\x8e\x39\xea\xb2\x54\x86\xcd\x88\x63\xee\x34\x31\xf2\x2f\x06\x81\xf1\xa1\x54\x96\xdc\x1d\xf5\x25\xac\x48", 177);
        				res = syz_usb_connect(3, 0x1a, 0x20000280, 0x200002c0);
        				if (res != -1)
        						r[4] = res;
        				break;
        			case 15:
        				syz_usb_disconnect(r[4]);
        				break;
        			}
        		
        		}
        		int main(void)
        		{
        				syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul, 0ul);
        					use_temporary_dir();
        					do_sandbox_none();
        			return 0;
        		}
        		
        		<stdin>: In function 'syz_usb_connect_impl':
        		<stdin>:637:63: error: unknown type name 'usb_ctrlrequest'
        		<stdin>:642:55: error: unknown type name 'usb_ctrlrequest'
        		
        		compiler invocation: /syzkaller/netbsd/src/../tools/bin/x86_64--netbsd-g++ [-o /tmp/syz-executor960180475 -DGOOS_netbsd=1 -DGOARCH_amd64=1 -DHOSTGOOS_linux=1 -x c - -m64 --sysroot /syzkaller/netbsd/src/../dest/ -O2 -pthread -Wall -Werror -Wparentheses -Wframe-larger-than=16384]
        --- FAIL: TestGenerate/netbsd/amd64/14 (0.22s)
        	csource_test.go:121: 
        --- FAIL: TestGenerate/netbsd/amd64/10 (0.21s)
        	csource_test.go:121: 
        --- FAIL: TestGenerate/netbsd/amd64/13 (0.22s)
        	csource_test.go:121: 
        --- FAIL: TestGenerate/netbsd/amd64/11 (0.21s)
        	csource_test.go:121: 
        --- FAIL: TestGenerate/netbsd/amd64/9 (0.25s)
        	csource_test.go:121: 
FAIL
FAIL	github.com/google/syzkaller/pkg/csource	3.129s
ok  	github.com/google/syzkaller/pkg/db	(cached)
ok  	github.com/google/syzkaller/pkg/email	(cached)
?   	github.com/google/syzkaller/pkg/gce	[no test files]
?   	github.com/google/syzkaller/pkg/gcs	[no test files]
?   	github.com/google/syzkaller/pkg/hash	[no test files]
ok  	github.com/google/syzkaller/pkg/host	(cached)
?   	github.com/google/syzkaller/pkg/html	[no test files]
ok  	github.com/google/syzkaller/pkg/ifuzz	(cached)
?   	github.com/google/syzkaller/pkg/ifuzz/gen	[no test files]
?   	github.com/google/syzkaller/pkg/ifuzz/generated	[no test files]
ok  	github.com/google/syzkaller/pkg/instance	(cached)
ok  	github.com/google/syzkaller/pkg/ipc	(cached)
?   	github.com/google/syzkaller/pkg/ipc/ipcconfig	[no test files]
ok  	github.com/google/syzkaller/pkg/kd	(cached)
ok  	github.com/google/syzkaller/pkg/log	(cached)
ok  	github.com/google/syzkaller/pkg/mgrconfig	(cached)
ok  	github.com/google/syzkaller/pkg/osutil	(cached)
ok  	github.com/google/syzkaller/pkg/report	(cached)
ok  	github.com/google/syzkaller/pkg/repro	(cached)
?   	github.com/google/syzkaller/pkg/rpctype	[no test files]
ok  	github.com/google/syzkaller/pkg/runtest	(cached)
ok  	github.com/google/syzkaller/pkg/serializer	(cached)
?   	github.com/google/syzkaller/pkg/signal	[no test files]
ok  	github.com/google/syzkaller/pkg/symbolizer	(cached)
ok  	github.com/google/syzkaller/pkg/vcs	(cached)
ok  	github.com/google/syzkaller/prog	(cached)
ok  	github.com/google/syzkaller/prog/test	(cached)
?   	github.com/google/syzkaller/sys	[no test files]
?   	github.com/google/syzkaller/sys/akaros	[no test files]
?   	github.com/google/syzkaller/sys/akaros/gen	[no test files]
?   	github.com/google/syzkaller/sys/freebsd	[no test files]
?   	github.com/google/syzkaller/sys/freebsd/gen	[no test files]
?   	github.com/google/syzkaller/sys/fuchsia	[no test files]
?   	github.com/google/syzkaller/sys/fuchsia/fidlgen	[no test files]
?   	github.com/google/syzkaller/sys/fuchsia/gen	[no test files]
?   	github.com/google/syzkaller/sys/fuchsia/layout	[no test files]
ok  	github.com/google/syzkaller/sys/linux	(cached)
?   	github.com/google/syzkaller/sys/linux/gen	[no test files]
?   	github.com/google/syzkaller/sys/netbsd	[no test files]
?   	github.com/google/syzkaller/sys/netbsd/gen	[no test files]
ok  	github.com/google/syzkaller/sys/openbsd	(cached)
?   	github.com/google/syzkaller/sys/openbsd/gen	[no test files]
?   	github.com/google/syzkaller/sys/syz-extract	[no test files]
?   	github.com/google/syzkaller/sys/syz-sysgen	[no test files]
?   	github.com/google/syzkaller/sys/targets	[no test files]
?   	github.com/google/syzkaller/sys/test	[no test files]
?   	github.com/google/syzkaller/sys/test/gen	[no test files]
?   	github.com/google/syzkaller/sys/trusty	[no test files]
?   	github.com/google/syzkaller/sys/trusty/gen	[no test files]
?   	github.com/google/syzkaller/sys/windows	[no test files]
?   	github.com/google/syzkaller/sys/windows/gen	[no test files]
ok  	github.com/google/syzkaller/syz-ci	(cached)
ok  	github.com/google/syzkaller/syz-fuzzer	(cached)
ok  	github.com/google/syzkaller/syz-hub	(cached)
ok  	github.com/google/syzkaller/syz-hub/state	(cached)
?   	github.com/google/syzkaller/syz-manager	[no test files]
?   	github.com/google/syzkaller/tools/syz-benchcmp	[no test files]
?   	github.com/google/syzkaller/tools/syz-bisect	[no test files]
?   	github.com/google/syzkaller/tools/syz-check	[no test files]
?   	github.com/google/syzkaller/tools/syz-cover	[no test files]
?   	github.com/google/syzkaller/tools/syz-crush	[no test files]
?   	github.com/google/syzkaller/tools/syz-db	[no test files]
?   	github.com/google/syzkaller/tools/syz-execprog	[no test files]
?   	github.com/google/syzkaller/tools/syz-expand	[no test files]
?   	github.com/google/syzkaller/tools/syz-fmt	[no test files]
?   	github.com/google/syzkaller/tools/syz-imagegen	[no test files]
?   	github.com/google/syzkaller/tools/syz-make	[no test files]
?   	github.com/google/syzkaller/tools/syz-mutate	[no test files]
?   	github.com/google/syzkaller/tools/syz-prog2c	[no test files]
?   	github.com/google/syzkaller/tools/syz-repro	[no test files]
?   	github.com/google/syzkaller/tools/syz-reprolist	[no test files]
?   	github.com/google/syzkaller/tools/syz-runtest	[no test files]
?   	github.com/google/syzkaller/tools/syz-showprio	[no test files]
?   	github.com/google/syzkaller/tools/syz-stress	[no test files]
?   	github.com/google/syzkaller/tools/syz-symbolize	[no test files]
?   	github.com/google/syzkaller/tools/syz-testbuild	[no test files]
?   	github.com/google/syzkaller/tools/syz-trace2syz	[no test files]
ok  	github.com/google/syzkaller/tools/syz-trace2syz/parser	(cached)
ok  	github.com/google/syzkaller/tools/syz-trace2syz/proggen	(cached)
?   	github.com/google/syzkaller/tools/syz-tty	[no test files]
?   	github.com/google/syzkaller/tools/syz-upgrade	[no test files]
?   	github.com/google/syzkaller/tools/syz-usbgen	[no test files]
ok  	github.com/google/syzkaller/vm	(cached)
?   	github.com/google/syzkaller/vm/adb	[no test files]
?   	github.com/google/syzkaller/vm/bhyve	[no test files]
?   	github.com/google/syzkaller/vm/gce	[no test files]
?   	github.com/google/syzkaller/vm/gvisor	[no test files]
ok  	github.com/google/syzkaller/vm/isolated	(cached)
?   	github.com/google/syzkaller/vm/kvm	[no test files]
?   	github.com/google/syzkaller/vm/odroid	[no test files]
?   	github.com/google/syzkaller/vm/qemu	[no test files]
ok  	github.com/google/syzkaller/vm/vmimpl	(cached)
?   	github.com/google/syzkaller/vm/vmm	[no test files]